1 /*
2 SPDX-FileCopyrightText: 2020 Benjamin Port <benjamin.port@enioka.com>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6
7 #include "keyboard_shortcuts_inhibit_v1_interface.h"
8
9 #include <qwayland-server-keyboard-shortcuts-inhibit-unstable-v1.h>
10
11 #include "display.h"
12 #include "seat_interface.h"
13 #include "surface_interface.h"
14
15 static const int s_version = 1;
16
17 namespace KWaylandServer
18 {
19 class KeyboardShortcutsInhibitorV1InterfacePrivate : public QtWaylandServer::zwp_keyboard_shortcuts_inhibitor_v1
20 {
21 public:
22 KeyboardShortcutsInhibitorV1InterfacePrivate(SurfaceInterface *surface,
23 SeatInterface *seat,
24 KeyboardShortcutsInhibitManagerV1Interface *manager,
25 KeyboardShortcutsInhibitorV1Interface *q,
26 wl_resource *resource);
27
28 KeyboardShortcutsInhibitorV1Interface *q;
29 QPointer<KeyboardShortcutsInhibitManagerV1Interface> m_manager;
30 SurfaceInterface *const m_surface;
31 SeatInterface *const m_seat;
32 bool m_active;
33
34 protected:
35 void zwp_keyboard_shortcuts_inhibitor_v1_destroy_resource(Resource *resource) override;
36
37 void zwp_keyboard_shortcuts_inhibitor_v1_destroy(Resource *resource) override;
38 };
39
40 class KeyboardShortcutsInhibitManagerV1InterfacePrivate : public QtWaylandServer::zwp_keyboard_shortcuts_inhibit_manager_v1
41 {
42 public:
43 KeyboardShortcutsInhibitManagerV1InterfacePrivate(Display *display, KeyboardShortcutsInhibitManagerV1Interface *q);
44
45 void zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(Resource *resource,
46 uint32_t id,
47 struct ::wl_resource *surface_resource,
48 struct ::wl_resource *seat_resource) override;
49
50 KeyboardShortcutsInhibitorV1Interface *findInhibitor(SurfaceInterface *surface, SeatInterface *seat) const;
51
52 void removeInhibitor(SurfaceInterface *const surface, SeatInterface *const seat);
53
54 KeyboardShortcutsInhibitManagerV1Interface *q;
55 Display *const m_display;
56 QHash<QPair<SurfaceInterface *, SeatInterface *>, KeyboardShortcutsInhibitorV1Interface *> m_inhibitors;
57
58 protected:
59 void zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(Resource *resource) override;
60 };
61
KeyboardShortcutsInhibitorV1InterfacePrivate(SurfaceInterface * surface,SeatInterface * seat,KeyboardShortcutsInhibitManagerV1Interface * manager,KeyboardShortcutsInhibitorV1Interface * q,wl_resource * resource)62 KeyboardShortcutsInhibitorV1InterfacePrivate::KeyboardShortcutsInhibitorV1InterfacePrivate(SurfaceInterface *surface,
63 SeatInterface *seat,
64 KeyboardShortcutsInhibitManagerV1Interface *manager,
65 KeyboardShortcutsInhibitorV1Interface *q,
66 wl_resource *resource)
67 : zwp_keyboard_shortcuts_inhibitor_v1(resource)
68 , q(q)
69 , m_manager(manager)
70 , m_surface(surface)
71 , m_seat(seat)
72 , m_active(false)
73 {
74 }
75
zwp_keyboard_shortcuts_inhibitor_v1_destroy(Resource * resource)76 void KeyboardShortcutsInhibitorV1InterfacePrivate::zwp_keyboard_shortcuts_inhibitor_v1_destroy(Resource *resource)
77 {
78 wl_resource_destroy(resource->handle);
79 }
80
zwp_keyboard_shortcuts_inhibitor_v1_destroy_resource(Resource * resource)81 void KeyboardShortcutsInhibitorV1InterfacePrivate::zwp_keyboard_shortcuts_inhibitor_v1_destroy_resource(Resource *resource)
82 {
83 Q_UNUSED(resource)
84 // Ensure manager don't track anymore this inhibitor
85 if (m_manager) {
86 m_manager->removeInhibitor(m_surface, m_seat);
87 }
88 delete q;
89 }
90
KeyboardShortcutsInhibitorV1Interface(SurfaceInterface * surface,SeatInterface * seat,KeyboardShortcutsInhibitManagerV1Interface * manager,wl_resource * resource)91 KeyboardShortcutsInhibitorV1Interface::KeyboardShortcutsInhibitorV1Interface(SurfaceInterface *surface,
92 SeatInterface *seat,
93 KeyboardShortcutsInhibitManagerV1Interface *manager,
94 wl_resource *resource)
95 : QObject(nullptr)
96 , d(new KeyboardShortcutsInhibitorV1InterfacePrivate(surface, seat, manager, this, resource))
97 {
98 }
99
100 KeyboardShortcutsInhibitorV1Interface::~KeyboardShortcutsInhibitorV1Interface() = default;
101
setActive(bool active)102 void KeyboardShortcutsInhibitorV1Interface::setActive(bool active)
103 {
104 if (d->m_active == active) {
105 return;
106 }
107 d->m_active = active;
108 if (active) {
109 d->send_active();
110 } else {
111 d->send_inactive();
112 }
113 }
114
isActive() const115 bool KeyboardShortcutsInhibitorV1Interface::isActive() const
116 {
117 return d->m_active;
118 }
119
seat() const120 SeatInterface *KeyboardShortcutsInhibitorV1Interface::seat() const
121 {
122 return d->m_seat;
123 }
124
surface() const125 SurfaceInterface *KeyboardShortcutsInhibitorV1Interface::surface() const
126 {
127 return d->m_surface;
128 }
129
KeyboardShortcutsInhibitManagerV1InterfacePrivate(Display * display,KeyboardShortcutsInhibitManagerV1Interface * q)130 KeyboardShortcutsInhibitManagerV1InterfacePrivate::KeyboardShortcutsInhibitManagerV1InterfacePrivate(Display *display,
131 KeyboardShortcutsInhibitManagerV1Interface *q)
132 : zwp_keyboard_shortcuts_inhibit_manager_v1(*display, s_version)
133 , q(q)
134 , m_display(display)
135 {
136 }
137
zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(Resource * resource,uint32_t id,wl_resource * surface_resource,wl_resource * seat_resource)138 void KeyboardShortcutsInhibitManagerV1InterfacePrivate::zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(Resource *resource,
139 uint32_t id,
140 wl_resource *surface_resource,
141 wl_resource *seat_resource)
142 {
143 SeatInterface *seat = SeatInterface::get(seat_resource);
144 SurfaceInterface *surface = SurfaceInterface::get(surface_resource);
145 if (m_inhibitors.contains({surface, seat})) {
146 wl_resource_post_error(resource->handle, error::error_already_inhibited, "the shortcuts are already inhibited for this surface and seat");
147 return;
148 }
149
150 wl_resource *inhibitorResource = wl_resource_create(resource->client(), &zwp_keyboard_shortcuts_inhibitor_v1_interface, resource->version(), id);
151 auto inhibitor = new KeyboardShortcutsInhibitorV1Interface(surface, seat, q, inhibitorResource);
152 m_inhibitors[{surface, seat}] = inhibitor;
153 Q_EMIT q->inhibitorCreated(inhibitor);
154 inhibitor->setActive(true);
155 }
156
findInhibitor(SurfaceInterface * surface,SeatInterface * seat) const157 KeyboardShortcutsInhibitorV1Interface *KeyboardShortcutsInhibitManagerV1InterfacePrivate::findInhibitor(SurfaceInterface *surface, SeatInterface *seat) const
158 {
159 return m_inhibitors.value({surface, seat}, nullptr);
160 }
161
zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(Resource * resource)162 void KeyboardShortcutsInhibitManagerV1InterfacePrivate::zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(Resource *resource)
163 {
164 wl_resource_destroy(resource->handle);
165 }
166
removeInhibitor(SurfaceInterface * const surface,SeatInterface * const seat)167 void KeyboardShortcutsInhibitManagerV1InterfacePrivate::removeInhibitor(SurfaceInterface *const surface, SeatInterface *const seat)
168 {
169 m_inhibitors.remove({surface, seat});
170 }
171
KeyboardShortcutsInhibitManagerV1Interface(Display * display,QObject * parent)172 KeyboardShortcutsInhibitManagerV1Interface::KeyboardShortcutsInhibitManagerV1Interface(Display *display, QObject *parent)
173 : QObject(parent)
174 , d(new KeyboardShortcutsInhibitManagerV1InterfacePrivate(display, this))
175 {
176 }
177
178 KeyboardShortcutsInhibitManagerV1Interface::~KeyboardShortcutsInhibitManagerV1Interface() = default;
179
findInhibitor(SurfaceInterface * surface,SeatInterface * seat) const180 KeyboardShortcutsInhibitorV1Interface *KeyboardShortcutsInhibitManagerV1Interface::findInhibitor(SurfaceInterface *surface, SeatInterface *seat) const
181 {
182 return d->findInhibitor(surface, seat);
183 }
184
removeInhibitor(SurfaceInterface * surface,SeatInterface * seat)185 void KeyboardShortcutsInhibitManagerV1Interface::removeInhibitor(SurfaceInterface *surface, SeatInterface *seat)
186 {
187 d->removeInhibitor(surface, seat);
188 }
189
190 }
191