GCC Code Coverage Report


Directory: ./
File: src/client/xdg_shell.cpp
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 82 90 91.1%
Branches: 14 28 50.0%

Line Branch Exec Source
1 /*
2 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
3 SPDX-FileCopyrightText: 2021 Roman Gilg <subdiff@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only
6 */
7 #include "xdg_shell.h"
8
9 #include "xdg_shell_popup.h"
10 #include "xdg_shell_positioner.h"
11 #include "xdg_shell_toplevel.h"
12
13 #include "event_queue.h"
14 #include "seat.h"
15 #include "surface.h"
16 #include "wayland_pointer_p.h"
17
18 #include <wayland-xdg-shell-client-protocol.h>
19
20 namespace Wrapland::Client
21 {
22
23 81 class Q_DECL_HIDDEN XdgShell::Private
24 {
25 public:
26 virtual ~Private();
27
28 void setup(xdg_wm_base* shell);
29 void release();
30 bool isValid() const;
31
32 6 operator xdg_wm_base*()
33 {
34 6 return xdg_shell_base;
35 }
36 operator xdg_wm_base*() const
37 {
38 return xdg_shell_base;
39 }
40
41 XdgShellToplevel* getXdgToplevel(Surface* surface, QObject* parent);
42 XdgShellPopup* get_xdg_popup(Surface* surface,
43 xdg_surface* parentSurface,
44 xdg_shell_positioner_data positioner_data,
45 QObject* parent);
46 xdg_shell_positioner* get_xdg_positioner(xdg_shell_positioner_data data, QObject* parent);
47
48 81 EventQueue* queue = nullptr;
49
50 private:
51 static void pingCallback(void* data, struct xdg_wm_base* shell, uint32_t serial);
52
53 WaylandPointer<xdg_wm_base, xdg_wm_base_destroy> xdg_shell_base;
54 static const struct xdg_wm_base_listener s_shellListener;
55 };
56
57 162 XdgShell::Private::~Private() = default;
58
59 struct xdg_wm_base_listener const XdgShell::Private::s_shellListener = {
60 pingCallback,
61 };
62
63 1 void XdgShell::Private::pingCallback(void* data, struct xdg_wm_base* shell, uint32_t serial)
64 {
65 Q_UNUSED(data)
66 1 xdg_wm_base_pong(shell, serial);
67 1 }
68
69 81 void XdgShell::Private::setup(xdg_wm_base* shell)
70 {
71
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 Q_ASSERT(shell);
72
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 Q_ASSERT(!xdg_shell_base);
73 81 xdg_shell_base.setup(shell);
74 81 xdg_wm_base_add_listener(shell, &s_shellListener, this);
75 81 }
76
77 83 void XdgShell::Private::release()
78 {
79 83 xdg_shell_base.release();
80 83 }
81
82 151 bool XdgShell::Private::isValid() const
83 {
84 151 return xdg_shell_base.isValid();
85 }
86
87 67 XdgShellToplevel* XdgShell::Private::getXdgToplevel(Surface* surface, QObject* parent)
88 {
89
1/2
✓ Branch 0 taken 67 times.
✗ Branch 1 not taken.
67 Q_ASSERT(isValid());
90 67 auto ss = xdg_wm_base_get_xdg_surface(xdg_shell_base, *surface);
91
92
1/2
✓ Branch 0 taken 67 times.
✗ Branch 1 not taken.
67 if (!ss) {
93 return nullptr;
94 }
95
96
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 auto s = new XdgShellToplevel(parent);
97 67 auto toplevel = xdg_surface_get_toplevel(ss);
98
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 if (queue) {
99 67 queue->addProxy(ss);
100 67 queue->addProxy(toplevel);
101 67 }
102 67 s->setup(ss, toplevel);
103 67 return s;
104 67 }
105
106 11 XdgShellPopup* XdgShell::Private::get_xdg_popup(Surface* surface,
107 xdg_surface* parentSurface,
108 xdg_shell_positioner_data positioner_data,
109 QObject* parent)
110 {
111
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 Q_ASSERT(isValid());
112 11 auto ss = xdg_wm_base_get_xdg_surface(xdg_shell_base, *surface);
113
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (!ss) {
114 return nullptr;
115 }
116
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 XdgShellPopup* s = new XdgShellPopup(parent);
118 11 auto positioner = get_xdg_positioner(positioner_data, nullptr);
119 11 auto popup = xdg_surface_get_popup(ss, parentSurface, *positioner);
120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (queue) {
121 // deliberately not adding the positioner because the positioner has no events sent to it
122 11 queue->addProxy(ss);
123 11 queue->addProxy(popup);
124 11 }
125 11 s->setup(ss, popup);
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 delete positioner;
127
128 11 return s;
129 11 }
130
131 12 xdg_shell_positioner* XdgShell::Private::get_xdg_positioner(xdg_shell_positioner_data data,
132 QObject* parent)
133 {
134
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 auto positioner = new xdg_shell_positioner(parent);
135 12 positioner->setup(xdg_wm_base_create_positioner(xdg_shell_base));
136 12 positioner->set_data(std::move(data));
137
138 // Deliberately not adding the positioner to the queue because it has no events sent to it.
139 12 return positioner;
140 }
141
142 81 XdgShell::XdgShell(QObject* parent)
143 81 : QObject(parent)
144
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 , d_ptr{new Private}
145 81 {
146 81 }
147
148 162 XdgShell::~XdgShell()
149 162 {
150
1/2
✓ Branch 0 taken 81 times.
✗ Branch 1 not taken.
81 release();
151 162 }
152
153 81 void XdgShell::setup(xdg_wm_base* xdg_wm_base)
154 {
155 81 d_ptr->setup(xdg_wm_base);
156 81 }
157
158 83 void XdgShell::release()
159 {
160 83 d_ptr->release();
161 83 }
162
163 81 void XdgShell::setEventQueue(EventQueue* queue)
164 {
165 81 d_ptr->queue = queue;
166 81 }
167
168 EventQueue* XdgShell::eventQueue()
169 {
170 return d_ptr->queue;
171 }
172
173 6 XdgShell::operator xdg_wm_base*()
174 {
175 6 return *(d_ptr.get());
176 }
177
178 XdgShell::operator xdg_wm_base*() const
179 {
180 return *(d_ptr.get());
181 }
182
183 73 bool XdgShell::isValid() const
184 {
185 73 return d_ptr->isValid();
186 }
187
188 67 XdgShellToplevel* XdgShell::create_toplevel(Surface* surface, QObject* parent)
189 {
190 67 return d_ptr->getXdgToplevel(surface, parent);
191 }
192
193 10 XdgShellPopup* XdgShell::create_popup(Surface* surface,
194 XdgShellToplevel* parentSurface,
195 xdg_shell_positioner_data positioner_data,
196 QObject* parent)
197 {
198 10 return d_ptr->get_xdg_popup(surface, *parentSurface, std::move(positioner_data), parent);
199 }
200
201 XdgShellPopup* XdgShell::create_popup(Surface* surface,
202 XdgShellPopup* parentSurface,
203 xdg_shell_positioner_data positioner_data,
204 QObject* parent)
205 {
206 return d_ptr->get_xdg_popup(surface, *parentSurface, std::move(positioner_data), parent);
207 }
208
209 XdgShellPopup*
210 1 XdgShell::create_popup(Surface* surface, xdg_shell_positioner_data positioner_data, QObject* parent)
211 {
212 1 return d_ptr->get_xdg_popup(surface, nullptr, std::move(positioner_data), parent);
213 }
214
215 1 xdg_shell_positioner* XdgShell::create_positioner(xdg_shell_positioner_data data, QObject* parent)
216 {
217 1 return d_ptr->get_xdg_positioner(std::move(data), parent);
218 }
219
220 }
221