From 46312963d853263ac5a73ec63fb456f4695b9f6b Mon Sep 17 00:00:00 2001 From: casglistro Date: Thu, 18 Apr 2024 16:38:28 +0800 Subject: [PATCH] add some configs --- .config/ags/config.js | 5 +- .../modules/.configuration/user_options.js | 37 +++++- .config/ags/modules/dock/dock.js | 124 ++++++++++++------ .config/ags/modules/dock/icons.js | 3 + .config/ags/modules/dock/main.js | 2 +- 5 files changed, 129 insertions(+), 42 deletions(-) diff --git a/.config/ags/config.js b/.config/ags/config.js index b061a455d..646f54dbf 100644 --- a/.config/ags/config.js +++ b/.config/ags/config.js @@ -50,11 +50,11 @@ const Windows = () => [ Overview(), forMonitors(Indicator), forMonitors(Cheatsheet), - forMonitors(Dock), SideLeft(), SideRight(), forMonitors(Osk), Session(), + ...(userOptions.dock.enabled ? [forMonitors(Dock)] : []), // forMonitors(Bar), ...(userOptions.appearance.fakeScreenRounding ? [ forMonitors((id) => Corner(id, 'top left', true)), @@ -82,5 +82,4 @@ App.config({ // Stuff that don't need to be toggled. And they're async so ugh... forMonitorsAsync(Bar); -// Bar().catch(print); // Use this to debug the bar. Single monitor only. - +// Bar().catch(print); // Use this to debug the bar. Single monitor only. \ No newline at end of file diff --git a/.config/ags/modules/.configuration/user_options.js b/.config/ags/modules/.configuration/user_options.js index 72f285a12..fec814440 100644 --- a/.config/ags/modules/.configuration/user_options.js +++ b/.config/ags/modules/.configuration/user_options.js @@ -71,11 +71,46 @@ let configOptions = { 'dateFormat': "%d/%m", // On notif time }, 'weather': { - 'city': "", + 'city': "Chengdu", }, 'workspaces': { 'shown': 10, }, + 'dock': { + 'enabled': false, + // Threshold for hover to trigger dock display + 'hoverMinHeight': 5, + 'pinnedApps': ['firefox', 'org.gnome.Nautilus'], + // top or bottom + 'layer': 'top', + // Find the window's icon by its class with levenshteinDistance + // All file paths are preprocessed and stored at ags startup, so if there + // are so many files under the path it will affect performance + // Maybe you need a comprehensive icon theme + // Example: ['/usr/share/icons/Tela-nord-dark/scalable/apps', 'others...'] + 'iconSearchPaths': [''], + // Dock will move to other monitor along with focus if enabled + 'monitorExclusivity': true, + // It's useful to keep the icons consistent, which is useful if you're OCD :) + 'searchPinnedAppIcons': false, + // available: client_added, client_move, workspace_active, client_active + 'trigger': ['client-added', 'client-removed', + 'workspace-active'], + // Automatically hide dock after a period of time + // after a trigger has been triggered. + // Time in milliseconds. empty if always displays. + // { 'trigger': 'client-added', interval: 1000, } + 'autoHidden': [ + { + 'trigger': 'client-added', + 'interval': 2000, + }, + { + 'trigger': 'client-removed', + 'interval': 2000, + }, + ], + }, // Longer stuff 'icons': { substitutions: { diff --git a/.config/ags/modules/dock/dock.js b/.config/ags/modules/dock/dock.js index 08254966b..8c18c7536 100644 --- a/.config/ags/modules/dock/dock.js +++ b/.config/ags/modules/dock/dock.js @@ -1,4 +1,4 @@ -const { Gtk } = imports.gi; +const { Gtk, GLib } = imports.gi; import { SCREEN_HEIGHT, SCREEN_WIDTH } from '../../variables.js'; import Widget from 'resource:///com/github/Aylur/ags/widget.js'; import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; @@ -12,7 +12,7 @@ import { setupCursorHover } from '../.widgetutils/cursorhover.js'; import { getAllFiles, searchIcons } from './icons.js' import { MaterialIcon } from '../.commonwidgets/materialicon.js'; -const icon_files = getAllFiles("/usr/share/icons/Tela-nord-dark/scalable/apps") +const icon_files = userOptions.dock.iconSearchPaths.map(e => getAllFiles(e)).flat(1) const pinnedApps = [ 'firefox', @@ -22,6 +22,13 @@ const pinnedApps = [ let isPinned = false let cachePath = new Map() +let timers = [] + +function clearTimes() { + timers.forEach(e => GLib.source_remove(e)) + timers = [] +} + function substitute(str) { const subs = [ { from: 'code-url-handler', to: 'visual-studio-code' }, @@ -67,23 +74,33 @@ const DockSeparator = (props = {}) => Box({ className: 'dock-separator', }) -const PinButton = () => Widget.Button({ - className: 'dock-app-btn', - tooltipText: 'Pin Dock', - child: Widget.Overlay({ - child: Widget.Box({ - homogeneous: true, - className: 'dock-app-icon', - child: MaterialIcon('Lock', 'larger') +const PinButton = () => { + let botton = Widget.Button({ + className: 'dock-app-btn dock-app-btn-animate', + tooltipText: 'Pin Dock', + child: Widget.Overlay({ + child: Widget.Box({ + homogeneous: true, + className: 'dock-app-icon', + child: MaterialIcon('Lock', 'larger') + }), + overlays: [Widget.Box({ + class_name: 'indicator', + vpack: 'end', + hpack: 'center', + })], }), - overlays: [Widget.Box({ - class_name: 'indicator', - vpack: 'end', - hpack: 'center', - })], - }), - onClicked: () => isPinned = !isPinned -}) + onClicked: () => { + isPinned = !isPinned + botton.className = `${isPinned ? "pinned-dock-app-btn" : "dock-app-btn animate"} dock-app-btn-animate` + }, + setup: (button) => { + setupCursorHover(button); + } + }) + + return botton +} const AppButton = ({ icon, ...rest }) => Widget.Revealer({ attribute: { @@ -94,7 +111,7 @@ const AppButton = ({ icon, ...rest }) => Widget.Revealer({ transitionDuration: userOptions.animations.durationLarge, child: Widget.Button({ ...rest, - className: 'dock-app-btn', + className: 'dock-app-btn dock-app-btn-animate', child: Widget.Box({ child: Widget.Overlay({ child: Widget.Box({ @@ -117,14 +134,15 @@ const AppButton = ({ icon, ...rest }) => Widget.Revealer({ }) }); -const Taskbar = () => Widget.Box({ +const Taskbar = (monitor) => Widget.Box({ className: 'dock-apps', attribute: { + monitor: monitor, 'map': new Map(), 'clientSortFunc': (a, b) => { return a.attribute.workspace > b.attribute.workspace; }, - 'update': (box) => { + 'update': (box, monitor) => { for (let i = 0; i < Hyprland.clients.length; i++) { const client = Hyprland.clients[i]; if (client["pid"] == -1) return; @@ -151,7 +169,7 @@ const Taskbar = () => Widget.Box({ } box.children = Array.from(box.attribute.map.values()); }, - 'add': (box, address) => { + 'add': (box, address, monitor) => { if (!address) { // First active emit is undefined box.attribute.update(box); return; @@ -193,7 +211,7 @@ const Taskbar = () => Widget.Box({ }, }, setup: (self) => { - self.hook(Hyprland, (box, address) => box.attribute.add(box, address), 'client-added') + self.hook(Hyprland, (box, address) => box.attribute.add(box, address, self.monitor), 'client-added') .hook(Hyprland, (box, address) => box.attribute.remove(box, address, self.monitor), 'client-removed') Utils.timeout(100, () => self.attribute.update(self)); }, @@ -208,7 +226,9 @@ const PinnedApps = () => Widget.Box({ .map(({ app, term = true }) => { const newButton = AppButton({ // different icon, emm... - icon: app.icon_name, + icon: userOptions.dock.searchPinnedAppIcons ? + searchIcons(app.icon_name, icon_files) : + app.icon_name, onClicked: () => { for (const client of Hyprland.clients) { if (client.class.toLowerCase().includes(term)) @@ -287,36 +307,66 @@ export default (monitor = 0) => { // // if (currentWorkspace === client.workspace.id) { // self.revealChild = true; // // } - self.revealChild = activeMonitorId() === monitor + + if (userOptions.dock.monitorExclusivity) { + self.revealChild = activeMonitorId() === monitor + } else { + self.revealChild = true; + } + + return self.revealChild } }, revealChild: false, transition: 'slide_up', transitionDuration: userOptions.animations.durationLarge, child: dockContent, - setup: (self) => self - // .hook(Hyprland, (self) => self.attribute.updateShow(self)) - .hook(Hyprland.active.workspace, (self) => self.attribute.updateShow(self)) - // .hook(Hyprland.active.client, (self) => self.attribute.updateShow(self)) - .hook(Hyprland, (self) => self.attribute.updateShow(self), 'client-added') - .hook(Hyprland, (self) => self.attribute.updateShow(self), 'client-removed') + setup: (self) => { + const callback = (self, trigger) => { + if (!userOptions.dock.trigger.includes(trigger)) return + const flag = self.attribute.updateShow(self) + + if (flag) { clearTimes() } + + const hidden = userOptions + .dock + .autoHidden.find(e => e["trigger"] === trigger) + + if (hidden) { + let id = Utils.timeout(hidden.interval, () => { + if (!isPinned) { self.revealChild = false } + timers = timers.filter(e => e !== id) + }) + timers.push(id) + } + } + + self + // .hook(Hyprland, (self) => self.attribute.updateShow(self)) + .hook(Hyprland.active.workspace, self => callback(self, "workspace-active")) + .hook(Hyprland.active.client, self => callback(self, "client-active")) + .hook(Hyprland, self => callback(self, "client-added"), "client-added") + .hook(Hyprland, self => callback(self, "client-removed"), "client-removed") + } , }) return EventBox({ onHover: () => { dockRevealer.revealChild = true; + clearTimes() }, - // onHoverLost: () => { - // if (Hyprland.active.client.attribute.class.length === 0) { return } - // dockRevealer.revealChild = false; - // }, child: Box({ homogeneous: true, - css: 'min-height: 20px;', + css: `min-height: ${userOptions.dock.hoverMinHeight}px;`, children: [ dockRevealer, ] }), - setup: self => self.on("leave-notify-event", () => { if (!isPinned) dockRevealer.revealChild = false }) + setup: self => self.on("leave-notify-event", () => { + if (!isPinned) dockRevealer.revealChild = false; + clearTimes() + }).on('key-press-event', (self, event) => { + console.log(self, event) + }) }) } diff --git a/.config/ags/modules/dock/icons.js b/.config/ags/modules/dock/icons.js index d9a91c158..a16e8ff0e 100644 --- a/.config/ags/modules/dock/icons.js +++ b/.config/ags/modules/dock/icons.js @@ -28,6 +28,7 @@ export const levenshteinDistance = (a, b) => { } export const getAllFiles = (dir, files = []) => { + if (!exists(dir)) { return [] } const file = Gio.File.new_for_path(dir); const enumerator = file.enumerate_children('standard::name,standard::type', Gio.FileQueryInfoFlags.NONE, null); @@ -44,6 +45,8 @@ export const getAllFiles = (dir, files = []) => { } export const searchIcons = (appClass, files) => { + if (!files.length) { return "" } + let appro = 0x3f3f3f3f let path = "" diff --git a/.config/ags/modules/dock/main.js b/.config/ags/modules/dock/main.js index 38bbbf7b2..77d394d9f 100644 --- a/.config/ags/modules/dock/main.js +++ b/.config/ags/modules/dock/main.js @@ -4,7 +4,7 @@ import Dock from './dock.js'; export default (monitor = 0) => Widget.Window({ monitor, name: `dock${monitor}`, - layer: 'top', + layer: userOptions.dock.layer, anchor: ['bottom'], exclusivity: 'normal', visible: true,