summaryrefslogtreecommitdiff
path: root/vcl/qt5/Qt5Frame.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/qt5/Qt5Frame.cxx')
-rw-r--r--vcl/qt5/Qt5Frame.cxx72
1 files changed, 72 insertions, 0 deletions
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index ed5f306d7ab0..8726b11bcf6d 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -36,6 +36,7 @@
#include <QtCore/QPoint>
#include <QtCore/QSize>
#include <QtCore/QThread>
+#include <QtCore/QVersionNumber>
#include <QtGui/QDragMoveEvent>
#include <QtGui/QDropEvent>
#include <QtGui/QIcon>
@@ -51,6 +52,9 @@
#if QT5_USING_X11
#include <QtX11Extras/QX11Info>
#include <xcb/xproto.h>
+#if QT5_HAVE_XCB_ICCCM
+#include <xcb/xcb_icccm.h>
+#endif
#endif
#include <saldatabasic.hxx>
@@ -63,6 +67,11 @@
#include <cairo.h>
#include <headless/svpgdi.hxx>
+#if 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,
sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight)
{
@@ -197,6 +206,69 @@ Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
m_aSystemData.platform = SystemEnvData::Platform::Wayland;
SetIcon(SV_ICON_ID_OFFICE);
+
+ fixICCCMwindowGroup();
+}
+
+void Qt5Frame::fixICCCMwindowGroup()
+{
+#if 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;
+
+ if (QGuiApplication::platformName() != "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);
+#endif
}
Qt5Frame::~Qt5Frame()