1 /*
2     KWin - the KDE window manager
3     This file is part of the KDE project.
4 
5     SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
6     SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
7 
8     SPDX-License-Identifier: GPL-2.0-or-later
9 */
10 #ifndef KWIN_ABSTRACT_CLIENT_H
11 #define KWIN_ABSTRACT_CLIENT_H
12 
13 #include "toplevel.h"
14 #include "options.h"
15 #include "rules.h"
16 #include "cursor.h"
17 
18 #include <memory>
19 
20 #include <QElapsedTimer>
21 #include <QIcon>
22 #include <QKeySequence>
23 #include <QPointer>
24 
25 class QMouseEvent;
26 
27 namespace KWaylandServer
28 {
29 class PlasmaWindowInterface;
30 }
31 
32 namespace KDecoration2
33 {
34 class Decoration;
35 }
36 
37 namespace KWin
38 {
39 class Group;
40 
41 namespace TabBox
42 {
43 class TabBoxClientImpl;
44 }
45 
46 namespace Decoration
47 {
48 class DecoratedClientImpl;
49 class DecorationPalette;
50 }
51 
52 class KWIN_EXPORT AbstractClient : public Toplevel
53 {
54     Q_OBJECT
55 
56     /**
57      * Whether this Client is fullScreen. A Client might either be fullScreen due to the _NET_WM property
58      * or through a legacy support hack. The fullScreen state can only be changed if the Client does not
59      * use the legacy hack. To be sure whether the state changed, connect to the notify signal.
60      */
61     Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged)
62 
63     /**
64      * Whether the Client can be set to fullScreen. The property is evaluated each time it is invoked.
65      * Because of that there is no notify signal.
66      */
67     Q_PROPERTY(bool fullScreenable READ isFullScreenable)
68 
69     /**
70      * Whether this Client is active or not. Use Workspace::activateClient() to activate a Client.
71      * @see Workspace::activateClient
72      */
73     Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
74 
75     /**
76      * The desktop this Client is on. If the Client is on all desktops the property has value -1.
77      * This is a legacy property, use x11DesktopIds instead
78      *
79      * @deprecated Use the desktops property instead.
80      */
81     Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged)
82 
83     /**
84      * The virtual desktops this client is on. If it's on all desktops, the list is empty.
85      */
86     Q_PROPERTY(QVector<KWin::VirtualDesktop *> desktops READ desktops WRITE setDesktops NOTIFY desktopChanged)
87 
88     /**
89      * Whether the Client is on all desktops. That is desktop is -1.
90      */
91     Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops WRITE setOnAllDesktops NOTIFY desktopChanged)
92 
93     /**
94      * The activities this client is on. If it's on all activities the property is empty.
95      */
96     Q_PROPERTY(QStringList activities READ activities WRITE setOnActivities NOTIFY activitiesChanged)
97 
98     /**
99      * The x11 ids for all desktops this client is in. On X11 this list will always have a length of 1
100      *
101      * @deprecated prefer using apis that use VirtualDesktop objects
102      */
103     Q_PROPERTY(QVector<uint> x11DesktopIds READ x11DesktopIds NOTIFY x11DesktopIdsChanged)
104 
105     /**
106      * Indicates that the window should not be included on a taskbar.
107      */
108     Q_PROPERTY(bool skipTaskbar READ skipTaskbar WRITE setSkipTaskbar NOTIFY skipTaskbarChanged)
109 
110     /**
111      * Indicates that the window should not be included on a Pager.
112      */
113     Q_PROPERTY(bool skipPager READ skipPager WRITE setSkipPager NOTIFY skipPagerChanged)
114 
115     /**
116      * Whether the Client should be excluded from window switching effects.
117      */
118     Q_PROPERTY(bool skipSwitcher READ skipSwitcher WRITE setSkipSwitcher NOTIFY skipSwitcherChanged)
119 
120     /**
121      * Whether the window can be closed by the user.
122      */
123     Q_PROPERTY(bool closeable READ isCloseable NOTIFY closeableChanged)
124 
125     Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged)
126 
127     /**
128      * Whether the Client is set to be kept above other windows.
129      */
130     Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChanged)
131 
132     /**
133      * Whether the Client is set to be kept below other windows.
134      */
135     Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChanged)
136 
137     /**
138      * Whether the Client can be shaded. The property is evaluated each time it is invoked.
139      * Because of that there is no notify signal.
140      */
141     Q_PROPERTY(bool shadeable READ isShadeable)
142 
143     /**
144      * Whether the Client is shaded.
145      */
146     Q_PROPERTY(bool shade READ isShade WRITE setShade NOTIFY shadeChanged)
147 
148     /**
149      * Whether the Client can be minimized. The property is evaluated each time it is invoked.
150      * Because of that there is no notify signal.
151      */
152     Q_PROPERTY(bool minimizable READ isMinimizable)
153 
154     /**
155      * Whether the Client is minimized.
156      */
157     Q_PROPERTY(bool minimized READ isMinimized WRITE setMinimized NOTIFY minimizedChanged)
158 
159     /**
160      * The optional geometry representing the minimized Client in e.g a taskbar.
161      * See _NET_WM_ICON_GEOMETRY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
162      * The value is evaluated each time the getter is called.
163      * Because of that no changed signal is provided.
164      */
165     Q_PROPERTY(QRect iconGeometry READ iconGeometry)
166 
167     /**
168      * Returns whether the window is any of special windows types (desktop, dock, splash, ...),
169      * i.e. window types that usually don't have a window frame and the user does not use window
170      * management (moving, raising,...) on them.
171      * The value is evaluated each time the getter is called.
172      * Because of that no changed signal is provided.
173      */
174     Q_PROPERTY(bool specialWindow READ isSpecialWindow)
175 
176     /**
177      * Whether window state _NET_WM_STATE_DEMANDS_ATTENTION is set. This state indicates that some
178      * action in or with the window happened. For example, it may be set by the Window Manager if
179      * the window requested activation but the Window Manager refused it, or the application may set
180      * it if it finished some work. This state may be set by both the Client and the Window Manager.
181      * It should be unset by the Window Manager when it decides the window got the required attention
182      * (usually, that it got activated).
183      */
184     Q_PROPERTY(bool demandsAttention READ isDemandingAttention WRITE demandAttention NOTIFY demandsAttentionChanged)
185 
186     /**
187      * The Caption of the Client. Read from WM_NAME property together with a suffix for hostname and shortcut.
188      * To read only the caption as provided by WM_NAME, use the getter with an additional @c false value.
189      */
190     Q_PROPERTY(QString caption READ caption NOTIFY captionChanged)
191 
192     /**
193      * Minimum size as specified in WM_NORMAL_HINTS
194      */
195     Q_PROPERTY(QSize minSize READ minSize)
196 
197     /**
198      * Maximum size as specified in WM_NORMAL_HINTS
199      */
200     Q_PROPERTY(QSize maxSize READ maxSize)
201 
202     /**
203      * Whether the Client can accept keyboard focus.
204      * The value is evaluated each time the getter is called.
205      * Because of that no changed signal is provided.
206      */
207     Q_PROPERTY(bool wantsInput READ wantsInput)
208 
209     /**
210      * Whether the Client is a transient Window to another Window.
211      * @see transientFor
212      */
213     Q_PROPERTY(bool transient READ isTransient NOTIFY transientChanged)
214 
215     /**
216      * The Client to which this Client is a transient if any.
217      */
218     Q_PROPERTY(KWin::AbstractClient *transientFor READ transientFor NOTIFY transientChanged)
219 
220     /**
221      * Whether the Client represents a modal window.
222      */
223     Q_PROPERTY(bool modal READ isModal NOTIFY modalChanged)
224 
225     /**
226      * The geometry of this Client. Be aware that depending on resize mode the frameGeometryChanged
227      * signal might be emitted at each resize step or only at the end of the resize operation.
228      *
229      * @deprecated Use frameGeometry
230      */
231     Q_PROPERTY(QRect geometry READ frameGeometry WRITE moveResize)
232 
233     /**
234      * The geometry of this Client. Be aware that depending on resize mode the frameGeometryChanged
235      * signal might be emitted at each resize step or only at the end of the resize operation.
236      */
237     Q_PROPERTY(QRect frameGeometry READ frameGeometry WRITE moveResize)
238 
239     /**
240      * Whether the Client is currently being moved by the user.
241      * Notify signal is emitted when the Client starts or ends move/resize mode.
242      */
243     Q_PROPERTY(bool move READ isInteractiveMove NOTIFY moveResizedChanged)
244 
245     /**
246      * Whether the Client is currently being resized by the user.
247      * Notify signal is emitted when the Client starts or ends move/resize mode.
248      */
249     Q_PROPERTY(bool resize READ isInteractiveResize NOTIFY moveResizedChanged)
250 
251     /**
252      * Whether the decoration is currently using an alpha channel.
253      */
254     Q_PROPERTY(bool decorationHasAlpha READ decorationHasAlpha)
255 
256     /**
257      * Whether the window has a decoration or not.
258      * This property is not allowed to be set by applications themselves.
259      * The decision whether a window has a border or not belongs to the window manager.
260      * If this property gets abused by application developers, it will be removed again.
261      */
262     Q_PROPERTY(bool noBorder READ noBorder WRITE setNoBorder)
263 
264     /**
265      * Whether the Client provides context help. Mostly needed by decorations to decide whether to
266      * show the help button or not.
267      */
268     Q_PROPERTY(bool providesContextHelp READ providesContextHelp CONSTANT)
269 
270     /**
271      * Whether the Client can be maximized both horizontally and vertically.
272      * The property is evaluated each time it is invoked.
273      * Because of that there is no notify signal.
274      */
275     Q_PROPERTY(bool maximizable READ isMaximizable)
276 
277     /**
278      * Whether the Client is moveable. Even if it is not moveable, it might be possible to move
279      * it to another screen. The property is evaluated each time it is invoked.
280      * Because of that there is no notify signal.
281      * @see moveableAcrossScreens
282      */
283     Q_PROPERTY(bool moveable READ isMovable)
284 
285     /**
286      * Whether the Client can be moved to another screen. The property is evaluated each time it is invoked.
287      * Because of that there is no notify signal.
288      * @see moveable
289      */
290     Q_PROPERTY(bool moveableAcrossScreens READ isMovableAcrossScreens)
291 
292     /**
293      * Whether the Client can be resized. The property is evaluated each time it is invoked.
294      * Because of that there is no notify signal.
295      */
296     Q_PROPERTY(bool resizeable READ isResizable)
297 
298     /**
299      * The desktop file name of the application this AbstractClient belongs to.
300      *
301      * This is either the base name without full path and without file extension of the
302      * desktop file for the window's application (e.g. "org.kde.foo").
303      *
304      * The application's desktop file name can also be the full path to the desktop file
305      * (e.g. "/opt/kde/share/org.kde.foo.desktop") in case it's not in a standard location.
306      */
307     Q_PROPERTY(QByteArray desktopFileName READ desktopFileName NOTIFY desktopFileNameChanged)
308 
309     /**
310      * Whether an application menu is available for this Client
311      */
312     Q_PROPERTY(bool hasApplicationMenu READ hasApplicationMenu NOTIFY hasApplicationMenuChanged)
313 
314     /**
315      * Whether the application menu for this Client is currently opened
316      */
317     Q_PROPERTY(bool applicationMenuActive READ applicationMenuActive NOTIFY applicationMenuActiveChanged)
318 
319     /**
320      * Whether this client is unresponsive.
321      *
322      * When an application failed to react on a ping request in time, it is
323      * considered unresponsive. This usually indicates that the application froze or crashed.
324      */
325     Q_PROPERTY(bool unresponsive READ unresponsive NOTIFY unresponsiveChanged)
326 
327     /**
328      * The color scheme set on this client
329      * Absolute file path, or name of palette in the user's config directory following KColorSchemes format.
330      * An empty string indicates the default palette from kdeglobals is used.
331      * @note this indicates the colour scheme requested, which might differ from the theme applied if the colorScheme cannot be found
332      */
333     Q_PROPERTY(QString colorScheme READ colorScheme NOTIFY colorSchemeChanged)
334 
335     Q_PROPERTY(KWin::Layer layer READ layer)
336 
337 public:
338     ~AbstractClient() override;
339 
tabBoxClient()340     QWeakPointer<TabBox::TabBoxClientImpl> tabBoxClient() const {
341         return m_tabBoxClient.toWeakRef();
342     }
isFirstInTabBox()343     bool isFirstInTabBox() const {
344         return m_firstInTabBox;
345     }
skipSwitcher()346     bool skipSwitcher() const {
347         return m_skipSwitcher;
348     }
349     void setSkipSwitcher(bool set);
350 
skipTaskbar()351     bool skipTaskbar() const {
352         return m_skipTaskbar;
353     }
354     void setSkipTaskbar(bool set);
355     void setOriginalSkipTaskbar(bool set);
originalSkipTaskbar()356     bool originalSkipTaskbar() const {
357         return m_originalSkipTaskbar;
358     }
359 
skipPager()360     bool skipPager() const {
361         return m_skipPager;
362     }
363     void setSkipPager(bool set);
364 
icon()365     const QIcon &icon() const {
366         return m_icon;
367     }
368 
369     bool isZombie() const;
isActive()370     bool isActive() const {
371         return m_active;
372     }
373     /**
374      * Sets the client's active state to \a act.
375      *
376      * This function does only change the visual appearance of the client,
377      * it does not change the focus setting. Use
378      * Workspace::activateClient() or Workspace::requestFocus() instead.
379      *
380      * If a client receives or looses the focus, it calls setActive() on
381      * its own.
382      */
383     void setActive(bool);
384 
keepAbove()385     bool keepAbove() const {
386         return m_keepAbove;
387     }
388     void setKeepAbove(bool);
keepBelow()389     bool keepBelow() const {
390         return m_keepBelow;
391     }
392     void setKeepBelow(bool);
393 
394     void demandAttention(bool set = true);
isDemandingAttention()395     bool isDemandingAttention() const {
396         return m_demandsAttention;
397     }
398 
399     void cancelAutoRaise();
400 
401     bool wantsTabFocus() const;
402 
403     QMargins frameMargins() const override;
clientPos()404     QPoint clientPos() const override {
405         return QPoint(borderLeft(), borderTop());
406     }
407 
408     virtual void updateMouseGrab();
409     /**
410      * @returns The caption consisting of captionNormal and captionSuffix
411      * @see captionNormal
412      * @see captionSuffix
413      */
414     QString caption() const;
415     /**
416      * @returns The caption as set by the AbstractClient without any suffix.
417      * @see caption
418      * @see captionSuffix
419      */
420     virtual QString captionNormal() const = 0;
421     /**
422      * @returns The suffix added to the caption (e.g. shortcut, machine name, etc.)
423      * @see caption
424      * @see captionNormal
425      */
426     virtual QString captionSuffix() const = 0;
427     virtual bool isPlaceable() const;
428     virtual bool isCloseable() const = 0;
429     // TODO: remove boolean trap
430     virtual bool isShown(bool shaded_is_shown) const = 0;
431     virtual bool isHiddenInternal() const = 0;
432     // TODO: remove boolean trap
433     virtual void hideClient(bool hide) = 0;
434     virtual bool isFullScreenable() const;
435     virtual bool isFullScreen() const;
436     virtual bool isRequestedFullScreen() const;
437     // TODO: remove boolean trap
438     virtual AbstractClient *findModal(bool allow_itself = false) = 0;
439     virtual bool isTransient() const;
440     /**
441      * @returns Whether there is a hint available to place the AbstractClient on it's parent, default @c false.
442      * @see transientPlacementHint
443      */
444     virtual bool hasTransientPlacementHint() const;
445     /**
446      * Only valid id hasTransientPlacementHint is true
447      * @returns The position the transient wishes to position itself
448      */
449     virtual QRect transientPlacement(const QRect &bounds) const;
450     const AbstractClient* transientFor() const;
451     AbstractClient* transientFor();
452     /**
453      * @returns @c true if c is the transient_for window for this client,
454      *  or recursively the transient_for window
455      * @todo: remove boolean trap
456      */
457     virtual bool hasTransient(const AbstractClient* c, bool indirect) const;
458     const QList<AbstractClient*>& transients() const; // Is not indirect
459     virtual void addTransient(AbstractClient *client);
460     virtual void removeTransient(AbstractClient* cl);
461     virtual QList<AbstractClient*> mainClients() const; // Call once before loop , is not indirect
462     QList<AbstractClient*> allMainClients() const; // Call once before loop , is indirect
463     /**
464      * Returns true for "special" windows and false for windows which are "normal"
465      * (normal=window which has a border, can be moved by the user, can be closed, etc.)
466      * true for Desktop, Dock, Splash, Override and TopMenu (and Toolbar??? - for now)
467      * false for Normal, Dialog, Utility and Menu (and Toolbar??? - not yet) TODO
468      */
469     bool isSpecialWindow() const;
470     void sendToOutput(AbstractOutput *output);
471     void updateGeometryRestoresForFullscreen(AbstractOutput *output);
shortcut()472     const QKeySequence &shortcut() const {
473         return _shortcut;
474     }
475     void setShortcut(const QString &cut);
476     bool performMouseCommand(Options::MouseCommand, const QPoint &globalPos);
477     void setOnAllDesktops(bool set);
478     void setDesktop(int);
479     void enterDesktop(VirtualDesktop *desktop);
480     void leaveDesktop(VirtualDesktop *desktop);
481 
482     /**
483      * Set the window as being on the attached list of desktops
484      * On X11 it will be set to the last entry
485      */
486     void setDesktops(QVector<VirtualDesktop *> desktops);
487 
488     int desktop() const override;
desktops()489     QVector<VirtualDesktop *> desktops() const override {
490         return m_desktops;
491     }
492     QVector<uint> x11DesktopIds() const;
493     QStringList desktopIds() const;
494 
495     void setMinimized(bool set);
496     /**
497      * Minimizes this client plus its transients
498      */
499     void minimize(bool avoid_animation = false);
500     void unminimize(bool avoid_animation = false);
isMinimized()501     bool isMinimized() const {
502         return m_minimized;
503     }
504     virtual void setFullScreen(bool set, bool user = true);
505 
506     virtual void setClientShown(bool shown);
507 
508     QRect geometryRestore() const;
509     virtual MaximizeMode maximizeMode() const;
510     virtual MaximizeMode requestedMaximizeMode() const;
511     void maximize(MaximizeMode);
512     /**
513      * Sets the maximization according to @p vertically and @p horizontally.
514      */
515     Q_INVOKABLE void setMaximize(bool vertically, bool horizontally);
516     virtual bool noBorder() const;
517     virtual void setNoBorder(bool set);
518     QPalette palette() const;
519     const Decoration::DecorationPalette *decorationPalette() const;
520     /**
521      * Returns whether the window is resizable or has a fixed size.
522      */
523     virtual bool isResizable() const = 0;
524     /**
525      * Returns whether the window is moveable or has a fixed position.
526      */
527     virtual bool isMovable() const = 0;
528     /**
529      * Returns whether the window can be moved to another screen.
530      */
531     virtual bool isMovableAcrossScreens() const = 0;
532     /**
533      * @c true only for @c ShadeNormal
534      */
isShade()535     bool isShade() const override {
536         return shadeMode() == ShadeNormal;
537     }
538     ShadeMode shadeMode() const; // Prefer isShade()
539     void setShade(bool set);
540     void setShade(ShadeMode mode);
541     void toggleShade();
542     void cancelShadeHoverTimer();
543     /**
544      * Whether the Client can be shaded. Default implementation returns @c false.
545      */
546     virtual bool isShadeable() const;
547     virtual bool isMaximizable() const;
548     virtual bool isMinimizable() const;
549     virtual QRect iconGeometry() const;
550     virtual bool userCanSetFullScreen() const;
551     virtual bool userCanSetNoBorder() const;
552     virtual void checkNoBorder();
553 
554     QStringList activities() const override;
555     void setOnActivity(const QString &activity, bool enable);
556     void setOnActivities(const QStringList &newActivitiesList);
557     void setOnAllActivities(bool all);
558     virtual void updateActivities(bool includeTransients);
559     void blockActivityUpdates(bool b = true);
560 
rules()561     const WindowRules* rules() const {
562         return &m_rules;
563     }
564     void removeRule(Rules* r);
565     void setupWindowRules(bool ignore_temporary);
566     void evaluateWindowRules();
567     virtual void applyWindowRules();
568     virtual bool takeFocus() = 0;
569     virtual bool wantsInput() const = 0;
570     /**
571      * Whether a dock window wants input.
572      *
573      * By default KWin doesn't pass focus to a dock window unless a force activate
574      * request is provided.
575      *
576      * This method allows to have dock windows take focus also through flags set on
577      * the window.
578      *
579      * The default implementation returns @c false.
580      */
581     virtual bool dockWantsInput() const;
582     void checkWorkspacePosition(QRect oldGeometry = QRect(), QRect oldClientGeometry = QRect(), const VirtualDesktop *oldDesktop = nullptr);
583     virtual xcb_timestamp_t userTime() const;
584     virtual void updateWindowRules(Rules::Types selection);
585 
586     void growHorizontal();
587     void shrinkHorizontal();
588     void growVertical();
589     void shrinkVertical();
590     void updateInteractiveMoveResize(const QPointF &currentGlobalCursor);
591     /**
592      * Ends move resize when all pointer buttons are up again.
593      */
594     void endInteractiveMoveResize();
595     void keyPressEvent(uint key_code);
596 
597     void enterEvent(const QPoint &globalPos);
598     void leaveEvent();
599 
600     /**
601      * These values represent positions inside an area
602      */
603     enum Position {
604         // without prefix, they'd conflict with Qt::TopLeftCorner etc. :(
605         PositionCenter         = 0x00,
606         PositionLeft           = 0x01,
607         PositionRight          = 0x02,
608         PositionTop            = 0x04,
609         PositionBottom         = 0x08,
610         PositionTopLeft        = PositionLeft | PositionTop,
611         PositionTopRight       = PositionRight | PositionTop,
612         PositionBottomLeft     = PositionLeft | PositionBottom,
613         PositionBottomRight    = PositionRight | PositionBottom
614     };
615     Position titlebarPosition() const;
616     bool titlebarPositionUnderMouse() const;
617 
618     // a helper for the workspace window packing. tests for screen validity and updates since in maximization case as with normal moving
619     void packTo(int left, int top);
620 
621     /**
622      * Sets the quick tile mode ("snap") of this window.
623      * This will also handle preserving and restoring of window geometry as necessary.
624      * @param mode The tile mode (left/right) to give this window.
625      * @param keyboard Defines whether to take keyboard cursor into account.
626      */
627     void setQuickTileMode(QuickTileMode mode, bool keyboard = false);
quickTileMode()628     QuickTileMode quickTileMode() const {
629         return QuickTileMode(m_quickTileMode);
630     }
631     Layer layer() const override;
632     void updateLayer();
633 
634     void placeIn(const QRect &area);
635 
636     void move(const QPoint &point);
637     void resize(const QSize &size);
638     void moveResize(const QRect &rect);
639 
640     virtual void resizeWithChecks(const QSize& s) = 0;
641     void keepInArea(QRect area, bool partial = false);
642     virtual QSize minSize() const;
643     virtual QSize maxSize() const;
644 
645     /**
646      * How to resize the window in order to obey constraints (mainly aspect ratios).
647      */
648     enum SizeMode {
649         SizeModeAny,
650         SizeModeFixedW, ///< Try not to affect width
651         SizeModeFixedH, ///< Try not to affect height
652         SizeModeMax ///< Try not to make it larger in either direction
653     };
654 
655     virtual QSize constrainClientSize(const QSize &size, SizeMode mode = SizeModeAny) const;
656     QSize constrainFrameSize(const QSize &size, SizeMode mode = SizeModeAny) const;
657     QSize adjustedSize() const;
658 
659     /**
660      * Calculates the matching client position for the given frame position @p point.
661      */
662     virtual QPoint framePosToClientPos(const QPoint &point) const;
663     /**
664      * Calculates the matching frame position for the given client position @p point.
665      */
666     virtual QPoint clientPosToFramePos(const QPoint &point) const;
667     /**
668      * Calculates the matching client size for the given frame size @p size.
669      *
670      * Notice that size constraints won't be applied.
671      *
672      * Default implementation returns the frame size with frame margins being excluded.
673      */
674     virtual QSize frameSizeToClientSize(const QSize &size) const;
675     /**
676      * Calculates the matching frame size for the given client size @p size.
677      *
678      * Notice that size constraints won't be applied.
679      *
680      * Default implementation returns the client size with frame margins being included.
681      */
682     virtual QSize clientSizeToFrameSize(const QSize &size) const;
683     /**
684      * Calculates the matching client rect for the given frame rect @p rect.
685      *
686      * Notice that size constraints won't be applied.
687      */
688     QRect frameRectToClientRect(const QRect &rect) const;
689     /**
690      * Calculates the matching frame rect for the given client rect @p rect.
691      *
692      * Notice that size constraints won't be applied.
693      */
694     QRect clientRectToFrameRect(const QRect &rect) const;
695 
696     /**
697      * Returns the last requested geometry. The returned value indicates the bounding
698      * geometry, meaning that the client can commit smaller window geometry if the window
699      * is resized.
700      *
701      * The main difference between the frame geometry and the move-resize geometry is
702      * that the former specifies the current geometry while the latter specifies the next
703      * geometry.
704      */
705     QRect moveResizeGeometry() const;
706 
707     /**
708      * Returns @c true if the Client is being interactively moved; otherwise @c false.
709      */
isInteractiveMove()710     bool isInteractiveMove() const {
711         return isInteractiveMoveResize() && interactiveMoveResizePointerMode() == PositionCenter;
712     }
713     /**
714      * Returns @c true if the Client is being interactively resized; otherwise @c false.
715      */
isInteractiveResize()716     bool isInteractiveResize() const {
717         return isInteractiveMoveResize() && interactiveMoveResizePointerMode() != PositionCenter;
718     }
719     /**
720      * Cursor shape for move/resize mode.
721      */
cursor()722     CursorShape cursor() const {
723         return m_interactiveMoveResize.cursor;
724     }
725 
726     virtual StrutRect strutRect(StrutArea area) const;
727     StrutRects strutRects() const;
728     virtual bool hasStrut() const;
729 
730     void setModal(bool modal);
731     bool isModal() const;
732 
733     /**
734      * Determines the mouse command for the given @p button in the current state.
735      *
736      * The @p handled argument specifies whether the button was handled or not.
737      * This value should be used to determine whether the mouse button should be
738      * passed to the AbstractClient or being filtered out.
739      */
740     Options::MouseCommand getMouseCommand(Qt::MouseButton button, bool *handled) const;
741     Options::MouseCommand getWheelCommand(Qt::Orientation orientation, bool *handled) const;
742 
743     // decoration related
decoration()744     KDecoration2::Decoration *decoration() {
745         return m_decoration.decoration.data();
746     }
decoration()747     const KDecoration2::Decoration *decoration() const {
748         return m_decoration.decoration.data();
749     }
isDecorated()750     bool isDecorated() const {
751         return m_decoration.decoration != nullptr;
752     }
753     QPointer<Decoration::DecoratedClientImpl> decoratedClient() const;
754     void setDecoratedClient(QPointer<Decoration::DecoratedClientImpl> client);
755     bool decorationHasAlpha() const;
756     void triggerDecorationRepaint();
757     void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const;
758     void processDecorationMove(const QPoint &localPos, const QPoint &globalPos);
759     bool processDecorationButtonPress(QMouseEvent *event, bool ignoreMenu = false);
760     void processDecorationButtonRelease(QMouseEvent *event);
761     bool wantsShadowToBeRendered() const override;
762 
763     /**
764      * TODO: fix boolean traps
765      */
766     virtual void updateDecoration(bool check_workspace_pos, bool force = false);
767 
768     /**
769      * Returns whether the window provides context help or not. If it does,
770      * you should show a help menu item or a help button like '?' and call
771      * contextHelp() if this is invoked.
772      *
773      * Default implementation returns @c false.
774      * @see showContextHelp;
775      */
776     virtual bool providesContextHelp() const;
777 
778     /**
779      * Invokes context help on the window. Only works if the window
780      * actually provides context help.
781      *
782      * Default implementation does nothing.
783      *
784      * @see providesContextHelp()
785      */
786     virtual void showContextHelp();
787 
788     QRect inputGeometry() const override;
789     bool hitTest(const QPoint &point) const override;
790 
791     /**
792      * @returns the geometry of the virtual keyboard
793      * This geometry is in global coordinates
794      */
795     QRect virtualKeyboardGeometry() const;
796 
797     /**
798      * Sets the geometry of the virtual keyboard, The window may resize itself in order to make space for the keybaord
799      * This geometry is in global coordinates
800      */
801     virtual void setVirtualKeyboardGeometry(const QRect &geo);
802 
803     /**
804      * Restores the AbstractClient after it had been hidden due to show on screen edge functionality.
805      * The AbstractClient also gets raised (e.g. Panel mode windows can cover) and the AbstractClient
806      * gets informed in a window specific way that it is shown and raised again.
807      */
808     virtual void showOnScreenEdge();
809 
desktopFileName()810     QByteArray desktopFileName() const {
811         return m_desktopFileName;
812     }
813 
814     /**
815      * Tries to terminate the process of this AbstractClient.
816      *
817      * Implementing subclasses can perform a windowing system solution for terminating.
818      */
819     virtual void killWindow() = 0;
820     virtual void destroyClient() = 0;
821 
822     enum class SameApplicationCheck {
823         RelaxedForActive = 1 << 0,
824         AllowCrossProcesses = 1 << 1
825     };
826     Q_DECLARE_FLAGS(SameApplicationChecks, SameApplicationCheck)
827     static bool belongToSameApplication(const AbstractClient* c1, const AbstractClient* c2, SameApplicationChecks checks = SameApplicationChecks());
828 
829     bool hasApplicationMenu() const;
applicationMenuActive()830     bool applicationMenuActive() const {
831         return m_applicationMenuActive;
832     }
833     void setApplicationMenuActive(bool applicationMenuActive);
834 
applicationMenuServiceName()835     QString applicationMenuServiceName() const {
836         return m_applicationMenuServiceName;
837     }
applicationMenuObjectPath()838     QString applicationMenuObjectPath() const {
839         return m_applicationMenuObjectPath;
840     }
841 
842     virtual QString preferredColorScheme() const;
843     QString colorScheme() const;
844     void setColorScheme(const QString &colorScheme);
845 
846     /**
847      * Request showing the application menu bar
848      * @param actionId The DBus menu ID of the action that should be highlighted, 0 for the root menu
849      */
850     void showApplicationMenu(int actionId);
851 
852     bool unresponsive() const;
853 
854     /**
855      * Default implementation returns @c null.
856      * Mostly intended for X11 clients, from EWMH:
857      * @verbatim
858      * If the WM_TRANSIENT_FOR property is set to None or Root window, the window should be
859      * treated as a transient for all other windows in the same group. It has been noted that this
860      * is a slight ICCCM violation, but as this behavior is pretty standard for many toolkits and
861      * window managers, and is extremely unlikely to break anything, it seems reasonable to document
862      * it as standard.
863      * @endverbatim
864      */
865     virtual bool groupTransient() const;
866     /**
867      * Default implementation returns @c null.
868      *
869      * Mostly for X11 clients, holds the client group
870      */
871     virtual const Group *group() const;
872     /**
873      * Default implementation returns @c null.
874      *
875      * Mostly for X11 clients, holds the client group
876      */
877     virtual Group *group();
878 
879     /**
880      * Returns whether this is an internal client.
881      *
882      * Internal clients are created by KWin and used for special purpose windows,
883      * like the task switcher, etc.
884      *
885      * Default implementation returns @c false.
886      */
887     virtual bool isInternal() const;
888 
889     /**
890      * Returns whether window rules can be applied to this client.
891      *
892      * Default implementation returns @c false.
893      */
894     virtual bool supportsWindowRules() const;
895 
896     /**
897      * Return window management interface
898      */
windowManagementInterface()899     KWaylandServer::PlasmaWindowInterface *windowManagementInterface() const {
900         return m_windowManagementInterface;
901     }
902 
903     QRect fullscreenGeometryRestore() const;
904 
905     /**
906      * Helper function to compute the icon out of an application id defined by @p fileName
907      *
908      * @returns an icon name that can be used with QIcon::fromTheme()
909      */
910     static QString iconFromDesktopFile(const QString &fileName);
911 
912 public Q_SLOTS:
913     virtual void closeWindow() = 0;
914 
915 Q_SIGNALS:
916     void fullScreenChanged();
917     void skipTaskbarChanged();
918     void skipPagerChanged();
919     void skipSwitcherChanged();
920     void iconChanged();
921     void activeChanged();
922     void keepAboveChanged(bool);
923     void keepBelowChanged(bool);
924     /**
925      * Emitted whenever the demands attention state changes.
926      */
927     void demandsAttentionChanged();
928     void desktopPresenceChanged(KWin::AbstractClient*, int); // to be forwarded by Workspace
929     void desktopChanged();
930     void activitiesChanged(KWin::AbstractClient* client);
931     void x11DesktopIdsChanged();
932     void minimizedChanged();
933     void clientMinimized(KWin::AbstractClient* client, bool animate);
934     void clientUnminimized(KWin::AbstractClient* client, bool animate);
935     void paletteChanged(const QPalette &p);
936     void colorSchemeChanged();
937     void captionChanged();
938     void clientMaximizedStateChanged(KWin::AbstractClient*, MaximizeMode);
939     void clientMaximizedStateChanged(KWin::AbstractClient* c, bool h, bool v);
940     void transientChanged();
941     void modalChanged();
942     void quickTileModeChanged();
943     void moveResizedChanged();
944     void moveResizeCursorChanged(CursorShape);
945     void clientStartUserMovedResized(KWin::AbstractClient*);
946     void clientStepUserMovedResized(KWin::AbstractClient *, const QRect&);
947     void clientFinishUserMovedResized(KWin::AbstractClient*);
948     void closeableChanged(bool);
949     void minimizeableChanged(bool);
950     void shadeableChanged(bool);
951     void maximizeableChanged(bool);
952     void desktopFileNameChanged();
953     void applicationMenuChanged();
954     void hasApplicationMenuChanged(bool);
955     void applicationMenuActiveChanged(bool);
956     void unresponsiveChanged(bool);
957     void decorationChanged();
958 
959 protected:
960     AbstractClient();
setFirstInTabBox(bool enable)961     void setFirstInTabBox(bool enable) {
962         m_firstInTabBox = enable;
963     }
964     void setIcon(const QIcon &icon);
965     void startAutoRaise();
966     void autoRaise();
967     bool isMostRecentlyRaised() const;
968     void markAsZombie();
969     /**
970      * Whether the window accepts focus.
971      * The difference to wantsInput is that the implementation should not check rules and return
972      * what the window effectively supports.
973      */
974     virtual bool acceptsFocus() const = 0;
975     /**
976      * Called from setActive once the active value got updated, but before the changed signal
977      * is emitted.
978      *
979      * Default implementation does nothing.
980      */
981     virtual void doSetActive();
982     /**
983      * Called from setKeepAbove once the keepBelow value got updated, but before the changed signal
984      * is emitted.
985      *
986      * Default implementation does nothing.
987      */
988     virtual void doSetKeepAbove();
989     /**
990      * Called from setKeepBelow once the keepBelow value got updated, but before the changed signal
991      * is emitted.
992      *
993      * Default implementation does nothing.
994      */
995     virtual void doSetKeepBelow();
996     /**
997      * Called from setShade() once the shadeMode value got updated, but before the changed signal
998      * is emitted.
999      *
1000      * Default implementation does nothing.
1001      */
1002     virtual void doSetShade(ShadeMode previousShadeMode);
1003     /**
1004      * Called from setDeskop once the desktop value got updated, but before the changed signal
1005      * is emitted.
1006      *
1007      * Default implementation does nothing.
1008      */
1009     virtual void doSetDesktop();
1010     /**
1011      * Called from @ref setOnActivities just after the activity list member has been updated, but before
1012      * @ref updateActivities is called.
1013      *
1014      * @param activityList the new list of activities set on that client
1015      *
1016      * Default implementation does nothing
1017      */
1018     virtual void doSetOnActivities(const QStringList &activityList);
1019     /**
1020      * Called from @ref minimize and @ref unminimize once the minimized value got updated, but before the
1021      * changed signal is emitted.
1022      *
1023      * Default implementation does nothig.
1024      */
1025     virtual void doMinimize();
1026     virtual bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const = 0;
1027 
1028     virtual void doSetSkipTaskbar();
1029     virtual void doSetSkipPager();
1030     virtual void doSetSkipSwitcher();
1031     virtual void doSetDemandsAttention();
1032     virtual void doSetQuickTileMode();
1033 
1034     void setupWindowManagementInterface();
1035     void updateColorScheme();
1036     void setTransientFor(AbstractClient *transientFor);
1037     /**
1038      * Just removes the @p cl from the transients without any further checks.
1039      */
1040     void removeTransientFromList(AbstractClient* cl);
1041 
1042     virtual Layer belongsToLayer() const;
1043     virtual bool belongsToDesktop() const;
1044     void invalidateLayer();
1045     bool isActiveFullScreen() const;
1046     virtual Layer layerForDock() const;
1047 
1048     // electric border / quick tiling
1049     void setElectricBorderMode(QuickTileMode mode);
electricBorderMode()1050     QuickTileMode electricBorderMode() const {
1051         return m_electricMode;
1052     }
1053     void setElectricBorderMaximizing(bool maximizing);
isElectricBorderMaximizing()1054     bool isElectricBorderMaximizing() const {
1055         return m_electricMaximizing;
1056     }
1057     QRect electricBorderMaximizeGeometry(const QPoint &pos) const;
updateQuickTileMode(QuickTileMode newMode)1058     void updateQuickTileMode(QuickTileMode newMode) {
1059         m_quickTileMode = newMode;
1060     }
1061 
1062     // geometry handling
1063     void checkOffscreenPosition(QRect *geom, const QRect &screenArea);
1064     int borderLeft() const;
1065     int borderRight() const;
1066     int borderTop() const;
1067     int borderBottom() const;
1068     virtual void changeMaximize(bool horizontal, bool vertical, bool adjust);
1069     void setGeometryRestore(const QRect &rect);
1070 
1071 
1072     void blockGeometryUpdates(bool block);
1073     void blockGeometryUpdates();
1074     void unblockGeometryUpdates();
1075     bool areGeometryUpdatesBlocked() const;
1076     enum class MoveResizeMode : uint {
1077         None,
1078         Move = 0x1,
1079         Resize = 0x2,
1080         MoveResize = Move | Resize,
1081     };
1082     MoveResizeMode pendingMoveResizeMode() const;
1083     void setPendingMoveResizeMode(MoveResizeMode mode);
1084     virtual void moveResizeInternal(const QRect &rect, MoveResizeMode mode) = 0;
1085 
1086     /**
1087      * @returns whether the Client is currently in move resize mode
1088      */
isInteractiveMoveResize()1089     bool isInteractiveMoveResize() const {
1090         return m_interactiveMoveResize.enabled;
1091     }
1092     /**
1093      * Sets whether the Client is in move resize mode to @p enabled.
1094      */
setInteractiveMoveResize(bool enabled)1095     void setInteractiveMoveResize(bool enabled) {
1096         m_interactiveMoveResize.enabled = enabled;
1097     }
1098     /**
1099      * @returns whether the move resize mode is unrestricted.
1100      */
isUnrestrictedInteractiveMoveResize()1101     bool isUnrestrictedInteractiveMoveResize() const {
1102         return m_interactiveMoveResize.unrestricted;
1103     }
1104     /**
1105      * Sets whether move resize mode is unrestricted to @p set.
1106      */
setUnrestrictedInteractiveMoveResize(bool set)1107     void setUnrestrictedInteractiveMoveResize(bool set) {
1108         m_interactiveMoveResize.unrestricted = set;
1109     }
interactiveMoveOffset()1110     QPoint interactiveMoveOffset() const {
1111         return m_interactiveMoveResize.offset;
1112     }
setInteractiveMoveOffset(const QPoint & offset)1113     void setInteractiveMoveOffset(const QPoint &offset) {
1114         m_interactiveMoveResize.offset = offset;
1115     }
invertedInteractiveMoveOffset()1116     QPoint invertedInteractiveMoveOffset() const {
1117         return m_interactiveMoveResize.invertedOffset;
1118     }
setInvertedInteractiveMoveOffset(const QPoint & offset)1119     void setInvertedInteractiveMoveOffset(const QPoint &offset) {
1120         m_interactiveMoveResize.invertedOffset = offset;
1121     }
initialInteractiveMoveResizeGeometry()1122     QRect initialInteractiveMoveResizeGeometry() const {
1123         return m_interactiveMoveResize.initialGeometry;
1124     }
1125     /**
1126      * Sets the initial move resize geometry to the current geometry.
1127      */
1128     void updateInitialMoveResizeGeometry();
1129     void setMoveResizeGeometry(const QRect &geo);
interactiveMoveResizePointerMode()1130     Position interactiveMoveResizePointerMode() const {
1131         return m_interactiveMoveResize.pointer;
1132     }
setInteractiveMoveResizePointerMode(Position mode)1133     void setInteractiveMoveResizePointerMode(Position mode) {
1134         m_interactiveMoveResize.pointer = mode;
1135     }
isInteractiveMoveResizePointerButtonDown()1136     bool isInteractiveMoveResizePointerButtonDown() const {
1137         return m_interactiveMoveResize.buttonDown;
1138     }
setInteractiveMoveResizePointerButtonDown(bool down)1139     void setInteractiveMoveResizePointerButtonDown(bool down) {
1140         m_interactiveMoveResize.buttonDown = down;
1141     }
interactiveMoveResizeStartOutput()1142     AbstractOutput *interactiveMoveResizeStartOutput() const {
1143         return m_interactiveMoveResize.startOutput;
1144     }
1145     void checkUnrestrictedInteractiveMoveResize();
1146     /**
1147      * Sets an appropriate cursor shape for the logical mouse position.
1148      */
1149     void updateCursor();
1150     void startDelayedInteractiveMoveResize();
1151     void stopDelayedInteractiveMoveResize();
1152     bool startInteractiveMoveResize();
1153     /**
1154      * Called from startMoveResize.
1155      *
1156      * Implementing classes should return @c false if starting move resize should
1157      * get aborted. In that case startMoveResize will also return @c false.
1158      *
1159      * Base implementation returns @c true.
1160      */
1161     virtual bool doStartInteractiveMoveResize();
1162     virtual void doFinishInteractiveMoveResize();
1163     void finishInteractiveMoveResize(bool cancel);
1164     /**
1165      * Leaves the move resize mode.
1166      *
1167      * Inheriting classes must invoke the base implementation which
1168      * ensures that the internal mode is properly ended.
1169      */
1170     virtual void leaveInteractiveMoveResize();
1171     virtual void positionGeometryTip();
1172     void performInteractiveMoveResize();
1173     /*
1174      * Checks if the mouse cursor is near the edge of the screen and if so
1175      * activates quick tiling or maximization
1176      */
1177     void checkQuickTilingMaximizationZones(int xroot, int yroot);
1178     /**
1179      * Whether a sync request is still pending.
1180      * Default implementation returns @c false.
1181      */
1182     virtual bool isWaitingForInteractiveMoveResizeSync() const;
1183     /**
1184      * Called during handling a resize. Implementing subclasses can use this
1185      * method to perform windowing system specific syncing.
1186      *
1187      * Default implementation does nothing.
1188      */
1189     virtual void doInteractiveResizeSync();
1190     void handleInteractiveMoveResize(int x, int y, int x_root, int y_root);
1191     void handleInteractiveMoveResize(const QPoint &local, const QPoint &global);
1192     void dontInteractiveMoveResize();
1193 
1194     virtual QSize resizeIncrements() const;
1195 
1196     /**
1197      * Returns the position depending on the Decoration's section under mouse.
1198      * If no decoration it returns PositionCenter.
1199      */
1200     Position mousePosition() const;
1201 
haveResizeEffect()1202     static bool haveResizeEffect() {
1203         return s_haveResizeEffect;
1204     }
1205     static void updateHaveResizeEffect();
resetHaveResizeEffect()1206     static void resetHaveResizeEffect() {
1207         s_haveResizeEffect = false;
1208     }
1209 
1210     void setDecoration(KDecoration2::Decoration *decoration);
1211     virtual void createDecoration(const QRect &oldGeometry);
1212     virtual void destroyDecoration();
1213     void startDecorationDoubleClickTimer();
1214     void invalidateDecorationDoubleClickTimer();
1215     void updateDecorationInputShape();
1216 
1217     void setDesktopFileName(QByteArray name);
1218     QString iconFromDesktopFile() const;
1219 
1220     void updateApplicationMenuServiceName(const QString &serviceName);
1221     void updateApplicationMenuObjectPath(const QString &objectPath);
1222 
1223     void setUnresponsive(bool unresponsive);
1224 
1225     virtual void setShortcutInternal();
1226     QString shortcutCaptionSuffix() const;
1227     virtual void updateCaption() = 0;
1228 
1229     /**
1230      * Looks for another AbstractClient with same captionNormal and captionSuffix.
1231      * If no such AbstractClient exists @c nullptr is returned.
1232      */
1233     AbstractClient *findClientWithSameCaption() const;
1234 
1235     void finishWindowRules();
1236     void discardTemporaryRules();
1237 
1238     bool tabTo(AbstractClient *other, bool behind, bool activate);
1239 
1240     void startShadeHoverTimer();
1241     void startShadeUnhoverTimer();
1242 
1243     // The geometry that the client should be restored when the virtual keyboard closes
1244     QRect keyboardGeometryRestore() const;
1245     void setKeyboardGeometryRestore(const QRect &geom);
1246 
1247     QRect m_virtualKeyboardGeometry;
1248 
1249     void setFullscreenGeometryRestore(const QRect &geom);
1250 
1251     void cleanTabBox();
1252 
1253 private Q_SLOTS:
1254     void shadeHover();
1255     void shadeUnhover();
1256 
1257 private:
1258     void handlePaletteChange();
1259     QSharedPointer<TabBox::TabBoxClientImpl> m_tabBoxClient;
1260     bool m_firstInTabBox = false;
1261     bool m_skipTaskbar = false;
1262     /**
1263      * Unaffected by KWin
1264      */
1265     bool m_originalSkipTaskbar = false;
1266     bool m_skipPager = false;
1267     bool m_skipSwitcher = false;
1268     QIcon m_icon;
1269     bool m_active = false;
1270     bool m_zombie = false;
1271     bool m_keepAbove = false;
1272     bool m_keepBelow = false;
1273     bool m_demandsAttention = false;
1274     bool m_minimized = false;
1275     QTimer *m_autoRaiseTimer = nullptr;
1276     QTimer *m_shadeHoverTimer = nullptr;
1277     ShadeMode m_shadeMode = ShadeNone;
1278     QVector <VirtualDesktop *> m_desktops;
1279 
1280     QStringList m_activityList;
1281     int m_activityUpdatesBlocked = 0;
1282     bool m_blockedActivityUpdatesRequireTransients = false;
1283 
1284     QString m_colorScheme;
1285     std::shared_ptr<Decoration::DecorationPalette> m_palette;
1286     static QHash<QString, std::weak_ptr<Decoration::DecorationPalette>> s_palettes;
1287     static std::shared_ptr<Decoration::DecorationPalette> s_defaultPalette;
1288 
1289     KWaylandServer::PlasmaWindowInterface *m_windowManagementInterface = nullptr;
1290 
1291     AbstractClient *m_transientFor = nullptr;
1292     QList<AbstractClient*> m_transients;
1293     bool m_modal = false;
1294     Layer m_layer = UnknownLayer;
1295 
1296     // electric border/quick tiling
1297     QuickTileMode m_electricMode = QuickTileFlag::None;
1298     bool m_electricMaximizing = false;
1299     // The quick tile mode of this window.
1300     int m_quickTileMode = int(QuickTileFlag::None);
1301     QTimer *m_electricMaximizingDelay = nullptr;
1302 
1303     // geometry
1304     int m_blockGeometryUpdates = 0; // > 0 = New geometry is remembered, but not actually set
1305     MoveResizeMode m_pendingMoveResizeMode = MoveResizeMode::None;
1306     friend class GeometryUpdatesBlocker;
1307     QRect m_moveResizeGeometry;
1308     QRect m_keyboardGeometryRestore;
1309     QRect m_maximizeGeometryRestore;
1310     QRect m_fullscreenGeometryRestore;
1311 
1312     struct {
1313         bool enabled = false;
1314         bool unrestricted = false;
1315         QPoint offset;
1316         QPoint invertedOffset;
1317         QRect initialGeometry;
1318         Position pointer = PositionCenter;
1319         bool buttonDown = false;
1320         CursorShape cursor = Qt::ArrowCursor;
1321         AbstractOutput *startOutput = nullptr;
1322         QTimer *delayedTimer = nullptr;
1323     } m_interactiveMoveResize;
1324 
1325     struct {
1326         QScopedPointer<KDecoration2::Decoration> decoration;
1327         QPointer<Decoration::DecoratedClientImpl> client;
1328         QElapsedTimer doubleClickTimer;
1329         QRegion inputRegion;
1330     } m_decoration;
1331     QByteArray m_desktopFileName;
1332 
1333     bool m_applicationMenuActive = false;
1334     QString m_applicationMenuServiceName;
1335     QString m_applicationMenuObjectPath;
1336 
1337     bool m_unresponsive = false;
1338 
1339     QKeySequence _shortcut;
1340 
1341     WindowRules m_rules;
1342 
1343     static bool s_haveResizeEffect;
1344 };
1345 
1346 /**
1347  * Helper for AbstractClient::blockGeometryUpdates() being called in pairs (true/false)
1348  */
1349 class GeometryUpdatesBlocker
1350 {
1351 public:
GeometryUpdatesBlocker(AbstractClient * c)1352     explicit GeometryUpdatesBlocker(AbstractClient* c)
1353         : cl(c) {
1354         cl->blockGeometryUpdates(true);
1355     }
~GeometryUpdatesBlocker()1356     ~GeometryUpdatesBlocker() {
1357         cl->blockGeometryUpdates(false);
1358     }
1359 
1360 private:
1361     AbstractClient* cl;
1362 };
1363 
transients()1364 inline const QList<AbstractClient*>& AbstractClient::transients() const
1365 {
1366     return m_transients;
1367 }
1368 
areGeometryUpdatesBlocked()1369 inline bool AbstractClient::areGeometryUpdatesBlocked() const
1370 {
1371     return m_blockGeometryUpdates != 0;
1372 }
1373 
blockGeometryUpdates()1374 inline void AbstractClient::blockGeometryUpdates()
1375 {
1376     m_blockGeometryUpdates++;
1377 }
1378 
unblockGeometryUpdates()1379 inline void AbstractClient::unblockGeometryUpdates()
1380 {
1381     m_blockGeometryUpdates--;
1382 }
1383 
pendingMoveResizeMode()1384 inline AbstractClient::MoveResizeMode AbstractClient::pendingMoveResizeMode() const
1385 {
1386     return m_pendingMoveResizeMode;
1387 }
1388 
setPendingMoveResizeMode(MoveResizeMode mode)1389 inline void AbstractClient::setPendingMoveResizeMode(MoveResizeMode mode)
1390 {
1391     m_pendingMoveResizeMode = MoveResizeMode(uint(m_pendingMoveResizeMode) | uint(mode));
1392 }
1393 
1394 }
1395 
1396 Q_DECLARE_METATYPE(KWin::AbstractClient*)
1397 Q_DECLARE_METATYPE(QList<KWin::AbstractClient*>)
1398 Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::AbstractClient::SameApplicationChecks)
1399 
1400 #endif
1401