2000-05-07 20:38:11 +00:00
|
|
|
/*****************************************************************
|
|
|
|
kwin - the KDE window manager
|
|
|
|
|
|
|
|
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
|
|
|
|
******************************************************************/
|
1999-08-19 23:26:42 +00:00
|
|
|
#ifndef CLIENT_H
|
|
|
|
#define CLIENT_H
|
|
|
|
|
|
|
|
#include "options.h"
|
1999-11-07 01:43:06 +00:00
|
|
|
#include <kwm.h>
|
1999-08-19 23:26:42 +00:00
|
|
|
#include <qframe.h>
|
|
|
|
#include <qvbox.h>
|
|
|
|
#include <qpixmap.h>
|
2000-05-07 23:10:21 +00:00
|
|
|
#include <qtimer.h>
|
1999-08-19 23:26:42 +00:00
|
|
|
#include <X11/X.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
|
|
|
|
class Workspace;
|
|
|
|
class Client;
|
|
|
|
|
|
|
|
class WindowWrapper : public QWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
WindowWrapper( WId w, Client *parent=0, const char* name=0);
|
|
|
|
~WindowWrapper();
|
|
|
|
|
1999-11-28 20:10:58 +00:00
|
|
|
WId window() const;
|
1999-08-19 23:26:42 +00:00
|
|
|
void releaseWindow();
|
|
|
|
void invalidateWindow();
|
|
|
|
QSize sizeHint() const;
|
|
|
|
QSizePolicy sizePolicy() const;
|
1999-11-22 01:57:51 +00:00
|
|
|
|
2000-03-29 14:53:25 +00:00
|
|
|
void setActive( bool );
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
protected:
|
|
|
|
void resizeEvent( QResizeEvent * );
|
|
|
|
void showEvent( QShowEvent* );
|
|
|
|
void hideEvent( QHideEvent* );
|
|
|
|
bool x11Event( XEvent * ); // X11 event
|
|
|
|
|
2000-05-07 23:10:21 +00:00
|
|
|
private slots:
|
|
|
|
void doResize();
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
private:
|
|
|
|
WId win;
|
|
|
|
Time lastMouseEventTime;
|
2000-03-22 11:47:10 +00:00
|
|
|
bool reparented;
|
2000-05-07 23:10:21 +00:00
|
|
|
QTimer* timer;
|
2000-05-08 20:22:10 +00:00
|
|
|
int cnt;
|
1999-08-19 23:26:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
inline WId WindowWrapper::window() const
|
|
|
|
{
|
|
|
|
return win;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Client : public QWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
Client( Workspace *ws, WId w, QWidget *parent=0, const char *name=0, WFlags f = 0);
|
|
|
|
~Client();
|
|
|
|
|
1999-11-28 20:10:58 +00:00
|
|
|
WId window() const;
|
|
|
|
WindowWrapper* windowWrapper() const;
|
|
|
|
Workspace* workspace() const;
|
1999-08-19 23:26:42 +00:00
|
|
|
void releaseWindow();
|
|
|
|
void invalidateWindow();
|
1999-11-28 20:10:58 +00:00
|
|
|
WId transientFor() const;
|
|
|
|
bool isTransient() const;
|
|
|
|
Client* mainClient();
|
1999-08-19 23:26:42 +00:00
|
|
|
|
2000-05-04 23:12:29 +00:00
|
|
|
void updateAvoidPolicy();
|
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
|
|
|
bool avoid() const { return avoid_; }
|
|
|
|
int anchorEdge() const { return anchorEdge_; }
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
virtual bool windowEvent( XEvent * );
|
|
|
|
|
|
|
|
void manage( bool isMapped = FALSE );
|
|
|
|
|
|
|
|
void setMappingState( int s );
|
|
|
|
int mappingState() const;
|
|
|
|
|
|
|
|
void requestActivation();
|
|
|
|
void withdraw();
|
|
|
|
|
|
|
|
QSize adjustedSize( const QSize& ) const;
|
|
|
|
|
1999-11-28 20:10:58 +00:00
|
|
|
QPixmap icon() const;
|
|
|
|
QPixmap miniIcon() const;
|
1999-08-19 23:26:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
// is the window in withdrawn state?
|
|
|
|
bool isWithdrawn(){
|
|
|
|
return state == WithdrawnState;
|
|
|
|
}
|
|
|
|
// is the window in iconic state?
|
|
|
|
bool isIconified(){
|
|
|
|
return state == IconicState;
|
|
|
|
}
|
|
|
|
// is the window in normal state?
|
|
|
|
bool isNormal(){
|
|
|
|
return state == NormalState;
|
|
|
|
}
|
|
|
|
|
1999-11-28 20:10:58 +00:00
|
|
|
bool isActive() const;
|
1999-08-19 23:26:42 +00:00
|
|
|
void setActive( bool );
|
|
|
|
|
|
|
|
int desktop() const;
|
1999-11-22 01:57:51 +00:00
|
|
|
void setDesktop( int );
|
1999-08-19 23:26:42 +00:00
|
|
|
bool isOnDesktop( int d ) const;
|
|
|
|
|
|
|
|
bool isShade() const;
|
|
|
|
virtual void setShade( bool );
|
|
|
|
|
1999-11-28 20:10:58 +00:00
|
|
|
bool isMaximized() const;
|
1999-08-19 23:26:42 +00:00
|
|
|
enum MaximizeMode { MaximizeVertical, MaximizeHorizontal, MaximizeFull };
|
|
|
|
|
1999-11-28 20:10:58 +00:00
|
|
|
bool isSticky() const;
|
1999-08-19 23:26:42 +00:00
|
|
|
void setSticky( bool );
|
|
|
|
|
2000-04-19 04:36:47 +00:00
|
|
|
bool mayMove() const { return may_move; }
|
|
|
|
void setMayMove( bool m) { may_move = m; }
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
void takeFocus();
|
|
|
|
|
1999-09-27 16:02:44 +00:00
|
|
|
void setMask( const QRegion & );
|
2000-05-03 00:04:26 +00:00
|
|
|
const QRegion& getMask() const;
|
1999-11-02 00:32:31 +00:00
|
|
|
|
1999-09-27 16:02:44 +00:00
|
|
|
// transparent stuff
|
|
|
|
virtual void drawbound( const QRect& geom );
|
|
|
|
virtual void clearbound();
|
1999-11-14 06:34:28 +00:00
|
|
|
|
|
|
|
|
1999-11-12 03:11:19 +00:00
|
|
|
// shape extensions
|
|
|
|
bool shape() const;
|
|
|
|
void updateShape();
|
1999-09-27 16:02:44 +00:00
|
|
|
|
1999-11-13 00:32:36 +00:00
|
|
|
void setGeometry( int x, int y, int w, int h );
|
|
|
|
void setGeometry( const QRect &r )
|
|
|
|
{ setGeometry( r.left(), r.top(), r.width(), r.height() ); }
|
|
|
|
void move( int x, int y );
|
|
|
|
void move( const QPoint & p )
|
|
|
|
{ move( p.x(), p.y() ); }
|
1999-11-15 00:52:05 +00:00
|
|
|
|
1999-11-22 01:57:51 +00:00
|
|
|
|
1999-11-17 17:25:26 +00:00
|
|
|
virtual bool wantsTabFocus() const { return TRUE;} //### just for now
|
1999-12-06 00:43:55 +00:00
|
|
|
|
1999-12-01 22:09:32 +00:00
|
|
|
bool providesContextHelp() const;
|
1999-11-15 00:52:05 +00:00
|
|
|
|
1999-11-29 02:06:41 +00:00
|
|
|
bool performMouseCommand( Options::MouseCommand, QPoint globalPos );
|
2000-03-29 14:53:25 +00:00
|
|
|
|
2000-03-24 22:23:02 +00:00
|
|
|
QCString windowRole();
|
|
|
|
QCString sessionId();
|
1999-11-13 00:32:36 +00:00
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
public slots:
|
|
|
|
void iconify();
|
|
|
|
void closeWindow();
|
|
|
|
void maximize( MaximizeMode );
|
|
|
|
void maximize();
|
|
|
|
void toggleSticky();
|
1999-12-01 22:09:32 +00:00
|
|
|
void contextHelp();
|
1999-08-19 23:26:42 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
void paintEvent( QPaintEvent * );
|
|
|
|
void mousePressEvent( QMouseEvent * );
|
|
|
|
void mouseReleaseEvent( QMouseEvent * );
|
|
|
|
void mouseMoveEvent( QMouseEvent * );
|
1999-12-06 00:43:55 +00:00
|
|
|
void keyPressEvent( QKeyEvent * );
|
1999-11-16 01:25:42 +00:00
|
|
|
void resizeEvent( QResizeEvent * );
|
1999-11-22 01:57:51 +00:00
|
|
|
virtual void windowWrapperShowEvent( QShowEvent* ){}
|
|
|
|
virtual void windowWrapperHideEvent( QHideEvent* ){}
|
1999-08-19 23:26:42 +00:00
|
|
|
void enterEvent( QEvent * );
|
|
|
|
void leaveEvent( QEvent * );
|
|
|
|
void showEvent( QShowEvent* );
|
|
|
|
void hideEvent( QHideEvent* );
|
|
|
|
bool x11Event( XEvent * ); // X11 event
|
|
|
|
|
|
|
|
bool eventFilter( QObject *, QEvent * );
|
|
|
|
|
|
|
|
|
|
|
|
virtual void init();
|
|
|
|
virtual void captionChange( const QString& name );
|
|
|
|
virtual void iconChange();
|
|
|
|
virtual void activeChange( bool );
|
|
|
|
virtual void maximizeChange( bool );
|
|
|
|
virtual void stickyChange( bool );
|
|
|
|
|
|
|
|
|
|
|
|
enum MousePosition {
|
|
|
|
Nowhere, TopLeft , BottomRight, BottomLeft, TopRight, Top, Bottom, Left, Right, Center
|
|
|
|
};
|
|
|
|
|
|
|
|
virtual MousePosition mousePosition( const QPoint& ) const;
|
|
|
|
virtual void setMouseCursor( MousePosition m );
|
|
|
|
|
|
|
|
// handlers for X11 events
|
|
|
|
bool mapRequest( XMapRequestEvent& e );
|
|
|
|
bool unmapNotify( XUnmapEvent& e );
|
|
|
|
bool configureRequest( XConfigureRequestEvent& e );
|
|
|
|
bool propertyNotify( XPropertyEvent& e );
|
1999-11-28 20:10:58 +00:00
|
|
|
bool clientMessage( XClientMessageEvent& e );
|
1999-08-19 23:26:42 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
QSize sizeForWindowSize( const QSize&, bool ignore_height = FALSE ) const;
|
|
|
|
void getWmNormalHints();
|
|
|
|
void fetchName();
|
|
|
|
void gravitate( bool invert );
|
|
|
|
|
|
|
|
|
|
|
|
WId win;
|
|
|
|
WindowWrapper* wwrap;
|
|
|
|
Workspace* wspace;
|
|
|
|
int desk;
|
|
|
|
bool buttonDown;
|
1999-09-27 16:02:44 +00:00
|
|
|
bool moveResizeMode;
|
|
|
|
bool isMove() const {
|
|
|
|
return moveResizeMode && mode == Center;
|
|
|
|
}
|
|
|
|
bool isResize() const {
|
1999-11-28 16:25:59 +00:00
|
|
|
return moveResizeMode && !isMove();
|
1999-09-27 16:02:44 +00:00
|
|
|
}
|
1999-08-19 23:26:42 +00:00
|
|
|
MousePosition mode;
|
|
|
|
QPoint moveOffset;
|
|
|
|
QPoint invertedMoveOffset;
|
|
|
|
QSize clientSize;
|
|
|
|
XSizeHints xSizeHint;
|
|
|
|
void sendSynteticConfigureNotify();
|
|
|
|
int state;
|
|
|
|
bool active;
|
|
|
|
QRect original_geometry;
|
1999-09-27 16:02:44 +00:00
|
|
|
QRect geom; //### TODO
|
1999-08-19 23:26:42 +00:00
|
|
|
bool shaded;
|
|
|
|
WId transient_for;
|
|
|
|
bool is_sticky;
|
1999-11-12 03:11:19 +00:00
|
|
|
bool is_shape;
|
2000-04-19 04:36:47 +00:00
|
|
|
bool may_move;
|
1999-11-28 20:10:58 +00:00
|
|
|
void getWMHints();
|
1999-08-19 23:26:42 +00:00
|
|
|
void getWindowProtocols();
|
|
|
|
uint Pdeletewindow :1; // does the window understand the DeleteWindow protocol?
|
|
|
|
uint Ptakefocus :1;// does the window understand the TakeFocus protocol?
|
1999-12-01 22:09:32 +00:00
|
|
|
uint Pcontexthelp : 1; // does the window understand the ContextHelp protocol?
|
1999-11-28 20:10:58 +00:00
|
|
|
uint input :1; // does the window want input in its wm_hints
|
1999-11-22 01:57:51 +00:00
|
|
|
uint mapped :1; // keeps track of our visiblity within the asynchronous event flow
|
1999-08-19 23:26:42 +00:00
|
|
|
QPixmap icon_pix;
|
|
|
|
QPixmap miniicon_pix;
|
|
|
|
QRect geom_restore;
|
1999-09-27 16:02:44 +00:00
|
|
|
QRegion mask;
|
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
|
|
|
|
|
|
|
bool avoid_;
|
|
|
|
int anchorEdge_;
|
1999-08-19 23:26:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
inline WId Client::window() const
|
|
|
|
{
|
|
|
|
return win;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline WindowWrapper* Client::windowWrapper() const
|
|
|
|
{
|
|
|
|
return wwrap;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Workspace* Client::workspace() const
|
|
|
|
{
|
|
|
|
return wspace;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline WId Client::transientFor() const
|
|
|
|
{
|
|
|
|
return transient_for;
|
|
|
|
}
|
|
|
|
|
1999-11-28 20:10:58 +00:00
|
|
|
inline bool Client::isTransient() const
|
|
|
|
{
|
|
|
|
return transient_for != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
inline int Client::mappingState() const
|
|
|
|
{
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline bool Client::isActive() const
|
|
|
|
{
|
|
|
|
return active;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the virtual desktop within the workspace() the client window
|
|
|
|
is located in, -1 if it isn't located on any special desktop. This may be
|
|
|
|
if the window wasn't mapped yet or if the window is sticky. Do not use
|
|
|
|
desktop() directly, use isOnDesktop() instead.
|
|
|
|
*/
|
|
|
|
inline int Client::desktop() const
|
|
|
|
{
|
|
|
|
return desk;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns whether the client is on visible or iconified on the virtual
|
|
|
|
desktop \a d. This is always TRUE for sticky clients.
|
|
|
|
*/
|
|
|
|
inline bool Client::isOnDesktop( int d ) const
|
|
|
|
{
|
|
|
|
return desk == d || desk == -1 || isSticky();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline QPixmap Client::icon() const
|
|
|
|
{
|
|
|
|
return icon_pix;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline QPixmap Client::miniIcon() const
|
|
|
|
{
|
|
|
|
return miniicon_pix;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Is the client maximized?
|
|
|
|
*/
|
|
|
|
inline bool Client::isMaximized() const
|
|
|
|
{
|
|
|
|
return !geom_restore.isNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool Client::isSticky() const
|
|
|
|
{
|
|
|
|
return is_sticky;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-12 03:11:19 +00:00
|
|
|
inline bool Client::shape() const
|
|
|
|
{
|
|
|
|
return is_shape;
|
|
|
|
}
|
|
|
|
|
2000-05-03 00:04:26 +00:00
|
|
|
inline const QRegion& Client::getMask() const
|
|
|
|
{
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
1999-08-19 23:26:42 +00:00
|
|
|
class NoBorderClient : public Client
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
NoBorderClient( Workspace *ws, WId w, QWidget *parent=0, const char *name=0 );
|
|
|
|
~NoBorderClient();
|
1999-11-17 17:25:26 +00:00
|
|
|
|
|
|
|
bool wantsTabFocus() const { return FALSE;} //### just for now
|
1999-08-19 23:26:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|