Skip to content

Commit

Permalink
Add grim-based wayland universal screenshot adapter (#3018)
Browse files Browse the repository at this point in the history
* Add grim-based wayland universal screenshot adapter

In the past, flameshot used a special and superfluous method to call the wayland screenshot component
- dbus protocol communication. Although this method is supported by a large number of distributions,
it does not take into account the actual situation of wayland (including WM custom desktop environment users).
Now, we can enable the wayland universal screenshot adapter with the help of grim,
just add the following compilation flags in cmake:

```
-DUSE_WAYLAND_GRIM=true
```

In addition, the patch also adds HYPRLAND type and OTHER type support

* grim outputs to standard streams instead of files

* Automatically enable wayland clipboard support when USE_WAYLAND_GRIM is enabled

* Cancel USE_WAYLAND_GRIM Activate USE_WAYLAND_CLIPBOARD by default

Due to the dependency problem of USE_WAYLAND_CLIPBOARD,
cancel USE_WAYLAND_GRIM to activate USE_WAYLAND_CLIPBOARD by default,
Add a warning prompt to activate USE_WAYLAND_GRIM when USE_WAYLAND_CLIPBOARD is activated

* perform formatting

* modify cmake message

The grim adapter cannot be used in gnome and similar environments, modify the cmake message to express it

* remove generic screenshot adapter for gnome

Generic screenshot adapter is only supported on compositors that support wlroots

* Update format
  • Loading branch information
jack9603301 authored Feb 15, 2023
1 parent f7e41f4 commit 3ededae
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,17 @@ target_link_libraries(
)

if (USE_WAYLAND_CLIPBOARD)
if(!USE_WAYLAND_GRIM)
message(WARNING "You activated the USE_WAYLAND_CLIPBOARD option, but did not activate the USE_WAYLAND_GRIM option. Flameshot will use the dbus protocol to support wayland. If you use wlroots-based wayland, it is recommended to enable USE_WAYLAND_GRIM")
endif()
target_compile_definitions(flameshot PRIVATE USE_WAYLAND_CLIPBOARD=1)
target_link_libraries(flameshot KF5::GuiAddons)
endif()

if (USE_WAYLAND_GRIM)
target_compile_definitions(flameshot PRIVATE USE_WAYLAND_GRIM=1)
endif()

if (APPLE)
set(MACOSX_BUNDLE_IDENTIFIER "org.flameshot")
set_target_properties(
Expand Down
3 changes: 3 additions & 0 deletions src/utils/desktopinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ DesktopInfo::WM DesktopInfo::windowManager()
if (desktop.contains(QLatin1String("sway"), Qt::CaseInsensitive)) {
return DesktopInfo::SWAY;
}
if (desktop.contains(QLatin1String("Hyprland"), Qt::CaseInsensitive)) {
return DesktopInfo::HYPRLAND;
}
if (desktop.contains(QLatin1String("kde-plasma"))) {
return DesktopInfo::KDE;
}
Expand Down
3 changes: 2 additions & 1 deletion src/utils/desktopinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class DesktopInfo
KDE,
OTHER,
QTILE,
SWAY
SWAY,
HYPRLAND
};

bool waylandDetected();
Expand Down
44 changes: 43 additions & 1 deletion src/utils/screengrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <QDesktopWidget>
#include <QGuiApplication>
#include <QPixmap>
#include <QProcess>
#include <QScreen>

#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
Expand All @@ -25,6 +26,29 @@ ScreenGrabber::ScreenGrabber(QObject* parent)
: QObject(parent)
{}

void ScreenGrabber::generalGrimScreenshot(bool& ok, QPixmap& res)
{
#ifdef USE_WAYLAND_GRIM
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
QProcess Process;
QString program = "grim";
QStringList arguments;
arguments << "-";
Process.start(program, arguments);
if (Process.waitForFinished()) {
res.loadFromData(Process.readAll());
ok = true;
} else {
ok = false;
AbstractLogger::error()
<< tr("The universal wayland screen capture adapter requires Grim as "
"the screen capture component of wayland. If the screen "
"capture component is missing, please install it!");
}
#endif
#endif
}

void ScreenGrabber::freeDesktopPortal(bool& ok, QPixmap& res)
{

Expand Down Expand Up @@ -102,9 +126,27 @@ QPixmap ScreenGrabber::grabEntireDesktop(bool& ok)
switch (m_info.windowManager()) {
case DesktopInfo::GNOME:
case DesktopInfo::KDE:
freeDesktopPortal(ok, res);
break;
case DesktopInfo::QTILE:
case DesktopInfo::SWAY: {
case DesktopInfo::SWAY:
case DesktopInfo::HYPRLAND:
case DesktopInfo::OTHER: {
#ifndef USE_WAYLAND_GRIM
AbstractLogger::warning() << tr(
"If the USE_WAYLAND_GRIM option is not activated, the dbus "
"protocol will be used. It should be noted that using the "
"dbus protocol under wayland is not recommended. It is "
"recommended to recompile with the USE_WAYLAND_GRIM flag to "
"activate the grim-based general wayland screenshot adapter");
freeDesktopPortal(ok, res);
#else
AbstractLogger::warning()
<< tr("grim's screenshot component is implemented based on "
"wlroots, it may not be used in GNOME or similar "
"desktop environments");
generalGrimScreenshot(ok, res);
#endif
break;
}
default:
Expand Down
1 change: 1 addition & 0 deletions src/utils/screengrabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class ScreenGrabber : public QObject
QRect screenGeometry(QScreen* screen);
QPixmap grabScreen(QScreen* screenNumber, bool& ok);
void freeDesktopPortal(bool& ok, QPixmap& res);
void generalGrimScreenshot(bool& ok, QPixmap& res);
QRect desktopGeometry();

private:
Expand Down

0 comments on commit 3ededae

Please sign in to comment.