shape windows support, some fixes for configure-request handling
svn path=/trunk/kdebase/kwin/; revision=33553
This commit is contained in:
parent
d94de9b5b6
commit
a30c061abb
4 changed files with 86 additions and 31 deletions
24
client.cpp
24
client.cpp
|
@ -13,6 +13,7 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
|
||||||
extern Atom qt_wm_state;
|
extern Atom qt_wm_state;
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ void Client::drawbound( const QRect& geom )
|
||||||
p.setRasterOp( Qt::XorROP );
|
p.setRasterOp( Qt::XorROP );
|
||||||
p.drawRect( geom );
|
p.drawRect( geom );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::clearbound()
|
void Client::clearbound()
|
||||||
{
|
{
|
||||||
if ( !visible_bound )
|
if ( !visible_bound )
|
||||||
|
@ -39,6 +41,16 @@ void Client::clearbound()
|
||||||
visible_bound = 0;
|
visible_bound = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::updateShape()
|
||||||
|
{
|
||||||
|
if ( shape() )
|
||||||
|
XShapeCombineShape(qt_xdisplay(), winId(), ShapeBounding,
|
||||||
|
windowWrapper()->x(), windowWrapper()->y(),
|
||||||
|
window(), ShapeBounding, ShapeSet);
|
||||||
|
else
|
||||||
|
XShapeCombineMask( qt_xdisplay(), winId(), ShapeBounding, 0, 0,
|
||||||
|
None, ShapeSet);
|
||||||
|
}
|
||||||
|
|
||||||
static void sendClientMessage(Window w, Atom a, long x){
|
static void sendClientMessage(Window w, Atom a, long x){
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
|
@ -116,7 +128,6 @@ WindowWrapper::WindowWrapper( WId w, Client *parent, const char* name)
|
||||||
StructureNotifyMask
|
StructureNotifyMask
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// install a passive grab to catch mouse button events
|
// install a passive grab to catch mouse button events
|
||||||
XGrabButton(qt_xdisplay(), AnyButton, AnyModifier, winId(), FALSE,
|
XGrabButton(qt_xdisplay(), AnyButton, AnyModifier, winId(), FALSE,
|
||||||
ButtonPressMask, GrabModeSync, GrabModeSync,
|
ButtonPressMask, GrabModeSync, GrabModeSync,
|
||||||
|
@ -145,7 +156,9 @@ void WindowWrapper::resizeEvent( QResizeEvent * )
|
||||||
if ( win ) {
|
if ( win ) {
|
||||||
XMoveResizeWindow( qt_xdisplay(), win,
|
XMoveResizeWindow( qt_xdisplay(), win,
|
||||||
0, 0, width(), height() );
|
0, 0, width(), height() );
|
||||||
}
|
if ( ((Client*)parentWidget())->shape() )
|
||||||
|
((Client*)parentWidget())->updateShape();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowWrapper::showEvent( QShowEvent* )
|
void WindowWrapper::showEvent( QShowEvent* )
|
||||||
|
@ -262,7 +275,7 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
||||||
active = FALSE;
|
active = FALSE;
|
||||||
shaded = FALSE;
|
shaded = FALSE;
|
||||||
transient_for = None;
|
transient_for = None;
|
||||||
is_sticky = FALSE;
|
is_shape = FALSE;
|
||||||
|
|
||||||
getIcons();
|
getIcons();
|
||||||
getWindowProtocols();
|
getWindowProtocols();
|
||||||
|
@ -325,6 +338,11 @@ void Client::manage( bool isMapped )
|
||||||
placementDone = TRUE;
|
placementDone = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( (is_shape = Shape::hasShape( win )) ) {
|
||||||
|
updateShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ### TODO check XGetWMHints() for initial mapping state, icon, etc. pp.
|
// ### TODO check XGetWMHints() for initial mapping state, icon, etc. pp.
|
||||||
// assume window wants to be visible on the current desktop
|
// assume window wants to be visible on the current desktop
|
||||||
desk = KWM::desktop( win ); //workspace()->currentDesktop();
|
desk = KWM::desktop( win ); //workspace()->currentDesktop();
|
||||||
|
|
11
client.h
11
client.h
|
@ -118,6 +118,11 @@ public:
|
||||||
// transparent stuff
|
// transparent stuff
|
||||||
virtual void drawbound( const QRect& geom );
|
virtual void drawbound( const QRect& geom );
|
||||||
virtual void clearbound();
|
virtual void clearbound();
|
||||||
|
|
||||||
|
|
||||||
|
// shape extensions
|
||||||
|
bool shape() const;
|
||||||
|
void updateShape();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void iconify();
|
void iconify();
|
||||||
|
@ -196,6 +201,7 @@ private:
|
||||||
bool shaded;
|
bool shaded;
|
||||||
WId transient_for;
|
WId transient_for;
|
||||||
bool is_sticky;
|
bool is_sticky;
|
||||||
|
bool is_shape;
|
||||||
void getIcons();
|
void getIcons();
|
||||||
void getWindowProtocols();
|
void getWindowProtocols();
|
||||||
uint Pdeletewindow :1; // does the window understand the DeleteWindow protocol?
|
uint Pdeletewindow :1; // does the window understand the DeleteWindow protocol?
|
||||||
|
@ -283,6 +289,11 @@ inline bool Client::isSticky() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Client::shape() const
|
||||||
|
{
|
||||||
|
return is_shape;
|
||||||
|
}
|
||||||
|
|
||||||
class NoBorderClient : public Client
|
class NoBorderClient : public Client
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -14,6 +14,31 @@
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
|
||||||
|
// used to store the return values of
|
||||||
|
// XShapeQueryExtension.
|
||||||
|
// Necessary since shaped window are an extension to X
|
||||||
|
static int kwin_has_shape = 0;
|
||||||
|
static int kwin_shape_event = 0;
|
||||||
|
|
||||||
|
// does the window w need a shape combine mask around it?
|
||||||
|
bool Shape::hasShape( WId w){
|
||||||
|
int xws, yws, xbs, ybs;
|
||||||
|
unsigned wws, hws, wbs, hbs;
|
||||||
|
int boundingShaped, clipShaped;
|
||||||
|
if (!kwin_has_shape)
|
||||||
|
return FALSE;
|
||||||
|
XShapeQueryExtents(qt_xdisplay(), w,
|
||||||
|
&boundingShaped, &xws, &yws, &wws, &hws,
|
||||||
|
&clipShaped, &xbs, &ybs, &wbs, &hbs);
|
||||||
|
return boundingShaped != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Shape::shapeEvent()
|
||||||
|
{
|
||||||
|
return kwin_shape_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Client* clientFactory( Workspace *ws, WId w )
|
static Client* clientFactory( Workspace *ws, WId w )
|
||||||
|
@ -37,17 +62,21 @@ static Client* clientFactory( Workspace *ws, WId w )
|
||||||
c->setSticky( TRUE );
|
c->setSticky( TRUE );
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( Shape::hasShape( w ) ){
|
||||||
|
return new NoBorderClient( ws, w );
|
||||||
|
}
|
||||||
|
|
||||||
KConfig *config = KGlobal::config();
|
KConfig *config = KGlobal::config();
|
||||||
config->setGroup("style");
|
config->setGroup("style");
|
||||||
// well, it will be soon ;-)
|
// well, it will be soon ;-)
|
||||||
QString tmpStr = config->readEntry("Plugin", "standard");
|
QString tmpStr = config->readEntry("Plugin", "standard");
|
||||||
if(tmpStr == "standard")
|
if(tmpStr == "system")
|
||||||
return new StdClient( ws, w );
|
return new SystemClient( ws, w );
|
||||||
else if(tmpStr == "system")
|
|
||||||
return new SystemClient( ws, w );
|
|
||||||
else if(tmpStr == "be")
|
else if(tmpStr == "be")
|
||||||
return new BeClient( ws, w );
|
return new BeClient( ws, w );
|
||||||
|
else
|
||||||
|
return new StdClient( ws, w );
|
||||||
}
|
}
|
||||||
|
|
||||||
Workspace::Workspace()
|
Workspace::Workspace()
|
||||||
|
@ -66,6 +95,9 @@ Workspace::Workspace()
|
||||||
SubstructureNotifyMask
|
SubstructureNotifyMask
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int dummy;
|
||||||
|
kwin_has_shape = XShapeQueryExtension(qt_xdisplay(), &kwin_shape_event, &dummy);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
control_grab = FALSE;
|
control_grab = FALSE;
|
||||||
tab_grab = FALSE;
|
tab_grab = FALSE;
|
||||||
|
@ -227,7 +259,10 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ConfigureRequest:
|
case ConfigureRequest:
|
||||||
if ( e->xconfigurerequest.parent == root ) {
|
c = findClient( e->xconfigurerequest.window );
|
||||||
|
if ( c )
|
||||||
|
return c->windowEvent( e );
|
||||||
|
else if ( e->xconfigurerequest.parent == root ) {
|
||||||
XWindowChanges wc;
|
XWindowChanges wc;
|
||||||
unsigned int value_mask = 0;
|
unsigned int value_mask = 0;
|
||||||
wc.border_width = 0;
|
wc.border_width = 0;
|
||||||
|
@ -239,29 +274,9 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
wc.stack_mode = Above;
|
wc.stack_mode = Above;
|
||||||
value_mask = e->xconfigurerequest.value_mask | CWBorderWidth;
|
value_mask = e->xconfigurerequest.value_mask | CWBorderWidth;
|
||||||
XConfigureWindow( qt_xdisplay(), e->xconfigurerequest.window, value_mask, & wc );
|
XConfigureWindow( qt_xdisplay(), e->xconfigurerequest.window, value_mask, & wc );
|
||||||
|
|
||||||
XWindowAttributes attr;
|
|
||||||
if (XGetWindowAttributes(qt_xdisplay(), e->xconfigurerequest.window, &attr)){
|
|
||||||
// send a synthetic configure notify in any case (even if we didn't change anything)
|
|
||||||
XConfigureEvent c;
|
|
||||||
c.type = ConfigureNotify;
|
|
||||||
c.event = e->xconfigurerequest.window;
|
|
||||||
c.window = e->xconfigurerequest.window;
|
|
||||||
c.x = attr.x;
|
|
||||||
c.y = attr.y;
|
|
||||||
c.width = attr.width;
|
|
||||||
c.height = attr.height;
|
|
||||||
c.border_width = 0;
|
|
||||||
XSendEvent( qt_xdisplay(), c.event, TRUE, NoEventMask, (XEvent*)&c );
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
c = findClient( e->xconfigurerequest.window );
|
|
||||||
if ( c )
|
|
||||||
return c->windowEvent( e );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
return keyPress(e->xkey);
|
return keyPress(e->xkey);
|
||||||
|
@ -277,6 +292,11 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
return clientMessage(e->xclient);
|
return clientMessage(e->xclient);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if ( e->type == Shape::shapeEvent() ) {
|
||||||
|
c = findClient( ((XShapeEvent *)e)->window );
|
||||||
|
if ( c )
|
||||||
|
c->updateShape();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -15,6 +15,12 @@ class KGlobalAccel;
|
||||||
typedef QValueList<Client*> ClientList;
|
typedef QValueList<Client*> ClientList;
|
||||||
typedef QValueList<WId> WIdList;
|
typedef QValueList<WId> WIdList;
|
||||||
|
|
||||||
|
class Shape {
|
||||||
|
public:
|
||||||
|
static bool hasShape( WId w);
|
||||||
|
static int shapeEvent();
|
||||||
|
};
|
||||||
|
|
||||||
class Workspace : public QObject
|
class Workspace : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -105,7 +111,7 @@ private:
|
||||||
void setDecoration( int deco );
|
void setDecoration( int deco );
|
||||||
|
|
||||||
void propagateClients( bool onlyStacking = FALSE);
|
void propagateClients( bool onlyStacking = FALSE);
|
||||||
|
|
||||||
WIdList dockwins;
|
WIdList dockwins;
|
||||||
bool addDockwin( WId w );
|
bool addDockwin( WId w );
|
||||||
bool removeDockwin( WId w );
|
bool removeDockwin( WId w );
|
||||||
|
|
Loading…
Reference in a new issue