kwin/workspace.h
Luboš Luňák dfcc58b00f Fix #49369 and generally try to improve window matching.
Use WM_WINDOW_ROLE also for fake sessions (Save window settings).
Remember also window type.

svn path=/trunk/kdebase/kwin/; revision=185456
2002-10-24 16:22:15 +00:00

513 lines
13 KiB
C++

/*****************************************************************
kwin - the KDE window manager
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
******************************************************************/
#ifndef KWIN_WORKSPACE_H
#define KWIN_WORKSPACE_H
#include <qwidget.h>
#include <qapplication.h>
#include <qpopupmenu.h>
#include <qguardedptr.h>
#include <qvaluelist.h>
#include <qptrlist.h>
#include <qtimer.h>
#include "options.h"
#include "KWinInterface.h"
#include <kshortcut.h>
#include <qcursor.h>
#include <netwm_def.h>
#include <X11/Xlib.h>
class KConfig;
class KGlobalAccel;
namespace KWinInternal {
class Client;
class TabBox;
class PopupInfo;
class RootInfo;
class PluginMgr;
typedef QValueList<Client*> ClientList;
class SystemTrayWindow
{
public:
SystemTrayWindow()
: win(0),winFor(0)
{}
SystemTrayWindow( WId w )
: win(w),winFor(0)
{}
SystemTrayWindow( WId w, WId wf )
: win(w),winFor(wf)
{}
bool operator==( const SystemTrayWindow& other )
{ return win == other.win; }
WId win;
WId winFor;
};
typedef QValueList<SystemTrayWindow> SystemTrayWindowList;
struct SessionInfo
{
QCString sessionId;
QCString windowRole;
QCString wmCommand;
QCString wmClientMachine;
QCString resourceName;
QCString resourceClass;
QRect geometry;
QRect restore;
int maximize;
int desktop;
bool iconified;
bool sticky;
bool shaded;
bool staysOnTop;
bool skipTaskbar;
bool skipPager;
NET::WindowType windowType;
};
class Shape {
public:
static bool hasShape( WId w);
static int shapeEvent();
};
class Motif {
public:
static bool noBorder( WId w );
static bool funcFlags( WId w, bool& resize, bool& move, bool& minimize,
bool& maximize, bool& close );
struct MwmHints {
ulong flags;
ulong functions;
ulong decorations;
long input_mode;
ulong status;
};
enum { MWM_HINTS_FUNCTIONS = (1L << 0),
MWM_HINTS_DECORATIONS = (1L << 1),
MWM_FUNC_ALL = (1L << 0),
MWM_FUNC_RESIZE = (1L << 1),
MWM_FUNC_MOVE = (1L << 2),
MWM_FUNC_MINIMIZE = (1L << 3),
MWM_FUNC_MAXIMIZE = (1L << 4),
MWM_FUNC_CLOSE = (1L << 5)
};
};
class WorkspacePrivate;
// NOTE: this class has to keep binary compatibility, just like other
// KWin classes accessible from the plugins
class Workspace : public QObject, virtual public KWinInterface
{
Q_OBJECT
public:
Workspace( bool restore = FALSE );
virtual ~Workspace();
static Workspace * self() { return _self; }
virtual bool workspaceEvent( XEvent * );
bool hasClient(Client *);
Client* findClient( WId w ) const;
QRect geometry() const;
enum clientAreaOption { PlacementArea, MovementArea, MaximizeArea };
// default is MaximizeArea
QRect clientArea(clientAreaOption, const QPoint& p);
QRect clientArea(const QPoint& p);
inline QRect clientArea(clientAreaOption opt) { return clientArea(opt, QCursor::pos()); }
void removeClient( Client* );
bool destroyClient( Client* );
/**
* @internal
* @obsolete
*/
void killWindowAtPosition(int x, int y);
/**
* @internal
*/
void killWindowId( Window window);
void killWindow() { slotKillWindow(); }
WId rootWin() const;
/**
* Returns the active client, i.e. the client that has the focus (or None
* if no client has the focus)
*/
Client* activeClient() const;
void setActiveClient( Client* );
void activateClient( Client*, bool force = FALSE );
void requestFocus( Client* c, bool force = FALSE );
void updateColormap();
void setFocusChangeEnabled(bool b) { focus_change = b; } // KDE 3.0: No longer used
bool focusChangeEnabled() { return focus_change; } // KDE 3.0: No longer used
/**
* Indicates that the client c is being moved around by the user.
*/
void setClientIsMoving( Client *c );
void place(Client *c);
void doPlacement(Client* c ); // obsolete KDE4 remove
QPoint adjustClientPosition( Client* c, QPoint pos );
void raiseClient( Client* c );
void lowerClient( Client* c );
void stackClientUnderActive( Client* );
void raiseOrLowerClient( Client * );
void reconfigure();
void clientHidden( Client* );
void clientReady( Client* );
void clientMoved(const QPoint &pos, unsigned long time);
/**
* Returns the current virtual desktop of this workspace
*/
int currentDesktop() const;
int nextDesktop( int iDesktop ) const;
int previousDesktop( int iDesktop ) const;
/**
* Returns the number of virtual desktops of this workspace
*/
int numberOfDesktops() const;
void setNumberOfDesktops( int n );
QWidget* desktopWidget();
Client* nextClient(Client*) const;
Client* previousClient(Client*) const;
Client* nextStaticClient(Client*) const;
Client* previousStaticClient(Client*) const;
/**
* Returns the list of clients sorted in stacking order, with topmost client
* at the last position
*/
const ClientList& stackingOrder() const;
Client* topClientOnDesktop() const;
void sendClientToDesktop( Client* c, int desktop );
/**
* @deprecated Use showWindowMenu()
*/
QPopupMenu* clientPopup( Client* );
/**
* @deprecated Use showWindowMenu()
*/
// KDE4 remove me - and it's also in the DCOP interface :(
void showWindowMenuAt( unsigned long id, int x, int y );
/**
* Shows the menu operations menu for the client
* and makes it active if it's not already.
*/
void showWindowMenu( int x, int y, Client* cl );
void showWindowMenu( QPoint pos, Client* cl );
void iconifyOrDeiconifyTransientsOf( Client* );
void setStickyTransientsOf( Client*, bool sticky );
bool hasCaption( const QString& caption );
void performWindowOperation( Client* c, Options::WindowOperation op );
void restoreLegacySession( KConfig* config );
void storeLegacySession( KConfig* config );
void storeSession( KConfig* config );
SessionInfo* takeSessionInfo( Client* );
virtual void updateClientArea();
// dcop interface
void cascadeDesktop();
void unclutterDesktop();
void doNotManage(QString);
void setCurrentDesktop( int new_desktop );
void nextDesktop();
void previousDesktop();
void circulateDesktopApplications();
QString desktopName( int desk );
void setDesktopLayout(int o, int x, int y);
bool isNotManaged( const QString& title );
public slots:
void refresh();
// keybindings
void slotSwitchDesktopNext();
void slotSwitchDesktopPrevious();
void slotSwitchDesktopRight();
void slotSwitchDesktopLeft();
void slotSwitchDesktopUp();
void slotSwitchDesktopDown();
void slotSwitchToDesktop( int );
//void slotSwitchToWindow( int );
void slotWindowToDesktop( int );
//void slotWindowToListPosition( int );
void slotWindowMaximize();
void slotWindowMaximizeVertical();
void slotWindowMaximizeHorizontal();
void slotWindowIconify();
void slotWindowIconifyAll();
void slotWindowShade();
void slotWindowRaise();
void slotWindowLower();
void slotWindowRaiseOrLower();
void slotWalkThroughDesktops();
void slotWalkBackThroughDesktops();
void slotWalkThroughDesktopList();
void slotWalkBackThroughDesktopList();
void slotWalkThroughWindows();
void slotWalkBackThroughWindows();
void slotWindowOperations();
void slotWindowClose();
void slotWindowMove();
void slotWindowResize();
void slotWindowToNextDesktop();
void slotWindowToPreviousDesktop();
void slotMouseEmulation();
void slotResetAllClientsDelayed();
void slotResetAllClients();
void slotSettingsChanged( int category );
void slotReconfigure();
void slotKillWindow();
void slotGrabWindow();
void slotGrabDesktop();
private slots:
void desktopPopupAboutToShow();
void clientPopupAboutToShow();
void sendToDesktop( int );
void clientPopupActivated( int );
void configureWM();
void focusEnsurance();
protected:
bool keyPress( XKeyEvent& ev );
bool keyRelease( XKeyEvent& ev );
bool keyPressMouseEmulation( XKeyEvent& ev );
bool netCheck( XEvent* e );
void checkStartOnDesktop( WId w );
private:
void init();
void initShortcuts();
void readShortcuts();
void initDesktopPopup();
bool startKDEWalkThroughWindows();
bool startWalkThroughDesktops( int mode ); // TabBox::Mode::DesktopMode | DesktopListMode
bool startWalkThroughDesktops();
bool startWalkThroughDesktopList();
void KDEWalkThroughWindows( bool forward );
void CDEWalkThroughWindows( bool forward );
void walkThroughDesktops( bool forward );
void KDEOneStepThroughWindows( bool forward );
void oneStepThroughDesktops( bool forward, int mode ); // TabBox::Mode::DesktopMode | DesktopListMode
void oneStepThroughDesktops( bool forward );
void oneStepThroughDesktopList( bool forward );
ClientList constrainedStackingOrder( const ClientList& list );
Client* clientFactory(WId w);
void raiseTransientsOf( ClientList& safeset, Client* c );
void lowerTransientsOf( ClientList& safeset, Client* c );
void randomPlacement(Client* c);
void smartPlacement(Client* c);
void cascadePlacement(Client* c, bool re_init = false);
void focusToNull();
Client* findClientWithId( WId w ) const;
void propagateClients( bool onlyStacking = FALSE);
bool addSystemTrayWin( WId w );
bool removeSystemTrayWin( WId w );
void propagateSystemTrayWins();
SystemTrayWindow findSystemTrayWin( WId w );
// desktop names and number of desktops
void loadDesktopSettings();
void saveDesktopSettings();
// mouse emulation
WId getMouseEmulationWindow();
enum MouseEmulation { EmuPress, EmuRelease, EmuMove };
unsigned int sendFakedMouseEvent( QPoint pos, WId win, MouseEmulation type, int button, unsigned int state ); // returns the new state
// electric borders
void createBorderWindows();
void destroyBorderWindows();
void electricBorder(XEvent * e);
void raiseElectricBorders();
// ------------------
void calcDesktopLayout(int &x, int &y);
QPopupMenu* clientPopup();
SystemTrayWindowList systemTrayWins;
int current_desktop;
int number_of_desktops;
QMemArray<int> desktop_focus_chain;
Client* popup_client;
void loadSessionInfo();
QWidget* desktop_widget;
QPtrList<SessionInfo> session;
QPtrList<SessionInfo> fakeSession;
void loadFakeSessionInfo();
void storeFakeSessionInfo( Client* c );
void writeFakeSessionInfo();
static const char* windowTypeToTxt( NET::WindowType type );
static NET::WindowType txtToWindowType( const char* txt );
static bool sessionInfoWindowTypeMatch( Client* c, SessionInfo* info );
Client* active_client;
Client* last_active_client;
Client* should_get_focus;
Client* most_recently_raised;
ClientList clients;
ClientList desktops;
ClientList stacking_order;
ClientList focus_chain;
bool control_grab;
bool tab_grab;
//KKeyNative walkThroughDesktopsKeycode, walkBackThroughDesktopsKeycode;
//KKeyNative walkThroughDesktopListKeycode, walkBackThroughDesktopListKeycode;
//KKeyNative walkThroughWindowsKeycode, walkBackThroughWindowsKeycode;
KShortcut cutWalkThroughDesktops, cutWalkThroughDesktopsReverse;
KShortcut cutWalkThroughDesktopList, cutWalkThroughDesktopListReverse;
KShortcut cutWalkThroughWindows, cutWalkThroughWindowsReverse;
bool mouse_emulation;
unsigned int mouse_emulation_state;
WId mouse_emulation_window;
bool focus_change;
TabBox* tab_box;
PopupInfo* popupinfo;
QPopupMenu *popup;
QPopupMenu *desk_popup;
KGlobalAccel *keys;
WId root;
PluginMgr *mgr;
RootInfo *rootInfo;
QWidget* supportWindow;
QRect area;
// swallowing
QStringList doNotManageList;
// colormap handling
Colormap default_colormap;
Colormap installed_colormap;
// Timer to collect requests for 'ResetAllClients'
QTimer resetTimer;
// Timer to collect requests for 'reconfigure'
QTimer reconfigureTimer;
QTimer focusEnsuranceTimer;
WorkspacePrivate* d;
static Workspace *_self;
void addClient( Client* c );
};
inline WId Workspace::rootWin() const
{
return root;
}
inline Client* Workspace::activeClient() const
{
return active_client;
}
inline int Workspace::currentDesktop() const
{
return current_desktop;
}
inline int Workspace::numberOfDesktops() const
{
return number_of_desktops;
}
inline const ClientList& Workspace::stackingOrder() const
{
return stacking_order;
}
inline void Workspace::showWindowMenu(QPoint pos, Client* cl)
{
showWindowMenu(pos.x(), pos.y(), cl);
}
};
#endif