2000-03-24 22:23:02 +00:00
|
|
|
/*****************************************************************
|
|
|
|
kwin - the KDE window manager
|
2000-04-06 18:29:04 +00:00
|
|
|
|
2000-03-24 22:23:02 +00:00
|
|
|
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|
|
|
******************************************************************/
|
1999-08-19 23:26:42 +00:00
|
|
|
#ifndef WORKSPACE_H
|
|
|
|
#define WORKSPACE_H
|
|
|
|
|
|
|
|
#include <qwidget.h>
|
|
|
|
#include <qapplication.h>
|
|
|
|
#include <qpopupmenu.h>
|
1999-11-22 01:57:51 +00:00
|
|
|
#include <qguardedptr.h>
|
1999-08-19 23:26:42 +00:00
|
|
|
#include <qvaluelist.h>
|
2000-03-24 22:23:02 +00:00
|
|
|
#include <qlist.h>
|
1999-08-19 23:26:42 +00:00
|
|
|
#include <X11/Xlib.h>
|
1999-11-29 02:06:41 +00:00
|
|
|
#include "options.h"
|
1999-12-24 01:36:47 +00:00
|
|
|
#include "plugins.h"
|
2000-05-04 23:12:29 +00:00
|
|
|
#include "KWinInterface.h"
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
class Client;
|
|
|
|
class TabBox;
|
1999-11-07 08:46:36 +00:00
|
|
|
|
2000-03-24 22:23:02 +00:00
|
|
|
class KConfig;
|
1999-11-07 08:46:36 +00:00
|
|
|
class KGlobalAccel;
|
1999-08-19 23:26:42 +00:00
|
|
|
|
|
|
|
typedef QValueList<Client*> ClientList;
|
1999-11-14 06:34:28 +00:00
|
|
|
|
Preliminary support for avoiding covering clients such as kicker
which want to be permanently visible.
I've used an XAtom called '_NET_AVOID_SPEC'. This of course can change
if need be. I think it's correct according to the wm spec, but the
wm spec seems to be empty on gnome.org, so who knows.
Windows can choose to be avoided by setting an XTextProperty
with one value, which can be either 'N', 'S', 'E', or 'W', according
to which screen edge they are anchored to.
kwin then sets its 'clientArea' rect appropriately, so that (in
theory at least) clients will not enter this area in some circumstances,
such as when being mapped for the first time.
You can see that this actually works if you start lots of konsoles. They
don't appear over the panel. I don't know what happens if you move the
panel, but I presume things will be screwed up, because I haven't
looked at that yet.
If you maximise a window, it'll still fill the screen, because the
implementation of maximise in kwin/client.cpp doesn't take account
of the workspace's clientArea rect. This is easy to fix, but I've
been awake for too long, so I'll do it after 42 winks.
svn path=/trunk/kdebase/kwin/; revision=46772
2000-04-16 09:06:03 +00:00
|
|
|
enum AnchorEdge { AnchorNorth, AnchorSouth, AnchorEast, AnchorWest };
|
|
|
|
|
1999-11-14 06:34:28 +00:00
|
|
|
class DockWindow
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
DockWindow()
|
|
|
|
: dockWin(0),dockFor(0)
|
|
|
|
{}
|
|
|
|
DockWindow( WId w )
|
|
|
|
: dockWin(w),dockFor(0)
|
|
|
|
{}
|
|
|
|
DockWindow( WId w, WId wf )
|
|
|
|
: dockWin(w),dockFor(wf)
|
|
|
|
{}
|
1999-11-15 00:52:05 +00:00
|
|
|
|
1999-11-14 06:34:28 +00:00
|
|
|
bool operator==( const DockWindow& other )
|
|
|
|
{ return dockWin == other.dockWin; }
|
|
|
|
WId dockWin;
|
|
|
|
WId dockFor;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef QValueList<DockWindow> DockWindowList;
|
1999-08-19 23:26:42 +00:00
|
|
|
|
2000-03-24 22:23:02 +00:00
|
|
|
|
|
|
|
struct SessionInfo
|
|
|
|
{
|
|
|
|
QCString sessionId;
|
|
|
|
QCString windowRole;
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
int desktop;
|
|
|
|
bool iconified;
|
|
|
|
bool sticky;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-11-12 03:11:19 +00:00
|
|
|
class Shape {
|
|
|
|
public:
|
|
|
|
static bool hasShape( WId w);
|
|
|
|
static int shapeEvent();
|
|
|
|
};
|
|
|
|
|
2000-04-06 18:29:04 +00:00
|
|
|
class Motif {
|
|
|
|
public:
|
|
|
|
static bool noBorder( WId w );
|
|
|
|
};
|
|
|
|
|
2000-05-04 23:12:29 +00:00
|
|
|
class Workspace : public QObject, virtual public KWinInterface
|
1999-08-19 23:26:42 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2000-03-24 22:23:02 +00:00
|
|
|
Workspace( bool restore = FALSE );
|
1999-08-19 23:26:42 +00:00
|
|
|
virtual ~Workspace();
|
|
|
|
|
|
|
|
virtual bool workspaceEvent( XEvent * );
|
|
|
|
|
1999-11-07 08:46:36 +00:00
|
|
|
bool hasClient(Client *);
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
Client* findClient( WId w ) const;
|
|
|
|
|
|
|
|
QRect geometry() const;
|
2000-05-06 18:59:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the area available for clients. This is the desktop
|
|
|
|
* geometry adjusted for edge-anchored windows.
|
|
|
|
* Placement algorithms should refer to this rather than geometry().
|
|
|
|
* @sa geometry()
|
|
|
|
*/
|
|
|
|
QRect clientArea();
|
1999-08-19 23:26:42 +00:00
|
|
|
|
|
|
|
bool destroyClient( Client* );
|
|
|
|
|
2000-05-17 23:02:42 +00:00
|
|
|
void killWindowAtPosition(int x, int y);
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
WId rootWin() const;
|
|
|
|
|
2000-05-04 23:12:29 +00:00
|
|
|
/**
|
|
|
|
* Returns the active client, i.e. the client that has the focus (or None
|
|
|
|
* if no client has the focus)
|
|
|
|
*/
|
1999-08-19 23:26:42 +00:00
|
|
|
Client* activeClient() const;
|
2000-05-04 23:12:29 +00:00
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
void setActiveClient( Client* );
|
|
|
|
void activateClient( Client* );
|
|
|
|
void requestFocus( Client* c);
|
|
|
|
|
|
|
|
void doPlacement( Client* c );
|
1999-11-25 16:38:11 +00:00
|
|
|
QPoint adjustClientPosition( Client* c, QPoint pos );
|
1999-08-19 23:26:42 +00:00
|
|
|
void raiseClient( Client* c );
|
2000-05-03 12:57:37 +00:00
|
|
|
void lowerClient( Client* c, bool dropFocus=true );
|
1999-08-19 23:26:42 +00:00
|
|
|
|
|
|
|
void clientHidden( Client* );
|
|
|
|
|
2000-05-04 23:12:29 +00:00
|
|
|
/**
|
|
|
|
* Returns the current virtual desktop of this workspace
|
|
|
|
*/
|
1999-08-19 23:26:42 +00:00
|
|
|
int currentDesktop() const;
|
2000-05-04 23:12:29 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the number of virtual desktops of this workspace
|
|
|
|
*/
|
1999-08-19 23:26:42 +00:00
|
|
|
int numberOfDesktops() const;
|
1999-11-07 01:43:06 +00:00
|
|
|
void setNumberOfDesktops( int n );
|
|
|
|
|
1999-09-27 16:02:44 +00:00
|
|
|
QWidget* desktopWidget();
|
1999-08-19 23:26:42 +00:00
|
|
|
|
|
|
|
void grabKey(KeySym keysym, unsigned int mod);
|
|
|
|
|
|
|
|
Client* nextClient(Client*) const;
|
|
|
|
Client* previousClient(Client*) const;
|
|
|
|
Client* nextStaticClient(Client*) const;
|
|
|
|
Client* previousStaticClient(Client*) const;
|
2000-05-04 23:12:29 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the list of clients sorted in stacking order, with topmost client
|
|
|
|
* at the last position
|
|
|
|
*/
|
2000-05-03 00:04:26 +00:00
|
|
|
const ClientList& stackingOrder() const;
|
1999-08-19 23:26:42 +00:00
|
|
|
|
|
|
|
//#### TODO right layers as default
|
|
|
|
Client* topClientOnDesktop( int fromLayer = 0, int toLayer = 0) const;
|
|
|
|
|
|
|
|
|
1999-11-22 01:57:51 +00:00
|
|
|
QPopupMenu* clientPopup( Client* );
|
1999-11-25 16:38:11 +00:00
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
void setDesktopClient( Client* );
|
|
|
|
|
1999-11-14 06:34:28 +00:00
|
|
|
bool iconifyMeansWithdraw( Client* );
|
1999-11-28 20:10:58 +00:00
|
|
|
void iconifyOrDeiconifyTransientsOf( Client* );
|
2000-01-10 03:47:30 +00:00
|
|
|
void setStickyTransientsOf( Client*, bool sticky );
|
1999-12-06 00:43:55 +00:00
|
|
|
|
1999-11-28 20:55:52 +00:00
|
|
|
bool hasCaption( const QString& caption );
|
1999-11-14 06:34:28 +00:00
|
|
|
|
1999-11-29 02:06:41 +00:00
|
|
|
void performWindowOperation( Client* c, Options::WindowOperation op );
|
|
|
|
|
1999-12-24 01:36:47 +00:00
|
|
|
Client* clientFactory(Workspace *ws, WId w);
|
2000-04-06 18:29:04 +00:00
|
|
|
|
2000-03-24 22:23:02 +00:00
|
|
|
void storeSession( KConfig* config );
|
2000-04-06 18:29:04 +00:00
|
|
|
|
2000-03-24 22:23:02 +00:00
|
|
|
SessionInfo* takeSessionInfo( Client* );
|
2000-04-26 21:28:51 +00:00
|
|
|
|
2000-05-04 23:12:29 +00:00
|
|
|
/**
|
|
|
|
* When the area that is available for clients (that which is not
|
|
|
|
* taken by windows like panels, the top-of-screen menu etc) may
|
|
|
|
* have changed, this will recalculate the available space.
|
|
|
|
*/
|
|
|
|
virtual void updateClientArea();
|
2000-05-06 18:59:43 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the area available for edge-anchored windows. This
|
|
|
|
* is the desktop geometry adjusted for other edge-anchored
|
|
|
|
* windows that have priority.
|
|
|
|
*/
|
|
|
|
virtual QRect edgeClientArea();
|
1999-11-29 02:06:41 +00:00
|
|
|
|
1999-11-14 06:34:28 +00:00
|
|
|
public slots:
|
1999-11-22 01:57:51 +00:00
|
|
|
void setCurrentDesktop( int new_desktop );
|
1999-11-13 01:51:22 +00:00
|
|
|
// keybindings
|
|
|
|
void slotSwitchDesktop1();
|
|
|
|
void slotSwitchDesktop2();
|
|
|
|
void slotSwitchDesktop3();
|
|
|
|
void slotSwitchDesktop4();
|
|
|
|
void slotSwitchDesktop5();
|
|
|
|
void slotSwitchDesktop6();
|
|
|
|
void slotSwitchDesktop7();
|
|
|
|
void slotSwitchDesktop8();
|
1999-11-25 16:38:11 +00:00
|
|
|
|
1999-11-29 02:18:29 +00:00
|
|
|
void slotWindowMaximize();
|
|
|
|
void slotWindowMaximizeVertical();
|
|
|
|
void slotWindowMaximizeHorizontal();
|
|
|
|
void slotWindowIconify();
|
1999-11-29 02:49:20 +00:00
|
|
|
void slotWindowShade();
|
1999-11-29 02:18:29 +00:00
|
|
|
|
1999-11-22 01:57:51 +00:00
|
|
|
void slotWindowOperations();
|
|
|
|
void slotWindowClose();
|
1999-12-06 00:43:55 +00:00
|
|
|
void slotWindowMove();
|
|
|
|
void slotWindowResize();
|
|
|
|
|
|
|
|
void slotMouseEmulation();
|
1999-11-25 16:38:11 +00:00
|
|
|
|
1999-12-24 01:36:47 +00:00
|
|
|
void slotResetAllClients();
|
|
|
|
|
2000-05-17 20:15:17 +00:00
|
|
|
void slotLogout();
|
|
|
|
|
2000-05-17 23:02:42 +00:00
|
|
|
void slotKillWindow();
|
|
|
|
|
1999-11-22 01:57:51 +00:00
|
|
|
private slots:
|
|
|
|
void desktopPopupAboutToShow();
|
|
|
|
void clientPopupAboutToShow();
|
|
|
|
void sendToDesktop( int );
|
|
|
|
void clientPopupActivated( int );
|
1999-11-07 08:46:36 +00:00
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
protected:
|
|
|
|
bool keyPress( XKeyEvent key );
|
|
|
|
bool keyRelease( XKeyEvent key );
|
1999-12-06 00:43:55 +00:00
|
|
|
bool keyPressMouseEmulation( XKeyEvent key );
|
1999-11-07 01:43:06 +00:00
|
|
|
bool clientMessage( XClientMessageEvent msg );
|
2000-03-22 12:36:07 +00:00
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
private:
|
|
|
|
void init();
|
1999-11-13 01:51:22 +00:00
|
|
|
void createKeybindings();
|
1999-08-19 23:26:42 +00:00
|
|
|
void freeKeyboard(bool pass);
|
|
|
|
|
|
|
|
void raiseTransientsOf( ClientList& safeset, Client* c );
|
2000-05-03 06:30:37 +00:00
|
|
|
void lowerTransientsOf( ClientList& safeset, Client* c );
|
1999-08-19 23:26:42 +00:00
|
|
|
void randomPlacement(Client* c);
|
1999-11-16 08:53:02 +00:00
|
|
|
void smartPlacement(Client* c);
|
1999-11-20 06:27:07 +00:00
|
|
|
void cascadePlacement(Client* c, bool re_init = false);
|
1999-08-19 23:26:42 +00:00
|
|
|
|
1999-12-03 21:08:07 +00:00
|
|
|
enum CleanupType { Cascade, Unclutter };
|
|
|
|
void deskCleanup(CleanupType);
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
void focusToNull();
|
|
|
|
|
2000-05-04 23:12:29 +00:00
|
|
|
Client* findClientWidthId( WId w ) const;
|
1999-09-27 16:02:44 +00:00
|
|
|
|
1999-11-07 01:43:06 +00:00
|
|
|
void propagateClients( bool onlyStacking = FALSE);
|
1999-11-12 03:11:19 +00:00
|
|
|
|
1999-11-11 01:22:41 +00:00
|
|
|
bool addDockwin( WId w );
|
|
|
|
bool removeDockwin( WId w );
|
|
|
|
void propagateDockwins();
|
1999-11-14 06:34:28 +00:00
|
|
|
DockWindow findDockwin( WId w );
|
1999-12-06 00:43:55 +00:00
|
|
|
|
1999-11-20 06:27:07 +00:00
|
|
|
//CT needed for cascading+
|
|
|
|
struct CascadingInfo {
|
|
|
|
QPoint pos;
|
|
|
|
int col;
|
|
|
|
int row;
|
|
|
|
};
|
2000-05-04 23:12:29 +00:00
|
|
|
|
|
|
|
// ------------------
|
|
|
|
|
|
|
|
DockWindowList dockwins;
|
|
|
|
|
|
|
|
int current_desktop;
|
|
|
|
int number_of_desktops;
|
|
|
|
|
|
|
|
QGuardedPtr<Client> popup_client;
|
|
|
|
|
|
|
|
void loadSessionInfo();
|
|
|
|
|
|
|
|
QWidget* desktop_widget;
|
|
|
|
|
|
|
|
QList<SessionInfo> session;
|
1999-11-20 06:27:07 +00:00
|
|
|
QValueList<CascadingInfo> cci;
|
2000-05-04 23:12:29 +00:00
|
|
|
|
|
|
|
Client* desktop_client;
|
|
|
|
Client* active_client;
|
|
|
|
Client* should_get_focus;
|
|
|
|
|
|
|
|
ClientList clients;
|
|
|
|
ClientList stacking_order;
|
|
|
|
ClientList focus_chain;
|
|
|
|
|
|
|
|
bool control_grab;
|
|
|
|
bool tab_grab;
|
|
|
|
bool mouse_emulation;
|
|
|
|
|
|
|
|
TabBox* tab_box;
|
|
|
|
|
|
|
|
QPopupMenu *popup;
|
|
|
|
QPopupMenu *desk_popup;
|
|
|
|
|
|
|
|
KGlobalAccel *keys;
|
|
|
|
WId root;
|
|
|
|
|
1999-11-22 01:57:51 +00:00
|
|
|
// -cascading
|
1999-12-03 21:08:07 +00:00
|
|
|
Atom kwm_command;
|
1999-12-24 01:36:47 +00:00
|
|
|
|
|
|
|
PluginMgr mgr;
|
Preliminary support for avoiding covering clients such as kicker
which want to be permanently visible.
I've used an XAtom called '_NET_AVOID_SPEC'. This of course can change
if need be. I think it's correct according to the wm spec, but the
wm spec seems to be empty on gnome.org, so who knows.
Windows can choose to be avoided by setting an XTextProperty
with one value, which can be either 'N', 'S', 'E', or 'W', according
to which screen edge they are anchored to.
kwin then sets its 'clientArea' rect appropriately, so that (in
theory at least) clients will not enter this area in some circumstances,
such as when being mapped for the first time.
You can see that this actually works if you start lots of konsoles. They
don't appear over the panel. I don't know what happens if you move the
panel, but I presume things will be screwed up, because I haven't
looked at that yet.
If you maximise a window, it'll still fill the screen, because the
implementation of maximise in kwin/client.cpp doesn't take account
of the workspace's clientArea rect. This is easy to fix, but I've
been awake for too long, so I'll do it after 42 winks.
svn path=/trunk/kdebase/kwin/; revision=46772
2000-04-16 09:06:03 +00:00
|
|
|
|
2000-05-06 18:59:43 +00:00
|
|
|
QRect clientArea_, edgeClientArea_;
|
1999-08-19 23:26:42 +00:00
|
|
|
};
|
|
|
|
|
2000-05-05 18:53:37 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
#endif
|