kwin Library API Documentation

workspace.h

00001 /*****************************************************************
00002  KWin - the KDE window manager
00003  This file is part of the KDE project.
00004 
00005 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
00006 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
00007 
00008 You can Freely distribute this program under the GNU General Public
00009 License. See the file "COPYING" for the exact licensing terms.
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         // Client that was activated, but it's not yet really activeClient(), because
00108         // we didn't process yet the matching FocusIn event. Used mostly in focus
00109         // stealing prevention code.
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     // for TabBox
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     // KDE4 remove me - and it's also in the DCOP interface :(
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     // dcop interface
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 );  // ### setter or getter ?
00215 
00216         void sendPingToWindow( Window w, Time timestamp ); // called from Client::pingWindow()
00217 
00218     // only called from Client::destroyClient() or Client::releaseWindow()
00219         void removeClient( Client*, allowed_t );
00220 
00221         bool checkStartupNotification( Window w, KStartupInfoData& data );
00222 
00223         void focusToNull(); // SELI public?
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     // keybindings
00243         void slotSwitchDesktopNext();
00244         void slotSwitchDesktopPrevious();
00245         void slotSwitchDesktopRight();
00246         void slotSwitchDesktopLeft();
00247         void slotSwitchDesktopUp();
00248         void slotSwitchDesktopDown();
00249 
00250         void slotSwitchToDesktop( int );
00251     //void slotSwitchToWindow( int );
00252         void slotWindowToDesktop( int );
00253     //void slotWindowToListPosition( int );
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 ); // TabBox::Mode::DesktopMode | DesktopListMode
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 ); // TabBox::Mode::DesktopMode | DesktopListMode
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 ); // called only from updateStackingOrder
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     // this is the right way to create a new client
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     // desktop names and number of desktops
00370         void loadDesktopSettings();
00371         void saveDesktopSettings();
00372 
00373     // mouse emulation
00374         WId getMouseEmulationWindow();
00375         enum MouseEmulation { EmuPress, EmuRelease, EmuMove };
00376         unsigned int sendFakedMouseEvent( QPoint pos, WId win, MouseEmulation type, int button, unsigned int state ); // returns the new state
00377 
00378         void tabBoxKeyPress( const KKeyNative& keyX );
00379         void tabBoxKeyRelease( const XKeyEvent& ev );
00380 
00381     // electric borders
00382         void createBorderWindows();
00383         void destroyBorderWindows();
00384         void electricBorder(XEvent * e);
00385         void raiseElectricBorders();
00386 
00387     // ------------------
00388     
00389         void helperDialog( const QString& message, const Client* c );
00390 
00391         void calcDesktopLayout(int &x, int &y);
00392 
00393         QPopupMenu* clientPopup();
00394 
00395         void updateClientArea( bool force );
00396 
00397         SystemTrayWindowList systemTrayWins;
00398 
00399         int current_desktop;
00400         int number_of_desktops;
00401         QMemArray<int> desktop_focus_chain;
00402 
00403         Client* popup_client;
00404 
00405         void loadSessionInfo();
00406 
00407         QWidget* desktop_widget;
00408 
00409         QPtrList<SessionInfo> session;
00410         QPtrList<SessionInfo> fakeSession;
00411         void loadFakeSessionInfo();
00412         void storeFakeSessionInfo( Client* c );
00413         void writeFakeSessionInfo();
00414         static const char* windowTypeToTxt( NET::WindowType type );
00415         static NET::WindowType txtToWindowType( const char* txt );
00416         static bool sessionInfoWindowTypeMatch( Client* c, SessionInfo* info );
00417 
00418         Client* active_client;
00419         Client* last_active_client;
00420         Client* most_recently_raised; // used _only_ by raiseOrLowerClient()
00421         Client* movingClient;
00422 
00423         ClientList clients;
00424         ClientList desktops;
00425 
00426         ClientList unconstrained_stacking_order;
00427         ClientList stacking_order;
00428         ClientList focus_chain;
00429         ClientList should_get_focus; // last is most recent
00430         ClientList attention_chain;
00431 
00432         GroupList groups;
00433 
00434         bool was_user_interaction;
00435         bool session_saving;
00436         int session_active_client;
00437         int session_desktop;
00438 
00439         bool control_grab;
00440         bool tab_grab;
00441     //KKeyNative walkThroughDesktopsKeycode, walkBackThroughDesktopsKeycode;
00442     //KKeyNative walkThroughDesktopListKeycode, walkBackThroughDesktopListKeycode;
00443     //KKeyNative walkThroughWindowsKeycode, walkBackThroughWindowsKeycode;
00444         KShortcut cutWalkThroughDesktops, cutWalkThroughDesktopsReverse;
00445         KShortcut cutWalkThroughDesktopList, cutWalkThroughDesktopListReverse;
00446         KShortcut cutWalkThroughWindows, cutWalkThroughWindowsReverse;
00447         bool mouse_emulation;
00448         unsigned int mouse_emulation_state;
00449         WId mouse_emulation_window;
00450         int block_focus;
00451 
00452         TabBox* tab_box;
00453         PopupInfo* popupinfo;
00454 
00455         QPopupMenu *popup;
00456         QPopupMenu *advanced_popup;
00457         QPopupMenu *desk_popup;
00458         int desk_popup_index;
00459 
00460         KGlobalAccel *keys;
00461         WId root;
00462 
00463         PluginMgr *mgr;
00464 
00465         RootInfo *rootInfo;
00466         QWidget* supportWindow;
00467 
00468     // swallowing
00469         QStringList doNotManageList;
00470 
00471     // colormap handling
00472         Colormap default_colormap;
00473         Colormap installed_colormap;
00474 
00475     // Timer to collect requests for 'reconfigure'
00476         QTimer reconfigureTimer;
00477 
00478         QTimer updateToolWindowsTimer;
00479 
00480         static Workspace *_self;
00481 
00482         bool workspaceInit;
00483 
00484         KStartupInfo* startup;
00485 
00486         bool electric_have_borders;
00487         int electric_current_border;
00488         WId electric_top_border;
00489         WId electric_bottom_border;
00490         WId electric_left_border;
00491         WId electric_right_border;
00492         int electricLeft;
00493         int electricRight;
00494         int electricTop;
00495         int electricBottom;
00496         Time electric_time_first;
00497         Time electric_time_last;
00498         QPoint electric_push_point;
00499 
00500         Qt::Orientation layoutOrientation;
00501         int layoutX;
00502         int layoutY;
00503 
00504         Placement *initPositioning;
00505 
00506         QRect* workarea; //  array of workareas for virtual desktops
00507 
00508         bool managing_topmenus;
00509         KSelectionOwner* topmenu_selection;
00510         KSelectionWatcher* topmenu_watcher;
00511         ClientList topmenus; // doesn't own them
00512         mutable int topmenu_height;
00513         QWidget* topmenu_space;
00514 
00515         int set_active_client_recursion;
00516         int block_stacking_updates; // when >0, stacking updates are temporarily disabled
00517         bool blocked_propagating_new_clients; // propagate also new clients after enabling stacking updates?
00518         friend class StackingUpdatesBlocker;
00519     };
00520 
00521 // helper for Workspace::blockStackingUpdates() being called in pairs (true/false)
00522 class StackingUpdatesBlocker
00523     {
00524     public:
00525         StackingUpdatesBlocker( Workspace* w )
00526             : ws( w ) { ws->blockStackingUpdates( true ); }
00527         ~StackingUpdatesBlocker()
00528             { ws->blockStackingUpdates( false ); }
00529     private:
00530         Workspace* ws;
00531     };
00532 
00533 // NET WM Protocol handler class
00534 class RootInfo : public NETRootInfo2
00535     {
00536     private:
00537         typedef KWinInternal::Client Client;  // because of NET::Client
00538     public:
00539         RootInfo( Workspace* ws, Display *dpy, Window w, const char *name, unsigned long pr[], int pr_num, int scr= -1);
00540     protected:
00541         virtual void changeNumberOfDesktops(int n);
00542         virtual void changeCurrentDesktop(int d);
00543 //    virtual void changeActiveWindow(Window w); the extended version is used
00544         virtual void changeActiveWindow(Window w,NET::RequestSource src, Time timestamp, Window active_window);
00545         virtual void closeWindow(Window w);
00546         virtual void moveResize(Window w, int x_root, int y_root, unsigned long direction);
00547         virtual void moveResizeWindow(Window w, int flags, int x, int y, int width, int height );
00548         virtual void gotPing(Window w, Time timestamp);
00549         virtual void restackWindow(Window w, Window above, int detail);
00550     private:
00551         Workspace* workspace;
00552     };
00553 
00554 
00555 inline WId Workspace::rootWin() const
00556     {
00557     return root;
00558     }
00559 
00560 inline bool Workspace::initializing() const
00561     {
00562     return workspaceInit;
00563     }
00564 
00565 inline Client* Workspace::activeClient() const
00566     {
00567     return active_client;
00568     }
00569 
00570 inline Client* Workspace::mostRecentlyActivatedClient() const
00571     {
00572     return should_get_focus.count() > 0 ? should_get_focus.last() : active_client;
00573     }
00574 
00575 inline int Workspace::currentDesktop() const
00576     {
00577     return current_desktop;
00578     }
00579 
00580 inline int Workspace::numberOfDesktops() const
00581     {
00582     return number_of_desktops;
00583     }
00584 
00585 inline void Workspace::addGroup( Group* group, allowed_t )
00586     {
00587     groups.append( group );
00588     }
00589 
00590 inline void Workspace::removeGroup( Group* group, allowed_t )
00591     {
00592     groups.remove( group );
00593     }
00594 
00595 inline const ClientList& Workspace::stackingOrder() const
00596     {
00597 // TODO    Q_ASSERT( block_stacking_updates == 0 );
00598     return stacking_order;
00599     }
00600 
00601 inline void Workspace::showWindowMenu(QPoint pos, Client* cl)
00602     {
00603     showWindowMenu(pos.x(), pos.y(), cl);
00604     }
00605 
00606 inline
00607 void Workspace::setWasUserInteraction()
00608     {
00609     was_user_interaction = true;
00610     }
00611 
00612 inline
00613 bool Workspace::managingTopMenus() const
00614     {
00615     return managing_topmenus;
00616     }
00617 
00618 inline void Workspace::sessionSaveStarted()
00619     {
00620     session_saving = true;
00621     }
00622 
00623 inline void Workspace::sessionSaveDone()
00624     {
00625     session_saving = false;
00626     }
00627 
00628 inline bool Workspace::sessionSaving() const
00629     {
00630     return session_saving;
00631     }
00632 
00633 template< typename T >
00634 inline Client* Workspace::findClient( T predicate )
00635     {
00636     if( Client* ret = findClientInList( clients, predicate ))
00637         return ret;
00638     if( Client* ret = findClientInList( desktops, predicate ))
00639         return ret;
00640     return NULL;
00641     }
00642 
00643 template< typename T1, typename T2 >
00644 inline void Workspace::forEachClient( T1 procedure, T2 predicate )
00645     {
00646     for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00647         if ( predicate( const_cast< const Client* >( *it)))
00648             procedure( *it );
00649     for ( ClientList::ConstIterator it = desktops.begin(); it != desktops.end(); ++it)
00650         if ( predicate( const_cast< const Client* >( *it)))
00651             procedure( *it );
00652     }
00653 
00654 template< typename T >
00655 inline void Workspace::forEachClient( T procedure )
00656     {
00657     return forEachClient( procedure, TruePredicate());
00658     }
00659 
00660 KWIN_COMPARE_PREDICATE( ClientMatchPredicate, const Client*, cl == value );
00661 inline bool Workspace::hasClient( const Client* c )
00662     {
00663     return findClient( ClientMatchPredicate( c ));
00664     }
00665 
00666 } // namespace
00667 
00668 #endif
KDE Logo
This file is part of the documentation for kwin Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Apr 11 13:44:54 2004 by doxygen 1.3.6-20040222 written by Dimitri van Heesch, © 1997-2003