mirror of
https://github.com/edu4rdshl/Strata.git
synced 2026-07-17 23:24:46 +00:00
fix: address EGO review 72215 feedback
- Use GNOME's stylesheet-dark.css/stylesheet-light.css for theming instead of loading light.css into the theme context by hand; the panel now follows the shell style variant - Track signals with connectObject/disconnectObject - Clear the daemon-restart timeout before scheduling a new one - Stop the daemon synchronously in disable(), no deferred kill timer - Drop the unused theme setting and its prefs combo - Bump the metadata version to 11 for resubmission
This commit is contained in:
parent
b6fe86f418
commit
6c4fa04221
9 changed files with 162 additions and 327 deletions
1
Makefile
1
Makefile
|
|
@ -39,7 +39,6 @@ pack: schemas
|
|||
--extra-source=ui \
|
||||
--extra-source=dbus.js \
|
||||
--extra-source=util.js \
|
||||
--extra-source=light.css \
|
||||
--force
|
||||
@echo "Packed: $(EXTENSION_UUID).shell-extension.zip"
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ export default class StrataExtension extends Extension {
|
|||
_daemonRestartAttempts = 0;
|
||||
_shuttingDown = false;
|
||||
_daemonRestartTimerId = null;
|
||||
_daemonKillTimerId = null;
|
||||
/** True while a GetNameOwner check before spawning is in flight, so an
|
||||
* overlapping respawn attempt can't spawn a second daemon. */
|
||||
_spawnPending = false;
|
||||
|
|
@ -36,18 +35,12 @@ export default class StrataExtension extends Extension {
|
|||
_itemDeletedId = null;
|
||||
_historyClearedId = null;
|
||||
|
||||
/** @type {number | null} focused-window signal connection ID */
|
||||
_focusSignalId = null;
|
||||
|
||||
/** @type {string} WM class of the currently focused app (lower-cased) */
|
||||
_currentFocusedApp = '';
|
||||
|
||||
/** @type {object | null} PanelMenu.Button indicator */
|
||||
_indicator = null;
|
||||
|
||||
/** @type {number | null} Meta.Selection owner-changed signal ID */
|
||||
_selectionChangedId = null;
|
||||
|
||||
/** @type {number | null} Debounce timer for clipboard reads */
|
||||
_clipboardDebounceId = null;
|
||||
|
||||
|
|
@ -64,29 +57,16 @@ export default class StrataExtension extends Extension {
|
|||
enable() {
|
||||
this._shuttingDown = false;
|
||||
this._daemonRestartAttempts = 0;
|
||||
// Cancel any pending force-kill timer left over from a previous disable
|
||||
// (enable→disable→enable within 1.5s) so it can't outlive this cycle.
|
||||
if (this._daemonKillTimerId) {
|
||||
GLib.Source.remove(this._daemonKillTimerId);
|
||||
this._daemonKillTimerId = null;
|
||||
}
|
||||
|
||||
this._settings = this.getSettings();
|
||||
this._excludedApps = this._settings.get_strv('excluded-apps');
|
||||
this._excludedAppsChangedId = this._settings.connect('changed::excluded-apps', () => {
|
||||
this._excludedApps = this._settings.get_strv('excluded-apps');
|
||||
});
|
||||
|
||||
this._readSizeLimits();
|
||||
this._configChangedIds = [
|
||||
this._settings.connect('changed::max-history', () => { this._readSizeLimits(); this._pushConfig(); }),
|
||||
this._settings.connect('changed::max-text-mb', () => { this._readSizeLimits(); this._pushConfig(); }),
|
||||
this._settings.connect('changed::max-image-mb', () => { this._readSizeLimits(); this._pushConfig(); }),
|
||||
];
|
||||
|
||||
// Load the light theme overrides into the Shell theme context. They stay
|
||||
// inert until the panel toggles the `.strata-theme-light` class (panel.js).
|
||||
this._loadThemeStylesheet();
|
||||
this._settings.connectObject(
|
||||
'changed::excluded-apps', () => { this._excludedApps = this._settings.get_strv('excluded-apps'); },
|
||||
'changed::max-history', () => { this._readSizeLimits(); this._pushConfig(); },
|
||||
'changed::max-text-mb', () => { this._readSizeLimits(); this._pushConfig(); },
|
||||
'changed::max-image-mb', () => { this._readSizeLimits(); this._pushConfig(); },
|
||||
this);
|
||||
|
||||
this._addIndicator();
|
||||
this._spawnDaemon();
|
||||
|
|
@ -108,27 +88,13 @@ export default class StrataExtension extends Extension {
|
|||
this._disconnectFocusTracking();
|
||||
this._disconnectSignals();
|
||||
this._clearIdleSources();
|
||||
if (this._proxyOwnerId && this._proxy) {
|
||||
this._proxy.disconnect(this._proxyOwnerId);
|
||||
this._proxyOwnerId = 0;
|
||||
}
|
||||
if (this._configChangedIds && this._settings) {
|
||||
for (const id of this._configChangedIds) this._settings.disconnect(id);
|
||||
this._configChangedIds = null;
|
||||
}
|
||||
if (this._excludedAppsChangedId && this._settings) {
|
||||
this._settings.disconnect(this._excludedAppsChangedId);
|
||||
this._excludedAppsChangedId = null;
|
||||
}
|
||||
this._proxy?.disconnectObject(this);
|
||||
this._settings?.disconnectObject(this);
|
||||
this._panel?.destroy();
|
||||
this._panel = null;
|
||||
if (this._indicatorClickId && this._indicator) {
|
||||
this._indicator.disconnect(this._indicatorClickId);
|
||||
this._indicatorClickId = null;
|
||||
}
|
||||
this._indicator?.disconnectObject(this);
|
||||
this._indicator?.destroy();
|
||||
this._indicator = null;
|
||||
this._unloadThemeStylesheet();
|
||||
this._stopDaemon();
|
||||
this._proxy = null;
|
||||
this._settings = null;
|
||||
|
|
@ -143,20 +109,19 @@ export default class StrataExtension extends Extension {
|
|||
style_class: 'system-status-icon',
|
||||
});
|
||||
this._indicator.add_child(icon);
|
||||
this._indicatorClickId = this._indicator.connect('button-press-event', () => {
|
||||
this._indicator.connectObject('button-press-event', () => {
|
||||
this._panel?.toggle();
|
||||
return false; // EVENT_PROPAGATE
|
||||
});
|
||||
}, this);
|
||||
Main.panel.addToStatusArea('strata', this._indicator);
|
||||
}
|
||||
|
||||
|
||||
_connectClipboardMonitor() {
|
||||
const selection = global.display.get_selection();
|
||||
this._selectionChangedId = selection.connect('owner-changed', (_sel, type) => {
|
||||
global.display.get_selection().connectObject('owner-changed', (_sel, type) => {
|
||||
if (type !== Meta.SelectionType.SELECTION_CLIPBOARD) return;
|
||||
this._scheduleClipboardRead();
|
||||
});
|
||||
}, this);
|
||||
}
|
||||
|
||||
_disconnectClipboardMonitor() {
|
||||
|
|
@ -167,10 +132,7 @@ export default class StrataExtension extends Extension {
|
|||
this._clipboardDebounceId = null;
|
||||
}
|
||||
this._clipboardTransferPending = false;
|
||||
if (this._selectionChangedId !== null) {
|
||||
global.display.get_selection().disconnect(this._selectionChangedId);
|
||||
this._selectionChangedId = null;
|
||||
}
|
||||
global.display.get_selection().disconnectObject(this);
|
||||
}
|
||||
|
||||
/** Debounce entry point - coalesces rapid clipboard changes (e.g. from
|
||||
|
|
@ -347,6 +309,10 @@ export default class StrataExtension extends Extension {
|
|||
|
||||
_scheduleDaemonRestart() {
|
||||
if (this._shuttingDown) return;
|
||||
if (this._daemonRestartTimerId !== null) {
|
||||
GLib.Source.remove(this._daemonRestartTimerId);
|
||||
this._daemonRestartTimerId = null;
|
||||
}
|
||||
// Exponential backoff: 1s, 2s, 4s, 8s, 16s
|
||||
const backoffMs = 1000 * Math.pow(2, Math.max(0, this._daemonRestartAttempts - 1));
|
||||
this._daemonRestartTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, backoffMs, () => {
|
||||
|
|
@ -358,20 +324,9 @@ export default class StrataExtension extends Extension {
|
|||
|
||||
_stopDaemon() {
|
||||
if (!this._daemon) return;
|
||||
// Capture reference immediately so the timer doesn't kill a newly-spawned daemon.
|
||||
const daemonToStop = this._daemon;
|
||||
const daemon = this._daemon;
|
||||
this._daemon = null;
|
||||
try {
|
||||
// Graceful shutdown via D-Bus first.
|
||||
this._proxy?.ShutdownRemote(() => {});
|
||||
} catch { /* proxy may already be gone */ }
|
||||
// Give it 1.5s then force-terminate. Track the source so a re-enable
|
||||
// within that window can cancel it (see enable()).
|
||||
this._daemonKillTimerId = GLib.timeout_add(GLib.PRIORITY_LOW, 1500, () => {
|
||||
this._daemonKillTimerId = null;
|
||||
try { daemonToStop.send_signal(15); } catch { /* already exited */ } // SIGTERM
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
try { daemon.send_signal(15); } catch { /* already exited */ } // SIGTERM
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -393,8 +348,8 @@ export default class StrataExtension extends Extension {
|
|||
// again on every owner transition so a respawned
|
||||
// daemon picks up the latest values.
|
||||
this._pushConfig();
|
||||
this._proxyOwnerId = proxy.connect('notify::g-name-owner',
|
||||
() => { if (proxy.g_name_owner) this._pushConfig(); });
|
||||
proxy.connectObject('notify::g-name-owner',
|
||||
() => { if (proxy.g_name_owner) this._pushConfig(); }, this);
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
|
|
@ -511,17 +466,14 @@ export default class StrataExtension extends Extension {
|
|||
|
||||
|
||||
_connectFocusTracking() {
|
||||
this._focusSignalId = global.display.connect('notify::focus-window', () => {
|
||||
global.display.connectObject('notify::focus-window', () => {
|
||||
const win = global.display.focus_window;
|
||||
this._currentFocusedApp = (win?.get_wm_class() ?? '').toLowerCase();
|
||||
});
|
||||
}, this);
|
||||
}
|
||||
|
||||
_disconnectFocusTracking() {
|
||||
if (this._focusSignalId !== null) {
|
||||
global.display.disconnect(this._focusSignalId);
|
||||
this._focusSignalId = null;
|
||||
}
|
||||
global.display.disconnectObject(this);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -542,29 +494,4 @@ export default class StrataExtension extends Extension {
|
|||
_unregisterShortcut() {
|
||||
Main.wm.removeKeybinding('keyboard-shortcut');
|
||||
}
|
||||
|
||||
|
||||
/** Load light.css once. It is scoped under `.strata-theme-light` and stays
|
||||
* inert until the panel adds that class. We do not subscribe to the theme
|
||||
* context's 'changed' signal because load_stylesheet itself emits it. */
|
||||
_loadThemeStylesheet() {
|
||||
try {
|
||||
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
this._lightCssFile = this.dir.get_child('light.css');
|
||||
this._stTheme = themeContext.get_theme();
|
||||
this._stTheme.load_stylesheet(this._lightCssFile);
|
||||
} catch (e) {
|
||||
logError('Failed to load light.css', e);
|
||||
}
|
||||
}
|
||||
|
||||
_unloadThemeStylesheet() {
|
||||
try {
|
||||
this._stTheme?.unload_stylesheet(this._lightCssFile);
|
||||
} catch (e) {
|
||||
logError('Failed to unload light.css', e);
|
||||
}
|
||||
this._stTheme = null;
|
||||
this._lightCssFile = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,143 +0,0 @@
|
|||
/* Strata light theme.
|
||||
*
|
||||
* Loaded into the Shell theme context by extension.js and activated by toggling
|
||||
* the `.strata-theme-light` class on the panel root box (see ui/panel.js).
|
||||
* Every rule is scoped under `.strata-theme-light` so it is strictly more
|
||||
* specific than its counterpart in stylesheet.css and wins deterministically,
|
||||
* regardless of stylesheet load order. The dark theme (stylesheet.css) is left
|
||||
* untouched: with no class present, none of these rules apply.
|
||||
*
|
||||
* Colors follow GNOME Adwaita (blue #3584e4, link #1a5fb4, amber #b5830a,
|
||||
* red #e01b24) and are picked for contrast on a light panel.
|
||||
*
|
||||
* Performance rule (same as stylesheet.css): NO `transition: all`, NO
|
||||
* Clutter/CSS animations. Only background-color transitions on hover.
|
||||
*/
|
||||
|
||||
/* ── Panel container ────────────────────────────────────────────────────── */
|
||||
.strata-panel.strata-theme-light {
|
||||
background-color: rgba(250, 250, 250, 0.98);
|
||||
border-color: rgba(0, 0, 0, 0.14);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
/* ── Header ─────────────────────────────────────────────────────────────── */
|
||||
.strata-theme-light .strata-title {
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-clear-btn {
|
||||
border-color: rgba(0, 0, 0, 0.18);
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-clear-btn:hover {
|
||||
background-color: rgba(0, 0, 0, 0.07);
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
/* ── Search box ─────────────────────────────────────────────────────────── */
|
||||
.strata-theme-light .strata-search {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
border-color: rgba(0, 0, 0, 0.14);
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
caret-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-search:focus {
|
||||
border-color: rgba(53, 132, 228, 0.8);
|
||||
background-color: rgba(0, 0, 0, 0.035);
|
||||
}
|
||||
|
||||
/* Placeholder ("Search...") text - legible dim gray on the light panel. */
|
||||
.strata-theme-light .strata-search-hint {
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/* ── Clipboard item: hover / focus (Adwaita blue) ───────────────────────── */
|
||||
.strata-theme-light .strata-item:hover,
|
||||
.strata-theme-light .strata-item-hovered {
|
||||
background-color: rgba(53, 132, 228, 0.14);
|
||||
border-color: rgba(53, 132, 228, 0.45);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item:focus,
|
||||
.strata-theme-light .strata-item-focused {
|
||||
background-color: rgba(53, 132, 228, 0.16);
|
||||
border-color: rgba(53, 132, 228, 0.65);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item:hover:focus,
|
||||
.strata-theme-light .strata-item-focused.strata-item-hovered {
|
||||
background-color: rgba(53, 132, 228, 0.24);
|
||||
border-color: rgba(53, 132, 228, 0.78);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item:focus .strata-item-text,
|
||||
.strata-theme-light .strata-item-focused .strata-item-text {
|
||||
color: rgba(0, 0, 0, 0.95);
|
||||
}
|
||||
|
||||
/* ── Active item (warm amber, darkened for light bg) ────────────────────── */
|
||||
.strata-theme-light .strata-item-active {
|
||||
background-color: rgba(181, 131, 10, 0.16);
|
||||
border-color: rgba(181, 131, 10, 0.50);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item-active .strata-item-text {
|
||||
color: rgba(120, 82, 0, 1.0);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item-active.strata-item-hovered {
|
||||
background-color: rgba(181, 131, 10, 0.24);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item-active.strata-item-focused,
|
||||
.strata-theme-light .strata-item-active:focus {
|
||||
background-color: rgba(53, 132, 228, 0.20);
|
||||
border-color: rgba(53, 132, 228, 0.65);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item-active.strata-item-focused .strata-item-text,
|
||||
.strata-theme-light .strata-item-active:focus .strata-item-text {
|
||||
color: rgba(0, 0, 0, 0.95);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item:active {
|
||||
background-color: rgba(0, 0, 0, 0.10);
|
||||
}
|
||||
|
||||
/* ── Item icon / thumbnail ──────────────────────────────────────────────── */
|
||||
.strata-theme-light .strata-item-icon {
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item-thumb {
|
||||
border-color: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* ── Text content ───────────────────────────────────────────────────────── */
|
||||
.strata-theme-light .strata-item-text {
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item-url {
|
||||
color: rgba(26, 95, 180, 1.0);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item-subtext {
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/* ── Delete button (Adwaita red) ────────────────────────────────────────── */
|
||||
.strata-theme-light .strata-item:hover .strata-item-delete,
|
||||
.strata-theme-light .strata-item:focus .strata-item-delete,
|
||||
.strata-theme-light .strata-item-focused .strata-item-delete,
|
||||
.strata-theme-light .strata-item-hovered .strata-item-delete {
|
||||
color: rgba(224, 27, 36, 0.75);
|
||||
}
|
||||
|
||||
.strata-theme-light .strata-item-delete:hover {
|
||||
background-color: rgba(224, 27, 36, 0.13);
|
||||
color: rgba(224, 27, 36, 1.0);
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Strata",
|
||||
"description": "A fast clipboard manager. Storage, search and image decoding run in a separate Rust daemon.",
|
||||
"uuid": "strata@edu4rdshl.dev",
|
||||
"version": 10,
|
||||
"version": 11,
|
||||
"shell-version": ["50"],
|
||||
"settings-schema": "org.gnome.shell.extensions.strata",
|
||||
"url": "https://github.com/Edu4rdSHL/Strata"
|
||||
|
|
|
|||
|
|
@ -79,29 +79,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
|
||||
const appearanceGroup = new Adw.PreferencesGroup({ title: 'Appearance' });
|
||||
|
||||
const themes = [
|
||||
{ id: 'auto', label: 'Automatic' },
|
||||
{ id: 'light', label: 'Light' },
|
||||
{ id: 'dark', label: 'Dark' },
|
||||
];
|
||||
const themeRow = new Adw.ComboRow({
|
||||
title: 'Theme',
|
||||
subtitle: 'Automatic follows the system light/dark preference',
|
||||
model: Gtk.StringList.new(themes.map(t => t.label)),
|
||||
});
|
||||
const currentTheme = settings.get_string('theme');
|
||||
const currentThemeIdx = themes.findIndex(t => t.id === currentTheme);
|
||||
themeRow.selected = currentThemeIdx >= 0 ? currentThemeIdx : 0;
|
||||
themeRow.connect('notify::selected', () => {
|
||||
settings.set_string('theme', themes[themeRow.selected].id);
|
||||
});
|
||||
settings.connect('changed::theme', () => {
|
||||
const idx = themes.findIndex(t => t.id === settings.get_string('theme'));
|
||||
if (idx >= 0 && themeRow.selected !== idx)
|
||||
themeRow.selected = idx;
|
||||
});
|
||||
appearanceGroup.add(themeRow);
|
||||
|
||||
const panelWidthRow = new Adw.SpinRow({
|
||||
title: 'Panel width',
|
||||
subtitle: 'Width of the clipboard panel in pixels',
|
||||
|
|
|
|||
|
|
@ -52,17 +52,6 @@
|
|||
<description>When enabled, clicking or pressing Enter on a history item moves it to position 1 in the list.</description>
|
||||
</key>
|
||||
|
||||
<key name="theme" type="s">
|
||||
<choices>
|
||||
<choice value="auto"/>
|
||||
<choice value="light"/>
|
||||
<choice value="dark"/>
|
||||
</choices>
|
||||
<default>'auto'</default>
|
||||
<summary>Panel color theme</summary>
|
||||
<description>Auto follows the system light/dark color scheme (org.gnome.desktop.interface color-scheme). Light and Dark force a fixed theme.</description>
|
||||
</key>
|
||||
|
||||
<key name="panel-position" type="s">
|
||||
<choices>
|
||||
<choice value="top-center"/>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Strata clipboard manager stylesheet.
|
||||
/* Strata dark theme (the default; loaded when the system color scheme is dark).
|
||||
*
|
||||
* Performance rule: NO `transition: all`, NO Clutter/CSS animations.
|
||||
* Only background-color transitions on hover (GPU-composited, zero JS).
|
||||
129
strata@edu4rdshl.dev/stylesheet-light.css
Normal file
129
strata@edu4rdshl.dev/stylesheet-light.css
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/* Strata light theme.
|
||||
*
|
||||
* GNOME Shell loads this instead of stylesheet-dark.css when the system color
|
||||
* scheme is light. It imports the dark base and overrides the colors below, so
|
||||
* the overrides win by load order. Colors follow GNOME Adwaita (blue #3584e4,
|
||||
* link #1a5fb4, amber, red #e01b24), picked for contrast on a light panel.
|
||||
*/
|
||||
|
||||
@import url("stylesheet-dark.css");
|
||||
|
||||
.strata-panel {
|
||||
background-color: rgba(250, 250, 250, 0.98);
|
||||
border-color: rgba(0, 0, 0, 0.14);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.strata-title {
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.strata-clear-btn {
|
||||
border-color: rgba(0, 0, 0, 0.18);
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
.strata-clear-btn:hover {
|
||||
background-color: rgba(0, 0, 0, 0.07);
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.strata-search {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
border-color: rgba(0, 0, 0, 0.14);
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
caret-color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.strata-search:focus {
|
||||
border-color: rgba(53, 132, 228, 0.8);
|
||||
background-color: rgba(0, 0, 0, 0.035);
|
||||
}
|
||||
|
||||
/* Placeholder ("Search...") text - legible dim gray on the light panel. */
|
||||
.strata-search-hint {
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
.strata-item:hover,
|
||||
.strata-item-hovered {
|
||||
background-color: rgba(53, 132, 228, 0.14);
|
||||
border-color: rgba(53, 132, 228, 0.45);
|
||||
}
|
||||
|
||||
.strata-item:focus,
|
||||
.strata-item-focused {
|
||||
background-color: rgba(53, 132, 228, 0.16);
|
||||
border-color: rgba(53, 132, 228, 0.65);
|
||||
}
|
||||
|
||||
.strata-item:hover:focus,
|
||||
.strata-item-focused.strata-item-hovered {
|
||||
background-color: rgba(53, 132, 228, 0.24);
|
||||
border-color: rgba(53, 132, 228, 0.78);
|
||||
}
|
||||
|
||||
.strata-item:focus .strata-item-text,
|
||||
.strata-item-focused .strata-item-text {
|
||||
color: rgba(0, 0, 0, 0.95);
|
||||
}
|
||||
|
||||
.strata-item-active {
|
||||
background-color: rgba(181, 131, 10, 0.16);
|
||||
border-color: rgba(181, 131, 10, 0.50);
|
||||
}
|
||||
|
||||
.strata-item-active .strata-item-text {
|
||||
color: rgba(120, 82, 0, 1.0);
|
||||
}
|
||||
|
||||
.strata-item-active.strata-item-hovered {
|
||||
background-color: rgba(181, 131, 10, 0.24);
|
||||
}
|
||||
|
||||
.strata-item-active.strata-item-focused,
|
||||
.strata-item-active:focus {
|
||||
background-color: rgba(53, 132, 228, 0.20);
|
||||
border-color: rgba(53, 132, 228, 0.65);
|
||||
}
|
||||
|
||||
.strata-item-active.strata-item-focused .strata-item-text,
|
||||
.strata-item-active:focus .strata-item-text {
|
||||
color: rgba(0, 0, 0, 0.95);
|
||||
}
|
||||
|
||||
.strata-item:active {
|
||||
background-color: rgba(0, 0, 0, 0.10);
|
||||
}
|
||||
|
||||
.strata-item-icon {
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
.strata-item-thumb {
|
||||
border-color: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.strata-item-text {
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.strata-item-url {
|
||||
color: rgba(26, 95, 180, 1.0);
|
||||
}
|
||||
|
||||
.strata-item-subtext {
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
.strata-item:hover .strata-item-delete,
|
||||
.strata-item:focus .strata-item-delete,
|
||||
.strata-item-focused .strata-item-delete,
|
||||
.strata-item-hovered .strata-item-delete {
|
||||
color: rgba(224, 27, 36, 0.75);
|
||||
}
|
||||
|
||||
.strata-item-delete:hover {
|
||||
background-color: rgba(224, 27, 36, 0.13);
|
||||
color: rgba(224, 27, 36, 1.0);
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
/* panel.js - Strata clipboard popup panel. */
|
||||
|
||||
import GLib from 'gi://GLib';
|
||||
import Gio from 'gi://Gio';
|
||||
import St from 'gi://St';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Meta from 'gi://Meta';
|
||||
|
|
@ -19,8 +18,8 @@ export class StrataPanel {
|
|||
this._proxy = proxy;
|
||||
this._settings = settings;
|
||||
this._pageSize = settings.get_int('page-size');
|
||||
this._pageSizeChangedId = settings.connect('changed::page-size',
|
||||
() => { this._pageSize = settings.get_int('page-size'); });
|
||||
settings.connectObject('changed::page-size',
|
||||
() => { this._pageSize = settings.get_int('page-size'); }, this);
|
||||
/** @type {{ id: string, mimeType: string, preview: string }[]} */
|
||||
this._items = [];
|
||||
/** @type {Map<string, ClipboardItem>} id → widget */
|
||||
|
|
@ -46,16 +45,6 @@ export class StrataPanel {
|
|||
|
||||
this._buildUI();
|
||||
|
||||
// Theme: apply light/dark to the panel box and react to changes.
|
||||
// The light.css overrides (loaded by extension.js) only take effect
|
||||
// while the `.strata-theme-light` class is present on `_box`.
|
||||
this._interfaceSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
||||
this._applyTheme();
|
||||
this._themeChangedId = this._settings.connect('changed::theme',
|
||||
() => this._applyTheme());
|
||||
this._colorSchemeChangedId = this._interfaceSettings.connect('changed::color-scheme',
|
||||
() => this._applyTheme());
|
||||
|
||||
// Trigger the initial load as soon as the daemon owns its bus name.
|
||||
// At extension boot the daemon may still be starting (its D-Bus name
|
||||
// not yet owned); the proxy fires notify::g-name-owner when that
|
||||
|
|
@ -63,25 +52,8 @@ export class StrataPanel {
|
|||
// and only then issue GetHistory. If the daemon is already up, the
|
||||
// owner is already set and we load immediately.
|
||||
this._tryInitialLoad();
|
||||
this._nameOwnerId = this._proxy.connect('notify::g-name-owner',
|
||||
() => this._tryInitialLoad());
|
||||
}
|
||||
|
||||
/** True when the effective theme is light. `auto` follows the system
|
||||
* color-scheme (anything other than prefer-dark counts as light). */
|
||||
_effectiveIsLight() {
|
||||
const mode = this._settings.get_string('theme');
|
||||
if (mode === 'light') return true;
|
||||
if (mode === 'dark') return false;
|
||||
return this._interfaceSettings.get_string('color-scheme') !== 'prefer-dark';
|
||||
}
|
||||
|
||||
_applyTheme() {
|
||||
if (!this._box) return;
|
||||
if (this._effectiveIsLight())
|
||||
this._box.add_style_class_name('strata-theme-light');
|
||||
else
|
||||
this._box.remove_style_class_name('strata-theme-light');
|
||||
this._proxy.connectObject('notify::g-name-owner',
|
||||
() => this._tryInitialLoad(), this);
|
||||
}
|
||||
|
||||
_tryInitialLoad() {
|
||||
|
|
@ -342,23 +314,8 @@ export class StrataPanel {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
if (this._pageSizeChangedId) {
|
||||
this._settings.disconnect(this._pageSizeChangedId);
|
||||
this._pageSizeChangedId = 0;
|
||||
}
|
||||
if (this._themeChangedId) {
|
||||
this._settings.disconnect(this._themeChangedId);
|
||||
this._themeChangedId = 0;
|
||||
}
|
||||
if (this._colorSchemeChangedId && this._interfaceSettings) {
|
||||
this._interfaceSettings.disconnect(this._colorSchemeChangedId);
|
||||
this._colorSchemeChangedId = 0;
|
||||
}
|
||||
this._interfaceSettings = null;
|
||||
if (this._nameOwnerId) {
|
||||
this._proxy.disconnect(this._nameOwnerId);
|
||||
this._nameOwnerId = 0;
|
||||
}
|
||||
this._settings.disconnectObject(this);
|
||||
this._proxy.disconnectObject(this);
|
||||
if (this._searchDebounceId) {
|
||||
GLib.Source.remove(this._searchDebounceId);
|
||||
this._searchDebounceId = null;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue