@@ -205,13 +205,25 @@ QPixmap ScreenGrabber::grabEntireDesktop(bool& ok, int preSelectedMonitor)
205205 screenshot.setDevicePixelRatio (currentScreen->devicePixelRatio ());
206206 return screenshot;
207207
208- #elif defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
209- freeDesktopPortal (ok, screenshot);
210- if (!ok) {
211- AbstractLogger::error () << tr (" Unable to capture screen" );
212- return QPixmap ();
208+ #elif defined(Q_OS_LINUX)
209+ if (!m_info.waylandDetected () && ConfigHandler ().useX11LegacyScreenshot ()) {
210+ qWarning () << " Using deprecated legacy X11 screenshot method. "
211+ " Consider installing xdg-desktop-portal for your "
212+ " desktop. Future versions of Flameshot may remove the "
213+ " option to use the legacy method." ;
214+ screenshot = x11LegacyScreenshot ();
215+ ok = !screenshot.isNull ();
216+ if (!ok) {
217+ AbstractLogger::error () << tr (" Unable to capture screen" );
218+ return QPixmap ();
219+ }
220+ } else {
221+ freeDesktopPortal (ok, screenshot);
222+ if (!ok) {
223+ AbstractLogger::error () << tr (" Unable to capture screen" );
224+ return QPixmap ();
225+ }
213226 }
214-
215227#elif defined(Q_OS_WIN)
216228 screenshot = windowsScreenshot (wid);
217229#endif
@@ -256,10 +268,21 @@ QPixmap ScreenGrabber::grabFullDesktop(bool& ok)
256268 painter.drawPixmap (offset, p);
257269 }
258270 painter.end ();
259- #elif defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
260- freeDesktopPortal (ok, screenshot);
261- if (!ok) {
262- AbstractLogger::error () << tr (" Unable to capture screen" );
271+ #elif defined(Q_OS_LINUX)
272+ if (!m_info.waylandDetected () && ConfigHandler ().useX11LegacyScreenshot ()) {
273+ qWarning () << " Using deprecated legacy X11 screenshot method. "
274+ " Consider installing xdg-desktop-portal for your "
275+ " desktop." ;
276+ screenshot = x11LegacyScreenshot ();
277+ ok = !screenshot.isNull ();
278+ if (!ok) {
279+ AbstractLogger::error () << tr (" Unable to capture screen" );
280+ }
281+ } else {
282+ freeDesktopPortal (ok, screenshot);
283+ if (!ok) {
284+ AbstractLogger::error () << tr (" Unable to capture screen" );
285+ }
263286 }
264287#elif defined(Q_OS_WIN)
265288 screenshot = windowsScreenshot (0 );
@@ -629,3 +652,44 @@ QPixmap ScreenGrabber::windowsScreenshot(int wid)
629652
630653 return desktop;
631654}
655+
656+ QPixmap ScreenGrabber::x11LegacyScreenshot ()
657+ {
658+ const QList<QScreen*> screens = QGuiApplication::screens ();
659+
660+ if (screens.isEmpty ()) {
661+ return QPixmap ();
662+ }
663+
664+ if (screens.size () == 1 ) {
665+ QScreen* screen = screens.first ();
666+ QPixmap p = screen->grabWindow (0 );
667+ p.setDevicePixelRatio (screen->devicePixelRatio ());
668+ return p;
669+ }
670+
671+ // Composite all screens using logical geometry.
672+ // On i3 (tested) DPR is uniform so we don't need the per-screen
673+ // physical pixel math that the Windows backend does. Not sure if this is
674+ // true for other DE's like xmonad.
675+ QRect totalGeom;
676+ for (QScreen* s : screens) {
677+ totalGeom = totalGeom.united (s->geometry ());
678+ }
679+
680+ qreal dpr = screens.first ()->devicePixelRatio ();
681+ QPixmap desktop (qRound (totalGeom.width () * dpr),
682+ qRound (totalGeom.height () * dpr));
683+ desktop.setDevicePixelRatio (dpr);
684+ desktop.fill (Qt::black);
685+
686+ QPainter painter (&desktop);
687+ for (QScreen* s : screens) {
688+ QPixmap p = s->grabWindow (0 );
689+ QPoint offset = s->geometry ().topLeft () - totalGeom.topLeft ();
690+ painter.drawPixmap (offset, p);
691+ }
692+ painter.end ();
693+
694+ return desktop;
695+ }
0 commit comments