mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 08:56:59 +01:00
The app and the tray stop polling. pdfs-core adds Request::Subscribe: the connection stays open and carries Event lines (status, transfers, and Changed with a Topic), with a heartbeat while quiet. In pdfs-fuse, an EventHub gives each subscriber a mailbox, code that changes something publishes its topic, and a sampler publishes the status, transfers and sync progress when they differ. The app follows the feed on one thread, paints status and transfers as they arrive, and reloads the page on screen when its topic changes, including after changes made with the pdfs CLI. A hidden window keeps the changes and catches up when focused. Front-ends fall back to polling a daemon that predates subscriptions. Refresh buttons leave the page headers; F5 and Ctrl+R still reload from the server. Photos gets a scrubber overlaid on the right edge of the timeline in place of the slider and scrollbar. It shows the years, appears when the pointer comes near or the timeline scrolls, names the month under the pointer and jumps to it on drag. Upload becomes a split button whose menu holds the Google Photos import. Tiles are pooled per row and rebound instead of rebuilt, hover scales the thumbnail to 1.02 without a shadow, and tiles lose their tooltip. On libadwaita 1.8 or newer the app uses AdwSpinner, AdwToggleGroup, AdwButtonRow and AdwShortcutsDialog, and keeps look-alike stand-ins on older releases (src/compat.rs, widgets/compat.rs). It still builds against libadwaita 1.5 and picks at run time, creating the newer widgets by class name through GtkBuilder, so every package gets them. PDFS_STAND_IN_WIDGETS forces the stand-ins. The Sync and share-link icons draw in full again: GTK drops group transforms from symbolic icons, so their coordinates are baked into the paths. All catalogs are updated and complete.
56 lines
2.1 KiB
Rust
56 lines
2.1 KiB
Rust
//! Widgets that newer libadwaita releases bring, with a stand-in built from
|
|
//! what the oldest supported release (1.5, as on Ubuntu 24.04) has.
|
|
//!
|
|
//! The app builds against 1.5 and picks at run time: when the libadwaita it
|
|
//! runs with is 1.8 or newer, the real widgets are made by class name through
|
|
//! a `gtk4::Builder`, since the 1.5 bindings have no types for them. Their
|
|
//! properties and signals are then reached by name. Call sites never care
|
|
//! which one they got.
|
|
|
|
use std::sync::OnceLock;
|
|
|
|
use gtk4::prelude::*;
|
|
|
|
/// Set to anything to use the stand-ins even on a new libadwaita, to see the
|
|
/// app as it looks on the oldest supported release.
|
|
const STAND_INS_ENV: &str = "PDFS_STAND_IN_WIDGETS";
|
|
|
|
/// Whether the libadwaita the app runs with has the 1.8 widgets.
|
|
pub(crate) fn has_adw_1_8() -> bool {
|
|
static HAS: OnceLock<bool> = OnceLock::new();
|
|
*HAS.get_or_init(|| {
|
|
std::env::var_os(STAND_INS_ENV).is_none()
|
|
&& (adw::major_version(), adw::minor_version()) >= (1, 8)
|
|
})
|
|
}
|
|
|
|
/// Build `xml`, a GtkBuilder interface naming classes the bindings lack. It
|
|
/// is only ever one this module wrote, so a failure is a bug here.
|
|
pub(crate) fn build_ui(xml: &str) -> gtk4::Builder {
|
|
gtk4::Builder::from_string(&format!("<interface>{xml}</interface>"))
|
|
}
|
|
|
|
/// The object `id` from a builder [`build_ui`] made.
|
|
pub(crate) fn built<T: IsA<gtk4::glib::Object>>(builder: >k4::Builder, id: &str) -> T {
|
|
builder
|
|
.object(id)
|
|
.unwrap_or_else(|| panic!("the compat UI has no object {id}"))
|
|
}
|
|
|
|
/// A busy spinner. It spins whenever it is shown: show and hide it with
|
|
/// `set_visible` rather than starting and stopping it.
|
|
pub(crate) type Spinner = gtk4::Widget;
|
|
|
|
/// A new [`Spinner`], shown: `AdwSpinner` on libadwaita 1.8, a spinning
|
|
/// `gtk4::Spinner` before.
|
|
pub(crate) fn spinner() -> Spinner {
|
|
if has_adw_1_8() {
|
|
let builder = build_ui(r#"<object class="AdwSpinner" id="spinner"/>"#);
|
|
built(&builder, "spinner")
|
|
} else {
|
|
// Spinning costs nothing while hidden: an unmapped widget draws no
|
|
// frames.
|
|
gtk4::Spinner::builder().spinning(true).build().upcast()
|
|
}
|
|
}
|