Skip to content

Commit 410cfae

Browse files
screengrabber: pass non-empty parent_window to xdg-desktop-portal (flameshot-org#4664)
* screengrabber: pass non-empty parent_window to xdg-desktop-portal xdg-desktop-portal-gnome on GNOME 46 rejects requests where the parent_window argument is an empty string with the error "Failed to associate portal window with parent window ''", which made daemon-mode (tray icon, DBus captureScreen) capture fail for all GNOME Wayland users. Allocate an offscreen QWidget (Qt::WA_DontShowOnScreen) so a winId is generated, and pass "x11:<hex>" on X11 sessions or "wayland:" on Wayland. Both are accepted by xdg-desktop-portal as valid no-real-parent handles, while remaining non-empty as the portal spec requires. Tested on: Ubuntu 24.04, GNOME 46 Wayland, NVIDIA proprietary 590.48.01, Qt 6.4.2, xdg-desktop-portal-gnome 46.2. Fixes daemon-mode capture on GNOME 46 Wayland. * clang format --------- Co-authored-by: Jeremy Borgman <borgman.jeremy@pm.me>
1 parent 46e4a7d commit 410cfae

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

src/utils/screengrabber.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,28 @@ void ScreenGrabber::freeDesktopPortal(bool& ok, QPixmap& res)
111111
});
112112
timeout.start();
113113

114+
// Build a non-empty parent_window handle. xdg-desktop-portal-gnome
115+
// (>= 46) rejects an empty string with "Failed to associate portal
116+
// window with parent window ''" and the Screenshot request fails.
117+
// On X11 we pass a real x11:<hex> handle from an offscreen QWidget.
118+
// On Wayland we fall back to an empty string inside a wayland: prefix
119+
// (xdg-desktop-portal-gnome treats unknown handles as no-parent and
120+
// proceeds, instead of rejecting outright).
121+
QString parentWindow;
122+
QWidget parentDummy;
123+
parentDummy.setAttribute(Qt::WA_DontShowOnScreen, true);
124+
parentDummy.resize(1, 1);
125+
parentDummy.show();
126+
if (QGuiApplication::platformName() == QLatin1String("wayland")) {
127+
parentWindow = QStringLiteral("wayland:");
128+
} else {
129+
parentWindow =
130+
QStringLiteral("x11:0x%1").arg(parentDummy.winId(), 0, 16);
131+
}
132+
114133
screenshotInterface.call(
115134
QStringLiteral("Screenshot"),
116-
"",
135+
parentWindow,
117136
QMap<QString, QVariant>({ { "handle_token", QVariant(token) },
118137
{ "interactive", QVariant(false) } }));
119138

0 commit comments

Comments
 (0)