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 #include <kxmessages.h>
00020
00021 #include "KWinInterface.h"
00022 #include "utils.h"
00023 #include "kdecoration.h"
00024 #include "sm.h"
00025
00026 #include <X11/Xlib.h>
00027
00028 class QPopupMenu;
00029 class KConfig;
00030 class KGlobalAccel;
00031 class KShortcutDialog;
00032 class KStartupInfo;
00033 class KStartupInfoId;
00034 class KStartupInfoData;
00035 class QSlider;
00036 class QPushButton;
00037 class KProcess;
00038
00039 namespace KWinInternal
00040 {
00041
00042 class Client;
00043 class TabBox;
00044 class PopupInfo;
00045 class RootInfo;
00046 class PluginMgr;
00047 class Placement;
00048 class Rules;
00049 class WindowRules;
00050
00051 class SystemTrayWindow
00052 {
00053 public:
00054 SystemTrayWindow()
00055 : win(0),winFor(0)
00056 {}
00057 SystemTrayWindow( WId w )
00058 : win(w),winFor(0)
00059 {}
00060 SystemTrayWindow( WId w, WId wf )
00061 : win(w),winFor(wf)
00062 {}
00063
00064 bool operator==( const SystemTrayWindow& other )
00065 { return win == other.win; }
00066 WId win;
00067 WId winFor;
00068 };
00069
00070 typedef QValueList<SystemTrayWindow> SystemTrayWindowList;
00071
00072 class Workspace : public QObject, public KWinInterface, public KDecorationDefines
00073 {
00074 Q_OBJECT
00075 public:
00076 Workspace( bool restore = FALSE );
00077 virtual ~Workspace();
00078
00079 static Workspace * self() { return _self; }
00080
00081 bool workspaceEvent( XEvent * );
00082
00083 KDecoration* createDecoration( KDecorationBridge* bridge );
00084
00085 bool hasClient( const Client * );
00086
00087 template< typename T > Client* findClient( T predicate );
00088 template< typename T1, typename T2 > void forEachClient( T1 procedure, T2 predicate );
00089 template< typename T > void forEachClient( T procedure );
00090
00091 QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const;
00092 QRect clientArea( clientAreaOption, const Client* c ) const;
00093
00097 void killWindowId( Window window);
00098
00099 void killWindow() { slotKillWindow(); }
00100
00101 WId rootWin() const;
00102
00103 bool initializing() const;
00104
00109 Client* activeClient() const;
00110
00111
00112
00113 Client* mostRecentlyActivatedClient() const;
00114
00115 void activateClient( Client*, bool force = FALSE );
00116 void requestFocus( Client* c, bool force = FALSE );
00117 void takeActivity( Client* c, int flags, bool handled );
00118 void handleTakeActivity( Client* c, Time timestamp, int flags );
00119 bool allowClientActivation( const Client* c, Time time = -1U, bool focus_in = false );
00120 void restoreFocus();
00121 void gotFocusIn( const Client* );
00122 void setShouldGetFocus( Client* );
00123 bool fakeRequestedActivity( Client* c );
00124 void unfakeActivity( Client* c );
00125 bool activateNextClient( Client* c );
00126 bool focusChangeEnabled() { return block_focus == 0; }
00127
00128 void updateColormap();
00129
00133 void setClientIsMoving( Client *c );
00134
00135 void place( Client *c, QRect& area );
00136 void placeSmart( Client* c, const QRect& area );
00137
00138 QPoint adjustClientPosition( Client* c, QPoint pos );
00139 QRect adjustClientSize( Client* c, QRect moveResizeGeom, int mode );
00140 void raiseClient( Client* c );
00141 void lowerClient( Client* c );
00142 void raiseClientRequest( Client* c, NET::RequestSource src, Time timestamp );
00143 void lowerClientRequest( Client* c, NET::RequestSource src, Time timestamp );
00144 void restackClientUnderActive( Client* );
00145 void updateClientLayer( Client* c );
00146 void raiseOrLowerClient( Client * );
00147 void reconfigure();
00148
00149 void clientHidden( Client* );
00150 void clientAttentionChanged( Client* c, bool set );
00151
00152 void clientMoved(const QPoint &pos, Time time);
00153
00157 int currentDesktop() const;
00161 int numberOfDesktops() const;
00162 void setNumberOfDesktops( int n );
00163
00164 QWidget* desktopWidget();
00165
00166
00167 Client* nextFocusChainClient(Client*) const;
00168 Client* previousFocusChainClient(Client*) const;
00169 Client* nextStaticClient(Client*) const;
00170 Client* previousStaticClient(Client*) const;
00171 int nextDesktopFocusChain( int iDesktop ) const;
00172 int previousDesktopFocusChain( int iDesktop ) const;
00173 void closeTabBox();
00174
00179 const ClientList& stackingOrder() const;
00180
00181 ClientList ensureStackingOrder( const ClientList& clients ) const;
00182
00183 Client* topClientOnDesktop( int desktop, bool unconstrained = false ) const;
00184 Client* findDesktop( bool topmost, int desktop ) const;
00185 void sendClientToDesktop( Client* c, int desktop, bool dont_activate );
00186
00187
00188 void showWindowMenuAt( unsigned long id, int x, int y );
00189
00194 void showWindowMenu( const QRect &pos, Client* cl );
00198 void showWindowMenu( int x, int y, Client* cl );
00199 void showWindowMenu( QPoint pos, Client* cl );
00200
00201 void updateMinimizedOfTransients( Client* );
00202 void updateOnAllDesktopsOfTransients( Client* );
00203 void checkTransients( Window w );
00204
00205 void performWindowOperation( Client* c, WindowOperation op );
00206
00207 void storeSession( KConfig* config, SMSavePhase phase );
00208
00209 SessionInfo* takeSessionInfo( Client* );
00210 WindowRules findWindowRules( const Client*, bool );
00211 void rulesUpdated();
00212
00213
00214 void cascadeDesktop();
00215 void unclutterDesktop();
00216 void doNotManage(QString);
00217 bool setCurrentDesktop( int new_desktop );
00218 void nextDesktop();
00219 void previousDesktop();
00220 void circulateDesktopApplications();
00221
00222 QString desktopName( int desk ) const;
00223 void setDesktopLayout(int o, int x, int y);
00224
00225 bool isNotManaged( const QString& title );
00226
00227 void sendPingToWindow( Window w, Time timestamp );
00228 void sendTakeActivity( Client* c, Time timestamp, long flags );
00229
00230 void stopKompmgr();
00231 bool kompmgrIsRunning();
00232 void setOpacity(unsigned long winId, unsigned int opacityPercent);
00233 void setShadowSize(unsigned long winId, unsigned int shadowSizePercent);
00234 void setUnshadowed(unsigned long winId);
00235
00236
00237 void removeClient( Client*, allowed_t );
00238 void setActiveClient( Client*, allowed_t );
00239 Group* findGroup( Window leader ) const;
00240 void addGroup( Group* group, allowed_t );
00241 void removeGroup( Group* group, allowed_t );
00242 Group* findClientLeaderGroup( const Client* c ) const;
00243
00244 bool checkStartupNotification( Window w, KStartupInfoId& id, KStartupInfoData& data );
00245
00246 void focusToNull();
00247
00248 bool forcedGlobalMouseGrab() const;
00249 void clientShortcutUpdated( Client* c );
00250 bool shortcutAvailable( const KShortcut& cut, Client* ignore = NULL ) const;
00251
00252 void sessionSaveStarted();
00253 void sessionSaveDone();
00254 void setWasUserInteraction();
00255 bool wasUserInteraction() const;
00256 bool sessionSaving() const;
00257
00258 bool managingTopMenus() const;
00259 int topMenuHeight() const;
00260 void updateCurrentTopMenu();
00261
00262 int packPositionLeft( const Client* cl, int oldx, bool left_edge ) const;
00263 int packPositionRight( const Client* cl, int oldx, bool right_edge ) const;
00264 int packPositionUp( const Client* cl, int oldy, bool top_edge ) const;
00265 int packPositionDown( const Client* cl, int oldy, bool bottom_edge ) const;
00266
00267 static QStringList configModules(bool controlCenter);
00268
00269 void cancelDelayFocus();
00270 void requestDelayFocus( Client* );
00271
00272 void toggleTopDockShadows(bool on);
00273
00274 public slots:
00275 void refresh();
00276
00277 void slotSwitchDesktopNext();
00278 void slotSwitchDesktopPrevious();
00279 void slotSwitchDesktopRight();
00280 void slotSwitchDesktopLeft();
00281 void slotSwitchDesktopUp();
00282 void slotSwitchDesktopDown();
00283
00284 void slotSwitchToDesktop( int );
00285
00286 void slotWindowToDesktop( int );
00287
00288
00289 void slotWindowMaximize();
00290 void slotWindowMaximizeVertical();
00291 void slotWindowMaximizeHorizontal();
00292 void slotWindowMinimize();
00293 void slotWindowShade();
00294 void slotWindowRaise();
00295 void slotWindowLower();
00296 void slotWindowRaiseOrLower();
00297 void slotActivateAttentionWindow();
00298 void slotWindowPackLeft();
00299 void slotWindowPackRight();
00300 void slotWindowPackUp();
00301 void slotWindowPackDown();
00302 void slotWindowGrowHorizontal();
00303 void slotWindowGrowVertical();
00304 void slotWindowShrinkHorizontal();
00305 void slotWindowShrinkVertical();
00306
00307 void slotWalkThroughDesktops();
00308 void slotWalkBackThroughDesktops();
00309 void slotWalkThroughDesktopList();
00310 void slotWalkBackThroughDesktopList();
00311 void slotWalkThroughWindows();
00312 void slotWalkBackThroughWindows();
00313
00314 void slotWindowOperations();
00315 void slotWindowClose();
00316 void slotWindowMove();
00317 void slotWindowResize();
00318 void slotWindowAbove();
00319 void slotWindowBelow();
00320 void slotWindowOnAllDesktops();
00321 void slotWindowFullScreen();
00322 void slotWindowNoBorder();
00323
00324 void slotWindowToNextDesktop();
00325 void slotWindowToPreviousDesktop();
00326 void slotWindowToDesktopRight();
00327 void slotWindowToDesktopLeft();
00328 void slotWindowToDesktopUp();
00329 void slotWindowToDesktopDown();
00330
00331 void slotMouseEmulation();
00332
00333 void slotSettingsChanged( int category );
00334
00335 void slotReconfigure();
00336
00337 void slotKillWindow();
00338
00339 void slotGrabWindow();
00340 void slotGrabDesktop();
00341
00342 void slotSetupWindowShortcut();
00343 void setupWindowShortcutDone( bool );
00344
00345 void updateClientArea();
00346
00347
00348 void startKompmgr();
00349
00350 private slots:
00351 void desktopPopupAboutToShow();
00352 void clientPopupAboutToShow();
00353 void slotSendToDesktop( int );
00354 void clientPopupActivated( int );
00355 void configureWM();
00356 void desktopResized();
00357 void slotUpdateToolWindows();
00358 void lostTopMenuSelection();
00359 void lostTopMenuOwner();
00360 void delayFocus();
00361 void gotTemporaryRulesMessage( const QString& );
00362 void cleanupTemporaryRules();
00363 void writeWindowRules();
00364
00365 void setPopupClientOpacity(int v);
00366 void resetClientOpacity();
00367 void setTransButtonText(int value);
00368 void unblockKompmgrRestart();
00369 void restartKompmgr();
00370 void handleKompmgrOutput( KProcess *proc, char *buffer, int buflen);
00371
00372
00373 protected:
00374 bool keyPressMouseEmulation( XKeyEvent& ev );
00375 bool netCheck( XEvent* e );
00376
00377 private:
00378 void init();
00379 void initShortcuts();
00380 void readShortcuts();
00381 void initDesktopPopup();
00382 void setupWindowShortcut( Client* c );
00383
00384 bool startKDEWalkThroughWindows();
00385 bool startWalkThroughDesktops( int mode );
00386 bool startWalkThroughDesktops();
00387 bool startWalkThroughDesktopList();
00388 void KDEWalkThroughWindows( bool forward );
00389 void CDEWalkThroughWindows( bool forward );
00390 void walkThroughDesktops( bool forward );
00391 void KDEOneStepThroughWindows( bool forward );
00392 void oneStepThroughDesktops( bool forward, int mode );
00393 void oneStepThroughDesktops( bool forward );
00394 void oneStepThroughDesktopList( bool forward );
00395 bool establishTabBoxGrab();
00396 void removeTabBoxGrab();
00397 int desktopToRight( int desktop ) const;
00398 int desktopToLeft( int desktop ) const;
00399 int desktopUp( int desktop ) const;
00400 int desktopDown( int desktop ) const;
00401
00402 void updateStackingOrder( bool propagate_new_clients = false );
00403 void propagateClients( bool propagate_new_clients );
00404 ClientList constrainedStackingOrder();
00405 void raiseClientWithinApplication( Client* c );
00406 void lowerClientWithinApplication( Client* c );
00407 bool allowFullClientRaising( const Client* c, Time timestamp );
00408 bool keepTransientAbove( const Client* mainwindow, const Client* transient );
00409 void blockStackingUpdates( bool block );
00410 void addTopMenu( Client* c );
00411 void removeTopMenu( Client* c );
00412 void setupTopMenuHandling();
00413 void updateTopMenuGeometry( Client* c = NULL );
00414 void updateToolWindows( bool also_hide );
00415
00416
00417 Client* createClient( Window w, bool is_mapped );
00418 void addClient( Client* c, allowed_t );
00419
00420 Window findSpecialEventWindow( XEvent* e );
00421
00422 void randomPlacement(Client* c);
00423 void smartPlacement(Client* c);
00424 void cascadePlacement(Client* c, bool re_init = false);
00425
00426 bool addSystemTrayWin( WId w );
00427 bool removeSystemTrayWin( WId w, bool check );
00428 void propagateSystemTrayWins();
00429 SystemTrayWindow findSystemTrayWin( WId w );
00430
00431
00432 void loadDesktopSettings();
00433 void saveDesktopSettings();
00434
00435
00436 WId getMouseEmulationWindow();
00437 enum MouseEmulation { EmuPress, EmuRelease, EmuMove };
00438 unsigned int sendFakedMouseEvent( QPoint pos, WId win, MouseEmulation type, int button, unsigned int state );
00439
00440 void tabBoxKeyPress( const KKeyNative& keyX );
00441 void tabBoxKeyRelease( const XKeyEvent& ev );
00442
00443
00444 void checkElectricBorders( bool force = false );
00445 void createBorderWindows();
00446 void destroyBorderWindows();
00447 bool electricBorder(XEvent * e);
00448 void raiseElectricBorders();
00449
00450
00451
00452 void helperDialog( const QString& message, const Client* c );
00453
00454 void calcDesktopLayout(int &x, int &y) const;
00455
00456 QPopupMenu* clientPopup();
00457 void closeActivePopup();
00458
00459 void updateClientArea( bool force );
00460
00461 SystemTrayWindowList systemTrayWins;
00462
00463 int current_desktop;
00464 int number_of_desktops;
00465 QMemArray<int> desktop_focus_chain;
00466
00467 QWidget* active_popup;
00468 Client* active_popup_client;
00469
00470 QWidget* desktop_widget;
00471
00472 void loadSessionInfo();
00473 void loadWindowRules();
00474 void editWindowRules( Client* );
00475
00476 QPtrList<SessionInfo> session;
00477 QValueList<Rules*> rules;
00478 KXMessages temporaryRulesMessages;
00479 QTimer rulesUpdatedTimer;
00480 static const char* windowTypeToTxt( NET::WindowType type );
00481 static NET::WindowType txtToWindowType( const char* txt );
00482 static bool sessionInfoWindowTypeMatch( Client* c, SessionInfo* info );
00483
00484 Client* active_client;
00485 Client* last_active_client;
00486 Client* most_recently_raised;
00487 Client* movingClient;
00488 Client* pending_take_activity;
00489
00490
00491 QTimer* delayFocusTimer;
00492 Client* delayfocus_client;
00493
00494 ClientList clients;
00495 ClientList desktops;
00496
00497 ClientList unconstrained_stacking_order;
00498 ClientList stacking_order;
00499 ClientList focus_chain;
00500 ClientList should_get_focus;
00501 ClientList attention_chain;
00502
00503 GroupList groups;
00504
00505 bool was_user_interaction;
00506 bool session_saving;
00507 int session_active_client;
00508 int session_desktop;
00509
00510 bool control_grab;
00511 bool tab_grab;
00512
00513
00514
00515 KShortcut cutWalkThroughDesktops, cutWalkThroughDesktopsReverse;
00516 KShortcut cutWalkThroughDesktopList, cutWalkThroughDesktopListReverse;
00517 KShortcut cutWalkThroughWindows, cutWalkThroughWindowsReverse;
00518 bool mouse_emulation;
00519 unsigned int mouse_emulation_state;
00520 WId mouse_emulation_window;
00521 int block_focus;
00522
00523 TabBox* tab_box;
00524 PopupInfo* popupinfo;
00525
00526 QPopupMenu *popup;
00527 QPopupMenu *advanced_popup;
00528 QPopupMenu *desk_popup;
00529 int desk_popup_index;
00530
00531 KGlobalAccel *keys;
00532 KGlobalAccel *client_keys;
00533 ShortcutDialog* client_keys_dialog;
00534 Client* client_keys_client;
00535
00536 WId root;
00537
00538 PluginMgr *mgr;
00539
00540 RootInfo *rootInfo;
00541 QWidget* supportWindow;
00542
00543
00544 QStringList doNotManageList;
00545
00546
00547 Colormap default_colormap;
00548 Colormap installed_colormap;
00549
00550
00551 QTimer reconfigureTimer;
00552
00553 QTimer updateToolWindowsTimer;
00554
00555 static Workspace *_self;
00556
00557 bool workspaceInit;
00558
00559 KStartupInfo* startup;
00560
00561 bool electric_have_borders;
00562 int electric_current_border;
00563 WId electric_top_border;
00564 WId electric_bottom_border;
00565 WId electric_left_border;
00566 WId electric_right_border;
00567 int electricLeft;
00568 int electricRight;
00569 int electricTop;
00570 int electricBottom;
00571 Time electric_time_first;
00572 Time electric_time_last;
00573 QPoint electric_push_point;
00574
00575 Qt::Orientation layoutOrientation;
00576 int layoutX;
00577 int layoutY;
00578
00579 Placement *initPositioning;
00580
00581 QRect* workarea;
00582 QRect** screenarea;
00583
00584 bool managing_topmenus;
00585 KSelectionOwner* topmenu_selection;
00586 KSelectionWatcher* topmenu_watcher;
00587 ClientList topmenus;
00588 mutable int topmenu_height;
00589 QWidget* topmenu_space;
00590
00591 int set_active_client_recursion;
00592 int block_stacking_updates;
00593 bool blocked_propagating_new_clients;
00594 Window null_focus_window;
00595 bool forced_global_mouse_grab;
00596 friend class StackingUpdatesBlocker;
00597
00598
00599 QSlider *transSlider;
00600 QPushButton *transButton;
00601
00602
00603
00604
00605
00606
00607 signals:
00608 void kompmgrStarted();
00609 void kompmgrStopped();
00610 };
00611
00612
00613 class StackingUpdatesBlocker
00614 {
00615 public:
00616 StackingUpdatesBlocker( Workspace* w )
00617 : ws( w ) { ws->blockStackingUpdates( true ); }
00618 ~StackingUpdatesBlocker()
00619 { ws->blockStackingUpdates( false ); }
00620 private:
00621 Workspace* ws;
00622 };
00623
00624
00625 class RootInfo : public NETRootInfo3
00626 {
00627 private:
00628 typedef KWinInternal::Client Client;
00629 public:
00630 RootInfo( Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr[], int pr_num, int scr= -1);
00631 protected:
00632 virtual void changeNumberOfDesktops(int n);
00633 virtual void changeCurrentDesktop(int d);
00634
00635 virtual void changeActiveWindow(Window w,NET::RequestSource src, Time timestamp, Window active_window);
00636 virtual void closeWindow(Window w);
00637 virtual void moveResize(Window w, int x_root, int y_root, unsigned long direction);
00638 virtual void moveResizeWindow(Window w, int flags, int x, int y, int width, int height );
00639 virtual void gotPing(Window w, Time timestamp);
00640 virtual void restackWindow(Window w, RequestSource source, Window above, int detail, Time timestamp);
00641 virtual void gotTakeActivity(Window w, Time timestamp, long flags );
00642 private:
00643 Workspace* workspace;
00644 };
00645
00646
00647 inline WId Workspace::rootWin() const
00648 {
00649 return root;
00650 }
00651
00652 inline bool Workspace::initializing() const
00653 {
00654 return workspaceInit;
00655 }
00656
00657 inline Client* Workspace::activeClient() const
00658 {
00659 return active_client;
00660 }
00661
00662 inline Client* Workspace::mostRecentlyActivatedClient() const
00663 {
00664 return should_get_focus.count() > 0 ? should_get_focus.last() : active_client;
00665 }
00666
00667 inline int Workspace::currentDesktop() const
00668 {
00669 return current_desktop;
00670 }
00671
00672 inline int Workspace::numberOfDesktops() const
00673 {
00674 return number_of_desktops;
00675 }
00676
00677 inline void Workspace::addGroup( Group* group, allowed_t )
00678 {
00679 groups.append( group );
00680 }
00681
00682 inline void Workspace::removeGroup( Group* group, allowed_t )
00683 {
00684 groups.remove( group );
00685 }
00686
00687 inline const ClientList& Workspace::stackingOrder() const
00688 {
00689
00690 return stacking_order;
00691 }
00692
00693 inline void Workspace::showWindowMenu(QPoint pos, Client* cl)
00694 {
00695 showWindowMenu(QRect(pos, pos), cl);
00696 }
00697
00698 inline void Workspace::showWindowMenu(int x, int y, Client* cl)
00699 {
00700 showWindowMenu(QRect(QPoint(x, y), QPoint(x, y)), cl);
00701 }
00702
00703 inline
00704 void Workspace::setWasUserInteraction()
00705 {
00706 was_user_interaction = true;
00707 }
00708
00709 inline
00710 bool Workspace::wasUserInteraction() const
00711 {
00712 return was_user_interaction;
00713 }
00714
00715 inline
00716 bool Workspace::managingTopMenus() const
00717 {
00718 return managing_topmenus;
00719 }
00720
00721 inline void Workspace::sessionSaveStarted()
00722 {
00723 session_saving = true;
00724 }
00725
00726 inline void Workspace::sessionSaveDone()
00727 {
00728 session_saving = false;
00729 }
00730
00731 inline bool Workspace::sessionSaving() const
00732 {
00733 return session_saving;
00734 }
00735
00736 inline bool Workspace::forcedGlobalMouseGrab() const
00737 {
00738 return forced_global_mouse_grab;
00739 }
00740
00741 template< typename T >
00742 inline Client* Workspace::findClient( T predicate )
00743 {
00744 if( Client* ret = findClientInList( clients, predicate ))
00745 return ret;
00746 if( Client* ret = findClientInList( desktops, predicate ))
00747 return ret;
00748 return NULL;
00749 }
00750
00751 template< typename T1, typename T2 >
00752 inline void Workspace::forEachClient( T1 procedure, T2 predicate )
00753 {
00754 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00755 if ( predicate( const_cast< const Client* >( *it)))
00756 procedure( *it );
00757 for ( ClientList::ConstIterator it = desktops.begin(); it != desktops.end(); ++it)
00758 if ( predicate( const_cast< const Client* >( *it)))
00759 procedure( *it );
00760 }
00761
00762 template< typename T >
00763 inline void Workspace::forEachClient( T procedure )
00764 {
00765 return forEachClient( procedure, TruePredicate());
00766 }
00767
00768 KWIN_COMPARE_PREDICATE( ClientMatchPredicate, const Client*, cl == value );
00769 inline bool Workspace::hasClient( const Client* c )
00770 {
00771 return findClient( ClientMatchPredicate( c ));
00772 }
00773
00774 }
00775
00776 #endif