From bc835043daa64bd11d1542353731cddaf891c4ac Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:42:55 +0700 Subject: [PATCH] workspace widget: even faster --- .config/ags/widgets/bar/workspaces.js | 190 ++++++++++++++------------ 1 file changed, 101 insertions(+), 89 deletions(-) diff --git a/.config/ags/widgets/bar/workspaces.js b/.config/ags/widgets/bar/workspaces.js index b3be638f..01e4a7ce 100644 --- a/.config/ags/widgets/bar/workspaces.js +++ b/.config/ags/widgets/bar/workspaces.js @@ -16,14 +16,11 @@ const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not sho const WorkspaceContents = (count = 10) => { return DrawingArea({ properties: [ + ['initialized', false], ['workspaceMask', 0], - ], - css: `transition: 500ms cubic-bezier(0.1, 1, 0, 1);`, - setup: (area) => area - .hook(Hyprland.active.workspace, (area) => - area.setCss(`font-size: ${Hyprland.active.workspace.id}px;`) - ) - .hook(Hyprland, (area) => { + ['updateMask', (self) => { + if(self._initialized) return; // We only need this to run once + console.log('update dayo') const workspaces = Hyprland.workspaces; let workspaceMask = 0; for (let i = 0; i < workspaces.length; i++) { @@ -34,95 +31,110 @@ const WorkspaceContents = (count = 10) => { workspaceMask |= (1 << ws.id); } } - area._workspaceMask = workspaceMask; - }, 'notify::workspaces') - .on('draw', Lang.bind(area, (area, cr) => { - const allocation = area.get_allocation(); - const { width, height } = allocation; + self._workspaceMask = workspaceMask; + self._initialized = true; + }], + ['toggleMask', (self, occupied, name) => { + if (occupied) self._workspaceMask |= (1 << parseInt(name)); + else self._workspaceMask &= ~(1 << parseInt(name)); + }] + ], + css: `transition: 90ms cubic-bezier(0.1, 1, 0, 1);`, + setup: (area) => { + area + .hook(Hyprland.active.workspace, (area) => + area.setCss(`font-size: ${Hyprland.active.workspace.id}px;`) + ) + .hook(Hyprland, (self) => self._updateMask(self), 'notify::workspaces') + .hook(Hyprland, (self, name) => self._toggleMask(self, true, name), 'workspace-added') + .hook(Hyprland, (self, name) => self._toggleMask(self, false, name), 'workspace-removed') + .on('draw', Lang.bind(area, (area, cr) => { + const allocation = area.get_allocation(); + const { width, height } = allocation; - const workspaceStyleContext = dummyWs.get_style_context(); - const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL); - const workspaceRadius = workspaceDiameter / 2; - const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3; - const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL); - const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL); - const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL); + const workspaceStyleContext = dummyWs.get_style_context(); + const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL); + const workspaceRadius = workspaceDiameter / 2; + const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3; + const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL); + const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL); + const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL); - const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context(); - const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL); - const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL); + const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context(); + const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL); + const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL); - const activeWorkspaceStyleContext = dummyActiveWs.get_style_context(); - const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL); - const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL); - area.set_size_request(workspaceDiameter * count, -1); - const widgetStyleContext = area.get_style_context(); - const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL); + const activeWorkspaceStyleContext = dummyActiveWs.get_style_context(); + const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL); + const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL); + area.set_size_request(workspaceDiameter * count, -1); + const widgetStyleContext = area.get_style_context(); + const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL); - const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs); - const activeWsCenterY = height / 2; + const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs); + const activeWsCenterY = height / 2; - // Font - const layout = PangoCairo.create_layout(cr); - const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`); - layout.set_font_description(fontDesc); - cr.setAntialias(Cairo.Antialias.BEST); - // Get kinda min radius for number indicators - layout.set_text("0".repeat(count.toString().length), -1); - const [layoutWidth, layoutHeight] = layout.get_pixel_size(); - const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.2; // a bit smaller than sqrt(2)*radius - const indicatorGap = workspaceRadius - indicatorRadius; - - // Draw workspace numbers - for (let i = 1; i <= count; i++) { - if (area._workspaceMask & (1 << i)) { - // Draw bg highlight - cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha); - const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i); - const wsCenterY = height / 2; - if (!(area._workspaceMask & (1 << (i - 1)))) { // Left - cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI); - cr.fill(); - } - else { - cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2) - cr.fill(); - } - if (!(area._workspaceMask & (1 << (i + 1)))) { // Right - cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI); - cr.fill(); - } - else { - cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2) - cr.fill(); - } - - // Set color for text - cr.setSourceRGBA(occupiedfg.red, occupiedfg.green, occupiedfg.blue, occupiedfg.alpha); - } - else - cr.setSourceRGBA(wsfg.red, wsfg.green, wsfg.blue, wsfg.alpha); - layout.set_text(`${i}`, -1); + // Font + const layout = PangoCairo.create_layout(cr); + const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`); + layout.set_font_description(fontDesc); + cr.setAntialias(Cairo.Antialias.BEST); + // Get kinda min radius for number indicators + layout.set_text("0".repeat(count.toString().length), -1); const [layoutWidth, layoutHeight] = layout.get_pixel_size(); - const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2); - const y = (height - layoutHeight) / 2; - cr.moveTo(x, y); - // cr.showText(text); - PangoCairo.show_layout(cr, layout); - cr.stroke(); - } + const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.2; // a bit smaller than sqrt(2)*radius + const indicatorGap = workspaceRadius - indicatorRadius; - // Draw active ws - // base - cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha); - cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI); - cr.fill(); - // inner decor - cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha); - cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI); - cr.fill(); - })) - , + // Draw workspace numbers + for (let i = 1; i <= count; i++) { + if (area._workspaceMask & (1 << i)) { + // Draw bg highlight + cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha); + const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i); + const wsCenterY = height / 2; + if (!(area._workspaceMask & (1 << (i - 1)))) { // Left + cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI); + cr.fill(); + } + else { + cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2) + cr.fill(); + } + if (!(area._workspaceMask & (1 << (i + 1)))) { // Right + cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI); + cr.fill(); + } + else { + cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2) + cr.fill(); + } + + // Set color for text + cr.setSourceRGBA(occupiedfg.red, occupiedfg.green, occupiedfg.blue, occupiedfg.alpha); + } + else + cr.setSourceRGBA(wsfg.red, wsfg.green, wsfg.blue, wsfg.alpha); + layout.set_text(`${i}`, -1); + const [layoutWidth, layoutHeight] = layout.get_pixel_size(); + const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2); + const y = (height - layoutHeight) / 2; + cr.moveTo(x, y); + // cr.showText(text); + PangoCairo.show_layout(cr, layout); + cr.stroke(); + } + + // Draw active ws + // base + cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha); + cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI); + cr.fill(); + // inner decor + cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha); + cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI); + cr.fill(); + })); + }, }) }