refactor(ags): improve typecheck and fix bugs

This commit is contained in:
matt1432 2023-12-19 12:28:29 -05:00
parent da30e6f05f
commit a126d97bbf
12 changed files with 201 additions and 157 deletions

View file

@ -1,15 +1,12 @@
import { Label } from 'resource:///com/github/Aylur/ags/widget.js'; import { Label } from 'resource:///com/github/Aylur/ags/widget.js';
export default () => Label({ export default () => Label({ className: 'clock' })
className: 'clock', .poll(1000, (self) => {
connections: [[1000, (self) => {
const time = imports.gi.GLib const time = imports.gi.GLib
.DateTime.new_now_local(); .DateTime.new_now_local();
self.label = time.format('%a. ') + self.label = time.format('%a. ') +
time.get_day_of_month() + time.get_day_of_month() +
time.format(' %b. %H:%M'); time.format(' %b. %H:%M');
}]], });
})

View file

@ -9,7 +9,7 @@ export const NotifPopups = () => PopupWindow({
anchor: ['bottom', 'left'], anchor: ['bottom', 'left'],
visible: true, visible: true,
transition: 'none', transition: 'none',
closeOnUnfocus: 'stay', close_on_unfocus: 'stay',
monitor: 1, monitor: 1,
child: PopUpsWidget(), child: PopUpsWidget(),

View file

@ -11,7 +11,7 @@ const SPACING = 4;
/** /**
* @param {Label} self * @param {Label} self
* @param {string} layout * @param {string} layout
* @param {void} _ * @param {string} _
*/ */
const getKbdLayout = (self, _, layout) => { const getKbdLayout = (self, _, layout) => {
if (layout) { if (layout) {

View file

@ -9,12 +9,16 @@ export default () => CursorBox({
on_primary_click_release: () => Tablet.toggleOsk(), on_primary_click_release: () => Tablet.toggleOsk(),
setup: (self) => {
self.hook(Tablet, () => {
self.toggleClassName('toggle-on', Tablet.oskState);
}, 'osk-toggled');
},
child: Label({ child: Label({
class_name: 'osk-toggle', class_name: 'osk-toggle',
xalign: 0.6, xalign: 0.6,
label: '󰌌 ', label: '󰌌 ',
}), }),
}).hook(Tablet, (self) => { });
self.toggleClassName('toggle-on', Tablet.oskState);
}, 'osk-toggled');

View file

@ -38,8 +38,11 @@ const SysTray = () => MenuBar({
}, },
setup: (self) => { setup: (self) => {
self /**
.hook(SystemTray, (_, id) => { * @param {import('types/widget').default} _
* @param {string} id
*/
const addTray = (_, id) => {
const item = SystemTray.getItem(id); const item = SystemTray.getItem(id);
if (self.attribute.items.has(id) || !item) { if (self.attribute.items.has(id) || !item) {
@ -58,9 +61,13 @@ const SysTray = () => MenuBar({
self.show_all(); self.show_all();
// @ts-expect-error // @ts-expect-error
w.child.reveal_child = true; w.child.reveal_child = true;
}, 'added') };
.hook(SystemTray, (_, id) => { /**
* @param {import('types/widget').default} _
* @param {string} id
*/
const removeTray = (_, id) => {
if (!self.attribute.items.has(id)) { if (!self.attribute.items.has(id)) {
return; return;
} }
@ -70,7 +77,11 @@ const SysTray = () => MenuBar({
self.attribute.items.get(id).destroy(); self.attribute.items.get(id).destroy();
self.attribute.items.delete(id); self.attribute.items.delete(id);
}); });
}, 'removed'); };
self
.hook(SystemTray, addTray, 'added')
.hook(SystemTray, removeTray, 'removed');
}, },
}); });

View file

@ -9,12 +9,16 @@ export default () => CursorBox({
on_primary_click_release: () => Tablet.toggleMode(), on_primary_click_release: () => Tablet.toggleMode(),
setup: (self) => {
self.hook(Tablet, () => {
self.toggleClassName('toggle-on', Tablet.tabletMode);
}, 'mode-toggled');
},
child: Box({ child: Box({
class_name: 'tablet-toggle', class_name: 'tablet-toggle',
vertical: false, vertical: false,
children: [Label(' 󰦧 ')], children: [Label(' 󰦧 ')],
}), }),
}).hook(Tablet, (self) => { });
self.toggleClassName('toggle-on', Tablet.tabletMode);
}, 'mode-toggled');

View file

@ -7,8 +7,6 @@ import CursorBox from '../../misc/cursorbox.js';
const URGENT_DURATION = 1000; const URGENT_DURATION = 1000;
/** @typedef {import('types/widget.js').Widget} Widget */
/** @property {number} id */ /** @property {number} id */
const Workspace = ({ id }) => { const Workspace = ({ id }) => {
@ -17,7 +15,7 @@ const Workspace = ({ id }) => {
attribute: { id }, attribute: { id },
child: CursorBox({ child: CursorBox({
tooltipText: `${id}`, tooltip_text: `${id}`,
on_primary_click_release: () => { on_primary_click_release: () => {
Hyprland.sendMessage(`dispatch workspace ${id}`); Hyprland.sendMessage(`dispatch workspace ${id}`);
@ -29,7 +27,7 @@ const Workspace = ({ id }) => {
setup: (self) => { setup: (self) => {
/** /**
* @param {Widget} _ * @param {import('types/widgets/box').default} _
* @param {string|undefined} addr * @param {string|undefined} addr
*/ */
const update = (_, addr) => { const update = (_, addr) => {
@ -80,11 +78,11 @@ export default () => {
const L_PADDING = 16; const L_PADDING = 16;
const WS_WIDTH = 30; const WS_WIDTH = 30;
/** @param {Widget} self */ /** @param {import('types/widgets/box').default} self */
const updateHighlight = (self) => { const updateHighlight = (self) => {
const currentId = Hyprland.active.workspace.id; const currentId = Hyprland.active.workspace.id;
// @ts-expect-error // @ts-expect-error
const indicators = self.get_parent().get_children()[0].child.child.children; const indicators = self?.get_parent()?.child.child.child.children;
const currentIndex = Array.from(indicators) const currentIndex = Array.from(indicators)
.findIndex((w) => w.attribute.id === currentId); .findIndex((w) => w.attribute.id === currentId);
@ -92,7 +90,6 @@ export default () => {
return; return;
} }
// @ts-expect-error
self.setCss(`margin-left: ${L_PADDING + (currentIndex * WS_WIDTH)}px`); self.setCss(`margin-left: ${L_PADDING + (currentIndex * WS_WIDTH)}px`);
}; };
@ -100,6 +97,7 @@ export default () => {
vpack: 'center', vpack: 'center',
hpack: 'start', hpack: 'start',
class_name: 'button active', class_name: 'button active',
}).hook(Hyprland.active.workspace, updateHighlight); }).hook(Hyprland.active.workspace, updateHighlight);
const widget = Overlay({ const widget = Overlay({
@ -118,7 +116,7 @@ export default () => {
rev.reveal_child = false; rev.reveal_child = false;
}); });
Array.from(self.attribute.workspaces).forEach((ws) => { Array.from(self.attribute.workspaces).forEach((ws) => {
ws.revealChild = true; ws.reveal_child = true;
}); });
}; };

View file

@ -35,8 +35,7 @@ export default (props) => {
vertical: true, vertical: true,
setup: (self) => { setup: (self) => {
self const checkCurrentWsFsState = () => {
.hook(Hyprland.active, () => {
const workspace = Hyprland.getWorkspace( const workspace = Hyprland.getWorkspace(
Hyprland.active.workspace.id, Hyprland.active.workspace.id,
); );
@ -44,11 +43,19 @@ export default (props) => {
if (workspace) { if (workspace) {
Revealed.value = !workspace['hasfullscreen']; Revealed.value = !workspace['hasfullscreen'];
} }
}) };
.hook(Hyprland, (_, fullscreen) => { /**
* @param {import('types/widgets/box').default} _
* @param {boolean} fullscreen
*/
const checkGlobalFsState = (_, fullscreen) => {
Revealed.value = !fullscreen; Revealed.value = !fullscreen;
}, 'fullscreen'); };
self
.hook(Hyprland.active, checkCurrentWsFsState)
.hook(Hyprland, checkGlobalFsState, 'fullscreen');
}, },
children: [ children: [

View file

@ -10,11 +10,17 @@ const TRANSITION = `transition: margin ${ANIM_DURATION}ms ease,
opacity ${ANIM_DURATION}ms ease;`; opacity ${ANIM_DURATION}ms ease;`;
/**
* @typedef {import('types/widgets/overlay').OverlayProps} OverlayProps
* @typedef {import('types/widgets/overlay').default} Overlay
*
* @param {OverlayProps & {
* setup?: function(Overlay):void
* }} o
*/
export default ({ export default ({
attribute = {}, attribute = {},
setup = (self) => { setup = () => {/**/},
self;
},
...props ...props
}) => { }) => {
const widget = EventBox(); const widget = EventBox();
@ -36,6 +42,7 @@ export default ({
// @ts-expect-error // @ts-expect-error
.filter((ch) => !ch.attribute?.empty), .filter((ch) => !ch.attribute?.empty),
/** @param {Overlay} playerW */
includesWidget: (playerW) => { includesWidget: (playerW) => {
return Array.from(content.attribute.list()) return Array.from(content.attribute.list())
.find((w) => w === playerW); .find((w) => w === playerW);
@ -46,6 +53,7 @@ export default ({
over.visible = over === content.attribute.list().at(-1); over.visible = over === content.attribute.list().at(-1);
}), }),
/** @param {import('types/widgets/centerbox').default} player */
moveToTop: (player) => { moveToTop: (player) => {
player.visible = true; player.visible = true;
content.reorder_overlay(player, -1); content.reorder_overlay(player, -1);
@ -61,9 +69,15 @@ export default ({
setup(self); setup(self);
self self
.hook(gesture, (overlay, realGesture) => { .hook(gesture,
/**
* @param {Overlay} overlay
* @param {number} realGesture
*/
(overlay, realGesture) => {
if (realGesture) { if (realGesture) {
Array.from(overlay.attribute.list()).forEach((over) => { Array.from(overlay.attribute.list())
.forEach((over) => {
over.visible = true; over.visible = true;
}); });
} }
@ -102,9 +116,13 @@ export default ({
${playerBox.attribute.bgStyle} ${playerBox.attribute.bgStyle}
`); `);
} }
}, 'drag-update') },
'drag-update')
.hook(gesture, (overlay) => {
.hook(gesture,
/** @param {Overlay} overlay */
(overlay) => {
// Don't allow gesture when only one player // Don't allow gesture when only one player
if (overlay.attribute.list().length <= 1) { if (overlay.attribute.list().length <= 1) {
return; return;
@ -156,7 +174,8 @@ export default ({
playerBox.setCss(`${TRANSITION} playerBox.setCss(`${TRANSITION}
${playerBox.attribute.bgStyle}`); ${playerBox.attribute.bgStyle}`);
} }
}, 'drag-end'); },
'drag-end');
}, },
}); });

View file

@ -5,11 +5,11 @@ import { EventBox } from 'resource:///com/github/Aylur/ags/widget.js';
const { Gtk } = imports.gi; const { Gtk } = imports.gi;
// TODO: wrap in another EventBox for disabled cursor
/** /**
* @typedef {import('types/widgets/eventbox').EventBoxProps} EventBox * @typedef {import('types/widgets/eventbox').EventBoxProps} EventBoxProps
* @typedef {import('types/widgets/eventbox').default} EventBox
* *
* @param {EventBox & { * @param {EventBoxProps & {
* on_primary_click_release?: function(EventBox):void * on_primary_click_release?: function(EventBox):void
* }} o * }} o
*/ */
@ -23,22 +23,7 @@ export default ({
const CanRun = Variable(true); const CanRun = Variable(true);
const Disabled = Variable(false); const Disabled = Variable(false);
const widget = EventBox({ let widget; // eslint-disable-line
...props,
sensitive: Disabled.bind().transform((v) => !v),
on_primary_click_release: (self) => {
// Every click, do a one shot connect to
// CanRun to wait for location of click
const id = CanRun.connect('changed', () => {
if (CanRun.value) {
on_primary_click_release(self);
}
CanRun.disconnect(id);
});
},
});
const wrapper = EventBox({ const wrapper = EventBox({
cursor: 'pointer', cursor: 'pointer',
@ -55,14 +40,31 @@ export default ({
}, },
}, },
child: widget,
}).hook(Disabled, (self) => { }).hook(Disabled, (self) => {
self.cursor = Disabled.value ? self.cursor = Disabled.value ?
'not-allowed' : 'not-allowed' :
'pointer'; 'pointer';
}); });
widget = EventBox({
...props,
sensitive: Disabled.bind().transform((v) => !v),
on_primary_click_release: () => {
// Every click, do a one shot connect to
// CanRun to wait for location of click
const id = CanRun.connect('changed', () => {
if (CanRun.value) {
on_primary_click_release(wrapper);
}
CanRun.disconnect(id);
});
},
});
wrapper.child = widget;
const gesture = Gtk.GestureLongPress.new(widget); const gesture = Gtk.GestureLongPress.new(widget);
widget.hook(gesture, () => { widget.hook(gesture, () => {

View file

@ -16,6 +16,7 @@ export const NotifPopups = () => PopupWindow({
const TOP_MARGIN = 6; const TOP_MARGIN = 6;
// FIXME: opens at wrong place
export const NotifCenter = () => PopupWindow({ export const NotifCenter = () => PopupWindow({
name: 'notification-center', name: 'notification-center',
anchor: ['top', 'right'], anchor: ['top', 'right'],

View file

@ -7,6 +7,7 @@ import PopupWindow from './misc/popup.js';
import CursorBox from './misc/cursorbox.js'; import CursorBox from './misc/cursorbox.js';
// FIXME: eventboxes are the wrong size
const PowermenuWidget = () => CenterBox({ const PowermenuWidget = () => CenterBox({
class_name: 'powermenu', class_name: 'powermenu',
// @ts-expect-error // @ts-expect-error