1 /*
2     KWin - the KDE window manager
3     This file is part of the KDE project.
4 
5     SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #ifndef KWIN_TOPLEVEL_H
11 #define KWIN_TOPLEVEL_H
12 
13 // kwin
14 #include "utils.h"
15 #include "xcbutils.h"
16 // KDE
17 #include <NETWM>
18 // Qt
19 #include <QObject>
20 #include <QMatrix4x4>
21 #include <QPointer>
22 #include <QRect>
23 #include <QUuid>
24 // c++
25 #include <functional>
26 
27 class QOpenGLFramebufferObject;
28 
29 namespace KWaylandServer
30 {
31 class SurfaceInterface;
32 }
33 
34 namespace KWin
35 {
36 
37 class AbstractOutput;
38 class ClientMachine;
39 class Deleted;
40 class EffectWindowImpl;
41 class Shadow;
42 class SurfaceItem;
43 class VirtualDesktop;
44 class WindowItem;
45 
46 /**
47  * Enum to describe the reason why a Toplevel has to be released.
48  */
49 enum class ReleaseReason {
50     Release, ///< Normal Release after e.g. an Unmap notify event (window still valid)
51     Destroyed, ///< Release after an Destroy notify event (window no longer valid)
52     KWinShutsDown ///< Release on KWin Shutdown (window still valid)
53 };
54 
55 class KWIN_EXPORT Toplevel : public QObject
56 {
57     Q_OBJECT
58 
59     Q_PROPERTY(bool alpha READ hasAlpha NOTIFY hasAlphaChanged)
60     Q_PROPERTY(qulonglong frameId READ frameId)
61 
62     /**
63      * This property holds the geometry of the Toplevel, excluding invisible
64      * portions, e.g. client-side and server-side drop-shadows, etc.
65      *
66      * @deprecated Use frameGeometry property instead.
67      */
68     Q_PROPERTY(QRect geometry READ frameGeometry NOTIFY frameGeometryChanged)
69 
70     /**
71      * This property holds rectangle that the pixmap or buffer of this Toplevel
72      * occupies on the screen. This rectangle includes invisible portions of the
73      * client, e.g. client-side drop shadows, etc.
74      */
75     Q_PROPERTY(QRect bufferGeometry READ bufferGeometry)
76 
77     /**
78      * This property holds the geometry of the Toplevel, excluding invisible
79      * portions, e.g. server-side and client-side drop-shadows, etc.
80      */
81     Q_PROPERTY(QRect frameGeometry READ frameGeometry NOTIFY frameGeometryChanged)
82 
83     /**
84      * This property holds the position of the Toplevel's frame geometry.
85      */
86     Q_PROPERTY(QPoint pos READ pos)
87 
88     /**
89      * This property holds the size of the Toplevel's frame geometry.
90      */
91     Q_PROPERTY(QSize size READ size)
92 
93     /**
94      * This property holds the x position of the Toplevel's frame geometry.
95      */
96     Q_PROPERTY(int x READ x NOTIFY frameGeometryChanged)
97 
98     /**
99      * This property holds the y position of the Toplevel's frame geometry.
100      */
101     Q_PROPERTY(int y READ y NOTIFY frameGeometryChanged)
102 
103     /**
104      * This property holds the width of the Toplevel's frame geometry.
105      */
106     Q_PROPERTY(int width READ width NOTIFY frameGeometryChanged)
107 
108     /**
109      * This property holds the height of the Toplevel's frame geometry.
110      */
111     Q_PROPERTY(int height READ height NOTIFY frameGeometryChanged)
112 
113     Q_PROPERTY(QRect visibleRect READ visibleGeometry)
114     Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
115     Q_PROPERTY(int screen READ screen NOTIFY screenChanged)
116     Q_PROPERTY(qulonglong windowId READ window CONSTANT)
117     Q_PROPERTY(int desktop READ desktop)
118 
119     /**
120      * Whether the window is on all desktops. That is desktop is -1.
121      */
122     Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops)
123 
124     Q_PROPERTY(QRect rect READ rect)
125     Q_PROPERTY(QPoint clientPos READ clientPos)
126     Q_PROPERTY(QSize clientSize READ clientSize)
127     Q_PROPERTY(QByteArray resourceName READ resourceName NOTIFY windowClassChanged)
128     Q_PROPERTY(QByteArray resourceClass READ resourceClass NOTIFY windowClassChanged)
129     Q_PROPERTY(QByteArray windowRole READ windowRole NOTIFY windowRoleChanged)
130 
131     /**
132      * Returns whether the window is a desktop background window (the one with wallpaper).
133      * See _NET_WM_WINDOW_TYPE_DESKTOP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
134      */
135     Q_PROPERTY(bool desktopWindow READ isDesktop)
136 
137     /**
138      * Returns whether the window is a dock (i.e. a panel).
139      * See _NET_WM_WINDOW_TYPE_DOCK at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
140      */
141     Q_PROPERTY(bool dock READ isDock)
142 
143     /**
144      * Returns whether the window is a standalone (detached) toolbar window.
145      * See _NET_WM_WINDOW_TYPE_TOOLBAR at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
146      */
147     Q_PROPERTY(bool toolbar READ isToolbar)
148 
149     /**
150      * Returns whether the window is a torn-off menu.
151      * See _NET_WM_WINDOW_TYPE_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
152      */
153     Q_PROPERTY(bool menu READ isMenu)
154 
155     /**
156      * Returns whether the window is a "normal" window, i.e. an application or any other window
157      * for which none of the specialized window types fit.
158      * See _NET_WM_WINDOW_TYPE_NORMAL at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
159      */
160     Q_PROPERTY(bool normalWindow READ isNormalWindow)
161 
162     /**
163      * Returns whether the window is a dialog window.
164      * See _NET_WM_WINDOW_TYPE_DIALOG at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
165      */
166     Q_PROPERTY(bool dialog READ isDialog)
167 
168     /**
169      * Returns whether the window is a splashscreen. Note that many (especially older) applications
170      * do not support marking their splash windows with this type.
171      * See _NET_WM_WINDOW_TYPE_SPLASH at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
172      */
173     Q_PROPERTY(bool splash READ isSplash)
174 
175     /**
176      * Returns whether the window is a utility window, such as a tool window.
177      * See _NET_WM_WINDOW_TYPE_UTILITY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
178      */
179     Q_PROPERTY(bool utility READ isUtility)
180 
181     /**
182      * Returns whether the window is a dropdown menu (i.e. a popup directly or indirectly open
183      * from the applications menubar).
184      * See _NET_WM_WINDOW_TYPE_DROPDOWN_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
185      */
186     Q_PROPERTY(bool dropdownMenu READ isDropdownMenu)
187 
188     /**
189      * Returns whether the window is a popup menu (that is not a torn-off or dropdown menu).
190      * See _NET_WM_WINDOW_TYPE_POPUP_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
191      */
192     Q_PROPERTY(bool popupMenu READ isPopupMenu)
193 
194     /**
195      * Returns whether the window is a tooltip.
196      * See _NET_WM_WINDOW_TYPE_TOOLTIP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
197      */
198     Q_PROPERTY(bool tooltip READ isTooltip)
199 
200     /**
201      * Returns whether the window is a window with a notification.
202      * See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
203      */
204     Q_PROPERTY(bool notification READ isNotification)
205 
206     /**
207      * Returns whether the window is a window with a critical notification.
208      */
209     Q_PROPERTY(bool criticalNotification READ isCriticalNotification)
210 
211     /**
212      * Returns whether the window is an On Screen Display.
213      */
214     Q_PROPERTY(bool onScreenDisplay READ isOnScreenDisplay)
215 
216     /**
217      * Returns whether the window is a combobox popup.
218      * See _NET_WM_WINDOW_TYPE_COMBO at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
219      */
220     Q_PROPERTY(bool comboBox READ isComboBox)
221 
222     /**
223      * Returns whether the window is a Drag&Drop icon.
224      * See _NET_WM_WINDOW_TYPE_DND at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
225      */
226     Q_PROPERTY(bool dndIcon READ isDNDIcon)
227 
228     /**
229      * Returns the NETWM window type
230      * See https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
231      */
232     Q_PROPERTY(int windowType READ windowType)
233 
234     Q_PROPERTY(QStringList activities READ activities)
235 
236     /**
237      * Whether this Toplevel is managed by KWin (it has control over its placement and other
238      * aspects, as opposed to override-redirect windows that are entirely handled by the application).
239      */
240     Q_PROPERTY(bool managed READ isClient CONSTANT)
241 
242     /**
243      * Whether this Toplevel represents an already deleted window and only kept for the compositor for animations.
244      */
245     Q_PROPERTY(bool deleted READ isDeleted CONSTANT)
246 
247     /**
248      * Whether the window has an own shape
249      */
250     Q_PROPERTY(bool shaped READ shape NOTIFY shapedChanged)
251 
252     /**
253      * Whether the window does not want to be animated on window close.
254      * There are legit reasons for this like a screenshot application which does not want it's
255      * window being captured.
256      */
257     Q_PROPERTY(bool skipsCloseAnimation READ skipsCloseAnimation WRITE setSkipCloseAnimation NOTIFY skipCloseAnimationChanged)
258 
259     /**
260      * Interface to the Wayland Surface.
261      * Relevant only in Wayland, in X11 it will be nullptr
262      */
263     Q_PROPERTY(KWaylandServer::SurfaceInterface *surface READ surface)
264 
265     /**
266      * Whether the window is a popup.
267      */
268     Q_PROPERTY(bool popupWindow READ isPopupWindow)
269 
270     /**
271      * Whether this Toplevel represents the outline.
272      *
273      * @note It's always @c false if compositing is turned off.
274      */
275     Q_PROPERTY(bool outline READ isOutline)
276 
277     /**
278      * This property holds a UUID to uniquely identify this Toplevel.
279      */
280     Q_PROPERTY(QUuid internalId READ internalId CONSTANT)
281 
282     /**
283      * The pid of the process owning this window.
284      *
285      * @since 5.20
286      */
287     Q_PROPERTY(int pid READ pid CONSTANT)
288 
289     /**
290      * The position of this window within Workspace's window stack.
291      */
292     Q_PROPERTY(int stackingOrder READ stackingOrder NOTIFY stackingOrderChanged)
293 
294 public:
295     explicit Toplevel();
296     virtual xcb_window_t frameId() const;
297     xcb_window_t window() const;
298     /**
299      * Returns the geometry of the pixmap or buffer attached to this Toplevel.
300      *
301      * For X11 clients, this method returns server-side geometry of the Toplevel.
302      *
303      * For Wayland clients, this method returns rectangle that the main surface
304      * occupies on the screen, in global screen coordinates.
305      */
306     QRect bufferGeometry() const;
307     /**
308      * Returns the geometry of the Toplevel, excluding invisible portions, e.g.
309      * server-side and client-side drop shadows, etc.
310      */
311     QRect frameGeometry() const;
312     /**
313      * Returns the geometry of the client window, in global screen coordinates.
314      */
315     QRect clientGeometry() const;
316     /**
317      * Returns the extents of the server-side decoration.
318      *
319      * Note that the returned margins object will have all margins set to 0 if
320      * the client doesn't have a server-side decoration.
321      *
322      * Default implementation returns a margins object with all margins set to 0.
323      */
324     virtual QMargins frameMargins() const;
325     /**
326      * The geometry of the Toplevel which accepts input events. This might be larger
327      * than the actual geometry, e.g. to support resizing outside the window.
328      *
329      * Default implementation returns same as geometry.
330      */
331     virtual QRect inputGeometry() const;
332     QSize size() const;
333     QPoint pos() const;
334     QRect rect() const;
335     int x() const;
336     int y() const;
337     int width() const;
338     int height() const;
339     bool isOnOutput(AbstractOutput *output) const;
340     bool isOnActiveOutput() const;
341     int screen() const; // the screen where the center is
342     AbstractOutput *output() const;
343     void setOutput(AbstractOutput *output);
344     /**
345      * The scale of the screen this window is currently on
346      * @note The buffer scale can be different.
347      * @since 5.12
348      */
349     qreal screenScale() const; //
350     /**
351      * Returns the ratio between physical pixels and device-independent pixels for
352      * the attached buffer (or pixmap).
353      *
354      * For X11 clients, this method always returns 1.
355      */
356     virtual qreal bufferScale() const;
357     virtual QPoint clientPos() const = 0; // inside of geometry()
358     QSize clientSize() const;
359     /**
360      * Returns a rectangle that the window occupies on the screen, including drop-shadows.
361      */
362     QRect visibleGeometry() const;
363     virtual bool isClient() const;
364     virtual bool isDeleted() const;
365 
366     /**
367      * Maps the specified @a point from the global screen coordinates to the frame coordinates.
368      */
369     QPoint mapToFrame(const QPoint &point) const;
370     /**
371      * Maps the specified @a point from the global screen coordinates to the surface-local
372      * coordinates of the main surface. For X11 clients, this function maps the specified point
373      * from the global screen coordinates to the buffer-local coordinates.
374      */
375     QPoint mapToLocal(const QPoint &point) const;
376     QPointF mapToLocal(const QPointF &point) const;
377     QPointF mapFromLocal(const QPointF &point) const;
378 
379     // prefer isXXX() instead
380     // 0 for supported types means default for managed/unmanaged types
381     virtual NET::WindowType windowType(bool direct = false, int supported_types = 0) const = 0;
382     bool hasNETSupport() const;
383     bool isDesktop() const;
384     bool isDock() const;
385     bool isToolbar() const;
386     bool isMenu() const;
387     bool isNormalWindow() const; // normal as in 'NET::Normal or NET::Unknown non-transient'
388     bool isDialog() const;
389     bool isSplash() const;
390     bool isUtility() const;
391     bool isDropdownMenu() const;
392     bool isPopupMenu() const; // a context popup, not dropdown, not torn-off
393     bool isTooltip() const;
394     bool isNotification() const;
395     bool isCriticalNotification() const;
396     bool isOnScreenDisplay() const;
397     bool isComboBox() const;
398     bool isDNDIcon() const;
399 
400     virtual bool isLockScreen() const;
401     virtual bool isInputMethod() const;
402     virtual bool isOutline() const;
403 
404     /**
405      * Returns the virtual desktop within the workspace() the client window
406      * is located in, 0 if it isn't located on any special desktop (not mapped yet),
407      * or NET::OnAllDesktops. Do not use desktop() directly, use
408      * isOnDesktop() instead.
409      */
410     virtual int desktop() const = 0;
411     virtual QVector<VirtualDesktop *> desktops() const = 0;
412     virtual QStringList activities() const = 0;
413     bool isOnDesktop(VirtualDesktop *desktop) const;
414     bool isOnDesktop(int d) const;
415     bool isOnActivity(const QString &activity) const;
416     bool isOnCurrentDesktop() const;
417     bool isOnCurrentActivity() const;
418     bool isOnAllDesktops() const;
419     bool isOnAllActivities() const;
420 
421     virtual QByteArray windowRole() const;
422     QByteArray sessionId() const;
423     QByteArray resourceName() const;
424     QByteArray resourceClass() const;
425     QByteArray wmCommand();
426     QByteArray wmClientMachine(bool use_localhost) const;
427     const ClientMachine *clientMachine() const;
428     virtual bool isLocalhost() const;
429     xcb_window_t wmClientLeader() const;
430     virtual pid_t pid() const;
431     static bool resourceMatch(const Toplevel* c1, const Toplevel* c2);
432 
433     bool readyForPainting() const; // true if the window has been already painted its contents
434     xcb_visualid_t visual() const;
435     bool shape() const;
436     QRegion inputShape() const;
437     void setOpacity(qreal opacity);
438     qreal opacity() const;
439     int depth() const;
440     bool hasAlpha() const;
441     virtual bool setupCompositing();
442     virtual void finishCompositing(ReleaseReason releaseReason = ReleaseReason::Release);
443     Q_INVOKABLE void addRepaint(const QRect& r);
444     Q_INVOKABLE void addRepaint(const QRegion& r);
445     Q_INVOKABLE void addRepaint(int x, int y, int w, int h);
446     Q_INVOKABLE void addLayerRepaint(const QRect& r);
447     Q_INVOKABLE void addLayerRepaint(const QRegion& r);
448     Q_INVOKABLE void addLayerRepaint(int x, int y, int w, int h);
449     Q_INVOKABLE virtual void addRepaintFull();
450     // these call workspace->addRepaint(), but first transform the damage if needed
451     void addWorkspaceRepaint(const QRect& r);
452     void addWorkspaceRepaint(int x, int y, int w, int h);
453     void addWorkspaceRepaint(const QRegion &region);
454     EffectWindowImpl* effectWindow();
455     const EffectWindowImpl* effectWindow() const;
456     SurfaceItem *surfaceItem() const;
457     WindowItem *windowItem() const;
458     /**
459      * Window will be temporarily painted as if being at the top of the stack.
460      * Only available if Compositor is active, if not active, this method is a no-op.
461      */
462     void elevate(bool elevate);
463 
464     /**
465      * Returns the Shadow associated with this Toplevel or @c null if it has no shadow.
466      */
467     Shadow *shadow() const;
468     /**
469      * Updates the Shadow associated with this Toplevel from X11 Property.
470      * Call this method when the Property changes or Compositing is started.
471      */
472     void updateShadow();
473     /**
474      * Whether the Toplevel currently wants the shadow to be rendered. Default
475      * implementation always returns @c true.
476      */
477     virtual bool wantsShadowToBeRendered() const;
478 
479     /**
480      * This method returns the area that the Toplevel window reports to be opaque.
481      * It is supposed to only provide valuable information if hasAlpha is @c true .
482      * @see hasAlpha
483      */
484     const QRegion& opaqueRegion() const;
485     QRegion shapeRegion() const;
486 
487     virtual Layer layer() const = 0;
488 
489     bool skipsCloseAnimation() const;
490     void setSkipCloseAnimation(bool set);
491 
492     quint32 pendingSurfaceId() const;
493     KWaylandServer::SurfaceInterface *surface() const;
494     void setSurface(KWaylandServer::SurfaceInterface *surface);
495 
496     const QSharedPointer<QOpenGLFramebufferObject> &internalFramebufferObject() const;
497     QImage internalImageObject() const;
498 
499     /**
500      * @returns Transformation to map from global to window coordinates.
501      *
502      * Default implementation returns a translation on negative pos().
503      * @see pos
504      */
505     virtual QMatrix4x4 inputTransformation() const;
506 
507     /**
508      * Returns @c true if the toplevel can accept input at the specified position @a point.
509      */
510     virtual bool hitTest(const QPoint &point) const;
511 
512     /**
513      * The window has a popup grab. This means that when it got mapped the
514      * parent window had an implicit (pointer) grab.
515      *
516      * Normally this is only relevant for transient windows.
517      *
518      * Once the popup grab ends (e.g. pointer press outside of any Toplevel of
519      * the client), the method popupDone should be invoked.
520      *
521      * The default implementation returns @c false.
522      * @see popupDone
523      * @since 5.10
524      */
hasPopupGrab()525     virtual bool hasPopupGrab() const {
526         return false;
527     }
528     /**
529      * This method should be invoked for Toplevels with a popup grab when
530      * the grab ends.
531      *
532      * The default implementation does nothing.
533      * @see hasPopupGrab
534      * @since 5.10
535      */
popupDone()536     virtual void popupDone() {};
537 
538     /**
539      * @brief Finds the Toplevel matching the condition expressed in @p func in @p list.
540      *
541      * The method is templated to operate on either a list of Toplevels or on a list of
542      * a subclass type of Toplevel.
543      * @param list The list to search in
544      * @param func The condition function (compare std::find_if)
545      * @return T* The found Toplevel or @c null if there is no matching Toplevel
546      */
547     template <class T, class U>
548     static T *findInList(const QList<T*> &list, std::function<bool (const U*)> func);
549 
550     /**
551      * Whether the window is a popup.
552      *
553      * Popups can be used to implement popup menus, tooltips, combo boxes, etc.
554      *
555      * @since 5.15
556      */
557     virtual bool isPopupWindow() const;
558 
559     /**
560      * A UUID to uniquely identify this Toplevel independent of windowing system.
561      */
internalId()562     QUuid internalId() const
563     {
564         return m_internalId;
565     }
566 
567     /**
568      * Returns @c true if the window is shaded; otherwise returns @c false.
569      */
isShade()570     virtual bool isShade() const { return false; }
571 
572     int stackingOrder() const;
573     void setStackingOrder(int order); ///< @internal
574 
575 Q_SIGNALS:
576     void stackingOrderChanged();
577     void shadeChanged();
578     void opacityChanged(KWin::Toplevel* toplevel, qreal oldOpacity);
579     void damaged(KWin::Toplevel* toplevel, const QRegion& damage);
580     void inputTransformationChanged();
581     /**
582      * This signal is emitted when the Toplevel's frame geometry changes.
583      * @deprecated since 5.19, use frameGeometryChanged instead
584      */
585     void geometryChanged();
586     void geometryShapeChanged(KWin::Toplevel* toplevel, const QRect& old);
587     void windowClosed(KWin::Toplevel* toplevel, KWin::Deleted* deleted);
588     void windowShown(KWin::Toplevel* toplevel);
589     void windowHidden(KWin::Toplevel* toplevel);
590     /**
591      * Signal emitted when the window's shape state changed. That is if it did not have a shape
592      * and received one or if the shape was withdrawn. Think of Chromium enabling/disabling KWin's
593      * decoration.
594      */
595     void shapedChanged();
596     /**
597      * Emitted whenever the Toplevel's screen changes. This can happen either in consequence to
598      * a screen being removed/added or if the Toplevel's geometry changes.
599      * @since 4.11
600      */
601     void screenChanged();
602     void skipCloseAnimationChanged();
603     /**
604      * Emitted whenever the window role of the window changes.
605      * @since 5.0
606      */
607     void windowRoleChanged();
608     /**
609      * Emitted whenever the window class name or resource name of the window changes.
610      * @since 5.0
611      */
612     void windowClassChanged();
613     /**
614      * @since 5.4
615      */
616     void hasAlphaChanged();
617 
618     /**
619      * Emitted whenever the Surface for this Toplevel changes.
620      */
621     void surfaceChanged();
622 
623     /*
624      * Emitted when the client's screen changes onto a screen of a different scale
625      * or the screen we're on changes
626      * @since 5.12
627      */
628     void screenScaleChanged();
629 
630     /**
631      * Emitted whenever the client's shadow changes.
632      * @since 5.15
633      */
634     void shadowChanged();
635 
636     /**
637      * This signal is emitted when the Toplevel's buffer geometry changes.
638      */
639     void bufferGeometryChanged(KWin::Toplevel *toplevel, const QRect &oldGeometry);
640     /**
641      * This signal is emitted when the Toplevel's frame geometry changes.
642      */
643     void frameGeometryChanged(KWin::Toplevel *toplevel, const QRect &oldGeometry);
644     /**
645      * This signal is emitted when the Toplevel's client geometry has changed.
646      */
647     void clientGeometryChanged(KWin::Toplevel *toplevel, const QRect &oldGeometry);
648 
649     /**
650      * This signal is emitted when the visible geometry has changed.
651      */
652     void visibleGeometryChanged();
653 
654 protected Q_SLOTS:
655     /**
656      * Checks whether the screen number for this Toplevel changed and updates if needed.
657      * Any method changing the geometry of the Toplevel should call this method.
658      */
659     void checkOutput();
660     void setupCheckOutputConnection();
661     void removeCheckOutputConnection();
662     void setReadyForPainting();
663 
664 protected:
665     ~Toplevel() override;
666     void setWindowHandles(xcb_window_t client);
667     void detectShape(xcb_window_t id);
668     virtual void propertyNotifyEvent(xcb_property_notify_event_t *e);
669     virtual void clientMessageEvent(xcb_client_message_event_t *e);
670     Xcb::Property fetchWmClientLeader() const;
671     void readWmClientLeader(Xcb::Property &p);
672     void getWmClientLeader();
673     void getWmClientMachine();
674 
675     /**
676      * This function fetches the opaque region from this Toplevel.
677      * Will only be called on corresponding property changes and for initialization.
678      */
679     void getWmOpaqueRegion();
680     void discardShapeRegion();
681 
682     void getResourceClass();
683     void setResourceClass(const QByteArray &name, const QByteArray &className = QByteArray());
684     Xcb::Property fetchSkipCloseAnimation() const;
685     void readSkipCloseAnimation(Xcb::Property &prop);
686     void getSkipCloseAnimation();
687     void copyToDeleted(Toplevel* c);
688     void disownDataPassedToDeleted();
689     void deleteShadow();
690     void deleteEffectWindow();
691     void setDepth(int depth);
692     QRect m_frameGeometry;
693     QRect m_clientGeometry;
694     QRect m_bufferGeometry;
695     xcb_visualid_t m_visual;
696     int bit_depth;
697     NETWinInfo* info;
698     bool ready_for_painting;
699     /**
700      * An FBO object KWin internal windows might render to.
701      */
702     QSharedPointer<QOpenGLFramebufferObject> m_internalFBO;
703     QImage m_internalImage;
704 
705 private:
706     // when adding new data members, check also copyToDeleted()
707     QUuid m_internalId;
708     Xcb::Window m_client;
709     bool is_shape;
710     EffectWindowImpl* effect_window;
711     Shadow *m_shadow = nullptr;
712     QByteArray resource_name;
713     QByteArray resource_class;
714     ClientMachine *m_clientMachine;
715     xcb_window_t m_wmClientLeader;
716     QRegion opaque_region;
717     mutable QRegion m_shapeRegion;
718     mutable bool m_shapeRegionIsValid = false;
719     AbstractOutput *m_output = nullptr;
720     bool m_skipCloseAnimation;
721     quint32 m_pendingSurfaceId = 0;
722     QPointer<KWaylandServer::SurfaceInterface> m_surface;
723     // when adding new data members, check also copyToDeleted()
724     qreal m_screenScale = 1.0;
725     qreal m_opacity = 1.0;
726     int m_stackingOrder = 0;
727 };
728 
window()729 inline xcb_window_t Toplevel::window() const
730 {
731     return m_client;
732 }
733 
setWindowHandles(xcb_window_t w)734 inline void Toplevel::setWindowHandles(xcb_window_t w)
735 {
736     Q_ASSERT(!m_client.isValid() && w != XCB_WINDOW_NONE);
737     m_client.reset(w, false);
738 }
739 
bufferGeometry()740 inline QRect Toplevel::bufferGeometry() const
741 {
742     return m_bufferGeometry;
743 }
744 
clientGeometry()745 inline QRect Toplevel::clientGeometry() const
746 {
747     return m_clientGeometry;
748 }
749 
clientSize()750 inline QSize Toplevel::clientSize() const
751 {
752     return m_clientGeometry.size();
753 }
754 
frameGeometry()755 inline QRect Toplevel::frameGeometry() const
756 {
757     return m_frameGeometry;
758 }
759 
size()760 inline QSize Toplevel::size() const
761 {
762     return m_frameGeometry.size();
763 }
764 
pos()765 inline QPoint Toplevel::pos() const
766 {
767     return m_frameGeometry.topLeft();
768 }
769 
x()770 inline int Toplevel::x() const
771 {
772     return m_frameGeometry.x();
773 }
774 
y()775 inline int Toplevel::y() const
776 {
777     return m_frameGeometry.y();
778 }
779 
width()780 inline int Toplevel::width() const
781 {
782     return m_frameGeometry.width();
783 }
784 
height()785 inline int Toplevel::height() const
786 {
787     return m_frameGeometry.height();
788 }
789 
rect()790 inline QRect Toplevel::rect() const
791 {
792     return QRect(0, 0, width(), height());
793 }
794 
readyForPainting()795 inline bool Toplevel::readyForPainting() const
796 {
797     return ready_for_painting;
798 }
799 
visual()800 inline xcb_visualid_t Toplevel::visual() const
801 {
802     return m_visual;
803 }
804 
isDesktop()805 inline bool Toplevel::isDesktop() const
806 {
807     return windowType() == NET::Desktop;
808 }
809 
isDock()810 inline bool Toplevel::isDock() const
811 {
812     return windowType() == NET::Dock;
813 }
814 
isMenu()815 inline bool Toplevel::isMenu() const
816 {
817     return windowType() == NET::Menu;
818 }
819 
isToolbar()820 inline bool Toplevel::isToolbar() const
821 {
822     return windowType() == NET::Toolbar;
823 }
824 
isSplash()825 inline bool Toplevel::isSplash() const
826 {
827     return windowType() == NET::Splash;
828 }
829 
isUtility()830 inline bool Toplevel::isUtility() const
831 {
832     return windowType() == NET::Utility;
833 }
834 
isDialog()835 inline bool Toplevel::isDialog() const
836 {
837     return windowType() == NET::Dialog;
838 }
839 
isNormalWindow()840 inline bool Toplevel::isNormalWindow() const
841 {
842     return windowType() == NET::Normal;
843 }
844 
isDropdownMenu()845 inline bool Toplevel::isDropdownMenu() const
846 {
847     return windowType() == NET::DropdownMenu;
848 }
849 
isPopupMenu()850 inline bool Toplevel::isPopupMenu() const
851 {
852     return windowType() == NET::PopupMenu;
853 }
854 
isTooltip()855 inline bool Toplevel::isTooltip() const
856 {
857     return windowType() == NET::Tooltip;
858 }
859 
isNotification()860 inline bool Toplevel::isNotification() const
861 {
862     return windowType() == NET::Notification;
863 }
864 
isCriticalNotification()865 inline bool Toplevel::isCriticalNotification() const
866 {
867     return windowType() == NET::CriticalNotification;
868 }
869 
isOnScreenDisplay()870 inline bool Toplevel::isOnScreenDisplay() const
871 {
872     return windowType() == NET::OnScreenDisplay;
873 }
874 
isComboBox()875 inline bool Toplevel::isComboBox() const
876 {
877     return windowType() == NET::ComboBox;
878 }
879 
isDNDIcon()880 inline bool Toplevel::isDNDIcon() const
881 {
882     return windowType() == NET::DNDIcon;
883 }
884 
isLockScreen()885 inline bool Toplevel::isLockScreen() const
886 {
887     return false;
888 }
889 
isInputMethod()890 inline bool Toplevel::isInputMethod() const
891 {
892     return false;
893 }
894 
isOutline()895 inline bool Toplevel::isOutline() const
896 {
897     return false;
898 }
899 
shape()900 inline bool Toplevel::shape() const
901 {
902     return is_shape;
903 }
904 
depth()905 inline int Toplevel::depth() const
906 {
907     return bit_depth;
908 }
909 
hasAlpha()910 inline bool Toplevel::hasAlpha() const
911 {
912     return depth() == 32;
913 }
914 
opaqueRegion()915 inline const QRegion& Toplevel::opaqueRegion() const
916 {
917     return opaque_region;
918 }
919 
920 inline
effectWindow()921 EffectWindowImpl* Toplevel::effectWindow()
922 {
923     return effect_window;
924 }
925 
926 inline
effectWindow()927 const EffectWindowImpl* Toplevel::effectWindow() const
928 {
929     return effect_window;
930 }
931 
isOnAllDesktops()932 inline bool Toplevel::isOnAllDesktops() const
933 {
934     return desktops().isEmpty();
935 }
936 
isOnAllActivities()937 inline bool Toplevel::isOnAllActivities() const
938 {
939     return activities().isEmpty();
940 }
941 
isOnActivity(const QString & activity)942 inline bool Toplevel::isOnActivity(const QString &activity) const
943 {
944     return activities().isEmpty() || activities().contains(activity);
945 }
946 
resourceName()947 inline QByteArray Toplevel::resourceName() const
948 {
949     return resource_name; // it is always lowercase
950 }
951 
resourceClass()952 inline QByteArray Toplevel::resourceClass() const
953 {
954     return resource_class; // it is always lowercase
955 }
956 
clientMachine()957 inline const ClientMachine *Toplevel::clientMachine() const
958 {
959     return m_clientMachine;
960 }
961 
pendingSurfaceId()962 inline quint32 Toplevel::pendingSurfaceId() const
963 {
964     return m_pendingSurfaceId;
965 }
966 
internalFramebufferObject()967 inline const QSharedPointer<QOpenGLFramebufferObject> &Toplevel::internalFramebufferObject() const
968 {
969     return m_internalFBO;
970 }
971 
internalImageObject()972 inline QImage Toplevel::internalImageObject() const
973 {
974     return m_internalImage;
975 }
976 
977 template <class T, class U>
findInList(const QList<T * > & list,std::function<bool (const U *)> func)978 inline T *Toplevel::findInList(const QList<T*> &list, std::function<bool (const U*)> func)
979 {
980     static_assert(std::is_base_of<U, T>::value,
981                  "U must be derived from T");
982     const auto it = std::find_if(list.begin(), list.end(), func);
983     if (it == list.end()) {
984         return nullptr;
985     }
986     return *it;
987 }
988 
isPopupWindow()989 inline bool Toplevel::isPopupWindow() const
990 {
991     switch (windowType()) {
992     case NET::ComboBox:
993     case NET::DropdownMenu:
994     case NET::PopupMenu:
995     case NET::Tooltip:
996         return true;
997 
998     default:
999         return false;
1000     }
1001 }
1002 
1003 KWIN_EXPORT QDebug operator<<(QDebug debug, const Toplevel *toplevel);
1004 
1005 } // namespace
1006 Q_DECLARE_METATYPE(KWin::Toplevel*)
1007 
1008 #endif
1009