refactor(ags): make all widgets functions, use export default and some formatting
This commit is contained in:
parent
f6160e3e0b
commit
9b4e7fac44
39 changed files with 797 additions and 694 deletions
|
@ -1,8 +1,8 @@
|
||||||
import { App, Applications, Utils, Widget } from '../../imports.js';
|
import { App, Applications, Utils, Widget } from '../../imports.js';
|
||||||
const { Label, Box, Icon, Button, Scrollable, Entry } = Widget;
|
const { Label, Box, Icon, Button, Scrollable, Entry } = Widget;
|
||||||
|
|
||||||
import { Separator } from '../misc/separator.js';
|
import Separator from '../misc/separator.js';
|
||||||
import { PopupWindow } from '../misc/popup.js';
|
import PopupWindow from '../misc/popup.js';
|
||||||
|
|
||||||
const icons = {
|
const icons = {
|
||||||
apps: {
|
apps: {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Audio, Widget } from '../../imports.js';
|
import { Audio, Widget } from '../../imports.js';
|
||||||
const { Label, Box, Icon } = Widget;
|
const { Label, Box, Icon } = Widget;
|
||||||
|
|
||||||
import { Separator } from '../misc/separator.js';
|
import Separator from '../misc/separator.js';
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
const items = {
|
const items = {
|
||||||
101: 'audio-volume-overamplified-symbolic',
|
101: 'audio-volume-overamplified-symbolic',
|
||||||
|
@ -13,36 +13,36 @@ const items = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const SpeakerIndicator = params => Icon({
|
const SpeakerIndicator = props => Icon({
|
||||||
...params,
|
...props,
|
||||||
icon: '',
|
icon: '',
|
||||||
connections: [[Audio, icon => {
|
connections: [[Audio, self => {
|
||||||
if (Audio.speaker) {
|
if (!Audio.speaker)
|
||||||
|
return;
|
||||||
|
|
||||||
if (Audio.speaker.stream.isMuted) {
|
if (Audio.speaker.stream.isMuted) {
|
||||||
icon.icon = items[0];
|
self.icon = items[0];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const vol = Audio.speaker.volume * 100;
|
const vol = Audio.speaker.volume * 100;
|
||||||
|
|
||||||
for (const threshold of [-1, 0, 33, 66, 100]) {
|
for (const threshold of [-1, 0, 33, 66, 100]) {
|
||||||
if (vol > threshold + 1) {
|
if (vol > threshold + 1)
|
||||||
icon.icon = items[threshold + 1];
|
self.icon = items[threshold + 1];
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 'speaker-changed']],
|
}, 'speaker-changed']],
|
||||||
});
|
});
|
||||||
|
|
||||||
const SpeakerPercentLabel = params => Label({
|
const SpeakerPercentLabel = props => Label({
|
||||||
...params,
|
...props,
|
||||||
connections: [[Audio, label => {
|
connections: [[Audio, label => {
|
||||||
if (Audio.speaker) {
|
if (Audio.speaker)
|
||||||
label.label = Math.round(Audio.speaker.volume * 100) + '%';
|
label.label = Math.round(Audio.speaker.volume * 100) + '%';
|
||||||
}
|
|
||||||
}, 'speaker-changed']],
|
}, 'speaker-changed']],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AudioIndicator = EventBox({
|
export default () => EventBox({
|
||||||
onPrimaryClickRelease: 'pavucontrol',
|
onPrimaryClickRelease: 'pavucontrol',
|
||||||
className: 'toggle-off',
|
className: 'toggle-off',
|
||||||
child: Box({
|
child: Box({
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Battery, Widget } from '../../imports.js';
|
import { Battery, Widget } from '../../imports.js';
|
||||||
const { Label, Icon, Stack, Box } = Widget;
|
const { Label, Icon, Stack, Box } = Widget;
|
||||||
|
|
||||||
import { Separator } from '../misc/separator.js';
|
import Separator from '../misc/separator.js';
|
||||||
|
|
||||||
const icons = charging => ([
|
const icons = charging => ([
|
||||||
...Array.from({ length: 10 }, (_, i) => i * 10).map(i => ([
|
...Array.from({ length: 10 }, (_, i) => i * 10).map(i => ([
|
||||||
|
@ -27,9 +27,9 @@ const Indicators = charging => Stack({
|
||||||
const Indicator = ({
|
const Indicator = ({
|
||||||
charging = Indicators(true),
|
charging = Indicators(true),
|
||||||
discharging = Indicators(false),
|
discharging = Indicators(false),
|
||||||
...params
|
...props
|
||||||
} = {}) => Stack({
|
} = {}) => Stack({
|
||||||
...params,
|
...props,
|
||||||
className: 'battery-indicator',
|
className: 'battery-indicator',
|
||||||
items: [
|
items: [
|
||||||
['true', charging],
|
['true', charging],
|
||||||
|
@ -43,13 +43,13 @@ const Indicator = ({
|
||||||
}]],
|
}]],
|
||||||
});
|
});
|
||||||
|
|
||||||
const LevelLabel = params => Label({
|
const LevelLabel = props => Label({
|
||||||
...params,
|
...props,
|
||||||
className: 'label',
|
className: 'label',
|
||||||
connections: [[Battery, label => label.label = `${Battery.percent}%`]],
|
connections: [[Battery, self => self.label = `${Battery.percent}%`]],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const BatteryIndicator = Box({
|
export default () => Box({
|
||||||
className: 'toggle-off battery',
|
className: 'toggle-off battery',
|
||||||
children: [
|
children: [
|
||||||
Indicator(),
|
Indicator(),
|
||||||
|
|
|
@ -1,25 +1,23 @@
|
||||||
import { Utils, Widget } from '../../imports.js';
|
import { Utils, Widget } from '../../imports.js';
|
||||||
const { ProgressBar, Overlay, Box } = Widget;
|
const { ProgressBar, Overlay, Box } = Widget;
|
||||||
|
|
||||||
import { Separator } from '../misc/separator.js';
|
import Separator from '../misc/separator.js';
|
||||||
import { Heart } from './heart.js';
|
import Heart from './heart.js';
|
||||||
|
|
||||||
|
|
||||||
export const Brightness = Overlay({
|
export default () => Overlay({
|
||||||
setup: widget => {
|
tooltipText: 'Brightness',
|
||||||
widget.set_tooltip_text('Brightness');
|
|
||||||
},
|
|
||||||
child: ProgressBar({
|
child: ProgressBar({
|
||||||
className: 'toggle-off brightness',
|
className: 'toggle-off brightness',
|
||||||
connections: [
|
connections: [
|
||||||
[200, progress => {
|
[200, self => {
|
||||||
Utils.execAsync('brightnessctl get').then(out => {
|
Utils.execAsync('brightnessctl get').then(out => {
|
||||||
let br = out / 255;
|
let br = out / 255;
|
||||||
if (br > 0.33) {
|
if (br > 0.33) {
|
||||||
progress.value = br;
|
self.value = br;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
progress.value = 0.33;
|
self.value = 0.33;
|
||||||
}
|
}
|
||||||
}).catch(print);
|
}).catch(print);
|
||||||
}],
|
}],
|
||||||
|
@ -30,7 +28,7 @@ export const Brightness = Overlay({
|
||||||
style: 'color: #CBA6F7;',
|
style: 'color: #CBA6F7;',
|
||||||
children: [
|
children: [
|
||||||
Separator(25),
|
Separator(25),
|
||||||
Heart,
|
Heart(),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
|
@ -4,30 +4,32 @@ const { Box, Label } = Widget;
|
||||||
import GLib from 'gi://GLib';
|
import GLib from 'gi://GLib';
|
||||||
const { DateTime } = GLib;
|
const { DateTime } = GLib;
|
||||||
|
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
const ClockModule = ({
|
const ClockModule = ({
|
||||||
interval = 1000,
|
interval = 1000,
|
||||||
...params
|
...props
|
||||||
}) => Label({
|
}) => Label({
|
||||||
...params,
|
...props,
|
||||||
className: 'clock',
|
className: 'clock',
|
||||||
connections: [
|
connections: [
|
||||||
[interval, label => {
|
[interval, self => {
|
||||||
var time = DateTime.new_now_local();
|
var time = DateTime.new_now_local();
|
||||||
label.label = time.format('%a. ') + time.get_day_of_month() + time.format(' %b. %H:%M');
|
self.label = time.format('%a. ') +
|
||||||
|
time.get_day_of_month() +
|
||||||
|
time.format(' %b. %H:%M');
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Clock = EventBox({
|
export default () => EventBox({
|
||||||
className: 'toggle-off',
|
className: 'toggle-off',
|
||||||
onPrimaryClickRelease: () => App.toggleWindow('calendar'),
|
onPrimaryClickRelease: () => App.toggleWindow('calendar'),
|
||||||
connections: [
|
connections: [
|
||||||
[App, (box, windowName, visible) => {
|
[App, (self, windowName, visible) => {
|
||||||
if (windowName == 'calendar') {
|
if (windowName == 'calendar') {
|
||||||
box.toggleClassName('toggle-on', visible);
|
self.toggleClassName('toggle-on', visible);
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
|
|
|
@ -2,12 +2,8 @@ import { Widget, Hyprland } from '../../imports.js';
|
||||||
const { Label } = Widget;
|
const { Label } = Widget;
|
||||||
|
|
||||||
|
|
||||||
export const CurrentWindow = Label({
|
export default () => Label({
|
||||||
style: 'color: #CBA6F7; font-size: 18px',
|
style: 'color: #CBA6F7; font-size: 18px',
|
||||||
truncate: 'end',
|
truncate: 'end',
|
||||||
connections: [
|
binds: [['label', Hyprland.active.client, 'title']],
|
||||||
[Hyprland, label => {
|
|
||||||
label.label = Hyprland.active.client.title;
|
|
||||||
}, 'changed'],
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,19 +4,14 @@ const { Box, EventBox, Overlay } = Widget;
|
||||||
const Revealed = Variable(true);
|
const Revealed = Variable(true);
|
||||||
const Hovering = Variable(false);
|
const Hovering = Variable(false);
|
||||||
|
|
||||||
import { Gesture } from './gesture.js';
|
|
||||||
import { RoundedCorner } from '../screen-corners.js';
|
import { RoundedCorner } from '../screen-corners.js';
|
||||||
|
import Gesture from './gesture.js';
|
||||||
|
|
||||||
|
|
||||||
export const Revealer = params => Overlay({
|
export default (props) => Overlay({
|
||||||
overlays: [
|
overlays: [
|
||||||
RoundedCorner('topleft', {
|
RoundedCorner('topleft', { className: 'corner' }),
|
||||||
className: 'corner',
|
RoundedCorner('topright', { className: 'corner' }),
|
||||||
}),
|
|
||||||
|
|
||||||
RoundedCorner('topright', {
|
|
||||||
className: 'corner',
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
|
|
||||||
child: Box({
|
child: Box({
|
||||||
|
@ -27,14 +22,14 @@ export const Revealer = params => Overlay({
|
||||||
Widget.Revealer({
|
Widget.Revealer({
|
||||||
transition: 'slide_down',
|
transition: 'slide_down',
|
||||||
setup: self => self.revealChild = true,
|
setup: self => self.revealChild = true,
|
||||||
properties: [
|
|
||||||
['timeouts', []],
|
properties: [['timeouts', []]],
|
||||||
],
|
|
||||||
connections: [[Hyprland, self => {
|
connections: [[Hyprland, self => {
|
||||||
Utils.execAsync('hyprctl activewindow -j')
|
Utils.execAsync('hyprctl activewindow -j').then(out => {
|
||||||
.then(result => {
|
let client = JSON.parse(out);
|
||||||
let client = JSON.parse(result);
|
if (client.fullscreen === Revealed.value)
|
||||||
if (client.fullscreen !== Revealed.value) {
|
return;
|
||||||
|
|
||||||
Revealed.value = client.fullscreen;
|
Revealed.value = client.fullscreen;
|
||||||
|
|
||||||
if (Revealed.value) {
|
if (Revealed.value) {
|
||||||
|
@ -46,7 +41,6 @@ export const Revealer = params => Overlay({
|
||||||
else {
|
else {
|
||||||
self.revealChild = true;
|
self.revealChild = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}).catch(print);
|
}).catch(print);
|
||||||
}]],
|
}]],
|
||||||
|
|
||||||
|
@ -63,7 +57,7 @@ export const Revealer = params => Overlay({
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
...params,
|
...props,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
|
@ -4,30 +4,25 @@ const { CenterBox, EventBox } = Widget;
|
||||||
import Gtk from 'gi://Gtk';
|
import Gtk from 'gi://Gtk';
|
||||||
|
|
||||||
|
|
||||||
export const Gesture = ({
|
export default ({
|
||||||
child,
|
child,
|
||||||
...params
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
let w = EventBox({
|
let widget = EventBox({
|
||||||
...params,
|
...props,
|
||||||
});
|
});
|
||||||
|
|
||||||
let gesture = Gtk.GestureSwipe.new(w);
|
let gesture = Gtk.GestureSwipe.new(widget);
|
||||||
|
|
||||||
w.child = CenterBox({
|
widget.child = CenterBox({
|
||||||
children: [
|
children: [ child ],
|
||||||
child,
|
connections: [[gesture, () => {
|
||||||
],
|
|
||||||
connections: [
|
|
||||||
|
|
||||||
[gesture, _ => {
|
|
||||||
const velocity = gesture.get_velocity()[1];
|
const velocity = gesture.get_velocity()[1];
|
||||||
if (velocity < -100)
|
if (velocity < -100)
|
||||||
App.openWindow('quick-settings');
|
App.openWindow('quick-settings');
|
||||||
}, 'update'],
|
|
||||||
|
|
||||||
],
|
}, 'update']],
|
||||||
});
|
});
|
||||||
|
|
||||||
return w;
|
return widget;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,26 +2,28 @@ import { Utils, Widget } from '../../imports.js';
|
||||||
const { Box, Label } = Widget;
|
const { Box, Label } = Widget;
|
||||||
const { subprocess, execAsync } = Utils;
|
const { subprocess, execAsync } = Utils;
|
||||||
|
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
subprocess(
|
export default () => EventBox({
|
||||||
['bash', '-c', 'tail -f /home/matt/.config/.heart'],
|
|
||||||
(output) => {
|
|
||||||
Heart.child.children[0].label = ' ' + output;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
export const Heart = EventBox({
|
|
||||||
halign: 'center',
|
halign: 'center',
|
||||||
|
|
||||||
onPrimaryClickRelease: () => {
|
onPrimaryClickRelease: () => {
|
||||||
execAsync(['bash', '-c', '$AGS_PATH/heart.sh toggle']).catch(print);
|
execAsync(['bash', '-c', '$AGS_PATH/heart.sh toggle']).catch(print);
|
||||||
},
|
},
|
||||||
|
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'heart-toggle',
|
className: 'heart-toggle',
|
||||||
vertical: false,
|
vertical: false,
|
||||||
|
|
||||||
child: Label({
|
child: Label({
|
||||||
label: '',
|
label: '',
|
||||||
|
setup: self => {
|
||||||
|
subprocess(
|
||||||
|
['bash', '-c', 'tail -f /home/matt/.config/.heart'],
|
||||||
|
(output) => self.label = ' ' + output,
|
||||||
|
);
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ const { Label, Box, Icon } = Widget;
|
||||||
|
|
||||||
const DEFAULT_KB = "at-translated-set-2-keyboard";
|
const DEFAULT_KB = "at-translated-set-2-keyboard";
|
||||||
|
|
||||||
export default Box({
|
export default () => Box({
|
||||||
className: 'toggle-off',
|
className: 'toggle-off',
|
||||||
children: [
|
children: [
|
||||||
Icon({
|
Icon({
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { Widget } from '../../imports.js';
|
import { Widget } from '../../imports.js';
|
||||||
const { Window, CenterBox, Box } = Widget;
|
const { Window, CenterBox, Box } = Widget;
|
||||||
|
|
||||||
import { Separator } from '../misc/separator.js';
|
import Separator from '../misc/separator.js';
|
||||||
import { CurrentWindow } from './current-window.js';
|
import CurrentWindow from './current-window.js';
|
||||||
import { Workspaces } from './workspaces.js';
|
import Workspaces from './workspaces.js';
|
||||||
import { OskToggle } from './osk-toggle.js';
|
import OskToggle from './osk-toggle.js';
|
||||||
import { TabletToggle } from './tablet-toggle.js';
|
import TabletToggle from './tablet-toggle.js';
|
||||||
import { QsToggle } from './quick-settings.js';
|
import QsToggle from './quick-settings.js';
|
||||||
import { NotifButton } from './notif-button.js';
|
import NotifButton from './notif-button.js';
|
||||||
import { Clock } from './clock.js';
|
import Clock from './clock.js';
|
||||||
import { SysTray } from './systray.js';
|
import SysTray from './systray.js';
|
||||||
import { BatteryIndicator } from './battery.js';
|
import Battery from './battery.js';
|
||||||
import { Brightness } from './brightness.js';
|
import Brightness from './brightness.js';
|
||||||
import { AudioIndicator } from './audio.js';
|
import Audio from './audio.js';
|
||||||
import { Revealer } from './fullscreen.js';
|
import Revealer from './fullscreen.js';
|
||||||
//import KeyboardLayout from './keyboard-layout.js';
|
//import KeyboardLayout from './keyboard-layout.js';
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,55 +31,55 @@ export const Bar = () => Window({
|
||||||
halign: 'start',
|
halign: 'start',
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
OskToggle,
|
OskToggle(),
|
||||||
|
|
||||||
Separator(12),
|
Separator(12),
|
||||||
|
|
||||||
TabletToggle,
|
TabletToggle(),
|
||||||
|
|
||||||
Separator(12),
|
Separator(12),
|
||||||
|
|
||||||
SysTray,
|
SysTray(),
|
||||||
|
|
||||||
AudioIndicator,
|
Audio(),
|
||||||
|
|
||||||
Separator(12),
|
Separator(12),
|
||||||
|
|
||||||
Brightness,
|
Brightness(),
|
||||||
|
|
||||||
Separator(12),
|
Separator(12),
|
||||||
|
|
||||||
Workspaces,
|
Workspaces(),
|
||||||
|
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
centerWidget: Box({
|
centerWidget: Box({
|
||||||
children: [
|
children: [
|
||||||
CurrentWindow,
|
CurrentWindow(),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
endWidget: Box({
|
endWidget: Box({
|
||||||
halign: 'end',
|
halign: 'end',
|
||||||
children: [
|
children: [
|
||||||
BatteryIndicator,
|
Battery(),
|
||||||
|
|
||||||
Separator(12),
|
Separator(12),
|
||||||
|
|
||||||
//KeyboardLayout,
|
//KeyboardLayout(),
|
||||||
|
|
||||||
//Separator(12),
|
//Separator(12),
|
||||||
|
|
||||||
Clock,
|
Clock(),
|
||||||
|
|
||||||
Separator(12),
|
Separator(12),
|
||||||
|
|
||||||
NotifButton,
|
NotifButton(),
|
||||||
|
|
||||||
Separator(12),
|
Separator(12),
|
||||||
|
|
||||||
QsToggle,
|
QsToggle(),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,20 +1,17 @@
|
||||||
import { App, Notifications, Widget } from '../../imports.js';
|
import { App, Notifications, Widget } from '../../imports.js';
|
||||||
const { Box, Label, Icon } = Widget;
|
const { Box, Label, Icon } = Widget;
|
||||||
|
|
||||||
import { Separator } from '../misc/separator.js';
|
import Separator from '../misc/separator.js';
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
export const NotifButton = EventBox({
|
export default () => EventBox({
|
||||||
className: 'toggle-off',
|
className: 'toggle-off',
|
||||||
onPrimaryClickRelease: () => App.toggleWindow('notification-center'),
|
onPrimaryClickRelease: () => App.toggleWindow('notification-center'),
|
||||||
connections: [
|
connections: [[App, (self, windowName, visible) => {
|
||||||
[App, (box, windowName, visible) => {
|
if (windowName == 'notification-center')
|
||||||
if (windowName == 'notification-center') {
|
self.toggleClassName('toggle-on', visible);
|
||||||
box.toggleClassName('toggle-on', visible);
|
}]],
|
||||||
}
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'notif-panel',
|
className: 'notif-panel',
|
||||||
vertical: false,
|
vertical: false,
|
||||||
|
@ -22,30 +19,26 @@ export const NotifButton = EventBox({
|
||||||
Separator(28),
|
Separator(28),
|
||||||
|
|
||||||
Icon({
|
Icon({
|
||||||
connections: [
|
connections: [[Notifications, self => {
|
||||||
[Notifications, icon => {
|
|
||||||
if (Notifications.dnd) {
|
if (Notifications.dnd) {
|
||||||
icon.icon = 'notification-disabled-symbolic'
|
self.icon = 'notification-disabled-symbolic'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (Notifications.notifications.length > 0) {
|
if (Notifications.notifications.length > 0) {
|
||||||
icon.icon = 'notification-new-symbolic'
|
self.icon = 'notification-new-symbolic'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
icon.icon = 'notification-symbolic'
|
self.icon = 'notification-symbolic'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}],
|
}]],
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Separator(8),
|
Separator(8),
|
||||||
|
|
||||||
Label({
|
Label({
|
||||||
connections: [
|
binds: [
|
||||||
[Notifications, label => {
|
['label', Notifications, 'notifications', n => String(n.length)],
|
||||||
label.label = String(Notifications.notifications.length);
|
|
||||||
}],
|
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
|
@ -2,33 +2,25 @@ import { Utils, Widget } from '../../imports.js';
|
||||||
const { Box, Label } = Widget;
|
const { Box, Label } = Widget;
|
||||||
const { subprocess } = Utils;
|
const { subprocess } = Utils;
|
||||||
|
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
subprocess(
|
export default () => EventBox({
|
||||||
['bash', '-c', '$AGS_PATH/osk-toggle.sh getState'],
|
|
||||||
(output) => {
|
|
||||||
if (output == 'Running') {
|
|
||||||
OskToggle.toggleClassName('toggle-on', true);
|
|
||||||
} else {
|
|
||||||
OskToggle.toggleClassName('toggle-on', false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
export const OskToggle = EventBox({
|
|
||||||
className: 'toggle-off',
|
className: 'toggle-off',
|
||||||
onPrimaryClickRelease: function() {
|
setup: self => {
|
||||||
subprocess(
|
subprocess(
|
||||||
['bash', '-c', '$AGS_PATH/osk-toggle.sh toggle'],
|
['bash', '-c', '$AGS_PATH/osk-toggle.sh getState'],
|
||||||
(output) => {
|
(output) => self.toggleClassName('toggle-on', output === 'Running'),
|
||||||
if (output == 'Running') {
|
|
||||||
OskToggle.toggleClassName('toggle-on', false);
|
|
||||||
} else {
|
|
||||||
OskToggle.toggleClassName('toggle-on', true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onPrimaryClickRelease: self => {
|
||||||
|
subprocess(
|
||||||
|
['bash', '-c', '$AGS_PATH/osk-toggle.sh toggle'],
|
||||||
|
(output) => self.toggleClassName('toggle-on', output !== 'Running'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'osk-toggle',
|
className: 'osk-toggle',
|
||||||
vertical: false,
|
vertical: false,
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
import { Widget, App } from '../../imports.js';
|
import { Widget, App } from '../../imports.js';
|
||||||
const { Box, Label } = Widget;
|
const { Box, Label } = Widget;
|
||||||
|
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
export const QsToggle = EventBox({
|
export default () => EventBox({
|
||||||
className: 'toggle-off',
|
className: 'toggle-off',
|
||||||
onPrimaryClickRelease: () => App.toggleWindow('quick-settings'),
|
onPrimaryClickRelease: () => App.toggleWindow('quick-settings'),
|
||||||
connections: [
|
connections: [[App, (self, windowName, visible) => {
|
||||||
[App, (box, windowName, visible) => {
|
if (windowName == 'quick-settings')
|
||||||
if (windowName == 'quick-settings') {
|
self.toggleClassName('toggle-on', visible);
|
||||||
box.toggleClassName('toggle-on', visible);
|
}]],
|
||||||
}
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'quick-settings-toggle',
|
className: 'quick-settings-toggle',
|
||||||
vertical: false,
|
vertical: false,
|
||||||
|
|
|
@ -3,7 +3,7 @@ const { Box, Revealer, Icon, MenuItem } = Widget;
|
||||||
|
|
||||||
import Gtk from 'gi://Gtk';
|
import Gtk from 'gi://Gtk';
|
||||||
|
|
||||||
import { Separator } from '../misc/separator.js';
|
import Separator from '../misc/separator.js';
|
||||||
|
|
||||||
|
|
||||||
const SysTrayItem = item => MenuItem({
|
const SysTrayItem = item => MenuItem({
|
||||||
|
@ -21,7 +21,7 @@ const SysTrayItem = item => MenuItem({
|
||||||
}]]
|
}]]
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SysTray = Revealer({
|
export default () => Revealer({
|
||||||
transition: 'slide_right',
|
transition: 'slide_right',
|
||||||
connections: [[SystemTray, rev => {
|
connections: [[SystemTray, rev => {
|
||||||
rev.revealChild = rev.child.children[0].get_children().length > 0;
|
rev.revealChild = rev.child.children[0].get_children().length > 0;
|
||||||
|
|
|
@ -2,22 +2,15 @@ import { Utils, Widget } from '../../imports.js';
|
||||||
const { Box, Label } = Widget;
|
const { Box, Label } = Widget;
|
||||||
const { subprocess } = Utils;
|
const { subprocess } = Utils;
|
||||||
|
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
export const TabletToggle = EventBox({
|
export default () => EventBox({
|
||||||
className: 'toggle-off',
|
className: 'toggle-off',
|
||||||
onPrimaryClickRelease: function() {
|
onPrimaryClickRelease: self => {
|
||||||
subprocess(
|
subprocess(
|
||||||
['bash', '-c', '$AGS_PATH/tablet-toggle.sh toggle'],
|
['bash', '-c', '$AGS_PATH/tablet-toggle.sh toggle'],
|
||||||
(output) => {
|
(output) => self.toggleClassName('toggle-on', output == 'Tablet'),
|
||||||
print(output)
|
|
||||||
if (output == 'Tablet') {
|
|
||||||
TabletToggle.toggleClassName('toggle-on', true);
|
|
||||||
} else {
|
|
||||||
TabletToggle.toggleClassName('toggle-on', false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Box({
|
child: Box({
|
||||||
|
|
|
@ -1,69 +1,69 @@
|
||||||
import { Hyprland, Utils, Widget } from '../../imports.js';
|
import { Hyprland, Utils, Widget } from '../../imports.js';
|
||||||
const { Box, Label, Revealer } = Widget;
|
const { Box, Revealer } = Widget;
|
||||||
const { execAsync } = Utils;
|
const { execAsync } = Utils;
|
||||||
|
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
const Workspace = ({ i } = {}) =>
|
const Workspace = ({ i } = {}) =>
|
||||||
Revealer({
|
Revealer({
|
||||||
transition: "slide_right",
|
transition: "slide_right",
|
||||||
properties: [
|
properties: [['id', i]],
|
||||||
['id', i],
|
|
||||||
],
|
|
||||||
child: EventBox({
|
child: EventBox({
|
||||||
tooltipText: `${i}`,
|
tooltipText: `${i}`,
|
||||||
onPrimaryClickRelease: () => execAsync(`hyprctl dispatch workspace ${i}`).catch(print),
|
onPrimaryClickRelease: () => {
|
||||||
|
execAsync(`hyprctl dispatch workspace ${i}`)
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'button',
|
className: 'button',
|
||||||
connections: [
|
connections: [[Hyprland, self => {
|
||||||
[Hyprland, btn => {
|
|
||||||
const occupied = Hyprland.getWorkspace(i)?.windows > 0;
|
const occupied = Hyprland.getWorkspace(i)?.windows > 0;
|
||||||
btn.toggleClassName('active', Hyprland.active.workspace.id === i);
|
self.toggleClassName('active', Hyprland.active.workspace.id === i);
|
||||||
btn.toggleClassName('occupied', occupied);
|
self.toggleClassName('occupied', occupied);
|
||||||
btn.toggleClassName('empty', !occupied);
|
self.toggleClassName('empty', !occupied);
|
||||||
}]
|
}]],
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Workspaces = Box({
|
export default () => Box({
|
||||||
className: 'workspaces',
|
className: 'workspaces',
|
||||||
children: [EventBox({
|
children: [EventBox({
|
||||||
child: Box({
|
child: Box({
|
||||||
properties: [
|
properties: [
|
||||||
['workspaces'],
|
['workspaces'],
|
||||||
|
|
||||||
['refresh', box => {
|
['refresh', self => {
|
||||||
box.children.forEach(rev => rev.reveal_child = false);
|
self.children.forEach(rev => rev.reveal_child = false);
|
||||||
box._workspaces.forEach(ws => {
|
self._workspaces.forEach(ws => {
|
||||||
ws.revealChild = true;
|
ws.revealChild = true;
|
||||||
});
|
});
|
||||||
}],
|
}],
|
||||||
|
|
||||||
['updateWs', box => {
|
['updateWs', self => {
|
||||||
Hyprland.workspaces.forEach(ws => {
|
Hyprland.workspaces.forEach(ws => {
|
||||||
let currentWs = box.children.find(ch => ch._id == ws.id);
|
let currentWs = self.children.find(ch => ch._id == ws.id);
|
||||||
if (!currentWs && ws.id > 0) {
|
if (!currentWs && ws.id > 0) {
|
||||||
box.add(Workspace({ i: ws.id}));
|
self.add(Workspace({ i: ws.id}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
box.show_all();
|
self.show_all();
|
||||||
|
|
||||||
// Make sure the order is correct
|
// Make sure the order is correct
|
||||||
box._workspaces.forEach((workspace, i) => {
|
self._workspaces.forEach((workspace, i) => {
|
||||||
workspace.get_parent().reorder_child(workspace, i);
|
workspace.get_parent().reorder_child(workspace, i);
|
||||||
});
|
});
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
connections: [[Hyprland, box => {
|
connections: [[Hyprland, self => {
|
||||||
box._workspaces = box.children.filter(ch => {
|
self._workspaces = self.children.filter(ch => {
|
||||||
return Hyprland.workspaces.find(ws => ws.id == ch._id)
|
return Hyprland.workspaces.find(ws => ws.id == ch._id)
|
||||||
}).sort((a, b) => a._id - b._id);
|
}).sort((a, b) => a._id - b._id);
|
||||||
|
|
||||||
box._updateWs(box);
|
self._updateWs(self);
|
||||||
box._refresh(box);
|
self._refresh(self);
|
||||||
}]],
|
}]],
|
||||||
}),
|
}),
|
||||||
})],
|
})],
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Gtk from 'gi://Gtk';
|
||||||
import GLib from 'gi://GLib';
|
import GLib from 'gi://GLib';
|
||||||
const { DateTime } = GLib;
|
const { DateTime } = GLib;
|
||||||
|
|
||||||
import { PopupWindow } from './misc/popup.js';
|
import PopupWindow from './misc/popup.js';
|
||||||
|
|
||||||
|
|
||||||
const Divider = () => Box({
|
const Divider = () => Box({
|
||||||
|
@ -27,8 +27,8 @@ const Time = () => Box({
|
||||||
Label({
|
Label({
|
||||||
className: 'content',
|
className: 'content',
|
||||||
label: 'hour',
|
label: 'hour',
|
||||||
connections: [[1000, label => {
|
connections: [[1000, self => {
|
||||||
label.label = DateTime.new_now_local().format('%H');
|
self.label = DateTime.new_now_local().format('%H');
|
||||||
}]],
|
}]],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ const Time = () => Box({
|
||||||
Label({
|
Label({
|
||||||
className: 'content',
|
className: 'content',
|
||||||
label: 'minute',
|
label: 'minute',
|
||||||
connections: [[1000, label => {
|
connections: [[1000, self => {
|
||||||
label.label = DateTime.new_now_local().format('%M');
|
self.label = DateTime.new_now_local().format('%M');
|
||||||
}]],
|
}]],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -51,9 +51,11 @@ const Time = () => Box({
|
||||||
child: Label({
|
child: Label({
|
||||||
style: 'font-size: 20px',
|
style: 'font-size: 20px',
|
||||||
label: 'complete date',
|
label: 'complete date',
|
||||||
connections: [[1000, label => {
|
connections: [[1000, self => {
|
||||||
var time = DateTime.new_now_local();
|
var time = DateTime.new_now_local();
|
||||||
label.label = time.format("%A, %B ") + time.get_day_of_month() + time.format(", %Y");
|
self.label = time.format("%A, %B ") +
|
||||||
|
time.get_day_of_month() +
|
||||||
|
time.format(", %Y");
|
||||||
}]],
|
}]],
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
@ -68,7 +70,6 @@ const CalendarWidget = () => Box({
|
||||||
showDayNames: true,
|
showDayNames: true,
|
||||||
showHeading: true,
|
showHeading: true,
|
||||||
className: 'cal',
|
className: 'cal',
|
||||||
connections: [/* */]
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,12 @@ const OFFSCREEN = 500;
|
||||||
const TRANSITION = 'transition: margin 0.5s ease, opacity 3s ease;';
|
const TRANSITION = 'transition: margin 0.5s ease, opacity 3s ease;';
|
||||||
|
|
||||||
|
|
||||||
export default ({ properties, connections, params } = {}) => {
|
export default ({ properties, connections, props } = {}) => {
|
||||||
let widget = EventBox();
|
let widget = EventBox();
|
||||||
let gesture = Gtk.GestureDrag.new(widget)
|
let gesture = Gtk.GestureDrag.new(widget)
|
||||||
|
|
||||||
widget.child = Overlay({
|
widget.child = Overlay({
|
||||||
...params,
|
...props,
|
||||||
properties: [
|
properties: [
|
||||||
...properties,
|
...properties,
|
||||||
['dragging', false],
|
['dragging', false],
|
||||||
|
|
|
@ -5,8 +5,8 @@ const { execAsync, lookUpIcon } = Utils;
|
||||||
import Gdk from 'gi://Gdk';
|
import Gdk from 'gi://Gdk';
|
||||||
const display = Gdk.Display.get_default();
|
const display = Gdk.Display.get_default();
|
||||||
|
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import Separator from '../misc/separator.js';
|
||||||
import { Separator } from '../misc/separator.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
const icons = {
|
const icons = {
|
||||||
mpris: {
|
mpris: {
|
||||||
|
@ -29,34 +29,35 @@ const icons = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const CoverArt = (player, params) => CenterBox({
|
export const CoverArt = (player, props) => CenterBox({
|
||||||
...params,
|
...props,
|
||||||
vertical: true,
|
vertical: true,
|
||||||
properties: [['bgStyle', '']],
|
properties: [['bgStyle', '']],
|
||||||
connections: [
|
connections: [[player, self => {
|
||||||
[player, box => {
|
execAsync(['bash', '-c', `[[ -f "${player.coverPath}" ]] &&
|
||||||
execAsync(['bash', '-c', `[[ -f "${player.coverPath}" ]] && coloryou "${player.coverPath}" | grep -v Warning`])
|
coloryou "${player.coverPath}" | grep -v Warning`])
|
||||||
.then(out => {
|
.then(out => {
|
||||||
if (!Mpris.players.find(p => player === p))
|
if (!Mpris.players.find(p => player === p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
player.colors.value = JSON.parse(out);
|
player.colors.value = JSON.parse(out);
|
||||||
|
|
||||||
box._bgStyle = `background: radial-gradient(circle,
|
self._bgStyle = `background: radial-gradient(circle,
|
||||||
rgba(0, 0, 0, 0.4) 30%,
|
rgba(0, 0, 0, 0.4) 30%,
|
||||||
${player.colors.value.imageAccent}),
|
${player.colors.value.imageAccent}),
|
||||||
url("${player.coverPath}");
|
url("${player.coverPath}");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;`;
|
background-position: center;`;
|
||||||
if (!box.get_parent()._dragging)
|
|
||||||
box.setStyle(box._bgStyle);
|
if (!self.get_parent()._dragging)
|
||||||
}).catch(err => { if (err !== "") print(err) });
|
self.setStyle(self._bgStyle);
|
||||||
}],
|
|
||||||
],
|
}).catch(err => {if (err !== "") print(err)});
|
||||||
|
}]],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const TitleLabel = (player, params) => Label({
|
export const TitleLabel = (player, props) => Label({
|
||||||
...params,
|
...props,
|
||||||
xalign: 0,
|
xalign: 0,
|
||||||
maxWidthChars: 40,
|
maxWidthChars: 40,
|
||||||
truncate: 'end',
|
truncate: 'end',
|
||||||
|
@ -65,8 +66,8 @@ export const TitleLabel = (player, params) => Label({
|
||||||
binds: [['label', player, 'track-title']],
|
binds: [['label', player, 'track-title']],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ArtistLabel = (player, params) => Label({
|
export const ArtistLabel = (player, props) => Label({
|
||||||
...params,
|
...props,
|
||||||
xalign: 0,
|
xalign: 0,
|
||||||
maxWidthChars: 40,
|
maxWidthChars: 40,
|
||||||
truncate: 'end',
|
truncate: 'end',
|
||||||
|
@ -75,27 +76,29 @@ export const ArtistLabel = (player, params) => Label({
|
||||||
binds: [['label', player, 'track-artists', a => a.join(', ') || '']],
|
binds: [['label', player, 'track-artists', a => a.join(', ') || '']],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PlayerIcon = (player, { symbolic = true, ...params } = {}) => {
|
export const PlayerIcon = (player, { symbolic = true, ...props } = {}) => {
|
||||||
let MainIcon = Icon({
|
let MainIcon = Icon({
|
||||||
...params,
|
...props,
|
||||||
className: 'player-icon',
|
className: 'player-icon',
|
||||||
size: 32,
|
size: 32,
|
||||||
tooltipText: player.identity || '',
|
tooltipText: player.identity || '',
|
||||||
connections: [
|
connections: [[player, self => {
|
||||||
[player, icon => {
|
|
||||||
const name = `${player.entry}${symbolic ? '-symbolic' : ''}`;
|
const name = `${player.entry}${symbolic ? '-symbolic' : ''}`;
|
||||||
lookUpIcon(name) ? icon.icon = name
|
lookUpIcon(name) ? self.icon = name
|
||||||
: icon.icon = icons.mpris.fallback;
|
: self.icon = icons.mpris.fallback;
|
||||||
}],
|
}]],
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return Box({
|
return Box({
|
||||||
connections: [
|
connections: [[Mpris, self => {
|
||||||
[Mpris, box => {
|
let overlays = self.get_parent().get_parent()
|
||||||
let overlays = box.get_parent().get_parent().get_parent().list();
|
.get_parent().list();
|
||||||
let player = overlays.find(overlay => overlay === box.get_parent().get_parent());
|
|
||||||
let index = overlays.indexOf(player)
|
let player = overlays.find(overlay => {
|
||||||
|
overlay === self.get_parent().get_parent();
|
||||||
|
});
|
||||||
|
|
||||||
|
let index = overlays.indexOf(player);
|
||||||
|
|
||||||
let children = [];
|
let children = [];
|
||||||
for (let i = 0; i < overlays.length; ++i) {
|
for (let i = 0; i < overlays.length; ++i) {
|
||||||
|
@ -104,33 +107,34 @@ export const PlayerIcon = (player, { symbolic = true, ...params } = {}) => {
|
||||||
children.push(Separator(2));
|
children.push(Separator(2));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
children.push(Box({ className: 'position-indicator' }));
|
children.push(Box({className: 'position-indicator'}));
|
||||||
children.push(Separator(2));
|
children.push(Separator(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
box.children = children;
|
self.children = children;
|
||||||
}],
|
}]],
|
||||||
],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PositionSlider = (player, params) => EventBox({
|
// FIXME: get the cursors right or just don't display when disabled
|
||||||
|
export const PositionSlider = (player, props) => EventBox({
|
||||||
child: Slider({
|
child: Slider({
|
||||||
...params,
|
...props,
|
||||||
className: 'position-slider',
|
className: 'position-slider',
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
drawValue: false,
|
drawValue: false,
|
||||||
onChange: ({ value }) => {
|
onChange: ({ value }) => {
|
||||||
player.position = player.length * value;
|
player.position = player.length * value;
|
||||||
},
|
},
|
||||||
properties: [
|
properties: [['update', slider => {
|
||||||
['update', slider => {
|
|
||||||
if (slider.dragging) {
|
if (slider.dragging) {
|
||||||
slider.get_parent().window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
|
slider.get_parent().window.set_cursor(Gdk.Cursor
|
||||||
|
.new_from_name(display, 'grabbing'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (slider.get_parent() && slider.get_parent().window) {
|
if (slider.get_parent() && slider.get_parent().window) {
|
||||||
slider.get_parent().window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer'));
|
slider.get_parent().window.set_cursor(Gdk.Cursor
|
||||||
|
.new_from_name(display, 'pointer'));
|
||||||
}
|
}
|
||||||
|
|
||||||
slider.sensitive = player.length > 0;
|
slider.sensitive = player.length > 0;
|
||||||
|
@ -138,17 +142,17 @@ export const PositionSlider = (player, params) => EventBox({
|
||||||
slider.value = player.position / player.length;
|
slider.value = player.position / player.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}],
|
}]],
|
||||||
],
|
|
||||||
connections: [
|
connections: [
|
||||||
[player, s => s._update(s), 'position'],
|
[player, s => s._update(s), 'position'],
|
||||||
[1000, s => s._update(s)],
|
[1000, s => s._update(s)],
|
||||||
[player.colors, s => {
|
[player.colors, s => {
|
||||||
if (player.colors.value)
|
let c = player.colors.value;
|
||||||
s.setCss(`highlight { background-color: ${player.colors.value.buttonAccent}; }
|
if (c)
|
||||||
slider { background-color: ${player.colors.value.buttonAccent}; }
|
s.setCss(`highlight { background-color: ${c.buttonAccent}; }
|
||||||
slider:hover { background-color: ${player.colors.value.hoverAccent}; }
|
slider { background-color: ${c.buttonAccent}; }
|
||||||
trough { background-color: ${player.colors.value.buttonText}; }`);
|
slider:hover { background-color: ${c.hoverAccent}; }
|
||||||
|
trough { background-color: ${c.buttonText}; }`);
|
||||||
}],
|
}],
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
@ -162,9 +166,9 @@ function lengthStr(length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PositionLabel = player => Label({
|
export const PositionLabel = player => Label({
|
||||||
properties: [['update', label => {
|
properties: [['update', self => {
|
||||||
player.length > 0 ? label.label = lengthStr(player.position)
|
player.length > 0 ? self.label = lengthStr(player.position)
|
||||||
: label.visible = !!player;
|
: self.visible = !!player;
|
||||||
}]],
|
}]],
|
||||||
connections: [
|
connections: [
|
||||||
[player, l => l._update(l), 'position'],
|
[player, l => l._update(l), 'position'],
|
||||||
|
@ -173,16 +177,16 @@ export const PositionLabel = player => Label({
|
||||||
});
|
});
|
||||||
|
|
||||||
export const LengthLabel = player => Label({
|
export const LengthLabel = player => Label({
|
||||||
connections: [[player, label => {
|
connections: [[player, self => {
|
||||||
player.length > 0 ? label.label = lengthStr(player.length)
|
player.length > 0 ? self.label = lengthStr(player.length)
|
||||||
: label.visible = !!player;
|
: self.visible = !!player;
|
||||||
}]],
|
}]],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Slash = player => Label({
|
export const Slash = player => Label({
|
||||||
label: '/',
|
label: '/',
|
||||||
connections: [[player, label => {
|
connections: [[player, self => {
|
||||||
label.visible = player.length > 0;
|
self.visible = player.length > 0;
|
||||||
}]],
|
}]],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -191,13 +195,13 @@ const PlayerButton = ({ player, items, onClick, prop }) => Button({
|
||||||
child: Stack({ items }),
|
child: Stack({ items }),
|
||||||
onPrimaryClickRelease: () => player[onClick](),
|
onPrimaryClickRelease: () => player[onClick](),
|
||||||
properties: [['hovered', false]],
|
properties: [['hovered', false]],
|
||||||
onHover: box => {
|
onHover: self => {
|
||||||
box._hovered = true;
|
self._hovered = true;
|
||||||
if (! box.child.sensitive || ! box.sensitive) {
|
if (! self.child.sensitive || ! self.sensitive) {
|
||||||
box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed'));
|
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer'));
|
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prop == 'playBackStatus') {
|
if (prop == 'playBackStatus') {
|
||||||
|
@ -209,9 +213,9 @@ const PlayerButton = ({ player, items, onClick, prop }) => Button({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onHoverLost: box => {
|
onHoverLost: self => {
|
||||||
box._hovered = false;
|
self._hovered = false;
|
||||||
box.window.set_cursor(null);
|
self.window.set_cursor(null);
|
||||||
if (prop == 'playBackStatus') {
|
if (prop == 'playBackStatus') {
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
item[1].setStyle(`background-color: ${player.colors.value.buttonAccent};
|
item[1].setStyle(`background-color: ${player.colors.value.buttonAccent};
|
||||||
|
|
|
@ -3,7 +3,9 @@ const { Box, CenterBox, Label } = Widget;
|
||||||
|
|
||||||
import * as mpris from './mpris.js';
|
import * as mpris from './mpris.js';
|
||||||
import PlayerGesture from './gesture.js';
|
import PlayerGesture from './gesture.js';
|
||||||
import { Separator } from '../misc/separator.js';
|
import Separator from '../misc/separator.js';
|
||||||
|
|
||||||
|
const FAVE_PLAYER = 'org.mpris.MediaPlayer2.spotify';
|
||||||
|
|
||||||
|
|
||||||
const Top = player => Box({
|
const Top = player => Box({
|
||||||
|
@ -56,20 +58,22 @@ const Center = player => Box({
|
||||||
const Bottom = player => Box({
|
const Bottom = player => Box({
|
||||||
className: 'bottom',
|
className: 'bottom',
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
mpris.PreviousButton(player, {
|
mpris.PreviousButton(player, {
|
||||||
valign: 'end',
|
valign: 'end',
|
||||||
halign: 'start',
|
halign: 'start',
|
||||||
}),
|
}),
|
||||||
Separator(8),
|
Separator(8),
|
||||||
|
|
||||||
mpris.PositionSlider(player),
|
mpris.PositionSlider(player),
|
||||||
Separator(8),
|
Separator(8),
|
||||||
|
|
||||||
mpris.NextButton(player),
|
mpris.NextButton(player),
|
||||||
Separator(8),
|
Separator(8),
|
||||||
|
|
||||||
mpris.ShuffleButton(player),
|
mpris.ShuffleButton(player),
|
||||||
Separator(8),
|
Separator(8),
|
||||||
mpris.LoopButton(player),
|
|
||||||
|
|
||||||
|
mpris.LoopButton(player),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -98,11 +102,13 @@ export default () => Box({
|
||||||
|
|
||||||
if (!busName) {
|
if (!busName) {
|
||||||
let player = Mpris.players.find(p => !overlay._players.has(p.busName));
|
let player = Mpris.players.find(p => !overlay._players.has(p.busName));
|
||||||
if (player)
|
if (player) {
|
||||||
busName = player.busName;
|
busName = player.busName;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const player = Mpris.getPlayer(busName);
|
const player = Mpris.getPlayer(busName);
|
||||||
player.colors = Variable();
|
player.colors = Variable();
|
||||||
|
@ -115,18 +121,20 @@ export default () => Box({
|
||||||
|
|
||||||
overlay.overlays = result;
|
overlay.overlays = result;
|
||||||
|
|
||||||
// Favor spotify
|
// Select favorite player at startup
|
||||||
if (!overlay._setup) {
|
if (!overlay._setup) {
|
||||||
if (overlay._players.has('org.mpris.MediaPlayer2.spotify')) {
|
if (overlay._players.has(FAVE_PLAYER)) {
|
||||||
overlay._selected = overlay._players.get('org.mpris.MediaPlayer2.spotify');
|
overlay._selected = overlay._players.get(FAVE_PLAYER);
|
||||||
}
|
}
|
||||||
overlay._setup = true;
|
overlay._setup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overlay._selected)
|
if (overlay._selected)
|
||||||
overlay.reorder_overlay(overlay._selected, -1);
|
overlay.reorder_overlay(overlay._selected, -1);
|
||||||
|
|
||||||
}, 'player-added'],
|
}, 'player-added'],
|
||||||
|
|
||||||
|
|
||||||
[Mpris, (overlay, busName) => {
|
[Mpris, (overlay, busName) => {
|
||||||
if (!busName || !overlay._players.has(busName))
|
if (!busName || !overlay._players.has(busName))
|
||||||
return;
|
return;
|
||||||
|
@ -141,6 +149,7 @@ export default () => Box({
|
||||||
overlay.overlays = result;
|
overlay.overlays = result;
|
||||||
if (overlay._selected)
|
if (overlay._selected)
|
||||||
overlay.reorder_overlay(overlay._selected, -1);
|
overlay.reorder_overlay(overlay._selected, -1);
|
||||||
|
|
||||||
}, 'player-closed'],
|
}, 'player-closed'],
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -21,7 +21,7 @@ const closeAll = () => {
|
||||||
});
|
});
|
||||||
App.closeWindow('closer');
|
App.closeWindow('closer');
|
||||||
};
|
};
|
||||||
globalThis.closeAll = () => closeAll();
|
globalThis.closeAll = closeAll;
|
||||||
|
|
||||||
Pointers.connect('new-line', (_, out) => {
|
Pointers.connect('new-line', (_, out) => {
|
||||||
if (out) {
|
if (out) {
|
||||||
|
|
|
@ -4,34 +4,43 @@ import Gdk from 'gi://Gdk';
|
||||||
const display = Gdk.Display.get_default();
|
const display = Gdk.Display.get_default();
|
||||||
|
|
||||||
|
|
||||||
export const EventBox = ({ reset = true, ...params }) => Widget.EventBox({
|
export default ({
|
||||||
...params,
|
type = "EventBox",
|
||||||
onHover: box => {
|
reset = true,
|
||||||
if (! box.child.sensitive || ! box.sensitive) {
|
...props
|
||||||
box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed'));
|
}) => {
|
||||||
|
if (type === "EventBox") {
|
||||||
|
return Widget.EventBox({
|
||||||
|
...props,
|
||||||
|
onHover: self => {
|
||||||
|
if (!self.child.sensitive || !self.sensitive) {
|
||||||
|
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer'));
|
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onHoverLost: box => {
|
onHoverLost: self => {
|
||||||
if (reset)
|
if (reset)
|
||||||
box.window.set_cursor(null);
|
self.window.set_cursor(null);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Button = ({ reset = true, ...params }) => Widget.Button({
|
|
||||||
...params,
|
|
||||||
onHover: box => {
|
|
||||||
if (! box.child.sensitive || ! box.sensitive) {
|
|
||||||
box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed'));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer'));
|
return Widget.Button({
|
||||||
|
...props,
|
||||||
|
onHover: self => {
|
||||||
|
if (!self.child.sensitive || !self.sensitive) {
|
||||||
|
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onHoverLost: box => {
|
onHoverLost: self => {
|
||||||
if (reset)
|
if (reset)
|
||||||
box.window.set_cursor(null);
|
self.window.set_cursor(null);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,26 +2,29 @@ import { App, Widget } from '../../imports.js';
|
||||||
const { Revealer, Box, Window } = Widget;
|
const { Revealer, Box, Window } = Widget;
|
||||||
|
|
||||||
|
|
||||||
export const PopupWindow = ({
|
export default ({
|
||||||
name,
|
name,
|
||||||
child,
|
child,
|
||||||
transition = 'slide_down',
|
transition = 'slide_down',
|
||||||
...params
|
onOpen = rev => {},
|
||||||
}) => Window({
|
...props
|
||||||
|
}) => {
|
||||||
|
let window = Window({
|
||||||
name,
|
name,
|
||||||
popup: true,
|
popup: true,
|
||||||
visible: false,
|
visible: false,
|
||||||
layer: 'overlay',
|
layer: 'overlay',
|
||||||
...params,
|
...props,
|
||||||
|
|
||||||
child: Box({
|
child: Box({
|
||||||
style: 'min-height:1px; min-width:1px',
|
style: 'min-height:1px; min-width:1px',
|
||||||
child: Revealer({
|
child: Revealer({
|
||||||
transition,
|
transition,
|
||||||
transitionDuration: 500,
|
transitionDuration: 500,
|
||||||
connections: [[App, (revealer, currentName, visible) => {
|
connections: [[App, (rev, currentName, visible) => {
|
||||||
if (currentName === name) {
|
if (currentName === name) {
|
||||||
revealer.reveal_child = visible;
|
rev.reveal_child = visible;
|
||||||
|
onOpen(child);
|
||||||
|
|
||||||
if (visible && name !== 'overview')
|
if (visible && name !== 'overview')
|
||||||
App.openWindow('closer');
|
App.openWindow('closer');
|
||||||
|
@ -30,4 +33,7 @@ export const PopupWindow = ({
|
||||||
child: child,
|
child: child,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
window.getChild = () => child;
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,15 @@ import { Widget } from '../../imports.js';
|
||||||
const { Box } = Widget;
|
const { Box } = Widget;
|
||||||
|
|
||||||
|
|
||||||
export const Separator = width => Box({
|
export default (size, { vertical = false } = {}) => {
|
||||||
style: `min-width: ${width}px;`,
|
if (vertical) {
|
||||||
});
|
return Box({
|
||||||
|
style: `min-height: ${size}px;`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Box({
|
||||||
|
style: `min-width: ${size}px;`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,8 +4,17 @@ const { Box, Icon, Label, Button } = Widget;
|
||||||
|
|
||||||
import GLib from 'gi://GLib';
|
import GLib from 'gi://GLib';
|
||||||
|
|
||||||
|
const setTime = time => {
|
||||||
|
return GLib.DateTime
|
||||||
|
.new_from_unix_local(time)
|
||||||
|
.format('%H:%M');
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDragState = box => box.get_parent().get_parent()
|
||||||
|
.get_parent().get_parent().get_parent()._dragging;
|
||||||
|
|
||||||
import Gesture from './gesture.js';
|
import Gesture from './gesture.js';
|
||||||
import { EventBox } from '../misc/cursorbox.js'
|
import EventBox from '../misc/cursorbox.js'
|
||||||
|
|
||||||
|
|
||||||
const NotificationIcon = notif => {
|
const NotificationIcon = notif => {
|
||||||
|
@ -14,19 +23,19 @@ const NotificationIcon = notif => {
|
||||||
if (Applications.query(notif.appEntry).length > 0) {
|
if (Applications.query(notif.appEntry).length > 0) {
|
||||||
let app = Applications.query(notif.appEntry)[0];
|
let app = Applications.query(notif.appEntry)[0];
|
||||||
|
|
||||||
if (app.app.get_string('StartupWMClass') != null) {
|
let wmClass = app.app.get_string('StartupWMClass');
|
||||||
|
if (app.app.get_filename().includes('discord'))
|
||||||
|
wmClass = 'discord';
|
||||||
|
|
||||||
|
if (wmClass != null) {
|
||||||
iconCmd = box => {
|
iconCmd = box => {
|
||||||
if (!box.get_parent().get_parent().get_parent().get_parent().get_parent()._dragging) {
|
if (!getDragState(box)) {
|
||||||
execAsync(['bash', '-c', `$AGS_PATH/launch-app.sh ${app.app.get_string('StartupWMClass')} ${app.app.get_string('Exec')}`]).catch(print);
|
execAsync(['bash', '-c',
|
||||||
globalThis.closeAll();
|
`$AGS_PATH/launch-app.sh
|
||||||
}
|
${wmClass}
|
||||||
}
|
${app.app.get_string('Exec')}`
|
||||||
}
|
]).catch(print);
|
||||||
else if (app.app.get_filename().includes('discord')) {
|
|
||||||
iconCmd = box => {
|
|
||||||
if (!box.get_parent().get_parent().get_parent().get_parent().get_parent()._dragging) {
|
|
||||||
execAsync(['bash', '-c', `$AGS_PATH/launch-app.sh discord ${app.app.get_string('Exec')}`])
|
|
||||||
.catch(print);
|
|
||||||
globalThis.closeAll();
|
globalThis.closeAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +91,7 @@ const NotificationIcon = notif => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ({ notif, command = () => {}} = {}) => {
|
export default ({ notif, command = () => {}, } = {}) => {
|
||||||
const BlockedApps = [
|
const BlockedApps = [
|
||||||
'Spotify',
|
'Spotify',
|
||||||
];
|
];
|
||||||
|
@ -142,7 +151,7 @@ export default ({ notif, command = () => {}} = {}) => {
|
||||||
Label({
|
Label({
|
||||||
className: 'time',
|
className: 'time',
|
||||||
valign: 'start',
|
valign: 'start',
|
||||||
label: GLib.DateTime.new_from_unix_local(notif.time).format('%H:%M'),
|
label: setTime(notif.time),
|
||||||
}),
|
}),
|
||||||
EventBox({
|
EventBox({
|
||||||
reset: false,
|
reset: false,
|
||||||
|
|
|
@ -3,23 +3,30 @@ const { Button, Label, Box, Icon, Scrollable, Revealer } = Widget;
|
||||||
const { timeout } = Utils;
|
const { timeout } = Utils;
|
||||||
|
|
||||||
import Notification from './base.js';
|
import Notification from './base.js';
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import PopupWindow from '../misc/popup.js';
|
||||||
import { PopupWindow } from '../misc/popup.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
const ClearButton = () => EventBox({
|
const ClearButton = () => EventBox({
|
||||||
child: Button({
|
child: Button({
|
||||||
onPrimaryClickRelease: button => {
|
onPrimaryClickRelease: button => {
|
||||||
button._popups.children.forEach(ch => ch.child.setStyle(ch.child._leftAnim1));
|
button._popups.children.forEach(ch => {
|
||||||
|
ch.child.setStyle(ch.child._leftAnim1);
|
||||||
|
});
|
||||||
|
|
||||||
button._notifList.children.forEach(ch => {
|
button._notifList.children.forEach(ch => {
|
||||||
|
if (ch.child)
|
||||||
ch.child.setStyle(ch.child._rightAnim1);
|
ch.child.setStyle(ch.child._rightAnim1);
|
||||||
timeout(500, () => {
|
timeout(500, () => {
|
||||||
button._notifList.remove(ch);
|
button._notifList.remove(ch);
|
||||||
Notifications.notifications.forEach(n => n.close());
|
Notifications.clear();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
properties: [['notifList'], ['popups']],
|
properties: [
|
||||||
|
['notifList'],
|
||||||
|
['popups'],
|
||||||
|
],
|
||||||
connections: [[Notifications, button => {
|
connections: [[Notifications, button => {
|
||||||
if (!button._notifList)
|
if (!button._notifList)
|
||||||
button._notifList = NotificationList;
|
button._notifList = NotificationList;
|
||||||
|
@ -33,8 +40,8 @@ const ClearButton = () => EventBox({
|
||||||
children: [
|
children: [
|
||||||
Label('Clear '),
|
Label('Clear '),
|
||||||
Icon({
|
Icon({
|
||||||
connections: [[Notifications, icon => {
|
connections: [[Notifications, self => {
|
||||||
icon.icon = Notifications.notifications.length > 0
|
self.icon = Notifications.notifications.length > 0
|
||||||
? 'user-trash-full-symbolic' : 'user-trash-symbolic';
|
? 'user-trash-full-symbolic' : 'user-trash-symbolic';
|
||||||
}]],
|
}]],
|
||||||
}),
|
}),
|
||||||
|
@ -46,7 +53,11 @@ const ClearButton = () => EventBox({
|
||||||
const Header = () => Box({
|
const Header = () => Box({
|
||||||
className: 'header',
|
className: 'header',
|
||||||
children: [
|
children: [
|
||||||
Label({ label: 'Notifications', hexpand: true, xalign: 0 }),
|
Label({
|
||||||
|
label: 'Notifications',
|
||||||
|
hexpand: true,
|
||||||
|
xalign: 0,
|
||||||
|
}),
|
||||||
ClearButton(),
|
ClearButton(),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -110,14 +121,15 @@ const Placeholder = () => Revealer({
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const NotificationCenterWidget = Box({
|
const NotificationCenterWidget = () => Box({
|
||||||
className: 'notification-center',
|
className: 'notification-center',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
children: [
|
children: [
|
||||||
Header(),
|
Header(),
|
||||||
Box({
|
Box({
|
||||||
className: 'notification-wallpaper-box',
|
className: 'notification-wallpaper-box',
|
||||||
children: [Scrollable({
|
children: [
|
||||||
|
Scrollable({
|
||||||
className: 'notification-list-box',
|
className: 'notification-list-box',
|
||||||
hscroll: 'never',
|
hscroll: 'never',
|
||||||
vscroll: 'automatic',
|
vscroll: 'automatic',
|
||||||
|
@ -129,7 +141,8 @@ const NotificationCenterWidget = Box({
|
||||||
Placeholder(),
|
Placeholder(),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
})],
|
})
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -138,5 +151,5 @@ export default () => PopupWindow({
|
||||||
name: 'notification-center',
|
name: 'notification-center',
|
||||||
anchor: [ 'top', 'right' ],
|
anchor: [ 'top', 'right' ],
|
||||||
margin: [ 8, 60, 0, 0 ],
|
margin: [ 8, 60, 0, 0 ],
|
||||||
child: NotificationCenterWidget,
|
child: NotificationCenterWidget(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,25 +16,25 @@ export default ({
|
||||||
child = '',
|
child = '',
|
||||||
children = [],
|
children = [],
|
||||||
properties = [[]],
|
properties = [[]],
|
||||||
...params
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
let w = EventBox({
|
let widget = EventBox({
|
||||||
...params,
|
...props,
|
||||||
properties: [
|
properties: [
|
||||||
['dragging', false],
|
['dragging', false],
|
||||||
...properties,
|
...properties,
|
||||||
],
|
],
|
||||||
onHover: box => {
|
onHover: self => {
|
||||||
box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
||||||
onHover(box);
|
onHover(self);
|
||||||
},
|
},
|
||||||
onHoverLost: box => {
|
onHoverLost: self => {
|
||||||
box.window.set_cursor(null);
|
self.window.set_cursor(null);
|
||||||
onHoverLost(box);
|
onHoverLost(self);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let gesture = Gtk.GestureDrag.new(w);
|
let gesture = Gtk.GestureDrag.new(widget);
|
||||||
|
|
||||||
let leftAnim1 = `transition: margin 0.5s ease, opacity 0.5s ease;
|
let leftAnim1 = `transition: margin 0.5s ease, opacity 0.5s ease;
|
||||||
margin-left: -${Number(maxOffset + endMargin)}px;
|
margin-left: -${Number(maxOffset + endMargin)}px;
|
||||||
|
@ -56,7 +56,7 @@ export default ({
|
||||||
margin-right: -${Number(maxOffset + endMargin)}px;
|
margin-right: -${Number(maxOffset + endMargin)}px;
|
||||||
margin-bottom: -70px; margin-top: -70px; opacity: 0;`;
|
margin-bottom: -70px; margin-top: -70px; opacity: 0;`;
|
||||||
|
|
||||||
w.child = Box({
|
widget.child = Box({
|
||||||
properties: [
|
properties: [
|
||||||
['leftAnim1', leftAnim1],
|
['leftAnim1', leftAnim1],
|
||||||
['leftAnim2', leftAnim2],
|
['leftAnim2', leftAnim2],
|
||||||
|
@ -71,39 +71,39 @@ export default ({
|
||||||
style: leftAnim2,
|
style: leftAnim2,
|
||||||
connections: [
|
connections: [
|
||||||
|
|
||||||
[gesture, box => {
|
[gesture, self => {
|
||||||
var offset = gesture.get_offset()[1];
|
var offset = gesture.get_offset()[1];
|
||||||
|
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
box.setStyle('margin-left: ' + Number(offset + startMargin) + 'px; ' +
|
self.setStyle(`margin-left: ${Number(offset + startMargin)}px;
|
||||||
'margin-right: -' + Number(offset + startMargin) + 'px;');
|
margin-right: -${Number(offset + startMargin)}px;`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
offset = Math.abs(offset);
|
offset = Math.abs(offset);
|
||||||
box.setStyle('margin-right: ' + Number(offset + startMargin) + 'px; ' +
|
self.setStyle(`margin-right: ${Number(offset + startMargin)}px;
|
||||||
'margin-left: -' + Number(offset + startMargin) + 'px;');
|
margin-left: -${Number(offset + startMargin)}px;`);
|
||||||
}
|
}
|
||||||
|
|
||||||
box.get_parent()._dragging = Math.abs(offset) > 10;
|
self.get_parent()._dragging = Math.abs(offset) > 10;
|
||||||
|
|
||||||
if (w.window)
|
if (widget.window)
|
||||||
w.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
|
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
|
||||||
}, 'drag-update'],
|
}, 'drag-update'],
|
||||||
|
|
||||||
[gesture, box => {
|
[gesture, self => {
|
||||||
if (!box._ready) {
|
if (!self._ready) {
|
||||||
box.setStyle(`transition: margin 0.5s ease, opacity 0.5s ease;
|
self.setStyle(`transition: margin 0.5s ease, opacity 0.5s ease;
|
||||||
margin-left: -${Number(maxOffset + endMargin)}px;
|
margin-left: -${Number(maxOffset + endMargin)}px;
|
||||||
margin-right: ${Number(maxOffset + endMargin)}px;
|
margin-right: ${Number(maxOffset + endMargin)}px;
|
||||||
margin-bottom: 0px; margin-top: 0px; opacity: 0;`);
|
margin-bottom: 0px; margin-top: 0px; opacity: 0;`);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
box.setStyle('transition: margin 0.5s ease, opacity 0.5s ease; ' +
|
self.setStyle(`transition: margin 0.5s ease, opacity 0.5s ease;
|
||||||
'margin-left: ' + startMargin + 'px; ' +
|
margin-left: ${startMargin}px;
|
||||||
'margin-right: ' + startMargin + 'px; ' +
|
margin-right: ${startMargin}px;
|
||||||
'margin-bottom: unset; margin-top: unset; opacity: 1;');
|
margin-bottom: unset; margin-top: unset; opacity: 1;`);
|
||||||
}, 500);
|
}, 500);
|
||||||
setTimeout(() => box._ready = true, 1000);
|
setTimeout(() => self._ready = true, 1000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,32 +111,32 @@ export default ({
|
||||||
|
|
||||||
if (Math.abs(offset) > maxOffset) {
|
if (Math.abs(offset) > maxOffset) {
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
box.setStyle(rightAnim1);
|
self.setStyle(rightAnim1);
|
||||||
setTimeout(() => box.setStyle(rightAnim2), 500);
|
setTimeout(() => self.setStyle(rightAnim2), 500);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
box.setStyle(leftAnim1);
|
self.setStyle(leftAnim1);
|
||||||
setTimeout(() => box.setStyle(leftAnim2), 500);
|
setTimeout(() => self.setStyle(leftAnim2), 500);
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
command();
|
command();
|
||||||
box.destroy();
|
self.destroy();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
box.setStyle('transition: margin 0.5s ease, opacity 0.5s ease; ' +
|
self.setStyle(`transition: margin 0.5s ease, opacity 0.5s ease;
|
||||||
'margin-left: ' + startMargin + 'px; ' +
|
margin-left: ${startMargin}px;
|
||||||
'margin-right: ' + startMargin + 'px; ' +
|
margin-right: ${startMargin}px;
|
||||||
'margin-bottom: unset; margin-top: unset; opacity: 1;');
|
margin-bottom: unset; margin-top: unset; opacity: 1;`);
|
||||||
if (w.window)
|
if (widget.window)
|
||||||
w.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
|
||||||
|
|
||||||
box.get_parent()._dragging = false;
|
self.get_parent()._dragging = false;
|
||||||
}
|
}
|
||||||
}, 'drag-end'],
|
}, 'drag-end'],
|
||||||
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
return w;
|
return widget;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,12 +8,13 @@ const Popups = () => Box({
|
||||||
vertical: true,
|
vertical: true,
|
||||||
properties: [
|
properties: [
|
||||||
['map', new Map()],
|
['map', new Map()],
|
||||||
['dismiss', (box, id, force = false) => {
|
|
||||||
if (!id || !box._map.has(id))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (box._map.get(id)._hovered && !force)
|
['dismiss', (box, id, force = false) => {
|
||||||
|
if (!id || !box._map.has(id) ||
|
||||||
|
box._map.get(id)._hovered && !force) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (box._map.size - 1 === 0)
|
if (box._map.size - 1 === 0)
|
||||||
box.get_parent().reveal_child = false;
|
box.get_parent().reveal_child = false;
|
||||||
|
@ -27,6 +28,7 @@ const Popups = () => Box({
|
||||||
box._map.delete(id);
|
box._map.delete(id);
|
||||||
}, 200);
|
}, 200);
|
||||||
}],
|
}],
|
||||||
|
|
||||||
['notify', (box, id) => {
|
['notify', (box, id) => {
|
||||||
if (!id || Notifications.dnd)
|
if (!id || Notifications.dnd)
|
||||||
return;
|
return;
|
||||||
|
@ -43,11 +45,12 @@ const Popups = () => Box({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
box.children = Array.from(box._map.values()).reverse();
|
box.children = Array.from(box._map.values()).reverse();
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
box.get_parent().revealChild = true;
|
box.get_parent().revealChild = true;
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
box._map.get(id).interval = setInterval(() => {
|
box._map.get(id).interval = setInterval(() => {
|
||||||
print('interval')
|
|
||||||
if (!box._map.get(id)._hovered) {
|
if (!box._map.get(id)._hovered) {
|
||||||
box._map.get(id).child.setStyle(box._map.get(id).child._leftAnim1);
|
box._map.get(id).child.setStyle(box._map.get(id).child._leftAnim1);
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,12 @@ const { execAsync } = Utils;
|
||||||
import { WindowButton } from './dragndrop.js';
|
import { WindowButton } from './dragndrop.js';
|
||||||
import * as VARS from './variables.js';
|
import * as VARS from './variables.js';
|
||||||
|
|
||||||
|
// Has to be a traditional function for 'this' scope
|
||||||
Array.prototype.remove = function (el) { this.splice(this.indexOf(el), 1) };
|
Array.prototype.remove = function (el) { this.splice(this.indexOf(el), 1) };
|
||||||
|
|
||||||
const scale = size => size * VARS.SCALE - VARS.MARGIN;
|
const scale = size => size * VARS.SCALE - VARS.MARGIN;
|
||||||
const getFontSize = client => Math.min(scale(client.size[0]), scale(client.size[1])) * VARS.ICON_SCALE;
|
const getFontSize = client => Math.min(scale(client.size[0]),
|
||||||
|
scale(client.size[1])) * VARS.ICON_SCALE;
|
||||||
|
|
||||||
const IconStyle = client => `transition: font-size 0.2s linear;
|
const IconStyle = client => `transition: font-size 0.2s linear;
|
||||||
min-width: ${scale(client.size[0])}px;
|
min-width: ${scale(client.size[0])}px;
|
||||||
|
@ -31,14 +33,22 @@ const Client = (client, active, clients) => {
|
||||||
],
|
],
|
||||||
child: WindowButton({
|
child: WindowButton({
|
||||||
address: client.address,
|
address: client.address,
|
||||||
onSecondaryClickRelease: () => execAsync(`hyprctl dispatch closewindow ${addr}`).catch(print),
|
onSecondaryClickRelease: () => {
|
||||||
|
execAsync(`hyprctl dispatch closewindow ${addr}`)
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
|
|
||||||
onPrimaryClickRelease: () => {
|
onPrimaryClickRelease: () => {
|
||||||
if (wsId < 0) {
|
if (wsId < 0) {
|
||||||
if (client.workspace.name === 'special') {
|
if (client.workspace.name === 'special') {
|
||||||
execAsync(`hyprctl dispatch movetoworkspacesilent special:${wsId},${addr}`).then(
|
execAsync(`hyprctl dispatch
|
||||||
|
movetoworkspacesilent special:${wsId},${addr}`)
|
||||||
|
.then(
|
||||||
|
|
||||||
execAsync(`hyprctl dispatch togglespecialworkspace ${wsId}`).then(
|
execAsync(`hyprctl dispatch togglespecialworkspace ${wsId}`).then(
|
||||||
() => App.closeWindow('overview')
|
() => App.closeWindow('overview')
|
||||||
).catch(print)
|
).catch(print)
|
||||||
|
|
||||||
).catch(print);
|
).catch(print);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -53,13 +63,15 @@ const Client = (client, active, clients) => {
|
||||||
let currentActive = clients.find(c => c.address === activeAddress)
|
let currentActive = clients.find(c => c.address === activeAddress)
|
||||||
|
|
||||||
if (currentActive && currentActive.workspace.id < 0) {
|
if (currentActive && currentActive.workspace.id < 0) {
|
||||||
execAsync(`hyprctl dispatch togglespecialworkspace ${wsName}`).catch(print);
|
execAsync(`hyprctl dispatch togglespecialworkspace ${wsName}`)
|
||||||
|
.catch(print);
|
||||||
}
|
}
|
||||||
execAsync(`hyprctl dispatch focuswindow ${addr}`).then(
|
execAsync(`hyprctl dispatch focuswindow ${addr}`).then(
|
||||||
() => App.closeWindow('overview')
|
() => App.closeWindow('overview')
|
||||||
).catch(print);
|
).catch(print);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
child: Icon({
|
child: Icon({
|
||||||
className: `window ${active}`,
|
className: `window ${active}`,
|
||||||
style: IconStyle(client) + 'font-size: 10px;',
|
style: IconStyle(client) + 'font-size: 10px;',
|
||||||
|
@ -70,15 +82,15 @@ const Client = (client, active, clients) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function updateClients(box) {
|
export function updateClients(box) {
|
||||||
execAsync('hyprctl clients -j').then(
|
execAsync('hyprctl clients -j').then(out => {
|
||||||
result => {
|
let clients = JSON.parse(out).filter(client => client.class)
|
||||||
let clients = JSON.parse(result).filter(client => client.class)
|
|
||||||
|
|
||||||
box._workspaces.forEach(workspace => {
|
box._workspaces.forEach(workspace => {
|
||||||
let fixed = workspace.child.child.get_children()[2].children[0];
|
let fixed = workspace.getFixed();
|
||||||
let toRemove = fixed.get_children();
|
let toRemove = fixed.get_children();
|
||||||
|
|
||||||
clients.filter(client => client.workspace.id == workspace._id).forEach(client => {
|
clients.filter(client => client.workspace.id == workspace._id)
|
||||||
|
.forEach(client => {
|
||||||
let active = '';
|
let active = '';
|
||||||
if (client.address == Hyprland.active.client.address) {
|
if (client.address == Hyprland.active.client.address) {
|
||||||
active = 'active';
|
active = 'active';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Gtk from 'gi://Gtk';
|
||||||
import Gdk from 'gi://Gdk';
|
import Gdk from 'gi://Gdk';
|
||||||
import Cairo from 'cairo';
|
import Cairo from 'cairo';
|
||||||
|
|
||||||
import { Button } from '../misc/cursorbox.js';
|
import Button from '../misc/cursorbox.js';
|
||||||
import { updateClients } from './clients.js';
|
import { updateClients } from './clients.js';
|
||||||
|
|
||||||
const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)];
|
const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)];
|
||||||
|
@ -29,13 +29,13 @@ function createSurfaceFromWidget(widget) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let hidden = 0;
|
let hidden = 0;
|
||||||
export const WorkspaceDrop = params => EventBox({
|
export const WorkspaceDrop = props => EventBox({
|
||||||
...params,
|
...props,
|
||||||
connections: [['drag-data-received', (eventbox, _c, _x, _y, data) => {
|
connections: [['drag-data-received', (self, _c, _x, _y, data) => {
|
||||||
let id = eventbox.get_parent()._id;
|
let id = self.get_parent()._id;
|
||||||
|
|
||||||
if (id < -1) {
|
if (id < -1) {
|
||||||
id = eventbox.get_parent()._name;
|
id = self.get_parent()._name;
|
||||||
}
|
}
|
||||||
else if (id === -1) {
|
else if (id === -1) {
|
||||||
id = `special:${++hidden}`;
|
id = `special:${++hidden}`;
|
||||||
|
@ -46,26 +46,27 @@ export const WorkspaceDrop = params => EventBox({
|
||||||
execAsync(`hyprctl dispatch movetoworkspacesilent ${id},address:${data.get_text()}`)
|
execAsync(`hyprctl dispatch movetoworkspacesilent ${id},address:${data.get_text()}`)
|
||||||
.catch(print);
|
.catch(print);
|
||||||
}]],
|
}]],
|
||||||
setup: eventbox => {
|
setup: self => {
|
||||||
eventbox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
|
self.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const WindowButton = ({address, ...params} = {}) => Button({
|
export const WindowButton = ({address, ...props} = {}) => Button({
|
||||||
...params,
|
type: "Button",
|
||||||
setup: button => {
|
...props,
|
||||||
button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, TARGET, Gdk.DragAction.COPY);
|
setup: self => {
|
||||||
button.connect('drag-data-get', (_w, _c, data) => {
|
self.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, TARGET, Gdk.DragAction.COPY);
|
||||||
|
self.connect('drag-data-get', (_w, _c, data) => {
|
||||||
data.set_text(address, address.length);
|
data.set_text(address, address.length);
|
||||||
});
|
});
|
||||||
button.connect('drag-begin', (_, context) => {
|
self.connect('drag-begin', (_, context) => {
|
||||||
Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(button));
|
Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(self));
|
||||||
button.get_parent().revealChild = false;
|
self.get_parent().revealChild = false;
|
||||||
});
|
});
|
||||||
button.connect('drag-end', () => {
|
self.connect('drag-end', () => {
|
||||||
button.get_parent().destroy();
|
self.get_parent().destroy();
|
||||||
|
|
||||||
let mainBox = App.getWindow('overview').child.children[0].child;
|
let mainBox = App.getWindow('overview').getChild();
|
||||||
updateClients(mainBox);
|
updateClients(mainBox);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { App, Hyprland, Widget } from '../../imports.js';
|
import { App, Hyprland, Widget } from '../../imports.js';
|
||||||
const { Box } = Widget;
|
const { Box } = Widget;
|
||||||
|
|
||||||
import { PopupWindow } from '../misc/popup.js';
|
import PopupWindow from '../misc/popup.js';
|
||||||
import { WorkspaceRow, getWorkspaces, updateWorkspaces } from './workspaces.js';
|
import { WorkspaceRow, getWorkspaces, updateWorkspaces } from './workspaces.js';
|
||||||
import { updateClients } from './clients.js';
|
import { updateClients } from './clients.js';
|
||||||
|
|
||||||
|
|
||||||
function update(box) {
|
function update(box) {
|
||||||
getWorkspaces(box);
|
getWorkspaces(box);
|
||||||
updateWorkspaces(box);
|
updateWorkspaces(box);
|
||||||
|
@ -14,6 +15,7 @@ function update(box) {
|
||||||
export default () => PopupWindow({
|
export default () => PopupWindow({
|
||||||
name: 'overview',
|
name: 'overview',
|
||||||
transition: 'crossfade',
|
transition: 'crossfade',
|
||||||
|
onOpen: child => update(child),
|
||||||
|
|
||||||
child: Box({
|
child: Box({
|
||||||
className: 'overview',
|
className: 'overview',
|
||||||
|
@ -32,17 +34,12 @@ export default () => PopupWindow({
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
// The timeout is because the list of clients is async
|
connections: [[Hyprland, self => {
|
||||||
setup: box => setTimeout(() => update(box), 100),
|
|
||||||
connections: [
|
|
||||||
[Hyprland, box => {
|
|
||||||
if (!App.getWindow('overview').visible)
|
if (!App.getWindow('overview').visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
print('running overview');
|
update(self);
|
||||||
update(box);
|
}]],
|
||||||
}],
|
|
||||||
],
|
|
||||||
properties: [
|
properties: [
|
||||||
['workspaces'],
|
['workspaces'],
|
||||||
],
|
],
|
||||||
|
|
|
@ -48,46 +48,24 @@ export const WorkspaceRow = (className, i) => Revealer({
|
||||||
child: Box({
|
child: Box({
|
||||||
className: className,
|
className: className,
|
||||||
children: [
|
children: [
|
||||||
Revealer({
|
Workspace(className === 'special' ? -1 : 1000,
|
||||||
transition: 'slide_right',
|
className === 'special' ? 'special' : '',
|
||||||
properties: [
|
true),
|
||||||
['id', className === 'special' ? -1 : 1000],
|
|
||||||
['name', className === 'special' ? 'special' : ''],
|
|
||||||
],
|
|
||||||
child: WorkspaceDrop({
|
|
||||||
child: Overlay({
|
|
||||||
child: Box({
|
|
||||||
className: 'workspace',
|
|
||||||
style: DEFAULT_STYLE,
|
|
||||||
}),
|
|
||||||
overlays: [
|
|
||||||
Box({
|
|
||||||
className: 'workspace active',
|
|
||||||
style: `${DEFAULT_STYLE} opacity: 0;`,
|
|
||||||
}),
|
|
||||||
Box({
|
|
||||||
style: DEFAULT_STYLE,
|
|
||||||
children: [
|
|
||||||
Widget({
|
|
||||||
type: Gtk.Fixed,
|
|
||||||
}),
|
|
||||||
Label({
|
|
||||||
label: ' +',
|
|
||||||
style: 'font-size: 40px;',
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
}), null],
|
}), null],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const Workspace = (id, name) => Revealer({
|
// TODO: please make this readable for the love of god
|
||||||
|
const Workspace = (id, name, extra = false) => {
|
||||||
|
let workspace;
|
||||||
|
let fixed = Widget({
|
||||||
|
type: Gtk.Fixed,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!extra) {
|
||||||
|
workspace = Revealer({
|
||||||
transition: 'slide_right',
|
transition: 'slide_right',
|
||||||
transitionDuration: 500,
|
transitionDuration: 500,
|
||||||
properties: [
|
properties: [
|
||||||
|
@ -160,14 +138,50 @@ const Workspace = (id, name) => Revealer({
|
||||||
Box({
|
Box({
|
||||||
className: 'workspace',
|
className: 'workspace',
|
||||||
style: DEFAULT_STYLE,
|
style: DEFAULT_STYLE,
|
||||||
child: Widget({
|
child: fixed,
|
||||||
type: Gtk.Fixed,
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
workspace = Revealer({
|
||||||
|
transition: 'slide_right',
|
||||||
|
properties: [
|
||||||
|
['id', id],
|
||||||
|
['name', name],
|
||||||
|
],
|
||||||
|
child: WorkspaceDrop({
|
||||||
|
child: Overlay({
|
||||||
|
child: Box({
|
||||||
|
className: 'workspace',
|
||||||
|
style: DEFAULT_STYLE,
|
||||||
|
}),
|
||||||
|
overlays: [
|
||||||
|
Box({
|
||||||
|
className: 'workspace active',
|
||||||
|
style: `${DEFAULT_STYLE} opacity: 0;`,
|
||||||
|
}),
|
||||||
|
Box({
|
||||||
|
style: DEFAULT_STYLE,
|
||||||
|
children: [
|
||||||
|
fixed,
|
||||||
|
Label({
|
||||||
|
label: ' +',
|
||||||
|
style: 'font-size: 40px;',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
workspace.getFixed = () => fixed;
|
||||||
|
return workspace;
|
||||||
|
};
|
||||||
|
|
||||||
export function updateWorkspaces(box) {
|
export function updateWorkspaces(box) {
|
||||||
Hyprland.workspaces.forEach(ws => {
|
Hyprland.workspaces.forEach(ws => {
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import { Widget } from '../imports.js';
|
import { Widget } from '../imports.js';
|
||||||
const { CenterBox, Label } = Widget;
|
const { CenterBox, Label } = Widget;
|
||||||
|
|
||||||
import { PopupWindow } from './misc/popup.js';
|
import PopupWindow from './misc/popup.js';
|
||||||
import { Button } from './misc/cursorbox.js'
|
import Button from './misc/cursorbox.js'
|
||||||
|
|
||||||
|
|
||||||
const PowermenuWidget = CenterBox({
|
const PowermenuWidget = () => CenterBox({
|
||||||
className: 'powermenu',
|
className: 'powermenu',
|
||||||
vertical: false,
|
vertical: false,
|
||||||
|
|
||||||
startWidget: Button({
|
startWidget: Button({
|
||||||
|
type: "Button",
|
||||||
className: 'shutdown',
|
className: 'shutdown',
|
||||||
onPrimaryClickRelease: 'systemctl poweroff',
|
onPrimaryClickRelease: 'systemctl poweroff',
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ const PowermenuWidget = CenterBox({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
centerWidget: Button({
|
centerWidget: Button({
|
||||||
|
type: "Button",
|
||||||
className: 'reboot',
|
className: 'reboot',
|
||||||
onPrimaryClickRelease: 'systemctl reboot',
|
onPrimaryClickRelease: 'systemctl reboot',
|
||||||
|
|
||||||
|
@ -28,6 +30,7 @@ const PowermenuWidget = CenterBox({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
endWidget: Button({
|
endWidget: Button({
|
||||||
|
type: "Button",
|
||||||
className: 'logout',
|
className: 'logout',
|
||||||
onPrimaryClickRelease: 'hyprctl dispatch exit',
|
onPrimaryClickRelease: 'hyprctl dispatch exit',
|
||||||
|
|
||||||
|
@ -40,5 +43,5 @@ const PowermenuWidget = CenterBox({
|
||||||
export default () => PopupWindow({
|
export default () => PopupWindow({
|
||||||
name: 'powermenu',
|
name: 'powermenu',
|
||||||
transition: 'crossfade',
|
transition: 'crossfade',
|
||||||
child: PowermenuWidget,
|
child: PowermenuWidget(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,10 +2,14 @@ import { Network, Bluetooth, Audio, App, Utils, Widget } from '../../imports.js'
|
||||||
const { Box, CenterBox, Label, Icon } = Widget;
|
const { Box, CenterBox, Label, Icon } = Widget;
|
||||||
const { execAsync } = Utils;
|
const { execAsync } = Utils;
|
||||||
|
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
|
|
||||||
|
|
||||||
const GridButton = ({ command = () => {}, secondaryCommand = () => {}, icon } = {}) => Box({
|
const GridButton = ({
|
||||||
|
command = () => {},
|
||||||
|
secondaryCommand = () => {},
|
||||||
|
icon
|
||||||
|
} = {}) => Box({
|
||||||
className: 'grid-button',
|
className: 'grid-button',
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
|
@ -27,7 +31,7 @@ const GridButton = ({ command = () => {}, secondaryCommand = () => {}, icon } =
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const FirstRow = Box({
|
const FirstRow = () => Box({
|
||||||
className: 'button-row',
|
className: 'button-row',
|
||||||
halign: 'center',
|
halign: 'center',
|
||||||
style: 'margin-top: 15px; margin-bottom: 7px;',
|
style: 'margin-top: 15px; margin-bottom: 7px;',
|
||||||
|
@ -35,7 +39,10 @@ const FirstRow = Box({
|
||||||
|
|
||||||
GridButton({
|
GridButton({
|
||||||
command: () => Network.toggleWifi(),
|
command: () => Network.toggleWifi(),
|
||||||
secondaryCommand: () => execAsync(['bash', '-c', 'nm-connection-editor']).catch(print),
|
secondaryCommand: () => {
|
||||||
|
execAsync(['bash', '-c', 'nm-connection-editor'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
icon: Icon({
|
icon: Icon({
|
||||||
className: 'grid-label',
|
className: 'grid-label',
|
||||||
connections: [[Network, icon => {
|
connections: [[Network, icon => {
|
||||||
|
@ -50,35 +57,47 @@ const FirstRow = Box({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
GridButton({
|
GridButton({
|
||||||
command: () => execAsync(['bash', '-c', '$AGS_PATH/qs-toggles.sh blue-toggle']).catch(print),
|
command: () => {
|
||||||
secondaryCommand: () => execAsync(['bash', '-c', 'blueberry']).catch(print),
|
execAsync(['bash', '-c', '$AGS_PATH/qs-toggles.sh blue-toggle'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
|
secondaryCommand: () => {
|
||||||
|
execAsync(['bash', '-c', 'blueberry'])
|
||||||
|
.catch(print)
|
||||||
|
},
|
||||||
icon: Icon({
|
icon: Icon({
|
||||||
className: 'grid-label',
|
className: 'grid-label',
|
||||||
connections: [[Bluetooth, icon => {
|
connections: [[Bluetooth, self => {
|
||||||
if (Bluetooth.enabled) {
|
if (Bluetooth.enabled) {
|
||||||
icon.icon = 'bluetooth-active-symbolic';
|
self.icon = 'bluetooth-active-symbolic';
|
||||||
execAsync(['bash', '-c', 'echo > $HOME/.config/.bluetooth']).catch(print);
|
execAsync(['bash', '-c', 'echo > $HOME/.config/.bluetooth'])
|
||||||
|
.catch(print);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
icon.icon = 'bluetooth-disabled-symbolic';
|
self.icon = 'bluetooth-disabled-symbolic';
|
||||||
execAsync(['bash', '-c', 'echo > $HOME/.config/.bluetooth']).catch(print);
|
execAsync(['bash', '-c', 'echo > $HOME/.config/.bluetooth'])
|
||||||
|
.catch(print);
|
||||||
}
|
}
|
||||||
}, 'changed']],
|
}, 'changed']],
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
|
||||||
GridButton({
|
GridButton({
|
||||||
command: () => execAsync(['bash', '-c', '$AGS_PATH/qs-toggles.sh toggle-radio']).catch(print),
|
command: () => {
|
||||||
secondaryCommand: () => execAsync(['notify-send', 'set this up moron']).catch(print),
|
execAsync(['bash', '-c', '$AGS_PATH/qs-toggles.sh toggle-radio'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
|
secondaryCommand: () => {
|
||||||
|
execAsync(['notify-send', 'set this up moron'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
icon: Icon({
|
icon: Icon({
|
||||||
className: 'grid-label',
|
className: 'grid-label',
|
||||||
connections: [[Network, icon => {
|
connections: [[Network, self => {
|
||||||
if (Network.wifi.enabled) {
|
if (Network.wifi.enabled)
|
||||||
icon.icon = 'airplane-mode-disabled-symbolic';
|
self.icon = 'airplane-mode-disabled-symbolic';
|
||||||
}
|
else
|
||||||
else {
|
self.icon = 'airplane-mode-symbolic';
|
||||||
icon.icon = 'airplane-mode-symbolic';
|
|
||||||
}
|
|
||||||
}, 'changed']],
|
}, 'changed']],
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
@ -86,7 +105,7 @@ const FirstRow = Box({
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const SubRow = CenterBox({
|
const SubRow = () => CenterBox({
|
||||||
halign: 'start',
|
halign: 'start',
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
|
@ -94,8 +113,9 @@ const SubRow = CenterBox({
|
||||||
className: 'sub-label',
|
className: 'sub-label',
|
||||||
truncate: 'end',
|
truncate: 'end',
|
||||||
maxWidthChars: 12,
|
maxWidthChars: 12,
|
||||||
connections: [[Network, label => {
|
connections: [[Network, self => {
|
||||||
label.label = Network.wifi.ssid;
|
// TODO: handle ethernet too
|
||||||
|
self.label = Network.wifi.ssid;
|
||||||
}, 'changed']],
|
}, 'changed']],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -103,20 +123,15 @@ const SubRow = CenterBox({
|
||||||
className: 'sub-label',
|
className: 'sub-label',
|
||||||
truncate: 'end',
|
truncate: 'end',
|
||||||
maxWidthChars: 12,
|
maxWidthChars: 12,
|
||||||
connections: [[Bluetooth, label => {
|
connections: [[Bluetooth, self => {
|
||||||
label.label = Bluetooth.connectedDevices[0] ? String(Bluetooth.connectedDevices[0]) :
|
if (Bluetooth.connectedDevices[0])
|
||||||
'Disconnected';
|
self.label = String(Bluetooth.connectedDevices[0])
|
||||||
|
else
|
||||||
|
self.label = 'Disconnected';
|
||||||
}, 'changed']],
|
}, 'changed']],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Label({
|
null,
|
||||||
className: '',
|
|
||||||
truncate: 'end',
|
|
||||||
maxWidthChars: 12,
|
|
||||||
/*connections: [[Network, label => {
|
|
||||||
label.label = Network.wifi.ssid;
|
|
||||||
}, 'changed']],*/
|
|
||||||
}),
|
|
||||||
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -135,15 +150,23 @@ const itemsMic = {
|
||||||
0: 'audio-input-microphone-muted-symbolic',
|
0: 'audio-input-microphone-muted-symbolic',
|
||||||
};
|
};
|
||||||
|
|
||||||
const SecondRow = Box({
|
const SecondRow = () => Box({
|
||||||
className: 'button-row',
|
className: 'button-row',
|
||||||
halign: 'center',
|
halign: 'center',
|
||||||
style: 'margin-top: 7px; margin-bottom: 15px;',
|
style: 'margin-top: 7px; margin-bottom: 15px;',
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
GridButton({
|
GridButton({
|
||||||
command: () => execAsync(['swayosd-client', '--output-volume', 'mute-toggle']).catch(print),
|
command: () => {
|
||||||
secondaryCommand: () => execAsync(['bash', '-c', 'pavucontrol']).catch(print),
|
execAsync(['swayosd-client', '--output-volume', 'mute-toggle'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
|
|
||||||
|
secondaryCommand: () => {
|
||||||
|
execAsync(['bash', '-c', 'pavucontrol'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
|
|
||||||
icon: Icon({
|
icon: Icon({
|
||||||
className: 'grid-label',
|
className: 'grid-label',
|
||||||
connections: [[Audio, icon => {
|
connections: [[Audio, icon => {
|
||||||
|
@ -165,8 +188,16 @@ const SecondRow = Box({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
GridButton({
|
GridButton({
|
||||||
command: () => execAsync(['swayosd-client', '--input-volume', 'mute-toggle']).catch(print),
|
command: () => {
|
||||||
secondaryCommand: () => execAsync(['bash', '-c', 'pavucontrol']).catch(print),
|
execAsync(['swayosd-client', '--input-volume', 'mute-toggle'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
|
|
||||||
|
secondaryCommand: () => {
|
||||||
|
execAsync(['bash', '-c', 'pavucontrol'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
|
|
||||||
icon: Icon({
|
icon: Icon({
|
||||||
className: 'grid-label',
|
className: 'grid-label',
|
||||||
connections: [[Audio, icon => {
|
connections: [[Audio, icon => {
|
||||||
|
@ -188,7 +219,10 @@ const SecondRow = Box({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
GridButton({
|
GridButton({
|
||||||
command: () => execAsync(['bash', '-c', '$LOCK_PATH/lock.sh']).catch(print),
|
command: () => {
|
||||||
|
execAsync(['bash', '-c', '$LOCK_PATH/lock.sh'])
|
||||||
|
.catch(print);
|
||||||
|
},
|
||||||
secondaryCommand: () => App.openWindow('powermenu'),
|
secondaryCommand: () => App.openWindow('powermenu'),
|
||||||
icon: Label({
|
icon: Label({
|
||||||
className: 'grid-label',
|
className: 'grid-label',
|
||||||
|
@ -199,14 +233,13 @@ const SecondRow = Box({
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default () => Box({
|
||||||
export const ButtonGrid = Box({
|
|
||||||
className: 'button-grid',
|
className: 'button-grid',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
halign: 'center',
|
halign: 'center',
|
||||||
children: [
|
children: [
|
||||||
FirstRow,
|
FirstRow(),
|
||||||
SubRow,
|
SubRow(),
|
||||||
SecondRow,
|
SecondRow(),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,14 +3,14 @@ const { Box, Label, Revealer, Icon } = Widget;
|
||||||
|
|
||||||
import Gtk from 'gi://Gtk';
|
import Gtk from 'gi://Gtk';
|
||||||
|
|
||||||
import { ButtonGrid } from './button-grid.js';
|
import ButtonGrid from './button-grid.js';
|
||||||
import { SliderBox } from './slider-box.js';
|
import SliderBox from './slider-box.js';
|
||||||
import Player from '../media-player/player.js';
|
import Player from '../media-player/player.js';
|
||||||
import { EventBox } from '../misc/cursorbox.js';
|
import EventBox from '../misc/cursorbox.js';
|
||||||
import { PopupWindow } from '../misc/popup.js';
|
import PopupWindow from '../misc/popup.js';
|
||||||
|
|
||||||
|
|
||||||
const QuickSettingsWidget = Box({
|
const QuickSettingsWidget = () => Box({
|
||||||
className: 'qs-container',
|
className: 'qs-container',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
children: [
|
children: [
|
||||||
|
@ -27,9 +27,9 @@ const QuickSettingsWidget = Box({
|
||||||
style: 'margin-left: 20px'
|
style: 'margin-left: 20px'
|
||||||
}),
|
}),
|
||||||
|
|
||||||
ButtonGrid,
|
ButtonGrid(),
|
||||||
|
|
||||||
SliderBox,
|
SliderBox(),
|
||||||
|
|
||||||
EventBox({
|
EventBox({
|
||||||
child: Widget({
|
child: Widget({
|
||||||
|
@ -41,13 +41,15 @@ const QuickSettingsWidget = Box({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
connections: [['toggled', button => {
|
connections: [['toggled', button => {
|
||||||
|
let rev = button.get_parent().get_parent().get_parent().children[1];
|
||||||
|
|
||||||
if (button.get_active()) {
|
if (button.get_active()) {
|
||||||
button.child.setStyle("-gtk-icon-transform: rotate(0deg);");
|
button.child.setStyle("-gtk-icon-transform: rotate(0deg);");
|
||||||
button.get_parent().get_parent().get_parent().children[1].revealChild = true;
|
rev.revealChild = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
button.child.setStyle('-gtk-icon-transform: rotate(180deg);');
|
button.child.setStyle('-gtk-icon-transform: rotate(180deg);');
|
||||||
button.get_parent().get_parent().get_parent().children[1].revealChild = false;
|
rev.revealChild = false;
|
||||||
}
|
}
|
||||||
}]],
|
}]],
|
||||||
child: Icon({
|
child: Icon({
|
||||||
|
@ -73,5 +75,5 @@ export default () => PopupWindow({
|
||||||
name: 'quick-settings',
|
name: 'quick-settings',
|
||||||
anchor: [ 'top', 'right' ],
|
anchor: [ 'top', 'right' ],
|
||||||
margin: [ 8, 5, 0, ],
|
margin: [ 8, 5, 0, ],
|
||||||
child: QuickSettingsWidget,
|
child: QuickSettingsWidget(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@ const items = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const SliderBox = Box({
|
export default () => Box({
|
||||||
className: 'slider-box',
|
className: 'slider-box',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
halign: 'center',
|
halign: 'center',
|
||||||
|
@ -73,11 +73,14 @@ export const SliderBox = Box({
|
||||||
['canChange', true],
|
['canChange', true],
|
||||||
],
|
],
|
||||||
onChange: ({ value }) => {
|
onChange: ({ value }) => {
|
||||||
execAsync(`brightnessctl set ${value}`).catch(print);
|
execAsync(`brightnessctl set ${value}`)
|
||||||
|
.catch(print);
|
||||||
},
|
},
|
||||||
connections: [[1000, slider => {
|
connections: [[1000, slider => {
|
||||||
if (slider._canChange) {
|
if (slider._canChange) {
|
||||||
execAsync('brightnessctl get').then(out => slider.value = out).catch(print);
|
execAsync('brightnessctl get')
|
||||||
|
.then(out => slider.value = out)
|
||||||
|
.catch(print);
|
||||||
}
|
}
|
||||||
}]],
|
}]],
|
||||||
min: 0,
|
min: 0,
|
||||||
|
|
|
@ -8,13 +8,23 @@ export const RoundedCorner = (place, props) => Widget({
|
||||||
halign: place.includes('left') ? 'start' : 'end',
|
halign: place.includes('left') ? 'start' : 'end',
|
||||||
valign: place.includes('top') ? 'start' : 'end',
|
valign: place.includes('top') ? 'start' : 'end',
|
||||||
setup: widget => {
|
setup: widget => {
|
||||||
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
|
const r = widget.get_style_context()
|
||||||
|
.get_property('border-radius', Gtk.StateFlags.NORMAL);
|
||||||
|
|
||||||
widget.set_size_request(r, r);
|
widget.set_size_request(r, r);
|
||||||
widget.connect('draw', Lang.bind(widget, (widget, cr) => {
|
widget.connect('draw', Lang.bind(widget, (widget, cr) => {
|
||||||
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
|
const c = widget.get_style_context()
|
||||||
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
|
.get_property('background-color', Gtk.StateFlags.NORMAL);
|
||||||
const borderColor = widget.get_style_context().get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
const borderWidth = widget.get_style_context().get_border(Gtk.StateFlags.NORMAL).left; // ur going to write border-width: something anyway
|
const r = widget.get_style_context()
|
||||||
|
.get_property('border-radius', Gtk.StateFlags.NORMAL);
|
||||||
|
|
||||||
|
const borderColor = widget.get_style_context()
|
||||||
|
.get_property('color', Gtk.StateFlags.NORMAL);
|
||||||
|
|
||||||
|
// ur going to write border-width: something anyway
|
||||||
|
const borderWidth = widget.get_style_context()
|
||||||
|
.get_border(Gtk.StateFlags.NORMAL).left;
|
||||||
widget.set_size_request(r, r);
|
widget.set_size_request(r, r);
|
||||||
|
|
||||||
switch (place) {
|
switch (place) {
|
||||||
|
@ -43,7 +53,10 @@ export const RoundedCorner = (place, props) => Widget({
|
||||||
cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
|
cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
|
||||||
cr.fill();
|
cr.fill();
|
||||||
cr.setLineWidth(borderWidth);
|
cr.setLineWidth(borderWidth);
|
||||||
cr.setSourceRGBA(borderColor.red, borderColor.green, borderColor.blue, borderColor.alpha);
|
cr.setSourceRGBA(borderColor.red,
|
||||||
|
borderColor.green,
|
||||||
|
borderColor.blue,
|
||||||
|
borderColor.alpha);
|
||||||
cr.stroke();
|
cr.stroke();
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
|
@ -28,7 +28,7 @@ exec-once = ags
|
||||||
exec-once = gnome-keyring-daemon --start --components=secrets
|
exec-once = gnome-keyring-daemon --start --components=secrets
|
||||||
exec-once = squeekboard
|
exec-once = squeekboard
|
||||||
|
|
||||||
exec-once = bash -c "sleep 1; ags -t applauncher"
|
exec-once = bash -c "sleep 3; ags -t applauncher"
|
||||||
exec-once = hyprpaper
|
exec-once = hyprpaper
|
||||||
|
|
||||||
exec-once = wl-paste --watch cliphist store
|
exec-once = wl-paste --watch cliphist store
|
||||||
|
|
Loading…
Reference in a new issue