diff --git a/devices/binto/config/ags/js/bar/buttons/clock.js b/devices/binto/config/ags/js/bar/buttons/clock.js index d4cd1f7..5673872 100644 --- a/devices/binto/config/ags/js/bar/buttons/clock.js +++ b/devices/binto/config/ags/js/bar/buttons/clock.js @@ -1,15 +1,12 @@ import { Label } from 'resource:///com/github/Aylur/ags/widget.js'; -export default () => Label({ - className: 'clock', - - connections: [[1000, (self) => { +export default () => Label({ className: 'clock' }) + .poll(1000, (self) => { const time = imports.gi.GLib - .DateTime.new_now_local(); + .DateTime.new_now_local(); self.label = time.format('%a. ') + time.get_day_of_month() + time.format(' %b. %H:%M'); - }]], -}) + }); diff --git a/devices/binto/config/ags/js/notifications/main.js b/devices/binto/config/ags/js/notifications/main.js index 788f976..7090a25 100644 --- a/devices/binto/config/ags/js/notifications/main.js +++ b/devices/binto/config/ags/js/notifications/main.js @@ -9,7 +9,7 @@ export const NotifPopups = () => PopupWindow({ anchor: ['bottom', 'left'], visible: true, transition: 'none', - closeOnUnfocus: 'stay', + close_on_unfocus: 'stay', monitor: 1, child: PopUpsWidget(), diff --git a/devices/wim/config/ags/js/bar/buttons/keyboard-layout.js b/devices/wim/config/ags/js/bar/buttons/keyboard-layout.js index 3da7566..a26a11f 100644 --- a/devices/wim/config/ags/js/bar/buttons/keyboard-layout.js +++ b/devices/wim/config/ags/js/bar/buttons/keyboard-layout.js @@ -11,7 +11,7 @@ const SPACING = 4; /** * @param {Label} self * @param {string} layout - * @param {void} _ + * @param {string} _ */ const getKbdLayout = (self, _, layout) => { if (layout) { diff --git a/devices/wim/config/ags/js/bar/buttons/osk-toggle.js b/devices/wim/config/ags/js/bar/buttons/osk-toggle.js index 2fe6e34..5182ddf 100644 --- a/devices/wim/config/ags/js/bar/buttons/osk-toggle.js +++ b/devices/wim/config/ags/js/bar/buttons/osk-toggle.js @@ -9,12 +9,16 @@ export default () => CursorBox({ on_primary_click_release: () => Tablet.toggleOsk(), + setup: (self) => { + self.hook(Tablet, () => { + self.toggleClassName('toggle-on', Tablet.oskState); + }, 'osk-toggled'); + }, + child: Label({ class_name: 'osk-toggle', xalign: 0.6, label: '󰌌 ', }), -}).hook(Tablet, (self) => { - self.toggleClassName('toggle-on', Tablet.oskState); -}, 'osk-toggled'); +}); diff --git a/devices/wim/config/ags/js/bar/buttons/systray.js b/devices/wim/config/ags/js/bar/buttons/systray.js index f75ac1b..9602107 100644 --- a/devices/wim/config/ags/js/bar/buttons/systray.js +++ b/devices/wim/config/ags/js/bar/buttons/systray.js @@ -38,39 +38,50 @@ const SysTray = () => MenuBar({ }, setup: (self) => { + /** + * @param {import('types/widget').default} _ + * @param {string} id + */ + const addTray = (_, id) => { + const item = SystemTray.getItem(id); + + if (self.attribute.items.has(id) || !item) { + return; + } + + const w = SysTrayItem(item); + + // Early return if item is in blocklist + if (!w) { + return; + } + + self.attribute.items.set(id, w); + self.child = w; + self.show_all(); + // @ts-expect-error + w.child.reveal_child = true; + }; + + /** + * @param {import('types/widget').default} _ + * @param {string} id + */ + const removeTray = (_, id) => { + if (!self.attribute.items.has(id)) { + return; + } + + self.attribute.items.get(id).child.reveal_child = false; + timeout(REVEAL_DURATION, () => { + self.attribute.items.get(id).destroy(); + self.attribute.items.delete(id); + }); + }; + self - .hook(SystemTray, (_, id) => { - const item = SystemTray.getItem(id); - - if (self.attribute.items.has(id) || !item) { - return; - } - - const w = SysTrayItem(item); - - // Early return if item is in blocklist - if (!w) { - return; - } - - self.attribute.items.set(id, w); - self.child = w; - self.show_all(); - // @ts-expect-error - w.child.reveal_child = true; - }, 'added') - - .hook(SystemTray, (_, id) => { - if (!self.attribute.items.has(id)) { - return; - } - - self.attribute.items.get(id).child.reveal_child = false; - timeout(REVEAL_DURATION, () => { - self.attribute.items.get(id).destroy(); - self.attribute.items.delete(id); - }); - }, 'removed'); + .hook(SystemTray, addTray, 'added') + .hook(SystemTray, removeTray, 'removed'); }, }); diff --git a/devices/wim/config/ags/js/bar/buttons/tablet-toggle.js b/devices/wim/config/ags/js/bar/buttons/tablet-toggle.js index 069cabb..8d6bfb1 100644 --- a/devices/wim/config/ags/js/bar/buttons/tablet-toggle.js +++ b/devices/wim/config/ags/js/bar/buttons/tablet-toggle.js @@ -9,12 +9,16 @@ export default () => CursorBox({ on_primary_click_release: () => Tablet.toggleMode(), + setup: (self) => { + self.hook(Tablet, () => { + self.toggleClassName('toggle-on', Tablet.tabletMode); + }, 'mode-toggled'); + }, + child: Box({ class_name: 'tablet-toggle', vertical: false, children: [Label(' 󰦧 ')], }), -}).hook(Tablet, (self) => { - self.toggleClassName('toggle-on', Tablet.tabletMode); -}, 'mode-toggled'); +}); diff --git a/devices/wim/config/ags/js/bar/buttons/workspaces.js b/devices/wim/config/ags/js/bar/buttons/workspaces.js index 5f664ee..cba7e11 100644 --- a/devices/wim/config/ags/js/bar/buttons/workspaces.js +++ b/devices/wim/config/ags/js/bar/buttons/workspaces.js @@ -7,8 +7,6 @@ import CursorBox from '../../misc/cursorbox.js'; const URGENT_DURATION = 1000; -/** @typedef {import('types/widget.js').Widget} Widget */ - /** @property {number} id */ const Workspace = ({ id }) => { @@ -17,7 +15,7 @@ const Workspace = ({ id }) => { attribute: { id }, child: CursorBox({ - tooltipText: `${id}`, + tooltip_text: `${id}`, on_primary_click_release: () => { Hyprland.sendMessage(`dispatch workspace ${id}`); @@ -29,7 +27,7 @@ const Workspace = ({ id }) => { setup: (self) => { /** - * @param {Widget} _ + * @param {import('types/widgets/box').default} _ * @param {string|undefined} addr */ const update = (_, addr) => { @@ -80,11 +78,11 @@ export default () => { const L_PADDING = 16; const WS_WIDTH = 30; - /** @param {Widget} self */ + /** @param {import('types/widgets/box').default} self */ const updateHighlight = (self) => { const currentId = Hyprland.active.workspace.id; // @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) .findIndex((w) => w.attribute.id === currentId); @@ -92,7 +90,6 @@ export default () => { return; } - // @ts-expect-error self.setCss(`margin-left: ${L_PADDING + (currentIndex * WS_WIDTH)}px`); }; @@ -100,6 +97,7 @@ export default () => { vpack: 'center', hpack: 'start', class_name: 'button active', + }).hook(Hyprland.active.workspace, updateHighlight); const widget = Overlay({ @@ -118,7 +116,7 @@ export default () => { rev.reveal_child = false; }); Array.from(self.attribute.workspaces).forEach((ws) => { - ws.revealChild = true; + ws.reveal_child = true; }); }; diff --git a/devices/wim/config/ags/js/bar/fullscreen.js b/devices/wim/config/ags/js/bar/fullscreen.js index f60277e..00e2020 100644 --- a/devices/wim/config/ags/js/bar/fullscreen.js +++ b/devices/wim/config/ags/js/bar/fullscreen.js @@ -35,20 +35,27 @@ export default (props) => { vertical: true, setup: (self) => { + const checkCurrentWsFsState = () => { + const workspace = Hyprland.getWorkspace( + Hyprland.active.workspace.id, + ); + + if (workspace) { + Revealed.value = !workspace['hasfullscreen']; + } + }; + + /** + * @param {import('types/widgets/box').default} _ + * @param {boolean} fullscreen + */ + const checkGlobalFsState = (_, fullscreen) => { + Revealed.value = !fullscreen; + }; + self - .hook(Hyprland.active, () => { - const workspace = Hyprland.getWorkspace( - Hyprland.active.workspace.id, - ); - - if (workspace) { - Revealed.value = !workspace['hasfullscreen']; - } - }) - - .hook(Hyprland, (_, fullscreen) => { - Revealed.value = !fullscreen; - }, 'fullscreen'); + .hook(Hyprland.active, checkCurrentWsFsState) + .hook(Hyprland, checkGlobalFsState, 'fullscreen'); }, children: [ diff --git a/devices/wim/config/ags/js/media-player/gesture.js b/devices/wim/config/ags/js/media-player/gesture.js index 38a553c..a787034 100644 --- a/devices/wim/config/ags/js/media-player/gesture.js +++ b/devices/wim/config/ags/js/media-player/gesture.js @@ -10,11 +10,17 @@ const TRANSITION = `transition: margin ${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 ({ attribute = {}, - setup = (self) => { - self; - }, + setup = () => {/**/}, ...props }) => { const widget = EventBox(); @@ -36,6 +42,7 @@ export default ({ // @ts-expect-error .filter((ch) => !ch.attribute?.empty), + /** @param {Overlay} playerW */ includesWidget: (playerW) => { return Array.from(content.attribute.list()) .find((w) => w === playerW); @@ -46,6 +53,7 @@ export default ({ over.visible = over === content.attribute.list().at(-1); }), + /** @param {import('types/widgets/centerbox').default} player */ moveToTop: (player) => { player.visible = true; content.reorder_overlay(player, -1); @@ -61,102 +69,113 @@ export default ({ setup(self); self - .hook(gesture, (overlay, realGesture) => { - if (realGesture) { - Array.from(overlay.attribute.list()).forEach((over) => { - over.visible = true; - }); - } - else { - overlay.attribute.showTopOnly(); - } + .hook(gesture, + /** + * @param {Overlay} overlay + * @param {number} realGesture + */ + (overlay, realGesture) => { + if (realGesture) { + Array.from(overlay.attribute.list()) + .forEach((over) => { + over.visible = true; + }); + } + else { + overlay.attribute.showTopOnly(); + } - // Don't allow gesture when only one player - if (overlay.attribute.list().length <= 1) { - return; - } + // Don't allow gesture when only one player + if (overlay.attribute.list().length <= 1) { + return; + } - overlay.attribute.dragging = true; - let offset = gesture.get_offset()[1]; - const playerBox = overlay.attribute.list().at(-1); + overlay.attribute.dragging = true; + let offset = gesture.get_offset()[1]; + const playerBox = overlay.attribute.list().at(-1); - if (!offset) { - return; - } + if (!offset) { + return; + } - // Slide right - if (offset >= 0) { - playerBox.setCss(` + // Slide right + if (offset >= 0) { + playerBox.setCss(` margin-left: ${offset}px; margin-right: -${offset}px; ${playerBox.attribute.bgStyle} `); - } + } - // Slide left - else { - offset = Math.abs(offset); - playerBox.setCss(` + // Slide left + else { + offset = Math.abs(offset); + playerBox.setCss(` margin-left: -${offset}px; margin-right: ${offset}px; ${playerBox.attribute.bgStyle} `); - } - }, 'drag-update') + } + }, + 'drag-update') - .hook(gesture, (overlay) => { - // Don't allow gesture when only one player - if (overlay.attribute.list().length <= 1) { - return; - } - overlay.attribute.dragging = false; - const offset = gesture.get_offset()[1]; + .hook(gesture, + /** @param {Overlay} overlay */ + (overlay) => { + // Don't allow gesture when only one player + if (overlay.attribute.list().length <= 1) { + return; + } - const playerBox = overlay.attribute.list().at(-1); + overlay.attribute.dragging = false; + const offset = gesture.get_offset()[1]; - // If crosses threshold after letting go, slide away - if (offset && Math.abs(offset) > MAX_OFFSET) { - // Disable inputs during animation - widget.sensitive = false; + const playerBox = overlay.attribute.list().at(-1); - // Slide away right - if (offset >= 0) { - playerBox.setCss(` + // If crosses threshold after letting go, slide away + if (offset && 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.attribute.bgStyle} `); - } + } - // Slide away left - else { - playerBox.setCss(` + // Slide away left + else { + playerBox.setCss(` ${TRANSITION} margin-left: -${OFFSCREEN}px; margin-right: ${OFFSCREEN}px; opacity: 0.7; ${playerBox.attribute.bgStyle} `); + } + + timeout(ANIM_DURATION, () => { + // Put the player in the back after anim + overlay.reorder_overlay(playerBox, 0); + // Recenter player + playerBox.setCss(playerBox.attribute.bgStyle); + + widget.sensitive = true; + + overlay.attribute.showTopOnly(); + }); } - - timeout(ANIM_DURATION, () => { - // Put the player in the back after anim - overlay.reorder_overlay(playerBox, 0); - // Recenter player - playerBox.setCss(playerBox.attribute.bgStyle); - - widget.sensitive = true; - - overlay.attribute.showTopOnly(); - }); - } - else { - // Recenter with transition for animation - playerBox.setCss(`${TRANSITION} + else { + // Recenter with transition for animation + playerBox.setCss(`${TRANSITION} ${playerBox.attribute.bgStyle}`); - } - }, 'drag-end'); + } + }, + 'drag-end'); }, }); diff --git a/devices/wim/config/ags/js/misc/cursorbox.js b/devices/wim/config/ags/js/misc/cursorbox.js index 511a74e..1067ac5 100644 --- a/devices/wim/config/ags/js/misc/cursorbox.js +++ b/devices/wim/config/ags/js/misc/cursorbox.js @@ -5,11 +5,11 @@ import { EventBox } from 'resource:///com/github/Aylur/ags/widget.js'; 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 * }} o */ @@ -23,22 +23,7 @@ export default ({ const CanRun = Variable(true); const Disabled = Variable(false); - const widget = EventBox({ - ...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); - }); - }, - }); + let widget; // eslint-disable-line const wrapper = EventBox({ cursor: 'pointer', @@ -55,14 +40,31 @@ export default ({ }, }, - child: widget, - }).hook(Disabled, (self) => { self.cursor = Disabled.value ? 'not-allowed' : '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); widget.hook(gesture, () => { diff --git a/devices/wim/config/ags/js/notifications/main.js b/devices/wim/config/ags/js/notifications/main.js index 1528c4b..9b1f0a2 100644 --- a/devices/wim/config/ags/js/notifications/main.js +++ b/devices/wim/config/ags/js/notifications/main.js @@ -16,6 +16,7 @@ export const NotifPopups = () => PopupWindow({ const TOP_MARGIN = 6; +// FIXME: opens at wrong place export const NotifCenter = () => PopupWindow({ name: 'notification-center', anchor: ['top', 'right'], diff --git a/devices/wim/config/ags/js/powermenu.js b/devices/wim/config/ags/js/powermenu.js index 520d1d1..0ad9dff 100644 --- a/devices/wim/config/ags/js/powermenu.js +++ b/devices/wim/config/ags/js/powermenu.js @@ -7,6 +7,7 @@ import PopupWindow from './misc/popup.js'; import CursorBox from './misc/cursorbox.js'; +// FIXME: eventboxes are the wrong size const PowermenuWidget = () => CenterBox({ class_name: 'powermenu', // @ts-expect-error