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 ¤tGlobalCursor);
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