breadbar: capture every view, not just bar/control-panel
breadbar is "a bar + the notification daemon + the OSD" — the screenshot mode only covered the bar and its control-panel popover, missing seven more distinct surfaces: the WiFi/Bluetooth connectivity popover (both tabs), the media-controls popover, the standalone notification window (both normal and critical urgency), the standalone OSD window (volume and brightness), and the wifi add-network dialog. All ten views are now --screenshot targets. Two real refactors needed to make the standalone notification/OSD windows screenshot-able at all, not just bigger match arms: - Both windows are built deep inside an async task (`run_osd`/ `popup::run`), only reachable after the real event loop starts — no window handle ever existed for a caller to hook `connect_map` on before that. Window construction is now synchronous in `osd::spawn`/ `notifications::spawn`, handed to the async loop as a parameter instead of created inside it. - Screenshot mode seeds each with one fixed sample event (SampleKind) via the same channel the real pactl/backlight/D-Bus sources feed, instead of waiting for real hardware/dbus activity. For notifications specifically this also means skipping the real org.freedesktop.Notifications D-Bus registration entirely in screenshot mode — claiming that well-known name would just race the real breadbar (if running) for it, for no benefit, since nothing external needs to reach a screenshot-only instance. show_add_network_dialog gained an `on_build` hook (called before `.present()`, the only point `connect_map` can still catch the map) so screenshot mode can capture it without changing its one real call site's behavior — and its `anchor` parameter widened from `&Button` to `&impl IsA<Widget>` since the screenshot path anchors off a `ToggleButton`, not a `Button`.
This commit is contained in:
parent
059e11cdeb
commit
566aeeed8b
5 changed files with 335 additions and 84 deletions
50
src/osd.rs
50
src/osd.rs
|
|
@ -9,14 +9,50 @@ enum OsdEvent {
|
|||
Brightness { pct: u8 },
|
||||
}
|
||||
|
||||
pub fn spawn() {
|
||||
/// A fixed sample event for `--screenshot osd-volume`/`osd-brightness` —
|
||||
/// substitutes for the real `pactl subscribe`/backlight-sysfs watchers so a
|
||||
/// capture doesn't depend on this machine's actual volume/brightness at
|
||||
/// capture time.
|
||||
pub enum SampleKind {
|
||||
Volume,
|
||||
Brightness,
|
||||
}
|
||||
|
||||
impl SampleKind {
|
||||
fn sample_event(&self) -> OsdEvent {
|
||||
match self {
|
||||
SampleKind::Volume => OsdEvent::Volume { pct: 65, muted: false },
|
||||
SampleKind::Brightness => OsdEvent::Brightness { pct: 80 },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds the OSD window synchronously (so a caller — screenshot mode, via
|
||||
/// `sample`, in particular — has a real window to hook `connect_map` on
|
||||
/// before the async event loop below ever runs) and spawns the event loop
|
||||
/// that shows/updates/hides it.
|
||||
///
|
||||
/// `sample`: `Some` skips the real volume/brightness watchers entirely and
|
||||
/// seeds the loop with one fixed sample event instead — screenshot mode
|
||||
/// only, so a capture never depends on (or is disrupted by) this machine's
|
||||
/// actual audio/backlight state.
|
||||
pub fn spawn(sample: Option<SampleKind>) -> gtk4::Window {
|
||||
let (tx, rx) = mpsc::channel::<OsdEvent>(8);
|
||||
|
||||
let tx1 = tx.clone();
|
||||
std::thread::spawn(move || volume_watcher(tx1));
|
||||
std::thread::spawn(move || brightness_watcher(tx));
|
||||
match sample {
|
||||
Some(kind) => {
|
||||
let _ = tx.try_send(kind.sample_event());
|
||||
}
|
||||
None => {
|
||||
let tx1 = tx.clone();
|
||||
std::thread::spawn(move || volume_watcher(tx1));
|
||||
std::thread::spawn(move || brightness_watcher(tx));
|
||||
}
|
||||
}
|
||||
|
||||
relm4::spawn_local(run_osd(rx));
|
||||
let window = create_window();
|
||||
relm4::spawn_local(run_osd(window.clone(), rx));
|
||||
window
|
||||
}
|
||||
|
||||
fn volume_watcher(tx: mpsc::Sender<OsdEvent>) {
|
||||
|
|
@ -119,9 +155,7 @@ fn brightness_watcher(tx: mpsc::Sender<OsdEvent>) {
|
|||
}
|
||||
}
|
||||
|
||||
async fn run_osd(mut rx: mpsc::Receiver<OsdEvent>) {
|
||||
let window = create_window();
|
||||
|
||||
async fn run_osd(window: gtk4::Window, mut rx: mpsc::Receiver<OsdEvent>) {
|
||||
let container = gtk4::Box::new(gtk4::Orientation::Horizontal, 0);
|
||||
container.set_margin_top(10);
|
||||
container.set_margin_bottom(10);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue