1/********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>.
20*********************************************************************/
21
22#ifndef KWIN_CLIENT_H
23#define KWIN_CLIENT_H
24
25// kwin
26#include "options.h"
27#include "rules.h"
28#include "tabgroup.h"
29#include "toplevel.h"
30#include "xcbutils.h"
31// KDE
32#include <KDE/KShortcut>
33#include <KDE/NETWinInfo>
34// Qt
35#include <QPixmap>
36// X
37#ifdef HAVE_XSYNC
38#include <X11/extensions/sync.h>
39#endif
40#include <X11/Xutil.h>
41#include <fixx11h.h>
42
43// TODO: Cleanup the order of things in this .h file
44
45class QTimer;
46class KStartupInfoData;
47class KStartupInfoId;
48
49namespace KWin
50{
51namespace TabBox
52{
53
54class TabBoxClientImpl;
55}
56
57class Bridge;
58class PaintRedirector;
59
60class Client
61 : public Toplevel
62{
63 Q_OBJECT
64 /**
65 * Whether this Client is active or not. Use Workspace::activateClient() to activate a Client.
66 * @see Workspace::activateClient
67 **/
68 Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
69 /**
70 * The Caption of the Client. Read from WM_NAME property together with a suffix for hostname and shortcut.
71 * To read only the caption as provided by WM_NAME, use the getter with an additional @c false value.
72 **/
73 Q_PROPERTY(QString caption READ caption NOTIFY captionChanged)
74 /**
75 * Whether the window can be closed by the user. The value is evaluated each time the getter is called.
76 * Because of that no changed signal is provided.
77 **/
78 Q_PROPERTY(bool closeable READ isCloseable)
79 /**
80 * The desktop this Client is on. If the Client is on all desktops the property has value -1.
81 **/
82 Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged)
83 /**
84 * Whether the Client is on all desktops. That is desktop is -1.
85 **/
86 Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops WRITE setOnAllDesktops NOTIFY desktopChanged)
87 /**
88 * Whether this Client is fullScreen. A Client might either be fullScreen due to the _NET_WM property
89 * or through a legacy support hack. The fullScreen state can only be changed if the Client does not
90 * use the legacy hack. To be sure whether the state changed, connect to the notify signal.
91 **/
92 Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged)
93 /**
94 * Whether the Client can be set to fullScreen. The property is evaluated each time it is invoked.
95 * Because of that there is no notify signal.
96 **/
97 Q_PROPERTY(bool fullScreenable READ isFullScreenable)
98 /**
99 * The geometry of this Client. Be aware that depending on resize mode the geometryChanged signal
100 * might be emitted at each resize step or only at the end of the resize operation.
101 **/
102 Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry)
103 /**
104 * Whether the Client is set to be kept above other windows.
105 **/
106 Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChanged)
107 /**
108 * Whether the Client is set to be kept below other windows.
109 **/
110 Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChanged)
111 /**
112 * Whether the Client can be maximized both horizontally and vertically.
113 * The property is evaluated each time it is invoked.
114 * Because of that there is no notify signal.
115 **/
116 Q_PROPERTY(bool maximizable READ isMaximizable)
117 /**
118 * Whether the Client can be minimized. The property is evaluated each time it is invoked.
119 * Because of that there is no notify signal.
120 **/
121 Q_PROPERTY(bool minimizable READ isMinimizable)
122 /**
123 * Whether the Client is minimized.
124 **/
125 Q_PROPERTY(bool minimized READ isMinimized WRITE setMinimized NOTIFY minimizedChanged)
126 /**
127 * Whether the Client represents a modal window.
128 **/
129 Q_PROPERTY(bool modal READ isModal NOTIFY modalChanged)
130 /**
131 * Whether the Client is moveable. Even if it is not moveable, it might be possible to move
132 * it to another screen. The property is evaluated each time it is invoked.
133 * Because of that there is no notify signal.
134 * @see moveableAcrossScreens
135 **/
136 Q_PROPERTY(bool moveable READ isMovable)
137 /**
138 * Whether the Client can be moved to another screen. The property is evaluated each time it is invoked.
139 * Because of that there is no notify signal.
140 * @see moveable
141 **/
142 Q_PROPERTY(bool moveableAcrossScreens READ isMovableAcrossScreens)
143 /**
144 * Whether the Client provides context help. Mostly needed by decorations to decide whether to
145 * show the help button or not.
146 **/
147 Q_PROPERTY(bool providesContextHelp READ providesContextHelp CONSTANT)
148 /**
149 * Whether the Client can be resized. The property is evaluated each time it is invoked.
150 * Because of that there is no notify signal.
151 **/
152 Q_PROPERTY(bool resizeable READ isResizable)
153 /**
154 * Whether the Client can be shaded. The property is evaluated each time it is invoked.
155 * Because of that there is no notify signal.
156 **/
157 Q_PROPERTY(bool shadeable READ isShadeable)
158 /**
159 * Whether the Client is shaded.
160 **/
161 Q_PROPERTY(bool shade READ isShade WRITE setShade NOTIFY shadeChanged)
162 /**
163 * Whether the Client is a transient Window to another Window.
164 * @see transientFor
165 **/
166 Q_PROPERTY(bool transient READ isTransient NOTIFY transientChanged)
167 /**
168 * The Client to which this Client is a transient if any.
169 **/
170 Q_PROPERTY(KWin::Client *transientFor READ transientFor NOTIFY transientChanged)
171 /**
172 * By how much the window wishes to grow/shrink at least. Usually QSize(1,1).
173 * MAY BE DISOBEYED BY THE WM! It's only for information, do NOT rely on it at all.
174 * The value is evaluated each time the getter is called.
175 * Because of that no changed signal is provided.
176 */
177 Q_PROPERTY(QSize basicUnit READ basicUnit)
178 /**
179 * Whether the Client is currently being moved by the user.
180 * Notify signal is emitted when the Client starts or ends move/resize mode.
181 **/
182 Q_PROPERTY(bool move READ isMove NOTIFY moveResizedChanged)
183 /**
184 * Whether the Client is currently being resized by the user.
185 * Notify signal is emitted when the Client starts or ends move/resize mode.
186 **/
187 Q_PROPERTY(bool resize READ isResize NOTIFY moveResizedChanged)
188 /**
189 * The optional geometry representing the minimized Client in e.g a taskbar.
190 * See _NET_WM_ICON_GEOMETRY at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
191 * The value is evaluated each time the getter is called.
192 * Because of that no changed signal is provided.
193 **/
194 Q_PROPERTY(QRect iconGeometry READ iconGeometry)
195 /**
196 * Returns whether the window is any of special windows types (desktop, dock, splash, ...),
197 * i.e. window types that usually don't have a window frame and the user does not use window
198 * management (moving, raising,...) on them.
199 * The value is evaluated each time the getter is called.
200 * Because of that no changed signal is provided.
201 **/
202 Q_PROPERTY(bool specialWindow READ isSpecialWindow)
203 /**
204 * Whether the Client can accept keyboard focus.
205 * The value is evaluated each time the getter is called.
206 * Because of that no changed signal is provided.
207 **/
208 Q_PROPERTY(bool wantsInput READ wantsInput)
209 // TODO: a QIcon with all icon sizes?
210 Q_PROPERTY(QPixmap icon READ icon NOTIFY iconChanged)
211 /**
212 * Whether the Client should be excluded from window switching effects.
213 **/
214 Q_PROPERTY(bool skipSwitcher READ skipSwitcher WRITE setSkipSwitcher NOTIFY skipSwitcherChanged)
215 /**
216 * Indicates that the window should not be included on a taskbar.
217 **/
218 Q_PROPERTY(bool skipTaskbar READ skipTaskbar WRITE setSkipTaskbar NOTIFY skipTaskbarChanged)
219 /**
220 * Indicates that the window should not be included on a Pager.
221 **/
222 Q_PROPERTY(bool skipPager READ skipPager WRITE setSkipPager NOTIFY skipPagerChanged)
223 /**
224 * The "Window Tabs" Group this Client belongs to.
225 **/
226 Q_PROPERTY(KWin::TabGroup* tabGroup READ tabGroup NOTIFY tabGroupChanged SCRIPTABLE false)
227 /**
228 * Whether this Client is the currently visible Client in its Client Group (Window Tabs).
229 * For change connect to the visibleChanged signal on the Client's Group.
230 **/
231 Q_PROPERTY(bool isCurrentTab READ isCurrentTab)
232 /**
233 * Minimum size as specified in WM_NORMAL_HINTS
234 **/
235 Q_PROPERTY(QSize minSize READ minSize)
236 /**
237 * Maximum size as specified in WM_NORMAL_HINTS
238 **/
239 Q_PROPERTY(QSize maxSize READ maxSize)
240 /**
241 * Whether the window has a decoration or not.
242 * This property is not allowed to be set by applications themselves.
243 * The decision whether a window has a border or not belongs to the window manager.
244 * If this property gets abused by application developers, it will be removed again.
245 **/
246 Q_PROPERTY(bool noBorder READ noBorder WRITE setNoBorder)
247 /**
248 * Whether window state _NET_WM_STATE_DEMANDS_ATTENTION is set. This state indicates that some
249 * action in or with the window happened. For example, it may be set by the Window Manager if
250 * the window requested activation but the Window Manager refused it, or the application may set
251 * it if it finished some work. This state may be set by both the Client and the Window Manager.
252 * It should be unset by the Window Manager when it decides the window got the required attention
253 * (usually, that it got activated).
254 **/
255 Q_PROPERTY(bool demandsAttention READ isDemandingAttention WRITE demandAttention NOTIFY demandsAttentionChanged)
256 /**
257 * A client can block compositing. That is while the Client is alive and the state is set,
258 * Compositing is suspended and is resumed when there are no Clients blocking compositing any
259 * more.
260 *
261 * This is actually set by a window property, unfortunately not used by the target application
262 * group. For convenience it's exported as a property to the scripts.
263 *
264 * Use with care!
265 **/
266 Q_PROPERTY(bool blocksCompositing READ isBlockingCompositing WRITE setBlockingCompositing NOTIFY blockingCompositingChanged)
267 /**
268 * Whether the decoration is currently using an alpha channel.
269 **/
270 Q_PROPERTY(bool decorationHasAlpha READ decorationHasAlpha)
271public:
272 explicit Client();
273 xcb_window_t wrapperId() const;
274 xcb_window_t decorationId() const;
275 xcb_window_t inputId() const { return m_decoInputExtent; }
276
277 const Client* transientFor() const;
278 Client* transientFor();
279 bool isTransient() const;
280 bool groupTransient() const;
281 bool wasOriginallyGroupTransient() const;
282 ClientList mainClients() const; // Call once before loop , is not indirect
283 ClientList allMainClients() const; // Call once before loop , is indirect
284 bool hasTransient(const Client* c, bool indirect) const;
285 const ClientList& transients() const; // Is not indirect
286 void checkTransient(xcb_window_t w);
287 Client* findModal(bool allow_itself = false);
288 const Group* group() const;
289 Group* group();
290 void checkGroup(Group* gr = NULL, bool force = false);
291 void changeClientLeaderGroup(Group* gr);
292 const WindowRules* rules() const;
293 void removeRule(Rules* r);
294 void setupWindowRules(bool ignore_temporary);
295 void applyWindowRules();
296 void updateWindowRules(Rules::Types selection);
297 void updateFullscreenMonitors(NETFullscreenMonitors topology);
298
299 /**
300 * Returns true for "special" windows and false for windows which are "normal"
301 * (normal=window which has a border, can be moved by the user, can be closed, etc.)
302 * true for Desktop, Dock, Splash, Override and TopMenu (and Toolbar??? - for now)
303 * false for Normal, Dialog, Utility and Menu (and Toolbar??? - not yet) TODO
304 */
305 bool isSpecialWindow() const;
306 bool hasNETSupport() const;
307
308 QSize minSize() const;
309 QSize maxSize() const;
310 QSize basicUnit() const;
311 virtual QPoint clientPos() const; // Inside of geometry()
312 virtual QSize clientSize() const;
313 QPoint inputPos() const { return input_offset; } // Inside of geometry()
314
315 bool windowEvent(XEvent* e);
316 virtual bool eventFilter(QObject* o, QEvent* e);
317#ifdef HAVE_XSYNC
318 void syncEvent(XSyncAlarmNotifyEvent* e);
319#endif
320 NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
321
322 bool manage(xcb_window_t w, bool isMapped);
323 void releaseWindow(bool on_shutdown = false);
324 void destroyClient();
325
326 /// How to resize the window in order to obey constains (mainly aspect ratios)
327 enum Sizemode {
328 SizemodeAny,
329 SizemodeFixedW, ///< Try not to affect width
330 SizemodeFixedH, ///< Try not to affect height
331 SizemodeMax ///< Try not to make it larger in either direction
332 };
333 QSize adjustedSize(const QSize&, Sizemode mode = SizemodeAny) const;
334 QSize adjustedSize() const;
335
336 QPixmap icon() const;
337 QPixmap icon(const QSize& size) const;
338 QPixmap miniIcon() const;
339 QPixmap bigIcon() const;
340 QPixmap hugeIcon() const;
341
342 bool isActive() const;
343 void setActive(bool);
344
345 virtual int desktop() const;
346 void setDesktop(int);
347 void setOnAllDesktops(bool set);
348
349 void sendToScreen(int screen);
350
351 virtual QStringList activities() const;
352 void setOnActivity(const QString &activity, bool enable);
353 void setOnAllActivities(bool set);
354 void setOnActivities(QStringList newActivitiesList);
355 void updateActivities(bool includeTransients);
356 void blockActivityUpdates(bool b = true);
357
358 /// Is not minimized and not hidden. I.e. normally visible on some virtual desktop.
359 bool isShown(bool shaded_is_shown) const;
360 bool isHiddenInternal() const; // For compositing
361
362 bool isShade() const; // True only for ShadeNormal
363 ShadeMode shadeMode() const; // Prefer isShade()
364 void setShade(bool set);
365 void setShade(ShadeMode mode);
366 bool isShadeable() const;
367
368 bool isMinimized() const;
369 bool isMaximizable() const;
370 QRect geometryRestore() const;
371 MaximizeMode maximizeMode() const;
372 QuickTileMode quickTileMode() const;
373 bool isMinimizable() const;
374 void setMaximize(bool vertically, bool horizontally);
375 QRect iconGeometry() const;
376
377 void setFullScreen(bool set, bool user = true);
378 bool isFullScreen() const;
379 bool isFullScreenable(bool fullscreen_hack = false) const;
380 bool isActiveFullScreen() const;
381 bool userCanSetFullScreen() const;
382 QRect geometryFSRestore() const {
383 return geom_fs_restore; // Only for session saving
384 }
385 int fullScreenMode() const {
386 return fullscreen_mode; // only for session saving
387 }
388
389 bool noBorder() const;
390 void setNoBorder(bool set);
391 bool userCanSetNoBorder() const;
392 void checkNoBorder();
393
394 bool skipTaskbar(bool from_outside = false) const;
395 void setSkipTaskbar(bool set, bool from_outside = false);
396
397 bool skipPager() const;
398 void setSkipPager(bool);
399
400 bool skipSwitcher() const;
401 void setSkipSwitcher(bool set);
402
403 bool keepAbove() const;
404 void setKeepAbove(bool);
405 bool keepBelow() const;
406 void setKeepBelow(bool);
407 virtual Layer layer() const;
408 Layer belongsToLayer() const;
409 void invalidateLayer();
410 void updateLayer();
411 int sessionStackingOrder() const;
412
413 void setModal(bool modal);
414 bool isModal() const;
415
416 // Auxiliary functions, depend on the windowType
417 bool wantsTabFocus() const;
418 bool wantsInput() const;
419
420 bool isResizable() const;
421 bool isMovable() const;
422 bool isMovableAcrossScreens() const;
423 bool isCloseable() const; ///< May be closed by the user (May have a close button)
424
425 void takeActivity(int flags, bool handled); // Takes ActivityFlags as arg (in utils.h)
426 void takeFocus();
427 bool isDemandingAttention() const {
428 return demands_attention;
429 }
430 void demandAttention(bool set = true);
431
432 void setMask(const QRegion& r, int mode = XCB_CLIP_ORDERING_UNSORTED);
433 QRegion mask() const;
434
435 void updateDecoration(bool check_workspace_pos, bool force = false);
436 bool checkBorderSizes(bool also_resize);
437 void triggerDecorationRepaint();
438
439 void updateShape();
440
441 void setGeometry(int x, int y, int w, int h, ForceGeometry_t force = NormalGeometrySet);
442 void setGeometry(const QRect& r, ForceGeometry_t force = NormalGeometrySet);
443 void move(int x, int y, ForceGeometry_t force = NormalGeometrySet);
444 void move(const QPoint& p, ForceGeometry_t force = NormalGeometrySet);
445 /// plainResize() simply resizes
446 void plainResize(int w, int h, ForceGeometry_t force = NormalGeometrySet);
447 void plainResize(const QSize& s, ForceGeometry_t force = NormalGeometrySet);
448 /// resizeWithChecks() resizes according to gravity, and checks workarea position
449 void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet);
450 void resizeWithChecks(const QSize& s, ForceGeometry_t force = NormalGeometrySet);
451 void keepInArea(QRect area, bool partial = false);
452 void setElectricBorderMode(QuickTileMode mode);
453 QuickTileMode electricBorderMode() const;
454 void setElectricBorderMaximizing(bool maximizing);
455 bool isElectricBorderMaximizing() const;
456 QRect electricBorderMaximizeGeometry(QPoint pos, int desktop);
457 QSize sizeForClientSize(const QSize&, Sizemode mode = SizemodeAny, bool noframe = false) const;
458
459 /** Set the quick tile mode ("snap") of this window.
460 * This will also handle preserving and restoring of window geometry as necessary.
461 * @param mode The tile mode (left/right) to give this window.
462 */
463 void setQuickTileMode(QuickTileMode mode, bool keyboard = false);
464
465 void growHorizontal();
466 void shrinkHorizontal();
467 void growVertical();
468 void shrinkVertical();
469
470 bool providesContextHelp() const;
471 KShortcut shortcut() const;
472 void setShortcut(const QString& cut);
473
474 WindowOperation mouseButtonToWindowOperation(Qt::MouseButtons button);
475 bool performMouseCommand(Options::MouseCommand, const QPoint& globalPos, bool handled = false);
476
477 QRect adjustedClientArea(const QRect& desktop, const QRect& area) const;
478
479 xcb_colormap_t colormap() const;
480
481 /// Updates visibility depending on being shaded, virtual desktop, etc.
482 void updateVisibility();
483 /// Hides a client - Basically like minimize, but without effects, it's simply hidden
484 void hideClient(bool hide);
485 bool hiddenPreview() const; ///< Window is mapped in order to get a window pixmap
486
487 virtual bool setupCompositing();
488 virtual void finishCompositing();
489 void setBlockingCompositing(bool block);
490 inline bool isBlockingCompositing() { return blocks_compositing; }
491 void updateCompositeBlocking(bool readProperty = false);
492
493 QString caption(bool full = true, bool stripped = false) const;
494
495 void keyPressEvent(uint key_code); // FRAME ??
496 void updateMouseGrab();
497 xcb_window_t moveResizeGrabWindow() const;
498
499 const QPoint calculateGravitation(bool invert, int gravity = 0) const; // FRAME public?
500
501 void NETMoveResize(int x_root, int y_root, NET::Direction direction);
502 void NETMoveResizeWindow(int flags, int x, int y, int width, int height);
503 void restackWindow(xcb_window_t above, int detail, NET::RequestSource source, xcb_timestamp_t timestamp,
504 bool send_event = false);
505
506 void gotPing(xcb_timestamp_t timestamp);
507
508 void checkWorkspacePosition(QRect oldGeometry = QRect(), int oldDesktop = -2);
509 void updateUserTime(xcb_timestamp_t time = XCB_TIME_CURRENT_TIME);
510 xcb_timestamp_t userTime() const;
511 bool hasUserTimeSupport() const;
512
513 /// Does 'delete c;'
514 static void deleteClient(Client* c);
515
516 static bool belongToSameApplication(const Client* c1, const Client* c2, bool active_hack = false);
517 static bool sameAppWindowRoleMatch(const Client* c1, const Client* c2, bool active_hack);
518 static void readIcons(xcb_window_t win, QPixmap* icon, QPixmap* miniicon, QPixmap* bigicon, QPixmap* hugeicon);
519
520 void setMinimized(bool set);
521 void minimize(bool avoid_animation = false);
522 void unminimize(bool avoid_animation = false);
523 void killWindow();
524 void maximize(MaximizeMode);
525 void toggleShade();
526 void showContextHelp();
527 void cancelShadeHoverTimer();
528 void cancelAutoRaise();
529 void checkActiveModal();
530 StrutRect strutRect(StrutArea area) const;
531 StrutRects strutRects() const;
532 bool hasStrut() const;
533
534 // Tabbing functions
535 TabGroup* tabGroup() const; // Returns a pointer to client_group
536 Q_INVOKABLE inline bool tabBefore(Client *other, bool activate) { return tabTo(other, false, activate); }
537 Q_INVOKABLE inline bool tabBehind(Client *other, bool activate) { return tabTo(other, true, activate); }
538 /**
539 * Syncs the *dynamic* @param property @param fromThisClient or the @link currentTab() to
540 * all members of the @link tabGroup() (if there is one)
541 *
542 * eg. if you call:
543 * client->setProperty("kwin_tiling_floats", true);
544 * client->syncTabGroupFor("kwin_tiling_floats", true)
545 * all clients in this tabGroup will have ::property("kwin_tiling_floats").toBool() == true
546 *
547 * WARNING: non dynamic properties are ignored - you're not supposed to alter/update such explicitly
548 */
549 Q_INVOKABLE void syncTabGroupFor(QString property, bool fromThisClient = false);
550 Q_INVOKABLE bool untab(const QRect &toGeometry = QRect(), bool clientRemoved = false);
551 /**
552 * Set tab group - this is to be invoked by TabGroup::add/remove(client) and NO ONE ELSE
553 */
554 void setTabGroup(TabGroup* group);
555 /*
556 * If shown is true the client is mapped and raised, if false
557 * the client is unmapped and hidden, this function is called
558 * when the tabbing group of the client switches its visible
559 * client.
560 */
561 void setClientShown(bool shown);
562 /*
563 * When a click is done in the decoration and it calls the group
564 * to change the visible client it starts to move-resize the new
565 * client, this function stops it.
566 */
567 void dontMoveResize();
568 bool isCurrentTab() const;
569
570 /**
571 * Whether or not the window has a strut that expands through the invisible area of
572 * an xinerama setup where the monitors are not the same resolution.
573 */
574 bool hasOffscreenXineramaStrut() const;
575
576 bool isMove() const {
577 return moveResizeMode && mode == PositionCenter;
578 }
579 bool isResize() const {
580 return moveResizeMode && mode != PositionCenter;
581 }
582
583 // Decorations <-> Effects
584 PaintRedirector *decorationPaintRedirector() {
585 return paintRedirector;
586 }
587
588 int paddingLeft() const {
589 return padding_left;
590 }
591 int paddingRight() const {
592 return padding_right;
593 }
594 int paddingTop() const {
595 return padding_top;
596 }
597 int paddingBottom() const {
598 return padding_bottom;
599 }
600
601 QRect decorationRect() const;
602
603 QRect transparentRect() const;
604
605 QRegion decorationPendingRegion() const;
606
607 bool decorationHasAlpha() const;
608
609 Position titlebarPosition() const;
610
611 enum CoordinateMode {
612 DecorationRelative, // Relative to the top left corner of the decoration
613 WindowRelative // Relative to the top left corner of the window
614 };
615 void layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom, CoordinateMode mode) const;
616
617 QWeakPointer<TabBox::TabBoxClientImpl> tabBoxClient() const {
618 return m_tabBoxClient.toWeakRef();
619 }
620 bool isFirstInTabBox() const {
621 return m_firstInTabBox;
622 }
623 void setFirstInTabBox(bool enable) {
624 m_firstInTabBox = enable;
625 }
626 void updateFirstInTabBox();
627
628 //sets whether the client should be treated as a SessionInteract window
629 void setSessionInteract(bool needed);
630 virtual bool isClient() const;
631 // a helper for the workspace window packing. tests for screen validity and updates since in maximization case as with normal moving
632 void packTo(int left, int top);
633
634#ifdef KWIN_BUILD_KAPPMENU
635 // Used by workspace
636 void emitShowRequest() {
637 emit showRequest();
638 }
639 void emitMenuHidden() {
640 emit menuHidden();
641 }
642 void setAppMenuAvailable();
643 void setAppMenuUnavailable();
644 void showApplicationMenu(const QPoint&);
645 bool menuAvailable() {
646 return m_menuAvailable;
647 }
648#endif
649
650 template <typename T>
651 void print(T &stream) const;
652
653public slots:
654 void closeWindow();
655 void updateCaption();
656
657private slots:
658 void autoRaise();
659 void shadeHover();
660 void shadeUnhover();
661 void shortcutActivated();
662 void delayedMoveResize();
663
664private:
665 friend class Bridge; // FRAME
666 virtual void processMousePressEvent(QMouseEvent* e);
667
668private:
669 // Use Workspace::createClient()
670 virtual ~Client(); ///< Use destroyClient() or releaseWindow()
671
672 Position mousePosition(const QPoint&) const;
673 void updateCursor();
674
675 // Handlers for X11 events
676 bool mapRequestEvent(XMapRequestEvent* e);
677 void unmapNotifyEvent(XUnmapEvent* e);
678 void destroyNotifyEvent(XDestroyWindowEvent* e);
679 void configureRequestEvent(XConfigureRequestEvent* e);
680 virtual void propertyNotifyEvent(XPropertyEvent* e);
681 void clientMessageEvent(XClientMessageEvent* e);
682 void enterNotifyEvent(XCrossingEvent* e);
683 void leaveNotifyEvent(XCrossingEvent* e);
684 void focusInEvent(XFocusInEvent* e);
685 void focusOutEvent(XFocusOutEvent* e);
686 virtual void damageNotifyEvent();
687
688 bool buttonPressEvent(xcb_window_t w, int button, int state, int x, int y, int x_root, int y_root);
689 bool buttonReleaseEvent(xcb_window_t w, int button, int state, int x, int y, int x_root, int y_root);
690 bool motionNotifyEvent(xcb_window_t w, int state, int x, int y, int x_root, int y_root);
691 void checkQuickTilingMaximizationZones(int xroot, int yroot);
692
693 bool processDecorationButtonPress(int button, int state, int x, int y, int x_root, int y_root,
694 bool ignoreMenu = false);
695 Client* findAutogroupCandidate() const;
696 void resetShowingDesktop(bool keep_hidden);
697
698protected:
699 virtual void debug(QDebug& stream) const;
700 virtual bool shouldUnredirect() const;
701
702private slots:
703 void delayedSetShortcut();
704 void performMoveResize();
705 void removeSyncSupport();
706 void pingTimeout();
707
708 //Signals for the scripting interface
709 //Signals make an excellent way for communication
710 //in between objects as compared to simple function
711 //calls
712signals:
713 void clientManaging(KWin::Client*);
714 void clientFullScreenSet(KWin::Client*, bool, bool);
715 void clientMaximizedStateChanged(KWin::Client*, KDecorationDefines::MaximizeMode);
716 void clientMaximizedStateChanged(KWin::Client* c, bool h, bool v);
717 void clientMinimized(KWin::Client* client, bool animate);
718 void clientUnminimized(KWin::Client* client, bool animate);
719 void clientStartUserMovedResized(KWin::Client*);
720 void clientStepUserMovedResized(KWin::Client *, const QRect&);
721 void clientFinishUserMovedResized(KWin::Client*);
722 void activeChanged();
723 void captionChanged();
724 void desktopChanged();
725 void desktopPresenceChanged(KWin::Client*, int); // to be forwarded by Workspace
726 void fullScreenChanged();
727 void transientChanged();
728 void modalChanged();
729 void shadeChanged();
730 void keepAboveChanged(bool);
731 void keepBelowChanged(bool);
732 void minimizedChanged();
733 void moveResizedChanged();
734 void iconChanged();
735 void skipSwitcherChanged();
736 void skipTaskbarChanged();
737 void skipPagerChanged();
738 /**
739 * Emitted whenever the Client's TabGroup changed. That is whenever the Client is moved to
740 * another group, but not when a Client gets added or removed to the Client's ClientGroup.
741 **/
742 void tabGroupChanged();
743
744 /**
745 * Emitted whenever the Client want to show it menu
746 */
747 void showRequest();
748 /**
749 * Emitted whenever the Client's menu is closed
750 */
751 void menuHidden();
752 /**
753 * Emitted whenever the Client's menu is available
754 **/
755 void appMenuAvailable();
756 /**
757 * Emitted whenever the Client's menu is unavailable
758 */
759 void appMenuUnavailable();
760
761 /**
762 * Emitted whenever the demands attention state changes.
763 **/
764 void demandsAttentionChanged();
765 /**
766 * Emitted whenever the Client's block compositing state changes.
767 **/
768 void blockingCompositingChanged(KWin::Client *client);
769
770private:
771 void exportMappingState(int s); // ICCCM 4.1.3.1, 4.1.4, NETWM 2.5.1
772 bool isManaged() const; ///< Returns false if this client is not yet managed
773 void updateAllowedActions(bool force = false);
774 QRect fullscreenMonitorsArea(NETFullscreenMonitors topology) const;
775 void changeMaximize(bool horizontal, bool vertical, bool adjust);
776 int checkFullScreenHack(const QRect& geom) const; // 0 - None, 1 - One xinerama screen, 2 - Full area
777 void updateFullScreenHack(const QRect& geom);
778 void getWmNormalHints();
779 void getMotifHints();
780 void getIcons();
781 void fetchName();
782 void fetchIconicName();
783 QString readName() const;
784 void setCaption(const QString& s, bool force = false);
785 bool hasTransientInternal(const Client* c, bool indirect, ConstClientList& set) const;
786 void finishWindowRules();
787 void setShortcutInternal(const KShortcut& cut);
788
789 void configureRequest(int value_mask, int rx, int ry, int rw, int rh, int gravity, bool from_tool);
790 NETExtendedStrut strut() const;
791 int checkShadeGeometry(int w, int h);
792 void blockGeometryUpdates(bool block);
793 void getSyncCounter();
794 void sendSyncRequest();
795 bool startMoveResize();
796 void finishMoveResize(bool cancel);
797 void leaveMoveResize();
798 void checkUnrestrictedMoveResize();
799 void handleMoveResize(int x, int y, int x_root, int y_root);
800 void startDelayedMoveResize();
801 void stopDelayedMoveResize();
802 void positionGeometryTip();
803 void grabButton(int mod);
804 void ungrabButton(int mod);
805 void resizeDecoration(const QSize& s);
806 void createDecoration(const QRect &oldgeom);
807
808 void pingWindow();
809 void killProcess(bool ask, xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME);
810 void updateUrgency();
811 static void sendClientMessage(xcb_window_t w, xcb_atom_t a, xcb_atom_t protocol,
812 long data1 = 0, long data2 = 0, long data3 = 0);
813
814 void embedClient(xcb_window_t w, const XWindowAttributes& attr);
815 void detectNoBorder();
816 void destroyDecoration();
817 void updateFrameExtents();
818
819 void internalShow();
820 void internalHide();
821 void internalKeep();
822 void map();
823 void unmap();
824 void updateHiddenPreview();
825
826 void updateInputShape();
827
828 xcb_timestamp_t readUserTimeMapTimestamp(const KStartupInfoId* asn_id, const KStartupInfoData* asn_data,
829 bool session) const;
830 xcb_timestamp_t readUserCreationTime() const;
831 void startupIdChanged();
832
833 void checkOffscreenPosition (QRect* geom, const QRect& screenArea);
834
835 void updateInputWindow();
836
837 bool tabTo(Client *other, bool behind, bool activate);
838
839 xcb_window_t m_client;
840 Xcb::Window m_wrapper;
841 KDecoration* decoration;
842 Bridge* bridge;
843 int desk;
844 QStringList activityList;
845 int m_activityUpdatesBlocked;
846 bool m_blockedActivityUpdatesRequireTransients;
847 bool buttonDown;
848 bool moveResizeMode;
849 Xcb::Window m_moveResizeGrabWindow;
850 bool move_resize_has_keyboard_grab;
851 bool unrestrictedMoveResize;
852 int moveResizeStartScreen;
853 static bool s_haveResizeEffect;
854 bool m_managed;
855
856 Position mode;
857 QPoint moveOffset;
858 QPoint invertedMoveOffset;
859 QRect moveResizeGeom;
860 QRect initialMoveResizeGeom;
861 XSizeHints xSizeHint;
862 void sendSyntheticConfigureNotify();
863 enum MappingState {
864 Withdrawn, ///< Not handled, as per ICCCM WithdrawnState
865 Mapped, ///< The frame is mapped
866 Unmapped, ///< The frame is not mapped
867 Kept ///< The frame should be unmapped, but is kept (For compositing)
868 };
869 MappingState mapping_state;
870
871 /** The quick tile mode of this window.
872 */
873 int quick_tile_mode;
874
875 void readTransient();
876 xcb_window_t verifyTransientFor(xcb_window_t transient_for, bool set);
877 void addTransient(Client* cl);
878 void removeTransient(Client* cl);
879 void removeFromMainClients();
880 void cleanGrouping();
881 void checkGroupTransients();
882 void setTransient(xcb_window_t new_transient_for_id);
883 Client* transient_for;
884 xcb_window_t m_transientForId;
885 xcb_window_t m_originalTransientForId;
886 ClientList transients_list; // SELI TODO: Make this ordered in stacking order?
887 ShadeMode shade_mode;
888 Client *shade_below;
889 uint active : 1;
890 uint deleting : 1; ///< True when doing cleanup and destroying the client
891 uint keep_above : 1; ///< NET::KeepAbove (was stays_on_top)
892 uint skip_taskbar : 1;
893 uint original_skip_taskbar : 1; ///< Unaffected by KWin
894 uint Pdeletewindow : 1; ///< Does the window understand the DeleteWindow protocol?
895 uint Ptakefocus : 1;///< Does the window understand the TakeFocus protocol?
896 uint Ptakeactivity : 1; ///< Does it support _NET_WM_TAKE_ACTIVITY
897 uint Pcontexthelp : 1; ///< Does the window understand the ContextHelp protocol?
898 uint Pping : 1; ///< Does it support _NET_WM_PING?
899 uint input : 1; ///< Does the window want input in its wm_hints
900 uint skip_pager : 1;
901 uint skip_switcher : 1;
902 uint motif_may_resize : 1;
903 uint motif_may_move : 1;
904 uint motif_may_close : 1;
905 uint keep_below : 1; ///< NET::KeepBelow
906 uint minimized : 1;
907 uint hidden : 1; ///< Forcibly hidden by calling hide()
908 uint modal : 1; ///< NET::Modal
909 uint noborder : 1;
910 uint app_noborder : 1; ///< App requested no border via window type, shape extension, etc.
911 uint motif_noborder : 1; ///< App requested no border via Motif WM hints
912 uint urgency : 1; ///< XWMHints, UrgencyHint
913 uint ignore_focus_stealing : 1; ///< Don't apply focus stealing prevention to this client
914 uint demands_attention : 1;
915 bool blocks_compositing;
916 WindowRules client_rules;
917 void getWMHints();
918 void readIcons();
919 void getWindowProtocols();
920 QPixmap icon_pix;
921 QPixmap miniicon_pix;
922 QPixmap bigicon_pix;
923 QPixmap hugeicon_pix;
924 Qt::CursorShape m_cursor;
925 // DON'T reorder - Saved to config files !!!
926 enum FullScreenMode {
927 FullScreenNone,
928 FullScreenNormal,
929 FullScreenHack ///< Non-NETWM fullscreen (noborder and size of desktop)
930 };
931 FullScreenMode fullscreen_mode;
932 MaximizeMode max_mode;
933 QRect geom_restore;
934 QRect geom_fs_restore;
935 QTimer* autoRaiseTimer;
936 QTimer* shadeHoverTimer;
937 QTimer* delayedMoveResizeTimer;
938 xcb_colormap_t m_colormap;
939 QString cap_normal, cap_iconic, cap_suffix, cap_deco;
940 Group* in_group;
941 xcb_window_t m_windowGroup;
942 TabGroup* tab_group;
943 Layer in_layer;
944 QTimer* ping_timer;
945 qint64 m_killHelperPID;
946 xcb_timestamp_t m_pingTimestamp;
947 xcb_timestamp_t m_userTime;
948 unsigned long allowed_actions;
949 QSize client_size;
950 int block_geometry_updates; // > 0 = New geometry is remembered, but not actually set
951 enum PendingGeometry_t {
952 PendingGeometryNone,
953 PendingGeometryNormal,
954 PendingGeometryForced
955 };
956 PendingGeometry_t pending_geometry_update;
957 QRect geom_before_block;
958 QRect deco_rect_before_block;
959 bool shade_geometry_change;
960#ifdef HAVE_XSYNC
961 struct {
962 XSyncCounter counter;
963 XSyncValue value;
964 XSyncAlarm alarm;
965 QTimer *timeout, *failsafeTimeout;
966 bool isPending;
967 } syncRequest;
968#endif
969 int border_left, border_right, border_top, border_bottom;
970 int padding_left, padding_right, padding_top, padding_bottom;
971 QRegion _mask;
972 static bool check_active_modal; ///< \see Client::checkActiveModal()
973 KShortcut _shortcut;
974 int sm_stacking_order;
975 friend struct FetchNameInternalPredicate;
976 friend struct ResetupRulesProcedure;
977 friend class GeometryUpdatesBlocker;
978 PaintRedirector* paintRedirector;
979 QSharedPointer<TabBox::TabBoxClientImpl> m_tabBoxClient;
980 bool m_firstInTabBox;
981
982 bool electricMaximizing;
983 QuickTileMode electricMode;
984
985 friend bool performTransiencyCheck();
986
987 void checkActivities();
988 bool activitiesDefined; //whether the x property was actually set
989
990 bool needsSessionInteract;
991 bool needsXWindowMove;
992
993#ifdef KWIN_BUILD_KAPPMENU
994 bool m_menuAvailable;
995#endif
996 Xcb::Window m_decoInputExtent;
997 QPoint input_offset;
998};
999
1000/**
1001 * Helper for Client::blockGeometryUpdates() being called in pairs (true/false)
1002 */
1003class GeometryUpdatesBlocker
1004{
1005public:
1006 explicit GeometryUpdatesBlocker(Client* c)
1007 : cl(c) {
1008 cl->blockGeometryUpdates(true);
1009 }
1010 ~GeometryUpdatesBlocker() {
1011 cl->blockGeometryUpdates(false);
1012 }
1013
1014private:
1015 Client* cl;
1016};
1017
1018inline xcb_window_t Client::wrapperId() const
1019{
1020 return m_wrapper;
1021}
1022
1023inline xcb_window_t Client::decorationId() const
1024{
1025 if (decoration) {
1026 return decoration->widget()->winId();
1027 }
1028 return XCB_WINDOW_NONE;
1029}
1030
1031inline const Client* Client::transientFor() const
1032{
1033 return transient_for;
1034}
1035
1036inline Client* Client::transientFor()
1037{
1038 return transient_for;
1039}
1040
1041inline bool Client::groupTransient() const
1042{
1043 return m_transientForId == rootWindow();
1044}
1045
1046// Needed because verifyTransientFor() may set transient_for_id to root window,
1047// if the original value has a problem (window doesn't exist, etc.)
1048inline bool Client::wasOriginallyGroupTransient() const
1049{
1050 return m_originalTransientForId == rootWindow();
1051}
1052
1053inline bool Client::isTransient() const
1054{
1055 return m_transientForId != XCB_WINDOW_NONE;
1056}
1057
1058inline const ClientList& Client::transients() const
1059{
1060 return transients_list;
1061}
1062
1063inline const Group* Client::group() const
1064{
1065 return in_group;
1066}
1067
1068inline Group* Client::group()
1069{
1070 return in_group;
1071}
1072
1073inline TabGroup* Client::tabGroup() const
1074{
1075 return tab_group;
1076}
1077
1078inline bool Client::isMinimized() const
1079{
1080 return minimized;
1081}
1082
1083inline bool Client::isActive() const
1084{
1085 return active;
1086}
1087
1088inline bool Client::isShown(bool shaded_is_shown) const
1089{
1090 return !isMinimized() && (!isShade() || shaded_is_shown) && !hidden &&
1091 (!tabGroup() || tabGroup()->current() == this);
1092}
1093
1094inline bool Client::isHiddenInternal() const
1095{
1096 return hidden;
1097}
1098
1099inline bool Client::isShade() const
1100{
1101 return shade_mode == ShadeNormal;
1102}
1103
1104inline ShadeMode Client::shadeMode() const
1105{
1106 return shade_mode;
1107}
1108
1109inline QPixmap Client::icon() const
1110{
1111 return icon_pix;
1112}
1113
1114inline QPixmap Client::miniIcon() const
1115{
1116 return miniicon_pix;
1117}
1118
1119inline QPixmap Client::bigIcon() const
1120{
1121 return bigicon_pix;
1122}
1123
1124inline QPixmap Client::hugeIcon() const
1125{
1126 return hugeicon_pix;
1127}
1128
1129inline QRect Client::geometryRestore() const
1130{
1131 return geom_restore;
1132}
1133
1134inline Client::MaximizeMode Client::maximizeMode() const
1135{
1136 return max_mode;
1137}
1138
1139inline Client::QuickTileMode Client::quickTileMode() const
1140{
1141 return (Client::QuickTileMode)quick_tile_mode;
1142}
1143
1144inline bool Client::skipTaskbar(bool from_outside) const
1145{
1146 return from_outside ? original_skip_taskbar : skip_taskbar;
1147}
1148
1149inline bool Client::skipPager() const
1150{
1151 return skip_pager;
1152}
1153
1154inline bool Client::skipSwitcher() const
1155{
1156 return skip_switcher;
1157}
1158
1159inline bool Client::keepAbove() const
1160{
1161 return keep_above;
1162}
1163
1164inline bool Client::keepBelow() const
1165{
1166 return keep_below;
1167}
1168
1169inline bool Client::isFullScreen() const
1170{
1171 return fullscreen_mode != FullScreenNone;
1172}
1173
1174inline bool Client::isModal() const
1175{
1176 return modal;
1177}
1178
1179inline bool Client::hasNETSupport() const
1180{
1181 return info->hasNETSupport();
1182}
1183
1184inline xcb_colormap_t Client::colormap() const
1185{
1186 return m_colormap;
1187}
1188
1189inline void Client::invalidateLayer()
1190{
1191 in_layer = UnknownLayer;
1192}
1193
1194inline int Client::sessionStackingOrder() const
1195{
1196 return sm_stacking_order;
1197}
1198
1199inline bool Client::isManaged() const
1200{
1201 return m_managed;
1202}
1203
1204inline QPoint Client::clientPos() const
1205{
1206 return QPoint(border_left, border_top);
1207}
1208
1209inline QSize Client::clientSize() const
1210{
1211 return client_size;
1212}
1213
1214inline void Client::setGeometry(const QRect& r, ForceGeometry_t force)
1215{
1216 setGeometry(r.x(), r.y(), r.width(), r.height(), force);
1217}
1218
1219inline void Client::move(const QPoint& p, ForceGeometry_t force)
1220{
1221 move(p.x(), p.y(), force);
1222}
1223
1224inline void Client::plainResize(const QSize& s, ForceGeometry_t force)
1225{
1226 plainResize(s.width(), s.height(), force);
1227}
1228
1229inline void Client::resizeWithChecks(const QSize& s, ForceGeometry_t force)
1230{
1231 resizeWithChecks(s.width(), s.height(), force);
1232}
1233
1234inline bool Client::hasUserTimeSupport() const
1235{
1236 return info->userTime() != -1U;
1237}
1238
1239inline const WindowRules* Client::rules() const
1240{
1241 return &client_rules;
1242}
1243
1244inline xcb_window_t Client::moveResizeGrabWindow() const
1245{
1246 return m_moveResizeGrabWindow;
1247}
1248
1249inline KShortcut Client::shortcut() const
1250{
1251 return _shortcut;
1252}
1253
1254inline void Client::removeRule(Rules* rule)
1255{
1256 client_rules.remove(rule);
1257}
1258
1259inline bool Client::hiddenPreview() const
1260{
1261 return mapping_state == Kept;
1262}
1263
1264template <typename T>
1265inline void Client::print(T &stream) const
1266{
1267 stream << "\'ID:" << window() << ";WMCLASS:" << resourceClass() << ":"
1268 << resourceName() << ";Caption:" << caption() << "\'";
1269}
1270
1271KWIN_COMPARE_PREDICATE(WrapperIdMatchPredicate, Client, Window, cl->wrapperId() == value);
1272KWIN_COMPARE_PREDICATE(InputIdMatchPredicate, Client, Window, cl->inputId() == value);
1273
1274} // namespace
1275Q_DECLARE_METATYPE(KWin::Client*)
1276Q_DECLARE_METATYPE(QList<KWin::Client*>)
1277
1278#endif
1279