KWayland

plasmashell.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.h"
7 #include "event_queue.h"
8 #include "output.h"
9 #include "surface.h"
10 #include "wayland_pointer_p.h"
11 // Wayland
12 #include <wayland-plasma-shell-client-protocol.h>
13 
14 namespace KWayland
15 {
16 namespace Client
17 {
18 class Q_DECL_HIDDEN PlasmaShell::Private
19 {
20 public:
21  WaylandPointer<org_kde_plasma_shell, org_kde_plasma_shell_destroy> shell;
22  EventQueue *queue = nullptr;
23 };
24 
25 class Q_DECL_HIDDEN PlasmaShellSurface::Private
26 {
27 public:
28  Private(PlasmaShellSurface *q);
29  ~Private();
30  void setup(org_kde_plasma_surface *surface);
31 
32  WaylandPointer<org_kde_plasma_surface, org_kde_plasma_surface_destroy> surface;
33  QSize size;
34  QPointer<Surface> parentSurface;
36 
37  static PlasmaShellSurface *get(Surface *surface);
38 
39 private:
40  static void autoHidingPanelHiddenCallback(void *data, org_kde_plasma_surface *org_kde_plasma_surface);
41  static void autoHidingPanelShownCallback(void *data, org_kde_plasma_surface *org_kde_plasma_surface);
42 
43  PlasmaShellSurface *q;
44  static QVector<Private *> s_surfaces;
45  static const org_kde_plasma_surface_listener s_listener;
46 };
47 
48 QVector<PlasmaShellSurface::Private *> PlasmaShellSurface::Private::s_surfaces;
49 
50 PlasmaShell::PlasmaShell(QObject *parent)
51  : QObject(parent)
52  , d(new Private)
53 {
54 }
55 
56 PlasmaShell::~PlasmaShell()
57 {
58  release();
59 }
60 
62 {
63  if (!d->shell) {
64  return;
65  }
67  d->shell.destroy();
68 }
69 
71 {
72  if (!d->shell) {
73  return;
74  }
76  d->shell.release();
77 }
78 
79 void PlasmaShell::setup(org_kde_plasma_shell *shell)
80 {
81  Q_ASSERT(!d->shell);
82  Q_ASSERT(shell);
83  d->shell.setup(shell);
84 }
85 
87 {
88  d->queue = queue;
89 }
90 
92 {
93  return d->queue;
94 }
95 
97 {
98  Q_ASSERT(isValid());
99  auto kwS = Surface::get(surface);
100  if (kwS) {
101  if (auto s = PlasmaShellSurface::Private::get(kwS)) {
102  return s;
103  }
104  }
108  auto w = org_kde_plasma_shell_get_surface(d->shell, surface);
109  if (d->queue) {
110  d->queue->addProxy(w);
111  }
112  s->setup(w);
113  s->d->parentSurface = QPointer<Surface>(kwS);
114  return s;
115 }
116 
118 {
119  return createSurface(*surface, parent);
120 }
121 
123 {
124  return d->shell.isValid();
125 }
126 
127 PlasmaShell::operator org_kde_plasma_shell *()
128 {
129  return d->shell;
130 }
131 
132 PlasmaShell::operator org_kde_plasma_shell *() const
133 {
134  return d->shell;
135 }
136 
137 PlasmaShellSurface::Private::Private(PlasmaShellSurface *q)
138  : role(PlasmaShellSurface::Role::Normal)
139  , q(q)
140 {
141  s_surfaces << this;
142 }
143 
144 PlasmaShellSurface::Private::~Private()
145 {
146  s_surfaces.removeAll(this);
147 }
148 
149 PlasmaShellSurface *PlasmaShellSurface::Private::get(Surface *surface)
150 {
151  if (!surface) {
152  return nullptr;
153  }
154  for (auto it = s_surfaces.constBegin(); it != s_surfaces.constEnd(); ++it) {
155  if ((*it)->parentSurface == surface) {
156  return (*it)->q;
157  }
158  }
159  return nullptr;
160 }
161 
162 void PlasmaShellSurface::Private::setup(org_kde_plasma_surface *s)
163 {
164  Q_ASSERT(s);
165  Q_ASSERT(!surface);
166  surface.setup(s);
167  org_kde_plasma_surface_add_listener(surface, &s_listener, this);
168 }
169 
170 const org_kde_plasma_surface_listener PlasmaShellSurface::Private::s_listener = {autoHidingPanelHiddenCallback, autoHidingPanelShownCallback};
171 
172 void PlasmaShellSurface::Private::autoHidingPanelHiddenCallback(void *data, org_kde_plasma_surface *org_kde_plasma_surface)
173 {
174  auto p = reinterpret_cast<PlasmaShellSurface::Private *>(data);
175  Q_ASSERT(p->surface == org_kde_plasma_surface);
176  Q_EMIT p->q->autoHidePanelHidden();
177 }
178 
179 void PlasmaShellSurface::Private::autoHidingPanelShownCallback(void *data, org_kde_plasma_surface *org_kde_plasma_surface)
180 {
181  auto p = reinterpret_cast<PlasmaShellSurface::Private *>(data);
182  Q_ASSERT(p->surface == org_kde_plasma_surface);
183  Q_EMIT p->q->autoHidePanelShown();
184 }
185 
186 PlasmaShellSurface::PlasmaShellSurface(QObject *parent)
187  : QObject(parent)
188  , d(new Private(this))
189 {
190 }
191 
192 PlasmaShellSurface::~PlasmaShellSurface()
193 {
194  release();
195 }
196 
198 {
199  d->surface.release();
200 }
201 
203 {
204  d->surface.destroy();
205 }
206 
207 void PlasmaShellSurface::setup(org_kde_plasma_surface *surface)
208 {
209  d->setup(surface);
210 }
211 
213 {
214  if (auto s = PlasmaShellSurface::Private::get(surface)) {
215  return s;
216  }
217 
218  return nullptr;
219 }
220 
222 {
223  return d->surface.isValid();
224 }
225 
226 PlasmaShellSurface::operator org_kde_plasma_surface *()
227 {
228  return d->surface;
229 }
230 
231 PlasmaShellSurface::operator org_kde_plasma_surface *() const
232 {
233  return d->surface;
234 }
235 
237 {
238  Q_ASSERT(isValid());
239  org_kde_plasma_surface_set_position(d->surface, point.x(), point.y());
240 }
241 
243 {
244  org_kde_plasma_surface_open_under_cursor(d->surface);
245 }
246 
248 {
249  Q_ASSERT(isValid());
250  uint32_t wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_NORMAL;
251  switch (role) {
252  case Role::Normal:
253  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_NORMAL;
254  break;
255  case Role::Desktop:
256  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_DESKTOP;
257  break;
258  case Role::Panel:
259  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_PANEL;
260  break;
262  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_ONSCREENDISPLAY;
263  break;
264  case Role::Notification:
265  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_NOTIFICATION;
266  break;
267  case Role::ToolTip:
268  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_TOOLTIP;
269  break;
271  if (wl_proxy_get_version(d->surface) < ORG_KDE_PLASMA_SURFACE_ROLE_CRITICALNOTIFICATION_SINCE_VERSION) {
272  // Fall back to generic notification type if not supported
273  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_NOTIFICATION;
274  } else {
275  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_CRITICALNOTIFICATION;
276  }
277  break;
278  case Role::AppletPopup:
279  // ORG_KDE_PLASMA_SURFACE_ROLE_APPLETPOPUP_SINCE_VERSION is not used for this check
280  // because it wrongly is 7 with old plasma wayland protocols
281  if (wl_proxy_get_version(d->surface) < 8) {
282  // dock is what applet popups were before
283  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_PANEL;
284  setPanelBehavior(PanelBehavior::WindowsGoBelow);
285  } else {
286  wlRole = ORG_KDE_PLASMA_SURFACE_ROLE_APPLETPOPUP;
287  }
288  break;
289  default:
290  Q_UNREACHABLE();
291  break;
292  }
293  org_kde_plasma_surface_set_role(d->surface, wlRole);
294  d->role = role;
295 }
296 
298 {
299  return d->role;
300 }
301 
303 {
304  Q_ASSERT(isValid());
305  uint32_t wlRole = ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_ALWAYS_VISIBLE;
306  switch (behavior) {
307  case PanelBehavior::AlwaysVisible:
308  wlRole = ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_ALWAYS_VISIBLE;
309  break;
310  case PanelBehavior::AutoHide:
311  wlRole = ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_AUTO_HIDE;
312  break;
313  case PanelBehavior::WindowsCanCover:
314  wlRole = ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_WINDOWS_CAN_COVER;
315  break;
316  case PanelBehavior::WindowsGoBelow:
317  wlRole = ORG_KDE_PLASMA_SURFACE_PANEL_BEHAVIOR_WINDOWS_GO_BELOW;
318  break;
319  default:
320  Q_UNREACHABLE();
321  break;
322  }
323  org_kde_plasma_surface_set_panel_behavior(d->surface, wlRole);
324 }
325 
327 {
328  org_kde_plasma_surface_set_skip_taskbar(d->surface, skip);
329 }
330 
332 {
333  org_kde_plasma_surface_set_skip_switcher(d->surface, skip);
334 }
335 
337 {
338  org_kde_plasma_surface_panel_auto_hide_hide(d->surface);
339 }
340 
342 {
343  org_kde_plasma_surface_panel_auto_hide_show(d->surface);
344 }
345 
347 {
348  org_kde_plasma_surface_set_panel_takes_focus(d->surface, takesFocus);
349 }
350 
351 }
352 }
@ ToolTip
The Surface represents a tooltip.
void setPanelTakesFocus(bool takesFocus)
Set whether a PlasmaShellSurface should get focus or not.
Q_EMITQ_EMIT
Wrapper for the wl_surface interface.
Definition: surface.h:43
Role
Describes possible roles this PlasmaShellSurface can have.
Definition: plasmashell.h:229
static Surface * get(wl_surface *native)
Definition: surface.cpp:212
Wrapper for the org_kde_plasma_surface interface.
Definition: plasmashell.h:173
PlasmaShellSurface * createSurface(wl_surface *surface, QObject *parent=nullptr)
Creates a PlasmaShellSurface for the given surface and sets it up.
Definition: plasmashell.cpp:96
int x() const const
int y() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void openUnderCursor()
Request that the initial position of this surface will be under the cursor.
void release()
Releases the org_kde_plasma_shell interface.
Definition: plasmashell.cpp:70
@ CriticalNotification
The Surface represents a critical notification, like battery is running out.
Wrapper class for wl_event_queue interface.
Definition: event_queue.h:54
void requestHideAutoHidingPanel()
Requests to hide a surface with Role Panel and PanelBahvior AutoHide.
void requestShowAutoHidingPanel()
Requests to show a surface with Role Panel and PanelBahvior AutoHide.
void setRole(Role role)
Changes the requested Role to role.
void setSkipTaskbar(bool skip)
Setting this bit to the window, will make it say it prefers to not be listed in the taskbar.
void interfaceAboutToBeDestroyed()
This signal is emitted right before the data is destroyed.
@ Panel
The Surface represents a panel (dock), normally stacked above normal surfaces.
void setEventQueue(EventQueue *queue)
Sets the queue to use for creating a Surface.
Definition: plasmashell.cpp:86
void interfaceAboutToBeReleased()
This signal is emitted right before the interface is released.
void destroy()
Destroys the data held by this PlasmaShell.
Definition: plasmashell.cpp:61
@ AppletPopup
The Surface used for applets.
void setup(org_kde_plasma_shell *shell)
Setup this Shell to manage the shell.
Definition: plasmashell.cpp:79
void setup(org_kde_plasma_surface *surface)
Setup this PlasmaShellSurface to manage the surface.
void setPanelBehavior(PanelBehavior behavior)
Sets the PanelBehavior for a PlasmaShellSurface with Role Role::Panel.
void destroy()
Destroys the data held by this PlasmaShellSurface.
@ Notification
The Surface represents a notification.
void release()
Releases the org_kde_plasma_surface interface.
static PlasmaShellSurface * get(Surface *surf)
PanelBehavior
Describes how a PlasmaShellSurface with role Role::Panel should behave.
Definition: plasmashell.h:266
void setPosition(const QPoint &point)
Requests to position this PlasmaShellSurface at point in global coordinates.
@ Desktop
The Surface represents a desktop, normally stacked below all other surfaces.
QObject * parent() const const
@ OnScreenDisplay
The Surface represents an on screen display, like a volume changed notification.
virtual QVariant get(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName)
void setSkipSwitcher(bool skip)
Setting this bit on a window will indicate it does not prefer to be included in a window switcher.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Feb 8 2023 03:59:21 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.