From 1762f1cc6152044f70b54f110c69049a1f83e67f Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Wed, 3 Apr 2024 22:07:17 +0700 Subject: [PATCH] implement click-to-close and fix config for new hyprland versions --- .config/ags/config.js | 2 + .../ags/modules/.widgethacks/popupwindow.js | 3 +- .config/ags/modules/cheatsheet/main.js | 1 + .config/ags/modules/click2close/main.js | 54 +++++++++++++++++++ .config/ags/modules/sideleft/main.js | 2 +- .config/ags/modules/sideright/main.js | 1 + .config/ags/variables.js | 37 ++++++++++++- .config/hypr/hyprland/general.conf | 6 +-- 8 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 .config/ags/modules/click2close/main.js diff --git a/.config/ags/config.js b/.config/ags/config.js index 745239245..9c58870a9 100644 --- a/.config/ags/config.js +++ b/.config/ags/config.js @@ -19,6 +19,7 @@ import Overview from './modules/overview/main.js'; import Session from './modules/session/main.js'; import SideLeft from './modules/sideleft/main.js'; import SideRight from './modules/sideright/main.js'; +import Click2Close from './modules/click2close/main.js'; const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated` const range = (length, start = 1) => Array.from({ length }, (_, i) => i + start); @@ -56,6 +57,7 @@ const Windows = () => [ forMonitors((id) => Corner(id, 'bottom right')), forMonitors(BarCornerTopleft), forMonitors(BarCornerTopright), + forMonitors(Click2Close), ]; const CLOSE_ANIM_TIME = 210; // Longer than actual anim time to make sure widgets animate fully diff --git a/.config/ags/modules/.widgethacks/popupwindow.js b/.config/ags/modules/.widgethacks/popupwindow.js index 26dad59c1..2facdcdba 100644 --- a/.config/ags/modules/.widgethacks/popupwindow.js +++ b/.config/ags/modules/.widgethacks/popupwindow.js @@ -22,7 +22,8 @@ export default ({ if (currentName === name) { self.toggleClassName(hideClassName, !visible); } - }).keybind("Escape", () => App.closeWindow(name)) + }).keybind("Escape", () => closeEverything()); + if (showClassName !== "" && hideClassName !== "") self.className = `${showClassName} ${hideClassName}`; }, diff --git a/.config/ags/modules/cheatsheet/main.js b/.config/ags/modules/cheatsheet/main.js index 984b0d052..59d540f86 100644 --- a/.config/ags/modules/cheatsheet/main.js +++ b/.config/ags/modules/cheatsheet/main.js @@ -70,6 +70,7 @@ const ClickOutsideToClose = () => Widget.EventBox({ export default (id) => PopupWindow({ name: `cheatsheet${id}`, + layer: 'overlay', exclusivity: 'ignore', keymode: 'exclusive', visible: false, diff --git a/.config/ags/modules/click2close/main.js b/.config/ags/modules/click2close/main.js new file mode 100644 index 000000000..7dd33dcd5 --- /dev/null +++ b/.config/ags/modules/click2close/main.js @@ -0,0 +1,54 @@ +const { Gdk } = imports.gi; +import Widget from 'resource:///com/github/Aylur/ags/widget.js'; +import PopupWindow from '../.widgethacks/popupwindow.js'; +import { SCREEN_HEIGHT, SCREEN_WIDTH } from '../../variables.js'; + +const WINDOWS_NEED_CLICK2CLOSE = [ + 'sideleft', 'sideright', 'overview', 'cheatsheet' +]; + +const range = (length, start = 1) => Array.from({ length }, (_, i) => i + start); + +export default (monitor = 0) => PopupWindow({ + monitor, + name: `click2close${monitor}`, + layer: 'top', + anchor: ['top', 'bottom', 'left', 'right'], + exclusivity: 'ignore', + child: Widget.EventBox({ + attribute: { + checkWindowRelevance: (currentName) => { + let relevant = false; + // use regex to check if name matches one of windows need click2close with a * + for (let i = 0; i < WINDOWS_NEED_CLICK2CLOSE.length; i++) { + // const testRegex = RegExp(`^${WINDOWS_NEED_CLICK2CLOSE[i]}\\d+$`); + const testRegex = /${WINDOWS_NEED_CLICK2CLOSE[i]}\\d+$/; + console.log(testRegex, testRegex.test(currentName)); + if (testRegex.test(currentName) || WINDOWS_NEED_CLICK2CLOSE[i] == currentName) { + console.log(WINDOWS_NEED_CLICK2CLOSE[i]); + relevant = true; + break; + } + } + return relevant; + } + }, + onPrimaryClick: () => closeEverything(), + onSecondaryClick: () => closeEverything(), + onMiddleClick: () => closeEverything(), + setup: (self) => self.hook(App, (self, currentName, visible) => { + if(!self.attribute.checkWindowRelevance(currentName)) return; + range(Gdk.Display.get_default()?.get_n_monitors() || 1, 0).forEach(id => { + if(visible) App.openWindow(`click2close${id}`); + else App.closeWindow(`click2close${id}`); + }); + }), + child: Widget.Box({ + css: ` + background-color: rgba(1,1,1,0.18); + min-height: ${SCREEN_HEIGHT}px; + min-width: ${SCREEN_WIDTH}px; + ` + }), + }) +}); \ No newline at end of file diff --git a/.config/ags/modules/sideleft/main.js b/.config/ags/modules/sideleft/main.js index 4aa74dfde..0f7ae0b2e 100644 --- a/.config/ags/modules/sideleft/main.js +++ b/.config/ags/modules/sideleft/main.js @@ -5,7 +5,7 @@ export default () => PopupWindow({ keymode: 'exclusive', anchor: ['left', 'top', 'bottom'], name: 'sideleft', - layer: 'top', + layer: 'overlay', showClassName: 'sideleft-show', hideClassName: 'sideleft-hide', child: SidebarLeft(), diff --git a/.config/ags/modules/sideright/main.js b/.config/ags/modules/sideright/main.js index 23298db82..f84de9fdc 100644 --- a/.config/ags/modules/sideright/main.js +++ b/.config/ags/modules/sideright/main.js @@ -5,6 +5,7 @@ export default () => PopupWindow({ keymode: 'exclusive', anchor: ['right', 'top', 'bottom'], name: 'sideright', + layer: 'overlay', showClassName: 'sideright-show', hideClassName: 'sideright-hide', child: SidebarRight(), diff --git a/.config/ags/variables.js b/.config/ags/variables.js index 8d407793e..72f76a9f3 100644 --- a/.config/ags/variables.js +++ b/.config/ags/variables.js @@ -1,5 +1,5 @@ -const { Gtk } = imports.gi; +const { Gdk, Gtk } = imports.gi; import App from 'resource:///com/github/Aylur/ags/app.js' import Variable from 'resource:///com/github/Aylur/ags/variable.js'; import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js'; @@ -29,3 +29,38 @@ globalThis['cycleMode'] = () => { currentShellMode.value = 'normal'; } } + +// // Window controls +const range = (length, start = 1) => Array.from({ length }, (_, i) => i + start); +globalThis['toggleWindowOnAllMonitors'] = (name) => { + function forMonitors(widget) { + range(Gdk.Display.get_default()?.get_n_monitors() || 1, 0).forEach(id => { + App.toggleWindow(`${name}${id}`); + }); + } +} +globalThis['closeWindowOnAllMonitors'] = (name) => { + function forMonitors(widget) { + range(Gdk.Display.get_default()?.get_n_monitors() || 1, 0).forEach(id => { + App.closeWindow(`${name}${id}`); + }); + } +} +globalThis['openWindowOnAllMonitors'] = (name) => { + function forMonitors(widget) { + range(Gdk.Display.get_default()?.get_n_monitors() || 1, 0).forEach(id => { + App.openWindow(`${name}${id}`); + }); + } +} + +globalThis['closeEverything'] = () => { + const numMonitors = Gdk.Display.get_default()?.get_n_monitors() || 1; + for (let i = 0; i < numMonitors; i++) { + App.closeWindow(`cheatsheet${i}`); + App.closeWindow(`click2close${i}`); + } + App.closeWindow('sideleft'); + App.closeWindow('sideright'); + App.closeWindow('overview'); +}; diff --git a/.config/hypr/hyprland/general.conf b/.config/hypr/hyprland/general.conf index cbc8f61cb..f641c5e91 100644 --- a/.config/hypr/hyprland/general.conf +++ b/.config/hypr/hyprland/general.conf @@ -78,8 +78,8 @@ decoration { brightness = 1 noise = 0.01 contrast = 1 - popup = true - popup_ignorealpha = 0.6 + popups = true + popups_ignorealpha = 0.6 } # Shadow drop_shadow = false @@ -119,7 +119,7 @@ animations { # Animation configs animation = windows, 1, 3, md3_decel, popin 60% animation = border, 1, 10, default - animation = fade, 1, 2.5, md3_decel + animation = fade, 1, 3, md3_decel animation = workspaces, 1, 7, fluent_decel, slide # animation = workspaces, 1, 2.5, softAcDecel, slide # animation = workspaces, 1, 7, fluent_decel, slidefade 15%