diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2022-06-15 23:34:01 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2022-06-18 12:18:19 +0200 |
commit | fbc61e06584ff8e6d9240f8b67be8dc28ecab5b9 (patch) | |
tree | a2d7984fc304f0ce23fc9c482442b5ba93cb749e | |
parent | 994d517a48f7e092ec57d179abb855ef5a86eacb (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.mk | 3 | ||||
-rw-r--r-- | vcl/Library_vclplug_qt6.mk | 3 | ||||
-rw-r--r-- | vcl/inc/qt5/QtTools.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/qt5/QtX11Support.hxx | 30 | ||||
-rw-r--r-- | vcl/inc/qt6/QtX11Support.hxx | 12 | ||||
-rw-r--r-- | vcl/qt5/QtFrame.cxx | 91 | ||||
-rw-r--r-- | vcl/qt5/QtX11Support.cxx | 117 | ||||
-rw-r--r-- | vcl/qt6/QtX11Support.cxx | 12 |
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: */ |