diff --git a/client.cpp b/client.cpp index dc7f1e3719..30c9d5f3a3 100644 --- a/client.cpp +++ b/client.cpp @@ -458,13 +458,36 @@ void Client::setUserNoBorder( bool set ) void Client::updateShape() { - if ( shape() ) + // workaround for #19644 - shaped windows shouldn't have decoration + if( shape() && !noBorder()) + { + noborder = true; + updateDecoration( true ); + } + if( shape()) + { XShapeCombineShape(display(), frameId(), ShapeBounding, clientPos().x(), clientPos().y(), window(), ShapeBounding, ShapeSet); + } else + { XShapeCombineMask( display(), frameId(), ShapeBounding, 0, 0, None, ShapeSet); + } + if( Extensions::shapeMajor() > 1 || Extensions::shapeMinor() >= 1 ) // has input shape support + { // there appears to be no way to find out if a window has input + // shape set or not, so always set propagate the input shape + // (it's the same like the bounding shape by default) + XShapeCombineMask( display(), frameId(), ShapeInput, 0, 0, + None, ShapeSet ); + XShapeCombineShape( display(), frameId(), ShapeInput, + clientPos().x(), clientPos().y(), + window(), ShapeBounding, ShapeSubtract ); + XShapeCombineShape( display(), frameId(), ShapeInput, + clientPos().x(), clientPos().y(), + window(), ShapeInput, ShapeUnion ); + } if( compositing()) addDamageFull(); if( scene != NULL ) diff --git a/geometry.cpp b/geometry.cpp index e3c6e18e0c..f6cdb0be1d 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -1758,8 +1758,7 @@ void Client::plainResize( int w, int h, ForceGeometry_t force ) cs.width(), cs.height()); XMoveResizeWindow( display(), window(), 0, 0, cs.width(), cs.height()); } - if( shape()) - updateShape(); + updateShape(); updateWorkareaDiffs(); sendSyntheticConfigureNotify(); updateWindowRules(); diff --git a/utils.cpp b/utils.cpp index 4938582ad3..c0861db5a8 100644 --- a/utils.cpp +++ b/utils.cpp @@ -45,7 +45,7 @@ namespace KWin #ifndef KCMRULES -bool Extensions::has_shape = false; +int Shape::kwin_shape_version = 0; int Extensions::shape_event_base = 0; bool Extensions::has_randr = false; int Extensions::randr_event_base = 0; @@ -58,7 +58,13 @@ bool Extensions::has_fixes = false; void Extensions::init() { int dummy; - has_shape = XShapeQueryExtension( display(), &shape_event_base, &dummy); + shape_version = 0; + if( XShapeQueryExtension( display(), &kwin_shape_event, &dummy )) + { + int major, minor; + if( XShapeQueryVersion( display(), &major, &minor )) + kwin_shape_version = major * 16 + minor; + } #ifdef HAVE_XRANDR has_randr = XRRQueryExtension( display(), &randr_event_base, &dummy ); if( has_randr ) @@ -106,7 +112,7 @@ bool Extensions::hasShape( Window w ) int xws, yws, xbs, ybs; unsigned int wws, hws, wbs, hbs; int boundingShaped = 0, clipShaped = 0; - if( !Extensions::shapeAvailable()) + if( !shapeAvailable()) return false; XShapeQueryExtents(display(), w, &boundingShaped, &xws, &yws, &wws, &hws, diff --git a/utils.h b/utils.h index ea270869bf..334866e993 100644 --- a/utils.h +++ b/utils.h @@ -148,7 +148,9 @@ class Extensions { public: static void init(); - static bool shapeAvailable() { return has_shape; } + static bool shapeAvailable() { return shape_version > 0; } + static int shapeMajor() { return shape_version / 16; } + static int shapeMinor() { return shape_version % 16; } static int shapeNotifyEvent(); static bool randrAvailable() { return has_randr; } static int randrNotifyEvent(); @@ -159,7 +161,7 @@ class Extensions static bool fixesAvailable() { return has_fixes; } static bool hasShape( Window w ); private: - static bool has_shape; + static int shape_version; // as 16*major+minor static int shape_event_base; static bool has_randr; static int randr_event_base;