diff --git a/modules/ags/config/services/clipboard.ts b/modules/ags/config/services/clipboard.ts index a3ec28ad..b884510a 100644 --- a/modules/ags/config/services/clipboard.ts +++ b/modules/ags/config/services/clipboard.ts @@ -1,27 +1,42 @@ -const { execAsync } = Utils; +const { execAsync, subprocess } = Utils; -// TODO: add wl-paste --watch to not have to get history every time -const MAX_CLIPS = 100; - class Clipboard extends Service { static { Service.register(this, { - 'clip-added': ['string'], + 'clip-added': ['jsobject'], 'history-searched': [], }, { clips: ['jsobject'], }); } + private static _MAX_CLIPS = 100; + + // Class Attributes private _clips_left = 0; + private _clips: Map = new Map(); get clips() { return this._clips; } + constructor() { + super(); + this._getHistory(); + this._watchClipboard(); + } + + // Public Class Methods + public copyOldItem(key: string | number): void { + execAsync([ + 'bash', '-c', `cliphist list | grep ${key} | cliphist decode | wl-copy`, + ]); + } + + // Private Class Methods private _decrementClipsLeft() { if (--this._clips_left === 0) { this.emit('history-searched'); @@ -48,56 +63,65 @@ class Clipboard extends Service { } } - public copyOldItem(key: string | number): void { - execAsync([ - 'bash', '-c', `cliphist list | grep ${key} | cliphist decode | wl-copy`, - ]); - } - - public getHistory() { + private _getHistory(n = Clipboard._MAX_CLIPS) { this._clips = new Map(); // FIXME: this is necessary when not putting a cap on clip amount // exec(`prlimit --pid ${exec('pgrep ags')} --nofile=10024:`); // This command comes from '../../clipboard/script.sh' - execAsync('clipboard-manager') - .then((out) => { - const rawClips = out.split('\n'); + execAsync('clipboard-manager').then((out) => { + const rawClips = out.split('\n'); - this._clips_left = Math.min(rawClips.length - 1, MAX_CLIPS); + this._clips_left = Math.min(rawClips.length - 1, n); - rawClips.forEach(async(clip, i) => { - if (i > MAX_CLIPS) { - return; - } + rawClips.forEach(async (clip, i) => { + if (i > n) { + return; + } - if (clip.includes('img')) { - this._decrementClipsLeft(); - this._clips.set( - parseInt((clip.match('[0-9]+') ?? [''])[0]), + if (clip.includes('img')) { + this._decrementClipsLeft(); + + const newClip: [number, {clip: string; isImage: boolean;}] = [ + parseInt((clip.match('[0-9]+') ?? [''])[0]), + { + clip, + isImage: true, + }, + ]; + + this._clips.set(...newClip); + this.emit('clip-added', newClip); + } + else { + const decodedClip = await this._decodeItem(clip); + + if (decodedClip) { + const newClip: [number, {clip: string; isImage: boolean;}] = [ + parseInt(clip), { - clip, - isImage: true, + clip: decodedClip, + isImage: false, }, - ); - } - else { - const decodedClip = await this._decodeItem(clip); + ]; - if (decodedClip) { - this._clips.set( - parseInt(clip), - { - clip: decodedClip, - isImage: false, - }, - ); - } + this._clips.set(...newClip); + this.emit('clip-added', newClip); } - }); - }) - .catch((error) => console.error(error)); + } + }); + }).catch((error) => console.error(error)); + } + + private _watchClipboard() { + subprocess( + ['wl-paste', '--watch', 'echo'], + () => { + this._getHistory(1); + }, + () => {/**/}, + ); } } diff --git a/modules/ags/config/ts/clipboard/main.ts b/modules/ags/config/ts/clipboard/main.ts index 8a0f4728..1defdea6 100644 --- a/modules/ags/config/ts/clipboard/main.ts +++ b/modules/ags/config/ts/clipboard/main.ts @@ -60,16 +60,21 @@ export default () => { App.closeWindow('win-clipboard'); }, - init_rows: (list) => { - Clipboard.getHistory(); - + setup_list: (list) => { const CONNECT_ID = Clipboard.connect('history-searched', () => { + // Do every clip that existed before this widget list.get_children().forEach((row) => { row.destroy(); }); Clipboard.clips.forEach((clip, key) => { makeItem(list, key, clip.clip, clip.isImage); }); + + // Setup connection for new clips + Clipboard.connect('clip-added', (_, [key, clip]) => { + makeItem(list, key, clip.clip, clip.isImage); + }); + Clipboard.disconnect(CONNECT_ID); }); },