From fc05aecce2b4551bd7cdcf1536341b29b3339e08 Mon Sep 17 00:00:00 2001 From: Jason Perlow Date: Thu, 27 Aug 2026 16:14:03 -0400 Subject: [PATCH] fix(screenshot): resolve target monitor before opening from the control-panel button system_view.vala's snap_btn.clicked handler called tool.present() directly, never calling prepare_for_invocation() first -- so _target_monitor and _target_connector stayed null (their declared defaults) for this entry point. The toolbar defaults to screen mode on open, and target_monitor_capture_args() returns null when neither is set, so every capture from THIS button failed immediately with 'no target monitor for screen capture', shown to the user as the generic 'Screenshots unavailable' dialog -- misleading, since the portal/backend were both healthy. shortcut_manager.vala's screenshot_tool_action() (the Print-key path) already calls prepare_for_invocation() before opening; this entry point never did. Match that pattern: resolve the focused-window handle, call prepare_for_invocation(), and use open_dialog() (matching the working path) instead of present(). Also adds real logging to ScreenshotPortal.is_available()'s previously silent failure paths -- useful on its own, and what let me rule out the portal/D-Bus layer here in the first place: it caught nothing on this bug precisely because nothing was wrong at that layer. Confirmed fixed on real O6N hardware: rebuilt, deployed, restarted, control-panel screenshot button now captures successfully. --- src/components/sidebar/views/system_view.vala | 10 +++++++++- src/core/screenshot_portal.vala | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/components/sidebar/views/system_view.vala b/src/components/sidebar/views/system_view.vala index e4c332f..be65f52 100644 --- a/src/components/sidebar/views/system_view.vala +++ b/src/components/sidebar/views/system_view.vala @@ -89,7 +89,15 @@ namespace Singularity { var app = (Gtk.Application) GLib.Application.get_default(); var tool = Singularity.ScreenshotTool.get_default(app); if (!tool.ensure_screenshots()) return; - tool.present(); + // prepare_for_invocation() resolves _target_monitor/_target_connector + // and sets the layer-shell output -- without it both stay null and + // screen-mode capture fails with "no target monitor for screen + // capture" the instant this opens, since it defaults to screen mode. + // shortcut_manager.vala's screenshot_tool_action() (the Print-key + // path) already does this; this entry point never did. + var handle = Singularity.AppSystem.get_default().get_focused_window_handle(); + tool.prepare_for_invocation(handle); + tool.open_dialog(); }); _edit_button = new Button.from_icon_name("document-edit-symbolic"); _edit_button.has_frame = false; diff --git a/src/core/screenshot_portal.vala b/src/core/screenshot_portal.vala index 18d964f..22ce698 100644 --- a/src/core/screenshot_portal.vala +++ b/src/core/screenshot_portal.vala @@ -23,7 +23,10 @@ namespace Singularity { } public bool is_available() { - if (connection == null) return false; + if (connection == null) { + warning("[ScreenshotPortal] is_available: no session bus connection"); + return false; + } try { var res = connection.call_sync( "org.freedesktop.DBus", @@ -35,8 +38,12 @@ namespace Singularity { DBusCallFlags.NONE, -1, null); bool owned; res.get("(b)", out owned); + if (!owned) { + warning("[ScreenshotPortal] is_available: org.freedesktop.portal.Desktop has no owner"); + } return owned; } catch (Error e) { + warning("[ScreenshotPortal] is_available: NameHasOwner call failed: %s", e.message); return false; } }