nixos-configs/modules/ags/config/widgets/misc/popup-window.tsx

112 lines
3.1 KiB
TypeScript
Raw Normal View History

2024-10-16 22:33:15 -04:00
import { App, Astal, Gtk, Widget } from 'astal/gtk3';
2024-10-22 13:09:39 -04:00
import { property, register } from 'astal/gobject';
import { Binding, idle } from 'astal';
2024-10-12 15:21:28 -04:00
2024-11-13 19:39:01 -05:00
import { get_hyprland_monitor, hyprMessage } from '../../lib';
2024-10-12 15:21:28 -04:00
/* Types */
type CloseType = 'none' | 'stay' | 'released' | 'clicked';
type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' |
'slide right' | 'popin' | 'fade';
type PopupCallback = (self?: Widget.Window) => void;
2024-10-12 15:21:28 -04:00
export type PopupWindowProps = Widget.WindowProps & {
2024-10-12 15:21:28 -04:00
transition?: HyprTransition | Binding<HyprTransition>
close_on_unfocus?: CloseType | Binding<CloseType>
on_open?: PopupCallback
on_close?: PopupCallback
};
@register()
2024-10-16 21:44:45 -04:00
export class PopupWindow extends Widget.Window {
2024-10-22 13:09:39 -04:00
@property(String)
declare transition: HyprTransition | Binding<HyprTransition>;
@property(String)
declare close_on_unfocus: CloseType | Binding<CloseType>;
2024-10-18 00:44:45 -04:00
on_open: PopupCallback;
on_close: PopupCallback;
2024-10-12 15:21:28 -04:00
constructor({
2024-10-16 21:44:45 -04:00
transition = 'slide top',
close_on_unfocus = 'released',
2024-10-12 15:21:28 -04:00
on_open = () => { /**/ },
on_close = () => { /**/ },
name,
visible = false,
layer = Astal.Layer.OVERLAY,
...rest
}: PopupWindowProps) {
super({
...rest,
2024-10-16 21:44:45 -04:00
name: `win-${name}`,
2024-10-12 15:21:28 -04:00
namespace: `win-${name}`,
visible: false,
layer,
setup: () => idle(() => {
// Add way to make window open on startup
if (visible) {
this.visible = true;
}
}),
});
2024-10-16 21:44:45 -04:00
App.add_window(this);
2024-10-12 15:21:28 -04:00
const setTransition = (_: PopupWindow, t: HyprTransition | Binding<HyprTransition>) => {
2024-10-16 22:33:15 -04:00
hyprMessage(`keyword layerrule animation ${t}, ${this.name}`).catch(console.log);
2024-10-12 15:21:28 -04:00
};
this.connect('notify::transition', setTransition);
this.close_on_unfocus = close_on_unfocus;
this.transition = transition;
this.on_open = on_open;
this.on_close = on_close;
this.connect('notify::visible', () => {
// Make sure we have the right animation
setTransition(this, this.transition);
if (this.visible) {
this.on_open(this);
}
else {
this.on_close(this);
}
});
};
2024-10-16 22:33:15 -04:00
async set_x_pos(
2024-10-16 22:33:15 -04:00
alloc: Gtk.Allocation,
side = 'right' as 'left' | 'right',
) {
const monitor = this.gdkmonitor ??
this.get_display().get_monitor_at_point(alloc.x, alloc.y);
2024-10-16 22:33:15 -04:00
2024-11-13 19:39:01 -05:00
const transform = get_hyprland_monitor(monitor)?.transform;
2024-10-16 22:33:15 -04:00
let width: number;
if (transform && (transform === 1 || transform === 3)) {
width = monitor.get_geometry().height;
}
else {
width = monitor.get_geometry().width;
}
this.margin_right = side === 'right' ?
(width - alloc.x - alloc.width) :
this.margin_right;
2024-10-16 22:33:15 -04:00
this.margin_left = side === 'right' ?
this.margin_left :
(alloc.x - alloc.width);
2024-10-16 22:33:15 -04:00
}
2024-10-12 15:21:28 -04:00
}
export default PopupWindow;