shape windows support, some fixes for configure-request handling

svn path=/trunk/kdebase/kwin/; revision=33553
This commit is contained in:
Matthias Ettrich 1999-11-12 03:11:19 +00:00
parent d94de9b5b6
commit a30c061abb
4 changed files with 86 additions and 31 deletions

View file

@ -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();

View file

@ -119,6 +119,11 @@ public:
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();
void closeWindow(); void closeWindow();
@ -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

View file

@ -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 )
@ -38,16 +63,20 @@ static Client* clientFactory( Workspace *ws, WId w )
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;
@ -240,28 +275,8 @@ bool Workspace::workspaceEvent( XEvent * e )
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;

View file

@ -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