calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / vcl / qt5 / QtX11Support.cxx
blobd6f372fdadf50d9a5e4a971647bf1528937d6e8c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
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>
21 #endif
23 #if QT5_HAVE_XCB_ICCCM
24 #include <xcb/xcb_icccm.h>
25 #endif
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)
34 xcb_atom_t nAtom = 0;
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);
37 if (atom_reply)
39 nAtom = atom_reply->atom;
40 free(atom_reply);
42 return nAtom;
45 void QtX11Support::fetchAtoms()
47 #if CHECK_QT5_USING_X11
48 if (m_bDidAtomLookups)
49 return;
50 m_bDidAtomLookups = true;
52 xcb_connection_t* pXcbConn = QX11Info::connection();
53 m_nWindowGroupAtom = lookupAtom(pXcbConn, m_sWindowGroupName);
54 #endif
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);
61 const char* pResClass
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);
73 delete[] data;
74 #else
75 Q_UNUSED(nWinId);
76 Q_UNUSED(rWMClass);
77 #endif
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))
87 return false;
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))
94 return false;
96 if (hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP)
97 return false;
99 fetchAtoms();
100 if (!m_nWindowGroupAtom)
101 return false;
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);
105 if (!prop_reply)
106 return true;
108 if (xcb_get_property_value_length(prop_reply) != 4)
110 free(prop_reply);
111 return true;
114 xcb_window_t leader = *static_cast<xcb_window_t*>(xcb_get_property_value(prop_reply));
115 free(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);
120 return true;
121 #else
122 Q_UNUSED(nWinId);
123 return false;
124 #endif
127 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */