1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *********************************************************************/
25 #include <config-X11.h>
32 #include <kshortcut.h>
35 #include <X11/Xutil.h>
40 #include "workspace.h"
41 #include "kdecoration.h"
46 #include <X11/extensions/sync.h>
51 class KStartupInfoData
;
65 Client( Workspace
*ws
);
66 Window
wrapperId() const;
67 Window
decorationId() const;
69 const Client
* transientFor() const;
70 Client
* transientFor();
71 bool isTransient() const;
72 bool groupTransient() const;
73 bool wasOriginallyGroupTransient() const;
74 ClientList
mainClients() const; // call once before loop , is not indirect
75 bool hasTransient( const Client
* c
, bool indirect
) const;
76 const ClientList
& transients() const; // is not indirect
77 void checkTransient( Window w
);
78 Client
* findModal( bool allow_itself
= false );
79 const Group
* group() const;
81 void checkGroup( Group
* gr
= NULL
, bool force
= false );
82 void changeClientLeaderGroup( Group
* gr
);
83 const WindowRules
* rules() const;
84 void removeRule( Rules
* r
);
85 void setupWindowRules( bool ignore_temporary
);
86 void applyWindowRules();
87 void updateWindowRules();
89 // returns true for "special" windows and false for windows which are "normal"
90 // (normal=window which has a border, can be moved by the user, can be closed, etc.)
91 // true for Desktop, Dock, Splash, Override and TopMenu (and Toolbar??? - for now)
92 // false for Normal, Dialog, Utility and Menu (and Toolbar??? - not yet) TODO
93 bool isSpecialWindow() const;
94 bool hasNETSupport() const;
96 QSize
minSize() const;
97 QSize
maxSize() const;
98 virtual QPoint
clientPos() const; // inside of geometry()
99 virtual QSize
clientSize() const;
101 bool windowEvent( XEvent
* e
);
102 virtual bool eventFilter( QObject
* o
, QEvent
* e
);
104 void syncEvent( XSyncAlarmNotifyEvent
* e
);
107 bool manage( Window w
, bool isMapped
);
108 void releaseWindow( bool on_shutdown
= false );
109 void destroyClient();
111 enum Sizemode
// how to resize the window in order to obey constains (mainly aspect ratios)
114 SizemodeFixedW
, // try not to affect width
115 SizemodeFixedH
, // try not to affect height
116 SizemodeMax
// try not to make it larger in either direction
118 QSize
adjustedSize( const QSize
&, Sizemode mode
= SizemodeAny
) const;
119 QSize
adjustedSize() const;
121 QPixmap
icon() const;
122 QPixmap
miniIcon() const;
124 bool isActive() const;
125 void setActive( bool );
127 virtual int desktop() const;
128 void setDesktop( int );
129 void setOnAllDesktops( bool set
);
131 bool isOnScreen( int screen
) const; // true if it's at least partially there
132 int screen() const; // the screen where the center is
134 // !isMinimized() && not hidden, i.e. normally visible on some virtual desktop
135 bool isShown( bool shaded_is_shown
) const;
136 bool isHiddenInternal() const; // for compositing
138 bool isShade() const; // true only for ShadeNormal
139 ShadeMode
shadeMode() const; // prefer isShade()
140 void setShade( ShadeMode mode
);
141 bool isShadeable() const;
143 bool isMinimized() const;
144 bool isMaximizable() const;
145 QRect
geometryRestore() const;
146 MaximizeMode
maximizeModeRestore() const;
147 MaximizeMode
maximizeMode() const;
148 bool isMinimizable() const;
149 void setMaximize( bool vertically
, bool horizontally
);
150 QRect
iconGeometry() const;
152 void setFullScreen( bool set
, bool user
);
153 bool isFullScreen() const;
154 bool isFullScreenable( bool fullscreen_hack
= false ) const;
155 bool userCanSetFullScreen() const;
156 QRect
geometryFSRestore() const { return geom_fs_restore
; } // only for session saving
157 int fullScreenMode() const { return fullscreen_mode
; } // only for session saving
159 bool isUserNoBorder() const;
160 void setUserNoBorder( bool set
);
161 bool userCanSetNoBorder() const;
162 bool noBorder() const;
164 bool skipTaskbar( bool from_outside
= false ) const;
165 void setSkipTaskbar( bool set
, bool from_outside
);
167 bool skipPager() const;
168 void setSkipPager( bool );
170 bool keepAbove() const;
171 void setKeepAbove( bool );
172 bool keepBelow() const;
173 void setKeepBelow( bool );
175 Layer
belongsToLayer() const;
176 void invalidateLayer();
177 int sessionStackingOrder() const;
179 void setModal( bool modal
);
180 bool isModal() const;
182 // auxiliary functions, depend on the windowType
183 bool wantsTabFocus() const;
184 bool wantsInput() const;
186 bool isResizable() const;
187 bool isMovable() const;
188 bool isCloseable() const; // may be closed by the user (may have a close button)
190 void takeActivity( int flags
, bool handled
, allowed_t
); // takes ActivityFlags as arg (in utils.h)
191 void takeFocus( allowed_t
);
192 void demandAttention( bool set
= true );
194 void setMask( const QRegion
& r
, int mode
= X::Unsorted
);
195 QRegion
mask() const;
197 void updateDecoration( bool check_workspace_pos
, bool force
= false );
198 void checkBorderSizes();
202 void setGeometry( int x
, int y
, int w
, int h
, ForceGeometry_t force
= NormalGeometrySet
);
203 void setGeometry( const QRect
& r
, ForceGeometry_t force
= NormalGeometrySet
);
204 void move( int x
, int y
, ForceGeometry_t force
= NormalGeometrySet
);
205 void move( const QPoint
& p
, ForceGeometry_t force
= NormalGeometrySet
);
206 // plainResize() simply resizes
207 void plainResize( int w
, int h
, ForceGeometry_t force
= NormalGeometrySet
);
208 void plainResize( const QSize
& s
, ForceGeometry_t force
= NormalGeometrySet
);
209 // resizeWithChecks() resizes according to gravity, and checks workarea position
210 void resizeWithChecks( int w
, int h
, ForceGeometry_t force
= NormalGeometrySet
);
211 void resizeWithChecks( const QSize
& s
, ForceGeometry_t force
= NormalGeometrySet
);
212 void keepInArea( QRect area
, bool partial
= false );
214 void growHorizontal();
215 void shrinkHorizontal();
217 void shrinkVertical();
219 bool providesContextHelp() const;
220 KShortcut
shortcut() const;
221 void setShortcut( const QString
& cut
);
223 bool performMouseCommand( Options::MouseCommand
, const QPoint
&globalPos
, bool handled
= false );
225 QRect
adjustedClientArea( const QRect
& desktop
, const QRect
& area
) const;
227 Colormap
colormap() const;
229 // updates visibility depending on being shaded, virtual desktop, etc.
230 void updateVisibility();
231 // hides a client - basically like minimize, but without effects, it's simply hidden
232 void hideClient( bool hide
);
233 bool hiddenPreview() const; // window is mapped in order to get a window pixmap
235 QString
caption( bool full
= true ) const;
236 void updateCaption();
238 void keyPressEvent( uint key_code
); // FRAME ??
239 void updateMouseGrab();
240 Window
moveResizeGrabWindow() const;
242 const QPoint
calculateGravitation( bool invert
, int gravity
= 0 ) const; // FRAME public?
244 void NETMoveResize( int x_root
, int y_root
, NET::Direction direction
);
245 void NETMoveResizeWindow( int flags
, int x
, int y
, int width
, int height
);
246 void restackWindow( Window above
, int detail
, NET::RequestSource source
, Time timestamp
, bool send_event
= false );
248 void gotPing( Time timestamp
);
250 void checkWorkspacePosition();
251 void updateUserTime( Time time
= CurrentTime
);
252 Time
userTime() const;
253 bool hasUserTimeSupport() const;
254 bool ignoreFocusStealing() const;
257 static void deleteClient( Client
* c
, allowed_t
);
259 static bool belongToSameApplication( const Client
* c1
, const Client
* c2
, bool active_hack
= false );
260 static bool sameAppWindowRoleMatch( const Client
* c1
, const Client
* c2
, bool active_hack
);
261 static void readIcons( Window win
, QPixmap
* icon
, QPixmap
* miniicon
);
263 void minimize( bool avoid_animation
= false );
264 void unminimize( bool avoid_animation
= false );
267 void maximize( MaximizeMode
);
269 void showContextHelp();
270 void cancelShadeHover();
271 void cancelAutoRaise();
272 void checkActiveModal();
273 bool hasStrut() const;
277 return moveResizeMode
&& mode
== PositionCenter
;
279 bool isResize() const
281 return moveResizeMode
&& mode
!= PositionCenter
;
287 void shortcutActivated();
288 void delayedMoveResize();
291 friend class Bridge
; // FRAME
292 virtual void processMousePressEvent( QMouseEvent
* e
);
294 private: // TODO cleanup the order of things in the .h file
295 // use Workspace::createClient()
296 virtual ~Client(); // use destroyClient() or releaseWindow()
298 Position
mousePosition( const QPoint
& ) const;
302 void drawbound( const QRect
& geom
);
304 void doDrawbound( const QRect
& geom
, bool clear
);
306 // handlers for X11 events
307 bool mapRequestEvent( XMapRequestEvent
* e
);
308 void unmapNotifyEvent( XUnmapEvent
*e
);
309 void destroyNotifyEvent( XDestroyWindowEvent
*e
);
310 void configureRequestEvent( XConfigureRequestEvent
* e
);
311 virtual void propertyNotifyEvent( XPropertyEvent
* e
);
312 void clientMessageEvent( XClientMessageEvent
* e
);
313 void enterNotifyEvent( XCrossingEvent
* e
);
314 void leaveNotifyEvent( XCrossingEvent
* e
);
315 void focusInEvent( XFocusInEvent
* e
);
316 void focusOutEvent( XFocusOutEvent
* e
);
318 virtual void damageNotifyEvent( XDamageNotifyEvent
* e
);
321 bool buttonPressEvent( Window w
, int button
, int state
, int x
, int y
, int x_root
, int y_root
);
322 bool buttonReleaseEvent( Window w
, int button
, int state
, int x
, int y
, int x_root
, int y_root
);
323 bool motionNotifyEvent( Window w
, int state
, int x
, int y
, int x_root
, int y_root
);
325 void processDecorationButtonPress( int button
, int state
, int x
, int y
, int x_root
, int y_root
);
328 virtual void debug( kdbgstream
& stream
) const;
332 void processKillerExited();
333 void demandAttentionKNotify();
337 void setMappingState( int s
); // ICCCM 4.1.3.1, 4.1.4 , NETWM 2.5.1
338 int mappingState() const;
339 bool isIconicState() const;
340 bool isNormalState() const;
341 bool isManaged() const; // returns false if this client is not yet managed
342 void updateAllowedActions( bool force
= false );
343 QSize
sizeForClientSize( const QSize
&, Sizemode mode
= SizemodeAny
, bool noframe
= false ) const;
344 void changeMaximize( bool horizontal
, bool vertical
, bool adjust
);
345 void checkMaximizeGeometry();
346 int checkFullScreenHack( const QRect
& geom
) const; // 0 - none, 1 - one xinerama screen, 2 - full area
347 void updateFullScreenHack( const QRect
& geom
);
348 void getWmNormalHints();
349 void getMotifHints();
352 void fetchIconicName();
353 QString
readName() const;
354 void setCaption( const QString
& s
, bool force
= false );
355 bool hasTransientInternal( const Client
* c
, bool indirect
, ConstClientList
& set
) const;
356 void finishWindowRules();
357 void setShortcutInternal( const KShortcut
& cut
);
359 void updateWorkareaDiffs();
360 void checkDirection( int new_diff
, int old_diff
, QRect
& rect
, const QRect
& area
);
361 static int computeWorkareaDiff( int left
, int right
, int a_left
, int a_right
);
362 void configureRequest( int value_mask
, int rx
, int ry
, int rw
, int rh
, int gravity
, bool from_tool
);
363 NETExtendedStrut
strut() const;
364 int checkShadeGeometry( int w
, int h
);
365 void blockGeometryUpdates( bool block
);
366 void getSyncCounter();
367 void sendSyncRequest();
369 bool startMoveResize();
370 void finishMoveResize( bool cancel
);
371 void leaveMoveResize();
372 void checkUnrestrictedMoveResize();
373 void handleMoveResize( int x
, int y
, int x_root
, int y_root
);
374 void startDelayedMoveResize();
375 void stopDelayedMoveResize();
376 void positionGeometryTip();
377 void grabButton( int mod
);
378 void ungrabButton( int mod
);
379 void resetMaximize();
380 void resizeDecoration( const QSize
& s
);
381 void performMoveResize();
384 void killProcess( bool ask
, Time timestamp
= CurrentTime
);
385 void updateUrgency();
386 static void sendClientMessage( Window w
, Atom a
, Atom protocol
,
387 long data1
= 0, long data2
= 0, long data3
= 0 );
389 void embedClient( Window w
, const XWindowAttributes
&attr
);
390 void detectNoBorder();
391 void destroyDecoration();
392 void updateFrameExtents();
394 void rawShow(); // just shows it
395 void rawHide(); // just hides it
396 void setHiddenPreview( bool set
, allowed_t
);
397 void updateInputShape();
399 Time
readUserTimeMapTimestamp( const KStartupInfoId
* asn_id
, const KStartupInfoData
* asn_data
,
400 bool session
) const;
401 Time
readUserCreationTime() const;
402 void startupIdChanged();
406 KDecoration
* decoration
;
411 bool move_faked_activity
;
412 Window move_resize_grab_window
;
413 bool move_resize_has_keyboard_grab
;
414 bool unrestrictedMoveResize
;
418 QPoint invertedMoveOffset
;
419 QRect moveResizeGeom
;
420 QRect initialMoveResizeGeom
;
421 XSizeHints xSizeHint
;
422 void sendSyntheticConfigureNotify();
424 void readTransient();
425 Window
verifyTransientFor( Window transient_for
, bool set
);
426 void addTransient( Client
* cl
);
427 void removeTransient( Client
* cl
);
428 void removeFromMainClients();
429 void cleanGrouping();
430 void checkGroupTransients();
431 void setTransient( Window new_transient_for_id
);
432 Client
* transient_for
;
433 Window transient_for_id
;
434 Window original_transient_for_id
;
435 ClientList transients_list
; // SELI make this ordered in stacking order?
436 ShadeMode shade_mode
;
438 uint deleting
: 1; // true when doing cleanup and destroying the client
439 uint keep_above
: 1; // NET::KeepAbove (was stays_on_top)
440 uint skip_taskbar
:1;
441 uint original_skip_taskbar
:1; // unaffected by KWin
442 uint Pdeletewindow
:1; // does the window understand the DeleteWindow protocol?
443 uint Ptakefocus
:1;// does the window understand the TakeFocus protocol?
444 uint Ptakeactivity
: 1; // does it support _NET_WM_TAKE_ACTIVITY
445 uint Pcontexthelp
: 1; // does the window understand the ContextHelp protocol?
446 uint Pping
: 1; // does it support _NET_WM_PING?
447 uint input
:1; // does the window want input in its wm_hints
449 uint motif_noborder
: 1;
450 uint motif_may_resize
: 1;
451 uint motif_may_move
:1;
452 uint motif_may_close
: 1;
453 uint keep_below
: 1; // NET::KeepBelow
455 uint hidden
: 1; // forcibly hidden by calling hide()
456 uint modal
: 1; // NET::Modal
458 uint user_noborder
: 1;
459 uint urgency
: 1; // XWMHints, UrgencyHint
460 uint ignore_focus_stealing
: 1; // don't apply focus stealing prevention to this client
461 uint demands_attention
: 1;
462 uint hidden_preview
: 1; // mapped only to get a window pixmap for compositing
463 uint raw_shown
: 1; // for use in rawShow()/rawHide()
464 WindowRules client_rules
;
467 void getWindowProtocols();
469 QPixmap miniicon_pix
;
471 // FullScreenHack - non-NETWM fullscreen (noborder,size of desktop)
472 // DON'T reorder - saved to config files !!!
473 enum FullScreenMode
{ FullScreenNone
, FullScreenNormal
, FullScreenHack
};
474 FullScreenMode fullscreen_mode
;
475 MaximizeMode max_mode
;
477 QRect geom_fs_restore
;
478 MaximizeMode maxmode_restore
;
479 int workarea_diff_x
, workarea_diff_y
;
480 QTimer
* autoRaiseTimer
;
481 QTimer
* shadeHoverTimer
;
482 QTimer
* delayedMoveResizeTimer
;
484 QString cap_normal
, cap_iconic
, cap_suffix
;
489 QProcess
* process_killer
;
492 unsigned long allowed_actions
;
494 int block_geometry_updates
; // >0 - new geometry is remembered, but not actually set
495 enum PendingGeometry_t
{ PendingGeometryNone
, PendingGeometryNormal
, PendingGeometryForced
};
496 PendingGeometry_t pending_geometry_update
;
497 QRect geom_before_block
;
498 bool shade_geometry_change
;
500 XSyncCounter sync_counter
;
501 XSyncValue sync_counter_value
;
502 XSyncAlarm sync_alarm
;
504 QTimer
* sync_timeout
;
505 bool sync_resize_pending
;
506 int border_left
, border_right
, border_top
, border_bottom
;
508 static bool check_active_modal
; // see Client::checkActiveModal()
510 int sm_stacking_order
;
511 friend struct FetchNameInternalPredicate
;
512 friend struct CheckIgnoreFocusStealingProcedure
;
513 friend struct ResetupRulesProcedure
;
514 friend class GeometryUpdatesBlocker
;
515 QTimer
* demandAttentionKNotifyTimer
;
517 friend bool performTransiencyCheck();
520 // helper for Client::blockGeometryUpdates() being called in pairs (true/false)
521 class GeometryUpdatesBlocker
524 GeometryUpdatesBlocker( Client
* c
)
525 : cl( c
) { cl
->blockGeometryUpdates( true ); }
526 ~GeometryUpdatesBlocker()
527 { cl
->blockGeometryUpdates( false ); }
533 // NET WM Protocol handler class
534 class WinInfo
: public NETWinInfo
537 typedef KWin::Client Client
; // because of NET::Client
539 WinInfo( Client
* c
, Display
* display
, Window window
,
540 Window rwin
, const unsigned long pr
[], int pr_size
);
541 virtual void changeDesktop(int desktop
);
542 virtual void changeState( unsigned long state
, unsigned long mask
);
548 inline Window
Client::wrapperId() const
553 inline Window
Client::decorationId() const
555 return decoration
!= NULL
? decoration
->widget()->winId() : None
;
558 inline const Client
* Client::transientFor() const
560 return transient_for
;
563 inline Client
* Client::transientFor()
565 return transient_for
;
568 inline bool Client::groupTransient() const
570 return transient_for_id
== rootWindow();
573 // needed because verifyTransientFor() may set transient_for_id to root window,
574 // if the original value has a problem (window doesn't exist, etc.)
575 inline bool Client::wasOriginallyGroupTransient() const
577 return original_transient_for_id
== rootWindow();
580 inline bool Client::isTransient() const
582 return transient_for_id
!= None
;
585 inline const ClientList
& Client::transients() const
587 return transients_list
;
590 inline const Group
* Client::group() const
595 inline Group
* Client::group()
600 inline int Client::mappingState() const
602 return mapping_state
;
606 bool Client::isMinimized() const
611 inline bool Client::isActive() const
617 bool Client::isShown( bool shaded_is_shown
) const
619 return !isMinimized() && ( !isShade() || shaded_is_shown
) && !hidden
;
623 bool Client::isHiddenInternal() const
629 bool Client::isShade() const
631 return shade_mode
== ShadeNormal
;
635 ShadeMode
Client::shadeMode() const
640 inline QPixmap
Client::icon() const
645 inline QPixmap
Client::miniIcon() const
650 inline QRect
Client::geometryRestore() const
655 inline Client::MaximizeMode
Client::maximizeModeRestore() const
657 return maxmode_restore
;
660 inline Client::MaximizeMode
Client::maximizeMode() const
665 inline bool Client::skipTaskbar( bool from_outside
) const
667 return from_outside
? original_skip_taskbar
: skip_taskbar
;
670 inline bool Client::skipPager() const
675 inline bool Client::keepAbove() const
680 inline bool Client::keepBelow() const
685 inline bool Client::isFullScreen() const
687 return fullscreen_mode
!= FullScreenNone
;
690 inline bool Client::isModal() const
695 inline bool Client::hasNETSupport() const
697 return info
->hasNETSupport();
700 inline Colormap
Client::colormap() const
705 inline void Client::invalidateLayer()
707 in_layer
= UnknownLayer
;
710 inline int Client::sessionStackingOrder() const
712 return sm_stacking_order
;
715 inline bool Client::isIconicState() const
717 return mapping_state
== IconicState
;
720 inline bool Client::isNormalState() const
722 return mapping_state
== NormalState
;
725 inline bool Client::isManaged() const
727 return mapping_state
!= WithdrawnState
;
730 inline QPoint
Client::clientPos() const
732 return QPoint( border_left
, border_top
);
735 inline QSize
Client::clientSize() const
740 inline void Client::setGeometry( const QRect
& r
, ForceGeometry_t force
)
742 setGeometry( r
.x(), r
.y(), r
.width(), r
.height(), force
);
745 inline void Client::move( const QPoint
& p
, ForceGeometry_t force
)
747 move( p
.x(), p
.y(), force
);
750 inline void Client::plainResize( const QSize
& s
, ForceGeometry_t force
)
752 plainResize( s
.width(), s
.height(), force
);
755 inline void Client::resizeWithChecks( const QSize
& s
, ForceGeometry_t force
)
757 resizeWithChecks( s
.width(), s
.height(), force
);
760 inline bool Client::hasUserTimeSupport() const
762 return info
->userTime() != -1U;
765 inline bool Client::ignoreFocusStealing() const
767 return ignore_focus_stealing
;
770 inline const WindowRules
* Client::rules() const
772 return &client_rules
;
775 KWIN_PROCEDURE( CheckIgnoreFocusStealingProcedure
, Client
, cl
->ignore_focus_stealing
= options
->checkIgnoreFocusStealing( cl
));
777 inline Window
Client::moveResizeGrabWindow() const
779 return move_resize_grab_window
;
782 inline KShortcut
Client::shortcut() const
787 inline void Client::removeRule( Rules
* rule
)
789 client_rules
.remove( rule
);
792 inline bool Client::hiddenPreview() const
794 return hidden_preview
;
797 KWIN_COMPARE_PREDICATE( WrapperIdMatchPredicate
, Client
, Window
, cl
->wrapperId() == value
);