✨ chore: better window management
now, everything is inside a single object! much better
This commit is contained in:
@@ -33,7 +33,7 @@ export function handleArguments(request: string): any {
|
|||||||
|
|
||||||
case "windows":
|
case "windows":
|
||||||
return Object.keys(Windows.getDefault().windows).map(name =>
|
return Object.keys(Windows.getDefault().windows).map(name =>
|
||||||
`${name}: ${Windows.getDefault().isVisible(name) ? "open" : "closed" }`).join('\n');
|
`${name}: ${Windows.getDefault().isOpen(name) ? "open" : "closed" }`).join('\n');
|
||||||
|
|
||||||
case "runner":
|
case "runner":
|
||||||
!Runner.instance ?
|
!Runner.instance ?
|
||||||
@@ -68,7 +68,7 @@ function handleWindowArgs(args: Array<string>): string {
|
|||||||
|
|
||||||
switch(args[0]) {
|
switch(args[0]) {
|
||||||
case "open":
|
case "open":
|
||||||
if(!Windows.getDefault().isVisible(specifiedWindow)) {
|
if(!Windows.getDefault().isOpen(specifiedWindow)) {
|
||||||
Windows.getDefault().open(specifiedWindow);
|
Windows.getDefault().open(specifiedWindow);
|
||||||
return `Setting visibility of window "${args[1]}" to true`;
|
return `Setting visibility of window "${args[1]}" to true`;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ function handleWindowArgs(args: Array<string>): string {
|
|||||||
return `Window is already open, ignored`;
|
return `Window is already open, ignored`;
|
||||||
|
|
||||||
case "close":
|
case "close":
|
||||||
if(Windows.getDefault().isVisible(specifiedWindow)) {
|
if(Windows.getDefault().isOpen(specifiedWindow)) {
|
||||||
Windows.getDefault().close(specifiedWindow);
|
Windows.getDefault().close(specifiedWindow);
|
||||||
return `Setting visibility of window "${args[1]}" to false`
|
return `Setting visibility of window "${args[1]}" to false`
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ function handleWindowArgs(args: Array<string>): string {
|
|||||||
return `Window is already closed, ignored`
|
return `Window is already closed, ignored`
|
||||||
|
|
||||||
case "toggle":
|
case "toggle":
|
||||||
if(!Windows.getDefault().isVisible(specifiedWindow)) {
|
if(!Windows.getDefault().isOpen(specifiedWindow)) {
|
||||||
Windows.getDefault().open(specifiedWindow);
|
Windows.getDefault().open(specifiedWindow);
|
||||||
return `Toggle opening window "${args[1]}"`;
|
return `Toggle opening window "${args[1]}"`;
|
||||||
}
|
}
|
||||||
|
|||||||
+173
-145
@@ -1,19 +1,29 @@
|
|||||||
import GObject, { getter, register, signal } from "ags/gobject";
|
|
||||||
import { Astal } from "ags/gtk4";
|
import { Astal } from "ags/gtk4";
|
||||||
import { Bar } from "./window/Bar";
|
import { Bar } from "./window/Bar";
|
||||||
|
import { variableToBoolean } from "./scripts/utils";
|
||||||
import App from "ags/gtk4/app"
|
|
||||||
import AstalHyprland from "gi://AstalHyprland";
|
|
||||||
import { OSD } from "./window/OSD";
|
import { OSD } from "./window/OSD";
|
||||||
import { ControlCenter } from "./window/ControlCenter";
|
import { ControlCenter } from "./window/ControlCenter";
|
||||||
import { FloatingNotifications } from "./window/FloatingNotifications";
|
import { FloatingNotifications } from "./window/FloatingNotifications";
|
||||||
import { CenterWindow } from "./window/CenterWindow";
|
import { CenterWindow } from "./window/CenterWindow";
|
||||||
import { LogoutMenu } from "./window/LogoutMenu";
|
import { LogoutMenu } from "./window/LogoutMenu";
|
||||||
import { AppsWindow } from "./window/AppsWindow";
|
import { AppsWindow } from "./window/AppsWindow";
|
||||||
|
import { createRoot, onCleanup } from "ags";
|
||||||
|
import GObject, { getter, register, signal } from "ags/gobject";
|
||||||
|
|
||||||
|
import AstalHyprland from "gi://AstalHyprland";
|
||||||
|
import { Scope } from "../../../../usr/share/ags/js/gnim/src/jsx/scope";
|
||||||
|
|
||||||
|
|
||||||
export { Windows };
|
export { Windows };
|
||||||
|
|
||||||
|
export type WindowInstance = { instance?: Astal.Window, connections: Array<number> };
|
||||||
|
export type WindowData = {
|
||||||
|
create: () => (Astal.Window | Array<Astal.Window>);
|
||||||
|
instance?: WindowInstance | Array<WindowInstance>;
|
||||||
|
status?: "open" | "closed";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Windowing System
|
* Windowing System
|
||||||
* Possible actions: getting window states, close, open, toggle windows and
|
* Possible actions: getting window states, close, open, toggle windows and
|
||||||
@@ -25,112 +35,130 @@ export { Windows };
|
|||||||
class Windows extends GObject.Object {
|
class Windows extends GObject.Object {
|
||||||
private static instance: (Windows | null);
|
private static instance: (Windows | null);
|
||||||
|
|
||||||
#openWindows: Record<string, Astal.Window | Array<Astal.Window>> = {};
|
#windows: Record<string, WindowData> = {
|
||||||
#windowConnections: Record<string, (Array<number> | Array<Array<number>>)> = {};
|
"bar": { create: this.createWindowForMonitors(Bar) },
|
||||||
#appConnections: Array<number> = [];
|
"osd": { create: this.createWindowForFocusedMonitor(OSD), },
|
||||||
#windows: Record<string, (() => (Astal.Window | Array<Astal.Window>))> = {
|
"control-center": { create: this.createWindowForFocusedMonitor(ControlCenter), },
|
||||||
"bar": this.createWindowForMonitors(Bar),
|
"center-window": { create: this.createWindowForFocusedMonitor(CenterWindow), },
|
||||||
"osd": this.createWindowForFocusedMonitor(OSD),
|
"logout-menu": { create: this.createWindowForFocusedMonitor(LogoutMenu), },
|
||||||
"control-center": this.createWindowForFocusedMonitor(ControlCenter),
|
"floating-notifications": { create: this.createWindowForFocusedMonitor(FloatingNotifications), },
|
||||||
"center-window": this.createWindowForFocusedMonitor(CenterWindow),
|
"apps-window": { create: this.createWindowForFocusedMonitor(AppsWindow) }
|
||||||
"logout-menu": this.createWindowForFocusedMonitor(LogoutMenu),
|
|
||||||
"floating-notifications": this.createWindowForFocusedMonitor(FloatingNotifications),
|
|
||||||
"apps-window": this.createWindowForFocusedMonitor(AppsWindow)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@signal(String) opened(_name: string) {}
|
@signal(String) windowOpen(_name: string) {}
|
||||||
@signal(String) closed(_name: string) {}
|
@signal(String) windowClosed(_name: string) {}
|
||||||
|
|
||||||
get windows() { return this.#windows; }
|
|
||||||
|
|
||||||
@getter(Object)
|
@getter(Object)
|
||||||
get openWindows(): object { return this.#openWindows; };
|
get windows(): object { return this.#windows; }
|
||||||
|
|
||||||
|
@getter(Array)
|
||||||
|
get openWindows(): Array<string> {
|
||||||
|
return Object.keys(this.#windows).filter((key) =>
|
||||||
|
this.#windows[key].status === "open");
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
// Listen to monitor events
|
createRoot((_) => {
|
||||||
this.#appConnections.push(
|
// Listen to monitor events
|
||||||
AstalHyprland.get_default().connect("monitor-added", (_, _monitor) => {
|
const hyprConnections = [
|
||||||
AstalHyprland.get_default().get_monitors().length > 0 &&
|
AstalHyprland.get_default().connect("monitor-added", () =>
|
||||||
this.reopen();
|
this.reopen()),
|
||||||
}),
|
AstalHyprland.get_default().connect("monitor-removed", () =>
|
||||||
AstalHyprland.get_default().connect("monitor-removed", (_, monitor) => {
|
AstalHyprland.get_default().get_monitors().length > 0 &&
|
||||||
Object.values(this.openWindows).map((window: (Array<Astal.Window> | Astal.Window), i: number) => {
|
this.reopen())
|
||||||
if(Array.isArray(window)) {
|
];
|
||||||
window = window as Array<Astal.Window>;
|
|
||||||
window.map(win => {
|
|
||||||
if(win.get_monitor() === monitor) {
|
|
||||||
win?.close();
|
|
||||||
this.#openWindows[i] = (this.#openWindows[i] as Array<Astal.Window>).filter(item =>
|
|
||||||
item !== win);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if((this.#openWindows[i] as Array<Astal.Window>).length < 1)
|
onCleanup(() => {
|
||||||
delete this.#openWindows[i];
|
hyprConnections.forEach(id =>
|
||||||
}
|
GObject.signal_handler_is_connected(AstalHyprland.get_default(), id) &&
|
||||||
|
AstalHyprland.get_default().disconnect(id)
|
||||||
|
);
|
||||||
|
|
||||||
window = window as Astal.Window;
|
this.openWindows.forEach(name => this.disconnectWindow(name));
|
||||||
if(window.get_monitor() === monitor)
|
});
|
||||||
window.close();
|
|
||||||
});
|
// open windows with the "open" status on startup
|
||||||
})
|
Object.keys(this.#windows).filter((key) =>
|
||||||
);
|
this.#windows[key].status === "open"
|
||||||
|
).forEach(name => {
|
||||||
|
this.open(name, true);
|
||||||
|
console.log(`Windows: opening window \`${name}\` on startup`);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
vfunc_dispose() {
|
private disconnectWindow(name: string) {
|
||||||
Object.keys(this.#windowConnections).map(name =>
|
if(!variableToBoolean(this.#windows[name]?.instance) || !this.#windows[name]) {
|
||||||
this.disconnectWindow(name));
|
console.error(`Windows: couldn't disconnect window's connections: either the window \`${name
|
||||||
|
}\` doesn't exist in the windows list or it has no valid instance to disconnect signals from(not open)`);
|
||||||
this.#appConnections.map(id =>
|
|
||||||
GObject.signal_handler_is_connected(App, id) &&
|
|
||||||
App.disconnect(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
private disconnectWindow(name: keyof typeof this.windows) {
|
|
||||||
const window = this.#openWindows[name];
|
|
||||||
if(!window) {
|
|
||||||
console.log("couldn't disconnect, window is not open");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#windowConnections[name].map((id: Array<number> | number) => {
|
const window = this.#windows[name].instance!;
|
||||||
if(Array.isArray(window)) {
|
|
||||||
window.map((win, i) => {
|
|
||||||
const curId = (id as Array<number>)[i];
|
|
||||||
|
|
||||||
GObject.signal_handler_is_connected(win, curId) &&
|
if(Array.isArray(window)) {
|
||||||
win.disconnect(curId);
|
window.forEach(win => {
|
||||||
});
|
this._disconnectAllFromInstance(win.instance!, win.connections!)
|
||||||
return;
|
win.connections = [];
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._disconnectAllFromInstance(window.instance!, window.connections!);
|
||||||
|
window.connections = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private _disconnectAllFromInstance(instance: GObject.Object, connections: Array<number>): void {
|
||||||
|
connections.forEach(id =>
|
||||||
|
GObject.signal_handler_is_connected(instance, id) &&
|
||||||
|
instance.disconnect(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private hasConnections(name: string): boolean {
|
||||||
|
if(!this.openWindows.includes(name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const window = this.#windows[name].instance;
|
||||||
|
if(!window) return false;
|
||||||
|
|
||||||
|
if(Array.isArray(window)) {
|
||||||
|
for(const win of window) {
|
||||||
|
if(win.connections!.length > 0)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GObject.signal_handler_is_connected(window, id as number) &&
|
return false;
|
||||||
window.disconnect(id as number);
|
}
|
||||||
});
|
|
||||||
|
|
||||||
delete this.#windowConnections[name];
|
return window.connections!.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private connectWindow(name: keyof typeof this.windows) {
|
private connectWindow(name: string) {
|
||||||
if(Object.hasOwn(this.#windowConnections, name)) return;
|
if(this.hasConnections(name)) {
|
||||||
|
console.log(`Windows: skipped connecting window: \`${name}\`. Already connected`);
|
||||||
if(!this.#openWindows?.[name]) {
|
|
||||||
console.log(`${name} is not open, will not connect`);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Array.isArray(this.#openWindows[name])) {
|
if(!this.openWindows.includes(name)) {
|
||||||
this.#windowConnections[name] = this.#openWindows[name].map(win => [
|
console.log(`Windows: \`${name}\` is not open, will not connect`);
|
||||||
win.connect("map", (window) => {
|
return;
|
||||||
if(this.isVisible(name)) return;
|
}
|
||||||
|
|
||||||
this.#openWindows[name] = window;
|
const window = this.#windows[name as keyof typeof this.windows];
|
||||||
this.notify("open-windows");
|
if(!window || !window.instance) {
|
||||||
}),
|
console.error(`Windows: Either \`${name}\` does not exist in the window list or it doesn't have a valid instance. Please add the window before trying to manage it here`);
|
||||||
win.connect("destroy", () => {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Array.isArray(window.instance)) {
|
||||||
|
window.instance.forEach(inst => inst.connections = [
|
||||||
|
inst.instance!.connect("close-request", () => {
|
||||||
this.disconnectWindow(name);
|
this.disconnectWindow(name);
|
||||||
|
inst.instance = undefined;
|
||||||
|
window.status = "closed";
|
||||||
this.notify("open-windows");
|
this.notify("open-windows");
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
@@ -138,16 +166,11 @@ class Windows extends GObject.Object {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#windowConnections[name] = [
|
window.instance.connections = [
|
||||||
this.#openWindows[name].connect("map", (window) => {
|
window.instance.instance!.connect("close-request", () => {
|
||||||
if(this.isVisible(name)) return;
|
|
||||||
|
|
||||||
this.#openWindows[name] = window;
|
|
||||||
this.notify("open-windows");
|
|
||||||
}),
|
|
||||||
this.#openWindows[name].connect("destroy", () => {
|
|
||||||
this.disconnectWindow(name);
|
this.disconnectWindow(name);
|
||||||
delete this.#openWindows[name];
|
(window.instance as WindowInstance).instance = undefined;
|
||||||
|
window.status = "closed";
|
||||||
this.notify("open-windows");
|
this.notify("open-windows");
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
@@ -162,54 +185,53 @@ class Windows extends GObject.Object {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a window instance for every monitor connected
|
* Creates a window instance for every monitor connected
|
||||||
* @param windowFun function: (mon: number) => Astal.Window, returned window must use provided monitor number
|
* @param create generates the window. use provided monitor number in the returned window
|
||||||
* @returns a function that when called, returns Array<Astal.Window>
|
* @returns a function that when called, returns Array<Astal.Window>
|
||||||
* @throws Error if there are no monitors connected
|
* @throws Error if there are no monitors connected
|
||||||
*/
|
*/
|
||||||
public createWindowForMonitors(windowFun: (mon: number) => GObject.Object|Astal.Window): (() => Array<Astal.Window>) {
|
public createWindowForMonitors(create: (mon: number, scope: Scope) => GObject.Object|Astal.Window): (() => Array<Astal.Window>) {
|
||||||
const monitors = AstalHyprland.get_default().get_monitors();
|
const monitors = AstalHyprland.get_default().get_monitors();
|
||||||
if(monitors.length < 1)
|
if(monitors.length < 1)
|
||||||
throw new Error("Couldn't create window for monitors", {
|
throw new Error("Couldn't create window for monitors", {
|
||||||
cause: `No monitors connected on Hyprland`
|
cause: "No monitors connected on Hyprland"
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => monitors.map(mon => windowFun(mon.id) as Astal.Window);
|
return () => {
|
||||||
|
const scope = new Scope(null);
|
||||||
|
return monitors.map(mon =>
|
||||||
|
scope.run(() => create(mon.id, scope) as Astal.Window)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a window instance for focused monitor only
|
* Creates a window instance for focused monitor only
|
||||||
* @param windowFun function: (mon: number) => Astal.Window, returned window must use provided monitor number
|
* @param create generates the window. use provided monitor number in the returned window
|
||||||
* @returns a function that when called, returns a Astal.Window instance
|
* @returns a function that when called, returns a Astal.Window instance
|
||||||
* @throws Error if no focused monitor is found
|
* @throws Error if no focused monitor is found
|
||||||
*/
|
*/
|
||||||
public createWindowForFocusedMonitor(windowFun: (mon: number) => GObject.Object|Astal.Window): (() => Astal.Window) {
|
public createWindowForFocusedMonitor(create: (mon: number, scope: Scope) => GObject.Object|Astal.Window): (() => Astal.Window) {
|
||||||
const focusedMonitor = AstalHyprland.get_default()
|
const focusedMonitor = this.getFocusedMonitorId();
|
||||||
.get_monitors().filter(mon => mon.focused)[0];
|
|
||||||
|
|
||||||
if(!focusedMonitor)
|
if(focusedMonitor == null)
|
||||||
throw new Error("Couldn't create window for focused monitor", {
|
throw new Error("Couldn't create window for focused monitor", {
|
||||||
cause: `No focused monitor found (${typeof focusedMonitor})`
|
cause: `No focused monitor found (${typeof focusedMonitor})`
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => (windowFun(focusedMonitor.id) as Astal.Window);
|
return () => {
|
||||||
|
const scope = new Scope(null);
|
||||||
|
return scope.run(() => create(focusedMonitor, scope) as Astal.Window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public addWindow(name: string, window: (() => (Astal.Window | Array<Astal.Window>))): void {
|
public addWindow(name: string, window: (() => (Astal.Window | Array<Astal.Window>))): void {
|
||||||
this.#windows[name] = window;
|
this.#windows[name] = { create: () => createRoot((_) => window()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasWindow(name: keyof typeof this.windows): boolean {
|
public hasWindow(name: string): boolean {
|
||||||
return Boolean(this.windows?.[name as keyof typeof this.windows]);
|
return Boolean(this.windows?.[name as keyof typeof this.windows]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getWindow(name: (keyof typeof this.windows | string)): ((() => (Astal.Window | Array<Astal.Window>)) | undefined) {
|
|
||||||
return this.windows?.[name as keyof typeof this.windows];
|
|
||||||
}
|
|
||||||
|
|
||||||
public getOpenWindow(name: (keyof typeof this.openWindows)): (Astal.Window | Array<Astal.Window> | undefined) {
|
|
||||||
return this.openWindows?.[name as keyof typeof this.openWindows];
|
|
||||||
}
|
|
||||||
|
|
||||||
public getWindows(): Array<(() => (Astal.Window | Array<Astal.Window>))> {
|
public getWindows(): Array<(() => (Astal.Window | Array<Astal.Window>))> {
|
||||||
return Object.values(this.windows);
|
return Object.values(this.windows);
|
||||||
}
|
}
|
||||||
@@ -218,60 +240,66 @@ class Windows extends GObject.Object {
|
|||||||
return AstalHyprland.get_default().get_monitors().filter(mon => mon.focused)?.[0]?.id ?? null;
|
return AstalHyprland.get_default().get_monitors().filter(mon => mon.focused)?.[0]?.id ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isVisible(name: keyof typeof this.windows): boolean {
|
public isOpen(name: string): boolean {
|
||||||
return Object.hasOwn(this.#openWindows, name) || Object.hasOwn(this.#windowConnections, name);
|
return this.openWindows.includes(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public open(name: keyof typeof this.windows): void {
|
public open(name: string, ignoreOpenStatus: boolean = false): void {
|
||||||
if(this.isVisible(name)) return;
|
if(this.isOpen(name) && !ignoreOpenStatus) return;
|
||||||
|
|
||||||
let window: (() => (Astal.Window | Array<Astal.Window>)) = this.getWindow(name)!;
|
const window = this.#windows[name];
|
||||||
const openWindows: (Array<Astal.Window> | Astal.Window) = window();
|
if(!window) {
|
||||||
this.#openWindows[name] = openWindows;
|
console.error(`Windows: cannot open a window (\`${name}\`) that is not registered/doesn't exist.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#windows[name].status = "open";
|
||||||
|
const windowInstance = window.create();
|
||||||
|
|
||||||
|
if(Array.isArray(windowInstance)) {
|
||||||
|
window.instance = windowInstance.map(wi => {
|
||||||
|
wi.show();
|
||||||
|
return { instance: wi, connections: [] };
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.instance = { instance: windowInstance, connections: [] };
|
||||||
|
windowInstance.show();
|
||||||
|
}
|
||||||
|
|
||||||
this.connectWindow(name);
|
this.connectWindow(name);
|
||||||
|
|
||||||
this.emit("opened", name);
|
this.emit("window-open", name);
|
||||||
this.notify("open-windows");
|
this.notify("open-windows");
|
||||||
|
|
||||||
if(Array.isArray(openWindows)) {
|
|
||||||
openWindows.map(win => win.show());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
openWindows.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public close(name: keyof typeof this.windows): void {
|
public close(name: string): void {
|
||||||
if(!this.isVisible(name)) return;
|
if(!this.isOpen(name)) return;
|
||||||
|
|
||||||
this.disconnectWindow(name);
|
this.disconnectWindow(name);
|
||||||
|
const window = this.#windows[name];
|
||||||
|
|
||||||
const window = this.#openWindows[name];
|
if(Array.isArray(window.instance))
|
||||||
delete this.#openWindows[name];
|
window.instance.map(inst => inst.instance!.close());
|
||||||
|
else
|
||||||
|
window.instance!.instance!.close();
|
||||||
|
|
||||||
if(Array.isArray(window)) {
|
this.#windows[name].status = "closed";
|
||||||
window.map(win => win.close());
|
|
||||||
this.emit("closed", name);
|
|
||||||
this.notify("open-windows");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.close();
|
this.emit("window-closed", name);
|
||||||
this.emit("closed", name);
|
|
||||||
this.notify("open-windows");
|
this.notify("open-windows");
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggle(name: keyof typeof this.windows): void {
|
public toggle(name: string): void {
|
||||||
this.isVisible(name) ? this.close(name) : this.open(name);
|
this.isOpen(name) ? this.close(name) : this.open(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public closeAll(): void {
|
public closeAll(): void {
|
||||||
Object.keys(this.openWindows).map(name => this.close(name));
|
this.openWindows.forEach(name => this.close(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public reopen(): void {
|
public reopen(): void {
|
||||||
const openWins = Object.keys(this.openWindows);
|
const openWins = [ ...this.openWindows ];
|
||||||
this.closeAll();
|
this.closeAll();
|
||||||
openWins.map(name => this.open(name));
|
openWins.forEach(name => this.open(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user