💥 fix(clipboard): issues with special characters on Clipboard.copyAsync()

This commit is contained in:
retrozinndev
2025-08-18 18:44:46 -03:00
parent db73023ac9
commit 49ded11c51
5 changed files with 54 additions and 38 deletions
+28 -17
View File
@@ -1,17 +1,12 @@
import { timeout } from "ags/time";
import { monitorFile, readFile } from "ags/file";
import { execAsync } from "ags/process";
import GObject, { getter, register, signal } from "ags/gobject";
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 {
TEXT = 0,
@@ -38,7 +33,10 @@ export { Clipboard };
class Clipboard extends GObject.Object {
private static instance: Clipboard;
declare $signals: ClipboardSignals;
declare $signals: GObject.Object.SignalSignatures & {
"copied": Clipboard["copied"];
"wiped": Clipboard["wiped"];
};
#dbFile: Gio.File;
#dbMonitor: Gio.FileMonitor;
@@ -50,7 +48,6 @@ class Clipboard extends GObject.Object {
@signal(GObject.TYPE_JSOBJECT) copied(_item: object) {}
@signal() wiped() {};
@getter(Array)
public get history() { return this.#history; }
@@ -97,11 +94,25 @@ class Clipboard extends GObject.Object {
);
}
public async copyAsync(content: string): Promise<void> {
await execAsync(`wl-copy "${content}"`).catch((err: Gio.IOErrorEnum) => {
console.error(`Clipboard: Couldn't copy text using wl-copy. Stderr:\n\t${err.message
} | Stack:\n\t\t${err.stack}`);
});
public async copyAsync(content: string): Promise<boolean> {
const proc = Gio.Subprocess.new(
["wl-copy", content],
Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE
);
const stderr = Gio.DataInputStream.new(proc.get_stderr_pipe()!);
if(!proc.wait_check()) {
try {
const [err, ] = stderr.read_upto('\x00', -1);
console.error(`Clipboard: An error occurred while copying text. Stderr: ${err}`);
} catch(_) {
console.error(`Clipboard: An error occurred while copying text and shell couldn't read \
stderr for more info.`);
}
}
return proc.get_exit_status() === 0;
}
public async selectItem(itemToSelect: number|ClipboardItem): Promise<boolean> {
+14 -1
View File
@@ -1,4 +1,5 @@
import { createRoot, createState, onCleanup } from "ags";
import { Accessor, createConnection, createRoot, createState, onCleanup } from "ags";
import { decoder } from "./utils";
import GObject from "ags/gobject";
import AstalMpris from "gi://AstalMpris";
@@ -54,6 +55,18 @@ export function initPlayer(): void {
});
}
export function accessMediaUrl(player: AstalMpris.Player): Accessor<string|undefined> {
return createConnection(player.get_meta("xesam:url"),
[player, "notify::metadata", () => player.get_meta("xesam:url")]
).as(url => {
const byteString = url?.get_data_as_bytes();
return byteString ?
decoder.decode(byteString.toArray())
: undefined;
})
}
export function disposePlayer(): void {
if(disposeFun) {
disposeFun();
+4
View File
@@ -51,6 +51,10 @@ export function escapeUnintendedMarkup(input: string): string {
});
}
export function escapeSpecialCharacters(str: string): string {
return str.replace(/[\\^$.*?()[\]{}|]/g, "\\$&");
}
export function getChildren(widget: Gtk.Widget): Array<Gtk.Widget> {
const firstChild = widget.get_first_child(),
children: Array<Gtk.Widget> = [];