vcl/Library_vclplug_qt5.mk   |    3 +
 vcl/Library_vclplug_qt6.mk   |    3 +
 vcl/inc/qt5/QtTools.hxx      |    2 
 vcl/inc/qt5/QtX11Support.hxx |   30 +++++++++++
 vcl/inc/qt6/QtX11Support.hxx |   12 ++++
 vcl/qt5/QtFrame.cxx          |   91 ++++-----------------------------
 vcl/qt5/QtX11Support.cxx     |  117 +++++++++++++++++++++++++++++++++++++++++++
 vcl/qt6/QtX11Support.cxx     |   12 ++++
 8 files changed, 192 insertions(+), 78 deletions(-)

New commits:
commit fbc61e06584ff8e6d9240f8b67be8dc28ecab5b9
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Wed Jun 15 23:34:01 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Sat Jun 18 12:18:19 2022 +0200

    Qt move most X11 specifics into QtX11Support
    
    Just some refactoring.
    
    Change-Id: I5b2ef531778d4d43d2fdc32fe7da59edffa3c02e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136061
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de>

diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk
index d21f7d989410..25a8864c83ad 100644
--- a/vcl/Library_vclplug_qt5.mk
+++ b/vcl/Library_vclplug_qt5.mk
@@ -106,6 +106,9 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\
     vcl/qt5/QtVirtualDevice \
     vcl/qt5/QtWidget \
     vcl/qt5/QtXAccessible \
+    $(if $(USING_X11), \
+        vcl/qt5/QtX11Support \
+    ) \
 ))
 
 ifeq ($(OS),LINUX)
diff --git a/vcl/Library_vclplug_qt6.mk b/vcl/Library_vclplug_qt6.mk
index 9a4e627f3e22..36da06abb294 100644
--- a/vcl/Library_vclplug_qt6.mk
+++ b/vcl/Library_vclplug_qt6.mk
@@ -105,6 +105,9 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt6,\
     vcl/qt6/QtVirtualDevice \
     vcl/qt6/QtWidget \
     vcl/qt6/QtXAccessible \
+    $(if $(USING_X11), \
+        vcl/qt6/QtX11Support \
+    ) \
 ))
 
 ifeq ($(OS),LINUX)
diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx
index ecaa7075a426..534fe74de772 100644
--- a/vcl/inc/qt5/QtTools.hxx
+++ b/vcl/inc/qt5/QtTools.hxx
@@ -19,6 +19,8 @@
 
 #pragma once
 
+#include <config_vclplug.h>
+
 #include <QtCore/QPoint>
 #include <QtCore/QRect>
 #include <QtCore/QSize>
diff --git a/vcl/inc/qt5/QtX11Support.hxx b/vcl/inc/qt5/QtX11Support.hxx
new file mode 100644
index 000000000000..2931e82e4d1a
--- /dev/null
+++ b/vcl/inc/qt5/QtX11Support.hxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <string_view>
+
+#include <xcb/xcb.h>
+
+class QtX11Support final
+{
+    static constexpr const char* m_sWindowGroupName = "WM_CLIENT_LEADER\0";
+    static xcb_atom_t m_nWindowGroupAtom;
+    static bool m_bDidAtomLookups;
+
+    static xcb_atom_t lookupAtom(xcb_connection_t*, const char* const 
sAtomName);
+    static void fetchAtoms();
+
+public:
+    static bool fixICCCMwindowGroup(xcb_window_t nWinId);
+    static void setApplicationID(xcb_window_t nWinId, std::u16string_view 
rWMClass);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt6/QtX11Support.hxx b/vcl/inc/qt6/QtX11Support.hxx
new file mode 100644
index 000000000000..df4ae0d1e069
--- /dev/null
+++ b/vcl/inc/qt6/QtX11Support.hxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "../qt5/QtX11Support.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 31ca3c432be9..006ad4a8bfc1 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -31,12 +31,14 @@
 #include <QtSystem.hxx>
 #include <QtTools.hxx>
 #include <QtTransferable.hxx>
+#if CHECK_ANY_QT_USING_X11
+#include <QtX11Support.hxx>
+#endif
 
 #include <QtCore/QMimeData>
 #include <QtCore/QPoint>
 #include <QtCore/QSize>
 #include <QtCore/QThread>
-#include <QtCore/QVersionNumber>
 #include <QtGui/QDragMoveEvent>
 #include <QtGui/QDropEvent>
 #include <QtGui/QIcon>
@@ -50,13 +52,8 @@
 #endif
 #include <QtWidgets/QMenuBar>
 #include <QtWidgets/QMainWindow>
-
 #if CHECK_QT5_USING_X11
 #include <QtX11Extras/QX11Info>
-#include <xcb/xproto.h>
-#if QT5_HAVE_XCB_ICCCM
-#include <xcb/xcb_icccm.h>
-#endif
 #endif
 
 #include <window.h>
@@ -71,7 +68,6 @@
 
 #if CHECK_QT5_USING_X11 && QT5_HAVE_XCB_ICCCM
 static bool g_bNeedsWmHintsWindowGroup = true;
-static xcb_atom_t g_aXcbClientLeaderAtom = 0;
 #endif
 
 static void SvpDamageHandler(void* handle, sal_Int32 nExtentsX, sal_Int32 
nExtentsY,
@@ -228,9 +224,6 @@ void QtFrame::FillSystemEnvData(SystemEnvData& rData, 
sal_IntPtr pWindow, QWidge
 void QtFrame::fixICCCMwindowGroup()
 {
 #if CHECK_QT5_USING_X11 && QT5_HAVE_XCB_ICCCM
-    // older Qt5 just sets WM_CLIENT_LEADER, but not the 
XCB_ICCCM_WM_HINT_WINDOW_GROUP
-    // see Qt commit 0de4b326d8 ("xcb: fix issue with dialogs hidden by other 
windows")
-    // or QTBUG-46626. So LO has to set this itself to help some WMs.
     if (!g_bNeedsWmHintsWindowGroup)
         return;
     g_bNeedsWmHintsWindowGroup = false;
@@ -238,52 +231,8 @@ void QtFrame::fixICCCMwindowGroup()
     assert(m_aSystemData.platform != SystemEnvData::Platform::Invalid);
     if (m_aSystemData.platform != SystemEnvData::Platform::Xcb)
         return;
-    if (QVersionNumber::fromString(qVersion()) >= QVersionNumber(5, 12))
-        return;
-
-    xcb_connection_t* conn = QX11Info::connection();
-    xcb_window_t win = asChild()->winId();
-
-    xcb_icccm_wm_hints_t hints;
-
-    xcb_get_property_cookie_t prop_cookie = 
xcb_icccm_get_wm_hints_unchecked(conn, win);
-    if (!xcb_icccm_get_wm_hints_reply(conn, prop_cookie, &hints, nullptr))
-        return;
-
-    if (hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP)
-        return;
-
-    if (g_aXcbClientLeaderAtom == 0)
-    {
-        const char* const leader_name = "WM_CLIENT_LEADER\0";
-        xcb_intern_atom_cookie_t atom_cookie
-            = xcb_intern_atom(conn, 1, strlen(leader_name), leader_name);
-        xcb_intern_atom_reply_t* atom_reply = xcb_intern_atom_reply(conn, 
atom_cookie, nullptr);
-        if (!atom_reply)
-            return;
-        g_aXcbClientLeaderAtom = atom_reply->atom;
-        free(atom_reply);
-    }
-
-    g_bNeedsWmHintsWindowGroup = true;
-
-    prop_cookie = xcb_get_property(conn, 0, win, g_aXcbClientLeaderAtom, 
XCB_ATOM_WINDOW, 0, 1);
-    xcb_get_property_reply_t* prop_reply = xcb_get_property_reply(conn, 
prop_cookie, nullptr);
-    if (!prop_reply)
-        return;
-
-    if (xcb_get_property_value_length(prop_reply) != 4)
-    {
-        free(prop_reply);
-        return;
-    }
 
-    xcb_window_t leader = 
*static_cast<xcb_window_t*>(xcb_get_property_value(prop_reply));
-    free(prop_reply);
-
-    hints.flags |= XCB_ICCCM_WM_HINT_WINDOW_GROUP;
-    hints.window_group = leader;
-    xcb_icccm_set_wm_hints(conn, win, &hints);
+    g_bNeedsWmHintsWindowGroup = 
QtX11Support::fixICCCMwindowGroup(asChild()->winId());
 #else
     (void)this; // avoid loplugin:staticmethods
 #endif
@@ -779,23 +728,22 @@ void QtFrame::ShowFullScreen(bool bFullScreen, sal_Int32 
nScreen)
 
 void QtFrame::StartPresentation(bool bStart)
 {
-// meh - so there's no Qt platform independent solution
-// 
https://forum.qt.io/topic/38504/solved-qdialog-in-fullscreen-disable-os-screensaver
-#if CHECK_QT5_USING_X11
+    // meh - so there's no Qt platform independent solution
+    // 
https://forum.qt.io/topic/38504/solved-qdialog-in-fullscreen-disable-os-screensaver
+    assert(m_aSystemData.platform != SystemEnvData::Platform::Invalid);
+    const bool bIsX11 = m_aSystemData.platform == SystemEnvData::Platform::Xcb;
     std::optional<unsigned int> aRootWindow;
     std::optional<Display*> aDisplay;
 
+#if CHECK_QT5_USING_X11
     if (QX11Info::isPlatformX11())
     {
         aRootWindow = QX11Info::appRootWindow();
         aDisplay = QX11Info::display();
     }
-
-    m_ScreenSaverInhibitor.inhibit(bStart, u"presentation", 
QX11Info::isPlatformX11(), aRootWindow,
-                                   aDisplay);
-#else
-    (void)bStart;
 #endif
+
+    m_ScreenSaverInhibitor.inhibit(bStart, u"presentation", bIsX11, 
aRootWindow, aDisplay);
 }
 
 void QtFrame::SetAlwaysOnTop(bool bOnTop)
@@ -1360,22 +1308,9 @@ void QtFrame::SetApplicationID(const OUString& rWMClass)
     if (m_aSystemData.platform != SystemEnvData::Platform::Xcb || !m_pTopLevel)
         return;
 
-    OString aResClass = OUStringToOString(rWMClass, RTL_TEXTENCODING_ASCII_US);
-    const char* pResClass
-        = !aResClass.isEmpty() ? aResClass.getStr() : 
SalGenericSystem::getFrameClassName();
-    OString aResName = SalGenericSystem::getFrameResName();
-
-    // the WM_CLASS data consists of two concatenated cstrings, including the 
terminating '\0' chars
-    const uint32_t data_len = aResName.getLength() + 1 + strlen(pResClass) + 1;
-    char* data = new char[data_len];
-    memcpy(data, aResName.getStr(), aResName.getLength() + 1);
-    memcpy(data + aResName.getLength() + 1, pResClass, strlen(pResClass) + 1);
-
-    xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, 
m_pTopLevel->winId(),
-                        XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, data_len, data);
-    delete[] data;
+    QtX11Support::setApplicationID(m_pTopLevel->winId(), rWMClass);
 #else
-    (void)rWMClass;
+    Q_UNUSED(rWMClass);
 #endif
 }
 
diff --git a/vcl/qt5/QtX11Support.cxx b/vcl/qt5/QtX11Support.cxx
new file mode 100644
index 000000000000..93f3085ffab3
--- /dev/null
+++ b/vcl/qt5/QtX11Support.cxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <QtX11Support.hxx>
+
+#include <config_vclplug.h>
+
+#include <QtCore/QVersionNumber>
+#include <QtX11Extras/QX11Info>
+
+#include <QtInstance.hxx>
+#include <QtTools.hxx>
+
+#if QT5_HAVE_XCB_ICCCM
+#include <xcb/xcb_icccm.h>
+#endif
+
+#include <unx/gensys.h>
+
+xcb_atom_t QtX11Support::m_nWindowGroupAtom = 0;
+bool QtX11Support::m_bDidAtomLookups = false;
+
+xcb_atom_t QtX11Support::lookupAtom(xcb_connection_t* pConn, const char* const 
sAtomName)
+{
+    xcb_atom_t nAtom = 0;
+    xcb_intern_atom_cookie_t atom_cookie = xcb_intern_atom(pConn, 1, 
strlen(sAtomName), sAtomName);
+    xcb_intern_atom_reply_t* atom_reply = xcb_intern_atom_reply(pConn, 
atom_cookie, nullptr);
+    if (atom_reply)
+    {
+        nAtom = atom_reply->atom;
+        free(atom_reply);
+    }
+    return nAtom;
+}
+
+void QtX11Support::fetchAtoms()
+{
+    if (m_bDidAtomLookups)
+        return;
+    m_bDidAtomLookups = true;
+
+    xcb_connection_t* pXcbConn = QX11Info::connection();
+    m_nWindowGroupAtom = lookupAtom(pXcbConn, m_sWindowGroupName);
+}
+
+void QtX11Support::setApplicationID(const xcb_window_t nWinId, 
std::u16string_view rWMClass)
+{
+    OString aResClass = OUStringToOString(rWMClass, RTL_TEXTENCODING_ASCII_US);
+    const char* pResClass
+        = !aResClass.isEmpty() ? aResClass.getStr() : 
SalGenericSystem::getFrameClassName();
+    OString aResName = SalGenericSystem::getFrameResName();
+
+    // the WM_CLASS data consists of two concatenated cstrings, including the 
terminating '\0' chars
+    const uint32_t data_len = aResName.getLength() + 1 + strlen(pResClass) + 1;
+    char* data = new char[data_len];
+    memcpy(data, aResName.getStr(), aResName.getLength() + 1);
+    memcpy(data + aResName.getLength() + 1, pResClass, strlen(pResClass) + 1);
+
+    xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, nWinId, 
XCB_ATOM_WM_CLASS,
+                        XCB_ATOM_STRING, 8, data_len, data);
+    delete[] data;
+}
+
+bool QtX11Support::fixICCCMwindowGroup(const xcb_window_t nWinId)
+{
+#if CHECK_QT5_USING_X11 && QT5_HAVE_XCB_ICCCM
+    // older Qt5 just sets WM_CLIENT_LEADER, but not the 
XCB_ICCCM_WM_HINT_WINDOW_GROUP
+    // see Qt commit 0de4b326d8 ("xcb: fix issue with dialogs hidden by other 
windows")
+    // or QTBUG-46626. So LO has to set this itself to help some WMs.
+    if (QVersionNumber::fromString(qVersion()) >= QVersionNumber(5, 12))
+        return false;
+
+    xcb_connection_t* pXcbConn = QX11Info::connection();
+    xcb_icccm_wm_hints_t hints;
+
+    xcb_get_property_cookie_t prop_cookie = 
xcb_icccm_get_wm_hints_unchecked(pXcbConn, nWinId);
+    if (!xcb_icccm_get_wm_hints_reply(pXcbConn, prop_cookie, &hints, nullptr))
+        return false;
+
+    if (hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP)
+        return false;
+
+    fetchAtoms();
+    if (!m_nWindowGroupAtom)
+        return false;
+
+    prop_cookie = xcb_get_property(pXcbConn, 0, nWinId, m_nWindowGroupAtom, 
XCB_ATOM_WINDOW, 0, 1);
+    xcb_get_property_reply_t* prop_reply = xcb_get_property_reply(pXcbConn, 
prop_cookie, nullptr);
+    if (!prop_reply)
+        return true;
+
+    if (xcb_get_property_value_length(prop_reply) != 4)
+    {
+        free(prop_reply);
+        return true;
+    }
+
+    xcb_window_t leader = 
*static_cast<xcb_window_t*>(xcb_get_property_value(prop_reply));
+    free(prop_reply);
+
+    hints.flags |= XCB_ICCCM_WM_HINT_WINDOW_GROUP;
+    hints.window_group = leader;
+    xcb_icccm_set_wm_hints(pXcbConn, nWinId, &hints);
+    return true;
+#else
+    Q_UNUSED(nWinId);
+    return false;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt6/QtX11Support.cxx b/vcl/qt6/QtX11Support.cxx
new file mode 100644
index 000000000000..28f67978e3eb
--- /dev/null
+++ b/vcl/qt6/QtX11Support.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "../qt5/QtX11Support.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to