💥 fix(custom-dialog): close popup if closeOnClick is enabled on option

This commit is contained in:
retrozinndev
2025-07-25 23:30:35 -03:00
parent 03b1b64c5c
commit e2b4af1787
2 changed files with 50 additions and 53 deletions
+36 -45
View File
@@ -3,7 +3,7 @@ import { Windows } from "../windows";
import { PopupWindow } from "./PopupWindow"; import { PopupWindow } from "./PopupWindow";
import { Separator } from "./Separator"; import { Separator } from "./Separator";
import { tr } from "../i18n/intl"; import { tr } from "../i18n/intl";
import { Accessor, For, With } from "ags"; import { Accessor } from "ags";
import { transformWidget, variableToBoolean, WidgetNodeType } from "../scripts/utils"; import { transformWidget, variableToBoolean, WidgetNodeType } from "../scripts/utils";
@@ -28,58 +28,49 @@ export interface CustomDialogOption {
closeOnClick?: boolean | Accessor<boolean>; closeOnClick?: boolean | Accessor<boolean>;
} }
function CustomDialogOption({closeOnClick = true, ...props}: CustomDialogOption & { dialog: Astal.Window }) { function CustomDialogOption({closeOnClick = true, ...props}: CustomDialogOption & {
function onClicked() { dialog: Astal.Window;
props.onClick?.(); }) {
closeOnClick &&
props.dialog?.close();
}
return <Gtk.Button class="option" hexpand label={props.text} return <Gtk.Button class="option" hexpand label={props.text}
onClicked={onClicked} onActivate={onClicked}/> onClicked={() => {
props.onClick?.();
closeOnClick &&
props.dialog?.close();
}}
/>
} }
export function CustomDialog({ options = [{ text: tr("accept") }], ...props}: CustomDialogProps) { export function CustomDialog({ options = [{ text: tr("accept") }], ...props}: CustomDialogProps) {
return Windows.getDefault().createWindowForFocusedMonitor((mon) => return Windows.getDefault().createWindowForFocusedMonitor((mon) => {
<PopupWindow namespace={props.namespace ?? "custom-dialog"} monitor={mon} const popup = <PopupWindow namespace={props.namespace ?? "custom-dialog"} monitor={mon}
cssBackgroundWindow={props.cssBackground ?? "background: rgba(0, 0, 0, .3);"} cssBackgroundWindow={props.cssBackground ?? "background: rgba(0, 0, 0, .3);"}
exclusivity={Astal.Exclusivity.IGNORE} layer={Astal.Layer.OVERLAY} exclusivity={Astal.Exclusivity.IGNORE} layer={Astal.Layer.OVERLAY}
halign={Gtk.Align.CENTER} valign={Gtk.Align.CENTER} halign={Gtk.Align.CENTER} valign={Gtk.Align.CENTER} actionClosed={() => props.onFinish?.()}
widthRequest={props.widthRequest ?? 400} heightRequest={props.heightRequest ?? 220} widthRequest={props.widthRequest ?? 400} heightRequest={props.heightRequest ?? 220}>
onDestroy={props.onFinish} $={(self) => self.set_child(
<Gtk.Box class={props.className ?? "custom-dialog-container"} <Gtk.Box class={props.className ?? "custom-dialog-container"}
orientation={Gtk.Orientation.VERTICAL}> orientation={Gtk.Orientation.VERTICAL}>
<Gtk.Label class={"title"} visible={variableToBoolean(props.title)} label={props.title} /> <Gtk.Label class={"title"} visible={variableToBoolean(props.title)} label={props.title} />
<Gtk.Label class={"text"} visible={variableToBoolean(props.text)} label={props.text} <Gtk.Label class={"text"} visible={variableToBoolean(props.text)} label={props.text}
vexpand/> vexpand valign={Gtk.Align.START} />
<Gtk.Box class={"custom-children custom-child"} visible={variableToBoolean(props.children)} <Gtk.Box class={"custom-children custom-child"} visible={variableToBoolean(props.children)}
orientation={props.childOrientation ?? Gtk.Orientation.VERTICAL}> orientation={props.childOrientation ?? Gtk.Orientation.VERTICAL}>
{ {transformWidget(props.children, (child) => child as JSX.Element)}
(props.children instanceof Accessor) ? </Gtk.Box>
(Array.isArray(props.children) ? <Separator alpha={.2} visible={options && options.length > 0}
<For each={props.children! as Accessor<Array<JSX.Element>>}> spacing={8} orientation={Gtk.Orientation.VERTICAL} />
{(widget) => widget && widget} </Gtk.Box>
</For> </PopupWindow> as Astal.Window;
: <With value={props.children as Accessor<JSX.Element>}>
{(widget) => widget && widget}
</With>)
: (Array.isArray(props.children) ?
props.children.map(widget => widget && widget).filter(w => w)
: props.children)
}
</Gtk.Box>
<Separator alpha={.2} visible={options && options.length > 0}
spacing={8} orientation={Gtk.Orientation.VERTICAL} />
<Gtk.Box class={"options"} orientation={props.optionsOrientation ?? Gtk.Orientation.HORIZONTAL} (popup.get_child()!.get_first_child()!.get_first_child() as Gtk.Box).append(
hexpand={true} heightRequest={38} homogeneous={true}> <Gtk.Box class={"options"} orientation={props.optionsOrientation ?? Gtk.Orientation.HORIZONTAL}
hexpand={true} heightRequest={38} homogeneous={true}>
{transformWidget(options, (props) => <CustomDialogOption {...props} dialog={self} />)} {transformWidget(options, (props) => <CustomDialogOption {...props} dialog={popup} />)}
</Gtk.Box> </Gtk.Box> as Gtk.Box
</Gtk.Box> as Gtk.Box );
)}
/> as Astal.Window return popup;
)(); })();
} }
+14 -8
View File
@@ -7,12 +7,12 @@ import GObject from "ags/gobject";
type PopupWindowSpecificProps = { type PopupWindowSpecificProps = {
$?: (self: Astal.Window, container: Gtk.Box) => void; $?: (self: Astal.Window) => void;
children?: WidgetNodeType; children?: WidgetNodeType;
/** Stylesheet for the background of the popup-window */ /** Stylesheet for the background of the popup-window */
cssBackgroundWindow?: string; cssBackgroundWindow?: string;
class?: string | Accessor<string>; class?: string | Accessor<string>;
onCloseRequest?: (self: Astal.Window) => void|boolean; actionClosed?: (self: Astal.Window) => void|boolean;
actionClickedOutside?: (self: Astal.Window) => void; actionClickedOutside?: (self: Astal.Window) => void;
actionKeyPressed?: (self: Astal.Window, keyval: number, keycode: number) => void; actionKeyPressed?: (self: Astal.Window, keyval: number, keycode: number) => void;
}; };
@@ -64,7 +64,11 @@ export function PopupWindow(props: PopupWindowProps): GObject.Object {
"visible", "visible",
"marginLeft", "marginLeft",
"marginRight", "marginRight",
"marginBottom" "marginBottom",
"hexpand",
"vexpand",
"actionClosed",
"$"
])} namespace={props.namespace ?? "popup-window"} class={ ])} namespace={props.namespace ?? "popup-window"} class={
(props.class instanceof Accessor) ? (props.class instanceof Accessor) ?
((props.namespace instanceof Accessor) ? ((props.namespace instanceof Accessor) ?
@@ -73,7 +77,8 @@ export function PopupWindow(props: PopupWindowProps): GObject.Object {
: props.class.as(clss => `popup-window ${clss} ${props.namespace ?? ""}`)) : props.class.as(clss => `popup-window ${clss} ${props.namespace ?? ""}`))
: `popup-window ${props.class ?? ""} ${props.namespace ?? ""}` : `popup-window ${props.class ?? ""} ${props.namespace ?? ""}`
} keymode={Astal.Keymode.EXCLUSIVE} exclusivity={props.exclusivity ?? Astal.Exclusivity.NORMAL} } keymode={Astal.Keymode.EXCLUSIVE} exclusivity={props.exclusivity ?? Astal.Exclusivity.NORMAL}
anchor={TOP | LEFT | BOTTOM | RIGHT} visible={false} onCloseRequest={props.onCloseRequest} anchor={TOP | LEFT | BOTTOM | RIGHT} visible={false}
onCloseRequest={(self) => props.actionClosed?.(self)}
$={(self) => { $={(self) => {
const conns: Map<GObject.Object, number> = new Map(); const conns: Map<GObject.Object, number> = new Map();
const gestureClick = Gtk.GestureClick.new(); const gestureClick = Gtk.GestureClick.new();
@@ -120,7 +125,10 @@ export function PopupWindow(props: PopupWindowProps): GObject.Object {
conns.set(self, self.connect("close-request", () => conns.forEach((id, obj) => conns.set(self, self.connect("close-request", () => conns.forEach((id, obj) =>
obj.disconnect(id)))); obj.disconnect(id))));
props.$?.(self, self.get_first_child()!.get_first_child()!.get_first_child() as Gtk.Box); conns.set(self, self.connect("destroy", () => conns.forEach((id, obj) =>
obj.disconnect(id))));
props.$?.(self);
}}> }}>
<Gtk.Box hexpand={false} vexpand={false}> <Gtk.Box hexpand={false} vexpand={false}>
<Gtk.Box class={"popup-window-container"} halign={props.halign} <Gtk.Box class={"popup-window-container"} halign={props.halign}
@@ -145,9 +153,7 @@ export function PopupWindow(props: PopupWindowProps): GObject.Object {
conns.set(self, self.connect("destroy", () => conns.forEach((id, obj) => conns.set(self, self.connect("destroy", () => conns.forEach((id, obj) =>
obj.disconnect(id)))); obj.disconnect(id))));
}}> }}>
<Gtk.Box> {props.children}
{props.children}
</Gtk.Box>
</Gtk.Box> </Gtk.Box>
</Gtk.Box> </Gtk.Box>
</Astal.Window> as Astal.Window; </Astal.Window> as Astal.Window;