🔧 chore(scripts): migrate util scripts to gtk4 and ags v3
This commit is contained in:
+11
-7
@@ -1,8 +1,8 @@
|
|||||||
import { Astal } from "astal/gtk3";
|
import { Gdk, Gtk } from "ags/gtk4";
|
||||||
|
import { execAsync } from "ags/process";
|
||||||
|
|
||||||
import AstalApps from "gi://AstalApps";
|
import AstalApps from "gi://AstalApps";
|
||||||
import AstalHyprland from "gi://AstalHyprland";
|
import AstalHyprland from "gi://AstalHyprland";
|
||||||
import { execAsync } from "astal";
|
|
||||||
|
|
||||||
|
|
||||||
export const uwsmIsActive: boolean = await execAsync(
|
export const uwsmIsActive: boolean = await execAsync(
|
||||||
@@ -35,6 +35,10 @@ export function execApp(app: AstalApps.Application|string, dispatchExecArgs?: st
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function lookupIcon(name: string): boolean {
|
||||||
|
return Gtk.IconTheme.get_for_display(Gdk.Display.get_default()!)?.has_icon(name);
|
||||||
|
}
|
||||||
|
|
||||||
export function getAppsByName(appName: string): (Array<AstalApps.Application>|undefined) {
|
export function getAppsByName(appName: string): (Array<AstalApps.Application>|undefined) {
|
||||||
let found: Array<AstalApps.Application> = [];
|
let found: Array<AstalApps.Application> = [];
|
||||||
|
|
||||||
@@ -50,14 +54,14 @@ export function getAppsByName(appName: string): (Array<AstalApps.Application>|un
|
|||||||
export function getIconByAppName(appName: string): (string|undefined) {
|
export function getIconByAppName(appName: string): (string|undefined) {
|
||||||
if(!appName) return undefined;
|
if(!appName) return undefined;
|
||||||
|
|
||||||
if(Astal.Icon.lookup_icon(appName))
|
if(lookupIcon(appName))
|
||||||
return appName;
|
return appName;
|
||||||
|
|
||||||
if(Astal.Icon.lookup_icon(appName.toLowerCase()))
|
if(lookupIcon(appName.toLowerCase()))
|
||||||
return appName.toLowerCase();
|
return appName.toLowerCase();
|
||||||
|
|
||||||
const nameReverseDNS = appName.split('.');
|
const nameReverseDNS = appName.split('.');
|
||||||
if(Astal.Icon.lookup_icon(nameReverseDNS[nameReverseDNS.length - 1]))
|
if(lookupIcon(nameReverseDNS[nameReverseDNS.length - 1]))
|
||||||
return nameReverseDNS[nameReverseDNS.length - 1];
|
return nameReverseDNS[nameReverseDNS.length - 1];
|
||||||
|
|
||||||
const found: (AstalApps.Application|undefined) = getAppsByName(appName)?.[0];
|
const found: (AstalApps.Application|undefined) = getAppsByName(appName)?.[0];
|
||||||
@@ -73,7 +77,7 @@ export function getAppIcon(app: (string|AstalApps.Application)): (string|undefin
|
|||||||
if(typeof app === "string")
|
if(typeof app === "string")
|
||||||
return getIconByAppName(app);
|
return getIconByAppName(app);
|
||||||
|
|
||||||
if(app.iconName && Astal.Icon.lookup_icon(app.iconName))
|
if(app.iconName && lookupIcon(app.iconName))
|
||||||
return app.iconName;
|
return app.iconName;
|
||||||
|
|
||||||
if(app.wmClass)
|
if(app.wmClass)
|
||||||
@@ -85,7 +89,7 @@ export function getAppIcon(app: (string|AstalApps.Application)): (string|undefin
|
|||||||
export function getSymbolicIcon(app: (string|AstalApps.Application)): (string|undefined) {
|
export function getSymbolicIcon(app: (string|AstalApps.Application)): (string|undefined) {
|
||||||
const icon = getAppIcon(app);
|
const icon = getAppIcon(app);
|
||||||
|
|
||||||
return (icon && Astal.Icon.lookup_icon(`${icon}-symbolic`)) ?
|
return (icon && lookupIcon(`${icon}-symbolic`)) ?
|
||||||
`${icon}-symbolic`
|
`${icon}-symbolic`
|
||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-12
@@ -1,11 +1,13 @@
|
|||||||
import { Wireplumber } from "./volume";
|
import { Wireplumber } from "./volume";
|
||||||
import { Windows } from "../windows";
|
import { Windows } from "../windows";
|
||||||
|
|
||||||
import { restartInstance } from "./reload-handler";
|
import { restartInstance } from "./reload-handler";
|
||||||
import { AstalIO, timeout } from "astal";
|
import { timeout } from "ags/time";
|
||||||
import { Runner } from "../runner/Runner";
|
import { Runner } from "../runner/Runner";
|
||||||
import { showWorkspaceNumber } from "../widget/bar/Workspaces";
|
import { showWorkspaceNumber } from "../widget/bar/Workspaces";
|
||||||
|
|
||||||
|
import AstalIO from "gi://AstalIO";
|
||||||
|
|
||||||
|
|
||||||
let wsTimeout: (AstalIO.Time|undefined);
|
let wsTimeout: (AstalIO.Time|undefined);
|
||||||
|
|
||||||
export function handleArguments(request: string): any {
|
export function handleArguments(request: string): any {
|
||||||
@@ -28,8 +30,8 @@ export function handleArguments(request: string): any {
|
|||||||
return "Restarting instance..."
|
return "Restarting instance..."
|
||||||
|
|
||||||
case "windows":
|
case "windows":
|
||||||
return Object.keys(Windows.windows).map(name =>
|
return Object.keys(Windows.getDefault().windows).map(name =>
|
||||||
`${name}: ${Windows.isVisible(name) ? "open" : "closed" }`).join('\n');
|
`${name}: ${Windows.getDefault().isVisible(name) ? "open" : "closed" }`).join('\n');
|
||||||
|
|
||||||
case "runner":
|
case "runner":
|
||||||
!Runner.instance ?
|
!Runner.instance ?
|
||||||
@@ -59,33 +61,33 @@ function handleWindowArgs(args: Array<string>): string {
|
|||||||
|
|
||||||
const specifiedWindow: string = args[1];
|
const specifiedWindow: string = args[1];
|
||||||
|
|
||||||
if(!Windows.hasWindow(specifiedWindow))
|
if(!Windows.getDefault().hasWindow(specifiedWindow))
|
||||||
return `Name "${specifiedWindow}" not found windows map! Make sure to add new Windows on the Map!`
|
return `Name "${specifiedWindow}" not found windows map! Make sure to add new Windows on the Map!`
|
||||||
|
|
||||||
switch(args[0]) {
|
switch(args[0]) {
|
||||||
case "open":
|
case "open":
|
||||||
if(!Windows.isVisible(specifiedWindow)) {
|
if(!Windows.getDefault().isVisible(specifiedWindow)) {
|
||||||
Windows.open(specifiedWindow);
|
Windows.getDefault().open(specifiedWindow);
|
||||||
return `Setting visibility of window "${args[1]}" to true`;
|
return `Setting visibility of window "${args[1]}" to true`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `Window is already open, ignored`;
|
return `Window is already open, ignored`;
|
||||||
|
|
||||||
case "close":
|
case "close":
|
||||||
if(Windows.isVisible(specifiedWindow)) {
|
if(Windows.getDefault().isVisible(specifiedWindow)) {
|
||||||
Windows.close(specifiedWindow);
|
Windows.getDefault().close(specifiedWindow);
|
||||||
return `Setting visibility of window "${args[1]}" to false`
|
return `Setting visibility of window "${args[1]}" to false`
|
||||||
}
|
}
|
||||||
|
|
||||||
return `Window is already closed, ignored`
|
return `Window is already closed, ignored`
|
||||||
|
|
||||||
case "toggle":
|
case "toggle":
|
||||||
if(!Windows.isVisible(specifiedWindow)) {
|
if(!Windows.getDefault().isVisible(specifiedWindow)) {
|
||||||
Windows.open(specifiedWindow);
|
Windows.getDefault().open(specifiedWindow);
|
||||||
return `Toggle opening window "${args[1]}"`;
|
return `Toggle opening window "${args[1]}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
Windows.close(specifiedWindow);
|
Windows.getDefault().close(specifiedWindow);
|
||||||
return `Toggle closing window "${args[1]}"`
|
return `Toggle closing window "${args[1]}"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,33 @@
|
|||||||
import { AstalIO, execAsync, Gio, GLib, GObject, monitorFile, property, readFile, register, signal, timeout } from "astal";
|
import AstalIO from "gi://AstalIO";
|
||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
|
||||||
|
import GObject, { getter, register, signal } from "ags/gobject";
|
||||||
|
import { timeout } from "ags/time";
|
||||||
|
import { monitorFile, readFile } from "ags/file";
|
||||||
|
import { execAsync } from "ags/process";
|
||||||
|
|
||||||
|
|
||||||
|
interface ClipboardSignals extends GObject.Object.SignalSignatures {
|
||||||
|
copied: Clipboard["copied"];
|
||||||
|
wiped: Clipboard["wiped"];
|
||||||
|
};
|
||||||
|
|
||||||
export enum ClipboardItemType {
|
export enum ClipboardItemType {
|
||||||
TEXT = 0,
|
TEXT = 0,
|
||||||
IMAGE = 1
|
IMAGE = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ClipboardItem = {
|
export class ClipboardItem {
|
||||||
id: number;
|
id: number;
|
||||||
type: ClipboardItemType;
|
type: ClipboardItemType;
|
||||||
preview: string;
|
preview: string;
|
||||||
|
|
||||||
|
constructor(id: number, type: ClipboardItemType, preview: string) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type;
|
||||||
|
this.preview = preview;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Clipboard };
|
export { Clipboard };
|
||||||
@@ -20,6 +38,8 @@ export { Clipboard };
|
|||||||
class Clipboard extends GObject.Object {
|
class Clipboard extends GObject.Object {
|
||||||
private static instance: Clipboard;
|
private static instance: Clipboard;
|
||||||
|
|
||||||
|
declare $signals: ClipboardSignals;
|
||||||
|
|
||||||
#dbFile: Gio.File;
|
#dbFile: Gio.File;
|
||||||
#dbMonitor: Gio.FileMonitor;
|
#dbMonitor: Gio.FileMonitor;
|
||||||
#updateDone: boolean = false;
|
#updateDone: boolean = false;
|
||||||
@@ -27,14 +47,11 @@ class Clipboard extends GObject.Object {
|
|||||||
#changesTimeout: (AstalIO.Time|undefined);
|
#changesTimeout: (AstalIO.Time|undefined);
|
||||||
#ignoreChanges: boolean = false;
|
#ignoreChanges: boolean = false;
|
||||||
|
|
||||||
@signal(Object)
|
@signal(GObject.TYPE_JSOBJECT) copied(_item: object) {}
|
||||||
declare copied: () => ClipboardItem;
|
@signal() wiped() {};
|
||||||
|
|
||||||
@signal()
|
|
||||||
declare wiped: () => void;
|
|
||||||
|
|
||||||
|
|
||||||
@property()
|
@getter(Array)
|
||||||
public get history() { return this.#history; }
|
public get history() { return this.#history; }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
|
||||||
|
import GObject, { getter, property, register } from "ags/gobject";
|
||||||
|
|
||||||
|
|
||||||
|
/** WIP Global implementation of a system that supports
|
||||||
|
* a variety of Wayland Compositors */
|
||||||
|
export namespace Compositor {
|
||||||
|
|
||||||
|
let instance: _Compositor;
|
||||||
|
|
||||||
|
@register({ GTypeName: "CompositorMonitor" })
|
||||||
|
class _CompositorMonitor extends GObject.Object {
|
||||||
|
public readonly width: number;
|
||||||
|
public readonly height: number;
|
||||||
|
|
||||||
|
@property(Boolean)
|
||||||
|
public readonly mirror: boolean;
|
||||||
|
|
||||||
|
constructor(width: number, height: number, mirror: boolean = false) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.mirror = mirror;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@register({ GTypeName: "CompositorWorkspace" })
|
||||||
|
class _CompositorWorkspace extends GObject.Object {
|
||||||
|
public readonly id: number;
|
||||||
|
|
||||||
|
@getter(_CompositorMonitor)
|
||||||
|
public readonly monitor: _CompositorMonitor;
|
||||||
|
|
||||||
|
constructor(monitor: _CompositorMonitor, id: number) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.monitor = monitor;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@register({ GTypeName: "Compositor" })
|
||||||
|
class _Compositor extends GObject.Object {
|
||||||
|
#workspaces: Array<_CompositorWorkspace> = [];
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public get workspaces() { return this.#workspaces; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export function getDefault(): _Compositor {
|
||||||
|
if(!instance)
|
||||||
|
instance = new _Compositor();
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Compositor = _Compositor,
|
||||||
|
CompositorWorkspace = _CompositorWorkspace,
|
||||||
|
CompositorMonitor = _CompositorMonitor;
|
||||||
|
|
||||||
|
/** Uses the XDG_CURRENT_DESKTOP variable to detect running compositor's name.
|
||||||
|
* ---
|
||||||
|
* @returns running wayland compositor's name (lowercase) or `undefined` if variable's not set */
|
||||||
|
export function getName(): string|undefined {
|
||||||
|
return GLib.getenv("XDG_CURRENT_DESKTOP") ?? undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+23
-30
@@ -1,8 +1,14 @@
|
|||||||
import { AstalIO, Gio, GLib, GObject, monitorFile, readFileAsync, register, timeout } from "astal";
|
import { timeout } from "ags/time";
|
||||||
import Binding, { bind, Subscribable } from "astal/binding";
|
import { monitorFile, readFileAsync } from "ags/file";
|
||||||
import { Notifications } from "./notifications";
|
import { Notifications } from "./notifications";
|
||||||
import AstalNotifd from "gi://AstalNotifd";
|
|
||||||
import { encoder } from "./utils";
|
import { encoder } from "./utils";
|
||||||
|
import GObject, { getter, register } from "ags/gobject";
|
||||||
|
|
||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
import AstalIO from "gi://AstalIO";
|
||||||
|
import AstalNotifd from "gi://AstalNotifd";
|
||||||
|
import { Accessor, createConnection } from "ags";
|
||||||
|
|
||||||
|
|
||||||
export { Config };
|
export { Config };
|
||||||
@@ -40,11 +46,15 @@ export type ConfigEntries = Partial<{
|
|||||||
|
|
||||||
type ValueTypes = "string" | "boolean" | "object" | "number" | "undefined" | "any";
|
type ValueTypes = "string" | "boolean" | "object" | "number" | "undefined" | "any";
|
||||||
|
|
||||||
|
|
||||||
@register({ GTypeName: "Config" })
|
@register({ GTypeName: "Config" })
|
||||||
class Config extends GObject.Object implements Subscribable {
|
class Config extends GObject.Object {
|
||||||
private static instance: Config;
|
private static instance: Config;
|
||||||
|
|
||||||
|
$signals = {
|
||||||
|
"notify": () => {},
|
||||||
|
"notify::entries": (_: ConfigEntries) => {}
|
||||||
|
};
|
||||||
|
|
||||||
private readonly defaultFile = Gio.File.new_for_path(
|
private readonly defaultFile = Gio.File.new_for_path(
|
||||||
`${GLib.get_user_config_dir()}/colorshell/config.json`);
|
`${GLib.get_user_config_dir()}/colorshell/config.json`);
|
||||||
|
|
||||||
@@ -71,11 +81,12 @@ class Config extends GObject.Object implements Subscribable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly entries: ConfigEntries = this.defaults;
|
@getter(Object)
|
||||||
|
public get entries() { return this.#entries; }
|
||||||
|
|
||||||
|
|
||||||
#subs: Set<(entries: ConfigEntries) => void> = new Set();
|
|
||||||
#file: Gio.File;
|
#file: Gio.File;
|
||||||
|
#entries: ConfigEntries = this.defaults;
|
||||||
|
|
||||||
private timeout: (AstalIO.Time|boolean|undefined);
|
private timeout: (AstalIO.Time|boolean|undefined);
|
||||||
public get file() { return this.#file; };
|
public get file() { return this.#file; };
|
||||||
|
|
||||||
@@ -172,7 +183,7 @@ class Config extends GObject.Object implements Subscribable {
|
|||||||
this.entries[k as keyof typeof this.entries] = config[k as keyof typeof config];
|
this.entries[k as keyof typeof this.entries] = config[k as keyof typeof config];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.notifySubs();
|
this.notify("entries");
|
||||||
}).catch((e: Gio.IOErrorEnum) => {
|
}).catch((e: Gio.IOErrorEnum) => {
|
||||||
Notifications.getDefault().sendNotification({
|
Notifications.getDefault().sendNotification({
|
||||||
urgency: AstalNotifd.Urgency.NORMAL,
|
urgency: AstalNotifd.Urgency.NORMAL,
|
||||||
@@ -184,15 +195,9 @@ class Config extends GObject.Object implements Subscribable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private notifySubs(): void {
|
public bindProperty(propertyPath: (keyof ConfigEntries|string), expectType?: ValueTypes): Accessor<any|undefined> {
|
||||||
for(const sub of this.#subs) {
|
return createConnection(this.getProperty(propertyPath), [(this as typeof Config.instance), "notify::entries", () =>
|
||||||
sub(this.entries);
|
this.getProperty(propertyPath, expectType)]);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bindProperty(propertyPath: (keyof ConfigEntries|string), expectType?: ValueTypes): Binding<any|undefined> {
|
|
||||||
return bind(this).as(() =>
|
|
||||||
this.getProperty(propertyPath, expectType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getProperty(path: string, expectType?: ValueTypes): (any|undefined) {
|
public getProperty(path: string, expectType?: ValueTypes): (any|undefined) {
|
||||||
@@ -234,16 +239,4 @@ class Config extends GObject.Object implements Subscribable {
|
|||||||
|
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get(): ConfigEntries {
|
|
||||||
return this.entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public subscribe(callback: (entries: ConfigEntries) => void): () => void {
|
|
||||||
this.#subs.add(callback);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
this.#subs.delete(callback);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { AstalIO, exec, execAsync, GLib, GObject, interval, property, register } from "astal";
|
import AstalIO from "gi://AstalIO";
|
||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
|
||||||
|
import GObject, { getter, register } from "ags/gobject";
|
||||||
|
import { execAsync, exec } from "ags/process";
|
||||||
|
import { interval } from "ags/time";
|
||||||
|
|
||||||
export { NightLight };
|
export { NightLight };
|
||||||
|
|
||||||
@@ -14,11 +19,11 @@ class NightLight extends GObject.Object {
|
|||||||
#prevTemperature: (number|null) = null;
|
#prevTemperature: (number|null) = null;
|
||||||
#prevGamma: (number|null) = null;
|
#prevGamma: (number|null) = null;
|
||||||
|
|
||||||
@property(Number)
|
@getter(Number)
|
||||||
public get temperature() { return this.#temperature; }
|
public get temperature() { return this.#temperature; }
|
||||||
public set temperature(newValue: number) { this.setTemperature(newValue); }
|
public set temperature(newValue: number) { this.setTemperature(newValue); }
|
||||||
|
|
||||||
@property(Number)
|
@getter(Number)
|
||||||
public get gamma() { return this.#gamma; }
|
public get gamma() { return this.#gamma; }
|
||||||
public set gamma(newValue: number) { this.setGamma(newValue); }
|
public set gamma(newValue: number) { this.setGamma(newValue); }
|
||||||
|
|
||||||
@@ -27,7 +32,7 @@ class NightLight extends GObject.Object {
|
|||||||
public readonly identityTemperature = 6000;
|
public readonly identityTemperature = 6000;
|
||||||
public readonly maxGamma = 100;
|
public readonly maxGamma = 100;
|
||||||
|
|
||||||
@property(Boolean)
|
@getter(Boolean)
|
||||||
public get identity() { return this.#identity; }
|
public get identity() { return this.#identity; }
|
||||||
public set identity(newValue: boolean) {
|
public set identity(newValue: boolean) {
|
||||||
newValue ? this.applyIdentity() : this.filter();
|
newValue ? this.applyIdentity() : this.filter();
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import { AstalIO, execAsync, Gio, GObject, property, register, signal, timeout } from "astal";
|
|
||||||
import AstalNotifd from "gi://AstalNotifd";
|
|
||||||
import { Config } from "./config";
|
import { Config } from "./config";
|
||||||
|
import { timeout } from "ags/time";
|
||||||
|
import { execAsync } from "ags/process";
|
||||||
|
|
||||||
|
import GObject, { getter, property, register, signal } from "ags/gobject";
|
||||||
|
import AstalNotifd from "gi://AstalNotifd";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
import AstalIO from "gi://AstalIO";
|
||||||
|
|
||||||
|
|
||||||
export interface HistoryNotification {
|
export interface HistoryNotification {
|
||||||
@@ -22,38 +27,22 @@ class Notifications extends GObject.Object {
|
|||||||
#history: Array<HistoryNotification> = [];
|
#history: Array<HistoryNotification> = [];
|
||||||
#notificationsOnHold: Set<number> = new Set<number>();
|
#notificationsOnHold: Set<number> = new Set<number>();
|
||||||
#connections: Array<number> = [];
|
#connections: Array<number> = [];
|
||||||
#historyLimit: number = 10;
|
|
||||||
|
|
||||||
@property()
|
@getter(Array<AstalNotifd.Notification>)
|
||||||
public get notifications() { return this.#notifications };
|
public get notifications() { return this.#notifications };
|
||||||
|
|
||||||
@property()
|
@getter(Array<HistoryNotification>)
|
||||||
public get history() { return this.#history };
|
public get history() { return this.#history };
|
||||||
|
|
||||||
@property()
|
@property(Number)
|
||||||
public get historyLimit() { return this.#historyLimit };
|
public historyLimit: number = 10;
|
||||||
|
|
||||||
public set historyLimit(newValue: number) {
|
|
||||||
this.#historyLimit = newValue;
|
|
||||||
this.notify("historyLimit");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@signal(AstalNotifd.Notification)
|
@signal(AstalNotifd.Notification) notificationAdded(_notification: AstalNotifd.Notification) {};
|
||||||
declare notificationAdded: (notification: AstalNotifd.Notification) => void;
|
@signal(Number) notificationRemoved(_id: number) {};
|
||||||
|
@signal(Object) historyAdded(_notification: Object) {};
|
||||||
@signal(Number)
|
@signal(Number) historyRemoved(_id: number) {};
|
||||||
declare notificationRemoved: (id: number) => void;
|
@signal(Number) notificationReplaced(_id: number) {};
|
||||||
|
|
||||||
@signal(Object) // It's an Object, beacuase HistoryNotification is just an interface
|
|
||||||
declare historyAdded: (notification: AstalNotifd.Notification) => void;
|
|
||||||
|
|
||||||
@signal(Number)
|
|
||||||
declare historyRemoved: (id: number) => void;
|
|
||||||
|
|
||||||
@signal(Number)
|
|
||||||
declare notificationReplaced: (id: number) => void;
|
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@@ -188,7 +177,7 @@ class Notifications extends GObject.Object {
|
|||||||
private addHistory(notif: AstalNotifd.Notification, onAdded?: (notif: AstalNotifd.Notification) => void): void {
|
private addHistory(notif: AstalNotifd.Notification, onAdded?: (notif: AstalNotifd.Notification) => void): void {
|
||||||
if(!notif) return;
|
if(!notif) return;
|
||||||
|
|
||||||
this.#history.length === this.#historyLimit &&
|
this.#history.length === this.historyLimit &&
|
||||||
this.removeHistory(this.#history[this.#history.length - 1]);
|
this.removeHistory(this.#history[this.#history.length - 1]);
|
||||||
|
|
||||||
this.#history.map((notifb, i) =>
|
this.#history.map((notifb, i) =>
|
||||||
|
|||||||
+21
-17
@@ -1,9 +1,14 @@
|
|||||||
import { execAsync, Gio, GLib, GObject } from "astal";
|
import { execAsync } from "ags/process";
|
||||||
import { property, register, signal } from "astal/gobject";
|
import { getter, register, signal } from "ags/gobject";
|
||||||
import { Gdk } from "astal/gtk3";
|
import { Gdk } from "ags/gtk4";
|
||||||
import { getDateTime } from "./time";
|
|
||||||
import { makeDirectory } from "./utils";
|
import { makeDirectory } from "./utils";
|
||||||
import { Notifications } from "./notifications";
|
import { Notifications } from "./notifications";
|
||||||
|
import { time } from "./utils";
|
||||||
|
|
||||||
|
import GObject from "ags/gobject";
|
||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
export { Recording };
|
export { Recording };
|
||||||
|
|
||||||
@@ -11,10 +16,8 @@ export { Recording };
|
|||||||
class Recording extends GObject.Object {
|
class Recording extends GObject.Object {
|
||||||
private static instance: Recording;
|
private static instance: Recording;
|
||||||
|
|
||||||
@signal()
|
@signal() started() {};
|
||||||
declare started: () => void;
|
@signal() stopped() {};
|
||||||
@signal()
|
|
||||||
declare stopped: () => void;
|
|
||||||
|
|
||||||
#recording: boolean = false;
|
#recording: boolean = false;
|
||||||
#path: string = "~/Recordings";
|
#path: string = "~/Recordings";
|
||||||
@@ -23,15 +26,16 @@ class Recording extends GObject.Object {
|
|||||||
#extension: string = "mp4";
|
#extension: string = "mp4";
|
||||||
#recordAudio: boolean = false;
|
#recordAudio: boolean = false;
|
||||||
#area: (Gdk.Rectangle|null) = null;
|
#area: (Gdk.Rectangle|null) = null;
|
||||||
#startedAt: (GLib.DateTime|null) = null;
|
#startedAt: number = -1;
|
||||||
#process: (Gio.Subprocess|null) = null;
|
#process: (Gio.Subprocess|null) = null;
|
||||||
#output: (string|null) = null;
|
#output: (string|null) = null;
|
||||||
|
|
||||||
@property()
|
/** GLib.DateTime of when recording started
|
||||||
/** GLib.DateTime of when recording started */
|
* its value can be `-1` if undefined(no recording is happening) */
|
||||||
|
@getter(Number)
|
||||||
public get startedAt() { return this.#startedAt; }
|
public get startedAt() { return this.#startedAt; }
|
||||||
|
|
||||||
@property(Boolean)
|
@getter(Boolean)
|
||||||
public get recording() { return this.#recording; }
|
public get recording() { return this.#recording; }
|
||||||
private set recording(newValue: boolean) {
|
private set recording(newValue: boolean) {
|
||||||
(!newValue && this.#recording) ?
|
(!newValue && this.#recording) ?
|
||||||
@@ -42,7 +46,7 @@ class Recording extends GObject.Object {
|
|||||||
this.notify("recording");
|
this.notify("recording");
|
||||||
}
|
}
|
||||||
|
|
||||||
@property(String)
|
@getter(String)
|
||||||
public get path() { return this.#path; }
|
public get path() { return this.#path; }
|
||||||
public set path(newPath: string) {
|
public set path(newPath: string) {
|
||||||
if(this.recording) return;
|
if(this.recording) return;
|
||||||
@@ -51,7 +55,7 @@ class Recording extends GObject.Object {
|
|||||||
this.notify("path");
|
this.notify("path");
|
||||||
}
|
}
|
||||||
|
|
||||||
@property(String)
|
@getter(String)
|
||||||
public get extension() { return this.#extension; }
|
public get extension() { return this.#extension; }
|
||||||
public set extension(newExt: string) {
|
public set extension(newExt: string) {
|
||||||
if(this.recording) return;
|
if(this.recording) return;
|
||||||
@@ -89,7 +93,7 @@ class Recording extends GObject.Object {
|
|||||||
if(this.recording)
|
if(this.recording)
|
||||||
throw new Error("Screen Recording is already running!");
|
throw new Error("Screen Recording is already running!");
|
||||||
|
|
||||||
this.#output = `${getDateTime().get().format("%Y-%m-%d-%H%M%S")}_rec.${this.extension || "mp4"}`;
|
this.#output = `${time.get().format("%Y-%m-%d-%H%M%S")}_rec.${this.extension || "mp4"}`;
|
||||||
this.#recording = true;
|
this.#recording = true;
|
||||||
this.notify("recording");
|
this.notify("recording");
|
||||||
this.emit("started");
|
this.emit("started");
|
||||||
@@ -111,7 +115,7 @@ class Recording extends GObject.Object {
|
|||||||
this.stopRecording();
|
this.stopRecording();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.#startedAt = getDateTime().get();
|
this.#startedAt = time.get().to_unix();
|
||||||
}
|
}
|
||||||
|
|
||||||
public stopRecording() {
|
public stopRecording() {
|
||||||
@@ -126,7 +130,7 @@ class Recording extends GObject.Object {
|
|||||||
|
|
||||||
this.#process = null;
|
this.#process = null;
|
||||||
this.#recording = false;
|
this.#recording = false;
|
||||||
this.#startedAt = null;
|
this.#startedAt = -1;
|
||||||
this.#output = null;
|
this.#output = null;
|
||||||
this.notify("recording");
|
this.notify("recording");
|
||||||
this.emit("stopped");
|
this.emit("stopped");
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { execAsync, Gio, monitorFile } from "astal";
|
import { monitorFile } from "ags/file";
|
||||||
import { App } from "astal/gtk3";
|
import { execAsync } from "ags/process";
|
||||||
import { uwsmIsActive } from "./apps";
|
import { uwsmIsActive } from "./apps";
|
||||||
|
|
||||||
|
import App from "ags/gtk4/app";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
const monitoringPaths = [ "./scripts", "./window", "./app.ts", "env.d.ts" ];
|
const monitoringPaths = [ "./scripts", "./window", "./app.ts", "env.d.ts" ];
|
||||||
|
|
||||||
export function restartInstance(instanceName?: string): void {
|
export function restartInstance(instanceName?: string): void {
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
// handles stylesheet compiling and reloading
|
import { monitorFile, readFile } from "ags/file";
|
||||||
|
import { timeout } from "ags/time";
|
||||||
|
import { exec, execAsync } from "ags/process";
|
||||||
|
|
||||||
import { monitorFile, AstalIO, timeout, GLib, Gio, execAsync, exec, readFile } from "astal";
|
import AstalIO from "gi://AstalIO";
|
||||||
import { App } from "astal/gtk3";
|
import App from "ags/gtk4/app";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
|
/** handles stylesheet compiling and reloading */
|
||||||
export class Stylesheet {
|
export class Stylesheet {
|
||||||
private static instance: Stylesheet;
|
private static instance: Stylesheet;
|
||||||
#watchDelay: (AstalIO.Time|undefined);
|
#watchDelay: (AstalIO.Time|undefined);
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
import { GLib, Variable } from "astal";
|
|
||||||
|
|
||||||
const time = new Variable<GLib.DateTime>(GLib.DateTime.new_now_local()).poll(500, () =>
|
|
||||||
GLib.DateTime.new_now_local())();
|
|
||||||
|
|
||||||
export const getDateTime = () => time;
|
|
||||||
+13
-1
@@ -1,8 +1,14 @@
|
|||||||
import { exec, execAsync, Gio, GLib } from "astal";
|
import { createPoll } from "ags/time";
|
||||||
|
import { exec, execAsync } from "ags/process";
|
||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
|
||||||
export const decoder = new TextDecoder("utf-8"),
|
export const decoder = new TextDecoder("utf-8"),
|
||||||
encoder = new TextEncoder();
|
encoder = new TextEncoder();
|
||||||
|
|
||||||
|
export const time = createPoll(GLib.DateTime.new_now_local(), 500, () =>
|
||||||
|
GLib.DateTime.new_now_local());
|
||||||
|
|
||||||
export function getHyprlandInstanceSig(): (string|null) {
|
export function getHyprlandInstanceSig(): (string|null) {
|
||||||
return GLib.getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
return GLib.getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||||
}
|
}
|
||||||
@@ -11,6 +17,12 @@ export function getHyprlandVersion(): string {
|
|||||||
return exec(`${GLib.getenv("HYPRLAND_CMD") || "Hyprland"} --version | head -n1`).split(" ")[1];
|
return exec(`${GLib.getenv("HYPRLAND_CMD") || "Hyprland"} --version | head -n1`).split(" ")[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function omitObjectKeys<ObjT = object>(obj: ObjT, keys: keyof ObjT|Array<keyof ObjT>): ObjT {
|
||||||
|
for(const objKey of Object.keys(obj)) {
|
||||||
|
for(const omitKey of keys) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function makeDirectory(dir: string): void {
|
export function makeDirectory(dir: string): void {
|
||||||
execAsync([ "mkdir", "-p", dir ]);
|
execAsync([ "mkdir", "-p", dir ]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
import { Subscribable } from "astal/binding";
|
|
||||||
|
|
||||||
export class VarMap<K, V> implements Subscribable {
|
|
||||||
|
|
||||||
#subs = new Set<(v: Map<K, V>) => void>();
|
|
||||||
#map: Map<K, V>;
|
|
||||||
|
|
||||||
constructor(initial?: Map<K, V>) {
|
|
||||||
this.#map = initial || new Map<K, V>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private notifyMap() {
|
|
||||||
const subs = this.#subs;
|
|
||||||
for(const sub of subs) {
|
|
||||||
sub(this.#map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public get(): Map<K, V> {
|
|
||||||
return this.#map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get size(): number {
|
|
||||||
return this.#map.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getValue(key: K): (V|undefined) {
|
|
||||||
return this.#map.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getKeyAt(index: number): (K|undefined) {
|
|
||||||
return [...this.#map.keys()][index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public getValueAt(index: number): (V|undefined) {
|
|
||||||
return [...this.#map.values()][index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public set(key: K, value: V): Map<K, V> {
|
|
||||||
const newMap: Map<K, V> = this.#map.set(key, value);
|
|
||||||
this.notifyMap();
|
|
||||||
|
|
||||||
return newMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public delete(key: K): boolean {
|
|
||||||
const deleted: boolean = this.#map.delete(key);
|
|
||||||
this.notifyMap();
|
|
||||||
return deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public has(key: K): boolean {
|
|
||||||
return this.#map.has(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public clear(): void {
|
|
||||||
this.#map.clear();
|
|
||||||
this.notifyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public entries(): MapIterator<[K, V]> {
|
|
||||||
return this.#map.entries();
|
|
||||||
}
|
|
||||||
|
|
||||||
public keys(): MapIterator<K> {
|
|
||||||
return this.#map.keys();
|
|
||||||
}
|
|
||||||
|
|
||||||
public values(): MapIterator<V> {
|
|
||||||
return this.#map.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
public forEach<ReturnType = any> (callback: (value: V, key: K, map: Map<K, V>) => ReturnType): ReturnType[] {
|
|
||||||
const result: Array<ReturnType> = [];
|
|
||||||
for(const entry of this.#map.entries()) {
|
|
||||||
result.push(callback(entry[1], entry[0], this.#map));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public subscribe(callback: (v: Map<K, V>) => void): () => void {
|
|
||||||
this.#subs.add(callback);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
this.#subs.delete(callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GObject, register } from "astal";
|
import GObject, { register } from "ags/gobject";
|
||||||
import AstalWp from "gi://AstalWp";
|
import AstalWp from "gi://AstalWp";
|
||||||
|
|
||||||
export { Wireplumber };
|
export { Wireplumber };
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
import { AstalIO, execAsync, Gio, GLib, GObject, monitorFile, property, register, timeout } from "astal";
|
import { execAsync } from "ags/process";
|
||||||
|
import { timeout } from "ags/time";
|
||||||
|
import GObject, { register, getter } from "ags/gobject";
|
||||||
|
import { monitorFile } from "ags/file";
|
||||||
|
|
||||||
|
import AstalIO from "gi://AstalIO";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
export { Wallpaper };
|
export { Wallpaper };
|
||||||
|
|
||||||
@@ -12,15 +20,17 @@ class Wallpaper extends GObject.Object {
|
|||||||
#wallpapersPath: string;
|
#wallpapersPath: string;
|
||||||
#ignoreWatch: boolean = false;
|
#ignoreWatch: boolean = false;
|
||||||
|
|
||||||
@property(Boolean)
|
@getter(Boolean)
|
||||||
public get splash() { return this.#splash; }
|
public get splash() { return this.#splash; }
|
||||||
public set splash(showSplash: boolean) {
|
public set splash(showSplash: boolean) {
|
||||||
this.#splash = showSplash;
|
this.#splash = showSplash;
|
||||||
this.notify("splash");
|
this.notify("splash");
|
||||||
}
|
}
|
||||||
|
|
||||||
@property(String)
|
/** current wallpaper's complete path
|
||||||
public get wallpaper(): (string|undefined) { return this.#wallpaper; }
|
* can be an empty string if undefined */
|
||||||
|
@getter(String)
|
||||||
|
public get wallpaper() { return this.#wallpaper ?? ""; }
|
||||||
public set wallpaper(newValue: string) { this.setWallpaper(newValue); }
|
public set wallpaper(newValue: string) { this.setWallpaper(newValue); }
|
||||||
|
|
||||||
public get wallpapersPath() { return this.#wallpapersPath; }
|
public get wallpapersPath() { return this.#wallpapersPath; }
|
||||||
@@ -28,8 +38,12 @@ class Wallpaper extends GObject.Object {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.#wallpapersPath = GLib.getenv("WALLPAPERS") ?? `${GLib.get_home_dir()}/wallpapers`;
|
this.#wallpapersPath = GLib.getenv("WALLPAPERS") ??
|
||||||
this.#hyprpaperFile = Gio.File.new_for_path(`${GLib.get_user_config_dir()}/hypr/hyprpaper.conf`);
|
`${GLib.get_home_dir()}/wallpapers`;
|
||||||
|
|
||||||
|
this.#hyprpaperFile = Gio.File.new_for_path(`${
|
||||||
|
GLib.get_user_config_dir()}/hypr/hyprpaper.conf`);
|
||||||
|
|
||||||
this.getWallpaper().then((wall) => {
|
this.getWallpaper().then((wall) => {
|
||||||
if(wall?.trim()) this.#wallpaper = wall.trim();
|
if(wall?.trim()) this.#wallpaper = wall.trim();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Astal } from "ags/gtk4";
|
||||||
|
|
||||||
export function addSliderMarksFromMinMax(slider: Widget.Slider, amountOfMarks: number = 2, markup?: (string | null)) {
|
export function addSliderMarksFromMinMax(slider: Astal.Slider, amountOfMarks: number = 2, markup?: (string | null)) {
|
||||||
if(markup && !markup.includes("{}"))
|
if(markup && !markup.includes("{}"))
|
||||||
markup = `${markup}{}`
|
markup = `${markup}{}`
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user