From ca01103f02db05a2e0e31a72f5c6063a15f60a7b Mon Sep 17 00:00:00 2001
From: Lukas Holecek <hluk@email.cz>
Date: Sun, 5 Nov 2023 09:59:33 +0100
Subject: [PATCH] Add build flag to disable X11 support

Mainly disables looking for private Qt headers for X11 support.

This effectively removes support for global shortcuts and getting window
titles.

Usage:

    cmake -DWITH_X11=OFF ...

Fixes #2532
---
 src/CMakeLists.txt                        |  1 +
 src/app/clipboardserver.cpp               | 12 ++---
 src/common/common.h                       |  9 ----
 src/common/config.cpp                     |  2 +-
 src/common/globalshortcutcommands.cpp     |  6 +--
 src/gui/commandwidget.cpp                 | 10 ++--
 src/gui/menuitems.cpp                     |  2 +-
 src/platform/platform.cmake               |  1 -
 src/platform/x11/x11info.cpp              | 17 ++++--
 src/platform/x11/x11platform.cmake        | 63 +++++++++++++----------
 src/platform/x11/x11platform.cpp          | 30 +++++++++--
 src/platform/x11/x11platform.h            |  2 +
 src/platform/x11/x11platformclipboard.cpp | 12 ++++-
 src/platform/x11/x11platformwindow.cpp    | 14 ++++-
 src/scriptable/scriptable.cpp             |  9 ++--
 15 files changed, 121 insertions(+), 69 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1b442852ef..611fa056f9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -39,6 +39,7 @@ if (USE_QXT)
         ../qxt/qxtglobalshortcut.cpp
         )
     add_definitions( -DQXT_STATIC )
+    add_definitions( -DCOPYQ_GLOBAL_SHORTCUTS )
 endif()
 
 # translations
diff --git a/src/app/clipboardserver.cpp b/src/app/clipboardserver.cpp
index 1d4849a815..426e3c746e 100644
--- a/src/app/clipboardserver.cpp
+++ b/src/app/clipboardserver.cpp
@@ -38,10 +38,10 @@
 #include <QStyleFactory>
 #include <QTextEdit>
 
-#ifdef NO_GLOBAL_SHORTCUTS
-class QxtGlobalShortcut final {};
-#else
+#ifdef COPYQ_GLOBAL_SHORTCUTS
 #include "../qxt/qxtglobalshortcut.h"
+#else
+class QxtGlobalShortcut final {};
 #endif
 
 #include <memory>
@@ -247,7 +247,7 @@ void ClipboardServer::removeGlobalShortcuts()
 
 void ClipboardServer::onCommandsSaved(const QVector<Command> &commands)
 {
-#ifndef NO_GLOBAL_SHORTCUTS
+#ifdef COPYQ_GLOBAL_SHORTCUTS
     removeGlobalShortcuts();
 
     QList<QKeySequence> usedShortcuts;
@@ -556,7 +556,7 @@ void ClipboardServer::onNotificationButtonClicked(const NotificationButton &butt
 
 void ClipboardServer::createGlobalShortcut(const QKeySequence &shortcut, const Command &command)
 {
-#ifdef NO_GLOBAL_SHORTCUTS
+#ifndef COPYQ_GLOBAL_SHORTCUTS
     Q_UNUSED(shortcut)
     Q_UNUSED(command)
 #else
@@ -731,7 +731,7 @@ void ClipboardServer::loadSettings(AppConfig *appConfig)
 
 void ClipboardServer::shortcutActivated(QxtGlobalShortcut *shortcut)
 {
-#ifdef NO_GLOBAL_SHORTCUTS
+#ifndef COPYQ_GLOBAL_SHORTCUTS
     Q_UNUSED(shortcut)
 #else
     m_ignoreKeysTimer.start();
diff --git a/src/common/common.h b/src/common/common.h
index 81bf7b5aef..573659d7b4 100644
--- a/src/common/common.h
+++ b/src/common/common.h
@@ -15,15 +15,6 @@ class QMimeData;
 class QProcess;
 class QString;
 
-#if !defined(COPYQ_WS_X11) && !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
-#   define NO_GLOBAL_SHORTCUTS
-#endif
-
-#ifdef COPYQ_WS_X11
-// QClipboard::supportsSelection() must return true.
-#   define HAS_MOUSE_SELECTIONS
-#endif
-
 bool isMainThread();
 
 QByteArray makeClipboardOwnerData();
diff --git a/src/common/config.cpp b/src/common/config.cpp
index c35331e53a..00fc2ff667 100644
--- a/src/common/config.cpp
+++ b/src/common/config.cpp
@@ -270,7 +270,7 @@ void saveMainWindowState(const QString &mainWindowObjectName, const QByteArray &
 
 void moveToCurrentWorkspace(QWidget *w)
 {
-#ifdef COPYQ_WS_X11
+#ifdef COPYQ_MOVE_TO_WORKSPACE
     /* Re-initialize window in window manager so it can popup on current workspace. */
     if (w->isVisible()) {
         GEOMETRY_LOG( w, QLatin1String("Move to current workspace") );
diff --git a/src/common/globalshortcutcommands.cpp b/src/common/globalshortcutcommands.cpp
index 4ca790ff85..4bb8b756db 100644
--- a/src/common/globalshortcutcommands.cpp
+++ b/src/common/globalshortcutcommands.cpp
@@ -3,14 +3,14 @@
 #include "globalshortcutcommands.h"
 
 #include "common/command.h"
-#include "common/shortcuts.h"
-#include "gui/icons.h"
 
 #include <QCoreApplication>
 #include <QLocale>
 #include <QVector>
 
-#ifndef NO_GLOBAL_SHORTCUTS
+#ifdef COPYQ_GLOBAL_SHORTCUTS
+#   include "common/shortcuts.h"
+#   include "gui/icons.h"
 
 namespace {
 
diff --git a/src/gui/commandwidget.cpp b/src/gui/commandwidget.cpp
index 44f80af2a9..08b4910f0f 100644
--- a/src/gui/commandwidget.cpp
+++ b/src/gui/commandwidget.cpp
@@ -22,9 +22,11 @@ namespace {
 
 const QIcon iconClipboard() { return getIcon("", IconClipboard); }
 const QIcon iconMenu() { return getIcon("", IconBars); }
-const QIcon iconShortcut() { return getIcon("", IconKeyboard); }
 const QIcon iconScript() { return getIcon("", IconGear); }
 const QIcon iconDisplay() { return getIcon("", IconEye); }
+#ifdef COPYQ_GLOBAL_SHORTCUTS
+const QIcon iconShortcut() { return getIcon("", IconKeyboard); }
+#endif
 
 QStringList serializeShortcuts(const QList<QKeySequence> &shortcuts)
 {
@@ -91,11 +93,11 @@ CommandWidget::CommandWidget(QWidget *parent)
 
     updateWidgets();
 
-#ifdef NO_GLOBAL_SHORTCUTS
+#ifdef COPYQ_GLOBAL_SHORTCUTS
+    ui->toolButtonGlobalShortcut->setIcon(iconShortcut());
+#else
     ui->toolButtonGlobalShortcut->hide();
     ui->shortcutButtonGlobalShortcut->hide();
-#else
-    ui->toolButtonGlobalShortcut->setIcon(iconShortcut());
 #endif
 
     ui->toolButtonAutomatic->setIcon(iconClipboard());
diff --git a/src/gui/menuitems.cpp b/src/gui/menuitems.cpp
index 2c74388a4c..d1b4404ecb 100644
--- a/src/gui/menuitems.cpp
+++ b/src/gui/menuitems.cpp
@@ -48,7 +48,7 @@ MenuItems menuItems()
     addMenuItem( items, Actions::File_Preferences, QObject::tr("&Preferences..."), "preferences", QObject::tr("Ctrl+P"),
                   "preferences-other", IconWrench );
     addMenuItem( items, Actions::File_Commands,
-#ifndef NO_GLOBAL_SHORTCUTS
+#ifdef COPYQ_GLOBAL_SHORTCUTS
                   QObject::tr("C&ommands/Global Shortcuts..."),
 #else
                   QObject::tr("C&ommands..."),
diff --git a/src/platform/platform.cmake b/src/platform/platform.cmake
index 3ce96a491f..b04057db5a 100644
--- a/src/platform/platform.cmake
+++ b/src/platform/platform.cmake
@@ -22,4 +22,3 @@ else()
         )
     set(USE_QXT FALSE)
 endif()
-
diff --git a/src/platform/x11/x11info.cpp b/src/platform/x11/x11info.cpp
index aac230d47e..0b445437ab 100644
--- a/src/platform/x11/x11info.cpp
+++ b/src/platform/x11/x11info.cpp
@@ -4,14 +4,17 @@
 
 #include <QGuiApplication>
 
-#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
-#   include <QX11Info>
+#ifdef COPYQ_WITH_X11
+#   if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+#       include <QX11Info>
+#   else
+#       include <QtGui/private/qtx11extras_p.h>
+#   endif
+#   include <X11/Xlib.h>
 #else
-#   include <QtGui/private/qtx11extras_p.h>
+struct _XDisplay {};
 #endif
 
-#include <X11/Xlib.h>
-
 bool X11Info::isPlatformX11()
 {
     return QGuiApplication::platformName() == QStringLiteral("xcb");
@@ -19,5 +22,9 @@ bool X11Info::isPlatformX11()
 
 Display *X11Info::display()
 {
+#ifdef COPYQ_WITH_X11
     return QX11Info::display();
+#else
+    return nullptr;
+#endif
 }
diff --git a/src/platform/x11/x11platform.cmake b/src/platform/x11/x11platform.cmake
index 841e4854e3..1ad0ed519a 100644
--- a/src/platform/x11/x11platform.cmake
+++ b/src/platform/x11/x11platform.cmake
@@ -1,36 +1,47 @@
-# X11 requires 'fixes' extension for clipboard to work correctly.
-message(STATUS "Building for X11 window system.")
-if(NOT X11_Xfixes_FOUND)
-    message(FATAL_ERROR "X11 'fixes' extension library is required")
-endif(NOT X11_Xfixes_FOUND)
-
-if(X11_XTest_FOUND)
-    add_definitions( -DHAS_X11TEST )
-    list(APPEND copyq_DEFINITIONS HAS_X11TEST)
-    list(APPEND copyq_LIBRARIES ${X11_XTest_LIB})
-else(X11_XTest_FOUND)
-    message(WARNING "X11 'TEST' extension library is needed to be able to"
-                    " automatically paste to some windows!")
-endif(X11_XTest_FOUND)
-
-add_definitions( -DCOPYQ_WS_X11 )
-list(APPEND copyq_DEFINITIONS COPYQ_WS_X11)
-
 file(GLOB copyq_SOURCES ${copyq_SOURCES}
-    platform/x11/*.cpp
+    platform/x11/x11info.cpp
+    platform/x11/x11platform.cpp
+    platform/x11/x11platformclipboard.cpp
     platform/dummy/dummyclipboard.cpp
     platform/platformcommon.cpp
-    ../qxt/qxtglobalshortcut_x11.cpp
     )
 
-set(USE_QXT TRUE)
+add_definitions( -DHAS_MOUSE_SELECTIONS )
+add_definitions( -DCOPYQ_MOVE_TO_WORKSPACE )
+
+OPTION(WITH_X11 "Enable X11 support (global shortcuts, getting window titles)" ON)
+if (WITH_X11)
+    add_definitions( -DCOPYQ_WITH_X11 )
+
+    # X11 requires 'fixes' extension for clipboard to work correctly.
+    message(STATUS "Building for X11 window system.")
+    if(NOT X11_Xfixes_FOUND)
+        message(FATAL_ERROR "X11 'fixes' extension library is required")
+    endif(NOT X11_Xfixes_FOUND)
+
+    if(X11_XTest_FOUND)
+        add_definitions( -DHAS_X11TEST )
+        list(APPEND copyq_DEFINITIONS HAS_X11TEST)
+        list(APPEND copyq_LIBRARIES ${X11_XTest_LIB})
+    else(X11_XTest_FOUND)
+        message(WARNING "X11 'TEST' extension library is needed to be able to"
+                        " automatically paste to some windows!")
+    endif(X11_XTest_FOUND)
+
+    file(GLOB copyq_SOURCES ${copyq_SOURCES}
+        platform/x11/x11platformwindow.cpp
+        ../qxt/qxtglobalshortcut_x11.cpp
+        )
+
+    set(USE_QXT TRUE)
 
-set(copyq_LIBRARIES ${copyq_LIBRARIES} ${X11_LIBRARIES} ${X11_Xfixes_LIB})
+    set(copyq_LIBRARIES ${copyq_LIBRARIES} ${X11_LIBRARIES} ${X11_Xfixes_LIB})
 
-if(WITH_QT6)
-    list(APPEND copyq_LIBRARIES Qt::GuiPrivate)
-else()
-    list(APPEND copyq_qt_modules X11Extras)
+    if(WITH_QT6)
+        list(APPEND copyq_LIBRARIES Qt::GuiPrivate)
+    else()
+        list(APPEND copyq_qt_modules X11Extras)
+    endif()
 endif()
 
 # Wayland clipboard
diff --git a/src/platform/x11/x11platform.cpp b/src/platform/x11/x11platform.cpp
index 97e2bee2d7..244a1eb6b3 100644
--- a/src/platform/x11/x11platform.cpp
+++ b/src/platform/x11/x11platform.cpp
@@ -16,18 +16,18 @@
 #include <QVariant>
 #include <QWidget>
 
-#include "x11platformwindow.h"
 #include "x11platformclipboard.h"
 
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
+#ifdef COPYQ_WITH_X11
+#   include "x11platformwindow.h"
+#   include <X11/Xatom.h>
+#   include <X11/Xlib.h>
+#endif
 
 #include <memory>
 
 namespace {
 
-int (*old_xio_errhandler)(Display *) = nullptr;
-
 const char *defaultDesktopFileContent =
 R"([Desktop Entry]
 Name=CopyQ
@@ -40,6 +40,9 @@ X-KDE-StartupNotify=false
 X-KDE-UniqueApplet=true
 )";
 
+#ifdef COPYQ_WITH_X11
+int (*old_xio_errhandler)(Display *) = nullptr;
+
 // Try to handle X11 fatal error gracefully.
 int copyq_xio_errhandler(Display *display)
 {
@@ -60,6 +63,7 @@ int copyq_xio_errhandler(Display *display)
     // As documentation for XSetIOErrorHandler states, this function should not return.
     exit(1);
 }
+#endif
 
 #ifdef COPYQ_DESKTOP_FILE
 QString getDesktopFilename()
@@ -96,20 +100,29 @@ X11Platform::~X11Platform() = default;
 
 PlatformWindowPtr X11Platform::getWindow(WId winId)
 {
+#ifdef COPYQ_WITH_X11
     if (!X11Info::isPlatformX11())
         return PlatformWindowPtr();
 
     std::unique_ptr<X11PlatformWindow> window(new X11PlatformWindow(winId));
     return PlatformWindowPtr(window->isValid() ? window.release() : nullptr);
+#else
+    Q_UNUSED(winId)
+    return PlatformWindowPtr();
+#endif
 }
 
 PlatformWindowPtr X11Platform::getCurrentWindow()
 {
+#ifdef COPYQ_WITH_X11
     if (!X11Info::isPlatformX11())
         return PlatformWindowPtr();
 
     std::unique_ptr<X11PlatformWindow> window(new X11PlatformWindow());
     return PlatformWindowPtr(window->isValid() ? window.release() : nullptr);
+#else
+    return PlatformWindowPtr();
+#endif
 }
 
 bool X11Platform::canAutostart()
@@ -227,8 +240,10 @@ QCoreApplication *X11Platform::createConsoleApplication(int &argc, char **argv)
 
 QApplication *X11Platform::createServerApplication(int &argc, char **argv)
 {
+#ifdef COPYQ_WITH_X11
     if (X11Info::isPlatformX11())
         old_xio_errhandler = XSetIOErrorHandler(copyq_xio_errhandler);
+#endif
     return new ApplicationExceptionHandler<QApplication>(argc, argv);
 }
 
@@ -305,15 +320,20 @@ QString X11Platform::translationPrefix()
     return QString();
 }
 
+#ifdef COPYQ_WITH_X11
 void sendDummyX11Event()
 {
     if (!X11Info::isPlatformX11())
         return;
 
     auto display = X11Info::display();
+    if (!display)
+        return;
+
     auto black = BlackPixel(display, 0);
     Window window = XCreateSimpleWindow(
         display, RootWindow(display, 0), -100000, -100000, 1, 1, 0, black, black);
     XDestroyWindow(display, window);
     XFlush(display);
 }
+#endif
diff --git a/src/platform/x11/x11platform.h b/src/platform/x11/x11platform.h
index 9a45961fba..aab04ea185 100644
--- a/src/platform/x11/x11platform.h
+++ b/src/platform/x11/x11platform.h
@@ -62,6 +62,8 @@ class X11Platform final : public PlatformNativeInterface
     QString themePrefix() override { return QString(); }
 };
 
+#ifdef COPYQ_WITH_X11
 void sendDummyX11Event();
+#endif
 
 #endif // X11PLATFORM_H
diff --git a/src/platform/x11/x11platformclipboard.cpp b/src/platform/x11/x11platformclipboard.cpp
index 17a4480fae..9c6499b771 100644
--- a/src/platform/x11/x11platformclipboard.cpp
+++ b/src/platform/x11/x11platformclipboard.cpp
@@ -13,8 +13,10 @@
 
 #include "systemclipboard/waylandclipboard.h"
 
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
+#ifdef COPYQ_WITH_X11
+#   include <X11/Xlib.h>
+#   include <X11/Xatom.h>
+#endif
 
 #include <QClipboard>
 #include <QMimeData>
@@ -28,10 +30,13 @@ constexpr auto maxRetryCount = 3;
 /// Return true only if selection is incomplete, i.e. mouse button or shift key is pressed.
 bool isSelectionIncomplete()
 {
+#ifdef COPYQ_WITH_X11
     if (!X11Info::isPlatformX11())
         return false;
 
     auto display = X11Info::display();
+    if (!display)
+        return false;
 
     // If mouse button or shift is pressed then assume that user is selecting text.
     XEvent event{};
@@ -42,6 +47,9 @@ bool isSelectionIncomplete()
                   &event.xbutton.state);
 
     return event.xbutton.state & (Button1Mask | ShiftMask);
+#else
+    return true;
+#endif
 }
 
 } // namespace
diff --git a/src/platform/x11/x11platformwindow.cpp b/src/platform/x11/x11platformwindow.cpp
index 0850db7ed9..d0937f1d05 100644
--- a/src/platform/x11/x11platformwindow.cpp
+++ b/src/platform/x11/x11platformwindow.cpp
@@ -171,6 +171,9 @@ Window getCurrentWindow()
         return 0L;
 
     auto display = X11Info::display();
+    if (!display)
+        return 0L;
+
     XSync(display, False);
 
     static Atom atomWindow = XInternAtom(display, "_NET_ACTIVE_WINDOW", true);
@@ -204,6 +207,9 @@ QString X11PlatformWindow::getTitle()
         return QString();
 
     auto display = X11Info::display();
+    if (!display)
+        return QString();
+
     static Atom atomName = XInternAtom(display, "_NET_WM_NAME", false);
     static Atom atomUTF8 = XInternAtom(display, "UTF8_STRING", false);
 
@@ -224,9 +230,11 @@ void X11PlatformWindow::raise()
     if (!X11Info::isPlatformX11())
         return;
 
-    COPYQ_LOG( QString("Raising window \"%1\"").arg(getTitle()) );
-
     auto display = X11Info::display();
+    if (!display)
+        return;
+
+    COPYQ_LOG( QString("Raising window \"%1\"").arg(getTitle()) );
 
     XEvent e{};
     memset(&e, 0, sizeof(e));
@@ -311,6 +319,8 @@ void X11PlatformWindow::sendKeyPress(int modifier, int key, const AppConfig &con
         return;
 
     auto display = X11Info::display();
+    if (!display)
+        return;
 
 #ifdef HAS_X11TEST
     simulateKeyPress(display, QList<int>() << modifier, static_cast<uint>(key), config);
diff --git a/src/scriptable/scriptable.cpp b/src/scriptable/scriptable.cpp
index 1b74659ada..af61985cbd 100644
--- a/src/scriptable/scriptable.cpp
+++ b/src/scriptable/scriptable.cpp
@@ -1715,10 +1715,10 @@ QJSValue Scriptable::info()
                 );
 
     info.insert("has-global-shortcuts",
-#ifdef NO_GLOBAL_SHORTCUTS
-                "0"
-#else
+#ifdef COPYQ_GLOBAL_SHORTCUTS
                 "1"
+#else
+                "0"
 #endif
                 );
 
@@ -1734,7 +1734,8 @@ QJSValue Scriptable::info()
 #else
                 "?"
 #endif
-#ifdef COPYQ_WS_X11
+
+#ifdef COPYQ_WITH_X11
                 "/X11"
 #endif
                 );