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