From 9807e5e676810c9665df68ac6e6a770efa2f555e Mon Sep 17 00:00:00 2001 From: simonb Date: Wed, 8 Aug 2007 15:43:01 +0000 Subject: port shaping fixes stage 1 from trunk --- src/Shape.cc | 88 +++++++++++++++++++++++++++++++++++++++++------------------ src/Shape.hh | 8 +++++- src/Window.cc | 14 ++++++++-- 3 files changed, 80 insertions(+), 30 deletions(-) diff --git a/src/Shape.cc b/src/Shape.cc index 3f053a3..a073b9f 100644 --- a/src/Shape.cc +++ b/src/Shape.cc @@ -48,11 +48,10 @@ using std::min; -namespace { - -FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { - if (win.window() == 0 || place == 0 || - win.width() < 3 || win.height() < 3) +// ignore_border basically means do clip shape instead of bounding shape +FbTk::FbPixmap *Shape::createShape(bool ignore_border) { + if (m_win->window() == 0 || m_shapeplaces == 0 || + m_win->width() < 3 || m_win->height() < 3) return 0; static char left_bits[] = { 0xc0, 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff }; @@ -60,9 +59,9 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { static char bottom_left_bits[] = { 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, 0xc0 }; static char bottom_right_bits[] = { 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x1f, 0x03 }; - const int borderw = win.borderWidth(); - const int win_width = win.width() + 2*borderw; - const int win_height = win.height() + 2*borderw; + const int borderw = m_win->borderWidth(); + const int win_width = m_win->width() + (ignore_border?0:2*borderw); + const int win_height = m_win->height() + (ignore_border?0:2*borderw); const int pixmap_width = min(8, win_width); const int pixmap_height = min(8, win_height); @@ -77,7 +76,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { memset(data, 0xFF, data_size); XImage *ximage = XCreateImage(disp, - DefaultVisual(disp, win.screenNumber()), + DefaultVisual(disp, m_win->screenNumber()), 1, XYPixmap, 0, data, @@ -90,7 +89,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { // shape corners - if (place & Shape::TOPLEFT) { + if (m_shapeplaces & Shape::TOPLEFT) { for (int y=0; ydisplay(), m_win->window(), - ShapeBounding, + ShapeClip, 0, 0, 0, ShapeSet); - } + // Reset shape of window + if (m_boundingshape.get()) { + XShapeCombineMask(FbTk::App::instance()->display(), + m_win->window(), + ShapeBounding, + 0, 0, + 0, + ShapeSet); + } + } #endif // SHAPE } @@ -171,19 +178,38 @@ void Shape::update() { if (m_win == 0 || m_win->window() == 0) return; #ifdef SHAPE - if (m_shape.get() == 0 || - m_win->width() != width() || - m_win->height() != height()) { - m_shape.reset(createShape(*m_win, m_shapeplaces)); + if (m_clipshape.get() == 0 || + m_win->width() != clipWidth() || + m_win->height() != clipHeight()) { + m_clipshape.reset(createShape(true)); + } + if (m_boundingshape.get() == 0 || + (m_win->width()+m_win->borderWidth()*2) != width() || + (m_win->height()+m_win->borderWidth()*2) != height()) { + if (m_win->borderWidth() != 0) + m_boundingshape.reset(createShape(false)); + else + m_boundingshape.reset(0); + } - // the m_shape can be = 0 which will just reset the shape mask + // the m_shape can be = 0 which will just raeset the shape mask + // and make the window normal + XShapeCombineMask(FbTk::App::instance()->display(), + m_win->window(), + ShapeClip, + 0, 0, + (m_clipshape.get() != 0)? m_clipshape->drawable() : 0, + ShapeSet); + + // the m_shape can be = 0 which will just raeset the shape mask // and make the window normal XShapeCombineMask(FbTk::App::instance()->display(), m_win->window(), ShapeBounding, -m_win->borderWidth(), -m_win->borderWidth(), - m_shape.get() ? m_shape->drawable() : 0, + (m_boundingshape.get() != 0)? m_boundingshape->drawable() : + ((m_clipshape.get() != 0)? m_clipshape->drawable(): 0), ShapeSet); @@ -223,9 +249,17 @@ bool Shape::isShaped(const FbTk::FbWindow &win) { } unsigned int Shape::width() const { - return m_shape.get() ? m_shape->width() : 0; + return m_boundingshape.get() ? m_boundingshape->width() : 0; } unsigned int Shape::height() const { - return m_shape.get() ? m_shape->height() : 0; + return m_boundingshape.get() ? m_boundingshape->height() : 0; +} + +unsigned int Shape::clipWidth() const { + return m_clipshape.get() ? m_clipshape->width() : 0; +} + +unsigned int Shape::clipHeight() const { + return m_clipshape.get() ? m_clipshape->height() : 0; } diff --git a/src/Shape.hh b/src/Shape.hh index 75d9bd4..c8db79a 100644 --- a/src/Shape.hh +++ b/src/Shape.hh @@ -53,14 +53,20 @@ public: void setWindow(FbTk::FbWindow &win); unsigned int width() const; unsigned int height() const; + unsigned int clipWidth() const; + unsigned int clipHeight() const; // sets shape notify mask static void setShapeNotify(const FbTk::FbWindow &win); /// @return true if window has shape static bool isShaped(const FbTk::FbWindow &win); private: + FbTk::FbPixmap *createShape(bool clipshape); // true for clip, false for bounding + FbTk::FbWindow *m_win; ///< window to be shaped - std::auto_ptr m_shape; ///< our shape pixmap + std::auto_ptr m_clipshape; ///< our shape pixmap + std::auto_ptr m_boundingshape; ///< our shape pixmap int m_shapeplaces; ///< places to shape + }; #endif // SHAPE_HH diff --git a/src/Window.cc b/src/Window.cc index cf20503..c64a0c9 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -568,6 +568,11 @@ void FluxboxWindow::shape() { #ifdef SHAPE if (m_shaped) { XShapeCombineShape(display, + frame().window().window(), ShapeClip, + 0, frame().clientArea().y(), // xOff, yOff + m_client->window(), + ShapeClip, ShapeSet); + XShapeCombineShape(display, frame().window().window(), ShapeBounding, 0, frame().clientArea().y(), // xOff, yOff m_client->window(), @@ -2249,6 +2254,10 @@ void FluxboxWindow::handleEvent(XEvent &event) { m_shaped = false; // set no shape XShapeCombineMask(display, + frame().window().window(), ShapeClip, + 0, 0, + None, ShapeSet); + XShapeCombineMask(display, frame().window().window(), ShapeBounding, 0, 0, None, ShapeSet); @@ -3080,10 +3089,11 @@ void FluxboxWindow::applyDecorations(bool initial) { } frame().reconfigure(); - if (!initial && client_move) { + if (client_move) Fluxbox::instance()->updateFrameExtents(*this); + + if (!initial && client_move) sendConfigureNotify(); - } } -- cgit v0.11.2