summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2022-06-15 23:34:01 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2022-06-18 12:18:19 +0200
commitfbc61e06584ff8e6d9240f8b67be8dc28ecab5b9 (patch)
treea2d7984fc304f0ce23fc9c482442b5ba93cb749e
parent994d517a48f7e092ec57d179abb855ef5a86eacb (diff)
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 <glogow@fbihome.de>
-rw-r--r--vcl/Library_vclplug_qt5.mk3
-rw-r--r--vcl/Library_vclplug_qt6.mk3
-rw-r--r--vcl/inc/qt5/QtTools.hxx2
-rw-r--r--vcl/inc/qt5/QtX11Support.hxx30
-rw-r--r--vcl/inc/qt6/QtX11Support.hxx12
-rw-r--r--vcl/qt5/QtFrame.cxx91
-rw-r--r--vcl/qt5/QtX11Support.cxx117
-rw-r--r--vcl/qt6/QtX11Support.cxx12
8 files changed, 192 insertions, 78 deletions
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: */