diff --git a/.config/ulauncher/extensions.json b/.config/ulauncher/extensions.json index a12832c..7238e2c 100644 --- a/.config/ulauncher/extensions.json +++ b/.config/ulauncher/extensions.json @@ -16,14 +16,14 @@ "com.github.brpaz.ulauncher-timestamp": { "id": "com.github.brpaz.ulauncher-timestamp", "url": "https://github.com/brpaz/ulauncher-timestamp", - "updated_at": "2023-12-08T02:10:39.017559", + "updated_at": "2024-02-01T21:50:59.845185", "last_commit": "e366a81f92b8130dddc0b1bddecad253124c49b9", "last_commit_time": "2021-12-12T15:49:08" }, "com.github.ulauncher.ulauncher-hash": { "id": "com.github.ulauncher.ulauncher-hash", "url": "https://github.com/Ulauncher/ulauncher-hash", - "updated_at": "2023-12-08T10:18:42.039069", + "updated_at": "2024-02-01T21:55:50.370690", "last_commit": "237dbb3610ff04df993c3223b12df42cb7df221f", "last_commit_time": "2022-09-04T14:29:55" } diff --git a/zorin/.config/dconf/user b/zorin/.config/dconf/user index 4cd3a5f..0f08826 100644 Binary files a/zorin/.config/dconf/user and b/zorin/.config/dconf/user differ diff --git a/zorin/.config/mimeapps.list b/zorin/.config/mimeapps.list index f83cf0e..2c0420f 100644 --- a/zorin/.config/mimeapps.list +++ b/zorin/.config/mimeapps.list @@ -1,6 +1,6 @@ [Added Associations] application/vnd.debian.binary-package=gnome-software-local-file.desktop;snap-store_ubuntu-software-local-file.desktop; -inode/directory=webstorm_webstorm.desktop;code_code.desktop;phpstorm_phpstorm.desktop;code.desktop; +inode/directory=phpstorm_phpstorm.desktop;code_code.desktop;webstorm_webstorm.desktop;code.desktop; x-content/audio-player=rhythmbox-device.desktop; x-content/image-dcf=org.gnome.eog.desktop; video/mp4=org.gnome.Totem.desktop;vlc.desktop; @@ -84,7 +84,7 @@ application/xhtml+xml=google-chrome.desktop;sidekick-browser.desktop; x-scheme-handler/https=google-chrome.desktop;sidekick-browser.desktop; x-scheme-handler/sms=org.gnome.Shell.Extensions.ZorinConnect.desktop; x-scheme-handler/tel=org.gnome.Shell.Extensions.ZorinConnect.desktop; -application/x-shellscript=org.gnome.gedit.desktop; +application/x-shellscript=com.zorin.exec-guard.linux.desktop;org.gnome.gedit.desktop; application/x-rpm=gnome-software-local-file.desktop; image/x-canon-cr2=org.gnome.eog.desktop; diff --git a/zorin/.local/share/gnome-shell/application_state b/zorin/.local/share/gnome-shell/application_state index d6ddc16..f35b9e0 100644 --- a/zorin/.local/share/gnome-shell/application_state +++ b/zorin/.local/share/gnome-shell/application_state @@ -1,30 +1,33 @@ - - - - - - + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/extension.js b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/extension.js index 72d3736..3917ce2 100644 --- a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/extension.js +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/extension.js @@ -1,51 +1,56 @@ /* -*- mode: js2 - indent-tabs-mode: nil - js2-basic-offset: 4 -*- */ -/*jshint multistr:true */ -/*jshint esnext:true */ -/*global imports: true */ -/*global global: true */ -/*global log: true */ +/* jshint multistr:true */ +/* jshint esnext:true */ +/* exported enable disable init */ /** - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -**/ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ 'use strict'; -const St = imports.gi.St; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; -const Main = imports.ui.main; -const Mainloop = imports.mainloop; -const PanelMenu = imports.ui.panelMenu; -const Shell = imports.gi.Shell; -const MessageTray = imports.ui.messageTray; -const Atk = imports.gi.Atk; +const { Atk, Gtk, Gio, GObject, Shell, St, Meta, Clutter, GLib } = imports.gi; const Config = imports.misc.config; +const Main = imports.ui.main; +const PopupMenu = imports.ui.popupMenu; +const QuickSettings = imports.ui.quickSettings; +const QuickSettingsMenu = imports.ui.main.panel.statusArea.quickSettings; + +const ShellVersion = Number(Config.PACKAGE_VERSION.split('.')[0]); const INHIBIT_APPS_KEY = 'inhibit-apps'; const SHOW_INDICATOR_KEY = 'show-indicator'; const SHOW_NOTIFICATIONS_KEY = 'show-notifications'; +const SHOW_TIMER_KEY= 'show-timer'; +const DURATION_TIMER_INDEX= 'duration-timer'; +const TOGGLE_STATE_KEY= 'toggle-state'; const USER_ENABLED_KEY = 'user-enabled'; const RESTORE_KEY = 'restore-state'; const FULLSCREEN_KEY = 'enable-fullscreen'; -const NIGHT_LIGHT_KEY = 'control-nightlight'; -const NIGHT_LIGHT_APP_ONLY_KEY = 'control-nightlight-for-app'; +const NIGHT_LIGHT_KEY = 'nightlight-control'; +const TOGGLE_SHORTCUT = 'toggle-shortcut'; +const TIMER_KEY = 'countdown-timer'; +const SCREEN_BLANK = 'screen-blank'; +const TRIGGER_APPS_MODE = 'trigger-apps-mode'; +const INDICATOR_POSITION = 'indicator-position'; +const INDICATOR_INDEX = 'indicator-position-index'; +const INDICATOR_POS_MAX = 'indicator-position-max'; const Gettext = imports.gettext.domain('gnome-shell-extension-caffeine'); const _ = Gettext.gettext; -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Convenience = Me.imports.convenience; +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); const ColorInterface = ' \ \ @@ -92,101 +97,329 @@ const DBusSessionManagerInhibitorIface = '\ const DBusSessionManagerInhibitorProxy = Gio.DBusProxy.makeProxyWrapper(DBusSessionManagerInhibitorIface); -const IndicatorName = "Caffeine"; +const IndicatorName = 'Caffeine'; +const TimerMenuName = _('Caffeine timer'); const DisabledIcon = 'my-caffeine-off-symbolic'; const EnabledIcon = 'my-caffeine-on-symbolic'; +const TimerMenuIcon = 'stopwatch-symbolic'; + +const ControlContext = { + NEVER: 0, + ALWAYS: 1, + FOR_APPS: 2, +}; + +const ShowIndicator = { + ONLY_ACTIVE: 0, + ALWAYS: 1, + NEVER: 2, +}; + +const AppsTrigger = { + ON_RUNNING: 0, + ON_FOCUS: 1, + ON_ACTIVE_WORKSPACE: 2, +}; + +const TIMERS = [ + [5,10,15,20,30,'caffeine-short-timer-symbolic'], + [10,20,30,40,50,'caffeine-medium-timer-symbolic'], + [30,45,60,75,80,'caffeine-long-timer-symbolic'], + [0,0,0,0,0,'caffeine-infinite-timer-symbolic'], +]; let CaffeineIndicator; -let ShellVersion = parseInt(Config.PACKAGE_VERSION.split(".")[1]); +/* +* ------- Load custom icon ------- +* hack (for Wayland?) via https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1997 +* +* For some reasons, I cannot use this instead: +* 'let iconTheme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())' +* see https://gjs.guide/extensions/upgrading/gnome-shell-40.html#custom-icon-theme +* I get this error: "TypeError: Gtk.IconTheme.get_for_display is not a function" +* This same line of code works on prefs.js... (Gnome 43) +*/ +Gtk.IconTheme.get_default = function() { + let theme = new Gtk.IconTheme(); + // gnome-shell switched away from GTK3 during the `44.rc` release. The Gtk.IconTheme method `set_custom_name` + // has been renamed to `set_theme_name`. The below line allows support for all versions of GNOME 43 and 44+. + if (theme.set_theme_name) { + theme.set_theme_name(St.Settings.get().gtk_icon_theme); + } else { + theme.set_custom_theme(St.Settings.get().gtk_icon_theme); + } + return theme; +}; -const Caffeine = GObject.registerClass( -class Caffeine extends PanelMenu.Button { +const CaffeineToggle = GObject.registerClass( +class CaffeineToggle extends QuickSettings.QuickMenuToggle { _init() { - super._init(null, IndicatorName); + super._init({ + // The 'label' property was renamed to 'title' in GNOME 44 but quick settings have otherwise + // not been changed. The below line allows support for both GNOME 43 and 44+ by using the + // appropriate property name based on the GNOME version. + [ShellVersion >= 44 ? 'title' : 'label']: IndicatorName, + toggleMode: true, + }); + + this._settings = ExtensionUtils.getSettings(); + + // Icons + this.finalTimerMenuIcon = TimerMenuIcon; + if (!Gtk.IconTheme.get_default().has_icon(TimerMenuIcon)) { + this.finalTimerMenuIcon = + Gio.icon_new_for_string(`${Me.path}/icons/${TimerMenuIcon}.svg`); + } + this._iconActivated = Gio.icon_new_for_string(`${Me.path}/icons/${EnabledIcon}.svg`);; + this._iconDeactivated = Gio.icon_new_for_string(`${Me.path}/icons/${DisabledIcon}.svg`); + this._iconName(); + + // Menu + this.menu.setHeader(this.finalTimerMenuIcon, TimerMenuName, null); - this.accessible_role = Atk.Role.TOGGLE_BUTTON; + // Add elements + this._itemsSection = new PopupMenu.PopupMenuSection(); + this.menu.addMenuItem(this._itemsSection); - this._settings = Convenience.getSettings(); - this._settings.connect(`changed::${SHOW_INDICATOR_KEY}`, () => { - if (this._settings.get_boolean(SHOW_INDICATOR_KEY)) - this.show(); - else - this.hide(); + // Init Timers + this._timerItems = new Map(); + this._syncTimers(false); + + // Bind signals + this._settings.bind(`${TOGGLE_STATE_KEY}`, + this, 'checked', + Gio.SettingsBindFlags.DEFAULT); + this._settings.connect(`changed::${TOGGLE_STATE_KEY}`, () => { + this._iconName(); + }); + this._settings.connect(`changed::${TIMER_KEY}`, () => { + this._sync(); + }); + this._settings.connect(`changed::${DURATION_TIMER_INDEX}`, () => { + this._syncTimers(true); + }); + this.connect('destroy', () => { + this._iconActivated = null; + this._iconDeactivated = null; + this.gicon = null; }); - if (!this._settings.get_boolean(SHOW_INDICATOR_KEY)) - this.hide(); + } + + _syncTimers(resetDefault) { + this._itemsSection.removeAll(); + this._timerItems.clear(); + const durationIndex = this._settings.get_int(DURATION_TIMER_INDEX); - this._proxy = new ColorProxy(Gio.DBus.session, 'org.gnome.SettingsDaemon.Color', '/org/gnome/SettingsDaemon/Color', (proxy, error) => { - if (error) { - log(error.message); - return; + for (const timer of TIMERS) { + let label = null; + if(timer[0] === 0) { + label = _('Infinite'); + } else { + label = parseInt(timer[durationIndex]) + _(' minutes'); } - }); + if (!label) + continue; + const icon = Gio.icon_new_for_string(`${Me.path}/icons/${timer[5]}.svg`); + const item = new PopupMenu.PopupImageMenuItem(label, icon); + item.connect('activate',() => (this._checkTimer(timer[durationIndex]))); + this._timerItems.set(timer[durationIndex], item); + this._itemsSection.addMenuItem(item); + } + this.menuEnabled = TIMERS.length > 2; + + // Select active duration + if (resetDefault && this._settings.get_int(TIMER_KEY) !== 0) { + // Set default duration to 0 + this._settings.set_int(TIMER_KEY, 0); + } else { + this._sync(); + } + } - this._night_light = false; + _sync() { + const activeTimerId = this._settings.get_int(TIMER_KEY); + for (const [timerId, item] of this._timerItems) { + item.setOrnament(timerId === activeTimerId + ? PopupMenu.Ornament.CHECK + : PopupMenu.Ornament.NONE); + } + } + _checkTimer(timerId) { + this._settings.set_int(TIMER_KEY, timerId); + this._settings.set_boolean(TOGGLE_STATE_KEY, true); + } + + _iconName() { + if (this._settings.get_boolean(TOGGLE_STATE_KEY)) { + this.gicon = this._iconActivated; + } else { + this.gicon = this._iconDeactivated; + } + } +}); + +const Caffeine = GObject.registerClass( +class Caffeine extends QuickSettings.SystemIndicator { + _init() { + super._init(); + + this._indicator = this._addIndicator(); + + this._settings = ExtensionUtils.getSettings(); + + // D-bus + this._proxy = new ColorProxy( + Gio.DBus.session, + 'org.gnome.SettingsDaemon.Color', + '/org/gnome/SettingsDaemon/Color', + (proxy, error) => { + if (error) + log(error.message); + }); this._sessionManager = new DBusSessionManagerProxy(Gio.DBus.session, - 'org.gnome.SessionManager', - '/org/gnome/SessionManager'); - this._inhibitorAddedId = this._sessionManager.connectSignal('InhibitorAdded', this._inhibitorAdded.bind(this)); - this._inhibitorRemovedId = this._sessionManager.connectSignal('InhibitorRemoved', this._inhibitorRemoved.bind(this)); + 'org.gnome.SessionManager', + '/org/gnome/SessionManager'); // From auto-move-windows@gnome-shell-extensions.gcampax.github.com this._appSystem = Shell.AppSystem.get_default(); + this._activeWorkspace = null; - this._appsChangedId = - this._appSystem.connect('installed-changed', - this._updateAppData.bind(this)); + // Init Apps Signals Id + this._appStateChangedSignalId = 0; + this._appDisplayChangedSignalId = 0; + this._appWorkspaceChangedSignalId = 0; + this._appAddWindowSignalId = 0; + this._appRemoveWindowSignalId = 0; // ("screen" in global) is false on 3.28, although global.screen exists - if (typeof global.screen !== "undefined") { + if (typeof global.screen !== 'undefined') { this._screen = global.screen; this._display = this._screen.get_display(); - } - else { + } else { this._screen = global.display; this._display = this._screen; } - this._icon = new St.Icon({ - style_class: 'system-status-icon' + // Add indicator label for the timer + this._timerLabel = new St.Label({ + y_expand: true, + y_align: Clutter.ActorAlign.CENTER, }); - this._icon.gicon = Gio.icon_new_for_string(`${Me.path}/icons/${DisabledIcon}.svg`); + this._timerLabel.visible = false; + this.add_child(this._timerLabel); + + // Icons + this._iconActivated = Gio.icon_new_for_string(`${Me.path}/icons/${EnabledIcon}.svg`);; + this._iconDeactivated = Gio.icon_new_for_string(`${Me.path}/icons/${DisabledIcon}.svg`); + this._indicator.gicon = this._iconDeactivated; + // Manage night light + this._nightLight = false; + + /* Inhibited flag value + * - 4: Inhibit suspending the session or computer + * - 12: Inhibit the session being marked as idle + */ + this.inhibitFlags= 12; + + // Caffeine state this._state = false; - // who has requested the inhibition - this._last_app = ""; - this._last_cookie = ""; - this._apps = []; - this._cookies = []; - this._objects = []; - - this.add_actor(this._icon); - this.add_style_class_name('panel-status-button'); - this.connect('button-press-event', this.toggleState.bind(this)); - this.connect('touch-event', this.toggleState.bind(this)); - - // Restore user state - if (this._settings.get_boolean(USER_ENABLED_KEY) && this._settings.get_boolean(RESTORE_KEY)) { - this.toggleState(); - } + this._userState = false; + + // Store the inhibition requests until processed + this._inhibitionAddedFifo=[]; + this._inhibitionRemovedFifo=[]; + + // Init Timers + this._timeOut = null; + this._timePrint = null; + this._timerEnable = false; + this._timeFullscreen = null; + this._timeWorkspaceAdd = null; + this._timeWorkspaceRemove = null; + this._timeAppUnblock = null; + + // Show icon + this._manageShowIndicator(); + + // Init app list + this._appConfigs = []; + this._appInhibitedData = new Map(); + this._updateAppConfigs(); + // Enable caffeine when fullscreen app is running if (this._settings.get_boolean(FULLSCREEN_KEY)) { this._inFullscreenId = this._screen.connect('in-fullscreen-changed', this.toggleFullscreen.bind(this)); this.toggleFullscreen(); } - this._appConfigs = []; - this._appData = new Map(); + // QuickSettings + this._caffeineToggle = new CaffeineToggle(); + this.quickSettingsItems.push(this._caffeineToggle); + this._updateTimerSubtitle(); - this._settings.connect(`changed::${INHIBIT_APPS_KEY}`, this._updateAppConfigs.bind(this)); - this._updateAppConfigs(); + // Init settings keys and restore user state + this._settings.reset(TOGGLE_STATE_KEY); + if (this._settings.get_boolean(USER_ENABLED_KEY) && this._settings.get_boolean(RESTORE_KEY)) { + this.toggleState(); + } else { + // reset user state + this._settings.reset(USER_ENABLED_KEY); + } + + // Bind signals + this._inhibitorAddedId = this._sessionManager.connectSignal( + 'InhibitorAdded', this._inhibitorAdded.bind(this)); + this._inhibitorRemovedId = this._sessionManager.connectSignal( + 'InhibitorRemoved', this._inhibitorRemoved.bind(this)); + this.inhibitId = this._settings.connect(`changed::${INHIBIT_APPS_KEY}`, + this._updateAppConfigs.bind(this)); + this.stateId = this._settings.connect(`changed::${TOGGLE_STATE_KEY}`, + this._updateMainState.bind(this)); + this.timerId = this._settings.connect(`changed::${TIMER_KEY}`, + this._startTimer.bind(this)); + this.showTimerId = this._settings.connect(`changed::${SHOW_TIMER_KEY}`, + this._showIndicatorLabel.bind(this)); + this.indicatorId = this._settings.connect(`changed::${INDICATOR_POSITION}`, + this._updateIndicatorPosition.bind(this)); + this.showIndicatorId = this._settings.connect(`changed::${SHOW_INDICATOR_KEY}`, () => { + this._manageShowIndicator(); + this._showIndicatorLabel(); + }); + this.triggerId = this._settings.connect(`changed::${TRIGGER_APPS_MODE}`, () => { + this._resetAppSignalId(); + this._updateAppEventMode(); + }); + + // Change user state on icon scroll event + this._indicator.reactive = true; + this._indicator.connect('scroll-event', + (actor, event) => this._handleScrollEvent(event)); + + // Init position and index of indicator icon + this.indicatorPosition = this._settings.get_int(INDICATOR_POSITION); + this.indicatorIndex = this._settings.get_int(INDICATOR_INDEX); + this.lastIndicatorPosition = this.indicatorPosition; + + QuickSettingsMenu._indicators.insert_child_at_index(this,this.indicatorIndex); + QuickSettingsMenu._addItems(this.quickSettingsItems); + + // Place the toggle above the background apps entry + if (ShellVersion >= 44) { + this.quickSettingsItems.forEach((item) => { + QuickSettingsMenu.menu._grid.set_child_below_sibling(item, + QuickSettingsMenu._backgroundApps.quickSettingsItems[0]); + }); + } + + this._updateLastIndicatorPosition(); } get inFullscreen() { - let nb_monitors = this._screen.get_n_monitors(); + let nbMonitors = this._screen.get_n_monitors(); let inFullscreen = false; - for (let i=0; i { - if (this.inFullscreen && !this._apps.includes('fullscreen')) { + this._manageScreenBlankState(false); + this._timeFullscreen = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, () => { + if (this.inFullscreen && !this._appInhibitedData.has('fullscreen')) { this.addInhibit('fullscreen'); - this._manageNightLight('disabled'); + this._manageNightLight(false, false); } + + this._timeFullscreen = null; + return GLib.SOURCE_REMOVE; }); - if (!this.inFullscreen && this._apps.includes('fullscreen')) { + if (!this.inFullscreen && this._appInhibitedData.has('fullscreen')) { this.removeInhibit('fullscreen'); - this._manageNightLight('enabled'); + this._manageNightLight(true, false); } } toggleState() { + this._manageScreenBlankState(false); if (this._state) { - this._apps.forEach(app_id => this.removeInhibit(app_id)); - this._manageNightLight('enabled'); - } - else { + this._removeTimer(); + this._appInhibitedData.forEach((data, appId) => + this.removeInhibit(appId) + ); + this._manageNightLight(true, false); + } else { this.addInhibit('user'); - this._manageNightLight('disabled'); + this._manageNightLight(false, false); + + // Enable timer when duration isn't null + if (this._settings.get_int(TIMER_KEY) !== 0 && !this._timerEnable) { + this._startTimer(); + } } } - addInhibit(app_id) { - this._sessionManager.InhibitRemote(app_id, - 0, "Inhibit by %s".format(IndicatorName), 12, + addInhibit(appId) { + this._sessionManager.InhibitRemote(appId, + 0, 'Inhibit by %s'.format(IndicatorName), this.inhibitFlags, cookie => { - this._last_cookie = cookie; - this._last_app = app_id; + this._inhibitionAddedFifo.push(appId); + // Init app data + let data = { + cookie: cookie, + isToggled: true, + isInhibited: false, + object: '', + }; + this._appInhibitedData.set(appId, data); } ); } - removeInhibit(app_id) { - let index = this._apps.indexOf(app_id); - this._sessionManager.UninhibitRemote(this._cookies[index]); + removeInhibit(appId) { + let appData = this._appInhibitedData.get(appId); + if(appData && appData.isInhibited){ + this._inhibitionRemovedFifo.push(appId); + this._sessionManager.UninhibitRemote(appData.cookie); + appData.isToggled = false; + this._appInhibitedData.set(appId, appData); + } + } + + _updateLastIndicatorPosition() { + let pos = -1; + let nbItems = QuickSettingsMenu._indicators.get_n_children(); + let targetIndicator = null; + + // Count only the visible item in indicator bar + for (let i = 0; i < nbItems; i++) { + targetIndicator = QuickSettingsMenu._indicators.get_child_at_index(i); + if (targetIndicator.is_visible()) { + pos += 1; + } + } + this._settings.set_int(INDICATOR_POS_MAX, pos); + } + + _incrementIndicatorPosIndex() { + if (this.lastIndicatorPosition < this.indicatorPosition) { + this.indicatorIndex += 1; + } else { + this.indicatorIndex -= 1; + } + } + + _updateIndicatorPosition() { + this._updateLastIndicatorPosition(); + const newPosition = this._settings.get_int(INDICATOR_POSITION); + + if (this.indicatorPosition != newPosition) { + this.indicatorPosition = newPosition; + this._incrementIndicatorPosIndex(); + + // Skip invisible indicator + let targetIndicator = + QuickSettingsMenu._indicators.get_child_at_index(this.indicatorIndex); + let maxIndex = QuickSettingsMenu._indicators.get_n_children(); + while (this.indicatorIndex < maxIndex && !targetIndicator.is_visible() && this.indicatorIndex > -1 ) { + this._incrementIndicatorPosIndex(); + targetIndicator = + QuickSettingsMenu._indicators.get_child_at_index(this.indicatorIndex); + } + + // Always reset index to 0 on position 0 + if (this.indicatorPosition == 0) { + this.indicatorIndex = 0; + } + + // Update last position + this.lastIndicatorPosition = newPosition; + + // Update indicator index + QuickSettingsMenu._indicators.remove_actor(this); + QuickSettingsMenu._indicators.insert_child_at_index(this,this.indicatorIndex); + this._settings.set_int(INDICATOR_INDEX, this.indicatorIndex); + } + } + + _showIndicatorLabel() { + if(this._settings.get_boolean(SHOW_TIMER_KEY) + && (this._settings.get_enum(SHOW_INDICATOR_KEY) !== ShowIndicator.NEVER) + && this._timerEnable) { + this._timerLabel.visible=true; + } else { + this._timerLabel.visible=false; + } + } + + _startTimer() { + // Reset timer + this._removeTimer(); + this._timerEnable = true; + + // Get duration + let timerDelay = (this._settings.get_int(TIMER_KEY) * 60); + + // Execute Timer only if duration isn't set on infinite time + if (timerDelay !== 0) { + let secondLeft = timerDelay; + this._showIndicatorLabel(); + this._printTimer(secondLeft); + this._timePrint = GLib.timeout_add(GLib.PRIORITY_DEFAULT, (1000), () => { + secondLeft -= 1; + this._printTimer(secondLeft); + return GLib.SOURCE_CONTINUE; + }); + + this._timeOut = GLib.timeout_add(GLib.PRIORITY_DEFAULT, (timerDelay * 1000), () => { + // Disable Caffeine when timer ended + this._removeTimer(); + this._settings.set_boolean(TOGGLE_STATE_KEY, false); + return GLib.SOURCE_REMOVE; + }); + } + } + + _printTimer(second) { + const min = Math.floor(second / 60); + const minS = Math.floor(second % 60).toLocaleString('en-US', { + minimumIntegerDigits: 2, + useGrouping: false + }); + // Print Timer in system Indicator and Toggle menu subLabel + this._updateLabelTimer(min + ':' + minS); + } + + _removeTimer() { + // End timer + this._timerEnable = false; + + // Flush and hide timer label + this._updateLabelTimer(null); + this._timerLabel.visible = false; + + // Remove timer + if((this._timeOut !== null) || (this._timePrint !== null)) { + GLib.Source.remove(this._timeOut); + GLib.Source.remove(this._timePrint); + this._timeOut=null; + this._timePrint=null; + } + } + + _updateLabelTimer(text) { + this._timerLabel.text = text; + this._caffeineToggle.menu.setHeader(this._caffeineToggle.finalTimerMenuIcon, TimerMenuName, text); + if (ShellVersion >= 44) { + this._caffeineToggle.subtitle = text; + } + } + + _handleScrollEvent(event) { + switch(event.get_scroll_direction()) { + case Clutter.ScrollDirection.UP: + if(!this._state) { + // User state on - UP + this._settings.set_boolean(TOGGLE_STATE_KEY, true); + } + break; + case Clutter.ScrollDirection.DOWN: + if(this._state) { + // Stop timer + this._removeTimer(); + // User state off - DOWN + this._settings.set_boolean(TOGGLE_STATE_KEY, false); + } + break; + } } _inhibitorAdded(proxy, sender, [object]) { this._sessionManager.GetInhibitorsRemote(([inhibitors]) => { - for(var i in inhibitors) { + // Get the first added request + let requestedId = this._inhibitionAddedFifo.shift(); + + for (let i of inhibitors) { let inhibitor = new DBusSessionManagerInhibitorProxy(Gio.DBus.session, - 'org.gnome.SessionManager', - inhibitors[i]); - inhibitor.GetAppIdRemote(app_id => { - if (app_id != '' && app_id == this._last_app) { - if (this._last_app == 'user') - this._settings.set_boolean(USER_ENABLED_KEY, true); - this._apps.push(this._last_app); - this._cookies.push(this._last_cookie); - this._objects.push(object); - this._last_app = ""; - this._last_cookie = ""; + 'org.gnome.SessionManager', + i); + inhibitor.GetAppIdRemote(appId => { + appId = String(appId); + let appData = this._appInhibitedData.get(appId); + if (appId !== '' && requestedId === appId && appData) { + appData.isInhibited = true; + appData.object = object; + this._appInhibitedData.set(appId, appData); + + if (appId === 'user') { + this._saveUserState(true); + } else { + this._updateAppSubtitle(appId); + } + + // Update state if (this._state === false) { - this._state = true; - this._icon.gicon = Gio.icon_new_for_string(`${Me.path}/icons/${EnabledIcon}.svg`); + this._saveMainState(true); + // Indicator icon + this._manageShowIndicator(); + this._indicator.gicon = this._iconActivated; + + // Shell OSD notifications if (this._settings.get_boolean(SHOW_NOTIFICATIONS_KEY) && !this.inFullscreen) { - this._sendNotification('enabled'); + this._sendOSDNotification(true); } } } @@ -264,120 +682,369 @@ class Caffeine extends PanelMenu.Button { } _inhibitorRemoved(proxy, sender, [object]) { - let index = this._objects.indexOf(object); - if (index != -1) { - if (this._apps[index] == 'user') - this._settings.set_boolean(USER_ENABLED_KEY, false); - // Remove app from list - this._apps.splice(index, 1); - this._cookies.splice(index, 1); - this._objects.splice(index, 1); - if (this._apps.length === 0) { - this._state = false; - this._icon.gicon = Gio.icon_new_for_string(`${Me.path}/icons/${DisabledIcon}.svg`); - if(this._settings.get_boolean(SHOW_NOTIFICATIONS_KEY)) { - this._sendNotification('disabled'); + // Get the first removed request + let appId = this._inhibitionRemovedFifo.shift(); + + if(appId){ + let appData = this._appInhibitedData.get(appId); + if (appData){ + // Remove app from list + this._appInhibitedData.delete(appId); + + if (appId === 'user') { + this._saveUserState(false); + } else { + this._updateAppSubtitle(null); + } + + // Update state + if (this._appInhibitedData.size === 0) { + this._saveMainState(false); + + // Indicator icon + this._manageShowIndicator(); + this._indicator.gicon = this._iconDeactivated; + + // Shell OSD notifications + if (this._settings.get_boolean(SHOW_NOTIFICATIONS_KEY)) { + this._sendOSDNotification(false); + } } } } } - _manageNightLight(state){ - if (state == 'enabled') { - if (this._settings.get_boolean(NIGHT_LIGHT_KEY) && this._proxy.NightLightActive && !this._settings.get_boolean(NIGHT_LIGHT_APP_ONLY_KEY)) { - this._proxy.DisabledUntilTomorrow = false; - this._night_light = true; - } else { - this._night_light = false; - } + _isToggleInhibited(appId) { + let appData = this._appInhibitedData.get(appId); + if (appData && appData.isToggled) { + return true; + } else { + return false; } - if (state == 'disabled') { - if (this._settings.get_boolean(NIGHT_LIGHT_KEY) && this._proxy.NightLightActive && !this._settings.get_boolean(NIGHT_LIGHT_APP_ONLY_KEY)) { - this._proxy.DisabledUntilTomorrow = true; - this._night_light = true; - } else { - this._night_light = false; - } + } + + _manageShowIndicator() { + if (this._state) { + this._indicator.visible = this._settings.get_enum(SHOW_INDICATOR_KEY) !== ShowIndicator.NEVER; + } else { + this._indicator.visible = this._settings.get_enum(SHOW_INDICATOR_KEY) === ShowIndicator.ALWAYS; } } - _sendNotification(state){ - if (state == 'enabled') { - if (this._settings.get_boolean(NIGHT_LIGHT_KEY) && this._night_light && this._proxy.DisabledUntilTomorrow) { - Main.notify(_('Auto suspend and screensaver disabled. Night Light paused.')); - } else { - Main.notify(_('Auto suspend and screensaver disabled')); - } + _manageScreenBlankState(isApp) { + let blankState = this._settings.get_enum(SCREEN_BLANK) === ControlContext.ALWAYS; + if (isApp) { + blankState = this._settings.get_enum(SCREEN_BLANK) > ControlContext.NEVER; } - if (state == 'disabled') { - if (this._settings.get_boolean(NIGHT_LIGHT_KEY) && this._night_light && !this._proxy.DisabledUntilTomorrow) { - Main.notify(_('Auto suspend and screensaver enabled. Night Light resumed.')); - } else { - Main.notify(_('Auto suspend and screensaver enabled')); + + if (blankState) { + this.inhibitFlags = 4; + } else { + this.inhibitFlags = 12; + } + } + + _manageNightLight(isEnable, isApp) { + let nightLightPref = this._settings.get_enum(NIGHT_LIGHT_KEY) === ControlContext.ALWAYS; + if (isApp) { + nightLightPref = this._settings.get_enum(NIGHT_LIGHT_KEY) > ControlContext.NEVER; + } + if (isEnable && (nightLightPref || this._nightLight && this._proxy.DisabledUntilTomorrow)) { + this._proxy.DisabledUntilTomorrow = false; + this._nightLight = false; + } else if (!isEnable && nightLightPref) { + this._proxy.DisabledUntilTomorrow = true; + this._nightLight = true; + } + } + + _sendOSDNotification(state) { + const nightLightPref = + this._settings.get_enum(NIGHT_LIGHT_KEY) !== ControlContext.NEVER; + if (state) { + let message = _('Caffeine enabled'); + if (nightLightPref && this._nightLight && this._proxy.NightLightActive) { + message = message + '. ' + _('Night Light paused'); } + Main.osdWindowManager.show(-1, this._iconActivated, + message, null, null); + } else { + let message = _('Caffeine disabled'); + if (nightLightPref && !this._nightLight && this._proxy.NightLightActive) { + message = message + '. ' + _('Night Light resumed'); + } + Main.osdWindowManager.show(-1, this._iconDeactivated, + message, null, null); + } + } + + // Add the name of App as subtitle (>= Gnome 44) + _updateAppSubtitle(id) { + if (ShellVersion >= 44) { + const listAppId = this._appInhibitedData.keys(); + let appId = id !== null ? id : listAppId.next().value; + if (appId !== undefined) { + let appInfo = Gio.DesktopAppInfo.new(appId); + this._caffeineToggle.subtitle = appInfo !== null + ? appInfo.get_display_name() + : null; + } + } + } + + // Add the timer duration selected as subtitle (>= Gnome 44) + _updateTimerSubtitle() { + if (ShellVersion >= 44 && !this._settings.get_boolean(TOGGLE_STATE_KEY)) { + const timerDuration = this._settings.get_int(TIMER_KEY); + this._caffeineToggle.subtitle = timerDuration !== 0 + ? parseInt(timerDuration) + _(' minutes') + : null; } } _updateAppConfigs() { this._appConfigs.length = 0; this._settings.get_strv(INHIBIT_APPS_KEY).forEach(appId => { - this._appConfigs.push(appId); + // Check if app still exist + const appInfo = Gio.DesktopAppInfo.new(appId); + if (appInfo) { + this._appConfigs.push(appId); + } + }); + + // Remove inhibited app that are not in the list anymore + let inhibitedAppsToRemove = [...this._appInhibitedData.keys()] + .filter(id => !this._appConfigs.includes(id)); + inhibitedAppsToRemove.forEach(id => { + this._manageScreenBlankState(true); // Allow blank screen + this._manageNightLight(true, true); + this.removeInhibit(id); // Uninhibit app + }); + + this._updateAppEventMode(); + } + + _updateMainState() { + if (this._settings.get_boolean(TOGGLE_STATE_KEY) !== this._state) { + this.toggleState(); + } + // Add timer duration as Subtitle when disable + this._updateTimerSubtitle(); + } + + _saveUserState(state) { + this._userState = state; + this._settings.set_boolean(USER_ENABLED_KEY, state); + } + + _saveMainState(state) { + this._state = state; + this._settings.set_boolean(TOGGLE_STATE_KEY, state); + } + + _resetAppSignalId(){ + if (this._appStateChangedSignalId > 0) { + this._appSystem.disconnect(this._appStateChangedSignalId); + this._appStateChangedSignalId = 0; + } + if (this._appDisplayChangedSignalId > 0) { + global.display.disconnect(this._appDisplayChangedSignalId); + this._appDisplayChangedSignalId = 0; + } + if (this._appWorkspaceChangedSignalId > 0) { + global.workspace_manager.disconnect(this._appWorkspaceChangedSignalId); + this._appWorkspaceChangedSignalId = 0; + } + if (this._appAddWindowSignalId > 0) { + this._activeWorkspace.disconnect(this._appAddWindowSignalId); + this._appAddWindowSignalId = 0; + } + if (this._appRemoveWindowSignalId > 0) { + this._activeWorkspace.disconnect(this._appRemoveWindowSignalId); + this._appRemoveWindowSignalId = 0; + } + } + + _updateAppEventMode() { + let appsTriggeredMode = this._settings.get_enum(TRIGGER_APPS_MODE); + + if (this._appConfigs.length === 0) { + this._resetAppSignalId(); + } else { + switch (appsTriggeredMode) { + // TRIGGER APPS MODE: ON RUNNING + case AppsTrigger.ON_RUNNING: + if(this._appStateChangedSignalId === 0){ + this._appStateChangedSignalId = + this._appSystem.connect('app-state-changed', + this._appStateChanged.bind(this)); + } + // Check if currently running App + this._appConfigs.forEach( id => { + let app = this._appSystem.lookup_app(id); + if(app && app.get_state() !== Shell.AppState.STOPPED) { + this._appStateChanged(this._appSystem, app); + } + }); + break; + // TRIGGER APPS MODE: ON FOCUS + case AppsTrigger.ON_FOCUS: + if(this._appDisplayChangedSignalId === 0){ + this._appDisplayChangedSignalId = + global.display.connect('notify::focus-window', + this._appWindowFocusChanged.bind(this)); + } + // Check if currently focused App + this._appWindowFocusChanged(); + break; + // TRIGGER APPS MODE: ON ACTIVE WORKSPACE + case AppsTrigger.ON_ACTIVE_WORKSPACE: + if(this._appWorkspaceChangedSignalId === 0){ + this._appWorkspaceChangedSignalId = + global.workspace_manager.connect('workspace-switched', + this._appWorkspaceChanged.bind(this)); + } + // Check if App is currently on active workspace + this._appWorkspaceChanged(); + break; + } + } + } + + _toggleWorkspace() { + // Search for triggered apps on active workspace + this._appConfigs.forEach( appId => { + let app = this._appSystem.lookup_app(appId); + let isOnWorkspace = app.is_on_workspace(this._activeWorkspace); + if(isOnWorkspace && !this._isToggleInhibited(appId)){ + this._manageScreenBlankState(true); // Allow blank screen + this._manageNightLight(false, true); + this.addInhibit(appId); // Inhibit app + } else if(!isOnWorkspace && this._isToggleInhibited(appId)){ + this._manageScreenBlankState(true); // Allow blank screen + this._manageNightLight(true, true); + this.removeInhibit(appId); // Uninhibit app + } }); - this._updateAppData(); } - _updateAppData() { - let ids = this._appConfigs.slice() - let removedApps = [...this._appData.keys()] - .filter(a => !ids.includes(a.id)); - removedApps.forEach(app => { - app.disconnect(this._appData.get(app).windowsChangedId); - let id = app.get_id(); - this._appData.delete(app); + _appWorkspaceChanged() { + // Reset signal for Add/remove windows on workspace + if (this._appAddWindowSignalId > 0) { + this._activeWorkspace.disconnect(this._appAddWindowSignalId); + this._appAddWindowSignalId = 0; + } + if (this._appRemoveWindowSignalId > 0) { + this._activeWorkspace.disconnect(this._appRemoveWindowSignalId); + this._appRemoveWindowSignalId = 0; + } + + // Get active workspace + this._activeWorkspace = global.workspace_manager.get_active_workspace(); + + // Add signal listener on add/remove windows for the active workspace + this._appAddWindowSignalId = + this._activeWorkspace.connect('window-added', (wkspace, window) => { + const type = window.get_window_type(); + // Accept only normal window, ignore all other type (dialog, menu,...) + if(type === 0) { + // Add 100 ms delay to handle window detection + this._timeWorkspaceAdd = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => { + this._toggleWorkspace(); + this._timeWorkspaceAdd = null; + return GLib.SOURCE_REMOVE; + }); + } }); - let addedApps = ids - .map(id => this._appSystem.lookup_app(id)) - .filter(app => app && !this._appData.has(app)); - addedApps.forEach(app => { - let data = { - windowsChangedId: app.connect('windows-changed', - this._appWindowsChanged.bind(this)), - }; - let id = app.get_id(); - this._appData.set(app, data); + this._appRemoveWindowSignalId = + this._activeWorkspace.connect('window-removed', (wkspace, window) => { + const type = window.get_window_type(); + // Accept only normal window, ignore all other type (dialog, menu,...) + if(type === 0) { + // Add 100 ms delay to handle window detection + this._timeWorkspaceRemove = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => { + this._toggleWorkspace(); + this._timeWorkspaceRemove = null; + return GLib.SOURCE_REMOVE; + }); + } }); + + // Check and toggle Caffeine + this._toggleWorkspace(); } - _appWindowsChanged(app) { - let app_id = app.get_id(); + _appWindowFocusChanged() { + let winTrack = Shell.WindowTracker.get_default(); + let appId = null; + let app = winTrack.focus_app; + + if(app) { + appId = app.get_id(); + } + if(this._appConfigs.includes(appId) && !this._isToggleInhibited(appId)){ + this._manageScreenBlankState(true); // Allow blank screen + this._manageNightLight(false, true); + this.addInhibit(appId); // Inhibit app + + // Uninhibit previous focused apps + this._appInhibitedData.forEach((data, id) => { + if (id !== appId && id !== 'user') { + this.removeInhibit(id); + } + }); + } else if (!this._appConfigs.includes(appId) && this._appInhibitedData.size !== 0){ + this._manageScreenBlankState(true); // Allow blank screen + this._manageNightLight(true, true); + // Uninhibit all apps + this._appInhibitedData.forEach((data, id) => { + if (id !== 'user') { + this.removeInhibit(id); + } + }); + } + } + + _appStateChanged(appSys, app) { + let appId = app.get_id(); let appState = app.get_state(); - // app is STARTING (1) or RUNNING (2) - if ((appState == 1) || (appState == 2)) { - this.addInhibit(app_id); - if (this._settings.get_boolean(NIGHT_LIGHT_KEY) && this._proxy.NightLightActive) { - this._proxy.DisabledUntilTomorrow = true; - this._night_light = true; - } else { - this._night_light = false; - } - // app is STOPPED (0) - } else { - this.removeInhibit(app_id); - if (this._settings.get_boolean(NIGHT_LIGHT_KEY) && this._proxy.NightLightActive) { - this._proxy.DisabledUntilTomorrow = false; - this._night_light = true; - } else { - this._night_light = false; + + if(this._appConfigs.includes(appId)){ + // Block App state signal + appSys.block_signal_handler(this._appStateChangedSignalId); + + // Allow blank screen + this._manageScreenBlankState(true); + + if (appState === Shell.AppState.STOPPED && this._isToggleInhibited(appId)){ + this._manageNightLight(true, true); + this.removeInhibit(appId); // Uninhibit app + } else if (appState !== Shell.AppState.STOPPED && !this._isToggleInhibited(appId)) { + this._manageNightLight(false, true); + this.addInhibit(appId); // Inhibit app } + + // Add 200 ms delay before unblock state signal + this._timeAppUnblock = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 200, () => { + appSys.unblock_signal_handler(this._appStateChangedSignalId); + this._timeAppUnblock = null; + return GLib.SOURCE_REMOVE; + }); } } destroy() { - // remove all inhibitors - this._apps.forEach(app_id => this.removeInhibit(app_id)); - // disconnect from signals - if (this._settings.get_boolean(FULLSCREEN_KEY)) + // Remove all inhibitors + this._appInhibitedData.forEach((data, appId) => this.removeInhibit(appId)); + this._appInhibitedData.clear(); + + // Remove ToggleMenu + this.quickSettingsItems.forEach(item => item.destroy()); + + // Disconnect from signals + if (this._settings.get_boolean(FULLSCREEN_KEY)) { this._screen.disconnect(this._inFullscreenId); + } if (this._inhibitorAddedId) { this._sessionManager.disconnectSignal(this._inhibitorAddedId); this._inhibitorAddedId = 0; @@ -394,26 +1061,97 @@ class Caffeine extends PanelMenu.Button { global.window_manager.disconnect(this._windowDestroyedId); this._windowDestroyedId = 0; } - if (this._appsChangedId) { - this._appSystem.disconnect(this._appsChangedId); - this._appsChangedId = 0; + if (this._timeOut) { + GLib.Source.remove(this._timeOut); + this._timeOut = null; + } + if (this._timePrint) { + GLib.Source.remove(this._timePrint); + this._timePrint = null; + } + if (this._timeFullscreen) { + GLib.Source.remove(this._timeFullscreen); + this._timeFullscreen = null; + } + if (this._timeWorkspaceAdd) { + GLib.Source.remove(this._timeWorkspaceAdd); + this._timeWorkspaceAdd = null; + } + if (this._timeWorkspaceRemove) { + GLib.Source.remove(this._timeWorkspaceRemove); + this._timeWorkspaceRemove = null; + } + if (this._timeAppUnblock) { + GLib.Source.remove(this._timeAppUnblock); + this._timeAppUnblock = null; + } + this._resetAppSignalId(); + + // Disconnect settings signals + if (this.inhibitId) { + this._settings.disconnect(this.inhibitId); + this.inhibitId = undefined; + } + if (this.stateId) { + this._settings.disconnect(this.stateId); + this.stateId = undefined; + } + if (this.timerId) { + this._settings.disconnect(this.timerId); + this.timerId = undefined; + } + if (this.showTimerId) { + this._settings.disconnect(this.showTimerId); + this.showTimerId = undefined; } + if (this.indicatorId) { + this._settings.disconnect(this.indicatorId); + this.indicatorId = undefined; + } + if (this.showIndicatorId) { + this._settings.disconnect(this.showIndicatorId); + this.showIndicatorId = undefined; + } + if (this.triggerId) { + this._settings.disconnect(this.triggerId); + this.triggerId = undefined; + } + this._appConfigs.length = 0; - this._updateAppData(); + this._settings = null; super.destroy(); } }); -function init(extensionMeta) { - Convenience.initTranslations(); +/** + * Steps to run on initialization of the extension + */ +function init() { + ExtensionUtils.initTranslations(); } +/** + * Steps to run when the extension is enabled + */ function enable() { + + const _settings = ExtensionUtils.getSettings(); + CaffeineIndicator = new Caffeine(); - Main.panel.addToStatusArea(IndicatorName, CaffeineIndicator); + + // Register shortcut + Main.wm.addKeybinding(TOGGLE_SHORTCUT, _settings, Meta.KeyBindingFlags.IGNORE_AUTOREPEAT, Shell.ActionMode.ALL, () => { + CaffeineIndicator.toggleState(); + }); } +/** + * Steps to run when the extension is disabled + */ function disable() { CaffeineIndicator.destroy(); CaffeineIndicator = null; + + // Unregister shortcut + Main.wm.removeKeybinding(TOGGLE_SHORTCUT); } diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-infinite-timer-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-infinite-timer-symbolic.svg new file mode 100644 index 0000000..be4fdb2 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-infinite-timer-symbolic.svg @@ -0,0 +1,37 @@ + + + + + + diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-long-timer-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-long-timer-symbolic.svg new file mode 100644 index 0000000..d354294 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-long-timer-symbolic.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-medium-timer-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-medium-timer-symbolic.svg new file mode 100644 index 0000000..26e802b --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-medium-timer-symbolic.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-short-timer-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-short-timer-symbolic.svg new file mode 100644 index 0000000..c3091d7 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/caffeine-short-timer-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/hicolor/scalable/actions/applications-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/hicolor/scalable/actions/applications-symbolic.svg new file mode 100644 index 0000000..87f307f --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/hicolor/scalable/actions/applications-symbolic.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/hicolor/scalable/actions/general-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/hicolor/scalable/actions/general-symbolic.svg new file mode 100644 index 0000000..e11da07 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/hicolor/scalable/actions/general-symbolic.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/my-caffeine-off-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/my-caffeine-off-symbolic.svg index d531087..e6d7f40 100644 --- a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/my-caffeine-off-symbolic.svg +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/my-caffeine-off-symbolic.svg @@ -2,20 +2,20 @@ + width="16" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> @@ -33,8 +33,8 @@ bordercolor="#666666" borderopacity="1" inkscape:current-layer="layer11" - inkscape:cx="6.0760965" - inkscape:cy="6.333427" + inkscape:cx="3.4863718" + inkscape:cy="8.404234" gridtolerance="10" inkscape:guide-bbox="true" guidetolerance="10" @@ -55,27 +55,31 @@ inkscape:snap-nodes="false" inkscape:snap-others="false" inkscape:snap-to-guides="true" - inkscape:window-height="741" + inkscape:window-height="1011" inkscape:window-maximized="1" - inkscape:window-width="1366" - inkscape:window-x="0" - inkscape:window-y="-3" - inkscape:zoom="32"> + inkscape:window-width="1920" + inkscape:window-x="1920" + inkscape:window-y="32" + inkscape:zoom="21.655751" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#555753"> + id="guide4029" + inkscape:locked="false" /> Gnome Symbolic Icon Theme diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/my-caffeine-on-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/my-caffeine-on-symbolic.svg index 5836586..3a730d2 100644 --- a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/my-caffeine-on-symbolic.svg +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/my-caffeine-on-symbolic.svg @@ -2,20 +2,20 @@ + width="16" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> @@ -33,8 +33,8 @@ bordercolor="#666666" borderopacity="1" inkscape:current-layer="layer11" - inkscape:cx="6.0760965" - inkscape:cy="6.333427" + inkscape:cx="6.109375" + inkscape:cy="6.34375" gridtolerance="10" inkscape:guide-bbox="true" guidetolerance="10" @@ -55,27 +55,31 @@ inkscape:snap-nodes="false" inkscape:snap-others="false" inkscape:snap-to-guides="true" - inkscape:window-height="741" + inkscape:window-height="1011" inkscape:window-maximized="1" - inkscape:window-width="1366" - inkscape:window-x="0" - inkscape:window-y="-3" - inkscape:zoom="32"> + inkscape:window-width="1920" + inkscape:window-x="1920" + inkscape:window-y="32" + inkscape:zoom="32" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#555753"> + id="guide4029" + inkscape:locked="false" /> Gnome Symbolic Icon Theme diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/stopwatch-symbolic.svg b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/stopwatch-symbolic.svg new file mode 100644 index 0000000..57a69d6 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/icons/stopwatch-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/cs/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/cs/LC_MESSAGES/gnome-shell-extension-caffeine.mo new file mode 100644 index 0000000..9f7c48d Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/cs/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/de/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/de/LC_MESSAGES/gnome-shell-extension-caffeine.mo index cfaa741..e559599 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/de/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/de/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/es/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/es/LC_MESSAGES/gnome-shell-extension-caffeine.mo index d9b36d0..df50678 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/es/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/es/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/fr/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/fr/LC_MESSAGES/gnome-shell-extension-caffeine.mo index 09cea95..fd8342c 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/fr/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/fr/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/hu/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/hu/LC_MESSAGES/gnome-shell-extension-caffeine.mo index 7c078ee..0492c51 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/hu/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/hu/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/it_IT/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/it_IT/LC_MESSAGES/gnome-shell-extension-caffeine.mo index f16f3e3..0902b79 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/it_IT/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/it_IT/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ja/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ja/LC_MESSAGES/gnome-shell-extension-caffeine.mo index f4a5759..cf5f3ce 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ja/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ja/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ka/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ka/LC_MESSAGES/gnome-shell-extension-caffeine.mo new file mode 100644 index 0000000..0683101 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ka/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/nl/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/nl/LC_MESSAGES/gnome-shell-extension-caffeine.mo new file mode 100644 index 0000000..63a335e Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/nl/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pl/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pl/LC_MESSAGES/gnome-shell-extension-caffeine.mo index d638ed6..340d1b1 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pl/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pl/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pr_BR/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pr_BR/LC_MESSAGES/gnome-shell-extension-caffeine.mo new file mode 100644 index 0000000..78ed8ec Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pr_BR/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pt_PT/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pt_PT/LC_MESSAGES/gnome-shell-extension-caffeine.mo index 9e59bc1..6566450 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pt_PT/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/pt_PT/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ru/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ru/LC_MESSAGES/gnome-shell-extension-caffeine.mo index e1a7e3c..d41718d 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ru/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/ru/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/sk/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/sk/LC_MESSAGES/gnome-shell-extension-caffeine.mo index e5fb401..74a4b37 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/sk/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/sk/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/sv/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/sv/LC_MESSAGES/gnome-shell-extension-caffeine.mo index 7c74c08..c1a7e14 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/sv/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/sv/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/tr/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/tr/LC_MESSAGES/gnome-shell-extension-caffeine.mo index 8cdafb2..95f5eaa 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/tr/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/tr/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/zh_CN/LC_MESSAGES/gnome-shell-extension-caffeine.mo b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/zh_CN/LC_MESSAGES/gnome-shell-extension-caffeine.mo index dadaa17..282d00f 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/zh_CN/LC_MESSAGES/gnome-shell-extension-caffeine.mo and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/locale/zh_CN/LC_MESSAGES/gnome-shell-extension-caffeine.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/metadata.json b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/metadata.json index 8944d72..25646a7 100644 --- a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/metadata.json +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/metadata.json @@ -5,10 +5,10 @@ "name": "Caffeine", "settings-schema": "org.gnome.shell.extensions.caffeine", "shell-version": [ - "3.36", - "3.38" + "43", + "44" ], "url": "https://github.com/eonpatapon/gnome-shell-extension-caffeine", "uuid": "caffeine@patapon.info", - "version": 37 + "version": 51 } \ No newline at end of file diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/appsPage.js b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/appsPage.js new file mode 100644 index 0000000..aa26ca7 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/appsPage.js @@ -0,0 +1,226 @@ +/* + This file is part of Caffeine (gnome-shell-extension-caffeine). + + Caffeine is free software: you can redistribute it and/or modify it under the terms of + the GNU General Public License as published by the Free Software Foundation, either + version 3 of the License, or (at your option) any later version. + + Caffeine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with Caffeine. + If not, see . + + Copyright 2022 Pakaoraki + + // From https://gitlab.com/skrewball/openweather/-/blob/master/src/prefs.js +*/ +'use strict'; + +const { Adw, Gtk, GObject, Gio } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); +const _ = Gettext.gettext; + +const AppsModeChoices = { + RUNNING: _("Running"), + FOCUS: _("Focus"), + WORKSPACE: _("Active workspace"), +}; + +var AppsPage = GObject.registerClass( +class Caffeine_AppsPage extends Adw.PreferencesPage { + _init(settings, settingsKey) { + super._init({ + title: _('Apps'), + icon_name: 'applications-symbolic', + name: 'AppsPage' + }); + this._settingsKey = settingsKey; + this._settings = settings; + this._listApps = []; + + // Apps behavior group + // -------------- + let appsBehaviorGroup = new Adw.PreferencesGroup({ + title: _("Trigger mode") + }); + + // Apps behavior select mode + let appsTriggerMode = new Gtk.StringList(); + appsTriggerMode.append(AppsModeChoices.RUNNING); + appsTriggerMode.append(AppsModeChoices.FOCUS); + appsTriggerMode.append(AppsModeChoices.WORKSPACE); + let appsTriggerModeRow = new Adw.ComboRow({ + title: _("Apps trigger Caffeine mode"), + subtitle: _("Choose the way apps will trigger Caffeine"), + model: appsTriggerMode, + selected: this._settings.get_enum(this._settingsKey.TRIGGER_APPS_MODE) + }); + + // Add elements + appsBehaviorGroup.add(appsTriggerModeRow); + this.add(appsBehaviorGroup); + + // Apps list group + // -------------- + let addAppsButton = new Gtk.Button({ + child: new Adw.ButtonContent({ + icon_name: 'list-add-symbolic', + label: _("Add") + }) + }); + this.appsGroup = new Adw.PreferencesGroup({ + title: _('Apps that trigger Caffeine'), + header_suffix: addAppsButton + }); + + this._refreshApps(); + + // Add elements + this.add(this.appsGroup); + + // Bind signals + addAppsButton.connect('clicked', this._onAddApp.bind(this)); + appsTriggerModeRow.connect('notify::selected', (widget) => { + this._settings.set_enum(this._settingsKey.TRIGGER_APPS_MODE, widget.selected); + }); + } + + _refreshApps() { + const _apps = this._settings.get_strv(this._settingsKey.INHIBIT_APPS); + + // Clear the Apps list + this._listApps.length = 0; + + // Update the list & Check if app still exist + _apps.forEach(id => { + const appInfo = Gio.DesktopAppInfo.new(id); + + if (appInfo) + this._listApps.push(id); + }); + + // Check if the apps list UI needs updating + if (this._appsListUi != this._listApps) { + + // Remove the old list + if (this._count) { + for (var i = 0; i < this._count; i++) { + this.appsGroup.remove(this.apps[i].Row); + } + this._count = null; + } + + if (this._listApps.length > 0) { + this.apps = {}; + + // Build new apps UI list + for (let i in this._listApps) { + this.apps[i] = {}; + this.apps[i].ButtonBox = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, + halign: Gtk.Align.CENTER, + spacing: 5, + hexpand: false, + vexpand: false + }); + this.apps[i].DeleteButton = new Gtk.Button({ + icon_name: 'edit-delete-symbolic', + valign: Gtk.Align.CENTER, + css_classes: ['error'], + hexpand: false, + vexpand: false + }); + + // App info + let appInfo = Gio.DesktopAppInfo.new(this._listApps[i]); + const appIcon = new Gtk.Image({ + gicon: appInfo.get_icon(), + pixel_size: 32, + }); + appIcon.get_style_context().add_class('icon-dropshadow'); + this.apps[i].Row = new Adw.ActionRow({ + title: appInfo.get_display_name(), + subtitle: this._listApps[i].replace('.desktop',''), + activatable: true + }); + + // Add elements + this.apps[i].Row.add_prefix(appIcon); + this.apps[i].ButtonBox.append(this.apps[i].DeleteButton); + this.apps[i].Row.add_suffix(this.apps[i].ButtonBox); + this.appsGroup.add(this.apps[i].Row); + } + // Bind signals + for (let i in this.apps) { + this.apps[i].DeleteButton.connect('clicked', () => { + this._onRemoveApp(this._listApps[i]); + }); + + } + this._count = this._listApps.length; + } + this._appsListUi = [...this._listApps]; + } + return 0; + } + + _onAddApp() { + const dialog = new NewAppDialog(this.get_root(), this._settingsKey); + dialog.connect('response', (dlg, id) => { + const appInfo = id === Gtk.ResponseType.OK + ? dialog.get_widget().get_app_info() : null; + const apps = this._settings.get_strv(this._settingsKey.INHIBIT_APPS); + if (appInfo && !apps.some(a => a === appInfo.get_id())) { + this._settings.set_strv(this._settingsKey.INHIBIT_APPS, [ + ...apps, appInfo.get_id(), + ]); + this._refreshApps(); + } + dialog.destroy(); + }); + dialog.show(); + } + + _onRemoveApp(appId) { + this._settings.set_strv(this._settingsKey.INHIBIT_APPS, + this._settings.get_strv(this._settingsKey.INHIBIT_APPS).filter(id => { + return id !== appId; + })); + this._refreshApps(); + } + +}); + +const NewAppDialog = GObject.registerClass( + class NewAppDialog extends Gtk.AppChooserDialog { + _init(parent, settingsKey) { + super._init({ + transient_for: parent, + modal: true, + }); + + this._settings = ExtensionUtils.getSettings(); + this._settingsKey = settingsKey; + + this.get_widget().set({ + show_all: true, + show_other: true, // hide more button + }); + + this.get_widget().connect('application-selected', + this._updateSensitivity.bind(this)); + this._updateSensitivity(); + } + + _updateSensitivity() { + const apps = this._settings.get_strv(this._settingsKey.INHIBIT_APPS); + const appInfo = this.get_widget().get_app_info(); + this.set_response_sensitive(Gtk.ResponseType.OK, + appInfo && !apps.some(i => i.startsWith(appInfo.get_id()))); + } + }); diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/displayPage.js b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/displayPage.js new file mode 100644 index 0000000..e669a08 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/displayPage.js @@ -0,0 +1,137 @@ +/* + This file is part of Caffeine (gnome-shell-extension-caffeine). + + Caffeine is free software: you can redistribute it and/or modify it under the terms of + the GNU General Public License as published by the Free Software Foundation, either + version 3 of the License, or (at your option) any later version. + + Caffeine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with Caffeine. + If not, see . + + Copyright 2022 Pakaoraki + + // From https://gitlab.com/skrewball/openweather/-/blob/master/src/prefs.js +*/ +'use strict'; + +const { Adw, Gtk, GObject, Gio } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); +const _ = Gettext.gettext; + +var DisplayPage = GObject.registerClass( +class Caffeine_DisplayPage extends Adw.PreferencesPage { + _init(settings, settingsKey) { + super._init({ + title: _("Display"), + icon_name: 'video-display-symbolic', + name: 'DisplayPage' + }); + this._settings = settings; + this._settingsKey = settingsKey; + + // Display group + // -------------- + let displayGroup = new Adw.PreferencesGroup({ + title: _("Display") + }); + + // Show indicator + let showStatusIndicator = new Gtk.StringList(); + showStatusIndicator.append(_("Only when active")); + showStatusIndicator.append(_("Always")); + showStatusIndicator.append(_("Never")); + let showStatusIndicatorRow = new Adw.ComboRow({ + title: _("Show status indicator in top panel"), + subtitle: _("Enable or disable the Caffeine icon in the top panel"), + model: showStatusIndicator, + selected: this._settings.get_enum(this._settingsKey.SHOW_INDICATOR) + }); + + // Show timer + let showTimerSwitch = new Gtk.Switch({ + valign: Gtk.Align.CENTER, + active: this._settings.get_boolean(this._settingsKey.SHOW_TIMER) + }); + let showTimerRow = new Adw.ActionRow({ + title: _("Show timer in top panel"), + subtitle: _("Enable or disable the timer in the top panel"), + activatable_widget: showTimerSwitch + }); + showTimerRow.add_suffix(showTimerSwitch); + + // Notifications + let notificationSwitch = new Gtk.Switch({ + valign: Gtk.Align.CENTER, + active: this._settings.get_boolean(this._settingsKey.SHOW_NOTIFICATIONS) + }); + let notificationRow = new Adw.ActionRow({ + title: _("Notifications"), + subtitle: _("Enable notifications when Caffeine is enabled or disabled"), + activatable_widget: notificationSwitch + }); + notificationRow.add_suffix(notificationSwitch); + + // Indicator position offset + this.lastIndicatorPos = this._settings.get_int(this._settingsKey.INDICATOR_POS_MAX); + this.posIndicatorOffsetButton = new Gtk.SpinButton({ + adjustment: new Gtk.Adjustment({ + lower: -1, + upper: this.lastIndicatorPos, + step_increment: 1, + page_increment: 1, + page_size: 0, + value: this._settings.get_int(this._settingsKey.INDICATOR_POSITION) + }), + climb_rate: 1, + digits: 0, + numeric: true, + valign: Gtk.Align.CENTER + }); + let posIndicatorOffsetRow = new Adw.ActionRow({ + title: _("Status indicator position"), + subtitle: _("The position relative of indicator icon to other items"), + activatable_widget: this.posIndicatorOffsetButton + }); + posIndicatorOffsetRow.add_suffix(this.posIndicatorOffsetButton); + + // Add elements + displayGroup.add(showStatusIndicatorRow); + displayGroup.add(showTimerRow); + displayGroup.add(notificationRow); + displayGroup.add(posIndicatorOffsetRow); + this.add(displayGroup); + + // Bind signals + // -------------- + showStatusIndicatorRow.connect('notify::selected', (widget) => { + if (widget.selected === 2) { + showTimerSwitch.set_sensitive(false); + } else { + showTimerSwitch.set_sensitive(true); + } + this._settings.set_enum(this._settingsKey.SHOW_INDICATOR, widget.selected); + }); + showTimerSwitch.connect('notify::active', (widget) => { + this._settings.set_boolean(this._settingsKey.SHOW_TIMER, widget.get_active()); + }); + notificationSwitch.connect('notify::active', (widget) => { + this._settings.set_boolean(this._settingsKey.SHOW_NOTIFICATIONS, widget.get_active()); + }); + this._settings.bind(this._settingsKey.INDICATOR_POSITION, + this.posIndicatorOffsetButton, 'value', + Gio.SettingsBindFlags.DEFAULT); + this._settings.connect(`changed::${this._settingsKey.INDICATOR_POS_MAX}`, this._updatePosMax.bind(this)); + } + + _updatePosMax() { + this.lastIndicatorPos = this._settings.get_int(this._settingsKey.INDICATOR_POS_MAX); + this.posIndicatorOffsetButton.adjustment.set_upper(this.lastIndicatorPos); + } +}); diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/generalPage.js b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/generalPage.js new file mode 100644 index 0000000..cb693eb --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/preferences/generalPage.js @@ -0,0 +1,390 @@ +/* + This file is part of Caffeine (gnome-shell-extension-caffeine). + + Caffeine is free software: you can redistribute it and/or modify it under the terms of + the GNU General Public License as published by the Free Software Foundation, either + version 3 of the License, or (at your option) any later version. + + Caffeine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with Caffeine. + If not, see . + + Copyright 2022 Pakaoraki + + // From https://gitlab.com/skrewball/openweather/-/blob/master/src/prefs.js +*/ +'use strict'; + +const { Adw, Gtk, GObject, Gdk } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); +const _ = Gettext.gettext; +const genParam = (type, name, ...dflt) => GObject.ParamSpec[type](name, name, name, GObject.ParamFlags.READWRITE, ...dflt); + +const ComboBoxChoices = { + NEVER: _("Never"), + ALWAYS: _("Always"), + FOR_APPS: _("For apps on list"), +}; + +const TIMERS_DURATION = [ + "05, 10, 30", + "10, 20, 45", + "15, 30, 60", + "20, 40, 75", + "30, 50, 80" +]; + +var GeneralPage = GObject.registerClass( +class Caffeine_GeneralPage extends Adw.PreferencesPage { + _init(settings, settingsKey) { + super._init({ + title: _("General"), + icon_name: 'general-symbolic', + name: 'GeneralPage' + }); + this._settings = settings; + this._settingsKey = settingsKey; + + // Behavior group + // -------------- + let behaviorGroup = new Adw.PreferencesGroup({ + title: _("Behavior") + }); + + // Enable / Disable fullscreen apps + let disableFullscreenSwitch = new Gtk.Switch({ + valign: Gtk.Align.CENTER, + active: this._settings.get_boolean(this._settingsKey.FULLSCREEN) + }); + let disableFullscreenRow = new Adw.ActionRow({ + title: _("Enable for fullscreen apps"), + subtitle: _("Automatically enable when an app enters fullscreen mode"), + activatable_widget: disableFullscreenSwitch + }); + disableFullscreenRow.add_suffix(disableFullscreenSwitch); + + // Remember state + let rememberStateSwitch = new Gtk.Switch({ + valign: Gtk.Align.CENTER, + active: this._settings.get_boolean(this._settingsKey.RESTORE) + }); + let rememberStateRow = new Adw.ActionRow({ + title: _("Remember state"), + subtitle: _("Remember the last state across sessions and reboots"), + activatable_widget: rememberStateSwitch + }); + rememberStateRow.add_suffix(rememberStateSwitch); + + // Pause and resume Night Light + let pauseNightLight = new Gtk.StringList(); + pauseNightLight.append(ComboBoxChoices.NEVER); + pauseNightLight.append(ComboBoxChoices.ALWAYS); + pauseNightLight.append(ComboBoxChoices.FOR_APPS); + let pauseNightLightRow = new Adw.ComboRow({ + title: _("Pause and resume Night Light"), + subtitle: _("Toggles the night light together with Caffeine\'s state"), + model: pauseNightLight, + selected: this._settings.get_enum(this._settingsKey.NIGHT_LIGHT) + }); + + // Allow blank screen + let allowBlankScreen = new Gtk.StringList(); + allowBlankScreen.append(ComboBoxChoices.NEVER); + allowBlankScreen.append(ComboBoxChoices.ALWAYS); + allowBlankScreen.append(ComboBoxChoices.FOR_APPS); + let allowBlankScreenRow = new Adw.ComboRow({ + title: _("Allow screen blank"), + subtitle: _("Allow turning off screen when Caffeine is enabled"), + model: allowBlankScreen, + selected: this._settings.get_enum(this._settingsKey.SCREEN_BLANK) + }); + + // Add elements + behaviorGroup.add(disableFullscreenRow); + behaviorGroup.add(rememberStateRow); + behaviorGroup.add(pauseNightLightRow); + behaviorGroup.add(allowBlankScreenRow); + this.add(behaviorGroup); + + // Timer group + // -------------- + let timerGroup = new Adw.PreferencesGroup({ + title: _("Timer") + }); + + const durationIndex = this._settings.get_int(this._settingsKey.DURATION_TIMER_INDEX); + this.timerOptionRow = new Adw.ActionRow({ + title: _("Durations"), + activatable: true + }); + + let adjustSliderTimer = new Gtk.Adjustment({ + lower: 0, + upper: 4, + step_increment: 0.1, + page_increment: 1, + value: durationIndex + }); + this._updateTimerDuration(durationIndex); + + let sliderTimer = new Gtk.Scale({ + valign: 'center', + hexpand: true, + width_request: '200px', + round_digits: false, + draw_value: false, + orientation: 'horizontal', + digits: 0, + adjustment: adjustSliderTimer + }); + sliderTimer.add_mark(0, Gtk.PositionType.BOTTOM, null); + sliderTimer.add_mark(1, Gtk.PositionType.BOTTOM, null); + sliderTimer.add_mark(2, Gtk.PositionType.BOTTOM, null); + sliderTimer.add_mark(3, Gtk.PositionType.BOTTOM, null); + sliderTimer.add_mark(4, Gtk.PositionType.BOTTOM, null); + this.timerOptionRow.add_suffix(sliderTimer); + + // Add elements + timerGroup.add(this.timerOptionRow); + this.add(timerGroup); + + // Shortcut group + // -------------- + let deleteShortcutButton = new Gtk.Button({ + icon_name: 'edit-delete-symbolic', + valign: Gtk.Align.CENTER, + css_classes: ['error'], + hexpand: false, + vexpand: false + }); + let shortcutGroup = new Adw.PreferencesGroup({ + title: _("Shortcut"), + header_suffix: deleteShortcutButton + }); + + // Keyboard shortcut + this.shortcutKeyBoard = new ShortcutSettingWidget( + this._settings, + this._settingsKey.TOGGLE_SHORTCUT, + _("Toggle shortcut"), + _("Use Backspace to clear") + ); + + // Hide/Show delete button + if( ! this.shortcutKeyBoard.isAcceleratorSet() ) { + deleteShortcutButton.visible = false; + } + + // Add elements + shortcutGroup.add(this.shortcutKeyBoard); + this.add(shortcutGroup); + + + // Bind signals + // -------------- + disableFullscreenSwitch.connect('notify::active', (widget) => { + this._settings.set_boolean(this._settingsKey.FULLSCREEN, widget.get_active()); + }); + rememberStateSwitch.connect('notify::active', (widget) => { + this._settings.set_boolean(this._settingsKey.RESTORE, widget.get_active()); + }); + pauseNightLightRow.connect('notify::selected', (widget) => { + this._settings.set_enum(this._settingsKey.NIGHT_LIGHT, widget.selected); + }); + allowBlankScreenRow.connect('notify::selected', (widget) => { + this._settings.set_enum(this._settingsKey.SCREEN_BLANK, widget.selected); + }); + sliderTimer.connect('change-value', + (widget) => this._updateTimerDuration(widget.get_value())); + deleteShortcutButton.connect('clicked', this._resetShortcut.bind(this)); + this._settings.connect(`changed::${this._settingsKey.TOGGLE_SHORTCUT}`, () => { + if( this.shortcutKeyBoard.isAcceleratorSet() ) { + deleteShortcutButton.visible = true; + } else { + deleteShortcutButton.visible = false; + } + }); + } + + _updateTimerDuration(value) { + const durationIndex = this._settings.get_int(this._settingsKey.DURATION_TIMER_INDEX); + this.timerOptionRow.set_subtitle(_("Set to ") + TIMERS_DURATION[value] + _(" minutes")); + if (durationIndex !== value) { + this._settings.set_int(this._settingsKey.DURATION_TIMER_INDEX, value); + } + } + + _resetShortcut() { + this.shortcutKeyBoard.resetAccelerator(); + } +}); + +/* +* Shortcut Widget +*/ +const ShortcutSettingWidget = class extends Adw.ActionRow { + static { + GObject.registerClass({ + Properties: { + shortcut: genParam('string', 'shortcut', ''), + }, + Signals: { + changed: { param_types: [GObject.TYPE_STRING] }, + }, + }, this); + } + + constructor(settings, key, label, sublabel) { + super({ + title: label, + subtitle: sublabel, + activatable: true + }); + + this.shortcutBox = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, + halign: Gtk.Align.CENTER, + spacing: 5, + hexpand: false, + vexpand: false + }); + + this._key = key; + this._settings = settings; + this._description = sublabel; + + this.add_suffix(this.shortcutBox); + this.shortLabel = new Gtk.ShortcutLabel({ + disabled_text: _('New accelerator…'), + valign: Gtk.Align.CENTER, + hexpand: false, + vexpand: false + }); + + this.shortcutBox.append(this.shortLabel); + + // Bind signals + this.connect('activated', this._onActivated.bind(this)); + this.bind_property('shortcut', this.shortLabel, 'accelerator', GObject.BindingFlags.DEFAULT); + [this.shortcut] = this._settings.get_strv(this._key); + + this.add_suffix(this.shortcutBox); + } + + isAcceleratorSet() { + if(this.shortLabel.get_accelerator()) { + return true; + } else { + return false; + } + } + + resetAccelerator() { + this.saveShortcut(); // Clear shortcut + } + + _onActivated(widget) { + let ctl = new Gtk.EventControllerKey(); + + let content = new Adw.StatusPage({ + title: _('New accelerator…'), + description: this._description, + icon_name: 'preferences-desktop-keyboard-shortcuts-symbolic', + }); + + this._editor = new Adw.Window({ + modal: true, + hide_on_close: true, + transient_for: widget.get_root(), + width_request: 480, + height_request: 320, + content, + }); + + this._editor.add_controller(ctl); + ctl.connect('key-pressed', this._onKeyPressed.bind(this)); + this._editor.present(); + } + + _onKeyPressed(_widget, keyval, keycode, state) { + let mask = state & Gtk.accelerator_get_default_mod_mask(); + mask &= ~Gdk.ModifierType.LOCK_MASK; + + if (!mask && keyval === Gdk.KEY_Escape) { + this._editor.close(); + return Gdk.EVENT_STOP; + } + + if (keyval === Gdk.KEY_BackSpace) { + this.saveShortcut(); // Clear shortcut + return Gdk.EVENT_STOP; + } + + if (!this.isValidBinding(mask, keycode, keyval) || !this.isValidAccel(mask, keyval)) + return Gdk.EVENT_STOP; + + this.saveShortcut(keyval, keycode, mask); + return Gdk.EVENT_STOP; + } + + saveShortcut(keyval, keycode, mask) { + if (!keyval && !keycode) { + this.shortcut = ""; + } else { + this.shortcut = Gtk.accelerator_name_with_keycode(null, keyval, keycode, mask); + } + + this.emit('changed', this.shortcut); + this._settings.set_strv(this._key, [this.shortcut]); + this._editor.destroy(); + } + + // Functions from https://gitlab.gnome.org/GNOME/gnome-control-center/-/blob/main/panels/keyboard/keyboard-shortcuts.c + + keyvalIsForbidden(keyval) { + return [ + // Navigation keys + Gdk.KEY_Home, + Gdk.KEY_Left, + Gdk.KEY_Up, + Gdk.KEY_Right, + Gdk.KEY_Down, + Gdk.KEY_Page_Up, + Gdk.KEY_Page_Down, + Gdk.KEY_End, + Gdk.KEY_Tab, + + // Return + Gdk.KEY_KP_Enter, + Gdk.KEY_Return, + + Gdk.KEY_Mode_switch, + ].includes(keyval); + } + + isValidBinding(mask, keycode, keyval) { + return !(mask === 0 || mask === Gdk.SHIFT_MASK && keycode !== 0 && + ((keyval >= Gdk.KEY_a && keyval <= Gdk.KEY_z) || + (keyval >= Gdk.KEY_A && keyval <= Gdk.KEY_Z) || + (keyval >= Gdk.KEY_0 && keyval <= Gdk.KEY_9) || + (keyval >= Gdk.KEY_kana_fullstop && keyval <= Gdk.KEY_semivoicedsound) || + (keyval >= Gdk.KEY_Arabic_comma && keyval <= Gdk.KEY_Arabic_sukun) || + (keyval >= Gdk.KEY_Serbian_dje && keyval <= Gdk.KEY_Cyrillic_HARDSIGN) || + (keyval >= Gdk.KEY_Greek_ALPHAaccent && keyval <= Gdk.KEY_Greek_omega) || + (keyval >= Gdk.KEY_hebrew_doublelowline && keyval <= Gdk.KEY_hebrew_taf) || + (keyval >= Gdk.KEY_Thai_kokai && keyval <= Gdk.KEY_Thai_lekkao) || + (keyval >= Gdk.KEY_Hangul_Kiyeog && keyval <= Gdk.KEY_Hangul_J_YeorinHieuh) || + (keyval === Gdk.KEY_space && mask === 0) || this.keyvalIsForbidden(keyval)) + ); + } + + isValidAccel(mask, keyval) { + return Gtk.accelerator_valid(keyval, mask) || (keyval === Gdk.KEY_Tab && mask !== 0); + } +}; diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/prefs.js b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/prefs.js index d2b595a..0fc991d 100644 --- a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/prefs.js +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/prefs.js @@ -1,300 +1,85 @@ -// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- -// Adapted from auto-move-windows@gnome-shell-extensions.gcampax.github.com +/* + This file is part of Caffeine (gnome-shell-extension-caffeine). -const Gio = imports.gi.Gio; -const Gtk = imports.gi.Gtk; -const GObject = imports.gi.GObject; -const Config = imports.misc.config; + Caffeine is free software: you can redistribute it and/or modify it under the terms of + the GNU General Public License as published by the Free Software Foundation, either + version 3 of the License, or (at your option) any later version. -const Gettext = imports.gettext.domain('gnome-shell-extension-caffeine'); -const _ = Gettext.gettext; + Caffeine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Convenience = Me.imports.convenience; - -const INHIBIT_APPS_KEY = 'inhibit-apps'; -const SHOW_INDICATOR_KEY = 'show-indicator'; -const SHOW_NOTIFICATIONS_KEY = 'show-notifications'; -const FULLSCREEN_KEY = 'enable-fullscreen'; -const RESTORE_KEY = 'restore-state'; -const NIGHT_LIGHT_KEY = 'control-nightlight'; -const NIGHT_LIGHT_APP_ONLY_KEY = 'control-nightlight-for-app'; - -const Columns = { - APPINFO: 0, - DISPLAY_NAME: 1, - ICON: 2 -}; - -let ShellVersion = parseInt(Config.PACKAGE_VERSION.split(".")[1]); - -class CaffeineWidget { - constructor(params) { - this.w = new Gtk.Grid(params); - this.w.set_orientation(Gtk.Orientation.VERTICAL); - - this._settings = Convenience.getSettings(); - this._settings.connect('changed', this._refresh.bind(this)); - this._changedPermitted = false; - - - let showCaffeineBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, - margin: 7}); - - let showCaffeineLabel = new Gtk.Label({label: _("Show Caffeine in top panel"), - xalign: 0}); - - let showCaffeineSwitch = new Gtk.Switch({active: this._settings.get_boolean(SHOW_INDICATOR_KEY)}); - showCaffeineSwitch.connect('notify::active', button => { - this._settings.set_boolean(SHOW_INDICATOR_KEY, button.active); - }); - - showCaffeineBox.pack_start(showCaffeineLabel, true, true, 0); - showCaffeineBox.add(showCaffeineSwitch); - - this.w.add(showCaffeineBox); - - if (ShellVersion > 6) { - const gtkhbox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, - margin: 7}); - - const enableFullscreenLabel = new Gtk.Label({label: _("Enable when a fullscreen application is running"), - xalign: 0}); - - const enableFullscreenSwitch = new Gtk.Switch({active: this._settings.get_boolean(FULLSCREEN_KEY)}); - enableFullscreenSwitch.connect('notify::active', button => { - this._settings.set_boolean(FULLSCREEN_KEY, button.active); - }); - - gtkhbox.pack_start(enableFullscreenLabel, true, true, 0); - gtkhbox.add(enableFullscreenSwitch); - - this.w.add(gtkhbox); - } - - const stateBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, - margin: 7}); - - const stateLabel = new Gtk.Label({label: _("Restore state across reboots"), - xalign: 0}); - - const stateSwitch = new Gtk.Switch({active: this._settings.get_boolean(RESTORE_KEY)}); - stateSwitch.connect('notify::active', button => { - this._settings.set_boolean(RESTORE_KEY, button.active); - }); - - stateBox.pack_start(stateLabel, true, true, 0); - stateBox.add(stateSwitch); - - this.w.add(stateBox); - - const notificationsBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, - margin: 7}); - - const notificationsLabel = new Gtk.Label({label: _("Enable notifications"), - xalign: 0}); - - const notificationsSwitch = new Gtk.Switch({active: this._settings.get_boolean(SHOW_NOTIFICATIONS_KEY)}); - notificationsSwitch.connect('notify::active', button => { - this._settings.set_boolean(SHOW_NOTIFICATIONS_KEY, button.active); - }); - - notificationsBox.pack_start(notificationsLabel, true, true, 0); - notificationsBox.add(notificationsSwitch); - - this.w.add(notificationsBox); - - const nightlightBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, - margin: 7}); - - const nightlightLabel = new Gtk.Label({label: _("Pause/resume Night Light if enabled"), - xalign: 0}); - - const nightlightSwitch = new Gtk.Switch({active: this._settings.get_boolean(NIGHT_LIGHT_KEY)}); - nightlightSwitch.connect('notify::active', button => { - this._settings.set_boolean(NIGHT_LIGHT_KEY, button.active); - }); - - nightlightBox.pack_start(nightlightLabel, true, true, 0); - nightlightBox.add(nightlightSwitch); - - this.w.add(nightlightBox); - - const nightlightAppBox = new Gtk.Box({orientation: Gtk.Orientation.HORIZONTAL, - margin: 7}); - - const nightlightAppLabel = new Gtk.Label({label: _("Pause/resume Night Light for defined applications only"), - xalign: 0}); - - const nightlightAppSwitch = new Gtk.Switch({active: this._settings.get_boolean(NIGHT_LIGHT_APP_ONLY_KEY)}); - nightlightAppSwitch.connect('notify::active', button => { - this._settings.set_boolean(NIGHT_LIGHT_APP_ONLY_KEY, button.active); - }); - nightlightSwitch.connect('notify::active', button => { - if (button.active) { - nightlightAppSwitch.set_sensitive(true); - } else { - nightlightAppSwitch.set_active(false); - nightlightAppSwitch.set_sensitive(false); - } - }); - - nightlightAppBox.pack_start(nightlightAppLabel, true, true, 0); - nightlightAppBox.add(nightlightAppSwitch); - - this.w.add(nightlightAppBox); + You should have received a copy of the GNU General Public License along with Caffeine. + If not, see . - this._store = new Gtk.ListStore(); - this._store.set_column_types([Gio.AppInfo, GObject.TYPE_STRING, Gio.Icon]); + Copyright 2022 Pakaoraki - this._treeView = new Gtk.TreeView({ model: this._store, - hexpand: true, vexpand: true }); - this._treeView.get_selection().set_mode(Gtk.SelectionMode.SINGLE); + // From https://gitlab.com/skrewball/openweather/-/blob/master/src/prefs.js +*/ +'use strict'; - const appColumn = new Gtk.TreeViewColumn({ expand: true, sort_column_id: Columns.DISPLAY_NAME, - title: _("Applications which enable Caffeine automatically") }); - const iconRenderer = new Gtk.CellRendererPixbuf; - appColumn.pack_start(iconRenderer, false); - appColumn.add_attribute(iconRenderer, "gicon", Columns.ICON); - const nameRenderer = new Gtk.CellRendererText; - appColumn.pack_start(nameRenderer, true); - appColumn.add_attribute(nameRenderer, "text", Columns.DISPLAY_NAME); - this._treeView.append_column(appColumn); +const { Adw, Gtk, Gdk } = imports.gi; - this.w.add(this._treeView); - - const toolbar = new Gtk.Toolbar(); - toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR); - this.w.add(toolbar); - - const newButton = new Gtk.ToolButton({ stock_id: Gtk.STOCK_NEW, - label: _("Add application"), - is_important: true }); - newButton.connect('clicked', this._createNew.bind(this)); - toolbar.add(newButton); - - const delButton = new Gtk.ToolButton({ stock_id: Gtk.STOCK_DELETE }); - delButton.connect('clicked', this._deleteSelected.bind(this)); - toolbar.add(delButton); - - this._changedPermitted = true; - this._refresh(); - } - - _createNew() { - const dialog = new Gtk.Dialog({ title: _("Create new matching rule"), - transient_for: this.w.get_toplevel(), - modal: true }); - dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL); - dialog.add_button(_("Add"), Gtk.ResponseType.OK); - dialog.set_default_response(Gtk.ResponseType.OK); - - const grid = new Gtk.Grid({ column_spacing: 10, - row_spacing: 15, - margin: 10 }); - dialog._appChooser = new Gtk.AppChooserWidget({ show_all: true }); - grid.attach(dialog._appChooser, 0, 0, 2, 1); - dialog.get_content_area().add(grid); - - dialog.connect('response', (dialog, id) => { - if (id != Gtk.ResponseType.OK) { - dialog.destroy(); - return; - } - - const appInfo = dialog._appChooser.get_app_info(); - if (!appInfo) - return; - - this._changedPermitted = false; - if (!this._appendItem(appInfo.get_id())) { - this._changedPermitted = true; - return; - } - let iter = this._store.append(); - - this._store.set(iter, - [Columns.APPINFO, Columns.ICON, Columns.DISPLAY_NAME], - [appInfo, appInfo.get_icon(), appInfo.get_display_name()]); - this._changedPermitted = true; - - dialog.destroy(); - }); - dialog.show_all(); - } - - _deleteSelected() { - const [any, , iter] = this._treeView.get_selection().get_selected(); - - if (any) { - const appInfo = this._store.get_value(iter, Columns.APPINFO); - - this._changedPermitted = false; - this._removeItem(appInfo.get_id()); - this._store.remove(iter); - this._changedPermitted = true; - } - } - - _refresh() { - if (!this._changedPermitted) - // Ignore this notification, model is being modified outside - return; - - this._store.clear(); - - const currentItems = this._settings.get_strv(INHIBIT_APPS_KEY); - const validItems = [ ]; - for (let i = 0; i < currentItems.length; i++) { - const id = currentItems[i]; - const appInfo = Gio.DesktopAppInfo.new(id); - if (!appInfo) - continue; - validItems.push(currentItems[i]); - - const iter = this._store.append(); - this._store.set(iter, - [Columns.APPINFO, Columns.ICON, Columns.DISPLAY_NAME], - [appInfo, appInfo.get_icon(), appInfo.get_display_name()]); - } - - if (validItems.length != currentItems.length) // some items were filtered out - this._settings.set_strv(INHIBIT_APPS_KEY, validItems); - } - - _appendItem(id) { - const currentItems = this._settings.get_strv(INHIBIT_APPS_KEY); - - if (currentItems.includes(id)) { - printerr("Already have an item for this id"); - return false; - } - - currentItems.push(id); - this._settings.set_strv(INHIBIT_APPS_KEY, currentItems); - return true; - } - - _removeItem(id) { - const currentItems = this._settings.get_strv(INHIBIT_APPS_KEY); - const index = currentItems.indexOf(id); - - if (index < 0) - return; - - currentItems.splice(index, 1); - this._settings.set_strv(INHIBIT_APPS_KEY, currentItems); - } -} +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +// Import preferences pages +const GeneralPrefs = Me.imports.preferences.generalPage; +const DisplayPrefs = Me.imports.preferences.displayPage; +const AppsPrefs = Me.imports.preferences.appsPage; + +const SettingsKey = { + INHIBIT_APPS: 'inhibit-apps', + SHOW_INDICATOR: 'show-indicator', + SHOW_NOTIFICATIONS: 'show-notifications', + SHOW_TIMER: 'show-timer', + DURATION_TIMER_INDEX: 'duration-timer', + FULLSCREEN: 'enable-fullscreen', + RESTORE: 'restore-state', + NIGHT_LIGHT: 'nightlight-control', + TOGGLE_SHORTCUT: 'toggle-shortcut', + DEFAULT_WIDTH: 'prefs-default-width', + DEFAULT_HEIGHT: 'prefs-default-height', + SCREEN_BLANK: 'screen-blank', + TRIGGER_APPS_MODE: 'trigger-apps-mode', + INDICATOR_POSITION: 'indicator-position', + INDICATOR_INDEX: 'indicator-position-index', + INDICATOR_POS_MAX: 'indicator-position-max', +}; function init() { - Convenience.initTranslations(); + ExtensionUtils.initTranslations(Me.metadata['gettext-domain']); } -function buildPrefsWidget() { - const widget = new CaffeineWidget(); - widget.w.show_all(); +function fillPreferencesWindow(window) { + let iconTheme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default()); + if (!iconTheme.get_search_path().includes(Me.path + "/icons")) { + iconTheme.add_search_path(Me.path + "/icons"); + } - return widget.w; + //const settings = ExtensionUtils.getSettings(Me.metadata['settings-schema']); + const settings = ExtensionUtils.getSettings(); + const generalPage = new GeneralPrefs.GeneralPage(settings, SettingsKey); + const displayPage = new DisplayPrefs.DisplayPage(settings, SettingsKey); + const appsPage = new AppsPrefs.AppsPage(settings, SettingsKey); + + let prefsWidth = settings.get_int(SettingsKey.DEFAULT_WIDTH); + let prefsHeight = settings.get_int(SettingsKey.DEFAULT_HEIGHT); + + window.set_default_size(prefsWidth, prefsHeight); + window.set_search_enabled(true); + + window.add(generalPage); + window.add(displayPage); + window.add(appsPage); + + window.connect('close-request', () => { + let currentWidth = window.default_width; + let currentHeight = window.default_height; + // Remember user window size adjustments. + if (currentWidth != prefsWidth || currentHeight != prefsHeight) { + settings.set_int(SettingsKey.DEFAULT_WIDTH, currentWidth); + settings.set_int(SettingsKey.DEFAULT_HEIGHT, currentHeight); + } + window.destroy(); + }); } diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/schemas/gschemas.compiled b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/schemas/gschemas.compiled index 3e888dd..4875085 100644 Binary files a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/schemas/gschemas.compiled and b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/schemas/gschemas.compiled differ diff --git a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/schemas/org.gnome.shell.extensions.caffeine.gschema.xml b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/schemas/org.gnome.shell.extensions.caffeine.gschema.xml index f56461f..6baaccb 100644 --- a/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/schemas/org.gnome.shell.extensions.caffeine.gschema.xml +++ b/zorin/.local/share/gnome-shell/extensions/caffeine@patapon.info/schemas/org.gnome.shell.extensions.caffeine.gschema.xml @@ -1,23 +1,54 @@ + + + + + + + + + + + + + + + + [ ] Application list A list of strings, each containing an application id (desktop file name) + + false + Store caffeine toggle state + + false Store caffeine user state + + 0 + Specify time (minutes) for the timer countdown + Specify time (minutes) for the timer countdown + + + 2 + Specify index of duration range for the timer + Specify index of duration range for the timer + false Restore caffeine state - - true + + "only-active" Show indicator Show the indicator on the top panel @@ -26,20 +57,60 @@ Show notifications Show notifications when enabled/disabled + + true + Show timer + Show timer when enabled/disabled + true Enable when a fullscreen application is running Enable when a fullscreen application is running - - false - Pause/resume Night Light - Pause/resume Night Light when enabled/disabled + + "never" + Night Light control mode + Set the way Caffeine interacts with the Night light setting. - - false - Pause/resume Night Light for defined applications only - Pause/resume Night Light for defined applicationa when enabled/disabled + + "never" + Allow screen blank + Allow turning off screen when Caffeine is enabled. + + + "on-running" + Trigger App control mode + Set the trigger method for apps. + + + [] + Toggle shortcut + Shortcut to toggle Caffeine. + + + 570 + Default width for the preferences window + + + 590 + Default height for the preferences window + + + 0 + Visible position offset of status icon in indicator menu + + + 0 + Real position offset of status icon in indicator menu that include invisible one + + + 1 + Last item index in indicator menu + + + + + diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/LICENSE.rst b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/LICENSE similarity index 97% rename from zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/LICENSE.rst rename to zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/LICENSE index 45cad82..a2d684f 100644 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/LICENSE.rst +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/LICENSE @@ -2,6 +2,7 @@ The MIT License (MIT) ====================== +Copyright (c) 2022, Alex Saveau Copyright (c) 2014, Yotam Bar-On ----------------------------------------- diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/README.md b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/README.md new file mode 100644 index 0000000..74d7fb3 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/README.md @@ -0,0 +1,54 @@ +# Gnome Clipboard History + +[Gnome Clipboard History](https://extensions.gnome.org/extension/4839/clipboard-history/) is a Gnome +extension that saves what you've copied into an easily +accessible, searchable history panel. + +The extension is a rewrite of +[Clipboard Indicator](https://github.com/Tudmotu/gnome-shell-extension-clipboard-indicator) with +[vastly improved performance](https://alexsaveau.dev/blog/projects/performance/gnome/gch/gnome-clipboard-history), new features, and +[bug fixes](https://github.com/Tudmotu/gnome-shell-extension-clipboard-indicator/pull/338). + +## Download + +[Get it on GNOME Extensions](https://extensions.gnome.org/extension/4839/clipboard-history/) + +## Tips + +![Tutorial screenshot](tutorial-screenshot.png) + +- Open the panel from anywhere with Super + Shift + V. +- Modify shortcuts in settings or delete them by hitting backspace while editing a shortcut. +- Use the `Only save favorites to disk` feature to wipe your non-favorited items on shutdown. +- Use `Private mode` to temporarily stop processing copied items. +- Use keyboard shortcuts while the panel is open: + - Ctrl + N where `N` is a number from 1 to 9 to select the Nth + non-favorited entry. + - Super + Ctrl + N where `N` is a number from 1 to 9 to select + the Nth favorited entry. + - Ctrl + p/n to navigate to the previous/next page. + - Ctrl + Alt + S to open settings. + - / to search. + - F to (un)favorite a highlighted item. +- Search uses case-insensitive [regex](https://regex101.com/?flavor=javascript). + +## Install from source + +### Build + +```shell +cd ~/.local/share/gnome-shell/extensions/ && \ + git clone https://github.com/SUPERCILEX/gnome-clipboard-history.git clipboard-history@alexsaveau.dev && \ + cd clipboard-history@alexsaveau.dev && \ + make +``` + +### Restart GNOME + +Alt + F2 then type `r`. + +### Install + +```shell +gnome-extensions enable clipboard-history@alexsaveau.dev +``` diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/confirmDialog.js b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/confirmDialog.js similarity index 64% rename from zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/confirmDialog.js rename to zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/confirmDialog.js index c39808a..e0d0b6f 100644 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/confirmDialog.js +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/confirmDialog.js @@ -1,43 +1,55 @@ -const St = imports.gi.St; -const GObject = imports.gi.GObject; -const ModalDialog = imports.ui.modalDialog; -const CheckBox = imports.ui.checkBox; -const Clutter = imports.gi.Clutter; - +'use strict'; +const { St, GObject, Clutter } = imports.gi; +const ModalDialog = imports.ui.modalDialog; +let _openDialog; -function openConfirmDialog(title, message, sub_message, ok_label, cancel_label, callback) { - new ConfirmDialog(title, message + "\n" + sub_message, ok_label, cancel_label, callback).open(); +function openConfirmDialog( + title, + message, + sub_message, + ok_label, + cancel_label, + callback, +) { + if (!_openDialog) { + _openDialog = new ConfirmDialog( + title, + message + '\n' + sub_message, + ok_label, + cancel_label, + callback, + ).open(); + } } const ConfirmDialog = GObject.registerClass( class ConfirmDialog extends ModalDialog.ModalDialog { - _init(title, desc, ok_label, cancel_label, callback) { super._init(); let main_box = new St.BoxLayout({ - vertical: false + vertical: false, }); this.contentLayout.add_child(main_box); let message_box = new St.BoxLayout({ - vertical: true + vertical: true, }); main_box.add_child(message_box); let subject_label = new St.Label({ style: 'font-weight: bold', x_align: Clutter.ActorAlign.CENTER, - text: title + text: title, }); message_box.add_child(subject_label); let desc_label = new St.Label({ style: 'padding-top: 12px', x_align: Clutter.ActorAlign.CENTER, - text: desc + text: desc, }); message_box.add_child(desc_label); @@ -46,17 +58,19 @@ const ConfirmDialog = GObject.registerClass( label: cancel_label, action: () => { this.close(); + _openDialog = null; }, - key: Clutter.Escape + key: Clutter.Escape, }, { label: ok_label, action: () => { this.close(); callback(); - } - } + _openDialog = null; + }, + }, ]); } - } + }, ); diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/dataStructures.js b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/dataStructures.js new file mode 100644 index 0000000..ba9acb2 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/dataStructures.js @@ -0,0 +1,417 @@ +// Derived from +// https://github.com/wooorm/linked-list/blob/d2390fe1cab9f780cfd34fa31c8fa8ede4ad674d/index.js + +var TYPE_TEXT = 'text'; + +// Creates a new `Iterator` for looping over the `List`. +class Iterator { + constructor(item) { + this.item = item; + } + + // Move the `Iterator` to the next item. + next() { + this.value = this.item; + this.done = !this.item; + this.item = this.item ? this.item.next : undefined; + return this; + } +} + +// Creates a new `Item`: +// An item is a bit like DOM node: It knows only about its "parent" (`list`), +// the item before it (`prev`), and the item after it (`next`). +var LLNode = class Item { + // Prepends the given item *before* the item operated on. + prepend(item) { + const list = this.list; + + if (!item || !item.append || !item.prepend || !item.detach) { + throw new Error( + 'An argument without append, prepend, or detach methods was given to `Item#prepend`.', + ); + } + + // If self is detached, return false. + if (!list) { + return false; + } + if (this === item) { + return false; + } + + // Detach the prependee. + const transient = this.list === item.list; + item.detach(transient); + + // If self has a previous item... + if (this.prev) { + item.prev = this.prev; + this.prev.next = item; + } + + // Connect the prependee. + item.next = this; + item.list = list; + + // Set the previous item of self to the prependee. + this.prev = item; + + // If self is the first item in the parent list, link the lists first item to + // the prependee. + if (this === list.head) { + list.head = item; + } + + // If the the parent list has no last item, link the lists last item to self. + if (!list.tail) { + list.tail = this; + } + + list.length++; + if (!transient) { + item._addToIndex(); + } + + return item; + } + + // Appends the given item *after* the item operated on. + append(item) { + const list = this.list; + + if (!item || !item.append || !item.prepend || !item.detach) { + throw new Error( + 'An argument without append, prepend, or detach methods was given to `Item#append`.', + ); + } + + if (!list) { + return false; + } + if (this === item) { + return false; + } + + // Detach the appendee. + const transient = this.list === item.list; + item.detach(transient); + + // If self has a next item... + if (this.next) { + item.next = this.next; + this.next.prev = item; + } + + // Connect the appendee. + item.prev = this; + item.list = list; + + // Set the next item of self to the appendee. + this.next = item; + + // If the the parent list has no last item or if self is the parent lists last + // item, link the lists last item to the appendee. + if (this === list.tail || !list.tail) { + list.tail = item; + } + + list.length++; + if (!transient) { + item._addToIndex(); + } + + return item; + } + + // Detaches the item operated on from its parent list. + detach(transient) { + const list = this.list; + + if (!list) { + return this; + } + if (!transient) { + this._removeFromIndex(); + } + + // If self is the last item in the parent list, link the lists last item to + // the previous item. + if (list.tail === this) { + list.tail = this.prev; + } + + // If self is the first item in the parent list, link the lists first item to + // the next item. + if (list.head === this) { + list.head = this.next; + } + + // If both the last and first items in the parent list are the same, remove + // the link to the last item. + if (list.tail === list.head) { + list.tail = null; + } + + // If a previous item exists, link its next item to selfs next item. + if (this.prev) { + this.prev.next = this.next; + } + + // If a next item exists, link its previous item to selfs previous item. + if (this.next) { + this.next.prev = this.prev; + } + + // Remove links from self to both the next and previous items, and to the + // parent list. + this.prev = this.next = this.list = null; + + list.length--; + + return this; + } + + nextCyclic() { + return this.next || this.list.head; + } + + prevCyclic() { + return this.prev || this.list.last(); + } + + _addToIndex() { + const hash = this._hash(); + if (hash === undefined || hash === null) { + return; + } + + if (this.type === TYPE_TEXT) { + this.list.bytes += this.text.length; + } + + let entries = this.list.invertedIndex[hash]; + if (!entries) { + entries = []; + this.list.invertedIndex[hash] = entries; + } + entries.push(this.id); + this.list.idsToItems[this.id] = this; + } + + _removeFromIndex() { + const hash = this._hash(); + if (hash === undefined || hash === null) { + return; + } + + if (this.type === TYPE_TEXT) { + this.list.bytes -= this.text.length; + } + + const entries = this.list.invertedIndex[hash]; + if (entries.length === 1) { + delete this.list.invertedIndex[hash]; + } else { + entries.splice(entries.indexOf(this.id), 1); + } + delete this.list.idsToItems[this.id]; + } + + _hash() { + if (this.type === TYPE_TEXT) { + return _hashText(this.text); + } else { + return null; + } + } +}; + +LLNode.prototype.next = LLNode.prototype.prev = LLNode.prototype.list = null; + +// Creates a new List: A linked list is a bit like an Array, but knows nothing +// about how many items are in it, and knows only about its first (`head`) and +// last (`tail`) items. +// Each item (e.g. `head`, `tail`, &c.) knows which item comes before or after +// it (its more like the implementation of the DOM in JavaScript). +var LinkedList = class List { + // Creates a new list from the arguments (each a list item) passed in. + static of(...items) { + return appendAll(new this(), items); + } + + // Creates a new list from the given array-like object (each a list item) passed + // in. + static from(items) { + return appendAll(new this(), items); + } + + constructor(...items) { + appendAll(this, items); + this.idsToItems = {}; + this.invertedIndex = {}; + /** Note: this isn't an accurate count because of UTF encoding and other JS mumbo jumbo. */ + this.bytes = 0; + } + + // Returns the list's items as an array. + // This does *not* detach the items. + toArray() { + let item = this.head; + const result = []; + + while (item) { + result.push(item); + item = item.next; + } + + return result; + } + + // Prepends the given item to the list. + // `item` will be the new first item (`head`). + prepend(item) { + if (!item) { + return false; + } + + if (!item.append || !item.prepend || !item.detach) { + throw new Error( + 'An argument without append, prepend, or detach methods was given to `List#prepend`.', + ); + } + + if (this.head) { + return this.head.prepend(item); + } + + item.detach(); + item.list = this; + this.head = item; + this.length++; + + item._addToIndex(); + + return item; + } + + // Appends the given item to the list. + // `item` will be the new last item (`tail`) if the list had a first item, and + // its first item (`head`) otherwise. + append(item) { + if (!item) { + return false; + } + + if (!item.append || !item.prepend || !item.detach) { + throw new Error( + 'An argument without append, prepend, or detach methods was given to `List#append`.', + ); + } + + // If self has a last item, defer appending to the last items append method, + // and return the result. + if (this.tail) { + return this.tail.append(item); + } + + // If self has a first item, defer appending to the first items append method, + // and return the result. + if (this.head) { + return this.head.append(item); + } + + // ...otherwise, there is no `tail` or `head` item yet. + item.detach(); + item.list = this; + this.head = item; + this.length++; + + item._addToIndex(); + + return item; + } + + last() { + return this.tail || this.head; + } + + findById(id) { + return this.idsToItems[id]; + } + + findTextItem(text) { + const entries = this.invertedIndex[_hashText(text)]; + if (!entries) { + return null; + } + + for (let i = entries.length - 1; i >= 0; i--) { + const item = this.idsToItems[entries[i]]; + if (item.type === TYPE_TEXT && item.text === text) { + return item; + } + } + return null; + } + + // Creates an iterator from the list. + [Symbol.iterator]() { + return new Iterator(this.head); + } +}; + +LinkedList.prototype.length = 0; +LinkedList.prototype.tail = LinkedList.prototype.head = null; + +// Creates a new list from the items passed in. +function appendAll(list, items) { + let index; + let item; + let iterator; + + if (!items) { + return list; + } + + if (items[Symbol.iterator]) { + iterator = items[Symbol.iterator](); + item = {}; + + while (!item.done) { + item = iterator.next(); + list.append(item && item.value); + } + } else { + index = -1; + + while (++index < items.length) { + list.append(items[index]); + } + } + + return list; +} + +function _hashText(text) { + // The goal of this hash function is to be extremely fast while minimizing collisions. To do + // this, we make an assumption about our data. If users copy text, the guess is that there is + // a very low likelihood of collisions when the text is very long. For example, why would + // someone copy two different pieces of text that are exactly 29047 characters long? However, for + // smaller pieces of text, it's very easy to get length collisions. For example, I can copy "the" + // and "123" to cause a collision. Thus, our hash function returns the string length for longer + // strings while using an ok-ish hash for short strings. + + if (text.length > 500) { + return text.length; + } + + // Copied from https://stackoverflow.com/a/7616484/4548500 + let hash = 0; + for (let i = 0; i < text.length; i++) { + let chr = text.charCodeAt(i); + hash = (hash << 5) - hash + chr; + hash |= 0; // Convert to integer + } + return hash; +} diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/extension.js b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/extension.js new file mode 100644 index 0000000..64898b5 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/extension.js @@ -0,0 +1,1314 @@ +'use strict'; + +const { Clutter, Meta, Shell, St, GObject } = imports.gi; +const Mainloop = imports.mainloop; +const MessageTray = imports.ui.messageTray; + +const Main = imports.ui.main; +const PanelMenu = imports.ui.panelMenu; +const PopupMenu = imports.ui.popupMenu; + +const Gettext = imports.gettext; + +const Clipboard = St.Clipboard.get_default(); +const VirtualKeyboard = (() => { + let VirtualKeyboard; + return () => { + if (!VirtualKeyboard) { + VirtualKeyboard = Clutter.get_default_backend() + .get_default_seat() + .create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE); + } + return VirtualKeyboard; + }; +})(); + +const SETTING_KEY_CLEAR_HISTORY = 'clear-history'; +const SETTING_KEY_PREV_ENTRY = 'prev-entry'; +const SETTING_KEY_NEXT_ENTRY = 'next-entry'; +const SETTING_KEY_TOGGLE_MENU = 'toggle-menu'; +const SETTING_KEY_PRIVATE_MODE = 'toggle-private-mode'; +const INDICATOR_ICON = 'edit-paste-symbolic'; + +const PAGE_SIZE = 50; +const MAX_VISIBLE_CHARS = 200; + +const Util = imports.misc.util; +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const Store = Me.imports.store; +const DS = Me.imports.dataStructures; +const ConfirmDialog = Me.imports.confirmDialog; +const Prefs = Me.imports.prefs; + +const IndicatorName = `${Me.metadata.name} Indicator`; +const _ = Gettext.domain(Me.uuid).gettext; + +let MAX_REGISTRY_LENGTH; +let MAX_BYTES; +let WINDOW_WIDTH_PERCENTAGE; +let CACHE_ONLY_FAVORITES; +let MOVE_ITEM_FIRST; +let ENABLE_KEYBINDING; +let PRIVATE_MODE; +let NOTIFY_ON_COPY; +let CONFIRM_ON_CLEAR; +let MAX_TOPBAR_LENGTH; +let TOPBAR_DISPLAY_MODE; // 0 - only icon, 1 - only clipboard content, 2 - both, 3 - none +let DISABLE_DOWN_ARROW; +let STRIP_TEXT; +let PASTE_ON_SELECTION; +let PROCESS_PRIMARY_SELECTION; + +class ClipboardIndicator extends PanelMenu.Button { + _init() { + super._init(0, IndicatorName, false); + + this._shortcutsBindingIds = []; + + const hbox = new St.BoxLayout({ + style_class: 'panel-status-menu-box clipboard-indicator-hbox', + }); + this.icon = new St.Icon({ + icon_name: INDICATOR_ICON, + style_class: 'system-status-icon clipboard-indicator-icon', + }); + hbox.add_child(this.icon); + this._buttonText = new St.Label({ + text: '', + y_align: Clutter.ActorAlign.CENTER, + }); + hbox.add_child(this._buttonText); + this._downArrow = PopupMenu.arrowIcon(St.Side.BOTTOM); + hbox.add(this._downArrow); + this.add_child(hbox); + + this._fetchSettings(); + this._buildMenu(); + this._updateTopbarLayout(); + } + + destroy() { + this._disconnectSettings(); + this._unbindShortcuts(); + this._disconnectSelectionListener(); + + if (this._searchFocusHackCallbackId) { + Mainloop.source_remove(this._searchFocusHackCallbackId); + this._searchFocusHackCallbackId = undefined; + } + if (this._pasteHackCallbackId) { + Mainloop.source_remove(this._pasteHackCallbackId); + this._pasteHackCallbackId = undefined; + } + + super.destroy(); + } + + _buildMenu() { + this.searchEntry = new St.Entry({ + name: 'searchEntry', + style_class: 'search-entry ci-history-search-entry', + can_focus: true, + hint_text: _('Search clipboard history…'), + track_hover: true, + x_expand: true, + y_expand: true, + }); + + const entryItem = new PopupMenu.PopupBaseMenuItem({ + style_class: 'ci-history-search-section', + reactive: false, + can_focus: false, + }); + entryItem.add(this.searchEntry); + this.menu.addMenuItem(entryItem); + + this.menu.connect('open-state-changed', (self, open) => { + if (open) { + this._setMenuWidth(); + this.searchEntry.set_text(''); + this._searchFocusHackCallbackId = Mainloop.timeout_add(1, () => { + global.stage.set_key_focus(this.searchEntry); + this._searchFocusHackCallbackId = undefined; + return false; + }); + } + }); + + // Create menu sections for items + // Favorites + this.favoritesSection = new PopupMenu.PopupMenuSection(); + + this.scrollViewFavoritesMenuSection = new PopupMenu.PopupMenuSection(); + const favoritesScrollView = new St.ScrollView({ + style_class: 'ci-history-menu-section', + overlay_scrollbars: true, + }); + favoritesScrollView.add_actor(this.favoritesSection.actor); + + this.scrollViewFavoritesMenuSection.actor.add_actor(favoritesScrollView); + this.menu.addMenuItem(this.scrollViewFavoritesMenuSection); + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + + // History + this.historySection = new PopupMenu.PopupMenuSection(); + + this.scrollViewMenuSection = new PopupMenu.PopupMenuSection(); + this.historyScrollView = new St.ScrollView({ + style_class: 'ci-history-menu-section', + overlay_scrollbars: true, + }); + this.historyScrollView.add_actor(this.historySection.actor); + + this.scrollViewMenuSection.actor.add_actor(this.historyScrollView); + + this.menu.addMenuItem(this.scrollViewMenuSection); + + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + + const actionsSection = new PopupMenu.PopupMenuSection(); + const actionsBox = new St.BoxLayout({ + style_class: 'ci-history-actions-section', + vertical: false, + }); + + actionsSection.actor.add(actionsBox); + this.menu.addMenuItem(actionsSection); + + const prevPage = new PopupMenu.PopupBaseMenuItem(); + prevPage.add_child( + new St.Icon({ + icon_name: 'go-previous-symbolic', + style_class: 'popup-menu-icon', + }), + ); + prevPage.connect('activate', this._navigatePrevPage.bind(this)); + actionsBox.add(prevPage); + + const nextPage = new PopupMenu.PopupBaseMenuItem(); + nextPage.add_child( + new St.Icon({ + icon_name: 'go-next-symbolic', + style_class: 'popup-menu-icon', + }), + ); + nextPage.connect('activate', this._navigateNextPage.bind(this)); + actionsBox.add(nextPage); + + actionsBox.add(new St.BoxLayout({ x_expand: true })); + + this.privateModeMenuItem = new PopupMenu.PopupSwitchMenuItem( + _('Private mode'), + PRIVATE_MODE, + { reactive: true }, + ); + this.privateModeMenuItem.connect('toggled', () => { + Prefs.Settings.set_boolean( + Prefs.Fields.PRIVATE_MODE, + this.privateModeMenuItem.state, + ); + }); + actionsBox.add(this.privateModeMenuItem); + this._updatePrivateModeState(); + + const clearMenuItem = new PopupMenu.PopupBaseMenuItem(); + clearMenuItem.add_child( + new St.Icon({ + icon_name: 'edit-delete-symbolic', + style_class: 'popup-menu-icon', + }), + ); + actionsBox.add(clearMenuItem); + + const settingsMenuItem = new PopupMenu.PopupBaseMenuItem(); + settingsMenuItem.add_child( + new St.Icon({ + icon_name: 'emblem-system-symbolic', + style_class: 'popup-menu-icon', + }), + ); + settingsMenuItem.connect('activate', this._openSettings.bind(this)); + actionsBox.add(settingsMenuItem); + + if (ENABLE_KEYBINDING) { + this._bindShortcuts(); + } + this.menu.actor.connect('key-press-event', (_, event) => + this._handleGlobalKeyEvent(event), + ); + + Store.buildClipboardStateFromLog( + (entries, favoriteEntries, nextId, nextDiskId) => { + /** + * This field stores the number of items in the historySection to avoid calling _getMenuItems + * since that method is slow. + */ + this.activeHistoryMenuItems = 0; + /** + * These two IDs are extremely important: making a mistake with either one breaks the + * extension. Both IDs are globally unique within compaction intervals. The normal ID is + * *always* present and valid -- it allows us to build an inverted index so we can find + * previously copied items in O(1) time. The Disk ID is only present when we cache all + * entries. This additional complexity is needed to know what the ID of an item is on disk as + * compared to in memory when we're only caching favorites. + */ + this.nextId = nextId; + this.nextDiskId = nextDiskId || nextId; + /** + * DS.LinkedList is the actual clipboard history and source of truth. Never use historySection + * or favoritesSection as the source of truth as these may get outdated during pagination. + * + * Entries *may* have a menuItem attached, meaning they are currently visible. On the other + * hand, menu items must always have an entry attached. + */ + this.entries = entries; + this.favoriteEntries = favoriteEntries; + + this.currentlySelectedEntry = entries.last(); + this._restoreFavoritedEntries(); + this._maybeRestoreMenuPages(); + + this._settingsChangedId = Prefs.Settings.connect( + 'changed', + this._onSettingsChange.bind(this), + ); + + this.searchEntry + .get_clutter_text() + .connect('text-changed', this._onSearchTextChanged.bind(this)); + clearMenuItem.connect('activate', this._removeAll.bind(this)); + + this._setupSelectionChangeListener(); + }, + ); + } + + _setMenuWidth() { + const display = global.display; + const screen_width = display.get_monitor_geometry( + display.get_primary_monitor(), + ).width; + + this.menu.actor.width = screen_width * (WINDOW_WIDTH_PERCENTAGE / 100); + } + + _handleGlobalKeyEvent(event) { + this._handleCtrlSelectKeyEvent(event); + this._handleSettingsKeyEvent(event); + this._handleNavigationKeyEvent(event); + this._handleFocusSearchKeyEvent(event); + } + + _handleCtrlSelectKeyEvent(event) { + if (!event.has_control_modifier()) { + return; + } + + const index = parseInt(event.get_key_unicode()); // Starts at 1 + if (isNaN(index) || index <= 0) { + return; + } + + const items = + event.get_state() === 68 // Ctrl + Super + ? this.favoritesSection._getMenuItems() + : this.historySection._getMenuItems(); + if (index > items.length) { + return; + } + + this._onMenuItemSelectedAndMenuClose(items[index - 1]); + } + + _handleSettingsKeyEvent(event) { + if (event.get_state() !== 12 || event.get_key_unicode() !== 's') { + return; + } + + this._openSettings(); + } + + _handleNavigationKeyEvent(event) { + if (!event.has_control_modifier()) { + return; + } + + if (event.get_key_unicode() === 'n') { + this._navigateNextPage(); + } else if (event.get_key_unicode() === 'p') { + this._navigatePrevPage(); + } + } + + _handleFocusSearchKeyEvent(event) { + if (event.get_key_unicode() !== '/') { + return; + } + + global.stage.set_key_focus(this.searchEntry); + } + + _addEntry(entry, selectEntry, updateClipboard, insertIndex) { + if (!entry.favorite && this.activeHistoryMenuItems >= PAGE_SIZE) { + const items = this.historySection._getMenuItems(); + const item = items[items.length - 1]; + this._rewriteMenuItem(item, entry); + this.historySection.moveMenuItem(item, 0); + + if (selectEntry) { + this._selectEntry(entry, updateClipboard); + } + return; + } + + const menuItem = new PopupMenu.PopupMenuItem('', { hover: false }); + + menuItem.entry = entry; + entry.menuItem = menuItem; + + menuItem.connect( + 'activate', + this._onMenuItemSelectedAndMenuClose.bind(this), + ); + menuItem.connect('key-press-event', (_, event) => + this._handleMenuItemKeyEvent(event, menuItem), + ); + + this._setEntryLabel(menuItem); + + // Favorite button + const icon_name = entry.favorite + ? 'starred-symbolic' + : 'non-starred-symbolic'; + const iconfav = new St.Icon({ + icon_name: icon_name, + style_class: 'system-status-icon', + }); + + const icofavBtn = new St.Button({ + style_class: 'ci-action-btn', + can_focus: true, + child: iconfav, + x_align: Clutter.ActorAlign.END, + x_expand: true, + y_expand: true, + }); + + menuItem.actor.add_child(icofavBtn); + icofavBtn.connect('clicked', () => { + this._favoriteToggle(menuItem); + }); + + // Delete button + const icon = new St.Icon({ + icon_name: 'edit-delete-symbolic', + style_class: 'system-status-icon', + }); + + const icoBtn = new St.Button({ + style_class: 'ci-action-btn', + can_focus: true, + child: icon, + x_align: Clutter.ActorAlign.END, + x_expand: false, + y_expand: true, + }); + + menuItem.actor.add_child(icoBtn); + icoBtn.connect('clicked', () => { + this._deleteEntryAndRestoreLatest(menuItem.entry); + }); + + menuItem.connect('destroy', () => { + delete menuItem.entry.menuItem; + if (!menuItem.entry.favorite) { + this.activeHistoryMenuItems--; + } + }); + menuItem.connect('key-focus-in', () => { + if (!menuItem.entry.favorite) { + Util.ensureActorVisibleInScrollView(this.historyScrollView, menuItem); + } + }); + + if (entry.favorite) { + this.favoritesSection.addMenuItem(menuItem, insertIndex); + } else { + this.historySection.addMenuItem(menuItem, insertIndex); + + this.activeHistoryMenuItems++; + } + + if (selectEntry) { + this._selectEntry(entry, updateClipboard); + } + } + + _handleMenuItemKeyEvent(event, menuItem) { + if (event.get_key_unicode() === 'f') { + this._favoriteToggle(menuItem); + } + if (event.get_key_code() === 119) { + const next = menuItem.entry.prev || menuItem.entry.next; + if (next?.menuItem) { + global.stage.set_key_focus(next.menuItem); + } + this._deleteEntryAndRestoreLatest(menuItem.entry); + } + } + + _updateButtonText(entry) { + if ( + !(TOPBAR_DISPLAY_MODE === 1 || TOPBAR_DISPLAY_MODE === 2) || + (entry && entry.type !== DS.TYPE_TEXT) + ) { + return; + } + + if (PRIVATE_MODE) { + this._buttonText.set_text('…'); + } else if (entry) { + this._buttonText.set_text(this._truncated(entry.text, MAX_TOPBAR_LENGTH)); + } else { + this._buttonText.set_text(''); + } + } + + _setEntryLabel(menuItem) { + const entry = menuItem.entry; + if (entry.type === DS.TYPE_TEXT) { + menuItem.label.set_text(this._truncated(entry.text, MAX_VISIBLE_CHARS)); + } else { + throw new TypeError('Unknown type: ' + entry.type); + } + } + + _favoriteToggle(menuItem) { + const entry = menuItem.entry; + const wasSelected = this.currentlySelectedEntry?.id === entry.id; + + // Move to front (end of list) + (entry.favorite ? this.entries : this.favoriteEntries).append(entry); + this._removeEntry(entry); + entry.favorite = !entry.favorite; + this._addEntry(entry, wasSelected, false, 0); + this._maybeRestoreMenuPages(); + global.stage.set_key_focus(entry.menuItem); + + if (CACHE_ONLY_FAVORITES && !entry.favorite) { + if (entry.diskId) { + Store.deleteTextEntry(entry.diskId, true); + delete entry.diskId; + } + return; + } + + if (entry.diskId) { + Store.updateFavoriteStatus(entry.diskId, entry.favorite); + } else { + entry.diskId = this.nextDiskId++; + + Store.storeTextEntry(entry.text); + Store.updateFavoriteStatus(entry.diskId, true); + } + } + + _removeAll() { + if (CONFIRM_ON_CLEAR) { + this._confirmRemoveAll(); + } else { + this._clearHistory(); + } + } + + _confirmRemoveAll() { + const title = _('Clear all?'); + const message = _('Are you sure you want to delete all clipboard items?'); + const sub_message = _('This operation cannot be undone.'); + + ConfirmDialog.openConfirmDialog( + title, + message, + sub_message, + _('Clear'), + _('Cancel'), + () => { + this._clearHistory(); + }, + ); + } + + _clearHistory() { + if (this.currentlySelectedEntry && !this.currentlySelectedEntry.favorite) { + this._resetSelectedMenuItem(true); + } + + // Favorites aren't touched when clearing history + this.entries = new DS.LinkedList(); + this.historySection.removeAll(); + + Store.resetDatabase(this._currentStateBuilder.bind(this)); + } + + _removeEntry(entry, fullyDelete, humanGenerated) { + if (fullyDelete) { + entry.detach(); + + if (entry.diskId) { + Store.deleteTextEntry(entry.diskId, entry.favorite); + } + } + + if (entry.id === this.currentlySelectedEntry?.id) { + this._resetSelectedMenuItem(humanGenerated); + } + entry.menuItem?.destroy(); + if (fullyDelete) { + this._maybeRestoreMenuPages(); + } + } + + _pruneOldestEntries() { + let entry = this.entries.head; + while ( + entry && + (this.entries.length > MAX_REGISTRY_LENGTH || + this.entries.bytes > MAX_BYTES) + ) { + const next = entry.next; + this._removeEntry(entry, true); + entry = next; + } + + Store.maybePerformLogCompaction(this._currentStateBuilder.bind(this)); + } + + _selectEntry(entry, updateClipboard, triggerPaste) { + this.currentlySelectedEntry?.menuItem?.setOrnament(PopupMenu.Ornament.NONE); + this.currentlySelectedEntry = entry; + + entry.menuItem?.setOrnament(PopupMenu.Ornament.DOT); + this._updateButtonText(entry); + if (updateClipboard !== false) { + if (entry.type === DS.TYPE_TEXT) { + this._setClipboardText(entry.text); + } else { + throw new TypeError('Unknown type: ' + entry.type); + } + + if (PASTE_ON_SELECTION && triggerPaste) { + this._triggerPasteHack(); + } + } + } + + _setClipboardText(text) { + if (this._debouncing !== undefined) { + this._debouncing++; + } + + Clipboard.set_text(St.ClipboardType.CLIPBOARD, text); + Clipboard.set_text(St.ClipboardType.PRIMARY, text); + } + + _triggerPasteHack() { + this._pasteHackCallbackId = Mainloop.timeout_add( + 1, // Just post to the end of the event loop + () => { + const eventTime = Clutter.get_current_event_time() * 1000; + VirtualKeyboard().notify_keyval( + eventTime, + Clutter.KEY_Shift_L, + Clutter.KeyState.PRESSED, + ); + VirtualKeyboard().notify_keyval( + eventTime, + Clutter.KEY_Insert, + Clutter.KeyState.PRESSED, + ); + VirtualKeyboard().notify_keyval( + eventTime, + Clutter.KEY_Insert, + Clutter.KeyState.RELEASED, + ); + VirtualKeyboard().notify_keyval( + eventTime, + Clutter.KEY_Shift_L, + Clutter.KeyState.RELEASED, + ); + + this._pasteHackCallbackId = undefined; + return false; + }, + ); + } + + _onMenuItemSelectedAndMenuClose(menuItem) { + this._moveEntryFirst(menuItem.entry); + this._selectEntry(menuItem.entry, true, true); + this.menu.close(); + } + + _resetSelectedMenuItem(resetClipboard) { + this.currentlySelectedEntry = undefined; + this._updateButtonText(); + if (resetClipboard) { + this._setClipboardText(''); + } + } + + _restoreFavoritedEntries() { + for (let entry = this.favoriteEntries.last(); entry; entry = entry.prev) { + this._addEntry(entry); + } + } + + _maybeRestoreMenuPages() { + if (this.activeHistoryMenuItems > 0) { + return; + } + + for ( + let entry = this.entries.last(); + entry && this.activeHistoryMenuItems < PAGE_SIZE; + entry = entry.prev + ) { + this._addEntry(entry, this.currentlySelectedEntry === entry); + } + } + + /** + * Our pagination implementation is purposefully "broken." The idea is simply to do no unnecessary + * work. As a consequence, if a user navigates to some page and then starts copying/moving items, + * those items will appear on the currently visible page even though they don't belong there. This + * could kind of be considered a feature since it means you can go back to some cluster of copied + * items and start copying stuff from the same cluster and have it all show up together. + * + * Note that over time (as the user copies items), the page reclamation process will morph the + * current page into the first page. This is the only way to make the user-visible state match our + * backing store after changing pages. + * + * Also note that the use of `last` and `next` is correct. Menu items are ordered from latest to + * oldest whereas `entries` is ordered from oldest to latest. + */ + _navigatePrevPage() { + if (this.searchEntryFront) { + this.populateSearchResults(this.searchEntry.get_text(), false); + return; + } + + const items = this.historySection._getMenuItems(); + if (items.length === 0) { + return; + } + + const start = items[0].entry; + for ( + let entry = start.nextCyclic(), i = items.length - 1; + entry !== start && i >= 0; + entry = entry.nextCyclic() + ) { + this._rewriteMenuItem(items[i--], entry); + } + } + + _navigateNextPage() { + if (this.searchEntryFront) { + this.populateSearchResults(this.searchEntry.get_text(), true); + return; + } + + const items = this.historySection._getMenuItems(); + if (items.length === 0) { + return; + } + + const start = items[items.length - 1].entry; + for ( + let entry = start.prevCyclic(), i = 0; + entry !== start && i < items.length; + entry = entry.prevCyclic() + ) { + this._rewriteMenuItem(items[i++], entry); + } + } + + _rewriteMenuItem(item, entry) { + if (item.entry.id === this.currentlySelectedEntry?.id) { + item.setOrnament(PopupMenu.Ornament.NONE); + } + + item.entry = entry; + entry.menuItem = item; + + this._setEntryLabel(item); + if (entry.id === this.currentlySelectedEntry?.id) { + item.setOrnament(PopupMenu.Ornament.DOT); + } + } + + _onSearchTextChanged() { + const query = this.searchEntry.get_text(); + + if (!query) { + this.historySection.removeAll(); + this.favoritesSection.removeAll(); + + this.searchEntryFront = this.searchEntryBack = undefined; + this._restoreFavoritedEntries(); + this._maybeRestoreMenuPages(); + return; + } + + this.searchEntryFront = this.searchEntryBack = this.entries.last(); + this.populateSearchResults(query); + } + + populateSearchResults(query, forward) { + if (!this.searchEntryFront) { + return; + } + + this.historySection.removeAll(); + this.favoritesSection.removeAll(); + + if (typeof forward !== 'boolean') { + forward = true; + } + + query = query.toLowerCase(); + let searchExp; + try { + searchExp = new RegExp(query, 'i'); + } catch {} + const start = forward ? this.searchEntryFront : this.searchEntryBack; + let entry = start; + + while (this.activeHistoryMenuItems < PAGE_SIZE) { + if (entry.type === DS.TYPE_TEXT) { + let match = entry.text.toLowerCase().indexOf(query); + if (searchExp && match < 0) { + match = entry.text.search(searchExp); + } + if (match >= 0) { + this._addEntry( + entry, + entry === this.currentlySelectedEntry, + false, + forward ? undefined : 0, + ); + entry.menuItem.label.set_text( + this._truncated( + entry.text, + match - 40, + match + MAX_VISIBLE_CHARS - 40, + ), + ); + } + } else { + throw new TypeError('Unknown type: ' + entry.type); + } + + entry = forward ? entry.prevCyclic() : entry.nextCyclic(); + if (entry === start) { + break; + } + } + + if (forward) { + this.searchEntryBack = this.searchEntryFront.nextCyclic(); + this.searchEntryFront = entry; + } else { + this.searchEntryFront = this.searchEntryBack.prevCyclic(); + this.searchEntryBack = entry; + } + } + + _queryClipboard() { + if (PRIVATE_MODE) { + return; + } + + Clipboard.get_text(St.ClipboardType.CLIPBOARD, (_, text) => { + this._processClipboardContent(text, true); + }); + } + + _queryPrimaryClipboard() { + if (PRIVATE_MODE) { + return; + } + + Clipboard.get_text(St.ClipboardType.PRIMARY, (_, text) => { + const last = this.entries.last(); + text = this._processClipboardContent(text, false); + if ( + last && + text && + text.length !== last.text.length && + (text.endsWith(last.text) || + text.startsWith(last.text) || + last.text.endsWith(text) || + last.text.startsWith(text)) + ) { + this._removeEntry(last, true); + } + }); + } + + _processClipboardContent(text, selectEntry) { + if (this._debouncing > 0) { + this._debouncing--; + return; + } + + if (STRIP_TEXT && text) { + text = text.trim(); + } + if (!text) { + return; + } + + let entry = + this.entries.findTextItem(text) || + this.favoriteEntries.findTextItem(text); + if (entry) { + const isFirst = + entry === this.entries.last() || entry === this.favoriteEntries.last(); + if (!isFirst) { + this._moveEntryFirst(entry); + } + if (selectEntry && (!isFirst || entry !== this.currentlySelectedEntry)) { + this._selectEntry(entry, false); + } + } else { + entry = new DS.LLNode(); + entry.id = this.nextId++; + entry.diskId = CACHE_ONLY_FAVORITES ? undefined : this.nextDiskId++; + entry.type = DS.TYPE_TEXT; + entry.text = text; + entry.favorite = false; + this.entries.append(entry); + this._addEntry(entry, selectEntry, false, 0); + + if (!CACHE_ONLY_FAVORITES) { + Store.storeTextEntry(text); + } + this._pruneOldestEntries(); + } + + if (NOTIFY_ON_COPY) { + this._showNotification(_('Copied to clipboard'), null, (notif) => { + notif.addAction(_('Cancel'), () => + this._deleteEntryAndRestoreLatest(this.currentlySelectedEntry), + ); + }); + } + + return text; + } + + _moveEntryFirst(entry) { + if (!MOVE_ITEM_FIRST) { + return; + } + + let menu; + let entries; + if (entry.favorite) { + menu = this.favoritesSection; + entries = this.favoriteEntries; + } else { + menu = this.historySection; + entries = this.entries; + } + + if (entry.menuItem) { + menu.moveMenuItem(entry.menuItem, 0); + } else { + this._addEntry(entry, false, false, 0); + } + + entries.append(entry); + if (entry.diskId) { + Store.moveEntryToEnd(entry.diskId); + } + } + + _currentStateBuilder() { + const state = []; + + this.nextDiskId = 1; + for (const entry of this.favoriteEntries) { + entry.diskId = this.nextDiskId++; + state.push(entry); + } + for (const entry of this.entries) { + if (CACHE_ONLY_FAVORITES) { + delete entry.diskId; + } else { + entry.diskId = this.nextDiskId++; + state.push(entry); + } + } + + return state; + } + + _setupSelectionChangeListener() { + this._debouncing = 0; + + this.selection = Shell.Global.get().get_display().get_selection(); + this._selectionOwnerChangedId = this.selection.connect( + 'owner-changed', + (_, selectionType) => { + if (selectionType === Meta.SelectionType.SELECTION_CLIPBOARD) { + this._queryClipboard(); + } else if ( + PROCESS_PRIMARY_SELECTION && + selectionType === Meta.SelectionType.SELECTION_PRIMARY + ) { + this._queryPrimaryClipboard(); + } + }, + ); + } + + _disconnectSelectionListener() { + if (!this._selectionOwnerChangedId) { + return; + } + + this.selection.disconnect(this._selectionOwnerChangedId); + this.selection = undefined; + this._selectionOwnerChangedId = undefined; + } + + _deleteEntryAndRestoreLatest(entry) { + this._removeEntry(entry, true, true); + + if (!this.currentlySelectedEntry) { + const nextEntry = this.entries.last(); + if (nextEntry) { + this._selectEntry(nextEntry, true); + } + } + } + + _initNotifSource() { + if (this._notifSource) { + return; + } + + this._notifSource = new MessageTray.Source(Me.uuid, INDICATOR_ICON); + this._notifSource.connect('destroy', () => { + this._notifSource = undefined; + }); + Main.messageTray.add(this._notifSource); + } + + _showNotification(title, message, transformFn) { + const dndOn = () => + !Main.panel.statusArea.dateMenu._indicator._settings.get_boolean( + 'show-banners', + ); + if (PRIVATE_MODE || dndOn()) { + return; + } + + this._initNotifSource(); + + let notification; + if (this._notifSource.count === 0) { + notification = new MessageTray.Notification( + this._notifSource, + title, + message, + ); + } else { + notification = this._notifSource.notifications[0]; + notification.update(title, message, { clear: true }); + } + + if (typeof transformFn === 'function') { + transformFn(notification); + } + + notification.setTransient(true); + this._notifSource.showNotification(notification); + } + + _updatePrivateModeState() { + // We hide the history in private mode because it will be out of sync + // (selected item will not reflect clipboard) + this.scrollViewMenuSection.actor.visible = !PRIVATE_MODE; + this.scrollViewFavoritesMenuSection.actor.visible = !PRIVATE_MODE; + + if (PRIVATE_MODE) { + this.icon.add_style_class_name('private-mode'); + this._updateButtonText(); + } else { + this.icon.remove_style_class_name('private-mode'); + if (this.currentlySelectedEntry) { + this._selectEntry(this.currentlySelectedEntry, true); + } else { + this._resetSelectedMenuItem(true); + } + } + } + + _fetchSettings() { + MAX_REGISTRY_LENGTH = Prefs.Settings.get_int(Prefs.Fields.HISTORY_SIZE); + MAX_BYTES = + (1 << 20) * Prefs.Settings.get_int(Prefs.Fields.CACHE_FILE_SIZE); + WINDOW_WIDTH_PERCENTAGE = Prefs.Settings.get_int( + Prefs.Fields.WINDOW_WIDTH_PERCENTAGE, + ); + CACHE_ONLY_FAVORITES = Prefs.Settings.get_boolean( + Prefs.Fields.CACHE_ONLY_FAVORITES, + ); + MOVE_ITEM_FIRST = Prefs.Settings.get_boolean(Prefs.Fields.MOVE_ITEM_FIRST); + NOTIFY_ON_COPY = Prefs.Settings.get_boolean(Prefs.Fields.NOTIFY_ON_COPY); + CONFIRM_ON_CLEAR = Prefs.Settings.get_boolean( + Prefs.Fields.CONFIRM_ON_CLEAR, + ); + ENABLE_KEYBINDING = Prefs.Settings.get_boolean( + Prefs.Fields.ENABLE_KEYBINDING, + ); + MAX_TOPBAR_LENGTH = Prefs.Settings.get_int( + Prefs.Fields.TOPBAR_PREVIEW_SIZE, + ); + TOPBAR_DISPLAY_MODE = Prefs.Settings.get_int( + Prefs.Fields.TOPBAR_DISPLAY_MODE_ID, + ); + DISABLE_DOWN_ARROW = Prefs.Settings.get_boolean( + Prefs.Fields.DISABLE_DOWN_ARROW, + ); + STRIP_TEXT = Prefs.Settings.get_boolean(Prefs.Fields.STRIP_TEXT); + PRIVATE_MODE = Prefs.Settings.get_boolean(Prefs.Fields.PRIVATE_MODE); + PASTE_ON_SELECTION = Prefs.Settings.get_boolean( + Prefs.Fields.PASTE_ON_SELECTION, + ); + PROCESS_PRIMARY_SELECTION = Prefs.Settings.get_boolean( + Prefs.Fields.PROCESS_PRIMARY_SELECTION, + ); + } + + _onSettingsChange() { + const prevCacheOnlyFavorites = CACHE_ONLY_FAVORITES; + const prevPrivateMode = PRIVATE_MODE; + + this._fetchSettings(); + + if ( + prevCacheOnlyFavorites !== undefined && + CACHE_ONLY_FAVORITES !== prevCacheOnlyFavorites + ) { + if (CACHE_ONLY_FAVORITES) { + Store.resetDatabase(this._currentStateBuilder.bind(this)); + } else { + for (const entry of this.entries) { + entry.diskId = this.nextDiskId++; + Store.storeTextEntry(entry.text); + } + } + } + + if (prevPrivateMode !== undefined && PRIVATE_MODE !== prevPrivateMode) { + this._updatePrivateModeState(); + } + + // Remove old entries in case the registry size changed + this._pruneOldestEntries(); + + // Re-set menu-items labels in case preview size changed + const resetLabel = (item) => this._setEntryLabel(item); + this.favoritesSection._getMenuItems().forEach(resetLabel); + this.historySection._getMenuItems().forEach(resetLabel); + + this._updateTopbarLayout(); + if (this.currentlySelectedEntry) { + this._updateButtonText(this.currentlySelectedEntry); + } + this._setMenuWidth(); + + if (ENABLE_KEYBINDING) { + this._bindShortcuts(); + } else { + this._unbindShortcuts(); + } + } + + _bindShortcuts() { + this._unbindShortcuts(); + this._bindShortcut(SETTING_KEY_CLEAR_HISTORY, () => { + if (this.entries) { + this._removeAll(); + } + }); + this._bindShortcut(SETTING_KEY_PREV_ENTRY, () => { + if (this.entries) { + this._previousEntry(); + } + }); + this._bindShortcut(SETTING_KEY_NEXT_ENTRY, () => { + if (this.entries) { + this._nextEntry(); + } + }); + this._bindShortcut(SETTING_KEY_TOGGLE_MENU, () => this.menu.toggle()); + this._bindShortcut(SETTING_KEY_PRIVATE_MODE, () => + this.privateModeMenuItem.toggle(), + ); + } + + _unbindShortcuts() { + this._shortcutsBindingIds.forEach((id) => Main.wm.removeKeybinding(id)); + + this._shortcutsBindingIds = []; + } + + _bindShortcut(name, cb) { + const ModeType = Shell.hasOwnProperty('ActionMode') + ? Shell.ActionMode + : Shell.KeyBindingMode; + + Main.wm.addKeybinding( + name, + Prefs.Settings, + Meta.KeyBindingFlags.NONE, + ModeType.ALL, + cb.bind(this), + ); + + this._shortcutsBindingIds.push(name); + } + + _updateTopbarLayout() { + if (TOPBAR_DISPLAY_MODE === 3) { + this.icon.visible = false; + this._buttonText.visible = false; + + this._style_class = this.style_class; + this.style_class = ''; + } else if (this._style_class) { + this.style_class = this._style_class; + } + + if (TOPBAR_DISPLAY_MODE === 0) { + this.icon.visible = true; + this._buttonText.visible = false; + } + if (TOPBAR_DISPLAY_MODE === 1) { + this.icon.visible = false; + this._buttonText.visible = true; + } + if (TOPBAR_DISPLAY_MODE === 2) { + this.icon.visible = true; + this._buttonText.visible = true; + } + this._downArrow.visible = !DISABLE_DOWN_ARROW; + } + + _disconnectSettings() { + if (!this._settingsChangedId) { + return; + } + + Prefs.Settings.disconnect(this._settingsChangedId); + this._settingsChangedId = undefined; + } + + _openSettings() { + ExtensionUtils.openPrefs(); + this.menu.close(); + } + + _previousEntry() { + this._selectNextPrevEntry( + this.currentlySelectedEntry.nextCyclic() || this.entries.head, + ); + } + + _nextEntry() { + this._selectNextPrevEntry( + this.currentlySelectedEntry.prevCyclic() || this.entries.last(), + ); + } + + _selectNextPrevEntry(entry) { + if (!entry) { + return; + } + + this._selectEntry(entry, true); + if (entry.type === DS.TYPE_TEXT) { + this._showNotification(_('Copied'), entry.text); + } + } + + _truncated(s, start, end) { + if (start < 0) { + start = 0; + } + if (!end) { + end = start; + start = 0; + } + if (end > s.length) { + end = s.length; + } + + const includesStart = start === 0; + const includesEnd = end === s.length; + const isMiddle = !includesStart && !includesEnd; + const length = end - start; + const overflow = s.length > length; + + // Reduce regex search space. If the string is mostly whitespace, + // we might end up removing too many characters, but oh well. + s = s.substring(start, end + 100); + + // Remove new lines and extra spaces so the text fits nicely on one line + s = s.replace(/\s+/g, ' ').trim(); + + if (includesStart && overflow) { + s = s.substring(0, length - 1) + '…'; + } + if (includesEnd && overflow) { + s = '…' + s.substring(1, length); + } + if (isMiddle) { + s = '…' + s.substring(1, length - 1) + '…'; + } + + return s; + } +} + +const ClipboardIndicatorObj = GObject.registerClass(ClipboardIndicator); + +function init() { + ExtensionUtils.initTranslations(Me.uuid); +} + +let clipboardIndicator; + +function enable() { + if (clipboardIndicator) { + return; + } + + Store.init(); + + clipboardIndicator = new ClipboardIndicatorObj(); + Main.panel.addToStatusArea(IndicatorName, clipboardIndicator, 1); +} + +function disable() { + clipboardIndicator.destroy(); + clipboardIndicator = undefined; + + Store.destroy(); +} diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ar/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ar/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..75db88b Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ar/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ca/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ca/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..c1e42c2 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ca/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/cs/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/cs/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..0849a18 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/cs/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/de/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/de/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..c79031f Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/de/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/el/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/el/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..9ef3647 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/el/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/es/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/es/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..b052702 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/es/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/eu/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/eu/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..c6d0697 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/eu/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fa/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fa/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..6c6f242 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fa/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fi/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fi/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..61be0a9 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fi/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fr/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fr/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..5975d31 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fr/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fr_FR/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fr_FR/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..05e04a7 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/fr_FR/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/hu/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/hu/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..8aaedc7 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/hu/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/it/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/it/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..50712b8 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/it/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ja/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ja/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..e78cac6 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ja/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/nl/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/nl/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..f80e11b Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/nl/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/oc/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/oc/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..29f8476 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/oc/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/pl/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/pl/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..d0efc79 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/pl/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/pt_BR/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/pt_BR/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..b1e6f99 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/pt_BR/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ru/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ru/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..8c4c350 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/ru/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/sk/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/sk/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..c351ec2 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/sk/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/tr/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/tr/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..af82a06 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/tr/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/uk/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/uk/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..25a2c41 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/uk/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/zh_CN/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/zh_CN/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo new file mode 100644 index 0000000..ee405d9 Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/locale/zh_CN/LC_MESSAGES/clipboard-history@alexsaveau.dev.mo differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/metadata.json b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/metadata.json new file mode 100644 index 0000000..6b286fd --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/metadata.json @@ -0,0 +1,15 @@ +{ + "_generated": "Generated by SweetTooth, do not edit", + "description": "Gnome Clipboard History is a Gnome extension that saves items you've copied into an easily accessible, searchable history panel.", + "name": "Clipboard History", + "shell-version": [ + "40", + "41", + "42", + "43", + "44" + ], + "url": "https://github.com/SUPERCILEX/gnome-clipboard-history", + "uuid": "clipboard-history@alexsaveau.dev", + "version": 32 +} \ No newline at end of file diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/prefs.js b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/prefs.js new file mode 100644 index 0000000..a611a60 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/prefs.js @@ -0,0 +1,446 @@ +'use strict'; + +const { GObject, Gtk, Gio } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); + +const Gettext = imports.gettext; +const _ = Gettext.domain(Me.uuid).gettext; + +var Fields = { + HISTORY_SIZE: 'history-size', + WINDOW_WIDTH_PERCENTAGE: 'window-width-percentage', + CACHE_FILE_SIZE: 'cache-size', + CACHE_ONLY_FAVORITES: 'cache-only-favorites', + NOTIFY_ON_COPY: 'notify-on-copy', + CONFIRM_ON_CLEAR: 'confirm-clear', + MOVE_ITEM_FIRST: 'move-item-first', + ENABLE_KEYBINDING: 'enable-keybindings', + TOPBAR_PREVIEW_SIZE: 'topbar-preview-size', + TOPBAR_DISPLAY_MODE_ID: 'display-mode', + DISABLE_DOWN_ARROW: 'disable-down-arrow', + STRIP_TEXT: 'strip-text', + PRIVATE_MODE: 'private-mode', + PASTE_ON_SELECTION: 'paste-on-selection', + PROCESS_PRIMARY_SELECTION: 'process-primary-selection', +}; + +const SCHEMA_NAME = 'org.gnome.shell.extensions.clipboard-history'; +var Settings = ExtensionUtils.getSettings(SCHEMA_NAME); + +function init() { + ExtensionUtils.initTranslations(Me.uuid); +} + +class Prefs extends GObject.Object { + _init() { + this.main = new Gtk.Grid({ + margin_top: 10, + margin_bottom: 10, + margin_start: 10, + margin_end: 10, + row_spacing: 12, + column_spacing: 18, + column_homogeneous: false, + row_homogeneous: false, + }); + this.field_size = new Gtk.SpinButton({ + adjustment: new Gtk.Adjustment({ + lower: 1, + upper: 100_000, + step_increment: 100, + }), + }); + this.window_width_percentage = new Gtk.SpinButton({ + adjustment: new Gtk.Adjustment({ + lower: 0, + upper: 100, + step_increment: 5, + }), + }); + this.field_cache_size = new Gtk.SpinButton({ + adjustment: new Gtk.Adjustment({ + lower: 1, + upper: 1024, + step_increment: 5, + }), + }); + this.field_topbar_preview_size = new Gtk.SpinButton({ + adjustment: new Gtk.Adjustment({ + lower: 1, + upper: 100, + step_increment: 10, + }), + }); + this.field_display_mode = new Gtk.ComboBox({ + model: this._create_display_mode_options(), + }); + + let rendererText = new Gtk.CellRendererText(); + this.field_display_mode.pack_start(rendererText, false); + this.field_display_mode.add_attribute(rendererText, 'text', 0); + this.field_disable_down_arrow = new Gtk.Switch(); + this.field_cache_disable = new Gtk.Switch(); + this.field_notification_toggle = new Gtk.Switch(); + this.field_confirm_clear_toggle = new Gtk.Switch(); + this.field_strip_text = new Gtk.Switch(); + this.field_paste_on_selection = new Gtk.Switch(); + this.field_process_primary_selection = new Gtk.Switch(); + this.field_move_item_first = new Gtk.Switch(); + this.field_keybinding = createKeybindingWidget(Settings); + addKeybinding( + this.field_keybinding.model, + Settings, + 'toggle-menu', + _('Toggle the menu'), + ); + addKeybinding( + this.field_keybinding.model, + Settings, + 'clear-history', + _('Clear history'), + ); + addKeybinding( + this.field_keybinding.model, + Settings, + 'prev-entry', + _('Previous entry'), + ); + addKeybinding( + this.field_keybinding.model, + Settings, + 'next-entry', + _('Next entry'), + ); + addKeybinding( + this.field_keybinding.model, + Settings, + 'toggle-private-mode', + _('Toggle private mode'), + ); + + this.field_keybinding_activation = new Gtk.Switch(); + this.field_keybinding_activation.connect('notify::active', (widget) => { + this.field_keybinding.set_sensitive(widget.active); + }); + + let sizeLabel = new Gtk.Label({ + label: _('Max number of items'), + hexpand: true, + halign: Gtk.Align.START, + }); + let windowWidthPercentageLabel = new Gtk.Label({ + label: _('Window width (%)'), + hexpand: true, + halign: Gtk.Align.START, + }); + let cacheSizeLabel = new Gtk.Label({ + label: _('Max clipboard history size (MiB)'), + hexpand: true, + halign: Gtk.Align.START, + }); + let cacheDisableLabel = new Gtk.Label({ + label: _('Only save favorites to disk'), + hexpand: true, + halign: Gtk.Align.START, + }); + let notificationLabel = new Gtk.Label({ + label: _('Show notification on copy'), + hexpand: true, + halign: Gtk.Align.START, + }); + let confirmClearLabel = new Gtk.Label({ + label: _('Ask for confirmation before clearing history'), + hexpand: true, + halign: Gtk.Align.START, + }); + let moveFirstLabel = new Gtk.Label({ + label: _('Move previously copied items to the top'), + hexpand: true, + halign: Gtk.Align.START, + }); + let keybindingLabel = new Gtk.Label({ + label: _('Keyboard shortcuts'), + hexpand: true, + halign: Gtk.Align.START, + }); + let topbarPreviewLabel = new Gtk.Label({ + label: _('Number of characters in status bar'), + hexpand: true, + halign: Gtk.Align.START, + }); + let displayModeLabel = new Gtk.Label({ + label: _('What to show in status bar'), + hexpand: true, + halign: Gtk.Align.START, + }); + let disableDownArrowLabel = new Gtk.Label({ + label: _('Remove down arrow in status bar'), + hexpand: true, + halign: Gtk.Align.START, + }); + let stripTextLabel = new Gtk.Label({ + label: _('Remove whitespace around text'), + hexpand: true, + halign: Gtk.Align.START, + }); + let pasteOnSelectionLabel = new Gtk.Label({ + label: _('Paste on selection'), + hexpand: true, + halign: Gtk.Align.START, + }); + let processPrimarySelection = new Gtk.Label({ + label: _('Save selected text to history'), + hexpand: true, + halign: Gtk.Align.START, + }); + + const addRow = ((main) => { + let row = 0; + return (label, input) => { + let inputWidget = input; + + if (input instanceof Gtk.Switch) { + inputWidget = new Gtk.Box({ + orientation: Gtk.Orientation.HORIZONTAL, + }); + inputWidget.append(input); + } + + if (label) { + main.attach(label, 0, row, 1, 1); + main.attach(inputWidget, 1, row, 1, 1); + } else { + main.attach(inputWidget, 0, row, 2, 1); + } + + row++; + }; + })(this.main); + + addRow(windowWidthPercentageLabel, this.window_width_percentage); + addRow(sizeLabel, this.field_size); + addRow(cacheSizeLabel, this.field_cache_size); + addRow(cacheDisableLabel, this.field_cache_disable); + addRow(moveFirstLabel, this.field_move_item_first); + addRow(stripTextLabel, this.field_strip_text); + addRow(pasteOnSelectionLabel, this.field_paste_on_selection); + addRow(processPrimarySelection, this.field_process_primary_selection); + addRow(displayModeLabel, this.field_display_mode); + addRow(disableDownArrowLabel, this.field_disable_down_arrow); + addRow(topbarPreviewLabel, this.field_topbar_preview_size); + addRow(notificationLabel, this.field_notification_toggle); + addRow(confirmClearLabel, this.field_confirm_clear_toggle); + addRow(keybindingLabel, this.field_keybinding_activation); + addRow(null, this.field_keybinding); + + Settings.bind( + Fields.HISTORY_SIZE, + this.field_size, + 'value', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.WINDOW_WIDTH_PERCENTAGE, + this.window_width_percentage, + 'value', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.CACHE_FILE_SIZE, + this.field_cache_size, + 'value', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.CACHE_ONLY_FAVORITES, + this.field_cache_disable, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.NOTIFY_ON_COPY, + this.field_notification_toggle, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.CONFIRM_ON_CLEAR, + this.field_confirm_clear_toggle, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.MOVE_ITEM_FIRST, + this.field_move_item_first, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.TOPBAR_DISPLAY_MODE_ID, + this.field_display_mode, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.DISABLE_DOWN_ARROW, + this.field_disable_down_arrow, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.TOPBAR_PREVIEW_SIZE, + this.field_topbar_preview_size, + 'value', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.STRIP_TEXT, + this.field_strip_text, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.PASTE_ON_SELECTION, + this.field_paste_on_selection, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.PROCESS_PRIMARY_SELECTION, + this.field_process_primary_selection, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + Settings.bind( + Fields.ENABLE_KEYBINDING, + this.field_keybinding_activation, + 'active', + Gio.SettingsBindFlags.DEFAULT, + ); + } + + _create_display_mode_options() { + let options = [ + { name: _('Icon') }, + { name: _('Clipboard contents') }, + { name: _('Both') }, + { name: _('Neither') }, + ]; + let liststore = new Gtk.ListStore(); + liststore.set_column_types([GObject.TYPE_STRING]); + for (let i = 0; i < options.length; i++) { + let option = options[i]; + let iter = liststore.append(); + liststore.set(iter, [0], [option.name]); + } + return liststore; + } +} + +const PrefsObj = new GObject.registerClass(Prefs); + +function buildPrefsWidget() { + let widget = new PrefsObj(); + return widget.main; +} + +//binding widgets +////////////////////////////////// +const COLUMN_ID = 0; +const COLUMN_DESCRIPTION = 1; +const COLUMN_KEY = 2; +const COLUMN_MODS = 3; + +function addKeybinding(model, settings, id, description) { + // Get the current accelerator. + let accelerator = settings.get_strv(id)[0]; + let key, mods; + if (accelerator == null) { + [key, mods] = [0, 0]; + } else { + [, key, mods] = Gtk.accelerator_parse(settings.get_strv(id)[0]); + } + + // Add a row for the keybinding. + let row = model.insert(100); // Erm... + model.set( + row, + [COLUMN_ID, COLUMN_DESCRIPTION, COLUMN_KEY, COLUMN_MODS], + [id, description, key, mods], + ); +} + +function createKeybindingWidget(Settings) { + let model = new Gtk.ListStore(); + + model.set_column_types([ + GObject.TYPE_STRING, // COLUMN_ID + GObject.TYPE_STRING, // COLUMN_DESCRIPTION + GObject.TYPE_INT, // COLUMN_KEY + GObject.TYPE_INT, + ]); // COLUMN_MODS + + let treeView = new Gtk.TreeView(); + treeView.model = model; + treeView.headers_visible = false; + + let column, renderer; + + // Description column. + renderer = new Gtk.CellRendererText(); + + column = new Gtk.TreeViewColumn(); + column.expand = true; + column.pack_start(renderer, true); + column.add_attribute(renderer, 'text', COLUMN_DESCRIPTION); + + treeView.append_column(column); + + // Key binding column. + renderer = new Gtk.CellRendererAccel(); + renderer.accel_mode = Gtk.CellRendererAccelMode.GTK; + renderer.editable = true; + + renderer.connect( + 'accel-edited', + function (renderer, path, key, mods, hwCode) { + let [ok, iter] = model.get_iter_from_string(path); + if (!ok) { + return; + } + + // Update the UI. + model.set(iter, [COLUMN_KEY, COLUMN_MODS], [key, mods]); + + // Update the stored setting. + let id = model.get_value(iter, COLUMN_ID); + let accelString = Gtk.accelerator_name(key, mods); + Settings.set_strv(id, [accelString]); + }, + ); + + renderer.connect('accel-cleared', function (renderer, path) { + let [ok, iter] = model.get_iter_from_string(path); + if (!ok) { + return; + } + + // Update the UI. + model.set(iter, [COLUMN_KEY, COLUMN_MODS], [0, 0]); + + // Update the stored setting. + let id = model.get_value(iter, COLUMN_ID); + Settings.set_strv(id, []); + }); + + column = new Gtk.TreeViewColumn(); + column.pack_end(renderer, false); + column.add_attribute(renderer, 'accel-key', COLUMN_KEY); + column.add_attribute(renderer, 'accel-mods', COLUMN_MODS); + + treeView.append_column(column); + + return treeView; +} diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/schemas/gschemas.compiled b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/schemas/gschemas.compiled new file mode 100644 index 0000000..b65ab2f Binary files /dev/null and b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/schemas/gschemas.compiled differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/schemas/org.gnome.shell.extensions.clipboard-indicator.gschema.xml b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/schemas/org.gnome.shell.extensions.clipboard-indicator.gschema.xml new file mode 100644 index 0000000..8817c44 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/schemas/org.gnome.shell.extensions.clipboard-indicator.gschema.xml @@ -0,0 +1,136 @@ + + + + + 1000 + The maximum number of items to remember + + + + + 0 + What to display in top bar + + + + + true + Remove down arrow in top bar + + + + 33 + Window width (%) + + The width of the clipboard panel as a percentage of screen width. + + + + + + 10 + Number of visible characters in top bar + + The number of characters to display for the current clipboard item in the top bar. + + + + + + 100 + The maximum clipboard history size (MiB) + + Note that this is the maximum number of clipboard item bytes to store, not the maximum file + size on disk. The clipboard history on disk may be larger than this limit due to storage + inefficiencies. + + + + + + false + Only save favorites to disk + + Non-favorite items will still be saved, but only in-memory. Restarting the Gnome Shell will + result in the loss of those items. + + + + + false + Show a notification on copy + + If true, a notification is shown when content is copied to clipboard with an undo button. + + + + + true + Show confirmation dialog on Clear History + + If true, a confirmation dialog is shown when attempting to Clear History. + + + + + false + Remove whitespace around copied plaintext items + + + + true + Paste selected items into the previously active window + + + + false + Save the currently selected text to the clipboard history + + If true, both the contents from the "CLIPBOARD" clipboard and the "PRIMARY" clipboard are added to the history. + For more info, see https://wiki.archlinux.org/title/clipboard#Selections. + + + + + true + Move previously copied items to the top of the list + + + + false + Enable private mode + + If true, copied items are not saved in the clipboard history (be that in memory or on disk). + + + + + true + Enable keyboard shortcuts + + + + Shortcut to clear history + + + + Shortcut to cycle to the previous clipboard entry + + + + + + Shortcut to cycle to the next clipboard entry + + + V']]]> + Shortcut to open the clipboard history + + + P']]]> + Toggle private mode + + + diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/settingsFields.js b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/settingsFields.js new file mode 100644 index 0000000..3ea6fb4 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/settingsFields.js @@ -0,0 +1,18 @@ +const SettingsFields = { + HISTORY_SIZE: 'history-size', + WINDOW_WIDTH_PERCENTAGE: 'window-width-percentage', + CACHE_FILE_SIZE: 'cache-size', + CACHE_ONLY_FAVORITES: 'cache-only-favorites', + NOTIFY_ON_COPY: 'notify-on-copy', + CONFIRM_ON_CLEAR: 'confirm-clear', + MOVE_ITEM_FIRST: 'move-item-first', + ENABLE_KEYBINDING: 'enable-keybindings', + TOPBAR_PREVIEW_SIZE: 'topbar-preview-size', + TOPBAR_DISPLAY_MODE_ID: 'display-mode', + DISABLE_DOWN_ARROW: 'disable-down-arrow', + STRIP_TEXT: 'strip-text', + PRIVATE_MODE: 'private-mode', + PASTE_ON_SELECTION: 'paste-on-selection', + PROCESS_PRIMARY_SELECTION: 'process-primary-selection', +}; +export default SettingsFields; diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/store.js b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/store.js new file mode 100644 index 0000000..5fdb550 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/store.js @@ -0,0 +1,511 @@ +'use strict'; + +const { GLib, Gio } = imports.gi; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); +const DS = Me.imports.dataStructures; + +const CACHE_DIR = GLib.build_filenamev([GLib.get_user_cache_dir(), Me.uuid]); +const OLD_REGISTRY_FILE = GLib.build_filenamev([ + GLib.get_user_cache_dir(), + 'clipboard-indicator@tudmotu.com', + 'registry.txt', +]); + +/** + * Stores our compacting log implementation. Here are its key ideas: + * - We only ever append to the log. + * - This means there will be operations that cancel each other out. These are wasted/useless ops + * that must be occasionally pruned. MAX_WASTED_OPS limits the number of useless ops. + * - The available operations are listed in the OP_TYPE_* constants. + * - An add op never moves (until compaction), allowing us to derive globally unique entry IDs based + * on the order in which these add ops are discovered. + */ +const DATABASE_FILE = GLib.build_filenamev([CACHE_DIR, 'database.log']); +const BYTE_ORDER = Gio.DataStreamByteOrder.LITTLE_ENDIAN; + +// Don't use zero b/c DataInputStream uses 0 as its error value +const OP_TYPE_SAVE_TEXT = 1; +const OP_TYPE_DELETE_TEXT = 2; +const OP_TYPE_FAVORITE_ITEM = 3; +const OP_TYPE_UNFAVORITE_ITEM = 4; +const OP_TYPE_MOVE_ITEM_TO_END = 5; + +const MAX_WASTED_OPS = 500; +let uselessOpCount; + +let opQueue = new DS.LinkedList(); +let opInProgress = false; +let writeStream; + +function init() { + if (GLib.mkdir_with_parents(CACHE_DIR, 0o775) !== 0) { + log( + Me.uuid, + "Failed to create cache dir, extension likely won't work", + CACHE_DIR, + ); + } +} + +function destroy() { + _pushToOpQueue((resolve) => { + if (writeStream) { + writeStream.close_async(0, null, (src, res) => { + src.close_finish(res); + resolve(); + }); + writeStream = undefined; + } else { + resolve(); + } + }); +} + +function buildClipboardStateFromLog(callback) { + if (typeof callback !== 'function') { + throw TypeError('`callback` must be a function'); + } + uselessOpCount = 0; + + Gio.File.new_for_path(DATABASE_FILE).read_async(0, null, (src, res) => { + try { + _parseLog(src.read_finish(res), callback); + } catch (e) { + if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND)) { + _readAndConsumeOldFormat(callback); + } else { + throw e; + } + } + }); +} + +function _parseLog(stream, callback) { + stream = Gio.DataInputStream.new(stream); + stream.set_byte_order(BYTE_ORDER); + + const state = { + entries: new DS.LinkedList(), + favorites: new DS.LinkedList(), + nextId: 1, + }; + _consumeStream(stream, state, callback); +} + +function _consumeStream(stream, state, callback) { + const finish = () => { + callback(state.entries, state.favorites, state.nextId); + }; + const forceFill = (minBytes, fillCallback) => { + stream.fill_async(/*count=*/ -1, 0, null, (src, res) => { + if (src.fill_finish(res) < minBytes) { + finish(); + } else { + fillCallback(); + } + }); + }; + + let parseAvailableAware; + + function loop() { + if (stream.get_available() === 0) { + forceFill(1, loop); + return; + } + + const opType = stream.read_byte(null); + if (opType === OP_TYPE_SAVE_TEXT) { + stream.read_upto_async( + /*stop_chars=*/ '\0', + /*stop_chars_len=*/ 1, + 0, + null, + (src, res) => { + const [text] = src.read_upto_finish(res); + src.read_byte(null); + + const node = new DS.LLNode(); + node.diskId = node.id = state.nextId++; + node.type = DS.TYPE_TEXT; + node.text = text || ''; + node.favorite = false; + state.entries.append(node); + + loop(); + }, + ); + } else if (opType === OP_TYPE_DELETE_TEXT) { + uselessOpCount += 2; + parseAvailableAware(4, () => { + const id = stream.read_uint32(null); + (state.entries.findById(id) || state.favorites.findById(id)).detach(); + }); + } else if (opType === OP_TYPE_FAVORITE_ITEM) { + parseAvailableAware(4, () => { + const id = stream.read_uint32(null); + const entry = state.entries.findById(id); + + entry.favorite = true; + state.favorites.append(entry); + }); + } else if (opType === OP_TYPE_UNFAVORITE_ITEM) { + uselessOpCount += 2; + parseAvailableAware(4, () => { + const id = stream.read_uint32(null); + const entry = state.favorites.findById(id); + + entry.favorite = false; + state.entries.append(entry); + }); + } else if (opType === OP_TYPE_MOVE_ITEM_TO_END) { + uselessOpCount++; + parseAvailableAware(4, () => { + const id = stream.read_uint32(null); + const entry = + state.entries.findById(id) || state.favorites.findById(id); + + if (entry.favorite) { + state.favorites.append(entry); + } else { + state.entries.append(entry); + } + }); + } else { + log(Me.uuid, 'Unknown op type, aborting load.', opType); + finish(); + } + } + + parseAvailableAware = (minBytes, parse) => { + const safeParse = (cont) => { + try { + parse(); + cont(); + } catch (e) { + log(Me.uuid, 'Parsing error'); + logError(e); + + const entries = new DS.LinkedList(); + let nextId = 1; + const addEntry = (text) => { + const node = new DS.LLNode(); + node.id = nextId++; + node.type = DS.TYPE_TEXT; + node.text = text; + node.favorite = false; + entries.prepend(node); + }; + + addEntry('Your clipboard data has been corrupted and was moved to:'); + addEntry('~/.cache/clipboard-history@alexsaveau.dev/corrupted.log'); + addEntry('Please file a bug report at:'); + addEntry( + 'https://github.com/SUPERCILEX/gnome-clipboard-history/issues/new?assignees=&labels=bug&template=1-bug.md', + ); + + try { + if ( + !Gio.File.new_for_path(DATABASE_FILE).move( + Gio.File.new_for_path( + GLib.build_filenamev([CACHE_DIR, 'corrupted.log']), + ), + Gio.FileCopyFlags.OVERWRITE, + null, + null, + ) + ) { + log(Me.uuid, 'Failed to move database file'); + } + } catch (e) { + log(Me.uuid, 'Crash moving database file'); + logError(e); + } + callback(entries, new DS.LinkedList(), nextId, 1); + } + }; + + if (stream.get_available() < minBytes) { + forceFill(minBytes, () => { + safeParse(loop); + }); + } else { + safeParse(loop); + } + }; + + loop(); +} + +function _readAndConsumeOldFormat(callback) { + Gio.File.new_for_path(OLD_REGISTRY_FILE).load_contents_async( + null, + (src, res) => { + const entries = new DS.LinkedList(); + const favorites = new DS.LinkedList(); + let id = 1; + + let contents; + try { + [, contents] = src.load_contents_finish(res); + } catch (e) { + if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND)) { + callback(entries, favorites, id); + return; + } else { + throw e; + } + } + + let registry = []; + try { + registry = JSON.parse(imports.byteArray.toString(contents)); + } catch (e) { + logError(e); + } + + for (const entry of registry) { + const node = new DS.LLNode(); + + node.diskId = node.id = id; + node.type = DS.TYPE_TEXT; + if (typeof entry === 'string') { + node.text = entry; + node.favorite = false; + + entries.append(node); + } else { + node.text = entry.contents; + node.favorite = entry.favorite; + + favorites.append(node); + } + + id++; + } + + resetDatabase(() => entries.toArray().concat(favorites.toArray())); + Gio.File.new_for_path(OLD_REGISTRY_FILE).trash_async( + 0, + null, + (src, res) => { + src.trash_finish(res); + }, + ); + + callback(entries, favorites, id); + }, + ); +} + +function maybePerformLogCompaction(currentStateBuilder) { + if (uselessOpCount >= MAX_WASTED_OPS) { + resetDatabase(currentStateBuilder); + } +} + +function resetDatabase(currentStateBuilder) { + uselessOpCount = 0; + + const state = currentStateBuilder(); + _pushToOpQueue((resolve) => { + // Sigh, can't use truncate because it doesn't have an async variant. Instead, nuke the stream + // and let the next append re-create it. Note that we can't use this stream because it tries to + // apply our operations atomically and therefore writes to a temporary file instead of the one + // we asked for. + writeStream = undefined; + + const priority = -10; + Gio.File.new_for_path(DATABASE_FILE).replace_async( + /*etag=*/ null, + /*make_backup=*/ false, + Gio.FileCreateFlags.PRIVATE, + priority, + null, + (src, res) => { + const stream = _intoDataStream(src.replace_finish(res)); + const finish = () => { + stream.close_async(priority, null, (src, res) => { + src.close_finish(res); + resolve(); + }); + }; + + if (state.length === 0) { + finish(); + return; + } + + let i = 0; + _writeToStream(stream, priority, finish, (dataStream) => { + do { + const entry = state[i]; + + if (entry.type === DS.TYPE_TEXT) { + _storeTextOp(entry.text)(dataStream); + } else { + throw new TypeError('Unknown type: ' + entry.type); + } + if (entry.favorite) { + _updateFavoriteStatusOp(entry.diskId, true)(dataStream); + } + + i++; + } while (i % 1000 !== 0 && i < state.length); + + // Flush the buffer every 1000 entries + return i >= state.length; + }); + }, + ); + }); +} + +function storeTextEntry(text) { + _appendBytesToLog(_storeTextOp(text), -5); +} + +function _storeTextOp(text) { + return (dataStream) => { + dataStream.put_byte(OP_TYPE_SAVE_TEXT, null); + dataStream.put_string(text, null); + dataStream.put_byte(0, null); // NUL terminator + return true; + }; +} + +function deleteTextEntry(id, isFavorite) { + _appendBytesToLog(_deleteTextOp(id), 5); + uselessOpCount += 2; + if (isFavorite) { + uselessOpCount++; + } +} + +function _deleteTextOp(id) { + return (dataStream) => { + dataStream.put_byte(OP_TYPE_DELETE_TEXT, null); + dataStream.put_uint32(id, null); + return true; + }; +} + +function updateFavoriteStatus(id, favorite) { + _appendBytesToLog(_updateFavoriteStatusOp(id, favorite)); + + if (!favorite) { + uselessOpCount += 2; + } +} + +function _updateFavoriteStatusOp(id, favorite) { + return (dataStream) => { + dataStream.put_byte( + favorite ? OP_TYPE_FAVORITE_ITEM : OP_TYPE_UNFAVORITE_ITEM, + null, + ); + dataStream.put_uint32(id, null); + return true; + }; +} + +function moveEntryToEnd(id) { + _appendBytesToLog(_moveToEndOp(id)); + uselessOpCount++; +} + +function _moveToEndOp(id) { + return (dataStream) => { + dataStream.put_byte(OP_TYPE_MOVE_ITEM_TO_END, null); + dataStream.put_uint32(id, null); + return true; + }; +} + +function _appendBytesToLog(callback, priority) { + priority = priority || 0; + _pushToOpQueue((resolve) => { + const runUnsafe = () => { + _writeToStream(writeStream, priority, resolve, callback); + }; + + if (writeStream === undefined) { + Gio.File.new_for_path(DATABASE_FILE).append_to_async( + Gio.FileCreateFlags.PRIVATE, + priority, + null, + (src, res) => { + writeStream = _intoDataStream(src.append_to_finish(res)); + runUnsafe(); + }, + ); + } else { + runUnsafe(); + } + }); +} + +function _writeToStream(stream, priority, resolve, callback) { + _writeCallbackBytesAsyncHack(callback, stream, priority, () => { + stream.flush_async(priority, null, (src, res) => { + src.flush_finish(res); + resolve(); + }); + }); +} + +/** + * This garbage code is here to keep disk writes off the main thread. DataOutputStream doesn't have + * async method variants, so we write to a memory buffer and then flush it asynchronously. We're + * basically trying to balance memory allocations with disk writes. + */ +function _writeCallbackBytesAsyncHack( + dataCallback, + stream, + priority, + callback, +) { + if (dataCallback(stream)) { + callback(); + } else { + stream.flush_async(priority, null, (src, res) => { + src.flush_finish(res); + _writeCallbackBytesAsyncHack(dataCallback, stream, priority, callback); + }); + } +} + +function _intoDataStream(stream) { + const bufStream = Gio.BufferedOutputStream.new(stream); + bufStream.set_auto_grow(true); // Blocks flushing, needed for hack + const ioStream = Gio.DataOutputStream.new(bufStream); + ioStream.set_byte_order(BYTE_ORDER); + return ioStream; +} + +function _pushToOpQueue(op) { + const consumeOp = () => { + const resolve = () => { + opInProgress = false; + + const next = opQueue.head; + if (next) { + next.detach(); + next.op(); + } + }; + + opInProgress = true; + op(resolve); + }; + + if (opInProgress) { + const node = new DS.LLNode(); + node.op = consumeOp; + opQueue.append(node); + } else { + consumeOp(); + } +} diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/stylesheet.css b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/stylesheet.css new file mode 100644 index 0000000..824aee7 --- /dev/null +++ b/zorin/.local/share/gnome-shell/extensions/clipboard-history@alexsaveau.dev/stylesheet.css @@ -0,0 +1,34 @@ +.clipboard-indicator-icon.private-mode { + color: rgba(255, 255, 255, 0.3); +} + +.ci-notification-label { + font-weight: bold; + color: #ffffff; + background-color: rgba(10, 10, 10, 0.7); + border-radius: 6px; + font-size: 2em; + padding: 0.5em; + width: 400px; +} + +.popup-menu-item .ci-action-btn StIcon { + icon-size: 16px; +} + +.ci-history-menu-section { + max-height: 450px; +} + +.ci-history-search-section { + padding-top: 0; +} + +.ci-history-search-section .popup-menu-ornament, +.ci-history-actions-section .popup-menu-ornament { + width: auto; +} + +.ci-history-search-entry { + width: 5em; +} diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/README.rst b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/README.rst deleted file mode 100644 index 9f1a6d6..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/README.rst +++ /dev/null @@ -1,22 +0,0 @@ -============================ -Clipboard Indicator -============================ - -Clipboard Manager extension for Gnome-Shell - Adds a clipboard indicator to the top panel, and caches clipboard history. - -Extension page on e.g.o: -https://extensions.gnome.org/extension/779/clipboard-indicator/ - -Installation ----------------- - -Installation via git is performed by cloning the repo into your local gnome-shell extensions directory (usually ~/.local/share/gnome-shell/extensions/):: - - $ git clone https://github.com/Tudmotu/gnome-shell-extension-clipboard-indicator.git /clipboard-indicator@tudmotu.com - -After cloning the repo, the extension is practically installed yet disabled. In -order to enable it, you need to use gnome-tweak-tool - find the extension, -titled 'Clipboard Indicator', in the 'Extensions' screen and turn it 'On'. -You may need to restart the shell (Alt+F2 and insert 'r' in the prompt) for the -extension to be listed there. - diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/extension.js b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/extension.js deleted file mode 100644 index b6d05c9..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/extension.js +++ /dev/null @@ -1,883 +0,0 @@ -const Clutter = imports.gi.Clutter; -const Config = imports.misc.config; -const Gio = imports.gi.Gio; -const Lang = imports.lang; -const Mainloop = imports.mainloop; -const Meta = imports.gi.Meta; -const Shell = imports.gi.Shell; -const St = imports.gi.St; -const PolicyType = imports.gi.Gtk.PolicyType; -const Util = imports.misc.util; -const MessageTray = imports.ui.messageTray; - -const Main = imports.ui.main; -const PanelMenu = imports.ui.panelMenu; -const PopupMenu = imports.ui.popupMenu; -const CheckBox = imports.ui.checkBox.CheckBox; - -const Gettext = imports.gettext; -const _ = Gettext.domain('clipboard-indicator').gettext; - -const Clipboard = St.Clipboard.get_default(); -const CLIPBOARD_TYPE = St.ClipboardType.CLIPBOARD; - -const SETTING_KEY_CLEAR_HISTORY = "clear-history"; -const SETTING_KEY_PREV_ENTRY = "prev-entry"; -const SETTING_KEY_NEXT_ENTRY = "next-entry"; -const SETTING_KEY_TOGGLE_MENU = "toggle-menu"; -const INDICATOR_ICON = 'edit-paste-symbolic'; - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Utils = Me.imports.utils; -const ConfirmDialog = Me.imports.confirmDialog; -const Prefs = Me.imports.prefs; -const prettyPrint = Utils.prettyPrint; -const writeRegistry = Utils.writeRegistry; -const readRegistry = Utils.readRegistry; - -let TIMEOUT_MS = 1000; -let MAX_REGISTRY_LENGTH = 15; -let MAX_ENTRY_LENGTH = 50; -let CACHE_ONLY_FAVORITE = false; -let DELETE_ENABLED = true; -let MOVE_ITEM_FIRST = false; -let ENABLE_KEYBINDING = true; -let PRIVATEMODE = false; -let NOTIFY_ON_COPY = true; -let MAX_TOPBAR_LENGTH = 15; -let TOPBAR_DISPLAY_MODE = 1; //0 - only icon, 1 - only clipbord content, 2 - both -let DISABLE_DOWN_ARROW = false; -let STRIP_TEXT = false; - -const ClipboardIndicator = Lang.Class({ - Name: 'ClipboardIndicator', - Extends: PanelMenu.Button, - - _settingsChangedId: null, - _clipboardTimeoutId: null, - _selectionOwnerChangedId: null, - _historyLabelTimeoutId: null, - _historyLabel: null, - _buttonText: null, - _disableDownArrow: null, - - destroy: function () { - this._disconnectSettings(); - this._unbindShortcuts(); - this._clearClipboardTimeout(); - this._disconnectSelectionListener(); - this._clearLabelTimeout(); - this._clearDelayedSelectionTimeout(); - - // Call parent - this.parent(); - }, - - _init: function() { - this.parent(0.0, "ClipboardIndicator"); - this._shortcutsBindingIds = []; - this.clipItemsRadioGroup = []; - - let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box clipboard-indicator-hbox' }); - this.icon = new St.Icon({ icon_name: INDICATOR_ICON, - style_class: 'system-status-icon clipboard-indicator-icon' }); - hbox.add_child(this.icon); - this._buttonText = new St.Label({ - text: _('Text will be here'), - y_align: Clutter.ActorAlign.CENTER - }); - hbox.add_child(this._buttonText); - this._downArrow = PopupMenu.arrowIcon(St.Side.BOTTOM); - hbox.add(this._downArrow); - this.actor.add_child(hbox); - - this._createHistoryLabel(); - this._loadSettings(); - this._buildMenu(); - - this._updateTopbarLayout(); - - this._setupListener(); - }, - _updateButtonText: function(content){ - if (!content || PRIVATEMODE){ - this._buttonText.set_text("...") - } else { - this._buttonText.set_text(this._truncate(content, MAX_TOPBAR_LENGTH)); - } - }, - - _buildMenu: function () { - let that = this; - this._getCache(function (clipHistory) { - let lastIdx = clipHistory.length - 1; - let clipItemsArr = that.clipItemsRadioGroup; - - /* This create the search entry, which is add to a menuItem. - The searchEntry is connected to the function for research. - The menu itself is connected to some shitty hack in order to - grab the focus of the keyboard. */ - that._entryItem = new PopupMenu.PopupBaseMenuItem({ - reactive: false, - can_focus: false - }); - that.searchEntry = new St.Entry({ - name: 'searchEntry', - style_class: 'search-entry', - can_focus: true, - hint_text: _('Type here to search...'), - track_hover: true, - x_expand: true, - y_expand: true - }); - - that.searchEntry.get_clutter_text().connect( - 'text-changed', - Lang.bind(that, that._onSearchTextChanged) - ); - - that._entryItem.add(that.searchEntry); - - that.menu.addMenuItem(that._entryItem); - - that.menu.connect('open-state-changed', Lang.bind(this, function(self, open){ - let a = Mainloop.timeout_add(50, Lang.bind(this, function() { - if (open) { - that.searchEntry.set_text(''); - global.stage.set_key_focus(that.searchEntry); - } - Mainloop.source_remove(a); - })); - })); - - // Create menu sections for items - // Favorites - that.favoritesSection = new PopupMenu.PopupMenuSection(); - - that.scrollViewFavoritesMenuSection = new PopupMenu.PopupMenuSection(); - let favoritesScrollView = new St.ScrollView({ - style_class: 'ci-history-menu-section', - overlay_scrollbars: true - }); - favoritesScrollView.add_actor(that.favoritesSection.actor); - - that.scrollViewFavoritesMenuSection.actor.add_actor(favoritesScrollView); - that.menu.addMenuItem(that.scrollViewFavoritesMenuSection); - that.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); - - // History - that.historySection = new PopupMenu.PopupMenuSection(); - - that.scrollViewMenuSection = new PopupMenu.PopupMenuSection(); - let historyScrollView = new St.ScrollView({ - style_class: 'ci-history-menu-section', - overlay_scrollbars: true - }); - historyScrollView.add_actor(that.historySection.actor); - - that.scrollViewMenuSection.actor.add_actor(historyScrollView); - - that.menu.addMenuItem(that.scrollViewMenuSection); - - // Add cached items - clipHistory.forEach(function (buffer) { - if (typeof buffer === 'string') { - // Old cache format - that._addEntry(buffer); - } else { - that._addEntry(buffer["contents"], buffer["favorite"]); - } - }); - - // Add separator - that.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); - - // Private mode switch - that.privateModeMenuItem = new PopupMenu.PopupSwitchMenuItem( - _("Private mode"), PRIVATEMODE, { reactive: true }); - that.privateModeMenuItem.connect('toggled', - Lang.bind(that, that._onPrivateModeSwitch)); - that.menu.addMenuItem(that.privateModeMenuItem); - that._onPrivateModeSwitch(); - - // Add 'Clear' button which removes all items from cache - let clearMenuItem = new PopupMenu.PopupMenuItem(_('Clear history')); - that.menu.addMenuItem(clearMenuItem); - clearMenuItem.connect('activate', Lang.bind(that, that._removeAll)); - - // Add 'Settings' menu item to open settings - let settingsMenuItem = new PopupMenu.PopupMenuItem(_('Settings')); - that.menu.addMenuItem(settingsMenuItem); - settingsMenuItem.connect('activate', Lang.bind(that, that._openSettings)); - - if (lastIdx >= 0) { - that._selectMenuItem(clipItemsArr[lastIdx]); - } - }); - }, - - /* When text change, this function will check, for each item of the - historySection and favoritesSestion, if it should be visible or not (based on words contained - in the clipContents attribute of the item). It doesn't destroy or create - items. It the entry is empty, the section is restored with all items - set as visible. */ - _onSearchTextChanged: function() { - let searchedText = this.searchEntry.get_text().toLowerCase(); - - if(searchedText === '') { - this._getAllIMenuItems().forEach(function(mItem){ - mItem.actor.visible = true; - }); - } - else { - this._getAllIMenuItems().forEach(function(mItem){ - let text = mItem.clipContents.toLowerCase(); - let isMatching = text.indexOf(searchedText) >= 0; - mItem.actor.visible = isMatching - }); - } - }, - - _truncate: function(string, length) { - let shortened = string.replace(/\s+/g, ' '); - - if (shortened.length > length) - shortened = shortened.substring(0,length-1) + '...'; - - return shortened; - }, - - _setEntryLabel: function (menuItem) { - let buffer = menuItem.clipContents; - menuItem.label.set_text(this._truncate(buffer, MAX_ENTRY_LENGTH)); - }, - - _addEntry: function (buffer, favorite, autoSelect, autoSetClip) { - let menuItem = new PopupMenu.PopupMenuItem(''); - - menuItem.menu = this.menu; - menuItem.clipContents = buffer; - menuItem.clipFavorite = favorite; - menuItem.radioGroup = this.clipItemsRadioGroup; - menuItem.buttonPressId = menuItem.connect('activate', - Lang.bind(menuItem, this._onMenuItemSelectedAndMenuClose)); - - this._setEntryLabel(menuItem); - this.clipItemsRadioGroup.push(menuItem); - - // Favorite button - let icon_name = favorite ? 'starred-symbolic' : 'non-starred-symbolic'; - let iconfav = new St.Icon({ - icon_name: icon_name, - style_class: 'system-status-icon' - }); - - let icofavBtn = new St.Button({ - style_class: 'ci-action-btn', - can_focus: true, - child: iconfav, - x_align: Clutter.ActorAlign.END, - x_expand: true, - y_expand: true - }); - - menuItem.actor.add_child(icofavBtn); - menuItem.icofavBtn = icofavBtn; - menuItem.favoritePressId = icofavBtn.connect('button-press-event', - Lang.bind(this, function () { - this._favoriteToggle(menuItem); - }) - ); - - // Delete button - let icon = new St.Icon({ - icon_name: 'edit-delete-symbolic', //'mail-attachment-symbolic', - style_class: 'system-status-icon' - }); - - let icoBtn = new St.Button({ - style_class: 'ci-action-btn', - can_focus: true, - child: icon, - x_align: Clutter.ActorAlign.END, - x_expand: false, - y_expand: true - }); - - menuItem.actor.add_child(icoBtn); - menuItem.icoBtn = icoBtn; - menuItem.deletePressId = icoBtn.connect('button-press-event', - Lang.bind(this, function () { - this._removeEntry(menuItem, 'delete'); - }) - ); - - if (favorite) { - this.favoritesSection.addMenuItem(menuItem, 0); - } else { - this.historySection.addMenuItem(menuItem, 0); - } - - if (autoSelect === true) - this._selectMenuItem(menuItem, autoSetClip); - - if (TOPBAR_DISPLAY_MODE === 1 || TOPBAR_DISPLAY_MODE === 2) { - this._updateButtonText(buffer); - } - - this._updateCache(); - }, - - _favoriteToggle: function (menuItem) { - menuItem.clipFavorite = menuItem.clipFavorite ? false : true; - this._moveItemFirst(menuItem); - - this._updateCache(); - }, - _removeAll: function () { - const title = _("Clear all?"); - const message = _("Are you sure you want to delete all clipboard items?"); - const sub_message = _("This operation cannot be undone."); - - ConfirmDialog.openConfirmDialog(title, message, sub_message, _("Clear"), _("Cancel"), () => {; - let that = this; - // We can't actually remove all items, because the clipboard still - // has data that will be re-captured on next refresh, so we remove - // all except the currently selected item - // Don't remove favorites here - that.historySection._getMenuItems().forEach(function (mItem) { - if (!mItem.currentlySelected) { - let idx = that.clipItemsRadioGroup.indexOf(mItem); - mItem.destroy(); - that.clipItemsRadioGroup.splice(idx,1); - } - }); - that._updateCache(); - that._showNotification(_("Clipboard history cleared")); - }); - }, - - _removeEntry: function (menuItem, event) { - let itemIdx = this.clipItemsRadioGroup.indexOf(menuItem); - - if(event === 'delete' && menuItem.currentlySelected) { - Clipboard.set_text(CLIPBOARD_TYPE, ""); - } - - menuItem.destroy(); - this.clipItemsRadioGroup.splice(itemIdx,1); - - this._updateCache(); - }, - - _removeOldestEntries: function () { - let that = this; - - let clipItemsRadioGroupNoFavorite = that.clipItemsRadioGroup.filter( - item => item.clipFavorite === false); - - while (clipItemsRadioGroupNoFavorite.length > MAX_REGISTRY_LENGTH) { - let oldestNoFavorite = clipItemsRadioGroupNoFavorite.shift(); - that._removeEntry(oldestNoFavorite); - - clipItemsRadioGroupNoFavorite = that.clipItemsRadioGroup.filter( - item => item.clipFavorite === false); - } - - that._updateCache(); - }, - - _onMenuItemSelected: function (autoSet) { - var that = this; - that.radioGroup.forEach(function (menuItem) { - let clipContents = that.clipContents; - - if (menuItem === that && clipContents) { - that.setOrnament(PopupMenu.Ornament.DOT); - that.currentlySelected = true; - if (autoSet !== false) - Clipboard.set_text(CLIPBOARD_TYPE, clipContents); - } - else { - menuItem.setOrnament(PopupMenu.Ornament.NONE); - menuItem.currentlySelected = false; - } - }); - }, - - _selectMenuItem: function (menuItem, autoSet) { - let fn = Lang.bind(menuItem, this._onMenuItemSelected); - fn(autoSet); - }, - - _onMenuItemSelectedAndMenuClose: function (autoSet) { - var that = this; - that.radioGroup.forEach(function (menuItem) { - let clipContents = that.clipContents; - - if (menuItem === that && clipContents) { - that.setOrnament(PopupMenu.Ornament.DOT); - that.currentlySelected = true; - if (autoSet !== false) - Clipboard.set_text(CLIPBOARD_TYPE, clipContents); - } - else { - menuItem.setOrnament(PopupMenu.Ornament.NONE); - menuItem.currentlySelected = false; - } - }); - - that.menu.close(); - }, - - _getCache: function (cb) { - return readRegistry(cb); - }, - - _updateCache: function () { - let registry = this.clipItemsRadioGroup.map(function (menuItem) { - return { - "contents" : menuItem.clipContents, - "favorite" : menuItem.clipFavorite - }; - }); - - writeRegistry(registry.filter(function (menuItem) { - if (CACHE_ONLY_FAVORITE) { - if (menuItem["favorite"]) { - return menuItem; - } - } else { - return menuItem; - } - })); - }, - - _onSelectionChange (selection, selectionType, selectionSource) { - if (selectionType === Meta.SelectionType.SELECTION_CLIPBOARD) { - this._refreshIndicator(); - } - }, - - _refreshIndicator: function () { - if (PRIVATEMODE) return; // Private mode, do not. - - let that = this; - - Clipboard.get_text(CLIPBOARD_TYPE, function (clipBoard, text) { - that._processClipboardContent(text); - }); - }, - - _processClipboardContent (text) { - const that = this; - - if (STRIP_TEXT) { - text = text.trim(); - } - - if (text !== "" && text) { - let registry = that.clipItemsRadioGroup.map(function (menuItem) { - return menuItem.clipContents; - }); - - const itemIndex = registry.indexOf(text); - - if (itemIndex < 0) { - that._addEntry(text, false, true, false); - that._removeOldestEntries(); - if (NOTIFY_ON_COPY) { - that._showNotification(_("Copied to clipboard"), notif => { - notif.addAction(_('Cancel'), Lang.bind(that, that._cancelNotification)); - }); - } - } - else if (itemIndex >= 0 && itemIndex < registry.length - 1) { - const item = that._findItem(text); - that._selectMenuItem(item, false); - - if (!item.clipFavorite && MOVE_ITEM_FIRST) { - that._moveItemFirst(item); - } - } - } - }, - - _moveItemFirst: function (item) { - this._removeEntry(item); - this._addEntry(item.clipContents, item.clipFavorite, item.currentlySelected, false); - }, - - _findItem: function (text) { - return this.clipItemsRadioGroup.filter( - item => item.clipContents === text)[0]; - }, - - _getCurrentlySelectedItem () { - return this.clipItemsRadioGroup.find(item => item.currentlySelected); - }, - - _getAllIMenuItems: function (text) { - return this.historySection._getMenuItems().concat(this.favoritesSection._getMenuItems()); - }, - - _setupListener () { - const metaDisplay = Shell.Global.get().get_display(); - - if (typeof metaDisplay.get_selection === 'function') { - const selection = metaDisplay.get_selection(); - this._setupSelectionTracking(selection); - } - else { - this._setupTimeout(); - } - }, - - _setupSelectionTracking (selection) { - this.selection = selection; - this._selectionOwnerChangedId = selection.connect('owner-changed', (selection, selectionType, selectionSource) => { - this._onSelectionChange(selection, selectionType, selectionSource); - }); - }, - - _setupTimeout: function (reiterate) { - let that = this; - reiterate = typeof reiterate === 'boolean' ? reiterate : true; - - this._clipboardTimeoutId = Mainloop.timeout_add(TIMEOUT_MS, function () { - that._refreshIndicator(); - - // If the timeout handler returns `false`, the source is - // automatically removed, so we reset the timeout-id so it won't - // be removed on `.destroy()` - if (reiterate === false) - that._clipboardTimeoutId = null; - - // As long as the timeout handler returns `true`, the handler - // will be invoked again and again as an interval - return reiterate; - }); - }, - - _openSettings: function () { - if (typeof ExtensionUtils.openPrefs === 'function') { - ExtensionUtils.openPrefs(); - } else { - Util.spawn([ - "gnome-shell-extension-prefs", - Me.uuid - ]); - } - }, - - _initNotifSource: function () { - if (!this._notifSource) { - this._notifSource = new MessageTray.Source('ClipboardIndicator', - INDICATOR_ICON); - this._notifSource.connect('destroy', Lang.bind(this, function() { - this._notifSource = null; - })); - Main.messageTray.add(this._notifSource); - } - }, - - _cancelNotification: function() { - if (this.clipItemsRadioGroup.length >= 2) { - let clipSecond = this.clipItemsRadioGroup.length - 2; - let previousClip = this.clipItemsRadioGroup[clipSecond]; - Clipboard.set_text(CLIPBOARD_TYPE, previousClip.clipContents); - previousClip.setOrnament(PopupMenu.Ornament.DOT); - previousClip.icoBtn.visible = false; - previousClip.currentlySelected = true; - } else { - Clipboard.set_text(CLIPBOARD_TYPE, ""); - } - let clipFirst = this.clipItemsRadioGroup.length - 1; - this._removeEntry(this.clipItemsRadioGroup[clipFirst]); - }, - - _showNotification: function (message, transformFn) { - let notification = null; - - this._initNotifSource(); - - if (this._notifSource.count === 0) { - notification = new MessageTray.Notification(this._notifSource, message); - } - else { - notification = this._notifSource.notifications[0]; - notification.update(message, '', { clear: true }); - } - - if (typeof transformFn === 'function') { - transformFn(notification); - } - - notification.setTransient(true); - if (Config.PACKAGE_VERSION < '3.38') - this._notifSource.notify(notification); - else - this._notifSource.showNotification(notification); - }, - - _createHistoryLabel: function () { - this._historyLabel = new St.Label({ - style_class: 'ci-notification-label', - text: '' - }); - - global.stage.add_actor(this._historyLabel); - - this._historyLabel.hide(); - }, - - _onPrivateModeSwitch: function() { - let that = this; - PRIVATEMODE = this.privateModeMenuItem.state; - // We hide the history in private ModeTypee because it will be out of sync (selected item will not reflect clipboard) - this.scrollViewMenuSection.actor.visible = !PRIVATEMODE; - this.scrollViewFavoritesMenuSection.actor.visible = !PRIVATEMODE; - // If we get out of private mode then we restore the clipboard to old state - if (!PRIVATEMODE) { - let selectList = this.clipItemsRadioGroup.filter((item) => !!item.currentlySelected); - Clipboard.get_text(CLIPBOARD_TYPE, function (clipBoard, text) { - that._updateButtonText(text); - }); - if (selectList.length) { - this._selectMenuItem(selectList[0]); - } else { - // Nothing to return to, let's empty it instead - Clipboard.set_text(CLIPBOARD_TYPE, ""); - } - - this.icon.remove_style_class_name('private-mode'); - } else { - this._buttonText.set_text('...'); - this.icon.add_style_class_name('private-mode'); - } - }, - - _loadSettings: function () { - this._settings = Prefs.SettingsSchema; - this._settingsChangedId = this._settings.connect('changed', - Lang.bind(this, this._onSettingsChange)); - - this._fetchSettings(); - - if (ENABLE_KEYBINDING) - this._bindShortcuts(); - }, - - _fetchSettings: function () { - TIMEOUT_MS = this._settings.get_int(Prefs.Fields.INTERVAL); - MAX_REGISTRY_LENGTH = this._settings.get_int(Prefs.Fields.HISTORY_SIZE); - MAX_ENTRY_LENGTH = this._settings.get_int(Prefs.Fields.PREVIEW_SIZE); - CACHE_ONLY_FAVORITE = this._settings.get_boolean(Prefs.Fields.CACHE_ONLY_FAVORITE); - DELETE_ENABLED = this._settings.get_boolean(Prefs.Fields.DELETE); - MOVE_ITEM_FIRST = this._settings.get_boolean(Prefs.Fields.MOVE_ITEM_FIRST); - NOTIFY_ON_COPY = this._settings.get_boolean(Prefs.Fields.NOTIFY_ON_COPY); - ENABLE_KEYBINDING = this._settings.get_boolean(Prefs.Fields.ENABLE_KEYBINDING); - MAX_TOPBAR_LENGTH = this._settings.get_int(Prefs.Fields.TOPBAR_PREVIEW_SIZE); - TOPBAR_DISPLAY_MODE = this._settings.get_int(Prefs.Fields.TOPBAR_DISPLAY_MODE_ID); - DISABLE_DOWN_ARROW = this._settings.get_boolean(Prefs.Fields.DISABLE_DOWN_ARROW); - STRIP_TEXT = this._settings.get_boolean(Prefs.Fields.STRIP_TEXT); - }, - - _onSettingsChange: function () { - var that = this; - - // Load the settings into variables - that._fetchSettings(); - - // Remove old entries in case the registry size changed - that._removeOldestEntries(); - - // Re-set menu-items lables in case preview size changed - this._getAllIMenuItems().forEach(function (mItem) { - that._setEntryLabel(mItem); - }); - - //update topbar - this._updateTopbarLayout(); - if(TOPBAR_DISPLAY_MODE === 1 || TOPBAR_DISPLAY_MODE === 2) { - Clipboard.get_text(CLIPBOARD_TYPE, function (clipBoard, text) { - that._updateButtonText(text); - }); - } - - // Bind or unbind shortcuts - if (ENABLE_KEYBINDING) - that._bindShortcuts(); - else - that._unbindShortcuts(); - }, - - _bindShortcuts: function () { - this._unbindShortcuts(); - this._bindShortcut(SETTING_KEY_CLEAR_HISTORY, this._removeAll); - this._bindShortcut(SETTING_KEY_PREV_ENTRY, this._previousEntry); - this._bindShortcut(SETTING_KEY_NEXT_ENTRY, this._nextEntry); - this._bindShortcut(SETTING_KEY_TOGGLE_MENU, this._toggleMenu); - }, - - _unbindShortcuts: function () { - this._shortcutsBindingIds.forEach( - (id) => Main.wm.removeKeybinding(id) - ); - - this._shortcutsBindingIds = []; - }, - - _bindShortcut: function(name, cb) { - var ModeType = Shell.hasOwnProperty('ActionMode') ? - Shell.ActionMode : Shell.KeyBindingMode; - - Main.wm.addKeybinding( - name, - this._settings, - Meta.KeyBindingFlags.NONE, - ModeType.ALL, - Lang.bind(this, cb) - ); - - this._shortcutsBindingIds.push(name); - }, - - _updateTopbarLayout: function(){ - if(TOPBAR_DISPLAY_MODE === 0){ - this.icon.visible = true; - this._buttonText.visible = false; - } - if(TOPBAR_DISPLAY_MODE === 1){ - this.icon.visible = false; - this._buttonText.visible = true; - } - if(TOPBAR_DISPLAY_MODE === 2){ - this.icon.visible = true; - this._buttonText.visible = true; - } - if(!DISABLE_DOWN_ARROW) { - this._downArrow.visible = true; - } else { - this._downArrow.visible = false; - } - }, - - _disconnectSettings: function () { - if (!this._settingsChangedId) - return; - - this._settings.disconnect(this._settingsChangedId); - this._settingsChangedId = null; - }, - - _clearClipboardTimeout: function () { - if (!this._clipboardTimeoutId) - return; - - Mainloop.source_remove(this._clipboardTimeoutId); - this._clipboardTimeoutId = null; - }, - - _disconnectSelectionListener () { - if (!this._selectionOwnerChangedId) - return; - - this.selection.disconnect(this._selectionOwnerChangedId); - }, - - _clearLabelTimeout: function () { - if (!this._historyLabelTimeoutId) - return; - - Mainloop.source_remove(this._historyLabelTimeoutId); - this._historyLabelTimeoutId = null; - }, - - _clearDelayedSelectionTimeout: function () { - if (this._delayedSelectionTimeoutId) { - Mainloop.source_remove(this._delayedSelectionTimeoutId); - } - }, - - _selectEntryWithDelay: function (entry) { - let that = this; - - that._selectMenuItem(entry, false); - that._delayedSelectionTimeoutId = Mainloop.timeout_add( - TIMEOUT_MS * 0.75, function () { - - that._selectMenuItem(entry); //select the item - - that._delayedSelectionTimeoutId = null; - return false; - }); - }, - - _previousEntry: function() { - let that = this; - - that._clearDelayedSelectionTimeout(); - - this._getAllIMenuItems().some(function (mItem, i, menuItems){ - if (mItem.currentlySelected) { - i--; //get the previous index - if (i < 0) i = menuItems.length - 1; //cycle if out of bound - let index = i + 1; //index to be displayed - that._showNotification(index + ' / ' + menuItems.length + ': ' + menuItems[i].label.text); - if (MOVE_ITEM_FIRST) { - that._selectEntryWithDelay(menuItems[i]); - } - else { - that._selectMenuItem(menuItems[i]); - } - return true; - } - return false; - }); - }, - - _nextEntry: function() { - let that = this; - - that._clearDelayedSelectionTimeout(); - - this._getAllIMenuItems().some(function (mItem, i, menuItems){ - if (mItem.currentlySelected) { - i++; //get the next index - if (i === menuItems.length) i = 0; //cycle if out of bound - let index = i + 1; //index to be displayed - that._showNotification(index + ' / ' + menuItems.length + ': ' + menuItems[i].label.text); - if (MOVE_ITEM_FIRST) { - that._selectEntryWithDelay(menuItems[i]); - } - else { - that._selectMenuItem(menuItems[i]); - } - return true; - } - return false; - }); - }, - - _toggleMenu: function(){ - this.menu.toggle(); - } -}); - - -function init () { - let localeDir = Me.dir.get_child('locale'); - Gettext.bindtextdomain('clipboard-indicator', localeDir.get_path()); -} - -let clipboardIndicator; -function enable () { - clipboardIndicator = new ClipboardIndicator(); - Main.panel.addToStatusArea('clipboardIndicator', clipboardIndicator, 1); -} - -function disable () { - clipboardIndicator.destroy(); -} diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ar/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ar/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 033cb8e..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ar/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ar/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ar/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index bbcc47e..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ar/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,143 +0,0 @@ -# Catalan translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) 2018 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# Adolfo Jayme Barrientos , 2018. -# -msgid "" -msgstr "" -"Project-Id-Version: gnome-shell-extension-clipboard-indicator\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2018-03-10 10:10-0600\n" -"Last-Translator: Ahmed Ayman \n" -"Language-Team: \n" -"Language: ca\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.6\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "النص سيكون هنا" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "اكتب هنا للبحث" - -#: extension.js:198 -msgid "Private mode" -msgstr "الوضع السري" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "محو السجلات" - -#: extension.js:210 -msgid "Settings" -msgstr "ضبط" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "تم ازالة سجلات الحافظة" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "تم النسخ في الحافظة" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "بدل حالة القائمة" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "المدخل السابق" - -#: prefs.js:111 -msgid "Next entry" -msgstr "المدخل التالي" - -#: prefs.js:120 -msgid "History Size" -msgstr "عدد العناصر في السجل " - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "فترة الريفريش بالمللي ثانية" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "عدد الاحرف في المراجعه" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "اقصي حجم للكاش فايل بالكيلوبايت" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "اظهار الاشعارات عند النسخ" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "اختصارات الكيبورد" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "عدد الاحرف في الشريط العلوي" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "ما سيظهر في الشريط العلوي" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "عدد الاحرف في الشريط العلوي" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "أيقونة" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "محتوي الحافظة" - -#: prefs.js:234 -msgid "Both" -msgstr "كلاهما" - -#~ msgid "Disable cache file" -#~ msgstr "الغاء الكاش في فايل" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ca/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ca/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index e98423e..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ca/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ca/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ca/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index ae577ac..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ca/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,143 +0,0 @@ -# Catalan translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) 2018 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# Adolfo Jayme Barrientos , 2018. -# -msgid "" -msgstr "" -"Project-Id-Version: gnome-shell-extension-clipboard-indicator\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2018-03-10 10:10-0600\n" -"Last-Translator: Adolfo Jayme Barrientos \n" -"Language-Team: \n" -"Language: ca\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.6\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "El text apareixerà aquí" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Escriviu aquí per a cercar…" - -#: extension.js:198 -msgid "Private mode" -msgstr "Mode privat" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Buida l’historial" - -#: extension.js:210 -msgid "Settings" -msgstr "Paràmetres" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "S’ha buidat l’historial del porta-retalls" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "S’ha copiat en el porta-retalls" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Commuta el menú" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Entrada anterior" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Entrada següent" - -#: prefs.js:120 -msgid "History Size" -msgstr "Mida de l’historial" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Interval d’actualització (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Mida de la previsualització (caràcters)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Mida màxima de la memòria cau (kB)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Mostra una notificació en copiar" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Dreceres de teclat" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Nombre de caràcters a la barra superior" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Què mostrar a la barra superior" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Nombre de caràcters a la barra superior" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "Icona" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Contingut del porta-retalls" - -#: prefs.js:234 -msgid "Both" -msgstr "Ambdós" - -#~ msgid "Disable cache file" -#~ msgstr "Inhabilita el fitxer de memòria cau" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/cs/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/cs/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 99bf1b8..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/cs/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/cs/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/cs/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index 23c0819..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/cs/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,144 +0,0 @@ -# Czech translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) 2014-2017, Yotam Bar-On -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# Daniel Rusek , 2017. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2017-11-03 21:22+0100\n" -"Last-Translator: Pavel Borecki \n" -"Language-Team: \n" -"Language: cs\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "Zde bude text" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Vyhledávejte psaním sem…" - -#: extension.js:198 -msgid "Private mode" -msgstr "Stop (proti úniku citlivých údajů)" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Vyčistit historii" - -#: extension.js:210 -msgid "Settings" -msgstr "Nastavení" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "Storno" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Historie schránky vyčištěna" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Zkopírováno do schránky" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Přepnout nabídku" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Předchozí položka" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Následující položka" - -#: prefs.js:120 -msgid "History Size" -msgstr "Hloubka historie" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Interval obnovování (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Velikost náhledu (znaky)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Omezit velikost mezipaměti na nejvýše (KB)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "Ukládat do mezipaměti pouze oblíbené" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Při zkopírování zobrazit oznámení" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "Poté, co byla vybrána, posunout položku na začátek seznamu" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Klávesové zkratky" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Počet znaků v horní liště" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Co zobrazovat v horní liště" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Počet znaků v horní liště" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "Odebrat prázdné místo kolem textu" - -#: prefs.js:232 -msgid "Icon" -msgstr "Ikonu" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Obsah schránky" - -#: prefs.js:234 -msgid "Both" -msgstr "Obojí" - -#~ msgid "Enable Deletion" -#~ msgstr "Zapnout mazání" - -#~ msgid "Disable cache file" -#~ msgstr "Nepoužívat mezipaměť (soubor)" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/de/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/de/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 8084947..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/de/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/de/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/de/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index a4f8e30..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/de/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,142 +0,0 @@ -# German translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) 2014-2015, Yotam Bar-On -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# Jens Lody , 2015. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2020-09-27 13:21+0200\n" -"Last-Translator: Onno Giesmann \n" -"Language-Team: Deutsch \n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.4.1\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "Hier erscheint der Text" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Text eingeben, um zu suchen…" - -#: extension.js:198 -msgid "Private mode" -msgstr "Privater Modus" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Verlauf löschen" - -#: extension.js:210 -msgid "Settings" -msgstr "Einstellungen" - -#: extension.js:339 -msgid "Clear all?" -msgstr "Alles löschen?" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "Soll die Zwischenablage wirklich geleert werden?" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "Diese Aktion kann nicht rückgängig gemacht werden." - -#: extension.js:343 -msgid "Clear" -msgstr "Löschen" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "Abbrechen" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Verlauf der Zwischenablage gelöscht" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "In Zwischenablage kopiert" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Das Menü öffnen/schließen" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Vorheriger Eintrag" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Nächster Eintrag" - -#: prefs.js:120 -msgid "History Size" -msgstr "Größe des Verlaufs" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Aktualisierungsintervall (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Vorschaugröße (Zeichen)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Maximale Größe der Pufferdatei (kb)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "Nur Favoriten zwischenspeichern" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Benachrichtigung beim Kopieren anzeigen" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "Eintrag nach Auswahl nach oben verschieben" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Tastaturkürzel" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Anzahl der Zeichen in oberer Leiste" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Folgendes in oberer Leiste anzeigen:" - -#: prefs.js:170 -msgid "Remove down arrow in top bar" -msgstr "Pfeil in der oberen Leiste nicht anzeigen" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "Leerzeichen vor und nach dem Text entfernen" - -#: prefs.js:232 -msgid "Icon" -msgstr "Symbol" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Inhalt der Zwischenablage" - -#: prefs.js:234 -msgid "Both" -msgstr "Beides" - -#~ msgid "Enable Deletion" -#~ msgstr "Löschen ermöglichen" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/el/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/el/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 14ec2db..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/el/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/el/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/el/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index 222c738..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/el/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,139 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2017-05-04 17:27+0300\n" -"Last-Translator: Raphael Rochet \n" -"Language-Team: \n" -"Language: el\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.1\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "" - -#: extension.js:198 -msgid "Private mode" -msgstr "Ιδιωτική λειτουργία" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Εκκάθαρση ιστορικού" - -#: extension.js:210 -msgid "Settings" -msgstr "Ρυθμίσεις" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Κενό ιστορικό" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Αντεγραμμένο στο πρόχειρο" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Εμφάνιση/Απόκρυψη μενού" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Προηγούμενη καταχώρηση" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Επόμενη καταχώρηση" - -#: prefs.js:120 -msgid "History Size" -msgstr "Μέγεθος ιστορικού" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Διάστημα επαναφόρτωσης (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Μέγεθος προεπισκόπησης (χαρακτήρες)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Μέγιστο μέγεθος αρχείων κρυφής μνήμης (kb)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Εμφάνιση ειδοποίησης με την αντιγραφή" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Συντομεύσεις πληκτρολογίου" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "" - -#: prefs.js:170 -msgid "Remove down arrow in top bar" -msgstr "" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "" - -#: prefs.js:234 -msgid "Both" -msgstr "" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index e9e68a8..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index ab2ad6f..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,143 +0,0 @@ -# Spanish translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# Javier Junquera , 2016. -# -msgid "" -msgstr "" -"Project-Id-Version: gnome-shell-extension-clipboard-indicator\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2018-03-10 09:43-0600\n" -"Last-Translator: Adolfo Jayme Barrientos \n" -"Language-Team: \n" -"Language: es\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.6\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "El texto aparecerá aquí" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Escriba aquí para buscar…" - -#: extension.js:198 -msgid "Private mode" -msgstr "Modo privado" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Vaciar historial" - -#: extension.js:210 -msgid "Settings" -msgstr "Configuración" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Historial del portapapeles vaciado" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Copiado en el portapapeles" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Alternar menú" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Entrada anterior" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Entrada siguiente" - -#: prefs.js:120 -msgid "History Size" -msgstr "Tamaño del historial" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Intervalo de actualización (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Tamaño de previsualización (caracteres)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Tamaño máximo de antememoria (kB)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Mostrar una notificación al copiar" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Atajos de teclado" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Número de caracteres en la barra superior" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Qué mostrar en la barra superior" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Número de caracteres en la barra superior" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "Icono" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Contenido del portapapeles" - -#: prefs.js:234 -msgid "Both" -msgstr "Ambos" - -#~ msgid "Disable cache file" -#~ msgstr "Desactivar archivo de antememoria" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es_ES/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es_ES/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 8bbca1c..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es_ES/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es_ES/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es_ES/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index 6f495f1..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/es_ES/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,63 +0,0 @@ -# Spanish translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# Javier Junquera , 2016. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-10-12 16:08+0100\n" -"PO-Revision-Date: 2016-10-12 16:16+0200\n" -"Last-Translator: Javier Junquera \n" -"Language-Team: Español; Castellano <>\n" -"Language: es_ES\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: \n" - -#: prefs.js:81 -msgid "Toggle the menu" -msgstr "Abrir menú" - -#: prefs.js:83 extension.js:106 -msgid "Clear history" -msgstr "Borrar historial" - -#: prefs.js:85 -msgid "Previous entry" -msgstr "Entrada anterior" - -#: prefs.js:87 -msgid "Next entry" -msgstr "Siguiente entrada" - -#: prefs.js:100 -msgid "History Size" -msgstr "Tamaño del historial" - -#: prefs.js:105 -msgid "Refresh Interval (ms)" -msgstr "Intervalo de actualización (ms)" - -#: prefs.js:110 -msgid "Preview Size (characters)" -msgstr "Tamaño de la vista previa (caracteres)" - -#: prefs.js:115 -msgid "Max Cache File Size (kb)" -msgstr "Tamaño máximo de la caché (kb)" - -#: prefs.js:120 -msgid "Keyboard shortcuts" -msgstr "Atajos de teclado" - -#: extension.js:111 -msgid "Settings" -msgstr "Configuración" - -#: extension.js:187 -msgid "Clipboard history cleared" -msgstr "Historial del portapapeles borrado" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/eu/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/eu/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 913ddc8..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/eu/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/eu/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/eu/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index be579df..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/eu/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,139 +0,0 @@ -# Basque translation for gnome-shell-extension-clipboard-indicator. -# This file is distributed under the same license as the Dash to Dock package. -# Ibai Oihanguren Sala , 2020. -# -msgid "" -msgstr "" -"Project-Id-Version: gnome-shell-extension-clipboard-indicator\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2020-10-05 23:34+0200\n" -"Last-Translator: Ibai Oihanguren Sala \n" -"Language-Team: \n" -"Language: eu\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "Testua hemen azalduko da" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Idatzi hemen bilatzeko..." - -#: extension.js:198 -msgid "Private mode" -msgstr "Modu pribatua" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Garbitu historia" - -#: extension.js:210 -msgid "Settings" -msgstr "Ezarpenak" - -#: extension.js:339 -msgid "Clear all?" -msgstr "Guztia garbitu?" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "Ziur arbeleko elementu guztiak kendu nahi dituzula?" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "Ezin da eragiketa hau desegin." - -#: extension.js:343 -msgid "Clear" -msgstr "Garbitu" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "Utzi" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Arbelaren historia garbituta" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Arbelera kopiatuta" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Erakutsi/ezkutatu menua" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Aurreko sarrera" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Hurrengo sarrera" - -#: prefs.js:120 -msgid "History Size" -msgstr "Historiaren tamaina" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Berritze-maiztasuna (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Aurrebistaren tamaina (karaktereak)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Cache fitxategiaren gehienezko tamaina (kb)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "Cacheratu gogokoak soilik" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Erakutsi jakinarazpena kopiatzean" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "Eraman elementua goraino hautatu ostean" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Laster-teklak" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Goiko barrako karaktere kopurua" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Zer erakutsi goiko barran" - -#: prefs.js:170 -msgid "Remove down arrow in top bar" -msgstr "Kendu beheranzko gezia goiko barran" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "Kendu testuaren inguruko hutsuneak" - -#: prefs.js:232 -msgid "Icon" -msgstr "Ikonoa" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Arbelaren edukia" - -#: prefs.js:234 -msgid "Both" -msgstr "Biak" - -#~ msgid "Enable Deletion" -#~ msgstr "Gaitu ezabaketa" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fi/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fi/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index eaeec15..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fi/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fi/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fi/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index aa6165c..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fi/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,140 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# Jiri Grönroos , 2017. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2017-09-06 09:53+0300\n" -"Last-Translator: Jiri Grönroos \n" -"Language-Team: suomi \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Gtranslator 2.91.7\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "" - -#: extension.js:198 -msgid "Private mode" -msgstr "Yksityistila" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Tyhjennä historia" - -#: extension.js:210 -msgid "Settings" -msgstr "Asetukset" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Leikepöydän sisältö tyhjennetty" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Kopioitu leikepöydälle" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Näytä/piilota valikko" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Edellinen tietue" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Seuraava tietue" - -#: prefs.js:120 -msgid "History Size" -msgstr "Historian koko" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Päivitysväli (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Esikatselun koko (merkkejä)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Välimuistin enimmäiskoko (kt)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Näytä ilmoitus kopioitaessa" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Pikanäppäimet" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "" - -#: prefs.js:170 -msgid "Remove down arrow in top bar" -msgstr "" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "" - -#: prefs.js:234 -msgid "Both" -msgstr "" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fr_FR/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fr_FR/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 0f40152..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fr_FR/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fr_FR/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fr_FR/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index 98af447..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/fr_FR/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,143 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2020-05-04 11:15+0200\n" -"Last-Translator: Raphael Rochet \n" -"Language-Team: \n" -"Language: fr_FR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.3\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "(Vide)" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Tapez ici pour chercher ..." - -#: extension.js:198 -msgid "Private mode" -msgstr "Mode privé" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Vider l'historique" - -#: extension.js:210 -msgid "Settings" -msgstr "Paramètres" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "Annuler" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Historique vidé" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Copié dans le presse-papier" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Afficher/cacher le menu" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Entrée précédente" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Entrée suivante" - -#: prefs.js:120 -msgid "History Size" -msgstr "Taille de l'historique" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Intervalle d'actualisation (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Longueur de l'aperçu (caractères)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Taille max du cache (Kio)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "Ne mémoriser que les favoris" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Afficher une notification à chaque copie" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "Déplacer l'élément sélectionné en haut" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Raccourcis clavier" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Nombre de caractères dans le panneau" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Afficher dans le panneau" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Nombre de caractères dans le panneau" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "Supprimer les espaces autour du texte" - -#: prefs.js:232 -msgid "Icon" -msgstr "Icône" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Contenu" - -#: prefs.js:234 -msgid "Both" -msgstr "Les deux" - -#~ msgid "Enable Deletion" -#~ msgstr "Activer la suppression" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/hu/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/hu/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 5a837f2..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/hu/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/hu/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/hu/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index 3b4e337..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/hu/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,143 +0,0 @@ -# Hungarian translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) 2014-2015, Yotam Bar-On -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# uno20001 , 2020. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2020-06-01 14:14+0200\n" -"Last-Translator: uno20001 \n" -"Language-Team: \n" -"Language: hu\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "A szöveg itt fog megjelenni" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Írj ide a kereséshez..." - -#: extension.js:198 -msgid "Private mode" -msgstr "Privát mód" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Előzmények törlése" - -#: extension.js:210 -msgid "Settings" -msgstr "Beállítások" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "Mégse" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Vágólap előzmények törölve" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Vágólapra másolva" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Menü megnyitása/bezárása" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Előző" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Következő" - -#: prefs.js:120 -msgid "History Size" -msgstr "Előzmények száma" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Frissítési időköz (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Előnézet mérete (karakter)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Gyorsítótár mérete (KiB)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "Csak a kedvencek gyorsítótárazása" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Értesítés vágólapra másoláskor" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "Első helyre mozgatás kiválasztás után" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Gyorsbillentyűk" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Karakterek száma a felső sávban" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Mi legyen látható a felső sávban" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Karakterek száma a felső sávban" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "Szóközök törlése a szöveg körül" - -#: prefs.js:232 -msgid "Icon" -msgstr "Ikon" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Vágólap tartalma" - -#: prefs.js:234 -msgid "Both" -msgstr "Mindkettő" - -#~ msgid "Enable Deletion" -#~ msgstr "Törlés engedélyezése" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/it/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/it/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 512e375..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/it/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/it/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/it/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index c9f4d4a..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/it/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,146 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2018-05-17 09:27+0200\n" -"Last-Translator: Robin \n" -"Language-Team: jimmy.scionti@gmail.com\n" -"Language: it\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.6\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "Il testo sarà qui" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Digita qui per cercare…" - -#: extension.js:198 -msgid "Private mode" -msgstr "Modalità privata" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Cancella la cronologia" - -#: extension.js:210 -msgid "Settings" -msgstr "Impostazioni" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "Annulla" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Cronologia cancellata" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Copiato negli appunti" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Mostra/nascondi il menu" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Voce precedente" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Voce successiva" - -#: prefs.js:120 -msgid "History Size" -msgstr "Dimensioni della cronologia" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Intervallo di aggiornamento (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Dimensioni dell'anteprima (caratteri)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Dimensioni massime della cache (kB)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "Metti in cache solo i preferiti" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Mostra una notifica quando copi" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "Porta l'elemento in cima dopo la selezione" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Scorciatoie da tastiera" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Numero di caratteri sul pannello" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Cosa mostrare sul pannello" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Numero di caratteri sul pannello" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "Rimuovi lo spazio bianco intorno al testo" - -#: prefs.js:232 -msgid "Icon" -msgstr "Icona" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Contenuto Clipboard" - -#: prefs.js:234 -msgid "Both" -msgstr "Entrambi" - -#~ msgid "Enable Deletion" -#~ msgstr "Abilita cancellazione" - -#~ msgid "Disable cache file" -#~ msgstr "Disabilità la cache dei file" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ja/LC_MESSAGES/ja.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ja/LC_MESSAGES/ja.mo deleted file mode 100644 index 1b54742..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ja/LC_MESSAGES/ja.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ja/LC_MESSAGES/ja.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ja/LC_MESSAGES/ja.po deleted file mode 100644 index 381802a..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ja/LC_MESSAGES/ja.po +++ /dev/null @@ -1,150 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2018-05-14 15:47+0900\n" -"Last-Translator: AKIRA \n" -"Language-Team: \n" -"Language: ja\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.6\n" -"X-Poedit-Basepath: .\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Poedit-SearchPath-0: prefs.js\n" -"X-Poedit-SearchPath-1: extension.js\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "ここにテキストを入力" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "検索ワードを入力..." - -#: extension.js:198 -msgid "Private mode" -msgstr "プライベートモード" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "履歴を消去" - -#: extension.js:210 -msgid "Settings" -msgstr "設定" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "消去しました" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "コピーしました" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "メニュー" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "前へ" - -#: prefs.js:111 -msgid "Next entry" -msgstr "次へ" - -#: prefs.js:120 -msgid "History Size" -msgstr "保存件数" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "更新間隔(ミリ秒)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "プレビュー文字数" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "最大キャッシュサイズ(KB)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "コピー時に通知を表示する" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "キーボードショートカット" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "" -"トップバーの単語数\n" -"\t" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "表示内容" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "" -"トップバーの単語数\n" -"\t" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "アイコン" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "クリップボードの内容" - -#: prefs.js:234 -msgid "Both" -msgstr "両方" - -#~ msgid "Disable cache file" -#~ msgstr "キャッシュを無効化" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pl/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pl/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index b866d47..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pl/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pl/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pl/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index 0bdde2f..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pl/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,149 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2017-12-02 09:23+0100\n" -"Last-Translator: Piotr Komur \n" -"Language-Team: \n" -"Language: pl_PL\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.4\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2);\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Szukaj..." - -#: extension.js:198 -msgid "Private mode" -msgstr "Tryb prywatny" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Wyczyść historię" - -#: extension.js:210 -msgid "Settings" -msgstr "Ustawienia" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Wyczyszczono historię schowka" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Skopiowano do schowka" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Przełącz menu" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Poprzednia pozycja" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Następna pozycja" - -#: prefs.js:120 -msgid "History Size" -msgstr "Rozmiar historii (liczba elementów)" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Interwał odświeżania (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Rozmiar podglądu (znaki)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Maksymalny rozmiar pliku pamięci podręcznej (kB)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Pokaż powiadomienie po skopiowaniu" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Skróty klawiszowe" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Liczba znaków na panelu" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Pokazuj na panelu" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Liczba znaków na panelu" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "Ikona" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Zawartość schowka" - -#: prefs.js:234 -msgid "Both" -msgstr "Ikona oraz zawartość schowka" - -#~ msgid "Disable cache file" -#~ msgstr "Nie zapisuj do pliku pamięci podręcznej " - -#, fuzzy -#~| msgid "Clipboard Content" -#~ msgid "Icon + Clipboard Content" -#~ msgstr "Zawartość schowka" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pt_BR/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pt_BR/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 7a229c0..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pt_BR/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pt_BR/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pt_BR/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index af07b71..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/pt_BR/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,146 +0,0 @@ -# Brazilian Portuguese translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Diego R Lima , 2017. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2017-11-09 03:01-0300\n" -"Last-Translator: Diego R Lima \n" -"Language-Team: \n" -"Language: pt_BR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.3\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Poedit-Basepath: ../../..\n" -"X-Poedit-SearchPath-0: prefs.js\n" -"X-Poedit-SearchPath-1: extension.js\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "O texto estará aqui" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Digite aqui para pesquisar..." - -#: extension.js:198 -msgid "Private mode" -msgstr "Modo privado" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Apagar histórico" - -#: extension.js:210 -msgid "Settings" -msgstr "Configurações" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Histórico da área de transferência apagado" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Copiado para a área de transferência" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Abrir menu" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Entrada anterior" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Próxima entrada" - -#: prefs.js:120 -msgid "History Size" -msgstr "Tamanho do histórico" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Intervalo de atualização (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Tamanho da visualização (caracteres)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Tamanho máximo do arquivo de cache (kb)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Mostrar notificação sobre cópia" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Atalhos do teclado" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Número de caracteres na barra superior" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "O que mostrar na barra superior" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Número de caracteres na barra superior" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "" - -#: prefs.js:234 -msgid "Both" -msgstr "" - -#~ msgid "Disable cache file" -#~ msgstr "Desabilitar arquivo de cache" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ru/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ru/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 74113e1..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ru/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ru/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ru/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index c4c54bf..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/ru/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,143 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Dragonic , 2017. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2017-10-26 14:48+0700\n" -"Last-Translator: dmig \n" -"Language-Team: \n" -"Language: ru\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2);\n" -"X-Generator: Poedit 2.0.1\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "" - -#: extension.js:198 -msgid "Private mode" -msgstr "Приватный режим" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Очистить историю" - -#: extension.js:210 -msgid "Settings" -msgstr "Настройки" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "История буфера очищена" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Скопировано в буфер" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Показать меню" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Предыдущая запись" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Следующая запись" - -#: prefs.js:120 -msgid "History Size" -msgstr "Размер истории" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Интервал обновления (мс)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Длина строки в меню (символов)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Максимальный размер кэша (кб)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Уведомление при копировании" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Горячие клавиши" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "" - -#: prefs.js:170 -msgid "Remove down arrow in top bar" -msgstr "" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "" - -#: prefs.js:234 -msgid "Both" -msgstr "" - -#~ msgid "Disable cache file" -#~ msgstr "Отключить кэш" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/sk/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/sk/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 257621b..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/sk/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/sk/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/sk/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index bf7b515..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/sk/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,149 +0,0 @@ -# Slovak translation for gnome-shell-extension-clipboard-indicator -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# Jose Riha , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2019-10-16 23:03+0200\n" -"Last-Translator: Jose Riha \n" -"Language-Team: \n" -"Language: sk_SK\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2.1\n" -"X-Poedit-Basepath: .\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n>=2 && n<=4 ? 1 : 2);\n" -"X-Poedit-SearchPath-0: prefs.js\n" -"X-Poedit-SearchPath-1: extension.js\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "Tu bude text" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "Kliknite sem pre vyhľadávanie..." - -#: extension.js:198 -msgid "Private mode" -msgstr "Súkromný režim" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Vymazanie histórie" - -#: extension.js:210 -msgid "Settings" -msgstr "Nastavenia" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "Zrušiť" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "História schránky vymazaná" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Skopírované do schránky" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Prepnutie ponuky" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Predchádzajúca položka" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Nasledujúca položka" - -#: prefs.js:120 -msgid "History Size" -msgstr "Veľkosť histórie" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Interval obnovovania (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Veľkosť náhľadu (v znakoch)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "Maximálna veľkosť súboru vyrovnávacej pamäte (kb)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "Do vyrovnávacej pamäte ukladať len obľúbené" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Zobraziť upozornenie pri kopírovaní" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "Po výbere presunúť položku na začiatok zoznamu" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Klávesové skratky" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "Počet znakov v hornom riadku" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "Čo zobraziť v hornom riadku" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "Počet znakov v hornom riadku" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "Odstraňovať medzery pred a za textom" - -#: prefs.js:232 -msgid "Icon" -msgstr "Ikona" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "Obsah schránky" - -#: prefs.js:234 -msgid "Both" -msgstr "Obidve" - -#~ msgid "Enable Deletion" -#~ msgstr "Povoliť mazanie" - -#~ msgid "Disable cache file" -#~ msgstr "Zakázať súbor vyrovnávacej pamäte" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/tr/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/tr/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index e9b5a75..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/tr/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/tr/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/tr/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index 6c226df..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/tr/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,139 +0,0 @@ -# Turkish translation for gnome-shell-extension-clipboard-indicator. -# Copyright (C) 2017-2018, neynefes -# This file is distributed under the same license as the gnome-shell-extension-clipboard-indicator package. -# Hüseyin Karacabey , 2017. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2017-04-30 00:23+0300\n" -"Last-Translator: neynefes - Hüseyin Karacabey \n" -"Language-Team: Turkish \n" -"Language: tr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Atom 1.16.0\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "" - -#: extension.js:198 -msgid "Private mode" -msgstr "Gizli Kip" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "Geçmişi temizle" - -#: extension.js:210 -msgid "Settings" -msgstr "Ayarlar" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "Pano geçmişi temizlendi" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "Panoya kopyalandı" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "Menüyü değiştir" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "Önceki girdi" - -#: prefs.js:111 -msgid "Next entry" -msgstr "Sonraki girdi" - -#: prefs.js:120 -msgid "History Size" -msgstr "Geçmiş Boyutu" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "Yenileme Sıklığı (ms)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "Önizleme Boyutu (karakter)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "En Yüksek Önbelek Boyutu (kb)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "Kopyalandığında bildirim göster" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "Kılavye kısayolları" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "" - -#: prefs.js:170 -msgid "Remove down arrow in top bar" -msgstr "" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "" - -#: prefs.js:234 -msgid "Both" -msgstr "" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/zh_CN/LC_MESSAGES/clipboard-indicator.mo b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/zh_CN/LC_MESSAGES/clipboard-indicator.mo deleted file mode 100644 index 635d70e..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/zh_CN/LC_MESSAGES/clipboard-indicator.mo and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/zh_CN/LC_MESSAGES/clipboard-indicator.po b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/zh_CN/LC_MESSAGES/clipboard-indicator.po deleted file mode 100644 index 3919571..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/locale/zh_CN/LC_MESSAGES/clipboard-indicator.po +++ /dev/null @@ -1,146 +0,0 @@ -# Chinese translations for PACKAGE package. -# Copyright (C) 2015 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# 绿色圣光 , 2015, 2017. -# Zhang WenChao , 2018 -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-10-23 20:10+0300\n" -"PO-Revision-Date: 2018-09-06 15:42+0800\n" -"Last-Translator: Zhang WenChao \n" -"Language-Team: \n" -"Language: zh_CN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.4\n" -"X-Poedit-Basepath: .\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Poedit-SearchPath-0: prefs.js\n" -"X-Poedit-SearchPath-1: extension.js\n" - -#: extension.js:87 -msgid "Text will be here" -msgstr "文本将在此处" - -#: extension.js:129 -msgid "Type here to search..." -msgstr "点击搜索…" - -#: extension.js:198 -msgid "Private mode" -msgstr "隐私模式" - -#: extension.js:205 prefs.js:107 -msgid "Clear history" -msgstr "清空历史" - -#: extension.js:210 -msgid "Settings" -msgstr "设置" - -#: extension.js:339 -msgid "Clear all?" -msgstr "" - -#: extension.js:340 -msgid "Are you sure you want to delete all clipboard items?" -msgstr "" - -#: extension.js:341 -msgid "This operation cannot be undone." -msgstr "" - -#: extension.js:343 -msgid "Clear" -msgstr "" - -#: extension.js:343 extension.js:492 -msgid "Cancel" -msgstr "" - -#: extension.js:357 -msgid "Clipboard history cleared" -msgstr "剪贴板已清空" - -#: extension.js:491 -msgid "Copied to clipboard" -msgstr "已复制到剪贴板" - -#: prefs.js:105 -msgid "Toggle the menu" -msgstr "切换菜单" - -#: prefs.js:109 -msgid "Previous entry" -msgstr "上一条" - -#: prefs.js:111 -msgid "Next entry" -msgstr "下一条" - -#: prefs.js:120 -msgid "History Size" -msgstr "历史条数" - -#: prefs.js:125 -msgid "Refresh Interval (ms)" -msgstr "刷新间隔(毫秒)" - -#: prefs.js:130 -msgid "Preview Size (characters)" -msgstr "预览大小(字符)" - -#: prefs.js:135 -msgid "Max cache file size (kb)" -msgstr "最大缓存文件大小(kb)" - -#: prefs.js:140 -msgid "Cache only favorites" -msgstr "" - -#: prefs.js:145 -msgid "Show notification on copy" -msgstr "复制时显示通知" - -#: prefs.js:150 -msgid "Move item to the top after selection" -msgstr "" - -#: prefs.js:155 -msgid "Keyboard shortcuts" -msgstr "键盘快捷键" - -#: prefs.js:160 -msgid "Number of characters in top bar" -msgstr "顶栏显示的字符数量" - -#: prefs.js:165 -msgid "What to show in top bar" -msgstr "如何在顶栏显示" - -#: prefs.js:170 -#, fuzzy -msgid "Remove down arrow in top bar" -msgstr "顶栏显示的字符数量" - -#: prefs.js:175 -msgid "Remove whitespace around text" -msgstr "" - -#: prefs.js:232 -msgid "Icon" -msgstr "图标" - -#: prefs.js:233 -msgid "Clipboard Content" -msgstr "剪贴板内容" - -#: prefs.js:234 -msgid "Both" -msgstr "全部" - -#~ msgid "Disable cache file" -#~ msgstr "关闭文件缓存" diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/metadata.json b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/metadata.json deleted file mode 100644 index 410d4b2..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/metadata.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "_generated": "Generated by SweetTooth, do not edit", - "description": "Clipboard Manager extension for Gnome-Shell - Adds a clipboard indicator to the top panel, and caches clipboard history.", - "name": "Clipboard Indicator", - "shell-version": [ - "3.38" - ], - "url": "https://github.com/Tudmotu/gnome-shell-extension-clipboard-indicator", - "uuid": "clipboard-indicator@tudmotu.com", - "version": 37 -} \ No newline at end of file diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/prefs.js b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/prefs.js deleted file mode 100644 index ec7fd0d..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/prefs.js +++ /dev/null @@ -1,343 +0,0 @@ -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Gio = imports.gi.Gio; -const Lang = imports.lang; -const Extension = imports.misc.extensionUtils.getCurrentExtension(); -const Utils = Extension.imports.utils; -const prettyPrint = Utils.prettyPrint; - -const Gettext = imports.gettext; -const _ = Gettext.domain('clipboard-indicator').gettext; - -var Fields = { - INTERVAL : 'refresh-interval', - HISTORY_SIZE : 'history-size', - PREVIEW_SIZE : 'preview-size', - CACHE_FILE_SIZE : 'cache-size', - CACHE_ONLY_FAVORITE : 'cache-only-favorites', - DELETE : 'enable-deletion', - NOTIFY_ON_COPY : 'notify-on-copy', - MOVE_ITEM_FIRST : 'move-item-first', - ENABLE_KEYBINDING : 'enable-keybindings', - TOPBAR_PREVIEW_SIZE : 'topbar-preview-size', - TOPBAR_DISPLAY_MODE_ID : 'display-mode', - DISABLE_DOWN_ARROW : 'disable-down-arrow', - STRIP_TEXT : 'strip-text' -}; - -const SCHEMA_NAME = 'org.gnome.shell.extensions.clipboard-indicator'; - -const getSchema = function () { - let schemaDir = Extension.dir.get_child('schemas').get_path(); - let schemaSource = Gio.SettingsSchemaSource.new_from_directory(schemaDir, Gio.SettingsSchemaSource.get_default(), false); - let schema = schemaSource.lookup(SCHEMA_NAME, false); - - return new Gio.Settings({ settings_schema: schema }); -}; - -var SettingsSchema = getSchema(); - - -function init() { - let localeDir = Extension.dir.get_child('locale'); - if (localeDir.query_exists(null)) - Gettext.bindtextdomain('clipboard-indicator', localeDir.get_path()); -} - -const App = new Lang.Class({ - Name: 'ClipboardIndicator.App', - _init: function() { - this.main = new Gtk.Grid({ - margin: 10, - row_spacing: 12, - column_spacing: 18, - column_homogeneous: false, - row_homogeneous: false - }); - this.field_interval = new Gtk.SpinButton({ - adjustment: new Gtk.Adjustment({ - lower: 500, - upper: 5000, - step_increment: 100 - }) - }); - this.field_size = new Gtk.SpinButton({ - adjustment: new Gtk.Adjustment({ - lower: 1, - upper: 200, - step_increment: 1 - }) - }); - this.field_preview_size = new Gtk.SpinButton({ - adjustment: new Gtk.Adjustment({ - lower: 10, - upper: 100, - step_increment: 1 - }) - }); - this.field_cache_size = new Gtk.SpinButton({ - adjustment: new Gtk.Adjustment({ - lower: 512, - upper: Math.pow(2, 14), - step_increment: 1 - }) - }); - this.field_topbar_preview_size = new Gtk.SpinButton({ - adjustment: new Gtk.Adjustment({ - lower: 1, - upper: 100, - step_increment: 1 - }) - }); - this.field_display_mode = new Gtk.ComboBox({ - model: this._create_display_mode_options()}); - - let rendererText = new Gtk.CellRendererText(); - this.field_display_mode.pack_start (rendererText, false); - this.field_display_mode.add_attribute (rendererText, "text", 0); - this.field_disable_down_arrow = new Gtk.Switch(); - this.field_cache_disable = new Gtk.Switch(); - this.field_notification_toggle = new Gtk.Switch(); - this.field_strip_text = new Gtk.Switch(); - this.field_move_item_first = new Gtk.Switch(); - this.field_keybinding = createKeybindingWidget(SettingsSchema); - addKeybinding(this.field_keybinding.model, SettingsSchema, "toggle-menu", - _("Toggle the menu")); - addKeybinding(this.field_keybinding.model, SettingsSchema, "clear-history", - _("Clear history")); - addKeybinding(this.field_keybinding.model, SettingsSchema, "prev-entry", - _("Previous entry")); - addKeybinding(this.field_keybinding.model, SettingsSchema, "next-entry", - _("Next entry")); - - var that = this; - this.field_keybinding_activation = new Gtk.Switch(); - this.field_keybinding_activation.connect("notify::active", function(widget){ - that.field_keybinding.set_sensitive(widget.active); - }); - - let sizeLabel = new Gtk.Label({ - label: _("History Size"), - hexpand: true, - halign: Gtk.Align.START - }); - let intervalLabel = new Gtk.Label({ - label: _("Refresh Interval (ms)"), - hexpand: true, - halign: Gtk.Align.START - }); - let previewLabel = new Gtk.Label({ - label: _("Preview Size (characters)"), - hexpand: true, - halign: Gtk.Align.START - }); - let cacheSizeLabel = new Gtk.Label({ - label: _("Max cache file size (kb)"), - hexpand: true, - halign: Gtk.Align.START - }); - let cacheDisableLabel = new Gtk.Label({ - label: _("Cache only favorites"), - hexpand: true, - halign: Gtk.Align.START - }); - let notificationLabel = new Gtk.Label({ - label: _("Show notification on copy"), - hexpand: true, - halign: Gtk.Align.START - }); - let moveFirstLabel = new Gtk.Label({ - label: _("Move item to the top after selection"), - hexpand: true, - halign: Gtk.Align.START - }); - let keybindingLabel = new Gtk.Label({ - label: _("Keyboard shortcuts"), - hexpand: true, - halign: Gtk.Align.START - }); - let topbarPreviewLabel = new Gtk.Label({ - label: _("Number of characters in top bar"), - hexpand: true, - halign: Gtk.Align.START - }); - let displayModeLabel = new Gtk.Label({ - label: _("What to show in top bar"), - hexpand: true, - halign: Gtk.Align.START - }); - let disableDownArrowLabel = new Gtk.Label({ - label: _("Remove down arrow in top bar"), - hexpand: true, - halign: Gtk.Align.START - }); - let stripTextLabel = new Gtk.Label({ - label: _("Remove whitespace around text"), - hexpand: true, - halign: Gtk.Align.START - }); - - const addRow = ((main) => { - let row = 0; - return (label, input) => { - let inputWidget = input; - - if (input instanceof Gtk.Switch) { - inputWidget = new Gtk.HBox(); - inputWidget.pack_end(input, false, false, 0); - } - - if (label) { - main.attach(label, 0, row, 1, 1); - main.attach(inputWidget, 1, row, 1, 1); - } - else { - main.attach(inputWidget, 0, row, 2, 1); - } - - row++; - }; - })(this.main); - - addRow(sizeLabel, this.field_size); - addRow(previewLabel, this.field_preview_size); - addRow(intervalLabel, this.field_interval); - addRow(cacheSizeLabel, this.field_cache_size); - addRow(cacheDisableLabel, this.field_cache_disable); - addRow(notificationLabel, this.field_notification_toggle); - addRow(displayModeLabel, this.field_display_mode); - addRow(disableDownArrowLabel, this.field_disable_down_arrow); - addRow(topbarPreviewLabel, this.field_topbar_preview_size); - addRow(stripTextLabel, this.field_strip_text); - addRow(moveFirstLabel, this.field_move_item_first); - addRow(keybindingLabel, this.field_keybinding_activation); - addRow(null, this.field_keybinding); - - SettingsSchema.bind(Fields.INTERVAL, this.field_interval, 'value', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.HISTORY_SIZE, this.field_size, 'value', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.PREVIEW_SIZE, this.field_preview_size, 'value', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.CACHE_FILE_SIZE, this.field_cache_size, 'value', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.CACHE_ONLY_FAVORITE, this.field_cache_disable, 'active', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.NOTIFY_ON_COPY, this.field_notification_toggle, 'active', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.MOVE_ITEM_FIRST, this.field_move_item_first, 'active', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.TOPBAR_DISPLAY_MODE_ID, this.field_display_mode, 'active', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.DISABLE_DOWN_ARROW, this.field_disable_down_arrow, 'active', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.TOPBAR_PREVIEW_SIZE, this.field_topbar_preview_size, 'value', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.STRIP_TEXT, this.field_strip_text, 'active', Gio.SettingsBindFlags.DEFAULT); - SettingsSchema.bind(Fields.ENABLE_KEYBINDING, this.field_keybinding_activation, 'active', Gio.SettingsBindFlags.DEFAULT); - - this.main.show_all(); - }, - _create_display_mode_options : function(){ - let options = [{ name: _("Icon") }, - { name: _("Clipboard Content"),}, - { name: _("Both")}]; - let liststore = new Gtk.ListStore(); - liststore.set_column_types([GObject.TYPE_STRING]) - for (let i = 0; i < options.length; i++ ) { - let option = options[i]; - let iter = liststore.append(); - liststore.set (iter, [0], [option.name]); - } - return liststore; - } -}); - -function buildPrefsWidget(){ - let widget = new App(); - return widget.main; -} - - -//binding widgets -////////////////////////////////// -const COLUMN_ID = 0; -const COLUMN_DESCRIPTION = 1; -const COLUMN_KEY = 2; -const COLUMN_MODS = 3; - - -function addKeybinding(model, settings, id, description) { - // Get the current accelerator. - let accelerator = settings.get_strv(id)[0]; - let key, mods; - if (accelerator == null) - [key, mods] = [0, 0]; - else - [key, mods] = Gtk.accelerator_parse(settings.get_strv(id)[0]); - - // Add a row for the keybinding. - let row = model.insert(100); // Erm... - model.set(row, - [COLUMN_ID, COLUMN_DESCRIPTION, COLUMN_KEY, COLUMN_MODS], - [id, description, key, mods]); -} - -function createKeybindingWidget(SettingsSchema) { - let model = new Gtk.ListStore(); - - model.set_column_types( - [GObject.TYPE_STRING, // COLUMN_ID - GObject.TYPE_STRING, // COLUMN_DESCRIPTION - GObject.TYPE_INT, // COLUMN_KEY - GObject.TYPE_INT]); // COLUMN_MODS - - let treeView = new Gtk.TreeView(); - treeView.model = model; - treeView.headers_visible = false; - - let column, renderer; - - // Description column. - renderer = new Gtk.CellRendererText(); - - column = new Gtk.TreeViewColumn(); - column.expand = true; - column.pack_start(renderer, true); - column.add_attribute(renderer, "text", COLUMN_DESCRIPTION); - - treeView.append_column(column); - - // Key binding column. - renderer = new Gtk.CellRendererAccel(); - renderer.accel_mode = Gtk.CellRendererAccelMode.GTK; - renderer.editable = true; - - renderer.connect("accel-edited", - function (renderer, path, key, mods, hwCode) { - let [ok, iter] = model.get_iter_from_string(path); - if(!ok) - return; - - // Update the UI. - model.set(iter, [COLUMN_KEY, COLUMN_MODS], [key, mods]); - - // Update the stored setting. - let id = model.get_value(iter, COLUMN_ID); - let accelString = Gtk.accelerator_name(key, mods); - SettingsSchema.set_strv(id, [accelString]); - }); - - renderer.connect("accel-cleared", - function (renderer, path) { - let [ok, iter] = model.get_iter_from_string(path); - if(!ok) - return; - - // Update the UI. - model.set(iter, [COLUMN_KEY, COLUMN_MODS], [0, 0]); - - // Update the stored setting. - let id = model.get_value(iter, COLUMN_ID); - SettingsSchema.set_strv(id, []); - }); - - column = new Gtk.TreeViewColumn(); - column.pack_end(renderer, false); - column.add_attribute(renderer, "accel-key", COLUMN_KEY); - column.add_attribute(renderer, "accel-mods", COLUMN_MODS); - - treeView.append_column(column); - - return treeView; -} diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/schemas/gschemas.compiled b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/schemas/gschemas.compiled deleted file mode 100644 index 5da7ba9..0000000 Binary files a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/schemas/gschemas.compiled and /dev/null differ diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/schemas/org.gnome.shell.extensions.clipboard-indicator.gschema.xml b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/schemas/org.gnome.shell.extensions.clipboard-indicator.gschema.xml deleted file mode 100644 index c09c940..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/schemas/org.gnome.shell.extensions.clipboard-indicator.gschema.xml +++ /dev/null @@ -1,133 +0,0 @@ - - - - - true - Enable the deletion of clipboard items from your history - - If true, displays 'delete' buttons on each item, and a 'Clear History' option - - - - - 1000 - The interval between updates in miliseconds - The interval between updates in miliseconds - - - - - 15 - The number of items to save in history - - - - - - 0 - What to display in top bar - - - - - false - Remove down arrow in top bar - - - - 30 - Amount of visible characters for clipboard items - - The number of characters to display for every clipboard item in - the history menu - - - - - - 10 - Amount of visible characters in topbar - - The number of characters to display for current clipboard item in the topbar - - - - - - 1024 - The allowed size for the registry cache file - - If the cache overflows this limit, the file will be overriden. - High limit might cause slowness of shell startup. - - - - - - false - Disable the registry cache file for favorites and use memory only - - Contents which are not favorites are not stored and retrieved from a cache (registry.txt) file. - This can avoid writing passwords to a plaintext file, but at the cost of persistant history. - Your clipboard history, except favorite items, is lost after a gnome-shell session ends or the extension is reloaded. - - - - - false - Show notification on copy to clipboard - - If true, a notification is shown when content is copied to clipboard. - - - - false - Remove whitespace around text - - If true, white spaces around text will be removed. - - - - false - Move items to the top of the list when selected. - - If true, move items to the top of the list when it is selected. - - - - - true - Enable the keyboard shortcuts - - If true, user can delete and cycle through the history with keyboard shortcuts - - - - F10']]]> - Key to clear the history - - - - - F11']]]> - Key to cycle to the previous entry in the clipboard - - - - - F12']]]> - Next entry - - Key to cycle to the next entry in the clipboard - - - - F9']]]> - Toggle the menu - - Key to toggle the clipboard menu - - - - diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/stylesheet.css b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/stylesheet.css deleted file mode 100644 index 580b42b..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/stylesheet.css +++ /dev/null @@ -1,21 +0,0 @@ -.clipboard-indicator-icon.private-mode { - color: rgba(255,255,255,0.3); -} - -.ci-notification-label { - font-weight: bold; - color: #ffffff; - background-color: rgba(10,10,10,0.7); - border-radius: 6px; - font-size:2em; - padding:.5em; - width:400px; -} - -.popup-menu-item .ci-action-btn StIcon { - icon-size:16px; -} - -.ci-history-menu-section { - max-height:450px; -} diff --git a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/utils.js b/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/utils.js deleted file mode 100644 index 3a95b73..0000000 --- a/zorin/.local/share/gnome-shell/extensions/clipboard-indicator@tudmotu.com/utils.js +++ /dev/null @@ -1,134 +0,0 @@ -const GLib = imports.gi.GLib; -const Gio = imports.gi.Gio; -const FileQueryInfoFlags = imports.gi.Gio.FileQueryInfoFlags; -const FileCopyFlags = imports.gi.Gio.FileCopyFlags; -const FileTest = GLib.FileTest; - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Prefs = Me.imports.prefs; -const SettingsSchema = Prefs.SettingsSchema; - -const REGISTRY_DIR = GLib.get_user_cache_dir() + '/' + Me.uuid; -const REGISTRY_FILE = 'registry.txt'; -const REGISTRY_PATH = REGISTRY_DIR + '/' + REGISTRY_FILE; -const BACKUP_REGISTRY_PATH = REGISTRY_PATH + '~'; - -// Print objects... why no dev tools -function prettyPrint (name, obj, recurse, _indent) { - let prefix = ''; - let indent = typeof _indent === 'number' ? _indent : 0; - for (let i = 0; i < indent; i++) { - prefix += ' '; - } - - recurse = typeof recurse === 'boolean' ? recurse : true; - if (typeof name !== 'string') { - obj = arguments[0]; - recurse = arguments[1]; - _indent = arguments[2]; - name = obj.toString(); - } - - log(prefix + '--------------'); - log(prefix + name); - log(prefix + '--------------'); - for (let k in obj) { - if (typeof obj[k] === 'object' && recurse) { - prettyPrint(name + '::' + k, obj[k], true, indent + 1); - } - else { - log(prefix + k, typeof obj[k] === 'function' ? '[Func]' : obj[k]); - } - } -} - -// I/O Files -function writeRegistry (registry) { - let json = JSON.stringify(registry); - let contents = new GLib.Bytes(json); - - // Make sure dir exists - GLib.mkdir_with_parents(REGISTRY_DIR, parseInt('0775', 8)); - - // Write contents to file asynchronously - let file = Gio.file_new_for_path(REGISTRY_PATH); - file.replace_async(null, false, Gio.FileCreateFlags.NONE, - GLib.PRIORITY_DEFAULT, null, function (obj, res) { - - let stream = obj.replace_finish(res); - - stream.write_bytes_async(contents, GLib.PRIORITY_DEFAULT, - null, function (w_obj, w_res) { - - w_obj.write_bytes_finish(w_res); - stream.close(null); - }); - }); -} - -function readRegistry (callback) { - if (typeof callback !== 'function') - throw TypeError('`callback` must be a function'); - - if (GLib.file_test(REGISTRY_PATH, FileTest.EXISTS)) { - let file = Gio.file_new_for_path(REGISTRY_PATH); - let CACHE_FILE_SIZE = SettingsSchema.get_int(Prefs.Fields.CACHE_FILE_SIZE); - - file.query_info_async('*', FileQueryInfoFlags.NONE, - GLib.PRIORITY_DEFAULT, null, function (src, res) { - // Check if file size is larger than CACHE_FILE_SIZE - // If so, make a backup of file, and invoke callback with empty array - let file_info = src.query_info_finish(res); - - if (file_info.get_size() >= CACHE_FILE_SIZE * 1024) { - let destination = Gio.file_new_for_path(BACKUP_REGISTRY_PATH); - - file.move(destination, FileCopyFlags.OVERWRITE, null, null); - callback([]); - return; - } - - file.load_contents_async(null, function (obj, res) { - let registry; - let [success, contents] = obj.load_contents_finish(res); - - if (success) { - try { - let max_size = SettingsSchema.get_int(Prefs.Fields.HISTORY_SIZE); - - // are we running gnome 3.30 or higher? - if (contents instanceof Uint8Array) { - contents = imports.byteArray.toString(contents); - } - - registry = JSON.parse(contents); - - let registryNoFavorite = registry.filter( - item => item['favorite'] === false); - - while (registryNoFavorite.length > max_size) { - let oldestNoFavorite = registryNoFavorite.shift(); - let itemIdx = registry.indexOf(oldestNoFavorite); - registry.splice(itemIdx,1); - - registryNoFavorite = registry.filter( - item => item["favorite"] === false); - } - } - catch (e) { - registry = []; - } - } - else { - registry = []; - } - - callback(registry); - }); - }); - } - else { - callback([]); - } -} diff --git a/zorin/.local/share/gnome-shell/notifications b/zorin/.local/share/gnome-shell/notifications index a43b62e..382b475 100644 Binary files a/zorin/.local/share/gnome-shell/notifications and b/zorin/.local/share/gnome-shell/notifications differ