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
59
src/main.rs
59
src/main.rs
|
|
@ -645,9 +645,16 @@ impl SimpleComponent for App {
|
|||
widgets.center_box.set_center_widget(Some(¢er_area));
|
||||
widgets.center_box.set_end_widget(Some(&stats_box));
|
||||
|
||||
// Captured before `control_popover` moves into `model` below — needed
|
||||
// by the screenshot dispatch just before this function returns.
|
||||
// Captured before these move into `model` (or are otherwise dropped
|
||||
// as bare locals, never stored on `App` at all) — needed by the
|
||||
// screenshot dispatch just before this function returns.
|
||||
let control_popover_for_screenshot = control_popover.clone();
|
||||
let connectivity_popover_for_screenshot = connectivity_popover.clone();
|
||||
let wifi_tab_btn_for_screenshot = wifi_tab_btn.clone();
|
||||
let bt_tab_btn_for_screenshot = bt_tab_btn.clone();
|
||||
let media_popover_for_screenshot = media_popover.clone();
|
||||
let media_widget_for_screenshot = media_widget.clone();
|
||||
let media_track_lbl_for_screenshot = media_track_lbl.clone();
|
||||
|
||||
let model = App {
|
||||
workspaces: vec![],
|
||||
|
|
@ -715,11 +722,43 @@ impl SimpleComponent for App {
|
|||
bar::wifi::spawn_status_poller(sender.clone());
|
||||
bar::media::spawn_poller(sender.clone());
|
||||
widgets::client::spawn(sender.clone());
|
||||
notifications::spawn();
|
||||
osd::spawn();
|
||||
|
||||
// Screenshot mode primes these with sample content instead of the
|
||||
// real D-Bus/pactl/backlight sources — see notifications::SampleKind
|
||||
// and osd::SampleKind's doc comments.
|
||||
let notif_sample = screenshot_req.as_ref().and_then(|r| match r.view.as_str() {
|
||||
"notification" => Some(notifications::SampleKind::Normal),
|
||||
"notification-critical" => Some(notifications::SampleKind::Critical),
|
||||
_ => None,
|
||||
});
|
||||
let notification_window = notifications::spawn(notif_sample);
|
||||
let osd_sample = screenshot_req.as_ref().and_then(|r| match r.view.as_str() {
|
||||
"osd-volume" => Some(osd::SampleKind::Volume),
|
||||
"osd-brightness" => Some(osd::SampleKind::Brightness),
|
||||
_ => None,
|
||||
});
|
||||
let osd_window = osd::spawn(osd_sample);
|
||||
|
||||
if let Some(req) = screenshot_req {
|
||||
screenshot::dispatch(&root, req, control_popover_for_screenshot);
|
||||
let notification_window = matches!(req.view.as_str(), "notification" | "notification-critical")
|
||||
.then_some(notification_window);
|
||||
let osd_window = matches!(req.view.as_str(), "osd-volume" | "osd-brightness")
|
||||
.then_some(osd_window);
|
||||
screenshot::dispatch(
|
||||
&root,
|
||||
req,
|
||||
screenshot::Handles {
|
||||
control_popover: control_popover_for_screenshot,
|
||||
connectivity_popover: connectivity_popover_for_screenshot,
|
||||
wifi_tab_btn: wifi_tab_btn_for_screenshot,
|
||||
bt_tab_btn: bt_tab_btn_for_screenshot,
|
||||
media_popover: media_popover_for_screenshot,
|
||||
media_widget: media_widget_for_screenshot,
|
||||
media_track_lbl: media_track_lbl_for_screenshot,
|
||||
notification_window,
|
||||
osd_window,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
ComponentParts { model, widgets }
|
||||
|
|
@ -1145,7 +1184,7 @@ impl App {
|
|||
if saved {
|
||||
bar::wifi::spawn_join(ssid_clone.clone());
|
||||
} else {
|
||||
show_add_network_dialog(btn, ssid_clone.clone());
|
||||
show_add_network_dialog(btn, ssid_clone.clone(), |_| {});
|
||||
}
|
||||
close_parent_popover(btn);
|
||||
});
|
||||
|
|
@ -1302,8 +1341,11 @@ fn close_parent_popover(widget: >k4::Button) {
|
|||
}
|
||||
|
||||
/// Small modal prompting for a password, then saves + joins the network via
|
||||
/// `breadcrumbs add` + `breadcrumbs join`.
|
||||
fn show_add_network_dialog(anchor: >k4::Button, ssid: String) {
|
||||
/// `breadcrumbs add` + `breadcrumbs join`. `on_build` runs on the freshly
|
||||
/// built dialog *before* it's presented — screenshot mode's only hook point,
|
||||
/// since `connect_map` registered any later would miss a map that already
|
||||
/// happened. The real call site passes a no-op.
|
||||
fn show_add_network_dialog(anchor: &impl IsA<gtk4::Widget>, ssid: String, on_build: impl FnOnce(>k4::Window)) {
|
||||
let dialog = gtk4::Window::new();
|
||||
dialog.set_title(Some(&format!("Add “{ssid}”")));
|
||||
dialog.set_resizable(false);
|
||||
|
|
@ -1367,6 +1409,7 @@ fn show_add_network_dialog(anchor: >k4::Button, ssid: String) {
|
|||
dialog_for_activate.close();
|
||||
});
|
||||
|
||||
on_build(&dialog);
|
||||
dialog.present();
|
||||
entry.grab_focus();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue