mirror of
https://github.com/edu4rdshl/Strata.git
synced 2026-07-17 23:24:46 +00:00
extension: cleanup before any future EGO submission
Remove narration breadcrumb comments, the unused _strataPreview field, the self-referencing this.actor alias, and three non-error console.log calls. Rename #busy to _busy for consistency with the rest of the class. Tighten a couple of over-long docstrings.
This commit is contained in:
parent
3fff367364
commit
43a68e7970
5 changed files with 16 additions and 83 deletions
|
|
@ -58,7 +58,7 @@ export default class StrataExtension extends Extension {
|
|||
_pendingSignalId = null;
|
||||
|
||||
/** @type {boolean} Re-entrancy guard for signal processing */
|
||||
#busy = false;
|
||||
_busy = false;
|
||||
|
||||
/** @type {number | null} Keyboard shortcut binding ID */
|
||||
_shortcutId = null;
|
||||
|
|
@ -90,22 +90,11 @@ export default class StrataExtension extends Extension {
|
|||
// inert until the panel toggles the `.strata-theme-light` class (panel.js).
|
||||
this._loadThemeStylesheet();
|
||||
|
||||
// 1. Top-bar indicator icon.
|
||||
this._addIndicator();
|
||||
|
||||
// 2. Spawn the Rust daemon.
|
||||
this._spawnDaemon();
|
||||
|
||||
// 3. Connect D-Bus proxy (async - doesn't block if daemon isn't ready yet).
|
||||
this._connectProxy();
|
||||
|
||||
// 4. Track focused window (lightweight - no clipboard I/O).
|
||||
this._connectFocusTracking();
|
||||
|
||||
// 5. Monitor clipboard via Meta.Selection (GNOME-native, no Wayland protocol needed).
|
||||
this._connectClipboardMonitor();
|
||||
|
||||
// 6. Register keyboard shortcut.
|
||||
this._registerShortcut();
|
||||
}
|
||||
|
||||
|
|
@ -261,9 +250,7 @@ export default class StrataExtension extends Extension {
|
|||
];
|
||||
for (const want of PREFERRED)
|
||||
if (mimes.includes(want)) return want;
|
||||
// Allowlist only: see comment in pick_mime (daemon). Reading unknown
|
||||
// mime types could pull a 1 GB blob into Shell memory before we can
|
||||
// size-check it.
|
||||
// Allowlist only: see pick_mime in the daemon. Unknown mime types are skipped.
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -288,10 +275,8 @@ export default class StrataExtension extends Extension {
|
|||
if (this._shuttingDown) return;
|
||||
try {
|
||||
_conn.call_finish(result);
|
||||
// Name already owned - daemon managed externally (systemd etc).
|
||||
console.log('[Strata] daemon already running, skipping spawn');
|
||||
// Name already owned (e.g. systemd user service) - don't spawn a second instance.
|
||||
} catch (_) {
|
||||
// Name not owned - spawn it ourselves.
|
||||
this._doSpawnDaemon();
|
||||
}
|
||||
}
|
||||
|
|
@ -351,10 +336,7 @@ export default class StrataExtension extends Extension {
|
|||
const lifetimeMs = (GLib.get_monotonic_time() / 1000) - this._daemonSpawnTime;
|
||||
this._daemon = null;
|
||||
|
||||
if (this._shuttingDown) {
|
||||
console.log(`[Strata] daemon exited cleanly during shutdown (status=${exit})`);
|
||||
return;
|
||||
}
|
||||
if (this._shuttingDown) return;
|
||||
|
||||
// Reset attempt counter if the daemon ran long enough to be considered healthy.
|
||||
if (lifetimeMs >= 5000) {
|
||||
|
|
@ -380,7 +362,6 @@ export default class StrataExtension extends Extension {
|
|||
if (this._shuttingDown) return;
|
||||
// Exponential backoff: 1s, 2s, 4s, 8s, 16s
|
||||
const backoffMs = 1000 * Math.pow(2, Math.max(0, this._daemonRestartAttempts - 1));
|
||||
console.log(`[Strata] respawning daemon in ${backoffMs}ms`);
|
||||
this._daemonRestartTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, backoffMs, () => {
|
||||
this._daemonRestartTimerId = null;
|
||||
this._spawnDaemon();
|
||||
|
|
@ -549,8 +530,8 @@ export default class StrataExtension extends Extension {
|
|||
}
|
||||
|
||||
async _processItemAdded(params) {
|
||||
if (this.#busy) return;
|
||||
this.#busy = true;
|
||||
if (this._busy) return;
|
||||
this._busy = true;
|
||||
try {
|
||||
const [id, mimeType, preview] = params.deepUnpack();
|
||||
|
||||
|
|
@ -570,7 +551,7 @@ export default class StrataExtension extends Extension {
|
|||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
} finally {
|
||||
this.#busy = false;
|
||||
this._busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -614,17 +595,9 @@ export default class StrataExtension extends Extension {
|
|||
}
|
||||
|
||||
|
||||
/** Load light.css into the global St theme context ONCE. It is scoped under
|
||||
* `.strata-theme-light`, so it stays inert until the panel adds that class
|
||||
* (dark/light switching is the panel's class toggle, independent of this).
|
||||
*
|
||||
* We deliberately do NOT subscribe to the theme context's 'changed'
|
||||
* signal: load_stylesheet itself emits 'changed', so reloading on it feeds
|
||||
* back into itself and hits "too much recursion" (it fired on screen
|
||||
* unlock, which restyles widgets). The only thing a one-time load gives up
|
||||
* is re-applying after a GNOME Shell *theme* switch (which replaces the
|
||||
* St.Theme and drops this sheet) - a rare action, recoverable by toggling
|
||||
* the extension. That trade is worth never touching the signal. */
|
||||
/** 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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Strata",
|
||||
"description": "A fast, stutter-free clipboard manager. All I/O runs in a Rust daemon - GNOME Shell is never blocked.",
|
||||
"description": "A fast clipboard manager. Storage, search and image decoding run in a separate Rust daemon.",
|
||||
"uuid": "strata@edu4rdshl.dev",
|
||||
"version": 8,
|
||||
"shell-version": ["45", "46", "47", "48", "49", "50"],
|
||||
|
|
|
|||
|
|
@ -1,10 +1,4 @@
|
|||
/**
|
||||
* prefs.js - Strata preferences window (GNOME 45+ / Adw).
|
||||
*
|
||||
* Pages:
|
||||
* General: max-history SpinRow, keyboard-shortcut ShortcutRow
|
||||
* Privacy: excluded-apps ExpanderRow + StringList (one entry per line)
|
||||
*/
|
||||
/* prefs.js - Strata preferences window. */
|
||||
|
||||
import Adw from 'gi://Adw';
|
||||
import Gtk from 'gi://Gtk';
|
||||
|
|
@ -22,17 +16,12 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
window.add(this._buildPrivacyPage(settings));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// General page
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
_buildGeneralPage(settings) {
|
||||
const page = new Adw.PreferencesPage({
|
||||
title: 'General',
|
||||
icon_name: 'preferences-system-symbolic',
|
||||
});
|
||||
|
||||
// ── History ──────────────────────────────────────────────────────────
|
||||
const historyGroup = new Adw.PreferencesGroup({ title: 'History' });
|
||||
|
||||
const maxHistoryRow = new Adw.SpinRow({
|
||||
|
|
@ -89,7 +78,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
|
||||
page.add(historyGroup);
|
||||
|
||||
// ── Appearance ───────────────────────────────────────────────────────
|
||||
const appearanceGroup = new Adw.PreferencesGroup({ title: 'Appearance' });
|
||||
|
||||
const themes = [
|
||||
|
|
@ -180,7 +168,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
|
||||
page.add(appearanceGroup);
|
||||
|
||||
// ── Keyboard ─────────────────────────────────────────────────────────
|
||||
const kbGroup = new Adw.PreferencesGroup({ title: 'Keyboard' });
|
||||
|
||||
const shortcutRow = new Adw.ActionRow({
|
||||
|
|
@ -208,10 +195,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
return page;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Privacy page
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
_buildPrivacyPage(settings) {
|
||||
const page = new Adw.PreferencesPage({
|
||||
title: 'Privacy',
|
||||
|
|
@ -223,7 +206,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
description: 'Items copied while these apps have focus will not be stored in history. Enter a partial app name (case-insensitive).',
|
||||
});
|
||||
|
||||
// We use a StringList model bound to excluded-apps.
|
||||
const model = new Gtk.StringList();
|
||||
const currentApps = settings.get_strv('excluded-apps');
|
||||
for (const app of currentApps)
|
||||
|
|
@ -239,7 +221,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
settings.set_strv('excluded-apps', apps);
|
||||
};
|
||||
|
||||
// Each item in the list: an EditableLabel + Remove button.
|
||||
const listBox = new Gtk.ListBox({
|
||||
selection_mode: Gtk.SelectionMode.NONE,
|
||||
css_classes: ['boxed-list'],
|
||||
|
|
@ -280,7 +261,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
listBox.append(row);
|
||||
}
|
||||
|
||||
// Add-new row.
|
||||
const addRow = new Adw.ActionRow({ activatable: false });
|
||||
const addEntry = new Gtk.Entry({
|
||||
placeholder_text: 'App name…',
|
||||
|
|
@ -314,10 +294,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
return page;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Keyboard shortcut dialog
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
_showShortcutDialog(parent, settings) {
|
||||
const dialog = new Adw.MessageDialog({
|
||||
heading: 'Set Keyboard Shortcut',
|
||||
|
|
|
|||
|
|
@ -48,13 +48,8 @@ export const ClipboardItem = GObject.registerClass({
|
|||
|
||||
this._id = id;
|
||||
this._mimeType = mimeType;
|
||||
/** D-Bus proxy used for lazy thumbnail fetch. */
|
||||
this._proxy = opts.proxy ?? null;
|
||||
/** Optional shared LRU cache (Map<id, string filePath>) - populated on first fetch. */
|
||||
this._thumbCache = opts.thumbCache ?? null;
|
||||
/** Stored on the actor so panel.js can filter by it. */
|
||||
this.actor = this;
|
||||
this._strataPreview = mimeType.startsWith('image/') ? '' : preview;
|
||||
|
||||
const row = new St.BoxLayout({
|
||||
style_class: 'strata-item-row',
|
||||
|
|
@ -112,10 +107,6 @@ export const ClipboardItem = GObject.registerClass({
|
|||
return icon;
|
||||
}
|
||||
|
||||
/** Build an image thumbnail container.
|
||||
* - If already in shared cache, apply immediately.
|
||||
* - Else fetch via GetThumbnailRemote, write to ~/.cache/strata/thumbnails/{id}.png,
|
||||
* then apply. The decode happens off-thread (CSS background-image loader). */
|
||||
_buildThumbnail(id) {
|
||||
const container = new St.Widget({
|
||||
width: THUMB_SIZE,
|
||||
|
|
@ -135,18 +126,15 @@ export const ClipboardItem = GObject.registerClass({
|
|||
};
|
||||
|
||||
try {
|
||||
// Fast path: already cached this session.
|
||||
if (this._thumbCache?.has(id)) {
|
||||
applyStyle();
|
||||
return container;
|
||||
}
|
||||
// Second fast path: file exists on disk from a previous session.
|
||||
if (GLib.file_test(cachePath, GLib.FileTest.EXISTS)) {
|
||||
this._thumbCache?.set(id, cachePath);
|
||||
applyStyle();
|
||||
return container;
|
||||
}
|
||||
// Slow path: ask the daemon for the bytes, then write file async.
|
||||
GLib.mkdir_with_parents(cacheDir, 0o755);
|
||||
if (!this._proxy) {
|
||||
this._fallbackIcon(container);
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ export class StrataPanel {
|
|||
|
||||
const widget = this._makeItemWidget(id, mimeType, preview);
|
||||
this._widgets.set(id, widget);
|
||||
this._itemList.insert_child_at_index(widget.actor, 0);
|
||||
this._itemList.insert_child_at_index(widget, 0);
|
||||
this._setActiveWidget(widget);
|
||||
} catch (e) {
|
||||
console.error(`[Strata] prependItem failed for id=${id} mime=${mimeType}:`, e);
|
||||
|
|
@ -425,7 +425,7 @@ export class StrataPanel {
|
|||
this._items.push({ id, mimeType, preview });
|
||||
const widget = this._makeItemWidget(id, mimeType, preview);
|
||||
this._widgets.set(id, widget);
|
||||
this._itemList.add_child(widget.actor);
|
||||
this._itemList.add_child(widget);
|
||||
} catch (e) {
|
||||
console.error(`[Strata] _appendItemFromMeta failed for id=${meta?.id}:`, e);
|
||||
}
|
||||
|
|
@ -475,12 +475,8 @@ export class StrataPanel {
|
|||
for (let j = i; j < e; j++)
|
||||
this._appendItemFromMeta(this._searchResults[j]);
|
||||
};
|
||||
// The very first chunk of a fresh render (start === 0, right after
|
||||
// _clearListDom) is rendered synchronously, in the same frame as
|
||||
// the clear, so the list never paints empty in between - that
|
||||
// empty frame is the "blink" seen while typing a search. Later
|
||||
// chunks (and scroll-driven pages) yield to idle to keep frames
|
||||
// light.
|
||||
// First chunk runs synchronously so the list never paints empty
|
||||
// between clear and first append. Later chunks yield to idle.
|
||||
if (i === 0) {
|
||||
renderChunk();
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue