mirror of
https://github.com/edu4rdshl/Strata.git
synced 2026-07-17 23:24:46 +00:00
docs: correct Wayland monitor protocol availability and post-0.3.0 drift
The monitor.rs comments claimed Mutter implements ext-data-control-v1 on GNOME 47+, contradicting ARCHITECTURE.md. Mutter exposes neither ext-data-control-v1 nor zwlr-data-control-v1, so the monitor never binds on GNOME and ingest comes from the extension via Meta.Selection + SubmitItem; the monitor only runs on wlroots. Correct the comments (module doc, Ext probe, bail! message) and the main.rs spawn comment. Also reconcile ARCHITECTURE.md with the code: supervisor backoff (1/2/4/8/16 s, 5 s reset, log-only give-up), SIGTERM at 1.5 s, prune as a separate post-insert call, multi-thread tokio default, the 200 px load-more threshold, and the SQL-side preview truncation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
a4a6f1a3f9
commit
8a7091755b
4 changed files with 35 additions and 19 deletions
|
|
@ -97,3 +97,5 @@ Signals: `ItemAdded(id s, mime_type s, preview s)`, `ItemDeleted(id s)`, `Histor
|
|||
- `Ordering::Relaxed` is intentional on `Arc<AtomicUsize>` limits (advisory, not critical path).
|
||||
- Never execute clipboard content. Writes go through `wl-clipboard-rs` (`copy_multi`) in the daemon, never via shell subprocess or `eval`.
|
||||
- Excluded apps list is checked before storing any clipboard item.
|
||||
- Ingest paths are mutually exclusive by environment: on GNOME the monitor cannot bind (Mutter exposes neither data-control protocol) so ingest is GJS `SubmitItem`; on wlroots the built-in monitor is the path.
|
||||
- List queries (`get_history_page`, `search_history`) return `content_text` truncated to `PREVIEW_CHARS` via `substr`; full content is served only by `GetItemContent` for paste-back.
|
||||
|
|
|
|||
|
|
@ -57,10 +57,13 @@ hot ingest path (it fires `SubmitItem` and returns immediately).
|
|||
`bin/strata-daemon` and registers a watchdog:
|
||||
|
||||
- If the child exits, schedule a respawn with exponential backoff
|
||||
(1 s, 2 s, 4 s, capped at 30 s).
|
||||
- After 5 rapid restarts within 60 s, stop and surface a notification.
|
||||
(1 s, 2 s, 4 s, 8 s, 16 s). A run that lasts at least 5 s resets the
|
||||
counter, so only a rapid crash loop escalates.
|
||||
- After 5 rapid restarts, stop retrying and log an error. (A missing
|
||||
`strata-daemon` binary is reported up front with a desktop notification;
|
||||
the crash-loop give-up is log-only.)
|
||||
- On disable, send `Shutdown` over D-Bus first, then `SIGTERM` if it
|
||||
doesn't exit within 2 s.
|
||||
doesn't exit within 1.5 s.
|
||||
|
||||
### Startup
|
||||
|
||||
|
|
@ -182,15 +185,16 @@ search query, not the SQL parser.
|
|||
|
||||
### Pruning
|
||||
|
||||
`upsert_item` checks `COUNT(*) > max_history` after each insert and
|
||||
deletes the oldest excess rows by `created_at ASC`, returning their ids.
|
||||
The D-Bus layer emits `ItemDeleted` for each so the extension can unlink
|
||||
the matching `~/.cache/strata/thumbnails/<id>.png`.
|
||||
After a genuinely new item is inserted, the ingest task calls `prune`,
|
||||
which deletes every row outside the newest `max_history` (by `created_at`)
|
||||
and returns their ids. The D-Bus layer emits `ItemDeleted` for each so the
|
||||
extension can unlink the matching `~/.cache/strata/thumbnails/<id>.png`.
|
||||
|
||||
## Concurrency
|
||||
|
||||
The Rust daemon runs `tokio::main(flavor = "multi_thread")`. zbus
|
||||
dispatches each incoming method call on the executor. rusqlite is sync,
|
||||
The Rust daemon runs on a multi-threaded tokio runtime (`#[tokio::main]`,
|
||||
which defaults to the multi-thread flavor). zbus dispatches each incoming
|
||||
method call on the executor. rusqlite is sync,
|
||||
so every DB call is wrapped:
|
||||
|
||||
```rust
|
||||
|
|
@ -227,10 +231,13 @@ history size.
|
|||
### Paginated history
|
||||
|
||||
`GetHistory(offset, limit)` returns metadata only (id, mime, short text
|
||||
preview, timestamp). The panel loads `page-size` rows on open, then
|
||||
another page each time the scroll position passes ~80 % of the viewport.
|
||||
The Rust side serves these from the `idx_created_at DESC` index with
|
||||
`LIMIT/OFFSET`, which stays O(log n) for any history size.
|
||||
preview, timestamp). The preview is truncated in SQL (`substr`, first
|
||||
~200 chars), so a page of large text items costs a few KB of JSON rather
|
||||
than megabytes; the full payload is only fetched on paste-back via
|
||||
`GetItemContent`. The panel loads `page-size` rows on open, then another
|
||||
page each time the scroll position comes within a fixed threshold (200 px)
|
||||
of the bottom. The Rust side serves these from the `idx_created_at DESC`
|
||||
index with `LIMIT/OFFSET`, which stays O(log n) for any history size.
|
||||
|
||||
Search shortcuts this path: when the search box is non-empty the panel
|
||||
calls `SearchHistory(query, limit)` instead and disables scroll-driven
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
/// Wayland clipboard monitor using the ext-data-control-v1 protocol (GNOME 47+)
|
||||
/// with a zwlr-data-control-v1 fallback for wlroots-based compositors.
|
||||
/// Wayland clipboard monitor using the ext-data-control-v1 protocol with a
|
||||
/// zwlr-data-control-v1 fallback for wlroots-based compositors. GNOME's Mutter
|
||||
/// exposes neither, so on GNOME this monitor does not bind and clipboard
|
||||
/// content arrives from the extension via Meta.Selection + SubmitItem.
|
||||
///
|
||||
/// Runs on a dedicated OS thread (NOT on the tokio runtime) to avoid blocking
|
||||
/// the async executor. Communicates clipboard change events to the tokio world
|
||||
|
|
@ -245,7 +247,9 @@ fn probe_protocol(conn: &Connection) -> Result<Protocol> {
|
|||
// A quick roundtrip to get the global list; no persistent state needed here.
|
||||
let (globals, _) = registry_queue_init::<MonitorState>(conn)?;
|
||||
|
||||
// ext-data-control-v1 preferred (GNOME 47+, KDE Plasma 6)
|
||||
// ext-data-control-v1 preferred (KDE Plasma 6 and other compositors that
|
||||
// expose it). GNOME's Mutter does NOT expose it, so this probe fails on
|
||||
// GNOME and ingest falls back to the extension's SubmitItem path.
|
||||
if globals.contents().with_list(|list| {
|
||||
list.iter()
|
||||
.any(|g| g.interface == "ext_data_control_manager_v1")
|
||||
|
|
@ -263,7 +267,8 @@ fn probe_protocol(conn: &Connection) -> Result<Protocol> {
|
|||
|
||||
bail!(
|
||||
"No supported clipboard control protocol found.\n\
|
||||
- GNOME: requires GNOME 47+ (Mutter implements ext-data-control-v1)\n\
|
||||
- GNOME: Mutter exposes neither protocol; ingest comes from the\n\
|
||||
extension via Meta.Selection + SubmitItem (this is expected).\n\
|
||||
- wlroots: requires zwlr-data-control-v1 (Sway, Hyprland, etc.)"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,10 @@ async fn main() -> Result<()> {
|
|||
tracing::info!("D-Bus service registered as org.gnome.Strata");
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Clipboard monitor (Wayland protocols - optional, soft-fail on GNOME)
|
||||
// GJS provides clipboard content via SubmitItem when this is unavailable.
|
||||
// Clipboard monitor (Wayland protocols - optional, soft-fail on GNOME).
|
||||
// GNOME's Mutter does not expose ext-data-control-v1 or zwlr-data-control-v1,
|
||||
// so this fails to bind there and the extension feeds content via SubmitItem
|
||||
// instead. On wlroots compositors (Sway, Hyprland) the monitor is the path.
|
||||
// -----------------------------------------------------------------------
|
||||
match clipboard::monitor::spawn(clip_tx) {
|
||||
Ok(()) => tracing::info!("Wayland clipboard monitor started"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue