KWayland

plasmashell_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2015 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "plasmashell_interface.h"
7 #include "global_p.h"
8 #include "resource_p.h"
9 #include "display.h"
10 #include "surface_interface.h"
11 
12 #include <QTimer>
13 
14 #include <wayland-server.h>
15 #include <wayland-plasma-shell-server-protocol.h>
16 
17 namespace KWayland
18 {
19 namespace Server
20 {
21 
22 class PlasmaShellInterface::Private : public Global::Private
23 {
24 public:
25  Private(PlasmaShellInterface *q, Display *d);
26 
28 
29 private:
30  static void createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface);
31  void bind(wl_client *client, uint32_t version, uint32_t id) override;
32  void createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface, wl_resource *parentResource);
33 
34  PlasmaShellInterface *q;
35  static const struct org_kde_plasma_shell_interface s_interface;
36  static const quint32 s_version;
37 };
38 
39 const quint32 PlasmaShellInterface::Private::s_version = 6;
40 
41 PlasmaShellInterface::Private::Private(PlasmaShellInterface *q, Display *d)
42  : Global::Private(d, &org_kde_plasma_shell_interface, s_version)
43  , q(q)
44 {
45 }
46 
47 #ifndef K_DOXYGEN
48 const struct org_kde_plasma_shell_interface PlasmaShellInterface::Private::s_interface = {
49  createSurfaceCallback
50 };
51 #endif
52 
53 
54 class PlasmaShellSurfaceInterface::Private : public Resource::Private
55 {
56 public:
57  Private(PlasmaShellSurfaceInterface *q, PlasmaShellInterface *shell, SurfaceInterface *surface, wl_resource *parentResource);
58 
59  SurfaceInterface *surface;
60  QPoint m_globalPos;
61  Role m_role = Role::Normal;
62  bool m_positionSet = false;
63  PanelBehavior m_panelBehavior = PanelBehavior::AlwaysVisible;
64  bool m_skipTaskbar = false;
65  bool m_skipSwitcher = false;
66  bool panelTakesFocus = false;
67 
68 private:
69  // interface callbacks
70  static void setOutputCallback(wl_client *client, wl_resource *resource, wl_resource *output);
71  static void setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y);
72  static void setRoleCallback(wl_client *client, wl_resource *resource, uint32_t role);
73  static void setPanelBehaviorCallback(wl_client *client, wl_resource *resource, uint32_t flag);
74  static void setSkipTaskbarCallback(wl_client *client, wl_resource *resource, uint32_t skip);
75  static void setSkipSwitcherCallback(wl_client *client, wl_resource *resource, uint32_t skip);
76  static void panelAutoHideHideCallback(wl_client *client, wl_resource *resource);
77  static void panelAutoHideShowCallback(wl_client *client, wl_resource *resource);
78  static void panelTakesFocusCallback(wl_client *client, wl_resource *resource, uint32_t takesFocus);
79 
80  void setPosition(const QPoint &globalPos);
81  void setRole(uint32_t role);
82  void setPanelBehavior(org_kde_plasma_surface_panel_behavior behavior);
83 
84  PlasmaShellSurfaceInterface *q_func() {
85  return reinterpret_cast<PlasmaShellSurfaceInterface *>(q);
86  }
87 
88  static const struct org_kde_plasma_surface_interface s_interface;
89 };
90 
91 PlasmaShellInterface::PlasmaShellInterface(Display *display, QObject *parent)
92  : Global(new Private(this, display), parent)
93 {
94 }
95 
96 PlasmaShellInterface::~PlasmaShellInterface() = default;
97 
98 void PlasmaShellInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
99 {
100  auto c = display->getConnection(client);
101  wl_resource *shell = c->createResource(&org_kde_plasma_shell_interface, qMin(version, s_version), id);
102  if (!shell) {
103  wl_client_post_no_memory(client);
104  return;
105  }
106  wl_resource_set_implementation(shell, &s_interface, this, nullptr);
107 }
108 
109 void PlasmaShellInterface::Private::createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
110 {
111  auto s = reinterpret_cast<PlasmaShellInterface::Private*>(wl_resource_get_user_data(resource));
112  s->createSurface(client, wl_resource_get_version(resource), id, SurfaceInterface::get(surface), resource);
113 }
114 
115 void PlasmaShellInterface::Private::createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface, wl_resource *parentResource)
116 {
117  auto it = std::find_if(surfaces.constBegin(), surfaces.constEnd(),
118  [surface](PlasmaShellSurfaceInterface *s) {
119  return surface == s->surface();
120  }
121  );
122  if (it != surfaces.constEnd()) {
123  wl_resource_post_error(surface->resource(), WL_DISPLAY_ERROR_INVALID_OBJECT, "PlasmaShellSurface already created");
124  return;
125  }
126  PlasmaShellSurfaceInterface *shellSurface = new PlasmaShellSurfaceInterface(q, surface, parentResource);
127  surfaces << shellSurface;
128  QObject::connect(shellSurface, &PlasmaShellSurfaceInterface::destroyed, q,
129  [this, shellSurface] {
130  surfaces.removeAll(shellSurface);
131  }
132  );
133  shellSurface->d->create(display->getConnection(client), version, id);
134  emit q->surfaceCreated(shellSurface);
135 }
136 
137 /*********************************
138  * ShellSurfaceInterface
139  *********************************/
140 PlasmaShellSurfaceInterface::Private::Private(PlasmaShellSurfaceInterface *q, PlasmaShellInterface *shell, SurfaceInterface *surface, wl_resource *parentResource)
141  : Resource::Private(q, shell, parentResource, &org_kde_plasma_surface_interface, &s_interface)
142  , surface(surface)
143 {
144 }
145 
146 #ifndef K_DOXYGEN
147 const struct org_kde_plasma_surface_interface PlasmaShellSurfaceInterface::Private::s_interface = {
148  resourceDestroyedCallback,
149  setOutputCallback,
150  setPositionCallback,
151  setRoleCallback,
152  setPanelBehaviorCallback,
153  setSkipTaskbarCallback,
154  panelAutoHideHideCallback,
155  panelAutoHideShowCallback,
156  panelTakesFocusCallback,
157  setSkipSwitcherCallback
158 };
159 #endif
160 
161 PlasmaShellSurfaceInterface::PlasmaShellSurfaceInterface(PlasmaShellInterface *shell, SurfaceInterface *parent, wl_resource *parentResource)
162  : Resource(new Private(this, shell, parent, parentResource))
163 {
164  auto unsetSurface = [this] {
165  Q_D();
166  d->surface = nullptr;
167  };
168  connect(parent, &Resource::unbound, this, unsetSurface);
169  connect(parent, &QObject::destroyed, this, unsetSurface);
170 }
171 
172 PlasmaShellSurfaceInterface::~PlasmaShellSurfaceInterface() = default;
173 
174 SurfaceInterface *PlasmaShellSurfaceInterface::surface() const {
175  Q_D();
176  return d->surface;
177 }
178 
179 PlasmaShellInterface *PlasmaShellSurfaceInterface::shell() const {
180  Q_D();
181  return reinterpret_cast<PlasmaShellInterface*>(d->global);
182 }
183 
184 PlasmaShellSurfaceInterface::Private *PlasmaShellSurfaceInterface::d_func() const
185 {
186  return reinterpret_cast<PlasmaShellSurfaceInterface::Private*>(d.data());
187 }
188 
189 void PlasmaShellSurfaceInterface::Private::setOutputCallback(wl_client *client, wl_resource *resource, wl_resource *output)
190 {
191  Q_UNUSED(client)
192  Q_UNUSED(resource)
193  Q_UNUSED(output)
194  // TODO: implement
195 }
196 
197 void PlasmaShellSurfaceInterface::Private::setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y)
198 {
199  auto s = cast<Private>(resource);
200  Q_ASSERT(client == *s->client);
201  s->setPosition(QPoint(x, y));
202 }
203 
204 void PlasmaShellSurfaceInterface::Private::setPosition(const QPoint &globalPos)
205 {
206  if (m_globalPos == globalPos && m_positionSet) {
207  return;
208  }
209  m_positionSet = true;
210  m_globalPos = globalPos;
212  emit q->positionChanged();
213 }
214 
215 void PlasmaShellSurfaceInterface::Private::setRoleCallback(wl_client *client, wl_resource *resource, uint32_t role)
216 {
217  auto s = cast<Private>(resource);
218  Q_ASSERT(client == *s->client);
219  s->setRole(role);
220 }
221 
222 void PlasmaShellSurfaceInterface::Private::setRole(uint32_t role)
223 {
224  Role r = Role::Normal;
225  switch (role) {
226  case ORG_KDE_PLASMA_SURFACE_ROLE_DESKTOP:
227  r = Role::Desktop;
228  break;
229  case ORG_KDE_PLASMA_SURFACE_ROLE_PANEL:
230  r = Role::Panel;
231  break;
232  case ORG_KDE_PLASMA_SURFACE_ROLE_ONSCREENDISPLAY:
234  break;
235  case ORG_KDE_PLASMA_SURFACE_ROLE_NOTIFICATION:
236  r = Role::Notification;
237  break;
238  case ORG_KDE_PLASMA_SURFACE_ROLE_TOOLTIP:
239  r = Role::ToolTip;
240  break;
241  case ORG_KDE_PLASMA_SURFACE_ROLE_CRITICALNOTIFICATION:
243  break;
244  case ORG_KDE_PLASMA_SURFACE_ROLE_NORMAL:
245  default:
246  r = Role::Normal;
247  break;
248  }
249  if (r == m_role) {
250  return;
251  }
252  m_role = r;
254  emit q->roleChanged();
255 }
256 
257 void PlasmaShellSurfaceInterface::Private::setPanelBehaviorCallback(wl_client *client, wl_resource *resource, uint32_t flag)
258 {
259  auto s = cast<Private>(resource);
260  Q_ASSERT(client == *s->client);
261  s->setPanelBehavior(org_kde_plasma_surface_panel_behavior(flag));
262 }
263 
264 void PlasmaShellSurfaceInterface::Private::setSkipTaskbarCallback(wl_client *client, wl_resource *resource, uint32_t skip)
265 {
266  auto s = cast<Private>(resource);
267  Q_ASSERT(client == *s->client);
268  s->m_skipTaskbar = (bool)skip;
269  emit s->q_func()->skipTaskbarChanged();
270 }
271 
272 void PlasmaShellSurfaceInterface::Private::setSkipSwitcherCallback(wl_client *client, wl_resource *resource, uint32_t skip)
273 {
274  auto s = cast<Private>(resource);
275  Q_ASSERT(client == *s->client);
276  s->m_skipSwitcher = (bool)skip;
277  emit s->q_func()->skipSwitcherChanged();
278 }
279 
280 void PlasmaShellSurfaceInterface::Private::panelAutoHideHideCallback(wl_client *client, wl_resource *resource)
281 {
282  auto s = cast<Private>(resource);
283  Q_ASSERT(client == *s->client);
284  if (s->m_role != Role::Panel || s->m_panelBehavior != PanelBehavior::AutoHide) {
285  wl_resource_post_error(s->resource, ORG_KDE_PLASMA_SURFACE_ERROR_PANEL_NOT_AUTO_HIDE, "Not an auto hide panel");
286  return;
287  }
288  emit s->q_func()->panelAutoHideHideRequested();
289 }
290 
291 void PlasmaShellSurfaceInterface::Private::panelAutoHideShowCallback(wl_client *client, wl_resource *resource)
292 {
293  auto s = cast<Private>(resource);
294  Q_ASSERT(client == *s->client);
295  if (s->m_role != Role::Panel || s->m_panelBehavior != PanelBehavior::AutoHide) {
296  wl_resource_post_error(s->resource, ORG_KDE_PLASMA_SURFACE_ERROR_PANEL_NOT_AUTO_HIDE, "Not an auto hide panel");
297  return;
298  }
299  emit s->q_func()->panelAutoHideShowRequested();
300 }
301 
302 void PlasmaShellSurfaceInterface::Private::panelTakesFocusCallback(wl_client *client, wl_resource *resource, uint32_t takesFocus)
303 {
304  auto s = cast<Private>(resource);
305  Q_ASSERT(client == *s->client);
306  if (s->panelTakesFocus == takesFocus) {
307  return;
308  }
309  s->panelTakesFocus = takesFocus;
310  emit s->q_func()->panelTakesFocusChanged();
311 }
312 
313 void PlasmaShellSurfaceInterface::Private::setPanelBehavior(org_kde_plasma_surface_panel_behavior behavior)
314 {
315  PanelBehavior newBehavior = PanelBehavior::AlwaysVisible;
316  switch (behavior) {
317  case ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_AUTO_HIDE:
318  newBehavior = PanelBehavior::AutoHide;
319  break;
320  case ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_WINDOWS_CAN_COVER:
321  newBehavior = PanelBehavior::WindowsCanCover;
322  break;
323  case ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_WINDOWS_GO_BELOW:
324  newBehavior = PanelBehavior::WindowsGoBelow;
325  break;
326  case ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_ALWAYS_VISIBLE:
327  default:
328  break;
329  }
330  if (m_panelBehavior == newBehavior) {
331  return;
332  }
333  m_panelBehavior = newBehavior;
335  emit q->panelBehaviorChanged();
336 }
337 
338 QPoint PlasmaShellSurfaceInterface::position() const
339 {
340  Q_D();
341  return d->m_globalPos;
342 }
343 
344 PlasmaShellSurfaceInterface::Role PlasmaShellSurfaceInterface::role() const
345 {
346  Q_D();
347  return d->m_role;
348 }
349 
350 bool PlasmaShellSurfaceInterface::isPositionSet() const
351 {
352  Q_D();
353  return d->m_positionSet;
354 }
355 
356 PlasmaShellSurfaceInterface::PanelBehavior PlasmaShellSurfaceInterface::panelBehavior() const
357 {
358  Q_D();
359  return d->m_panelBehavior;
360 }
361 
362 bool PlasmaShellSurfaceInterface::skipTaskbar() const
363 {
364  Q_D();
365  return d->m_skipTaskbar;
366 }
367 
368 bool PlasmaShellSurfaceInterface::skipSwitcher() const
369 {
370  Q_D();
371  return d->m_skipSwitcher;
372 }
373 
374 void PlasmaShellSurfaceInterface::hideAutoHidingPanel()
375 {
376  Q_D();
377  if (!d->resource) {
378  return;
379  }
380  org_kde_plasma_surface_send_auto_hidden_panel_hidden(d->resource);
381 }
382 
383 void PlasmaShellSurfaceInterface::showAutoHidingPanel()
384 {
385  Q_D();
386  if (!d->resource) {
387  return;
388  }
389  org_kde_plasma_surface_send_auto_hidden_panel_shown(d->resource);
390 }
391 
392 bool PlasmaShellSurfaceInterface::panelTakesFocus() const
393 {
394  Q_D();
395  return d->panelTakesFocus;
396 }
397 
398 PlasmaShellSurfaceInterface *PlasmaShellSurfaceInterface::get(wl_resource *native)
399 {
400  return Private::get<PlasmaShellSurfaceInterface>(native);
401 }
402 
403 }
404 }
The Surface represents a tooltip.
Global for the org_kde_plasma_shell interface.
The Surface represents a desktop, normally stacked below all other surfaces.
The Surface represents a critical notification, like battery is running out.
The Surface represents a notification.
void setPanelBehavior(PanelBehavior behavior)
Sets the PanelBehavior for a PlasmaShellSurface with Role Role::Panel.
void setRole(Role role)
Changes the requested Role to role.
The Surface represents an on screen display, like a volume changed notification.
Resource for the org_kde_plasma_shell_surface interface.
Resource representing a wl_surface.
T * data() const const
The Surface represents a panel (dock), normally stacked above normal surfaces.
void setPosition(const QPoint &point)
Requests to position this PlasmaShellSurface at point in global coordinates.
PanelBehavior
Describes how a PlasmaShellSurfaceInterface with role Role::Panel should behave.
Role
Describes possible roles this PlasmaShellSurfaceInterface can have.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
void destroyed(QObject *obj)
Role
Describes possible roles this PlasmaShellSurface can have.
Definition: plasmashell.h:229
PanelBehavior
Describes how a PlasmaShellSurface with role Role::Panel should behave.
Definition: plasmashell.h:257
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Aug 10 2020 22:53:34 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.