From d721ea30dbd09e33a44063dffdbcb0d98bdf61aa Mon Sep 17 00:00:00 2001 From: retrozinndev Date: Wed, 23 Jul 2025 21:53:43 -0300 Subject: [PATCH] :sparkles: chore: make apps-window and floating notifications work better on gtk4 --- ags/window/AppsWindow.tsx | 84 +++++++++++++++------------- ags/window/Bar.tsx | 1 + ags/window/CenterWindow.tsx | 4 +- ags/window/ControlCenter.tsx | 18 +++--- ags/window/FloatingNotifications.tsx | 42 ++++++++------ ags/window/LogoutMenu.tsx | 14 +++-- 6 files changed, 91 insertions(+), 72 deletions(-) diff --git a/ags/window/AppsWindow.tsx b/ags/window/AppsWindow.tsx index 2359dbe..4fa7a9e 100644 --- a/ags/window/AppsWindow.tsx +++ b/ags/window/AppsWindow.tsx @@ -6,10 +6,14 @@ import AstalApps from "gi://AstalApps"; import Pango from "gi://Pango?version=1.0"; import { createState, For } from "ags"; + const ignoredKeys = [ Gdk.KEY_Right, Gdk.KEY_Down, Gdk.KEY_Up, + Gdk.KEY_Shift_L, + Gdk.KEY_Shift_R, + Gdk.KEY_Shift_Lock, Gdk.KEY_Left, Gdk.KEY_Return, Gdk.KEY_space @@ -18,55 +22,55 @@ const ignoredKeys = [ export const AppsWindow = (mon: number) => { const [results, setResults] = createState(getApps() as Array); - const entry: Gtk.SearchEntry = { - setResults(getAstalApps().fuzzy_query(self.text.trim())); - }}/> as Gtk.SearchEntry; - return { + cssBackgroundWindow="background: rgba(0, 0, 0, .2);" + actionKeyPressed={(self, key) => { + const entry = self.get_first_child()!.get_first_child()! + .get_first_child()!.get_first_child() as Gtk.SearchEntry; + for(const ignoredKey of ignoredKeys) if(key === ignoredKey) return - !entry.is_focus && entry.grab_focus(); + entry.grab_focus(); }}> - - - + + { + setResults(getAstalApps().fuzzy_query(self.text.trim())); + }} /> + + - - - - {(app) => - ${ - app.description}` : ""}`.replace(/\&/g, "&")} + - onActivate={() => { - execApp(app); - window.close(); - }} onClicked={() => { - execApp(app); - window.close(); - }}> - - - - - - - } - - - - + + {(app) => + ${app.description}` + : ""}`.replace(/\&/g, "&") + } onActivate={() => { + execApp(app); + window.close(); + }} onClicked={() => { + execApp(app); + window.close(); + }}> + + + + + + } + + + + } diff --git a/ags/window/Bar.tsx b/ags/window/Bar.tsx index 38cd5bd..2d6d1c5 100644 --- a/ags/window/Bar.tsx +++ b/ags/window/Bar.tsx @@ -8,6 +8,7 @@ import { Apps } from "../widget/bar/Apps"; import { Clock } from "../widget/bar/Clock"; import { Status } from "../widget/bar/Status"; + export const Bar = (mon: number) => { const widgetSpacing = 4; return - + diff --git a/ags/window/ControlCenter.tsx b/ags/window/ControlCenter.tsx index 4d3d1d6..d5cf6da 100644 --- a/ags/window/ControlCenter.tsx +++ b/ags/window/ControlCenter.tsx @@ -1,22 +1,24 @@ import { Astal, Gtk } from "ags/gtk4"; import { PopupWindow } from "../widget/PopupWindow"; -import { NotifHistory } from "../widget/control-center/NotifHistory"; import { QuickActions } from "../widget/control-center/QuickActions"; +import { NotifHistory } from "../widget/control-center/NotifHistory"; +import { Tiles } from "../widget/control-center/Tiles"; +import { Sliders } from "../widget/control-center/Sliders"; export const ControlCenter = (mon: number) => - - - + + + + diff --git a/ags/window/FloatingNotifications.tsx b/ags/window/FloatingNotifications.tsx index bc9cb42..faa0650 100644 --- a/ags/window/FloatingNotifications.tsx +++ b/ags/window/FloatingNotifications.tsx @@ -2,32 +2,40 @@ import { Astal, Gtk } from "ags/gtk4"; import { createBinding, For } from "ags"; import { Notifications } from "../scripts/notifications"; import { NotificationWidget } from "../widget/Notification"; -import { variableToBoolean } from "../scripts/utils"; -import AstalNotifd from "gi://AstalNotifd?version=0.1"; +import AstalNotifd from "gi://AstalNotifd?version=0.1"; +import Adw from "gi://Adw?version=1"; + +const size = 450; export const FloatingNotifications = (mon: number) => + anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT} exclusivity={Astal.Exclusivity.NORMAL} + resizable={false} widthRequest={450}> - + {(notif: AstalNotifd.Notification) => - - Notifications.getDefault().removeNotification(notif)} - holdOnHover={true} actionClicked={() => { - const viewAction = notif.actions.filter(action => - action.label.toLowerCase() === "view")?.[0]; + + - viewAction && notif.invoke(viewAction.id); - }} - /> - + {/* + Why is holdOnHover disabled: the shell for some reason crashes + when removing the notification on hover-lost 💔 + */} + Notifications.getDefault().removeNotification(notif)} + holdOnHover={false} actionClicked={() => { + const viewAction = notif.actions.filter(action => + action.label.toLowerCase() === "view")?.[0]; + + viewAction && notif.invoke(viewAction.id); + }} + /> + + } diff --git a/ags/window/LogoutMenu.tsx b/ags/window/LogoutMenu.tsx index 3719e96..3277a0c 100644 --- a/ags/window/LogoutMenu.tsx +++ b/ags/window/LogoutMenu.tsx @@ -10,6 +10,7 @@ import AstalNotifd from "gi://AstalNotifd"; import Gio from "gi://Gio?version=2.0"; import GObject from "gi://GObject?version=2.0"; import { time } from "../scripts/utils"; +import { onCleanup } from "ags"; const { TOP, LEFT, RIGHT, BOTTOM } = Astal.WindowAnchor; @@ -24,10 +25,10 @@ export const LogoutMenu = (mon: number) => self.add_controller(controllerKey); conns.set(controllerKey, controllerKey.connect("key-released", (_, keyval) => { if(keyval === Gdk.KEY_Escape) - self.close(); + self.destroy(); })); - conns.set(self, self.connect("destroy", () => conns.forEach((id, obj) => - obj.disconnect(id)))); + + onCleanup(() => conns.forEach((id, obj) => obj.disconnect(id))); }}> return true; } })); + + onCleanup(() => conns.forEach((id, obj) => obj.disconnect(id))); }}> + orientation={Gtk.Orientation.VERTICAL} valign={Gtk.Align.START}> t.format("%H:%M")!)} /> d.format("%A, %B %d %Y")!)} /> - + AskPopup(poweroffAsk)} onActivate={() => AskPopup(poweroffAsk)}