chore: update ags and start fixing breaking changes

This commit is contained in:
matt1432 2023-12-17 00:01:58 -05:00
parent 4f349dae0f
commit 4412d13997
39 changed files with 1103 additions and 1005 deletions

View file

@ -21,6 +21,7 @@ exec(`sassc ${scss} ${css}`);
Setup();
// TODO: get rid of 'properties' and 'binds' prop
export default {
style: css,
notificationPopupTimeout: 5000,

View file

@ -101,6 +101,23 @@ const Applauncher = ({ window_name = 'applauncher' } = {}) => {
className: 'applauncher',
vertical: true,
setup: (self) => {
self.hook(App, (_, name, visible) => {
if (name !== window_name) {
return;
}
entry.text = '';
if (visible) {
entry.grab_focus();
}
else {
makeNewChildren();
}
});
},
children: [
Box({
className: 'header',
@ -119,21 +136,6 @@ const Applauncher = ({ window_name = 'applauncher' } = {}) => {
}),
}),
],
connections: [[App, (_, name, visible) => {
if (name !== window_name) {
return;
}
entry.text = '';
if (visible) {
entry.grab_focus();
}
else {
makeNewChildren();
}
}]],
});
};

View file

@ -13,11 +13,13 @@ const SpeakerIndicator = (props) => Icon({
const SpeakerPercentLabel = (props) => Label({
...props,
connections: [[Audio, (label) => {
if (Audio.speaker) {
label.label = `${Math.round(Audio.speaker.volume * 100)}%`;
}
}, 'speaker-changed']],
setup: (self) => {
self.hook(Audio, (label) => {
if (Audio.speaker) {
label.label = `${Math.round(Audio.speaker.volume * 100)}%`;
}
}, 'speaker-changed');
},
});
const SPACING = 5;

View file

@ -12,20 +12,24 @@ const Indicator = () => Icon({
binds: [['icon', Battery, 'icon-name']],
connections: [[Battery, (self) => {
self.toggleClassName('charging', Battery.charging);
self.toggleClassName('charged', Battery.charged);
self.toggleClassName('low', Battery.percent < LOW_BATT);
}]],
setup: (self) => {
self.hook(Battery, () => {
self.toggleClassName('charging', Battery.charging);
self.toggleClassName('charged', Battery.charged);
self.toggleClassName('low', Battery.percent < LOW_BATT);
});
},
});
const LevelLabel = (props) => Label({
...props,
className: 'label',
connections: [[Battery, (self) => {
self.label = `${Battery.percent}%`;
}]],
setup: (self) => {
self.hook(Battery, () => {
self.label = `${Battery.percent}%`;
});
},
});
const SPACING = 5;

View file

@ -7,25 +7,29 @@ import Separator from '../../misc/separator.js';
const Indicator = (props) => Icon({
...props,
connections: [[Bluetooth, (self) => {
if (Bluetooth.enabled) {
self.icon = Bluetooth.connectedDevices[0] ?
Bluetooth.connectedDevices[0].iconName :
'bluetooth-active-symbolic';
}
else {
self.icon = 'bluetooth-disabled-symbolic';
}
}]],
setup: (self) => {
self.hook(Bluetooth, () => {
if (Bluetooth.enabled) {
self.icon = Bluetooth.connectedDevices[0] ?
Bluetooth.connectedDevices[0].iconName :
'bluetooth-active-symbolic';
}
else {
self.icon = 'bluetooth-disabled-symbolic';
}
});
},
});
const ConnectedLabel = (props) => Label({
...props,
connections: [[Bluetooth, (self) => {
self.label = Bluetooth.connectedDevices[0] ?
`${Bluetooth.connectedDevices[0]}` :
'Disconnected';
}, 'notify::connected-devices']],
setup: (self) => {
self.hook(Bluetooth, () => {
self.label = Bluetooth.connectedDevices[0] ?
`${Bluetooth.connectedDevices[0]}` :
'Disconnected';
}, 'notify::connected-devices');
},
});
const SPACING = 5;

View file

@ -13,9 +13,11 @@ const Indicator = (props) => Icon({
const BrightnessPercentLabel = (props) => Label({
...props,
connections: [[Brightness, (self) => {
self.label = `${Math.round(Brightness.screen * 100)}%`;
}, 'screen']],
setup: (self) => {
self.hook(Brightness, () => {
self.label = `${Math.round(Brightness.screen * 100)}%`;
}, 'screen');
},
});
export default () => {

View file

@ -8,36 +8,32 @@ const { DateTime } = GLib;
import EventBox from '../../misc/cursorbox.js';
const ClockModule = ({
interval = 1000,
...props
} = {}) => {
return Label({
...props,
className: 'clock',
const ClockModule = () => Label({
className: 'clock',
connections: [[interval, (self) => {
setup: (self) => {
self.poll(1000, () => {
const time = DateTime.new_now_local();
self.label = time.format('%a. ') +
time.get_day_of_month() +
time.format(' %b. %H:%M');
}]],
});
};
});
},
});
export default () => EventBox({
className: 'toggle-off',
onPrimaryClickRelease: () => App.toggleWindow('calendar'),
connections: [
[App, (self, windowName, visible) => {
setup: (self) => {
self.hook(App, (_, windowName, visible) => {
if (windowName === 'calendar') {
self.toggleClassName('toggle-on', visible);
}
}],
],
});
},
child: ClockModule(),
});

View file

@ -13,14 +13,17 @@ export default () => Box({
Icon({
size: 30,
connections: [[Hyprland.active.client, (self) => {
const app = Applications.query(Hyprland.active.client.class)[0];
setup: (self) => {
self.hook(Hyprland.active.client, () => {
const app = Applications
.query(Hyprland.active.client.class)[0];
if (app) {
self.icon = app.iconName;
self.visible = Hyprland.active.client.title !== '';
}
}]],
if (app) {
self.icon = app.iconName;
self.visible = Hyprland.active.client.title !== '';
}
});
},
}),
Separator(SPACING),

View file

@ -8,40 +8,44 @@ const DEFAULT_KB = 'at-translated-set-2-keyboard';
const SPACING = 4;
const Indicator = () => Label({
css: 'font-size: 20px;',
setup: (self) => {
self.hook(Hyprland, (_, _n, layout) => {
if (layout) {
if (layout === 'error') {
return;
}
const shortName = layout.match(/\(([A-Za-z]+)\)/);
self.label = shortName ? shortName[1] : layout;
}
else {
// At launch, kb layout is undefined
Hyprland.sendMessage('j/devices').then((obj) => {
const kb = JSON.parse(obj).keyboards
.find((val) => val.name === DEFAULT_KB);
layout = kb['active_keymap'];
const shortName = layout
.match(/\(([A-Za-z]+)\)/);
self.label = shortName ? shortName[1] : layout;
}).catch(print);
}
}, 'keyboard-layout');
},
});
export default () => {
const rev = Revealer({
transition: 'slide_right',
child: Box({
children: [
Separator(SPACING),
Label({
css: 'font-size: 20px;',
connections: [[Hyprland, (self, _n, layout) => {
if (layout) {
if (layout === 'error') {
return;
}
const shortName = layout.match(/\(([A-Za-z]+)\)/);
self.label = shortName ? shortName[1] : layout;
}
else {
// At launch, kb layout is undefined
Hyprland.sendMessage('j/devices').then((obj) => {
const kb = JSON.parse(obj).keyboards
.find((val) => val.name === DEFAULT_KB);
layout = kb['active_keymap'];
const shortName = layout
.match(/\(([A-Za-z]+)\)/);
self.label = shortName ? shortName[1] : layout;
}).catch(print);
}
}, 'keyboard-layout']],
}),
Indicator(),
],
}),
});

View file

@ -7,36 +7,40 @@ import Separator from '../../misc/separator.js';
const Indicator = (props) => Icon({
...props,
connections: [[Network, (self) => {
if (Network.wifi.internet === 'connected' ||
Network.wifi.internet === 'connecting') {
self.icon = Network.wifi.iconName;
}
else if (Network.wired.internet === 'connected' ||
Network.wired.internet === 'connecting') {
self.icon = Network.wired.iconName;
}
else {
self.icon = Network.wifi.iconName;
}
}]],
setup: (self) => {
self.hook(Network, () => {
if (Network.wifi.internet === 'connected' ||
Network.wifi.internet === 'connecting') {
self.icon = Network.wifi.iconName;
}
else if (Network.wired.internet === 'connected' ||
Network.wired.internet === 'connecting') {
self.icon = Network.wired.iconName;
}
else {
self.icon = Network.wifi.iconName;
}
});
},
});
const APLabel = (props) => Label({
...props,
connections: [[Network, (self) => {
if (Network.wifi.internet === 'connected' ||
Network.wifi.internet === 'connecting') {
self.label = Network.wifi.ssid;
}
else if (Network.wired.internet === 'connected' ||
Network.wired.internet === 'connecting') {
self.label = 'Connected';
}
else {
self.label = 'Disconnected';
}
}]],
setup: (self) => {
self.hook(Network, () => {
if (Network.wifi.internet === 'connected' ||
Network.wifi.internet === 'connecting') {
self.label = Network.wifi.ssid;
}
else if (Network.wired.internet === 'connected' ||
Network.wired.internet === 'connecting') {
self.label = 'Connected';
}
else {
self.label = 'Disconnected';
}
});
},
});
const SPACING = 5;

View file

@ -19,11 +19,13 @@ export default () => EventBox({
App.toggleWindow('notification-center');
},
connections: [[App, (self, windowName, visible) => {
if (windowName === 'notification-center') {
self.toggleClassName('toggle-on', visible);
}
}]],
setup: (self) => {
self.hook(App, (_, windowName, visible) => {
if (windowName === 'notification-center') {
self.toggleClassName('toggle-on', visible);
}
});
},
child: CenterBox({
className: 'notif-panel',
@ -31,17 +33,19 @@ export default () => EventBox({
center_widget: Box({
children: [
Icon({
connections: [[Notifications, (self) => {
if (Notifications.dnd) {
self.icon = 'notification-disabled-symbolic';
}
else if (Notifications.notifications.length > 0) {
self.icon = 'notification-new-symbolic';
}
else {
self.icon = 'notification-symbolic';
}
}]],
setup: (self) => {
self.hook(Notifications, () => {
if (Notifications.dnd) {
self.icon = 'notification-disabled-symbolic';
}
else if (Notifications.notifications.length > 0) {
self.icon = 'notification-new-symbolic';
}
else {
self.icon = 'notification-symbolic';
}
});
},
}),
Separator(SPACING),

View file

@ -9,9 +9,11 @@ export default () => EventBox({
onPrimaryClickRelease: () => Tablet.toggleOsk(),
connections: [[Tablet, (self) => {
self.toggleClassName('toggle-on', Tablet.oskState);
}, 'osk-toggled']],
setup: (self) => {
self.hook(Tablet, () => {
self.toggleClassName('toggle-on', Tablet.oskState);
}, 'osk-toggled');
},
child: Box({
className: 'osk-toggle',

View file

@ -26,11 +26,13 @@ export default () => EventBox({
App.toggleWindow('quick-settings');
},
connections: [[App, (self, windowName, visible) => {
if (windowName === 'quick-settings') {
self.toggleClassName('toggle-on', visible);
}
}]],
setup: (self) => {
self.hook(App, (_, windowName, visible) => {
if (windowName === 'quick-settings') {
self.toggleClassName('toggle-on', visible);
}
});
},
child: Box({
className: 'quick-settings-toggle',

View file

@ -33,42 +33,39 @@ const SysTray = () => MenuBar({
setup: (self) => {
self.items = new Map();
self.onAdded = (id) => {
const item = SystemTray.getItem(id);
self
.hook(SystemTray, (_, id) => {
const item = SystemTray.getItem(id);
if (self.items.has(id) || !item) {
return;
}
if (self.items.has(id) || !item) {
return;
}
const w = SysTrayItem(item);
const w = SysTrayItem(item);
// Early return if item is in blocklist
if (!w) {
return;
}
// Early return if item is in blocklist
if (!w) {
return;
}
self.items.set(id, w);
self.add(w);
self.show_all();
w.child.revealChild = true;
};
self.items.set(id, w);
self.add(w);
self.show_all();
w.child.revealChild = true;
}, 'added')
self.onRemoved = (id) => {
if (!self.items.has(id)) {
return;
}
.hook(SystemTray, (_, id) => {
if (!self.items.has(id)) {
return;
}
self.items.get(id).child.revealChild = false;
timeout(REVEAL_DURATION, () => {
self.items.get(id).destroy();
self.items.delete(id);
});
};
self.items.get(id).child.revealChild = false;
timeout(REVEAL_DURATION, () => {
self.items.get(id).destroy();
self.items.delete(id);
});
}, 'removed');
},
connections: [
[SystemTray, (self, id) => self.onAdded(id), 'added'],
[SystemTray, (self, id) => self.onRemoved(id), 'removed'],
],
});
export default () => {
@ -77,9 +74,11 @@ export default () => {
return Revealer({
transition: 'slide_right',
connections: [[SystemTray, (rev) => {
rev.revealChild = systray.get_children().length > 0;
}]],
setup: (self) => {
self.hook(SystemTray, () => {
self.revealChild = systray.get_children().length > 0;
});
},
child: Box({
children: [

View file

@ -9,9 +9,11 @@ export default () => EventBox({
onPrimaryClickRelease: () => Tablet.toggleMode(),
connections: [[Tablet, (self) => {
self.toggleClassName('toggle-on', Tablet.tabletMode);
}, 'mode-toggled']],
setup: (self) => {
self.hook(Tablet, () => {
self.toggleClassName('toggle-on', Tablet.tabletMode);
}, 'mode-toggled');
},
child: Box({
className: 'tablet-toggle',

View file

@ -43,19 +43,19 @@ const Workspace = ({ i } = {}) => {
}
}
};
self
.hook(Hyprland, () => self.update())
// Deal with urgent windows
.hook(Hyprland, (_, a) => {
self.update(a);
}, 'urgent-window')
.hook(Hyprland.active.workspace, () => {
if (Hyprland.active.workspace.id === i) {
self.toggleClassName('urgent', false);
}
});
},
connections: [
[Hyprland, (self) => self.update()],
// Deal with urgent windows
[Hyprland, (self, a) => self.update(a), 'urgent-window'],
[Hyprland.active.workspace, (self) => {
if (Hyprland.active.workspace.id === i) {
self.toggleClassName('urgent', false);
}
}],
],
}),
}),
});
@ -81,7 +81,9 @@ export default () => {
vpack: 'center',
hpack: 'start',
className: 'button active',
connections: [[Hyprland.active.workspace, updateHighlight]],
setup: (self) => {
self.hook(Hyprland.active.workspace, updateHighlight);
},
});
const widget = Overlay({
@ -122,21 +124,23 @@ export default () => {
}],
],
connections: [[Hyprland, (self) => {
self._workspaces = self.children.filter((ch) => {
return Hyprland.workspaces.find((ws) => {
return ws.id === ch._id;
});
}).sort((a, b) => a._id - b._id);
setup: (self) => {
self.hook(Hyprland, () => {
self._workspaces = self.children.filter((ch) => {
return Hyprland.workspaces.find((ws) => {
return ws.id === ch._id;
});
}).sort((a, b) => a._id - b._id);
self._updateWorkspaces(self);
self._refresh(self);
self._updateWorkspaces(self);
self._refresh(self);
// Make sure the highlight doesn't go too far
const TEMP_TIMEOUT = 10;
// Make sure the highlight doesn't go too far
const TEMP_TIMEOUT = 10;
timeout(TEMP_TIMEOUT, () => updateHighlight(highlight));
}]],
timeout(TEMP_TIMEOUT, () => updateHighlight(highlight));
});
},
}),
}),
});

View file

@ -31,19 +31,20 @@ export default (props) => {
hexpand: true,
vertical: true,
connections: [
[Hyprland.active, () => {
const workspace = Hyprland.getWorkspace(
Hyprland.active.workspace.id,
);
setup: (self) => {
self
.hook(Hyprland.active, () => {
const workspace = Hyprland.getWorkspace(
Hyprland.active.workspace.id,
);
Revealed.value = !workspace?.hasfullscreen;
}],
Revealed.value = !workspace?.hasfullscreen;
})
[Hyprland, (_, fullscreen) => {
Revealed.value = !fullscreen;
}, 'fullscreen'],
],
.hook(Hyprland, (_, fullscreen) => {
Revealed.value = !fullscreen;
}, 'fullscreen');
},
children: [
Revealer({

View file

@ -25,9 +25,11 @@ const Time = () => Box({
Label({
className: 'content',
label: 'hour',
connections: [[1000, (self) => {
self.label = DateTime.new_now_local().format('%H');
}]],
setup: (self) => {
self.poll(1000, () => {
self.label = DateTime.new_now_local().format('%H');
});
},
}),
Divider(),
@ -35,9 +37,11 @@ const Time = () => Box({
Label({
className: 'content',
label: 'minute',
connections: [[1000, (self) => {
self.label = DateTime.new_now_local().format('%M');
}]],
setup: (self) => {
self.poll(1000, () => {
self.label = DateTime.new_now_local().format('%M');
});
},
}),
],
@ -49,13 +53,15 @@ const Time = () => Box({
child: Label({
css: 'font-size: 20px',
label: 'complete date',
connections: [[1000, (self) => {
const time = DateTime.new_now_local();
setup: (self) => {
self.poll(1000, () => {
const time = DateTime.new_now_local();
self.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');
});
},
}),
}),

View file

@ -12,7 +12,7 @@ const TRANSITION = `transition: margin ${ANIM_DURATION}ms ease,
export default ({
properties,
connections,
setup = () => {/**/},
props,
} = {}) => {
const widget = EventBox();
@ -33,101 +33,103 @@ export default ({
child: emptyPlayer,
connections: [
...connections,
setup: (self) => {
setup(self);
[gesture, (overlay, realGesture) => {
if (realGesture) {
overlay.list().forEach((over) => {
over.visible = true;
});
}
else {
overlay.showTopOnly();
}
self
.hook(gesture, (overlay, realGesture) => {
if (realGesture) {
overlay.list().forEach((over) => {
over.visible = true;
});
}
else {
overlay.showTopOnly();
}
// Don't allow gesture when only one player
if (overlay.list().length <= 1) {
return;
}
// Don't allow gesture when only one player
if (overlay.list().length <= 1) {
return;
}
overlay._dragging = true;
let offset = gesture.get_offset()[1];
overlay._dragging = true;
let offset = gesture.get_offset()[1];
const playerBox = overlay.list().at(-1);
const playerBox = overlay.list().at(-1);
// Slide right
if (offset >= 0) {
playerBox.setCss(`
margin-left: ${offset}px;
margin-right: -${offset}px;
${playerBox._bgStyle}
`);
}
// Slide left
else {
offset = Math.abs(offset);
playerBox.setCss(`
margin-left: -${offset}px;
margin-right: ${offset}px;
${playerBox._bgStyle}
`);
}
}, 'drag-update'],
[gesture, (overlay) => {
// Don't allow gesture when only one player
if (overlay.list().length <= 1) {
return;
}
overlay._dragging = false;
const offset = gesture.get_offset()[1];
const playerBox = overlay.list().at(-1);
// If crosses threshold after letting go, slide away
if (Math.abs(offset) > MAX_OFFSET) {
// Disable inputs during animation
widget.sensitive = false;
// Slide away right
// Slide right
if (offset >= 0) {
playerBox.setCss(`
${TRANSITION}
margin-left: ${OFFSCREEN}px;
margin-right: -${OFFSCREEN}px;
opacity: 0.7; ${playerBox._bgStyle}
margin-left: ${offset}px;
margin-right: -${offset}px;
${playerBox._bgStyle}
`);
}
// Slide away left
// Slide left
else {
offset = Math.abs(offset);
playerBox.setCss(`
${TRANSITION}
margin-left: -${OFFSCREEN}px;
margin-right: ${OFFSCREEN}px;
opacity: 0.7; ${playerBox._bgStyle}`);
margin-left: -${offset}px;
margin-right: ${offset}px;
${playerBox._bgStyle}
`);
}
}, 'drag-update')
.hook(gesture, (overlay) => {
// Don't allow gesture when only one player
if (overlay.list().length <= 1) {
return;
}
timeout(ANIM_DURATION, () => {
// Put the player in the back after anim
overlay.reorder_overlay(playerBox, 0);
// Recenter player
playerBox.setCss(playerBox._bgStyle);
overlay._dragging = false;
const offset = gesture.get_offset()[1];
widget.sensitive = true;
const playerBox = overlay.list().at(-1);
overlay.showTopOnly();
});
}
else {
// Recenter with transition for animation
playerBox.setCss(`${TRANSITION} ${playerBox._bgStyle}`);
}
}, 'drag-end'],
],
// If crosses threshold after letting go, slide away
if (Math.abs(offset) > MAX_OFFSET) {
// Disable inputs during animation
widget.sensitive = false;
// Slide away right
if (offset >= 0) {
playerBox.setCss(`
${TRANSITION}
margin-left: ${OFFSCREEN}px;
margin-right: -${OFFSCREEN}px;
opacity: 0.7; ${playerBox._bgStyle}
`);
}
// Slide away left
else {
playerBox.setCss(`
${TRANSITION}
margin-left: -${OFFSCREEN}px;
margin-right: ${OFFSCREEN}px;
opacity: 0.7; ${playerBox._bgStyle}
`);
}
timeout(ANIM_DURATION, () => {
// Put the player in the back after anim
overlay.reorder_overlay(playerBox, 0);
// Recenter player
playerBox.setCss(playerBox._bgStyle);
widget.sensitive = true;
overlay.showTopOnly();
});
}
else {
// Recenter with transition for animation
playerBox.setCss(`${TRANSITION} ${playerBox._bgStyle}`);
}
}, 'drag-end');
},
});
widget.add(content);

View file

@ -60,19 +60,18 @@ export const CoverArt = (player, props) => CenterBox({
self.setCss(self._bgStyle);
}
});
},
connections: [[player, (self) => {
execAsync(['bash', '-c', `[[ -f "${player.coverPath}" ]] &&
self.hook(player, () => {
execAsync(['bash', '-c', `[[ -f "${player.coverPath}" ]] &&
coloryou "${player.coverPath}" | grep -v Warning`])
.then((out) => {
if (!Mpris.players.find((p) => player === p)) {
return;
}
.then((out) => {
if (!Mpris.players.find((p) => player === p)) {
return;
}
player.colors.value = JSON.parse(out);
player.colors.value = JSON.parse(out);
self._bgStyle = `
self._bgStyle = `
background: radial-gradient(circle,
rgba(0, 0, 0, 0.4) 30%,
${player.colors.value.imageAccent}),
@ -81,15 +80,16 @@ export const CoverArt = (player, props) => CenterBox({
background-position: center;
`;
if (!self.get_parent()._dragging) {
self.setCss(self._bgStyle);
}
}).catch((err) => {
if (err !== '') {
print(err);
}
});
}]],
if (!self.get_parent()._dragging) {
self.setCss(self._bgStyle);
}
}).catch((err) => {
if (err !== '') {
print(err);
}
});
});
},
});
export const TitleLabel = (player, props) => Label({
@ -127,27 +127,31 @@ export const PlayerIcon = (player, overlay, props) => {
className: widget ? 'position-indicator' : 'player-icon',
size: widget ? '' : ICON_SIZE,
connections: [[p, (self) => {
self.icon = lookUpIcon(p.entry) ?
p.entry :
icons.mpris.fallback;
}]],
setup: (self) => {
self.hook(p, () => {
self.icon = lookUpIcon(p.entry) ?
p.entry :
icons.mpris.fallback;
});
},
}),
});
return Box({
connections: [[Mpris, (self) => {
const thisIndex = overlay.list()
.indexOf(self.get_parent().get_parent());
setup: (self) => {
self.hook(Mpris, () => {
const thisIndex = overlay.list()
.indexOf(self.get_parent().get_parent());
self.children = overlay.list().map((over, i) => {
self.children.push(Separator(2));
self.children = overlay.list().map((over, i) => {
self.children.push(Separator(2));
return i === thisIndex ?
playerIcon(player) :
playerIcon(over._player, overlay, over);
}).reverse();
}]],
return i === thisIndex ?
playerIcon(player) :
playerIcon(over._player, overlay, over);
}).reverse();
});
},
});
};
@ -163,38 +167,38 @@ export const PositionSlider = (player, props) => Slider({
player.position = player.length * value;
},
properties: [['update', (slider) => {
if (!slider.dragging) {
slider.visible = player.length > 0;
if (player.length > 0) {
slider.value = player.position / player.length;
setup: (self) => {
const update = () => {
if (!self.dragging) {
self.visible = player.length > 0;
if (player.length > 0) {
self.value = player.position / player.length;
}
}
}
}]],
};
connections: [
[1000, (s) => s._update(s)],
[player, (s) => s._update(s), 'position'],
[player.colors, (s) => {
if (player.colors.value) {
const c = player.colors.value;
self
.poll(1000, () => update())
.hook(player, () => update(), 'position')
.hook(player.colors, () => {
if (player.colors.value) {
const c = player.colors.value;
s.setCss(`
highlight { background-color: ${c.buttonAccent}; }
slider { background-color: ${c.buttonAccent}; }
slider:hover { background-color: ${c.hoverAccent}; }
trough { background-color: ${c.buttonText}; }
`);
}
}],
['button-press-event', (s) => {
s.cursor = 'grabbing';
}],
['button-release-event', (s) => {
s.cursor = 'pointer';
}],
],
self.setCss(`
highlight { background-color: ${c.buttonAccent}; }
slider { background-color: ${c.buttonAccent}; }
slider:hover { background-color: ${c.hoverAccent}; }
trough { background-color: ${c.buttonText}; }
`);
}
})
.on('button-press-event', (s) => {
s.cursor = 'grabbing';
})
.on('button-release-event', (s) => {
s.cursor = 'pointer';
});
},
});
const PlayerButton = ({ player, items, onClick, prop }) => EventBox({
@ -212,13 +216,13 @@ const PlayerButton = ({ player, items, onClick, prop }) => EventBox({
items.forEach((item) => {
item[1].setCss(`
background-color: ${c.hoverAccent};
color: ${c.buttonText};
min-height: 40px;
min-width: 36px;
margin-bottom: 1px;
margin-right: 1px;
`);
background-color: ${c.hoverAccent};
color: ${c.buttonText};
min-height: 40px;
min-width: 36px;
margin-bottom: 1px;
margin-right: 1px;
`);
});
}
},
@ -230,60 +234,61 @@ const PlayerButton = ({ player, items, onClick, prop }) => EventBox({
items.forEach((item) => {
item[1].setCss(`
background-color: ${c.buttonAccent};
color: ${c.buttonText};
min-height: 42px;
min-width: 38px;
`);
background-color: ${c.buttonAccent};
color: ${c.buttonText};
min-height: 42px;
min-width: 38px;
`);
});
}
},
connections: [
[player, (button) => {
button.child.shown = `${player[prop]}`;
}],
setup: (self) => {
self
.hook(player, () => {
self.child.shown = `${player[prop]}`;
})
.hook(player.colors, () => {
if (!Mpris.players.find((p) => player === p)) {
return;
}
[player.colors, (button) => {
if (!Mpris.players.find((p) => player === p)) {
return;
}
if (player.colors.value) {
const c = player.colors.value;
if (player.colors.value) {
const c = player.colors.value;
if (prop === 'playBackStatus') {
if (button._hovered) {
items.forEach((item) => {
item[1].setCss(`
background-color: ${c.hoverAccent};
color: ${c.buttonText};
min-height: 40px;
min-width: 36px;
margin-bottom: 1px;
margin-right: 1px;
`);
});
if (prop === 'playBackStatus') {
if (self._hovered) {
items.forEach((item) => {
item[1].setCss(`
background-color: ${c.hoverAccent};
color: ${c.buttonText};
min-height: 40px;
min-width: 36px;
margin-bottom: 1px;
margin-right: 1px;
`);
});
}
else {
items.forEach((item) => {
item[1].setCss(`
background-color: ${c.buttonAccent};
color: ${c.buttonText};
min-height: 42px;
min-width: 38px;
`);
});
}
}
else {
items.forEach((item) => {
item[1].setCss(`
background-color: ${c.buttonAccent};
color: ${c.buttonText};
min-height: 42px;
min-width: 38px;`);
});
self.setCss(`
* { color: ${c.buttonAccent}; }
*:hover { color: ${c.hoverAccent}; }
`);
}
}
else {
button.setCss(`
* { color: ${c.buttonAccent}; }
*:hover { color: ${c.hoverAccent}; }
`);
}
}
}],
],
});
},
}),
});

View file

@ -107,72 +107,72 @@ export default () => {
['setup', false],
],
connections: [
[Mpris, (overlay, busName) => {
if (overlay._players.has(busName)) {
return;
}
// Sometimes the signal doesn't give the busName
if (!busName) {
const player = Mpris.players.find((p) => {
return !overlay._players.has(p.busName);
});
if (player) {
busName = player.busName;
}
else {
setup: (self) => {
self
.hook(Mpris, (overlay, busName) => {
if (overlay._players.has(busName)) {
return;
}
}
// Get the one on top so we can move it up later
const previousFirst = overlay.list().at(-1);
// Sometimes the signal doesn't give the busName
if (!busName) {
const player = Mpris.players.find((p) => {
return !overlay._players.has(p.busName);
});
// Make the new player
const player = Mpris.getPlayer(busName);
if (player) {
busName = player.busName;
}
else {
return;
}
}
player.colors = Variable();
overlay._players.set(
busName,
PlayerBox(player, content.getOverlay()),
);
overlay.overlays = Array.from(overlay._players.values())
.map((widget) => widget);
// Get the one on top so we can move it up later
const previousFirst = overlay.list().at(-1);
// Select favorite player at startup
if (!overlay._setup && overlay._players.has(FAVE_PLAYER)) {
overlay.moveToTop(overlay._players.get(FAVE_PLAYER));
overlay._setup = true;
}
// Make the new player
const player = Mpris.getPlayer(busName);
// Move previousFirst on top again
else if (overlay.includesWidget(previousFirst)) {
overlay.moveToTop(previousFirst);
}
}, 'player-added'],
player.colors = Variable();
overlay._players.set(
busName,
PlayerBox(player, content.getOverlay()),
);
overlay.overlays = Array.from(overlay._players.values())
.map((widget) => widget);
// Select favorite player at startup
if (!overlay._setup && overlay._players.has(FAVE_PLAYER)) {
overlay.moveToTop(overlay._players.get(FAVE_PLAYER));
overlay._setup = true;
}
[Mpris, (overlay, busName) => {
if (!busName || !overlay._players.has(busName)) {
return;
}
// Move previousFirst on top again
else if (overlay.includesWidget(previousFirst)) {
overlay.moveToTop(previousFirst);
}
}, 'player-added')
// Get the one on top so we can move it up later
const previousFirst = overlay.list().at(-1);
.hook(Mpris, (overlay, busName) => {
if (!busName || !overlay._players.has(busName)) {
return;
}
// Remake overlays without deleted one
overlay._players.delete(busName);
overlay.overlays = Array.from(overlay._players.values())
.map((widget) => widget);
// Get the one on top so we can move it up later
const previousFirst = overlay.list().at(-1);
// Move previousFirst on top again
if (overlay.includesWidget(previousFirst)) {
overlay.moveToTop(previousFirst);
}
}, 'player-closed'],
],
// Remake overlays without deleted one
overlay._players.delete(busName);
overlay.overlays = Array.from(overlay._players.values())
.map((widget) => widget);
// Move previousFirst on top again
if (overlay.includesWidget(previousFirst)) {
overlay.moveToTop(previousFirst);
}
}, 'player-closed');
},
});
return Box({

View file

@ -42,7 +42,7 @@ export default ({
const gesture = Gtk.GestureLongPress.new(widget);
widget.connectTo(gesture, () => {
widget.hook(gesture, () => {
const pointer = gesture.get_point(null);
const x = pointer[1];
const y = pointer[2];

View file

@ -58,20 +58,22 @@ export default ({
transition,
transitionDuration,
connections: [[App, (rev, currentName, isOpen) => {
if (currentName === name) {
rev.revealChild = isOpen;
setup: (self) => {
self.hook(App, (_, currentName, isOpen) => {
if (currentName === name) {
self.revealChild = isOpen;
if (isOpen) {
onOpen(window);
if (isOpen) {
onOpen(window);
}
else {
timeout(transitionDuration, () => {
onClose(window);
});
}
}
else {
timeout(transitionDuration, () => {
onClose(window);
});
}
}
}]],
});
},
child: child || Box(),
}),

View file

@ -28,28 +28,30 @@ const NotificationList = () => Box({
vexpand: true,
vpack: 'start',
binds: [['visible', HasNotifs]],
connections: [
[Notifications, (box, id) => {
// Handle cached notifs
if (box.children.length === 0) {
Notifications.notifications.forEach((n) => {
addNotif(box, n);
});
}
else if (id) {
addNotif(box, Notifications.getNotification(id));
}
}, 'notified'],
setup: (self) => {
self
.hook(Notifications, (box, id) => {
// Handle cached notifs
if (box.children.length === 0) {
Notifications.notifications.forEach((n) => {
addNotif(box, n);
});
}
[Notifications, (box, id) => {
const notif = box.children.find((ch) => ch._id === id);
else if (id) {
addNotif(box, Notifications.getNotification(id));
}
}, 'notified')
if (notif?.sensitive) {
notif.slideAway('Right');
}
}, 'closed'],
],
.hook(Notifications, (box, id) => {
const notif = box.children.find((ch) => ch._id === id);
if (notif?.sensitive) {
notif.slideAway('Right');
}
}, 'closed');
},
});
// Needs to be wrapped to still have onHover when disabled
@ -64,11 +66,13 @@ const ClearButton = () => EventBox({
children: [
Label('Clear '),
Icon({
connections: [[Notifications, (self) => {
self.icon = Notifications.notifications.length > 0 ?
'user-trash-full-symbolic' :
'user-trash-symbolic';
}]],
setup: (self) => {
self.hook(Notifications, () => {
self.icon = Notifications.notifications.length > 0 ?
'user-trash-full-symbolic' :
'user-trash-symbolic';
});
},
}),
],
}),

View file

@ -91,80 +91,80 @@ export default ({
widget.add(Box({
css: squeezeLeft,
connections: [
setup: (self) => {
self
// When dragging
.hook(gesture, () => {
let offset = gesture.get_offset()[1];
// When dragging
[gesture, (self) => {
let offset = gesture.get_offset()[1];
if (offset === 0) {
return;
}
if (offset === 0) {
return;
}
// Slide right
if (offset > 0) {
self.setCss(`
// Slide right
if (offset > 0) {
self.setCss(`
margin-top: 0px; margin-bottom: 0px;
opacity: 1; transition: none;
margin-left: ${offset}px;
margin-right: -${offset}px;
`);
}
}
// Slide left
else {
offset = Math.abs(offset);
self.setCss(`
// Slide left
else {
offset = Math.abs(offset);
self.setCss(`
margin-top: 0px; margin-bottom: 0px;
opacity: 1; transition: none;
margin-right: ${offset}px;
margin-left: -${offset}px;
`);
}
}
// Put a threshold on if a click is actually dragging
widget._dragging = Math.abs(offset) > SLIDE_MIN_THRESHOLD;
widget.cursor = 'grabbing';
}, 'drag-update'],
// Put a threshold on if a click is actually dragging
widget._dragging = Math.abs(offset) > SLIDE_MIN_THRESHOLD;
widget.cursor = 'grabbing';
}, 'drag-update')
// On drag end
.hook(gesture, () => {
// Make it slide in on init
if (!widget.ready) {
// Reverse of slideAway, so it started at squeeze, then we go to slide
self.setCss(slideIn === 'Left' ?
slideLeft :
slideRight);
// On drag end
[gesture, (self) => {
// Make it slide in on init
if (!widget.ready) {
// Reverse of slideAway, so it started at squeeze, then we go to slide
self.setCss(slideIn === 'Left' ? slideLeft : slideRight);
timeout(ANIM_DURATION, () => {
// Then we go to center
self.setCss(defaultStyle);
timeout(ANIM_DURATION, () => {
widget.ready = true;
// Then we go to center
self.setCss(defaultStyle);
timeout(ANIM_DURATION, () => {
widget.ready = true;
});
});
});
return;
}
return;
}
const offset = gesture.get_offset()[1];
const offset = gesture.get_offset()[1];
// If crosses threshold after letting go, slide away
if (Math.abs(offset) > MAX_OFFSET) {
if (offset > 0) {
widget.slideAway('Right');
// If crosses threshold after letting go, slide away
if (Math.abs(offset) > MAX_OFFSET) {
if (offset > 0) {
widget.slideAway('Right');
}
else {
widget.slideAway('Left');
}
}
else {
widget.slideAway('Left');
self.setCss(defaultStyle);
widget.cursor = 'grab';
widget._dragging = false;
}
}
else {
self.setCss(defaultStyle);
widget.cursor = 'grab';
widget._dragging = false;
}
}, 'drag-end'],
],
}, 'drag-end');
},
}));
return widget;

View file

@ -10,56 +10,57 @@ import { Notification } from './base.js';
const DELAY = 2000;
const addPopup = (box, id) => {
if (!id) {
return;
}
const notif = Notifications.getNotification(id);
const NewNotif = Notification({
notif,
command: () => notif.dismiss(),
});
if (NewNotif) {
// Use this instead of add to put it at the top
box.pack_end(NewNotif, false, false, 0);
box.show_all();
}
};
const handleDismiss = (box, id, force = false) => {
const notif = box.children.find((ch) => ch._id === id);
if (!notif) {
return;
}
// If notif isn't hovered or was closed, slide away
if (!notif._hovered || force) {
notif.slideAway('Left');
}
// If notif is hovered, delay close
else if (notif._hovered) {
notif.interval = interval(DELAY, () => {
if (!notif._hovered && notif.interval) {
notif.slideAway('Left');
GLib.source_remove(notif.interval);
notif.interval = null;
}
});
}
};
export default () => Box({
vertical: true,
connections: [
[Notifications, (s, id) => addPopup(s, id), 'notified'],
[Notifications, (s, id) => handleDismiss(s, id), 'dismissed'],
[Notifications, (s, id) => handleDismiss(s, id, true), 'closed'],
],
setup: (self) => {
const addPopup = (id) => {
if (!id) {
return;
}
const notif = Notifications.getNotification(id);
const NewNotif = Notification({
notif,
command: () => notif.dismiss(),
});
if (NewNotif) {
// Use this instead of add to put it at the top
self.pack_end(NewNotif, false, false, 0);
self.show_all();
}
};
const handleDismiss = (id, force = false) => {
const notif = self.children.find((ch) => ch._id === id);
if (!notif) {
return;
}
// If notif isn't hovered or was closed, slide away
if (!notif._hovered || force) {
notif.slideAway('Left');
}
// If notif is hovered, delay close
else if (notif._hovered) {
notif.interval = interval(DELAY, () => {
if (!notif._hovered && notif.interval) {
notif.slideAway('Left');
GLib.source_remove(notif.interval);
notif.interval = null;
}
});
}
};
self
.hook(Notifications, (_, id) => addPopup(id), 'notified')
.hook(Notifications, (_, id) => handleDismiss(id), 'dismissed')
.hook(Notifications, (_, id) => handleDismiss(id, true), 'closed');
},
});

View file

@ -37,15 +37,17 @@ export default (window) => Box({
active: true,
vpack: 'center',
connections: [['toggled', (self) => {
self.toggleClassName(
'toggled',
self.get_active(),
);
window.exclusivity = self.get_active() ?
'exclusive' :
'normal';
}]],
setup: (self) => {
self.on('toggled', () => {
self.toggleClassName(
'toggled',
self.get_active(),
);
window.exclusivity = self.get_active() ?
'exclusive' :
'normal';
});
},
child: Label('Exclusive'),
}),

View file

@ -86,11 +86,13 @@ const ModKey = (key) => {
self.child.toggleClassName('active', !Mod.value);
Mod.value = !Mod.value;
},
connections: [[NormalClick, (self) => {
Mod.value = false;
self.child.toggleClassName('active', false);
execAsync(`ydotool key ${key.keycode}:0`);
}]],
setup: (self) => {
self.hook(NormalClick, () => {
Mod.value = false;
self.child.toggleClassName('active', false);
execAsync(`ydotool key ${key.keycode}:0`);
});
},
child: Label({
class_name: `mod ${key.label}`,
label: key.label,
@ -114,40 +116,41 @@ const RegularKey = (key) => {
class_name: `normal ${key.label}`,
label: key.label,
connections: [
[Shift, (self) => {
if (!key.labelShift) {
return;
}
setup: (self) => {
self
.hook(Shift, () => {
if (!key.labelShift) {
return;
}
self.label = Shift.value ? key.labelShift : key.label;
}],
self.label = Shift.value ? key.labelShift : key.label;
})
.hook(Caps, () => {
if (key.label === 'Caps') {
self.toggleClassName('active', Caps.value);
[Caps, (self) => {
if (key.label === 'Caps') {
self.toggleClassName('active', Caps.value);
return;
}
return;
}
if (!key.labelShift) {
return;
}
if (!key.labelShift) {
return;
}
if (key.label.match(/[A-Za-z]/)) {
self.label = Caps.value ?
key.labelShift :
key.label;
}
})
.hook(AltGr, () => {
if (!key.labelAltGr) {
return;
}
if (key.label.match(/[A-Za-z]/)) {
self.label = Caps.value ? key.labelShift : key.label;
}
}],
[AltGr, (self) => {
if (!key.labelAltGr) {
return;
}
self.toggleClassName('altgr', AltGr.value);
self.label = AltGr.value ? key.labelAltGr : key.label;
}],
],
self.toggleClassName('altgr', AltGr.value);
self.label = AltGr.value ? key.labelAltGr : key.label;
});
},
}),
});
@ -156,7 +159,7 @@ const RegularKey = (key) => {
gesture.delay_factor = 1.0;
// Long press
widget.connectTo(gesture, () => {
widget.hook(gesture, () => {
const pointer = gesture.get_point(null);
const x = pointer[1];
const y = pointer[2];
@ -171,7 +174,7 @@ const RegularKey = (key) => {
}, 'pressed');
// OnPrimaryClickRelease
widget.connectTo(gesture, () => {
widget.hook(gesture, () => {
const pointer = gesture.get_point(null);
const x = pointer[1];
const y = pointer[2];

View file

@ -16,17 +16,18 @@ export default () => {
visible: false,
anchor: ['left', 'bottom', 'right'],
connections: [
[Tablet, (self, state) => {
self.setVisible(state);
}, 'osk-toggled'],
setup: (self) => {
self
.hook(Tablet, (_, state) => {
self.setVisible(state);
}, 'osk-toggled')
[Tablet, () => {
if (!Tablet.tabletMode && !Tablet.oskState) {
window.visible = false;
}
}, 'mode-toggled'],
],
.hook(Tablet, () => {
if (!Tablet.tabletMode && !Tablet.oskState) {
window.visible = false;
}
}, 'mode-toggled');
},
});
window.child = Keyboard(window);

View file

@ -36,7 +36,7 @@ export default ({ stack, icon, info } = {}) => {
connectFunc = () => stack.popup(osd);
}
osd.children[0].children[1].connectTo(info.mod, connectFunc, info.signal);
osd.children[0].children[1].hook(info.mod, connectFunc, info.signal);
return osd;
};

View file

@ -33,28 +33,28 @@ let hidden = 0;
export const WorkspaceDrop = (props) => EventBox({
...props,
connections: [['drag-data-received', (self, _c, _x, _y, data) => {
let id = self.get_parent()._id;
if (id < -1) {
id = self.get_parent()._name;
}
else if (id === -1) {
id = `special:${++hidden}`;
}
else if (id === 1000) {
id = 'empty';
}
Hyprland.sendMessage('dispatch ' +
`movetoworkspacesilent ${id},address:${data.get_text()}`)
.catch(print);
}]],
setup: (self) => {
self.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY);
self.on('drag-data-received', (_, _c, _x, _y, data) => {
let id = self.get_parent()._id;
if (id < -1) {
id = self.get_parent()._name;
}
else if (id === -1) {
id = `special:${++hidden}`;
}
else if (id === 1000) {
id = 'empty';
}
Hyprland.sendMessage('dispatch ' +
`movetoworkspacesilent ${id},address:${data.get_text()}`)
.catch(print);
});
},
});
@ -69,16 +69,16 @@ export const WindowButton = ({ address, mainBox, ...props } = {}) => Button({
Gdk.DragAction.COPY,
);
self.connect('drag-data-get', (_w, _c, data) => {
self.on('drag-data-get', (_w, _c, data) => {
data.set_text(address, address.length);
});
self.connect('drag-begin', (_, context) => {
self.on('drag-begin', (_, context) => {
Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(self));
self.get_parent().revealChild = false;
});
self.connect('drag-end', () => {
self.on('drag-end', () => {
self.get_parent().destroy();
updateClients(mainBox);

View file

@ -40,13 +40,15 @@ export const Overview = () => {
}),
],
connections: [[Hyprland, (self) => {
if (!App.getWindow('overview').visible) {
return;
}
setup: (self) => {
self.hook(Hyprland, () => {
if (!App.getWindow('overview').visible) {
return;
}
self.update();
}]],
self.update();
});
},
properties: [
['workspaces'],
@ -72,15 +74,17 @@ export const Overview = () => {
}),
// TODO: throttle his?
connections: [['get-child-position', (self, ch) => {
if (ch === mainBox) {
self.child.setCss(`
transition: min-height 0.2s ease, min-width 0.2s ease;
min-height: ${mainBox.get_allocated_height()}px;
min-width: ${mainBox.get_allocated_width()}px;
`);
}
}]],
setup: (self) => {
self.on('get-child-position', (_, ch) => {
if (ch === mainBox) {
self.child.setCss(`
transition: min-height 0.2s ease, min-width 0.2s ease;
min-height: ${mainBox.get_allocated_height()}px;
min-width: ${mainBox.get_allocated_width()}px;
`);
}
});
},
});
widget.getChild = () => mainBox;

View file

@ -31,17 +31,17 @@ const Workspace = (id, name, normal = true) => {
transition: 'slide_right',
transitionDuration: 500,
connections: normal ?
setup: (self) => {
if (normal) {
self.hook(Hyprland, () => {
const activeId = Hyprland.active.workspace.id;
const active = activeId === self._id;
[[Hyprland, (box) => {
const activeId = Hyprland.active.workspace.id;
const active = activeId === box._id;
box.revealChild = Hyprland.getWorkspace(box._id)
?.windows > 0 || active;
}]] :
[],
self.revealChild = Hyprland.getWorkspace(self._id)
?.windows > 0 || active;
});
}
},
child: WorkspaceDrop({
child: Box({
@ -88,38 +88,42 @@ export const WorkspaceRow = (className, i) => {
transition: 'slide_down',
hpack: className === 'special' ? '' : 'start',
connections: [[Hyprland, (rev) => {
const minId = i * VARS.WORKSPACE_PER_ROW;
const activeId = Hyprland.active.workspace.id;
setup: (self) => {
self.hook(Hyprland, (rev) => {
const minId = i * VARS.WORKSPACE_PER_ROW;
const activeId = Hyprland.active.workspace.id;
const rowExists = Hyprland.workspaces.some((ws) => {
const isInRow = ws.id > minId;
const hasClients = ws.windows > 0;
const isActive = ws.id === activeId;
const rowExists = Hyprland.workspaces.some((ws) => {
const isInRow = ws.id > minId;
const hasClients = ws.windows > 0;
const isActive = ws.id === activeId;
return isInRow && (hasClients || isActive);
return isInRow && (hasClients || isActive);
});
rev.revealChild = rowExists;
});
rev.revealChild = rowExists;
}]],
},
child: CenterBox({
children: [null, EventBox({
connections: [[Hyprland, () => {
const maxId = (i + 1) * VARS.WORKSPACE_PER_ROW;
const activeId = Hyprland.active.workspace.id;
setup: (self) => {
self.hook(Hyprland, () => {
const maxId = (i + 1) * VARS.WORKSPACE_PER_ROW;
const activeId = Hyprland.active.workspace.id;
const isSpecial = className === 'special';
const nextRowExists = Hyprland.workspaces.some((ws) => {
const isInNextRow = ws.id > maxId;
const hasClients = ws.windows > 0;
const isActive = ws.id === activeId;
const isSpecial = className === 'special';
const nextRowExists = Hyprland.workspaces.some((ws) => {
const isInNextRow = ws.id > maxId;
const hasClients = ws.windows > 0;
const isActive = ws.id === activeId;
return isInNextRow && (hasClients || isActive);
return isInNextRow && (hasClients || isActive);
});
addWorkspace.revealChild = isSpecial || !nextRowExists;
});
addWorkspace.revealChild = isSpecial || !nextRowExists;
}]],
},
child: Box({
className,

View file

@ -5,8 +5,8 @@ import { Box, Icon, Label, ListBox, Overlay, Revealer, Scrollable } from 'resour
import EventBox from '../misc/cursorbox.js';
const SCROLL_THRESHOLD_H = 200;
const SCROLL_THRESHOLD_N = 7;
const SCROLL_THRESH_H = 200;
const SCROLL_THRESH_N = 7;
const BluetoothDevice = (dev) => {
@ -29,9 +29,11 @@ const BluetoothDevice = (dev) => {
icon: 'object-select-symbolic',
hexpand: true,
hpack: 'end',
connections: [[dev, (self) => {
self.setCss(`opacity: ${dev.paired ? '1' : '0'};`);
}]],
setup: (self) => {
self.hook(dev, () => {
self.setCss(`opacity: ${dev.paired ? '1' : '0'};`);
});
},
}),
],
});
@ -95,17 +97,19 @@ export const BluetoothMenu = () => {
hscroll: 'never',
vscroll: 'never',
connections: [['edge-reached', (_, pos) => {
// Manage scroll indicators
if (pos === 2) {
topArrow.revealChild = false;
bottomArrow.revealChild = true;
}
else if (pos === 3) {
topArrow.revealChild = true;
bottomArrow.revealChild = false;
}
}]],
setup: (self) => {
self.on('edge-reached', (_, pos) => {
// Manage scroll indicators
if (pos === 2) {
topArrow.revealChild = false;
bottomArrow.revealChild = true;
}
else if (pos === 3) {
topArrow.revealChild = true;
bottomArrow.revealChild = false;
}
});
},
child: ListBox({
setup: (self) => {
@ -113,78 +117,79 @@ export const BluetoothMenu = () => {
return b.get_children()[0].dev.paired -
a.get_children()[0].dev.paired;
});
},
connections: [[Bluetooth, (box) => {
// Get all devices
const Devices = [].concat(
Bluetooth.devices,
Bluetooth.connectedDevices,
);
self.hook(Bluetooth, () => {
// Get all devices
const Devices = [].concat(
Bluetooth.devices,
Bluetooth.connectedDevices,
);
// Add missing devices
Devices.forEach((dev) => {
if (!DevList.has(dev) && dev.name) {
DevList.set(dev, BluetoothDevice(dev));
// Add missing devices
Devices.forEach((dev) => {
if (!DevList.has(dev) && dev.name) {
DevList.set(dev, BluetoothDevice(dev));
box.add(DevList.get(dev));
box.show_all();
}
});
self.add(DevList.get(dev));
self.show_all();
}
});
// Delete ones that don't exist anymore
const difference = Array.from(DevList.keys())
.filter((dev) => !Devices
.find((d) => dev === d) &&
// Delete ones that don't exist anymore
const difference = Array.from(DevList.keys())
.filter((dev) => !Devices
.find((d) => dev === d) &&
dev.name);
difference.forEach((dev) => {
const devWidget = DevList.get(dev);
difference.forEach((dev) => {
const devWidget = DevList.get(dev);
if (devWidget) {
if (devWidget.toDestroy) {
devWidget.get_parent().destroy();
DevList.delete(dev);
if (devWidget) {
if (devWidget.toDestroy) {
devWidget.get_parent().destroy();
DevList.delete(dev);
}
else {
devWidget.children[0]
.revealChild = false;
devWidget.toDestroy = true;
}
}
else {
devWidget.children[0].revealChild = false;
devWidget.toDestroy = true;
});
// Start scrolling after a specified height
// is reached by the children
const height = Math.max(
self.get_parent().get_allocated_height(),
SCROLL_THRESH_H,
);
const scroll = self.get_parent().get_parent();
if (self.get_children().length > SCROLL_THRESH_N) {
scroll.vscroll = 'always';
scroll.setCss(`min-height: ${height}px;`);
// Make bottom scroll indicator appear only
// when first getting overflowing children
if (!(bottomArrow.revealChild === true ||
topArrow.revealChild === true)) {
bottomArrow.revealChild = true;
}
}
});
// Start scrolling after a specified height
// is reached by the children
const height = Math.max(
box.get_parent().get_allocated_height(),
SCROLL_THRESHOLD_H,
);
const scroll = box.get_parent().get_parent();
if (box.get_children().length > SCROLL_THRESHOLD_N) {
scroll.vscroll = 'always';
scroll.setCss(`min-height: ${height}px;`);
// Make bottom scroll indicator appear only
// when first getting overflowing children
if (!(bottomArrow.revealChild === true ||
topArrow.revealChild === true)) {
bottomArrow.revealChild = true;
else {
scroll.vscroll = 'never';
scroll.setCss('');
topArrow.revealChild = false;
bottomArrow.revealChild = false;
}
}
else {
scroll.vscroll = 'never';
scroll.setCss('');
topArrow.revealChild = false;
bottomArrow.revealChild = false;
}
// Trigger sort_func
box.get_children().forEach((ch) => {
ch.changed();
// Trigger sort_func
self.get_children().forEach((ch) => {
ch.changed();
});
});
}]],
},
}),
}),
}),

View file

@ -34,24 +34,27 @@ const GridButton = ({
icon = Icon({
className: 'grid-label',
icon,
connections: [[Activated, (self) => {
self.setCss(`color: ${Activated.value ?
'rgba(189, 147, 249, 0.8)' :
'unset'};`);
}]],
setup: (self) => {
self.hook(Activated, () => {
self.setCss(`color: ${Activated.value ?
'rgba(189, 147, 249, 0.8)' :
'unset'};`);
});
},
});
}
else {
icon = Icon({
className: 'grid-label',
connections: [
icon,
[Activated, (self) => {
self.setCss(`color: ${Activated.value ?
'rgba(189, 147, 249, 0.8)' :
'unset'};`);
}],
],
setup: (self) => {
self
.hook(...icon)
.hook(Activated, () => {
self.setCss(`color: ${Activated.value ?
'rgba(189, 147, 249, 0.8)' :
'unset'};`);
});
},
});
}
@ -61,7 +64,9 @@ const GridButton = ({
justification: 'left',
truncate: 'end',
maxWidthChars: 12,
connections: [indicator],
setup: (self) => {
self.hook(...indicator);
},
});
}
@ -126,17 +131,19 @@ const GridButton = ({
icon: `${App.configDir }/icons/down-large.svg`,
className: 'grid-chev',
connections: [[Activated, (self) => {
let deg = 270;
setup: (self) => {
self.hook(Activated, () => {
let deg = 270;
if (Activated.value) {
deg = menu ? 360 : 450;
onOpen(menu);
}
self.setCss(`
-gtk-icon-transform: rotate(${deg}deg);
`);
}]],
if (Activated.value) {
deg = menu ? 360 : 450;
onOpen(menu);
}
self.setCss(`
-gtk-icon-transform: rotate(${deg}deg);
`);
});
},
}),
}),

View file

@ -7,8 +7,8 @@ import { execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
import EventBox from '../misc/cursorbox.js';
const SCROLL_THRESHOLD_H = 200;
const SCROLL_THRESHOLD_N = 7;
const SCROLL_THRESH_H = 200;
const SCROLL_THRESH_N = 7;
const AccessPoint = (ap) => {
@ -22,28 +22,37 @@ const AccessPoint = (ap) => {
hexpand: true,
children: [
Icon({
connections: [[widget.ap, (self) => {
self.icon = widget.ap.value.iconName;
}]],
setup: (self) => {
self.hook(widget.ap, () => {
self.icon = widget.ap.value.iconName;
});
},
}),
Label({
connections: [[widget.ap, (self) => {
self.label = widget.ap.value.ssid || '';
}]],
setup: (self) => {
self.hook(widget.ap, () => {
self.label = widget.ap.value.ssid || '';
});
},
}),
Icon({
icon: 'object-select-symbolic',
hexpand: true,
hpack: 'end',
connections: [[Network, (self) => {
self.setCss(`opacity: ${
widget.ap.value.ssid === Network.wifi.ssid ?
'1' :
'0'
};`);
}]],
setup: (self) => {
self.hook(Network, () => {
self.setCss(
`opacity: ${
widget.ap.value.ssid === Network.wifi.ssid ?
'1' :
'0'
};
`,
);
});
},
}),
],
});
@ -109,17 +118,19 @@ export const NetworkMenu = () => {
hscroll: 'never',
vscroll: 'never',
connections: [['edge-reached', (_, pos) => {
// Manage scroll indicators
if (pos === 2) {
topArrow.revealChild = false;
bottomArrow.revealChild = true;
}
else if (pos === 3) {
topArrow.revealChild = true;
bottomArrow.revealChild = false;
}
}]],
setup: (self) => {
self.on('edge-reached', (_, pos) => {
// Manage scroll indicators
if (pos === 2) {
topArrow.revealChild = false;
bottomArrow.revealChild = true;
}
else if (pos === 3) {
topArrow.revealChild = true;
bottomArrow.revealChild = false;
}
});
},
child: ListBox({
setup: (self) => {
@ -127,82 +138,83 @@ export const NetworkMenu = () => {
return b.get_children()[0].ap.value.strength -
a.get_children()[0].ap.value.strength;
});
},
connections: [[Network, (box) => {
// Add missing APs
Network.wifi?.access_points.forEach((ap) => {
if (ap.ssid !== 'Unknown') {
if (APList.has(ap.ssid)) {
const accesPoint = APList.get(ap.ssid)
.ap.value;
self.hook(Network, () => {
// Add missing APs
Network.wifi?.access_points.forEach((ap) => {
if (ap.ssid !== 'Unknown') {
if (APList.has(ap.ssid)) {
const accesPoint = APList.get(ap.ssid)
.ap.value;
if (accesPoint.strength < ap.strength) {
APList.get(ap.ssid).ap.value = ap;
if (accesPoint.strength < ap.strength) {
APList.get(ap.ssid).ap.value = ap;
}
}
else {
APList.set(ap.ssid, AccessPoint(ap));
self.add(APList.get(ap.ssid));
self.show_all();
}
}
else {
APList.set(ap.ssid, AccessPoint(ap));
});
box.add(APList.get(ap.ssid));
box.show_all();
// Delete ones that don't exist anymore
const difference = Array.from(APList.keys())
.filter((ssid) => !Network.wifi.access_points
.find((ap) => ap.ssid === ssid) &&
ssid !== 'Unknown');
difference.forEach((ssid) => {
const apWidget = APList.get(ssid);
if (apWidget) {
if (apWidget.toDestroy) {
apWidget.get_parent().destroy();
APList.delete(ssid);
}
else {
apWidget.children[0]
.revealChild = false;
apWidget.toDestroy = true;
}
}
});
// Start scrolling after a specified height
// is reached by the children
const height = Math.max(
self.get_parent().get_allocated_height(),
SCROLL_THRESH_H,
);
const scroll = self.get_parent().get_parent();
if (self.get_children().length > SCROLL_THRESH_N) {
scroll.vscroll = 'always';
scroll.setCss(`min-height: ${height}px;`);
// Make bottom scroll indicator appear only
// when first getting overflowing children
if (!(bottomArrow.revealChild === true ||
topArrow.revealChild === true)) {
bottomArrow.revealChild = true;
}
}
});
// Delete ones that don't exist anymore
const difference = Array.from(APList.keys())
.filter((ssid) => !Network.wifi.access_points
.find((ap) => ap.ssid === ssid) &&
ssid !== 'Unknown');
difference.forEach((ssid) => {
const apWidget = APList.get(ssid);
if (apWidget) {
if (apWidget.toDestroy) {
apWidget.get_parent().destroy();
APList.delete(ssid);
}
else {
apWidget.children[0].revealChild = false;
apWidget.toDestroy = true;
}
else {
scroll.vscroll = 'never';
scroll.setCss('');
topArrow.revealChild = false;
bottomArrow.revealChild = false;
}
// Trigger sort_func
self.get_children().forEach((ch) => {
ch.changed();
});
});
// Start scrolling after a specified height
// is reached by the children
const height = Math.max(
box.get_parent().get_allocated_height(),
SCROLL_THRESHOLD_H,
);
const scroll = box.get_parent().get_parent();
if (box.get_children().length > SCROLL_THRESHOLD_N) {
scroll.vscroll = 'always';
scroll.setCss(`min-height: ${height}px;`);
// Make bottom scroll indicator appear only
// when first getting overflowing children
if (!(bottomArrow.revealChild === true ||
topArrow.revealChild === true)) {
bottomArrow.revealChild = true;
}
}
else {
scroll.vscroll = 'never';
scroll.setCss('');
topArrow.revealChild = false;
bottomArrow.revealChild = false;
}
// Trigger sort_func
box.get_children().forEach((ch) => {
ch.changed();
});
}]],
},
}),
}),
}),

View file

@ -34,18 +34,20 @@ export default () => Box({
Audio.speaker.volume = value;
},
connections: [
[Audio, (slider) => {
slider.value = Audio.speaker?.volume;
}, 'speaker-changed'],
setup: (self) => {
self
.hook(Audio, () => {
self.value = Audio.speaker?.volume;
}, 'speaker-changed')
['button-press-event', (s) => {
s.cursor = 'grabbing';
}],
['button-release-event', (s) => {
s.cursor = 'pointer';
}],
],
.on('button-press-event', () => {
self.cursor = 'grabbing';
})
.on('button-release-event', () => {
self.cursor = 'pointer';
});
},
}),
],
}),
@ -70,18 +72,20 @@ export default () => Box({
Brightness.screen = value;
},
connections: [
[Brightness, (slider) => {
slider.value = Brightness.screen;
}, 'screen'],
setup: (self) => {
self
.hook(Brightness, () => {
self.value = Brightness.screen;
}, 'screen')
['button-press-event', (s) => {
s.cursor = 'grabbing';
}],
['button-release-event', (s) => {
s.cursor = 'pointer';
}],
],
.on('button-press-event', () => {
self.cursor = 'grabbing';
})
.on('button-release-event', () => {
self.cursor = 'pointer';
});
},
}),
],
}),

View file

@ -14,20 +14,20 @@ export default (rev) => CenterBox({
self.set_active(Mpris.players.length > 0);
Mpris.disconnect(id);
});
},
connections: [['toggled', (self) => {
if (self.get_active()) {
self.get_children()[0]
.setCss('-gtk-icon-transform: rotate(0deg);');
rev.revealChild = true;
}
else {
self.get_children()[0]
.setCss('-gtk-icon-transform: rotate(180deg);');
rev.revealChild = false;
}
}]],
self.on('toggled', () => {
if (self.get_active()) {
self.get_children()[0]
.setCss('-gtk-icon-transform: rotate(0deg);');
rev.revealChild = true;
}
else {
self.get_children()[0]
.setCss('-gtk-icon-transform: rotate(180deg);');
rev.revealChild = false;
}
});
},
child: Icon({
icon: `${App.configDir }/icons/down-large.svg`,

View file

@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1702637287,
"narHash": "sha256-HLXLYcHQfiOvsCF6/X9FY89URAOr/E62tOw8XWgMloU=",
"lastModified": 1702684413,
"narHash": "sha256-GdAkD8HJxsb3j9lOW7XFuRpG9S7OND/i1GjkNok4mj0=",
"owner": "Aylur",
"repo": "ags",
"rev": "6cfc5ace1077ffbf7f323e1f8c040e17dece6910",
"rev": "79d0f0555ba95c00c103aaa8ff3a14b49e2fe24f",
"type": "github"
},
"original": {
@ -314,11 +314,11 @@
]
},
"locked": {
"lastModified": 1702538064,
"narHash": "sha256-At5GwJPu2tzvS9dllhBoZmqK6lkkh/sOp2YefWRlaL8=",
"lastModified": 1702735279,
"narHash": "sha256-SztEzDOE/6bDNnWWvnRbSHPVrgewLwdSei1sxoZFejM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "0e2e443ff24f9d75925e91b89d1da44b863734af",
"rev": "e9b9ecef4295a835ab073814f100498716b05a96",
"type": "github"
},
"original": {
@ -334,11 +334,11 @@
]
},
"locked": {
"lastModified": 1702564334,
"narHash": "sha256-MwzG4YZhag4CFzM7JQJi+/QINCDZPJhue++TXr3Xxo4=",
"lastModified": 1702781283,
"narHash": "sha256-uR/vE/EGJwSEzJS40mEYATwybUODgMgH54l73xkjr0k=",
"owner": "horriblename",
"repo": "hyprgrass",
"rev": "f600c18e0c6672e1b053aa281c8175aef5eafebe",
"rev": "ebc604b2e0e1fba8949675bbd09426f8a5374ab0",
"type": "github"
},
"original": {
@ -358,11 +358,11 @@
"xdph": "xdph"
},
"locked": {
"lastModified": 1702600743,
"narHash": "sha256-gxWffHkvtfarJ3ANJFRO3aohrIgwGVnDpG2WhKfLbf8=",
"lastModified": 1702759678,
"narHash": "sha256-+UGyDbOEvKewPkDD1tj1M3rcBTkX7UgE4zh8N1Hh2+o=",
"owner": "hyprwm",
"repo": "Hyprland",
"rev": "36fa33f7ca2f555cc8581a13c5899effed2bf84b",
"rev": "9ca0c7d814d6039450ff0341556faa1ce9b37e82",
"type": "github"
},
"original": {
@ -426,11 +426,11 @@
]
},
"locked": {
"lastModified": 1702598962,
"narHash": "sha256-uh0Tw7og6xswrrQ9PxEFOCLQXcwQHUynO4bL1fkUJO8=",
"lastModified": 1702771628,
"narHash": "sha256-xU762QNKQZBWlbZ/b1S1a58txXoG+6sIcSCj1TqEn7c=",
"owner": "nix-community",
"repo": "neovim-nightly-overlay",
"rev": "21a2bc2a9f18c49d4c9ba811ab6c6746b8d62580",
"rev": "916b055a001b578567dfa4ccb82aaa210e2f3e20",
"type": "github"
},
"original": {
@ -449,11 +449,11 @@
},
"locked": {
"dir": "contrib",
"lastModified": 1702595978,
"narHash": "sha256-PvcPk+f9ENeY5Jq1nvWpkL12KWeVQFhqQ2a8PLNfP/k=",
"lastModified": 1702769013,
"narHash": "sha256-Kaq//79n61r4e2p5N7g0MDDdUUPOj5+NnUhtLC0k23s=",
"owner": "neovim",
"repo": "neovim",
"rev": "f31f260f0c6449dba4c84071be6bfe91d3cb4993",
"rev": "8f08b1efbd096850c04c2e8e2890d993bd4d9f95",
"type": "github"
},
"original": {
@ -489,11 +489,11 @@
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1702254072,
"narHash": "sha256-48qPUGgw5CY3O1M2r6K5g9mJMyxvG1K9GaAb4tXxmSs=",
"lastModified": 1702743345,
"narHash": "sha256-xvRuGxFJLPbUPrLke4zf9UiqZadeLzV/gSfFTum0K4s=",
"owner": "nix-community",
"repo": "nix-eval-jobs",
"rev": "843dc25cfe93eb620f8dc8825b1de001e5b33e9f",
"rev": "4a1123c42dc9c4c07863a4bfa426f7fcc8f12b90",
"type": "github"
},
"original": {
@ -531,11 +531,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1702516441,
"narHash": "sha256-bhC1cqytO99L9i4BZLjaIEgDP4CpuVf+yP9pIFaWHjE=",
"lastModified": 1702776069,
"narHash": "sha256-NCza/LTcFVu8YMzoo9XqQwzTaYjqb2Q4DMZxG6vWIX8=",
"owner": "fufexan",
"repo": "nix-gaming",
"rev": "dcd1a7c19691646e41a3328aa7d055ec43443b8d",
"rev": "b5bcd1163fff15a3fc9d97e7d148812736212b89",
"type": "github"
},
"original": {
@ -719,11 +719,11 @@
"nixpkgs": "nixpkgs_6"
},
"locked": {
"lastModified": 1702649675,
"narHash": "sha256-sSGEuGpPnXhHWtR8e9XOlKm/OPy2ocfr2vaPDk1n0x4=",
"lastModified": 1702757751,
"narHash": "sha256-fDmMncKTNVVypMjv4Bv7F66MUdmMC3qZUyC+uVjsLs0=",
"owner": "nix-community",
"repo": "nixpkgs-wayland",
"rev": "8248ceefd6f2802d763aa9fc1b8682976ec8cc92",
"rev": "13140e9610b7de62b3f3e1e9d17f779c8d9fa21c",
"type": "github"
},
"original": {
@ -734,11 +734,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1702029940,
"narHash": "sha256-qM3Du0perpLesh5hr87mVPZ79McMUKIWUH7EQMh2kWo=",
"lastModified": 1702539185,
"narHash": "sha256-KnIRG5NMdLIpEkZTnN5zovNYc0hhXjAgv6pfd5Z4c7U=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e9ef8a102c555da4f8f417fe5cf5bd539d8a38b7",
"rev": "aa9d4729cbc99dabacb50e3994dcefb3ea0f7447",
"type": "github"
},
"original": {
@ -782,11 +782,11 @@
},
"nixpkgs_5": {
"locked": {
"lastModified": 1702249933,
"narHash": "sha256-OlqCC8A6OC5n0n4meCklk73V64JcyoJQ+EGa5arhvsI=",
"lastModified": 1702667777,
"narHash": "sha256-qpgZVpFrOEgW0DimJ24UXeFh63TI9fQFXxc58DPtG8Q=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0838486e9183ce39398f01b221766e68b50f405c",
"rev": "203ecda835bcf69633df7183459283543dd4a874",
"type": "github"
},
"original": {
@ -878,11 +878,11 @@
},
"nur": {
"locked": {
"lastModified": 1702640491,
"narHash": "sha256-+mKwkPnutEB1adKn51ykH2SbKXh2gcB4YWrIM9do7IU=",
"lastModified": 1702780981,
"narHash": "sha256-Ct9FHSS6VeFrAyA2/19bL1sq4JIzLfg+0neXvpDwOzY=",
"owner": "nix-community",
"repo": "NUR",
"rev": "476bb9eacb33dace8b614bf35bdc04129faeaae2",
"rev": "ddb4fe1f170116376c1c300883b239d4ce45f939",
"type": "github"
},
"original": {
@ -1116,11 +1116,11 @@
]
},
"locked": {
"lastModified": 1702212301,
"narHash": "sha256-Rvl8BD7mnHZC1Qz6TxT120UyjsGUEdcsthHbEY+1vnU=",
"lastModified": 1702461037,
"narHash": "sha256-ssyGxfGHRuuLHuMex+vV6RMOt7nAo07nwufg9L5GkLg=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "afdd5e48a0869b389027307652a658051c0d2f96",
"rev": "d06b70e5163a903f19009c3f97770014787a080f",
"type": "github"
},
"original": {