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 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;
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;
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
00442
00443
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
00469 QStringList doNotManageList;
00470
00471
00472 Colormap default_colormap;
00473 Colormap installed_colormap;
00474
00475
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;
00507
00508
bool managing_topmenus;
00509 KSelectionOwner* topmenu_selection;
00510 KSelectionWatcher* topmenu_watcher;
00511 ClientList topmenus;
00512
mutable int topmenu_height;
00513 QWidget* topmenu_space;
00514
00515
int set_active_client_recursion;
00516
int block_stacking_updates;
00517
bool blocked_propagating_new_clients;
00518
friend class StackingUpdatesBlocker;
00519 };
00520
00521
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
00534
class RootInfo :
public NETRootInfo2
00535 {
00536
private:
00537
typedef KWinInternal::Client 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
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
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 }
00667
00668
#endif