1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qxcbwmsupport.h" |
5 | #include "qxcbscreen.h" |
6 | |
7 | #include <qdebug.h> |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | QXcbWMSupport::QXcbWMSupport(QXcbConnection *c) |
12 | : QXcbObject(c) |
13 | { |
14 | updateNetWMAtoms(); |
15 | updateVirtualRoots(); |
16 | } |
17 | |
18 | bool QXcbWMSupport::isSupportedByWM(xcb_atom_t atom) const |
19 | { |
20 | return net_wm_atoms.contains(t: atom); |
21 | } |
22 | |
23 | |
24 | |
25 | void QXcbWMSupport::updateNetWMAtoms() |
26 | { |
27 | net_wm_atoms.clear(); |
28 | |
29 | xcb_window_t root = connection()->primaryScreen()->root(); |
30 | int offset = 0; |
31 | int remaining = 0; |
32 | do { |
33 | auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, root, atom(QXcbAtom::Atom_NET_SUPPORTED), XCB_ATOM_ATOM, offset, 1024); |
34 | if (!reply) |
35 | break; |
36 | |
37 | remaining = 0; |
38 | |
39 | if (reply->type == XCB_ATOM_ATOM && reply->format == 32) { |
40 | int len = xcb_get_property_value_length(R: reply.get())/sizeof(xcb_atom_t); |
41 | xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(R: reply.get()); |
42 | int s = net_wm_atoms.size(); |
43 | net_wm_atoms.resize(size: s + len); |
44 | memcpy(dest: net_wm_atoms.data() + s, src: atoms, n: len*sizeof(xcb_atom_t)); |
45 | |
46 | remaining = reply->bytes_after; |
47 | offset += len; |
48 | } |
49 | } while (remaining > 0); |
50 | } |
51 | |
52 | // update the virtual roots array |
53 | void QXcbWMSupport::updateVirtualRoots() |
54 | { |
55 | net_virtual_roots.clear(); |
56 | |
57 | if (!isSupportedByWM(atom: atom(atom: QXcbAtom::Atom_NET_VIRTUAL_ROOTS))) |
58 | return; |
59 | |
60 | xcb_window_t root = connection()->primaryScreen()->root(); |
61 | int offset = 0; |
62 | int remaining = 0; |
63 | do { |
64 | auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), |
65 | false, root, atom(QXcbAtom::Atom_NET_VIRTUAL_ROOTS), XCB_ATOM_WINDOW, offset, 1024); |
66 | if (!reply) |
67 | break; |
68 | |
69 | remaining = 0; |
70 | |
71 | if (reply->type == XCB_ATOM_WINDOW && reply->format == 32) { |
72 | int len = xcb_get_property_value_length(R: reply.get())/sizeof(xcb_window_t); |
73 | xcb_window_t *roots = (xcb_window_t *)xcb_get_property_value(R: reply.get()); |
74 | int s = net_virtual_roots.size(); |
75 | net_virtual_roots.resize(size: s + len); |
76 | memcpy(dest: net_virtual_roots.data() + s, src: roots, n: len*sizeof(xcb_window_t)); |
77 | |
78 | remaining = reply->bytes_after; |
79 | offset += len; |
80 | } |
81 | |
82 | } while (remaining > 0); |
83 | |
84 | //#define VIRTUAL_ROOTS_DEBUG |
85 | #ifdef VIRTUAL_ROOTS_DEBUG |
86 | qDebug("======== updateVirtualRoots" ); |
87 | for (int i = 0; i < net_virtual_roots.size(); ++i) |
88 | qDebug() << connection()->atomName(net_virtual_roots.at(i)); |
89 | qDebug("======== updateVirtualRoots" ); |
90 | #endif |
91 | } |
92 | |
93 | QT_END_NAMESPACE |
94 | |