00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef KWIN_WORKSPACE_H
00013 #define KWIN_WORKSPACE_H
00014
00015 #include <qtimer.h>
00016 #include <kshortcut.h>
00017 #include <qcursor.h>
00018 #include <netwm.h>
00019
00020 #include "KWinInterface.h"
00021 #include "utils.h"
00022 #include "kdecoration.h"
00023 #include "sm.h"
00024
00025 #include <X11/Xlib.h>
00026
00027 class QPopupMenu;
00028 class KConfig;
00029 class KGlobalAccel;
00030 class KStartupInfo;
00031 class KStartupInfoData;
00032
00033 namespace KWinInternal
00034 {
00035
00036 class Client;
00037 class TabBox;
00038 class PopupInfo;
00039 class RootInfo;
00040 class PluginMgr;
00041 class Placement;
00042
00043 class SystemTrayWindow
00044 {
00045 public:
00046 SystemTrayWindow()
00047 : win(0),winFor(0)
00048 {}
00049 SystemTrayWindow( WId w )
00050 : win(w),winFor(0)
00051 {}
00052 SystemTrayWindow( WId w, WId wf )
00053 : win(w),winFor(wf)
00054 {}
00055
00056 bool operator==( const SystemTrayWindow& other )
00057 { return win == other.win; }
00058 WId win;
00059 WId winFor;
00060 };
00061
00062 typedef QValueList<SystemTrayWindow> SystemTrayWindowList;
00063
00064 class Workspace : public QObject, public KWinInterface, public KDecorationDefines
00065 {
00066 Q_OBJECT
00067 public:
00068 Workspace( bool restore = FALSE );
00069 virtual ~Workspace();
00070
00071 static Workspace * self() { return _self; }
00072
00073 bool workspaceEvent( XEvent * );
00074
00075 KDecoration* createDecoration( KDecorationBridge* bridge );
00076
00077 bool hasClient( const Client * );
00078
00079 template< typename T > Client* findClient( T predicate );
00080 template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate );
00081 template< typename T > void forEachClient( T procedure );
00082
00083 Group* findGroup( Window leader ) const;
00084 void addGroup( Group* group, allowed_t );
00085 void removeGroup( Group* group, allowed_t );
00086 Group* findClientLeaderGroup( const Client* c ) const;
00087
00088 QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const;
00089 QRect clientArea( clientAreaOption, const Client* c ) const;
00090
00094 void killWindowId( Window window);
00095
00096 void killWindow() { slotKillWindow(); }
00097
00098 WId rootWin() const;
00099
00100 bool initializing() const;
00101
00106 Client* activeClient() const;
00107
00108
00109
00110 Client* mostRecentlyActivatedClient() const;
00111
00112 void setActiveClient( Client*, allowed_t );
00113 void activateClient( Client*, bool force = FALSE );
00114 void requestFocus( Client* c, bool force = FALSE );
00115 bool allowClientActivation( const Client* c, Time time = -1U, bool focus_in = false,
00116 bool session_active = false );
00117 void restoreFocus();
00118 void gotFocusIn( const Client* );
00119 bool fakeRequestedActivity( Client* c );
00120 void unfakeActivity( Client* c );
00121 void activateNextClient( Client* c );
00122 bool focusChangeEnabled() { return block_focus == 0; }
00123
00124 void updateColormap();
00125
00129 void setClientIsMoving( Client *c );
00130
00131 void place( Client *c, QRect& area );
00132 void placeSmart( Client* c, const QRect& area );
00133
00134 QPoint adjustClientPosition( Client* c, QPoint pos );
00135 void raiseClient( Client* c );
00136 void lowerClient( Client* c );
00137 void raiseClientRequest( Client* c );
00138 void lowerClientRequest( Client* c );
00139 void restackClientUnderActive( Client* );
00140 void updateClientLayer( Client* c );
00141 void raiseOrLowerClient( Client * );
00142 void reconfigure();
00143
00144 void clientHidden( Client* );
00145 void clientAttentionChanged( Client* c, bool set );
00146
00147 void clientMoved(const QPoint &pos, Time time);
00148
00152 int currentDesktop() const;
00156 int numberOfDesktops() const;
00157 void setNumberOfDesktops( int n );
00158
00159 QWidget* desktopWidget();
00160
00161
00162 Client* nextFocusChainClient(Client*) const;
00163 Client* previousFocusChainClient(Client*) const;
00164 Client* nextStaticClient(Client*) const;
00165 Client* previousStaticClient(Client*) const;
00166 int nextDesktopFocusChain( int iDesktop ) const;
00167 int previousDesktopFocusChain( int iDesktop ) const;
00168
00173 const ClientList& stackingOrder() const;
00174
00175 ClientList ensureStackingOrder( const ClientList& clients ) const;
00176
00177 Client* topClientOnDesktop( int desktop, bool unconstrained = false ) const;
00178 Client* findDesktop( bool topmost, int desktop ) const;
00179 void sendClientToDesktop( Client* c, int desktop, bool dont_activate );
00180
00181
00182 void showWindowMenuAt( unsigned long id, int x, int y );
00183
00188 void showWindowMenu( int x, int y, Client* cl );
00189 void showWindowMenu( QPoint pos, Client* cl );
00190
00191 void updateMinimizedOfTransients( Client* );
00192 void updateOnAllDesktopsOfTransients( Client* );
00193 void checkTransients( Window w );
00194
00195 void performWindowOperation( Client* c, WindowOperation op );
00196
00197 void storeSession( KConfig* config, SMSavePhase phase );
00198
00199 SessionInfo* takeSessionInfo( Client* );
00200
00201
00202
00203 void cascadeDesktop();
00204 void unclutterDesktop();
00205 void doNotManage(QString);
00206 bool setCurrentDesktop( int new_desktop );
00207 void nextDesktop();
00208 void previousDesktop();
00209 void circulateDesktopApplications();
00210
00211 QString desktopName( int desk ) const;
00212 void setDesktopLayout(int o, int x, int y);
00213
00214 bool isNotManaged( const QString& title );
00215
00216 void sendPingToWindow( Window w, Time timestamp );
00217
00218
00219 void removeClient( Client*, allowed_t );
00220
00221 bool checkStartupNotification( Window w, KStartupInfoData& data );
00222
00223 void focusToNull();
00224
00225 void sessionSaveStarted();
00226 void sessionSaveDone();
00227 void setWasUserInteraction();
00228 bool sessionSaving() const;
00229
00230 bool managingTopMenus() const;
00231 int topMenuHeight() const;
00232
00233 int packPositionLeft( const Client* cl, int oldx, bool left_edge ) const;
00234 int packPositionRight( const Client* cl, int oldx, bool right_edge ) const;
00235 int packPositionUp( const Client* cl, int oldy, bool top_edge ) const;
00236 int packPositionDown( const Client* cl, int oldy, bool bottom_edge ) const;
00237
00238 static QStringList configModules(bool controlCenter);
00239
00240 public slots:
00241 void refresh();
00242
00243 void slotSwitchDesktopNext();
00244 void slotSwitchDesktopPrevious();
00245 void slotSwitchDesktopRight();
00246 void slotSwitchDesktopLeft();
00247 void slotSwitchDesktopUp();
00248 void slotSwitchDesktopDown();
00249
00250 void slotSwitchToDesktop( int );
00251
00252 void slotWindowToDesktop( int );
00253
00254
00255 void slotWindowMaximize();
00256 void slotWindowMaximizeVertical();
00257 void slotWindowMaximizeHorizontal();
00258 void slotWindowMinimize();
00259 void slotWindowShade();
00260 void slotWindowRaise();
00261 void slotWindowLower();
00262 void slotWindowRaiseOrLower();
00263 void slotActivateAttentionWindow();
00264 void slotWindowPackLeft();
00265 void slotWindowPackRight();
00266 void slotWindowPackUp();
00267 void slotWindowPackDown();
00268 void slotWindowGrowHorizontal();
00269 void slotWindowGrowVertical();
00270 void slotWindowShrinkHorizontal();
00271 void slotWindowShrinkVertical();
00272
00273 void slotWalkThroughDesktops();
00274 void slotWalkBackThroughDesktops();
00275 void slotWalkThroughDesktopList();
00276 void slotWalkBackThroughDesktopList();
00277 void slotWalkThroughWindows();
00278 void slotWalkBackThroughWindows();
00279
00280 void slotWindowOperations();
00281 void slotWindowClose();
00282 void slotWindowMove();
00283 void slotWindowResize();
00284 void slotWindowAbove();
00285 void slotWindowBelow();
00286 void slotWindowOnAllDesktops();
00287 void slotWindowFullScreen();
00288 void slotWindowNoBorder();
00289
00290 void slotWindowToNextDesktop();
00291 void slotWindowToPreviousDesktop();
00292
00293 void slotMouseEmulation();
00294
00295 void slotSettingsChanged( int category );
00296
00297 void slotReconfigure();
00298
00299 void slotKillWindow();
00300
00301 void slotGrabWindow();
00302 void slotGrabDesktop();
00303
00304 void updateClientArea();
00305
00306 private slots:
00307 void desktopPopupAboutToShow();
00308 void clientPopupAboutToShow();
00309 void sendToDesktop( int );
00310 void clientPopupActivated( int );
00311 void configureWM();
00312 void desktopResized();
00313 void slotUpdateToolWindows();
00314 void lostTopMenuSelection();
00315 void lostTopMenuOwner();
00316
00317 protected:
00318 bool keyPressMouseEmulation( XKeyEvent& ev );
00319 bool netCheck( XEvent* e );
00320
00321 private:
00322 void init();
00323 void initShortcuts();
00324 void readShortcuts();
00325 void initDesktopPopup();
00326
00327 bool startKDEWalkThroughWindows();
00328 bool startWalkThroughDesktops( int mode );
00329 bool startWalkThroughDesktops();
00330 bool startWalkThroughDesktopList();
00331 void KDEWalkThroughWindows( bool forward );
00332 void CDEWalkThroughWindows( bool forward );
00333 void walkThroughDesktops( bool forward );
00334 void KDEOneStepThroughWindows( bool forward );
00335 void oneStepThroughDesktops( bool forward, int mode );
00336 void oneStepThroughDesktops( bool forward );
00337 void oneStepThroughDesktopList( bool forward );
00338
00339 void updateStackingOrder( bool propagate_new_clients = false );
00340 void propagateClients( bool propagate_new_clients );
00341 ClientList constrainedStackingOrder();
00342 void raiseClientWithinApplication( Client* c );
00343 void lowerClientWithinApplication( Client* c );
00344 bool allowFullClientRaising( const Client* c );
00345 bool keepTransientAbove( const Client* mainwindow, const Client* transient );
00346 void blockStackingUpdates( bool block );
00347 void updateCurrentTopMenu();
00348 void addTopMenu( Client* c );
00349 void removeTopMenu( Client* c );
00350 void setupTopMenuHandling();
00351 void updateTopMenuGeometry( Client* c = NULL );
00352 void updateToolWindows( bool also_hide );
00353
00354
00355 Client* createClient( Window w, bool is_mapped );
00356 void addClient( Client* c, allowed_t );
00357
00358 Window findSpecialEventWindow( XEvent* e );
00359
00360 void randomPlacement(Client* c);
00361 void smartPlacement(Client* c);
00362 void cascadePlacement(Client* c, bool re_init = false);
00363
00364 bool addSystemTrayWin( WId w );
00365 bool removeSystemTrayWin( WId w, bool check );
00366 void propagateSystemTrayWins();
00367 SystemTrayWindow findSystemTrayWin( WId w );
00368
00369
00370 void loadDesktopSettings();
00371 void saveDesktopSettings();
00372
00373
00374 WId getMouseEmulationWindow();
00375 enum MouseEmulation { EmuPress, EmuRelease, EmuMove };
00376 unsigned int sendFakedMouseEvent( QPoint pos, WId win, MouseEmulation type, int button, unsigned int state );
00377
00378 void tabBoxKeyPress( const KKeyNative& keyX );
00379 void tabBoxKeyRelease( const XKeyEvent& ev );
00380
00381
00382 void checkElectricBorders();
00383 void createBorderWindows();
00384 void destroyBorderWindows();
00385 void electricBorder(XEvent * e);
00386 void raiseElectricBorders();
00387
00388
00389
00390 void helperDialog( const QString& message, const Client* c );
00391
00392 void calcDesktopLayout(int &x, int &y);
00393
00394 QPopupMenu* clientPopup();
00395
00396 void updateClientArea( bool force );
00397
00398 SystemTrayWindowList systemTrayWins;
00399
00400 int current_desktop;
00401 int number_of_desktops;
00402 QMemArray<int> desktop_focus_chain;
00403
00404 Client* popup_client;
00405
00406 void loadSessionInfo();
00407
00408 QWidget* desktop_widget;
00409
00410 QPtrList<SessionInfo> session;
00411 QPtrList<SessionInfo> fakeSession;
00412 void loadFakeSessionInfo();
00413 void storeFakeSessionInfo( Client* c );
00414 void writeFakeSessionInfo();
00415 static const char* windowTypeToTxt( NET::WindowType type );
00416 static NET::WindowType txtToWindowType( const char* txt );
00417 static bool sessionInfoWindowTypeMatch( Client* c, SessionInfo* info );
00418
00419 Client* active_client;
00420 Client* last_active_client;
00421 Client* most_recently_raised;
00422 Client* movingClient;
00423
00424 ClientList clients;
00425 ClientList desktops;
00426
00427 ClientList unconstrained_stacking_order;
00428 ClientList stacking_order;
00429 ClientList focus_chain;
00430 ClientList should_get_focus;
00431 ClientList attention_chain;
00432
00433 GroupList groups;
00434
00435 bool was_user_interaction;
00436 bool session_saving;
00437 int session_active_client;
00438 int session_desktop;
00439
00440 bool control_grab;
00441 bool tab_grab;
00442
00443
00444
00445 KShortcut cutWalkThroughDesktops, cutWalkThroughDesktopsReverse;
00446 KShortcut cutWalkThroughDesktopList, cutWalkThroughDesktopListReverse;
00447 KShortcut cutWalkThroughWindows, cutWalkThroughWindowsReverse;
00448 bool mouse_emulation;
00449 unsigned int mouse_emulation_state;
00450 WId mouse_emulation_window;
00451 int block_focus;
00452
00453 TabBox* tab_box;
00454 PopupInfo* popupinfo;
00455
00456 QPopupMenu *popup;
00457 QPopupMenu *advanced_popup;
00458 QPopupMenu *desk_popup;
00459 int desk_popup_index;
00460
00461 KGlobalAccel *keys;
00462 WId root;
00463
00464 PluginMgr *mgr;
00465
00466 RootInfo *rootInfo;
00467 QWidget* supportWindow;
00468
00469
00470 QStringList doNotManageList;
00471
00472
00473 Colormap default_colormap;
00474 Colormap installed_colormap;
00475
00476
00477 QTimer reconfigureTimer;
00478
00479 QTimer updateToolWindowsTimer;
00480
00481 static Workspace *_self;
00482
00483 bool workspaceInit;
00484
00485 KStartupInfo* startup;
00486
00487 bool electric_have_borders;
00488 int electric_current_border;
00489 WId electric_top_border;
00490 WId electric_bottom_border;
00491 WId electric_left_border;
00492 WId electric_right_border;
00493 int electricLeft;
00494 int electricRight;
00495 int electricTop;
00496 int electricBottom;
00497 Time electric_time_first;
00498 Time electric_time_last;
00499 QPoint electric_push_point;
00500
00501 Qt::Orientation layoutOrientation;
00502 int layoutX;
00503 int layoutY;
00504
00505 Placement *initPositioning;
00506
00507 QRect* workarea;
00508
00509 bool managing_topmenus;
00510 KSelectionOwner* topmenu_selection;
00511 KSelectionWatcher* topmenu_watcher;
00512 ClientList topmenus;
00513 mutable int topmenu_height;
00514 QWidget* topmenu_space;
00515
00516 int set_active_client_recursion;
00517 int block_stacking_updates;
00518 bool blocked_propagating_new_clients;
00519 friend class StackingUpdatesBlocker;
00520 };
00521
00522
00523 class StackingUpdatesBlocker
00524 {
00525 public:
00526 StackingUpdatesBlocker( Workspace* w )
00527 : ws( w ) { ws->blockStackingUpdates( true ); }
00528 ~StackingUpdatesBlocker()
00529 { ws->blockStackingUpdates( false ); }
00530 private:
00531 Workspace* ws;
00532 };
00533
00534
00535 class RootInfo : public NETRootInfo2
00536 {
00537 private:
00538 typedef KWinInternal::Client Client;
00539 public:
00540 RootInfo( Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr[], int pr_num, int scr= -1);
00541 protected:
00542 virtual void changeNumberOfDesktops(int n);
00543 virtual void changeCurrentDesktop(int d);
00544
00545 virtual void changeActiveWindow(Window w,NET::RequestSource src, Time timestamp, Window active_window);
00546 virtual void closeWindow(Window w);
00547 virtual void moveResize(Window w, int x_root, int y_root, unsigned long direction);
00548 virtual void moveResizeWindow(Window w, int flags, int x, int y, int width, int height );
00549 virtual void gotPing(Window w, Time timestamp);
00550 virtual void restackWindow(Window w, Window above, int detail);
00551 private:
00552 Workspace* workspace;
00553 };
00554
00555
00556 inline WId Workspace::rootWin() const
00557 {
00558 return root;
00559 }
00560
00561 inline bool Workspace::initializing() const
00562 {
00563 return workspaceInit;
00564 }
00565
00566 inline Client* Workspace::activeClient() const
00567 {
00568 return active_client;
00569 }
00570
00571 inline Client* Workspace::mostRecentlyActivatedClient() const
00572 {
00573 return should_get_focus.count() > 0 ? should_get_focus.last() : active_client;
00574 }
00575
00576 inline int Workspace::currentDesktop() const
00577 {
00578 return current_desktop;
00579 }
00580
00581 inline int Workspace::numberOfDesktops() const
00582 {
00583 return number_of_desktops;
00584 }
00585
00586 inline void Workspace::addGroup( Group* group, allowed_t )
00587 {
00588 groups.append( group );
00589 }
00590
00591 inline void Workspace::removeGroup( Group* group, allowed_t )
00592 {
00593 groups.remove( group );
00594 }
00595
00596 inline const ClientList& Workspace::stackingOrder() const
00597 {
00598
00599 return stacking_order;
00600 }
00601
00602 inline void Workspace::showWindowMenu(QPoint pos, Client* cl)
00603 {
00604 showWindowMenu(pos.x(), pos.y(), cl);
00605 }
00606
00607 inline
00608 void Workspace::setWasUserInteraction()
00609 {
00610 was_user_interaction = true;
00611 }
00612
00613 inline
00614 bool Workspace::managingTopMenus() const
00615 {
00616 return managing_topmenus;
00617 }
00618
00619 inline void Workspace::sessionSaveStarted()
00620 {
00621 session_saving = true;
00622 }
00623
00624 inline void Workspace::sessionSaveDone()
00625 {
00626 session_saving = false;
00627 }
00628
00629 inline bool Workspace::sessionSaving() const
00630 {
00631 return session_saving;
00632 }
00633
00634 template< typename T >
00635 inline Client* Workspace::findClient( T predicate )
00636 {
00637 if( Client* ret = findClientInList( clients, predicate ))
00638 return ret;
00639 if( Client* ret = findClientInList( desktops, predicate ))
00640 return ret;
00641 return NULL;
00642 }
00643
00644 template< typename T1, typename T2 >
00645 inline void Workspace::forEachClient( T1 procedure, T2 predicate )
00646 {
00647 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00648 if ( predicate( const_cast< const Client* >( *it)))
00649 procedure( *it );
00650 for ( ClientList::ConstIterator it = desktops.begin(); it != desktops.end(); ++it)
00651 if ( predicate( const_cast< const Client* >( *it)))
00652 procedure( *it );
00653 }
00654
00655 template< typename T >
00656 inline void Workspace::forEachClient( T procedure )
00657 {
00658 return forEachClient( procedure, TruePredicate());
00659 }
00660
00661 KWIN_COMPARE_PREDICATE( ClientMatchPredicate, const Client*, cl == value );
00662 inline bool Workspace::hasClient( const Client* c )
00663 {
00664 return findClient( ClientMatchPredicate( c ));
00665 }
00666
00667 }
00668
00669 #endif