💥 fix(popup-window): outside-click not working
this commit applies another method of doing this function. The checks happen in the same layer, instead of two layers
This commit is contained in:
+21
-9
@@ -4,6 +4,7 @@ import { PopupWindow, PopupWindowProps } from "../widget/PopupWindow";
|
|||||||
import { updateApps } from "../scripts/apps";
|
import { updateApps } from "../scripts/apps";
|
||||||
import { ResultWidget, ResultWidgetProps } from "../widget/runner/ResultWidget";
|
import { ResultWidget, ResultWidgetProps } from "../widget/runner/ResultWidget";
|
||||||
import { Windows } from "../windows";
|
import { Windows } from "../windows";
|
||||||
|
import AstalHyprland from "gi://AstalHyprland";
|
||||||
|
|
||||||
export namespace Runner {
|
export namespace Runner {
|
||||||
export type RunnerProps = {
|
export type RunnerProps = {
|
||||||
@@ -13,6 +14,7 @@ export type RunnerProps = {
|
|||||||
height?: number;
|
height?: number;
|
||||||
entryPlaceHolder?: string;
|
entryPlaceHolder?: string;
|
||||||
initialText?: string;
|
initialText?: string;
|
||||||
|
resultsLimit?: number;
|
||||||
showResultsPlaceHolderOnStartup?: boolean;
|
showResultsPlaceHolderOnStartup?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -57,7 +59,7 @@ export function getPlugins(): Array<Runner.Plugin> {
|
|||||||
return [...plugins.values()];
|
return [...plugins.values()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes a plugin from the runner plugin list
|
/** Removes a plugin from the runner plugins list
|
||||||
* @returns true if plugin was removed or false if plugin wasn't found
|
* @returns true if plugin was removed or false if plugin wasn't found
|
||||||
*/
|
*/
|
||||||
export function removePlugin(plugin: Plugin): boolean {
|
export function removePlugin(plugin: Plugin): boolean {
|
||||||
@@ -75,7 +77,8 @@ export function openDefault(initialText?: string) {
|
|||||||
return Runner.openRunner({
|
return Runner.openRunner({
|
||||||
entryPlaceHolder: "Start typing...",
|
entryPlaceHolder: "Start typing...",
|
||||||
showResultsPlaceHolderOnStartup: false,
|
showResultsPlaceHolderOnStartup: false,
|
||||||
initialText
|
initialText,
|
||||||
|
resultsLimit: 24
|
||||||
} as Runner.RunnerProps,
|
} as Runner.RunnerProps,
|
||||||
() => [
|
() => [
|
||||||
new ResultWidget({
|
new ResultWidget({
|
||||||
@@ -145,6 +148,8 @@ export function openRunner(props?: RunnerProps, placeholder?: () => Array<Result
|
|||||||
primary_icon_name: "system-search"
|
primary_icon_name: "system-search"
|
||||||
} as Widget.EntryProps);
|
} as Widget.EntryProps);
|
||||||
|
|
||||||
|
const defaultHeight = 300;
|
||||||
|
|
||||||
const resultsList: Gtk.ListBox = new Gtk.ListBox({
|
const resultsList: Gtk.ListBox = new Gtk.ListBox({
|
||||||
visible: true,
|
visible: true,
|
||||||
expand: true
|
expand: true
|
||||||
@@ -174,9 +179,14 @@ export function openRunner(props?: RunnerProps, placeholder?: () => Array<Result
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return calledPlugins.map(plugin => plugin.handle(
|
const results = calledPlugins.map(plugin => plugin.handle(
|
||||||
plugin.prefix ? input.replace(plugin.prefix, "") : input)
|
plugin.prefix ? input.replace(plugin.prefix, "") : input)
|
||||||
).filter(value => value !== undefined && value !== null).flat(1);
|
).filter(value => value !== undefined && value !== null).flat(1);
|
||||||
|
|
||||||
|
return props?.resultsLimit != null &&
|
||||||
|
props.resultsLimit !== Infinity ?
|
||||||
|
results.splice(0, props.resultsLimit)
|
||||||
|
: results;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateResultsList(entryText: string) {
|
function updateResultsList(entryText: string) {
|
||||||
@@ -213,10 +223,12 @@ export function openRunner(props?: RunnerProps, placeholder?: () => Array<Result
|
|||||||
instance = Windows.createWindowForFocusedMonitor((mon: number): (Widget.Window) => PopupWindow({
|
instance = Windows.createWindowForFocusedMonitor((mon: number): (Widget.Window) => PopupWindow({
|
||||||
namespace: "runner",
|
namespace: "runner",
|
||||||
monitor: mon,
|
monitor: mon,
|
||||||
widthRequest: props?.width ?? 750,
|
widthRequest: props?.width ?? 780,
|
||||||
heightRequest: props?.height ?? 450,
|
heightRequest: props?.height ?? defaultHeight,
|
||||||
marginTop: 240,
|
marginTop: (AstalHyprland.get_default().get_monitor(mon)?.height / 2) - 220,
|
||||||
anchor: Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM,
|
exclusivity: Astal.Exclusivity.IGNORE,
|
||||||
|
halign: Gtk.Align.CENTER,
|
||||||
|
valign: Gtk.Align.START,
|
||||||
setup: () => {
|
setup: () => {
|
||||||
// Init plugins
|
// Init plugins
|
||||||
plugins.forEach(plugin => plugin.init && plugin.init());
|
plugins.forEach(plugin => plugin.init && plugin.init());
|
||||||
@@ -246,7 +258,7 @@ export function openRunner(props?: RunnerProps, placeholder?: () => Array<Result
|
|||||||
child: new Widget.Box({
|
child: new Widget.Box({
|
||||||
className: "runner main",
|
className: "runner main",
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
expand: false,
|
hexpand: true,
|
||||||
valign: Gtk.Align.START,
|
valign: Gtk.Align.START,
|
||||||
children: [
|
children: [
|
||||||
gtkEntry,
|
gtkEntry,
|
||||||
@@ -256,7 +268,7 @@ export function openRunner(props?: RunnerProps, placeholder?: () => Array<Result
|
|||||||
hscroll: Gtk.PolicyType.NEVER,
|
hscroll: Gtk.PolicyType.NEVER,
|
||||||
expand: true,
|
expand: true,
|
||||||
propagateNaturalHeight: true,
|
propagateNaturalHeight: true,
|
||||||
maxContentHeight: props?.height ?? 450,
|
maxContentHeight: props?.height ?? defaultHeight,
|
||||||
child: resultsList
|
child: resultsList
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export type BackgroundWindowProps = {
|
|||||||
/** Function that is called when the user clicks on the window with secodary mouse button */
|
/** Function that is called when the user clicks on the window with secodary mouse button */
|
||||||
onClickSecondary?: (window: Widget.Window) => void;
|
onClickSecondary?: (window: Widget.Window) => void;
|
||||||
keymode?: Astal.Keymode;
|
keymode?: Astal.Keymode;
|
||||||
|
exclusivity?: Astal.Exclusivity;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Creates a fullscreen GtkWindow that is used for making
|
/** Creates a fullscreen GtkWindow that is used for making
|
||||||
@@ -35,8 +36,8 @@ export function BackgroundWindow(props: BackgroundWindowProps) {
|
|||||||
monitor: props.monitor,
|
monitor: props.monitor,
|
||||||
layer: props.layer ?? Astal.Layer.OVERLAY,
|
layer: props.layer ?? Astal.Layer.OVERLAY,
|
||||||
anchor: TOP | LEFT | BOTTOM | RIGHT,
|
anchor: TOP | LEFT | BOTTOM | RIGHT,
|
||||||
keymode: props.keymode ?? Astal.Keymode.NONE,
|
keymode: props.keymode,
|
||||||
exclusivity: Astal.Exclusivity.IGNORE,
|
exclusivity: props.exclusivity ?? Astal.Exclusivity.IGNORE,
|
||||||
onKeyPressEvent: (self, event: Gdk.Event) => {
|
onKeyPressEvent: (self, event: Gdk.Event) => {
|
||||||
event.get_keyval()[1] === Gdk.KEY_Escape &&
|
event.get_keyval()[1] === Gdk.KEY_Escape &&
|
||||||
props.onAction?.(self);
|
props.onAction?.(self);
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ export function CustomDialog(props: CustomDialogProps = {
|
|||||||
cssBackgroundWindow: props.cssBackground ?? "background: rgba(0, 0, 0, .3);",
|
cssBackgroundWindow: props.cssBackground ?? "background: rgba(0, 0, 0, .3);",
|
||||||
exclusivity: Astal.Exclusivity.IGNORE,
|
exclusivity: Astal.Exclusivity.IGNORE,
|
||||||
layer: Astal.Layer.OVERLAY,
|
layer: Astal.Layer.OVERLAY,
|
||||||
|
halign: Gtk.Align.CENTER,
|
||||||
|
valign: Gtk.Align.CENTER,
|
||||||
widthRequest: props.widthRequest ?? 400,
|
widthRequest: props.widthRequest ?? 400,
|
||||||
heightRequest: props.heightRequest ?? 220,
|
heightRequest: props.heightRequest ?? 220,
|
||||||
onDestroy: props.onFinish,
|
onDestroy: props.onFinish,
|
||||||
|
|||||||
+77
-13
@@ -1,37 +1,84 @@
|
|||||||
import { Binding } from "astal";
|
import { Binding } from "astal";
|
||||||
import { Astal, Gdk, Widget } from "astal/gtk3";
|
import { Astal, Gdk, Gtk, Widget } from "astal/gtk3";
|
||||||
import { BackgroundWindow } from "./BackgroundWindow";
|
import { BackgroundWindow } from "./BackgroundWindow";
|
||||||
|
|
||||||
type PopupWindowSpecificProps = {
|
type PopupWindowSpecificProps = {
|
||||||
onDestroy?: (self: Widget.Window) => void;
|
onDestroy?: (self: Widget.Window) => void;
|
||||||
onKeyPressEvent?: (win: Widget.Window, event: Gdk.Event) => void;
|
onKeyPressEvent?: (self: Widget.Window, event: Gdk.Event) => void;
|
||||||
|
onButtonPressEvent?: (self: Gtk.Widget, event: Gdk.Event) => void;
|
||||||
/** Stylesheet for the background of the popup-window */
|
/** Stylesheet for the background of the popup-window */
|
||||||
cssBackgroundWindow?: string;
|
cssBackgroundWindow?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PopupWindowProps = Omit<Widget.WindowProps, "keymode"> & PopupWindowSpecificProps;
|
export type PopupWindowProps = Pick<Widget.WindowProps,
|
||||||
|
"child"
|
||||||
|
| "monitor"
|
||||||
|
| "css"
|
||||||
|
| "layer"
|
||||||
|
| "exclusivity"
|
||||||
|
| "marginLeft"
|
||||||
|
| "marginTop"
|
||||||
|
| "marginRight"
|
||||||
|
| "marginBottom"
|
||||||
|
| "expand"
|
||||||
|
| "cursor"
|
||||||
|
| "canFocus"
|
||||||
|
| "hasFocus"
|
||||||
|
| "tooltipMarkup"
|
||||||
|
| "namespace"
|
||||||
|
| "widthRequest"
|
||||||
|
| "heightRequest"
|
||||||
|
| "halign"
|
||||||
|
| "valign"
|
||||||
|
| "vexpand"
|
||||||
|
| "hexpand"> & PopupWindowSpecificProps;
|
||||||
|
|
||||||
|
const { TOP, LEFT, RIGHT, BOTTOM } = Astal.WindowAnchor;
|
||||||
|
|
||||||
export function PopupWindow(props: PopupWindowProps): Widget.Window {
|
export function PopupWindow(props: PopupWindowProps): Widget.Window {
|
||||||
props.layer = props.layer ?? Astal.Layer.OVERLAY;
|
props.layer = props.layer ?? Astal.Layer.OVERLAY;
|
||||||
|
|
||||||
const bgWindow = BackgroundWindow({
|
const bgWindow = props.cssBackgroundWindow ? BackgroundWindow({
|
||||||
monitor: props.monitor ?? 0,
|
monitor: props.monitor ?? 0,
|
||||||
layer: props.layer!,
|
layer: props.layer,
|
||||||
css: props.cssBackgroundWindow ?? "",
|
css: props.cssBackgroundWindow,
|
||||||
onAction: () => window.close()
|
}) : undefined;
|
||||||
});
|
|
||||||
|
|
||||||
const window = new Widget.Window({
|
return new Widget.Window({
|
||||||
...props,
|
...props,
|
||||||
namespace: props?.namespace ?? "popup-window",
|
namespace: props?.namespace ?? "popup-window",
|
||||||
className: `popup-window ${(props.namespace instanceof Binding ?
|
className: `popup-window ${(props.namespace instanceof Binding ?
|
||||||
props.namespace.get() : props.namespace) || ""}`,
|
props.namespace.get() : props.namespace) || ""}`,
|
||||||
keymode: Astal.Keymode.EXCLUSIVE,
|
keymode: Astal.Keymode.EXCLUSIVE,
|
||||||
layer: props.layer!,
|
anchor: TOP | LEFT | RIGHT | BOTTOM,
|
||||||
|
exclusivity: props.exclusivity ?? Astal.Exclusivity.NORMAL,
|
||||||
|
halign: undefined,
|
||||||
|
valign: undefined,
|
||||||
|
focusOnMap: true,
|
||||||
|
widthRequest: undefined,
|
||||||
|
heightRequest: undefined,
|
||||||
|
marginTop: undefined,
|
||||||
|
marginBottom: undefined,
|
||||||
|
marginLeft: undefined,
|
||||||
|
marginRight: undefined,
|
||||||
onDestroy: (self) => {
|
onDestroy: (self) => {
|
||||||
bgWindow.close();
|
bgWindow?.close();
|
||||||
props.onDestroy?.(self);
|
props.onDestroy?.(self);
|
||||||
},
|
},
|
||||||
|
onButtonPressEvent: (self, event) => {
|
||||||
|
if((event.get_button()[1] === Gdk.BUTTON_PRIMARY ||
|
||||||
|
event.get_button()[1] === Gdk.BUTTON_SECONDARY)) {
|
||||||
|
|
||||||
|
const [ , x, y ] = event.get_coords();
|
||||||
|
const allocation = (self.get_child()! as Widget.Box).get_child()!.get_allocation();
|
||||||
|
|
||||||
|
if((x < allocation.x || x > (allocation.x + allocation.width)) ||
|
||||||
|
(y < allocation.y || y > (allocation.y + allocation.height))) {
|
||||||
|
|
||||||
|
self.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
onKeyPressEvent: (self, event: Gdk.Event) => {
|
onKeyPressEvent: (self, event: Gdk.Event) => {
|
||||||
if(event.get_keyval()[1] === Gdk.KEY_Escape) {
|
if(event.get_keyval()[1] === Gdk.KEY_Escape) {
|
||||||
self.close();
|
self.close();
|
||||||
@@ -40,7 +87,24 @@ export function PopupWindow(props: PopupWindowProps): Widget.Window {
|
|||||||
|
|
||||||
props.onKeyPressEvent?.(self, event);
|
props.onKeyPressEvent?.(self, event);
|
||||||
},
|
},
|
||||||
} as Widget.WindowProps);
|
child: new Widget.Box({
|
||||||
|
expand: props.expand ?? false,
|
||||||
|
halign: props.halign,
|
||||||
|
valign: props.valign,
|
||||||
|
hexpand: true,
|
||||||
|
css: `box {
|
||||||
|
margin-left: ${props.marginLeft ?? 0}px;
|
||||||
|
margin-right: ${props.marginRight ?? 0}px;
|
||||||
|
margin-top: ${props.marginTop ?? 0}px;
|
||||||
|
margin-bottom: ${props.marginBottom ?? 0}px;
|
||||||
|
}`,
|
||||||
|
|
||||||
return window;
|
child: new Widget.Box({
|
||||||
|
onButtonPressEvent: props.onButtonPressEvent ?? (() => true),
|
||||||
|
widthRequest: props.widthRequest,
|
||||||
|
heightRequest: props.heightRequest,
|
||||||
|
child: props.child
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
} as Widget.WindowProps);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import { cleanExec, getAppIcon, getApps, getAstalApps } from "../scripts/apps";
|
|||||||
import AstalApps from "gi://AstalApps";
|
import AstalApps from "gi://AstalApps";
|
||||||
import { PopupWindow } from "../widget/PopupWindow";
|
import { PopupWindow } from "../widget/PopupWindow";
|
||||||
|
|
||||||
const { TOP, LEFT, RIGHT, BOTTOM } = Astal.WindowAnchor;
|
|
||||||
|
|
||||||
export const AppsWindow = (mon: number): (Widget.Window) => {
|
export const AppsWindow = (mon: number): (Widget.Window) => {
|
||||||
const searchString = new Variable<string>("");
|
const searchString = new Variable<string>("");
|
||||||
const searchSubscription = searchString.subscribe((str: string) => {
|
const searchSubscription = searchString.subscribe((str: string) => {
|
||||||
@@ -111,10 +109,9 @@ export const AppsWindow = (mon: number): (Widget.Window) => {
|
|||||||
namespace: "apps-window",
|
namespace: "apps-window",
|
||||||
layer: Astal.Layer.OVERLAY,
|
layer: Astal.Layer.OVERLAY,
|
||||||
exclusivity: Astal.Exclusivity.IGNORE,
|
exclusivity: Astal.Exclusivity.IGNORE,
|
||||||
anchor: TOP | LEFT | RIGHT | BOTTOM,
|
|
||||||
monitor: mon,
|
monitor: mon,
|
||||||
cssBackgroundWindow: "background: rgba(0, 0, 0, .2)",
|
|
||||||
marginTop: 64,
|
marginTop: 64,
|
||||||
|
cssBackgroundWindow: "background: rgba(0, 0, 0, .2)",
|
||||||
onDestroy: () => {
|
onDestroy: () => {
|
||||||
searchSubscription?.();
|
searchSubscription?.();
|
||||||
searchString.drop();
|
searchString.drop();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Astal, Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
import { bind, GLib } from "astal";
|
import { bind, GLib } from "astal";
|
||||||
|
|
||||||
import { getDateTime } from "../scripts/time";
|
import { getDateTime } from "../scripts/time";
|
||||||
@@ -10,7 +10,8 @@ import AstalMpris from "gi://AstalMpris";
|
|||||||
export const CenterWindow = (mon: number) => PopupWindow({
|
export const CenterWindow = (mon: number) => PopupWindow({
|
||||||
namespace: "center-window",
|
namespace: "center-window",
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
anchor: Astal.WindowAnchor.TOP,
|
halign: Gtk.Align.CENTER,
|
||||||
|
valign: Gtk.Align.START,
|
||||||
monitor: mon,
|
monitor: mon,
|
||||||
child: new Widget.Box({
|
child: new Widget.Box({
|
||||||
className: "center-window-container",
|
className: "center-window-container",
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ import { QuickActions } from "../widget/control-center/QuickActions";
|
|||||||
import { Tiles } from "../widget/control-center/Tiles";
|
import { Tiles } from "../widget/control-center/Tiles";
|
||||||
import { Sliders } from "../widget/control-center/Sliders";
|
import { Sliders } from "../widget/control-center/Sliders";
|
||||||
import { NotifHistory } from "../widget/control-center/NotifHistory";
|
import { NotifHistory } from "../widget/control-center/NotifHistory";
|
||||||
import { PopupWindow } from "../widget/PopupWindow";
|
import { PopupWindow, PopupWindowProps } from "../widget/PopupWindow";
|
||||||
|
|
||||||
|
|
||||||
export const ControlCenter = (mon: number) => PopupWindow({
|
export const ControlCenter = (mon: number) => PopupWindow({
|
||||||
namespace: "control-center",
|
namespace: "control-center",
|
||||||
className: "control-center",
|
className: "control-center",
|
||||||
exclusivity: Astal.Exclusivity.NORMAL,
|
halign: Gtk.Align.END,
|
||||||
anchor: Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.BOTTOM,
|
valign: Gtk.Align.START,
|
||||||
layer: Astal.Layer.OVERLAY,
|
layer: Astal.Layer.OVERLAY,
|
||||||
focusOnMap: true,
|
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
@@ -34,4 +33,4 @@ export const ControlCenter = (mon: number) => PopupWindow({
|
|||||||
NotifHistory()
|
NotifHistory()
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
} as Widget.WindowProps);
|
} as PopupWindowProps);
|
||||||
|
|||||||
Reference in New Issue
Block a user