feat(agsV2): only let one notif popup at a time
All checks were successful
Discord / discord commits (push) Has been skipped

This commit is contained in:
matt1432 2024-10-17 11:04:24 -04:00
parent 4c7fd11ee3
commit bb17277123
6 changed files with 96 additions and 60 deletions

View file

@ -88,7 +88,7 @@ export class PopupWindow extends Widget.Window {
side = 'right' as 'left' | 'right', side = 'right' as 'left' | 'right',
) { ) {
const monitor = this.gdkmonitor ?? const monitor = this.gdkmonitor ??
this.get_display().get_monitor_at_point(alloc.x, alloc.y); this.get_display().get_monitor_at_point(alloc.x, alloc.y);
// @ts-expect-error this should exist // @ts-expect-error this should exist
const transform = get_hyprland_monitor(monitor)?.transform; const transform = get_hyprland_monitor(monitor)?.transform;
@ -103,12 +103,12 @@ export class PopupWindow extends Widget.Window {
} }
this.margin_right = side === 'right' ? this.margin_right = side === 'right' ?
(width - alloc.x - alloc.width) : (width - alloc.x - alloc.width) :
this.margin_right; this.margin_right;
this.margin_left = side === 'right' ? this.margin_left = side === 'right' ?
this.margin_left : this.margin_left :
(alloc.x - alloc.width); (alloc.x - alloc.width);
} }
} }

View file

@ -59,29 +59,33 @@ const NotificationList = () => (
); );
const ClearButton = () => ( const ClearButton = () => (
<button <eventbox
className="clear" cursor={bind(HasNotifs).as((hasNotifs) => hasNotifs ? 'pointer' : 'not-allowed')}
sensitive={bind(HasNotifs)}
onButtonReleaseEvent={() => {
Notifications.get_notifications().forEach((notif) => {
notif.dismiss();
});
timeout(1000, () => {
App.get_window('win-notif-center')?.set_visible(false);
});
}}
> >
<box> <button
<label label="Clear " /> className="clear"
sensitive={bind(HasNotifs)}
<icon icon={bind(Notifications, 'notifications') onButtonReleaseEvent={() => {
.as((notifs) => notifs.length > 0 ? Notifications.get_notifications().forEach((notif) => {
'user-trash-full-symbolic' : notif.dismiss();
'user-trash-symbolic')} });
/> timeout(1000, () => {
</box> App.get_window('win-notif-center')?.set_visible(false);
</button> });
}}
>
<box>
<label label="Clear " />
<icon icon={bind(Notifications, 'notifications')
.as((notifs) => notifs.length > 0 ?
'user-trash-full-symbolic' :
'user-trash-symbolic')}
/>
</box>
</button>
</eventbox>
); );
const Header = () => ( const Header = () => (

View file

@ -62,6 +62,9 @@ export class NotifGestureWrapper extends Widget.EventBox {
@signal(Number) @signal(Number)
declare timer_update: (popup_timer: number) => void; declare timer_update: (popup_timer: number) => void;
public static sliding_in = 0;
public static on_sliding_in: (amount: number) => void;
public dragging: boolean; public dragging: boolean;
private async get_hovered(): Promise<boolean> { private async get_hovered(): Promise<boolean> {
@ -69,37 +72,33 @@ export class NotifGestureWrapper extends Widget.EventBox {
const layers = JSON.parse(await hyprMessage('j/layers')) as LayerResult; const layers = JSON.parse(await hyprMessage('j/layers')) as LayerResult;
const cursorPos = JSON.parse(await hyprMessage('j/cursorpos')) as CursorPos; const cursorPos = JSON.parse(await hyprMessage('j/cursorpos')) as CursorPos;
const window = this.get_window(); const monitor = display?.get_monitor_at_window(this.get_window()!);
const plugName = get_hyprland_monitor(monitor!)?.name;
if (window) { const notifLayer = layers[plugName ?? '']?.levels['3']
const monitor = display?.get_monitor_at_window(window); ?.find((n) => n.namespace === 'notifications');
if (monitor) { if (!notifLayer) {
const plugName = get_hyprland_monitor(monitor)?.name; return false;
const notifLayer = layers[plugName ?? '']?.levels['3'] }
?.find((n) => n.namespace === 'notifications');
if (notifLayer) { const index = [...NotifGestureWrapper.popups.keys()]
const index = [...NotifGestureWrapper.popups.keys()] .sort((a, b) => b - a)
.sort((a, b) => b - a) .indexOf(this.id);
.indexOf(this.id);
const popups = [...NotifGestureWrapper.popups.entries()] const popups = [...NotifGestureWrapper.popups.entries()]
.sort((a, b) => b[0] - a[0]) .sort((a, b) => b[0] - a[0])
.map(([key, val]) => [key, val.get_allocated_height()]); .map(([key, val]) => [key, val.get_allocated_height()]);
const thisY = notifLayer.y + popups const thisY = notifLayer.y + popups
.map((v) => v[1]) .map((v) => v[1])
.slice(0, index) .slice(0, index)
.reduce((prev, curr) => prev + curr, 0); .reduce((prev, curr) => prev + curr, 0);
if (cursorPos.y >= thisY && cursorPos.y <= thisY + (popups[index][1] ?? 0)) { if (cursorPos.y >= thisY && cursorPos.y <= thisY + (popups[index][1] ?? 0)) {
if (cursorPos.x >= notifLayer.x && if (cursorPos.x >= notifLayer.x &&
cursorPos.x <= notifLayer.x + notifLayer.w) { cursorPos.x <= notifLayer.x + notifLayer.w) {
return true; return true;
}
}
}
} }
} }
} }
@ -301,6 +300,10 @@ export class NotifGestureWrapper extends Widget.EventBox {
} }
}); });
if (this.is_popup) {
NotifGestureWrapper.on_sliding_in(++NotifGestureWrapper.sliding_in);
}
// Reverse of slideAway, so it started at squeeze, then we go to slide // Reverse of slideAway, so it started at squeeze, then we go to slide
self.css = this.slide_in_from === 'Left' ? self.css = this.slide_in_from === 'Left' ?
slideLeft : slideLeft :
@ -312,6 +315,14 @@ export class NotifGestureWrapper extends Widget.EventBox {
setTimeout(() => { setTimeout(() => {
// Then we go to center // Then we go to center
self.css = defaultStyle; self.css = defaultStyle;
if (this.is_popup) {
setTimeout(() => {
NotifGestureWrapper.on_sliding_in(
--NotifGestureWrapper.sliding_in,
);
}, ANIM_DURATION);
}
}, ANIM_DURATION); }, ANIM_DURATION);
}); });
}} }}

View file

@ -1,4 +1,4 @@
import { App, Gtk, Gdk } from 'astal/gtk3'; import { App, Gtk, Gdk, Widget } from 'astal/gtk3';
import { Variable } from 'astal'; import { Variable } from 'astal';
import GLib from 'gi://GLib?version=2.0'; import GLib from 'gi://GLib?version=2.0';
@ -26,11 +26,11 @@ const NotifIcon = ({ notifObj }: {
}) => { }) => {
let icon: string; let icon: string;
if (notifObj.get_image() !== '') { if (notifObj.get_image() && notifObj.get_image() !== '') {
icon = notifObj.get_image(); icon = notifObj.get_image();
App.add_icons(icon); App.add_icons(icon);
} }
else if (notifObj.get_app_icon() !== '') { else if (notifObj.get_app_icon() !== '' && Widget.Icon.lookup_icon(notifObj.get_app_icon())) {
icon = notifObj.get_app_icon(); icon = notifObj.get_app_icon();
} }
else { else {

View file

@ -13,19 +13,36 @@ export default () => (
vertical vertical
setup={(self) => { setup={(self) => {
const notifQueue: number[] = [];
const addPopup = (id: number) => { const addPopup = (id: number) => {
if (!id) { if (!id) {
return; return;
} }
const NewNotif = Notification({ id, popup_timer: 5 }); if (NotifGestureWrapper.sliding_in === 0) {
const NewNotif = Notification({ id, popup_timer: 5 });
if (NewNotif) { if (NewNotif) {
// Use this instead of add to put it at the top // Use this instead of add to put it at the top
self.pack_end(NewNotif, false, false, 0); self.pack_end(NewNotif, false, false, 0);
self.show_all(); self.show_all();
NotifGestureWrapper.popups.set(id, NewNotif); NotifGestureWrapper.popups.set(id, NewNotif);
}
}
else {
notifQueue.push(id);
}
};
NotifGestureWrapper.on_sliding_in = (n) => {
if (n === 0) {
const id = notifQueue.shift();
if (id) {
addPopup(id);
}
} }
}; };

View file

@ -70,6 +70,10 @@
border-radius: 30px; border-radius: 30px;
border-top: 2px solid $accent-color; border-top: 2px solid $accent-color;
.notification {
box-shadow: none;
}
viewport { viewport {
all: unset; all: unset;
} }