KWaylandServer

plasmashell_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2015 Martin Gräßlin <[email protected]>
3  SPDX-FileCopyrightText: 2020 David Edmundson <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 #include "plasmashell_interface.h"
8 #include "display.h"
9 #include "surface_interface.h"
10 #include "utils.h"
11 
12 #include <qwayland-server-plasma-shell.h>
13 
14 namespace KWaylandServer
15 {
16 static const quint32 s_version = 6;
17 static QList<PlasmaShellSurfaceInterface *> s_shellSurfaces;
18 
19 class PlasmaShellInterfacePrivate : public QtWaylandServer::org_kde_plasma_shell
20 {
21 public:
22  PlasmaShellInterfacePrivate(PlasmaShellInterface *q, Display *display);
23 
24 private:
25  void org_kde_plasma_shell_get_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) override;
26  PlasmaShellInterface *q;
27 };
28 
29 PlasmaShellInterfacePrivate::PlasmaShellInterfacePrivate(PlasmaShellInterface *_q, Display *display)
30  : QtWaylandServer::org_kde_plasma_shell(*display, s_version)
31  , q(_q)
32 {
33 }
34 
35 class PlasmaShellSurfaceInterfacePrivate : public QtWaylandServer::org_kde_plasma_surface
36 {
37 public:
38  PlasmaShellSurfaceInterfacePrivate(PlasmaShellSurfaceInterface *q, SurfaceInterface *surface, wl_resource *resource);
39 
41  PlasmaShellSurfaceInterface *q;
42  QPoint m_globalPos;
43  PlasmaShellSurfaceInterface::Role m_role = PlasmaShellSurfaceInterface::Role::Normal;
44  PlasmaShellSurfaceInterface::PanelBehavior m_panelBehavior = PlasmaShellSurfaceInterface::PanelBehavior::AlwaysVisible;
45  bool m_positionSet = false;
46  bool m_skipTaskbar = false;
47  bool m_skipSwitcher = false;
48  bool m_panelTakesFocus = false;
49 
50 private:
51  void org_kde_plasma_surface_destroy_resource(Resource *resource) override;
52  void org_kde_plasma_surface_destroy(Resource *resource) override;
53  void org_kde_plasma_surface_set_output(Resource *resource, struct ::wl_resource *output) override;
54  void org_kde_plasma_surface_set_position(Resource *resource, int32_t x, int32_t y) override;
55  void org_kde_plasma_surface_set_role(Resource *resource, uint32_t role) override;
56  void org_kde_plasma_surface_set_panel_behavior(Resource *resource, uint32_t flag) override;
57  void org_kde_plasma_surface_set_skip_taskbar(Resource *resource, uint32_t skip) override;
58  void org_kde_plasma_surface_panel_auto_hide_hide(Resource *resource) override;
59  void org_kde_plasma_surface_panel_auto_hide_show(Resource *resource) override;
60  void org_kde_plasma_surface_set_panel_takes_focus(Resource *resource, uint32_t takes_focus) override;
61  void org_kde_plasma_surface_set_skip_switcher(Resource *resource, uint32_t skip) override;
62 };
63 
64 PlasmaShellInterface::PlasmaShellInterface(Display *display, QObject *parent)
65  : QObject(parent)
66  , d(new PlasmaShellInterfacePrivate(this, display))
67 {
68 }
69 
70 PlasmaShellInterface::~PlasmaShellInterface() = default;
71 
72 void PlasmaShellInterfacePrivate::org_kde_plasma_shell_get_surface(QtWaylandServer::org_kde_plasma_shell::Resource *resource,
73  uint32_t id,
74  struct ::wl_resource *surface)
75 {
76  SurfaceInterface *s = SurfaceInterface::get(surface);
77  if (!s) {
78  wl_resource_post_error(resource->handle, 0, "Invalid surface");
79  return;
80  }
81 
82  if (PlasmaShellSurfaceInterface::get(s)) {
83  wl_resource_post_error(resource->handle, 0, "org_kde_plasma_shell_surface already exists");
84  return;
85  }
86 
87  wl_resource *shell_resource = wl_resource_create(resource->client(), &org_kde_plasma_surface_interface, resource->version(), id);
88 
89  auto shellSurface = new PlasmaShellSurfaceInterface(s, shell_resource);
90  s_shellSurfaces.append(shellSurface);
91 
92  QObject::connect(shellSurface, &QObject::destroyed, [shellSurface]() {
93  s_shellSurfaces.removeOne(shellSurface);
94  });
95 
96  Q_EMIT q->surfaceCreated(shellSurface);
97 }
98 
99 /*********************************
100  * ShellSurfaceInterface
101  *********************************/
102 PlasmaShellSurfaceInterfacePrivate::PlasmaShellSurfaceInterfacePrivate(PlasmaShellSurfaceInterface *_q, SurfaceInterface *surface, wl_resource *resource)
103  : QtWaylandServer::org_kde_plasma_surface(resource)
104  , surface(surface)
105  , q(_q)
106 {
107 }
108 
109 PlasmaShellSurfaceInterface::PlasmaShellSurfaceInterface(SurfaceInterface *surface, wl_resource *resource)
110  : d(new PlasmaShellSurfaceInterfacePrivate(this, surface, resource))
111 {
112 }
113 
114 PlasmaShellSurfaceInterface::~PlasmaShellSurfaceInterface() = default;
115 
116 SurfaceInterface *PlasmaShellSurfaceInterface::surface() const
117 {
118  return d->surface;
119 }
120 
121 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_destroy(Resource *resource)
122 {
123  wl_resource_destroy(resource->handle);
124 }
125 
126 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_destroy_resource(Resource *resource)
127 {
128  Q_UNUSED(resource)
129  delete q;
130 }
131 
132 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_output(Resource *resource, struct ::wl_resource *output)
133 {
134  Q_UNUSED(resource)
135  Q_UNUSED(output)
136  // TODO: implement
137 }
138 
139 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_position(Resource *resource, int32_t x, int32_t y)
140 {
141  Q_UNUSED(resource);
142  QPoint globalPos(x, y);
143  if (m_globalPos == globalPos && m_positionSet) {
144  return;
145  }
146  m_positionSet = true;
147  m_globalPos = globalPos;
148  Q_EMIT q->positionChanged();
149 }
150 
151 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_role(Resource *resource, uint32_t role)
152 {
153  Q_UNUSED(resource)
154 
155  PlasmaShellSurfaceInterface::Role r = PlasmaShellSurfaceInterface::Role::Normal;
156  switch (role) {
157  case role_desktop:
158  r = PlasmaShellSurfaceInterface::Role::Desktop;
159  break;
160  case role_panel:
161  r = PlasmaShellSurfaceInterface::Role::Panel;
162  break;
163  case role_onscreendisplay:
164  r = PlasmaShellSurfaceInterface::Role::OnScreenDisplay;
165  break;
166  case role_notification:
167  r = PlasmaShellSurfaceInterface::Role::Notification;
168  break;
169  case role_tooltip:
170  r = PlasmaShellSurfaceInterface::Role::ToolTip;
171  break;
172  case role_criticalnotification:
173  r = PlasmaShellSurfaceInterface::Role::CriticalNotification;
174  break;
175  case role_normal:
176  default:
177  r = PlasmaShellSurfaceInterface::Role::Normal;
178  break;
179  }
180  if (r == m_role) {
181  return;
182  }
183  m_role = r;
184  Q_EMIT q->roleChanged();
185 }
186 
187 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_panel_behavior(Resource *resource, uint32_t flag)
188 {
189  Q_UNUSED(resource)
190 
191  PlasmaShellSurfaceInterface::PanelBehavior newBehavior = PlasmaShellSurfaceInterface::PanelBehavior::AlwaysVisible;
192  switch (flag) {
193  case panel_behavior_auto_hide:
194  newBehavior = PlasmaShellSurfaceInterface::PanelBehavior::AutoHide;
195  break;
196  case panel_behavior_windows_can_cover:
197  newBehavior = PlasmaShellSurfaceInterface::PanelBehavior::WindowsCanCover;
198  break;
199  case panel_behavior_windows_go_below:
200  newBehavior = PlasmaShellSurfaceInterface::PanelBehavior::WindowsGoBelow;
201  break;
202  case panel_behavior_always_visible:
203  default:
204  break;
205  }
206  if (m_panelBehavior == newBehavior) {
207  return;
208  }
209  m_panelBehavior = newBehavior;
210  Q_EMIT q->panelBehaviorChanged();
211 }
212 
213 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_skip_taskbar(Resource *resource, uint32_t skip)
214 {
215  Q_UNUSED(resource)
216 
217  m_skipTaskbar = (bool)skip;
218  Q_EMIT q->skipTaskbarChanged();
219 }
220 
221 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_skip_switcher(Resource *resource, uint32_t skip)
222 {
223  Q_UNUSED(resource)
224 
225  m_skipSwitcher = (bool)skip;
226  Q_EMIT q->skipSwitcherChanged();
227 }
228 
229 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_panel_auto_hide_hide(Resource *resource)
230 {
231  if (m_role != PlasmaShellSurfaceInterface::Role::Panel
232  || (m_panelBehavior != PlasmaShellSurfaceInterface::PanelBehavior::AutoHide
233  && m_panelBehavior != PlasmaShellSurfaceInterface::PanelBehavior::WindowsCanCover)) {
234  wl_resource_post_error(resource->handle, error_panel_not_auto_hide, "Not an auto hide panel");
235  return;
236  }
237  Q_EMIT q->panelAutoHideHideRequested();
238 }
239 
240 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_panel_auto_hide_show(Resource *resource)
241 {
242  if (m_role != PlasmaShellSurfaceInterface::Role::Panel || m_panelBehavior != PlasmaShellSurfaceInterface::PanelBehavior::AutoHide) {
243  wl_resource_post_error(resource->handle, error_panel_not_auto_hide, "Not an auto hide panel");
244  return;
245  }
246  Q_EMIT q->panelAutoHideShowRequested();
247 }
248 
249 void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_panel_takes_focus(Resource *resource, uint32_t takesFocus)
250 {
251  Q_UNUSED(resource)
252 
253  if (m_panelTakesFocus == takesFocus) {
254  return;
255  }
256  m_panelTakesFocus = takesFocus;
257  Q_EMIT q->panelTakesFocusChanged();
258 }
259 
260 QPoint PlasmaShellSurfaceInterface::position() const
261 {
262  return d->m_globalPos;
263 }
264 
265 PlasmaShellSurfaceInterface::Role PlasmaShellSurfaceInterface::role() const
266 {
267  return d->m_role;
268 }
269 
270 bool PlasmaShellSurfaceInterface::isPositionSet() const
271 {
272  return d->m_positionSet;
273 }
274 
275 PlasmaShellSurfaceInterface::PanelBehavior PlasmaShellSurfaceInterface::panelBehavior() const
276 {
277  return d->m_panelBehavior;
278 }
279 
280 bool PlasmaShellSurfaceInterface::skipTaskbar() const
281 {
282  return d->m_skipTaskbar;
283 }
284 
285 bool PlasmaShellSurfaceInterface::skipSwitcher() const
286 {
287  return d->m_skipSwitcher;
288 }
289 
290 void PlasmaShellSurfaceInterface::hideAutoHidingPanel()
291 {
292  d->send_auto_hidden_panel_hidden();
293 }
294 
295 void PlasmaShellSurfaceInterface::showAutoHidingPanel()
296 {
297  d->send_auto_hidden_panel_shown();
298 }
299 
300 bool PlasmaShellSurfaceInterface::panelTakesFocus() const
301 {
302  return d->m_panelTakesFocus;
303 }
304 
305 PlasmaShellSurfaceInterface *PlasmaShellSurfaceInterface::get(wl_resource *native)
306 {
307  if (auto surfacePrivate = resource_cast<PlasmaShellSurfaceInterfacePrivate *>(native)) {
308  return surfacePrivate->q;
309  }
310  return nullptr;
311 }
312 
313 PlasmaShellSurfaceInterface *PlasmaShellSurfaceInterface::get(SurfaceInterface *surface)
314 {
315  for (PlasmaShellSurfaceInterface *shellSurface : qAsConst(s_shellSurfaces)) {
316  if (shellSurface->surface() == surface) {
317  return shellSurface;
318  }
319  }
320  return nullptr;
321 }
322 
323 }
PanelBehavior
Describes how a PlasmaShellSurfaceInterface with role Role::Panel should behave.
void append(const T &value)
Role
Describes possible roles this PlasmaShellSurfaceInterface can have.
Resource for the org_kde_plasma_shell_surface interface.
Resource representing a wl_surface.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool removeOne(const T &value)
void destroyed(QObject *obj)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:08:27 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.