all repos — fluxbox @ a04eed16c5287c11e565ecb25f465b96d6f61279

custom fork of the fluxbox windowmanager

fix elements of shaping, more to come
simonb simonb
commit

a04eed16c5287c11e565ecb25f465b96d6f61279

parent

8c53e8861ed51f284545634b46150f0adeb567e2

4 files changed, 85 insertions(+), 30 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,5 +1,10 @@

(Format: Year/Month/Day) Changes for 1.0.0: +*07/08/09: + * Fix shaping handling, stage 1, (Simon) + - do borders properly with rounded corners + - propagate client clip mask as well as bounding mask + Shape.hh/cc Window.cc *07/08/07: * Rotate toolbar background texture along with toolbar, bug #1694959 (Mark) Toolbar.cc
M src/Shape.ccsrc/Shape.cc

@@ -48,11 +48,10 @@ #include <algorithm>

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 @@ static char right_bits[] = { 0x03, 0x1f, 0x3f, 0x7f, 0x7f, 0x7f, 0xff, 0xff};

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

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

// shape corners - if (place & Shape::TOPLEFT) { + if (m_shapeplaces & Shape::TOPLEFT) { for (int y=0; y<pixmap_height; y++) { for (int x=0; x<pixmap_width; x++) { XPutPixel(ximage, x, y, (left_bits[y] & (0x01 << x)) ? 1 : 0);

@@ -98,7 +97,7 @@ }

} } - if (place & Shape::TOPRIGHT) { + if (m_shapeplaces & Shape::TOPRIGHT) { for (int y=0; y<pixmap_height; y++) { for (int x=0; x<pixmap_width; x++) { XPutPixel(ximage, x + win_width - pixmap_width, y,

@@ -107,7 +106,7 @@ }

} } - if (place & Shape::BOTTOMLEFT) { + if (m_shapeplaces & Shape::BOTTOMLEFT) { for (int y=0; y<pixmap_height; y++) { for (int x=0; x<pixmap_width; x++) { XPutPixel(ximage, x, y + win_height - pixmap_height,

@@ -116,7 +115,7 @@ }

} } - if (place & Shape::BOTTOMRIGHT) { + if (m_shapeplaces & Shape::BOTTOMRIGHT) { for (int y=0; y<pixmap_height; y++) { for (int x=0; x<pixmap_width; x++) { XPutPixel(ximage, x + win_width - pixmap_width, y + win_height - pixmap_height,

@@ -125,7 +124,7 @@ }

} } - FbTk::FbPixmap *pm = new FbTk::FbPixmap(win, win_width, win_height, 1); + FbTk::FbPixmap *pm = new FbTk::FbPixmap(*m_win, win_width, win_height, 1); FbTk::GContext gc(*pm);

@@ -139,13 +138,12 @@ return pm;

} -} // end anonymous namespace - Shape::Shape(FbTk::FbWindow &win, int shapeplaces): m_win(&win), m_shapeplaces(shapeplaces) { - m_shape.reset(createShape(win, shapeplaces)); + m_clipshape.reset(createShape(true)); + m_boundingshape.reset(createShape(false)); } Shape::~Shape() {

@@ -155,11 +153,20 @@ if (m_win != 0 && m_win->window()) {

// Reset shape of window XShapeCombineMask(FbTk::App::instance()->display(), 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 @@ return (shaped != 0 ? true : false);

} 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; }
M src/Shape.hhsrc/Shape.hh

@@ -53,14 +53,20 @@ /// assign a new window

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<FbTk::FbPixmap> m_shape; ///< our shape pixmap + std::auto_ptr<FbTk::FbPixmap> m_clipshape; ///< our shape pixmap + std::auto_ptr<FbTk::FbPixmap> m_boundingshape; ///< our shape pixmap int m_shapeplaces; ///< places to shape + }; #endif // SHAPE_HH
M src/Window.ccsrc/Window.cc

@@ -562,6 +562,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(),

@@ -2347,6 +2352,10 @@ } else {

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

@@ -3204,10 +3213,11 @@ client_move = true;

} frame().reconfigure(); - if (!initial && client_move) { + if (client_move) Fluxbox::instance()->updateFrameExtents(*this); + + if (!initial && client_move) sendConfigureNotify(); - } }