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