mirror of
https://github.com/edu4rdshl/Strata.git
synced 2026-07-17 23:24:46 +00:00
fix: rename D-Bus name to dev.edu4rdshl.Strata; drop recursive theme reload
Two changes for 0.7.0: BREAKING (D-Bus): the service is renamed from org.gnome.Strata to dev.edu4rdshl.Strata. The org.gnome.* namespace is reserved for official GNOME software; Strata is third-party, so it now uses the reverse-DNS of its own domain (matching the strata@edu4rdshl.dev UUID). Bus name, object path (/dev/edu4rdshl/Strata), and interface (dev.edu4rdshl.Strata.Manager) all change. Daemon and extension are updated together; only external busctl scripts / non-GNOME front-ends that hard-coded the old name need updating. The GSettings schema (org.gnome.shell.extensions.strata) is unchanged - that namespace is correct for GNOME Shell extension settings. Fix recursion: the theme-context 'changed' handler reloaded light.css, but load_stylesheet itself emits 'changed', so it fed back into itself and hit "too much recursion" - flooding the journal and spinning the CPU on screen unlock (which restyles widgets and fires 'changed'). The subscription is removed; light.css is loaded once. Dark/light switching is unaffected (it is the panel's class toggle, not this load). A GNOME Shell theme switch no longer auto-re-applies the sheet, which is recoverable by re-enabling. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
3f32c19fd0
commit
b41c9662cb
8 changed files with 40 additions and 44 deletions
|
|
@ -72,7 +72,7 @@ ssh fedoradev 'glib-compile-schemas ~/.local/share/gnome-shell/extensions/strata
|
|||
|
||||
## D-Bus interface summary
|
||||
|
||||
Service `org.gnome.Strata`, object `/org/gnome/Strata`, interface `org.gnome.Strata.Manager`.
|
||||
Service `dev.edu4rdshl.Strata`, object `/dev/edu4rdshl/Strata`, interface `dev.edu4rdshl.Strata.Manager`.
|
||||
|
||||
Methods: `GetHistory(offset u32, limit u32) -> json s`,
|
||||
`SearchHistory(query s, limit u32) -> json s`,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ together and the trade-offs at each layer.
|
|||
| | ItemAdded / ItemDeleted / HistoryCleared |
|
||||
+--------+-------------------------------------------------------------------------+
|
||||
|
|
||||
| session D-Bus (org.gnome.Strata)
|
||||
| session D-Bus (dev.edu4rdshl.Strata)
|
||||
v
|
||||
+----------------------- strata-daemon (Rust process) --------------------------+
|
||||
| |
|
||||
|
|
@ -68,7 +68,7 @@ hot ingest path (it fires `SubmitItem` and returns immediately).
|
|||
### Startup
|
||||
|
||||
The extension listens for `notify::g-name-owner` on the D-Bus proxy. When
|
||||
the daemon's `org.gnome.Strata` name becomes owned, the panel triggers
|
||||
the daemon's `dev.edu4rdshl.Strata` name becomes owned, the panel triggers
|
||||
its initial fetch. No polling, no fixed delays.
|
||||
|
||||
## Ingest path
|
||||
|
|
@ -313,7 +313,7 @@ and it is small and isolated.
|
|||
| App to history | Password leak | `x-kde-passwordManagerHint` opt-out |
|
||||
| User to search | SQL injection | rusqlite `params![]`, FTS5 input bound as value |
|
||||
| Daemon to FS | Path traversal via id | Ids are server-generated UUID v4 |
|
||||
| Daemon to extension | Signal spoofing | D-Bus enforces single owner of `org.gnome.Strata` |
|
||||
| Daemon to extension | Signal spoofing | D-Bus enforces single owner of `dev.edu4rdshl.Strata` |
|
||||
| Stored item to paste | Command execution | No spawn, no launch_uri, no markup parsing |
|
||||
|
||||
## Non-GNOME front-end
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Strata is **two components**, and you need **both** for it to work:
|
|||
|
||||
| Component | Language | Role |
|
||||
|---|---|---|
|
||||
| [`strata-daemon/`](strata-daemon/) | Rust + tokio + zbus | Storage (SQLite + FTS5), dedup, thumbnails, D-Bus service `org.gnome.Strata` |
|
||||
| [`strata-daemon/`](strata-daemon/) | Rust + tokio + zbus | Storage (SQLite + FTS5), dedup, thumbnails, D-Bus service `dev.edu4rdshl.Strata` |
|
||||
| [`strata@edu4rdshl.dev/`](strata@edu4rdshl.dev/) | GJS (GNOME Shell extension) | Top-bar panel, search UI, paste-back, clipboard ingest |
|
||||
|
||||
The extension auto-connects to the daemon on enable. If the daemon is managed
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ manually if you're using a non-GNOME front-end.
|
|||
|
||||
## D-Bus interface
|
||||
|
||||
- **Bus name:** `org.gnome.Strata`
|
||||
- **Object path:** `/org/gnome/Strata`
|
||||
- **Interface:** `org.gnome.Strata.Manager`
|
||||
- **Bus name:** `dev.edu4rdshl.Strata`
|
||||
- **Object path:** `/dev/edu4rdshl/Strata`
|
||||
- **Interface:** `dev.edu4rdshl.Strata.Manager`
|
||||
|
||||
| Member | Signature | Notes |
|
||||
|---|---|---|
|
||||
|
|
@ -51,15 +51,15 @@ manually if you're using a non-GNOME front-end.
|
|||
./target/release/strata-daemon
|
||||
|
||||
# In another terminal:
|
||||
busctl --user call org.gnome.Strata /org/gnome/Strata \
|
||||
org.gnome.Strata.Manager GetHistory uu 0 10
|
||||
busctl --user call dev.edu4rdshl.Strata /dev/edu4rdshl/Strata \
|
||||
dev.edu4rdshl.Strata.Manager GetHistory uu 0 10
|
||||
|
||||
# Submit text:
|
||||
busctl --user call org.gnome.Strata /org/gnome/Strata \
|
||||
org.gnome.Strata.Manager SubmitItem say "text/plain;charset=utf-8" 5 104 101 108 108 111
|
||||
busctl --user call dev.edu4rdshl.Strata /dev/edu4rdshl/Strata \
|
||||
dev.edu4rdshl.Strata.Manager SubmitItem say "text/plain;charset=utf-8" 5 104 101 108 108 111
|
||||
|
||||
# Listen for new items:
|
||||
busctl --user monitor org.gnome.Strata
|
||||
busctl --user monitor dev.edu4rdshl.Strata
|
||||
```
|
||||
|
||||
## Supported clipboard payloads
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ pub struct StrataManager {
|
|||
pub shutdown_tx: tokio::sync::mpsc::UnboundedSender<()>,
|
||||
}
|
||||
|
||||
#[interface(name = "org.gnome.Strata.Manager")]
|
||||
#[interface(name = "dev.edu4rdshl.Strata.Manager")]
|
||||
impl StrataManager {
|
||||
/// Called by the GJS extension when it detects a clipboard change via Meta.Selection.
|
||||
/// `content` is the raw bytes of the clipboard payload (D-Bus `ay`).
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ async fn main() -> Result<()> {
|
|||
};
|
||||
|
||||
let dbus_conn = zbus::connection::Builder::session()?
|
||||
.serve_at("/org/gnome/Strata", manager)?
|
||||
.serve_at("/dev/edu4rdshl/Strata", manager)?
|
||||
.build()
|
||||
.await
|
||||
.context("Building D-Bus connection")?;
|
||||
|
|
@ -61,14 +61,14 @@ async fn main() -> Result<()> {
|
|||
// would be refused.
|
||||
dbus_conn
|
||||
.request_name_with_flags(
|
||||
"org.gnome.Strata",
|
||||
"dev.edu4rdshl.Strata",
|
||||
zbus::fdo::RequestNameFlags::ReplaceExisting
|
||||
| zbus::fdo::RequestNameFlags::AllowReplacement,
|
||||
)
|
||||
.await
|
||||
.context("Acquiring D-Bus name org.gnome.Strata")?;
|
||||
.context("Acquiring D-Bus name dev.edu4rdshl.Strata")?;
|
||||
|
||||
tracing::info!("D-Bus service registered as org.gnome.Strata");
|
||||
tracing::info!("D-Bus service registered as dev.edu4rdshl.Strata");
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Clipboard monitor (Wayland protocols - optional, soft-fail on GNOME).
|
||||
|
|
@ -312,7 +312,7 @@ async fn process_bytes(
|
|||
if is_new {
|
||||
let iface = conn
|
||||
.object_server()
|
||||
.interface::<_, StrataManager>("/org/gnome/Strata")
|
||||
.interface::<_, StrataManager>("/dev/edu4rdshl/Strata")
|
||||
.await
|
||||
.context("Getting StrataManager interface ref")?;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import Gio from 'gi://Gio';
|
|||
|
||||
const STRATA_IFACE_XML = `
|
||||
<node>
|
||||
<interface name="org.gnome.Strata.Manager">
|
||||
<interface name="dev.edu4rdshl.Strata.Manager">
|
||||
|
||||
<method name="GetHistory">
|
||||
<arg type="u" direction="in" name="offset"/>
|
||||
|
|
@ -75,5 +75,5 @@ const STRATA_IFACE_XML = `
|
|||
|
||||
export const StrataProxy = Gio.DBusProxy.makeProxyWrapper(STRATA_IFACE_XML);
|
||||
|
||||
export const BUS_NAME = 'org.gnome.Strata';
|
||||
export const OBJECT_PATH = '/org/gnome/Strata';
|
||||
export const BUS_NAME = 'dev.edu4rdshl.Strata';
|
||||
export const OBJECT_PATH = '/dev/edu4rdshl/Strata';
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ export default class StrataExtension extends Extension {
|
|||
_connectSignals() {
|
||||
this._itemAddedId = Gio.DBus.session.signal_subscribe(
|
||||
BUS_NAME,
|
||||
'org.gnome.Strata.Manager',
|
||||
'dev.edu4rdshl.Strata.Manager',
|
||||
'ItemAdded',
|
||||
OBJECT_PATH,
|
||||
null,
|
||||
|
|
@ -450,7 +450,7 @@ export default class StrataExtension extends Extension {
|
|||
|
||||
this._itemDeletedId = Gio.DBus.session.signal_subscribe(
|
||||
BUS_NAME,
|
||||
'org.gnome.Strata.Manager',
|
||||
'dev.edu4rdshl.Strata.Manager',
|
||||
'ItemDeleted',
|
||||
OBJECT_PATH,
|
||||
null,
|
||||
|
|
@ -473,7 +473,7 @@ export default class StrataExtension extends Extension {
|
|||
|
||||
this._historyClearedId = Gio.DBus.session.signal_subscribe(
|
||||
BUS_NAME,
|
||||
'org.gnome.Strata.Manager',
|
||||
'dev.edu4rdshl.Strata.Manager',
|
||||
'HistoryCleared',
|
||||
OBJECT_PATH,
|
||||
null,
|
||||
|
|
@ -600,22 +600,23 @@ export default class StrataExtension extends Extension {
|
|||
}
|
||||
|
||||
|
||||
/** Load light.css into the global St theme context. Scoped under
|
||||
* `.strata-theme-light`, so it does nothing until the panel adds that
|
||||
* class. Reloaded on theme-context changes (a Shell-theme switch drops
|
||||
* dynamically loaded stylesheets). */
|
||||
/** 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. */
|
||||
_loadThemeStylesheet() {
|
||||
try {
|
||||
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
this._lightCssFile = this.dir.get_child('light.css');
|
||||
themeContext.get_theme().load_stylesheet(this._lightCssFile);
|
||||
this._stThemeChangedId = themeContext.connect('changed', () => {
|
||||
try {
|
||||
themeContext.get_theme().load_stylesheet(this._lightCssFile);
|
||||
} catch (e) {
|
||||
console.error('[Strata] light.css reload failed:', e);
|
||||
}
|
||||
});
|
||||
this._stTheme = themeContext.get_theme();
|
||||
this._stTheme.load_stylesheet(this._lightCssFile);
|
||||
} catch (e) {
|
||||
console.error('[Strata] Failed to load light.css:', e);
|
||||
}
|
||||
|
|
@ -623,16 +624,11 @@ export default class StrataExtension extends Extension {
|
|||
|
||||
_unloadThemeStylesheet() {
|
||||
try {
|
||||
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
if (this._stThemeChangedId) {
|
||||
themeContext.disconnect(this._stThemeChangedId);
|
||||
this._stThemeChangedId = null;
|
||||
}
|
||||
if (this._lightCssFile)
|
||||
themeContext.get_theme().unload_stylesheet(this._lightCssFile);
|
||||
this._stTheme?.unload_stylesheet(this._lightCssFile);
|
||||
} catch (e) {
|
||||
console.error('[Strata] Failed to unload light.css:', e);
|
||||
}
|
||||
this._stTheme = null;
|
||||
this._lightCssFile = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue