1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <QtX11Support.hxx>
12 #include <config_vclplug.h>
14 #include <QtCore/QVersionNumber>
16 #include <QtInstance.hxx>
17 #include <QtTools.hxx>
19 #if CHECK_QT5_USING_X11
20 #include <QtX11Extras/QX11Info>
23 #if QT5_HAVE_XCB_ICCCM
24 #include <xcb/xcb_icccm.h>
27 #include <unx/gensys.h>
29 xcb_atom_t
QtX11Support::m_nWindowGroupAtom
= 0;
30 bool QtX11Support::m_bDidAtomLookups
= false;
32 xcb_atom_t
QtX11Support::lookupAtom(xcb_connection_t
* pConn
, const char* const sAtomName
)
35 xcb_intern_atom_cookie_t atom_cookie
= xcb_intern_atom(pConn
, 1, strlen(sAtomName
), sAtomName
);
36 xcb_intern_atom_reply_t
* atom_reply
= xcb_intern_atom_reply(pConn
, atom_cookie
, nullptr);
39 nAtom
= atom_reply
->atom
;
45 void QtX11Support::fetchAtoms()
47 #if CHECK_QT5_USING_X11
48 if (m_bDidAtomLookups
)
50 m_bDidAtomLookups
= true;
52 xcb_connection_t
* pXcbConn
= QX11Info::connection();
53 m_nWindowGroupAtom
= lookupAtom(pXcbConn
, m_sWindowGroupName
);
57 void QtX11Support::setApplicationID(const xcb_window_t nWinId
, std::u16string_view rWMClass
)
59 #if CHECK_QT5_USING_X11
60 OString aResClass
= OUStringToOString(rWMClass
, RTL_TEXTENCODING_ASCII_US
);
62 = !aResClass
.isEmpty() ? aResClass
.getStr() : SalGenericSystem::getFrameClassName();
63 OString aResName
= SalGenericSystem::getFrameResName();
65 // the WM_CLASS data consists of two concatenated cstrings, including the terminating '\0' chars
66 const uint32_t data_len
= aResName
.getLength() + 1 + strlen(pResClass
) + 1;
67 char* data
= new char[data_len
];
68 memcpy(data
, aResName
.getStr(), aResName
.getLength() + 1);
69 memcpy(data
+ aResName
.getLength() + 1, pResClass
, strlen(pResClass
) + 1);
71 xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE
, nWinId
, XCB_ATOM_WM_CLASS
,
72 XCB_ATOM_STRING
, 8, data_len
, data
);
80 bool QtX11Support::fixICCCMwindowGroup(const xcb_window_t nWinId
)
82 #if CHECK_QT5_USING_X11 && QT5_HAVE_XCB_ICCCM
83 // older Qt5 just sets WM_CLIENT_LEADER, but not the XCB_ICCCM_WM_HINT_WINDOW_GROUP
84 // see Qt commit 0de4b326d8 ("xcb: fix issue with dialogs hidden by other windows")
85 // or QTBUG-46626. So LO has to set this itself to help some WMs.
86 if (QVersionNumber::fromString(qVersion()) >= QVersionNumber(5, 12))
89 xcb_connection_t
* pXcbConn
= QX11Info::connection();
90 xcb_icccm_wm_hints_t hints
;
92 xcb_get_property_cookie_t prop_cookie
= xcb_icccm_get_wm_hints_unchecked(pXcbConn
, nWinId
);
93 if (!xcb_icccm_get_wm_hints_reply(pXcbConn
, prop_cookie
, &hints
, nullptr))
96 if (hints
.flags
& XCB_ICCCM_WM_HINT_WINDOW_GROUP
)
100 if (!m_nWindowGroupAtom
)
103 prop_cookie
= xcb_get_property(pXcbConn
, 0, nWinId
, m_nWindowGroupAtom
, XCB_ATOM_WINDOW
, 0, 1);
104 xcb_get_property_reply_t
* prop_reply
= xcb_get_property_reply(pXcbConn
, prop_cookie
, nullptr);
108 if (xcb_get_property_value_length(prop_reply
) != 4)
114 xcb_window_t leader
= *static_cast<xcb_window_t
*>(xcb_get_property_value(prop_reply
));
117 hints
.flags
|= XCB_ICCCM_WM_HINT_WINDOW_GROUP
;
118 hints
.window_group
= leader
;
119 xcb_icccm_set_wm_hints(pXcbConn
, nWinId
, &hints
);
127 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */