diff options
author | simonb <simonb> | 2007-08-08 15:41:10 (GMT) |
---|---|---|
committer | simonb <simonb> | 2007-08-08 15:41:10 (GMT) |
commit | a04eed16c5287c11e565ecb25f465b96d6f61279 (patch) | |
tree | ad857bb3a77acb1e846b4a60bb3ca74b334dbd59 | |
parent | 8c53e8861ed51f284545634b46150f0adeb567e2 (diff) | |
download | fluxbox-a04eed16c5287c11e565ecb25f465b96d6f61279.zip fluxbox-a04eed16c5287c11e565ecb25f465b96d6f61279.tar.bz2 |
fix elements of shaping, more to come
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/Shape.cc | 88 | ||||
-rw-r--r-- | src/Shape.hh | 8 | ||||
-rw-r--r-- | src/Window.cc | 14 |
4 files changed, 85 insertions, 30 deletions
@@ -1,5 +1,10 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 1.0.0: | 2 | Changes for 1.0.0: |
3 | *07/08/09: | ||
4 | * Fix shaping handling, stage 1, (Simon) | ||
5 | - do borders properly with rounded corners | ||
6 | - propagate client clip mask as well as bounding mask | ||
7 | Shape.hh/cc Window.cc | ||
3 | *07/08/07: | 8 | *07/08/07: |
4 | * Rotate toolbar background texture along with toolbar, bug #1694959 (Mark) | 9 | * Rotate toolbar background texture along with toolbar, bug #1694959 (Mark) |
5 | Toolbar.cc | 10 | Toolbar.cc |
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 @@ | |||
48 | 48 | ||
49 | using std::min; | 49 | using std::min; |
50 | 50 | ||
51 | namespace { | 51 | // ignore_border basically means do clip shape instead of bounding shape |
52 | 52 | FbTk::FbPixmap *Shape::createShape(bool ignore_border) { | |
53 | FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | 53 | if (m_win->window() == 0 || m_shapeplaces == 0 || |
54 | if (win.window() == 0 || place == 0 || | 54 | m_win->width() < 3 || m_win->height() < 3) |
55 | win.width() < 3 || win.height() < 3) | ||
56 | return 0; | 55 | return 0; |
57 | 56 | ||
58 | static char left_bits[] = { 0xc0, 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff }; | 57 | 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) { | |||
60 | static char bottom_left_bits[] = { 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, 0xc0 }; | 59 | static char bottom_left_bits[] = { 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, 0xc0 }; |
61 | static char bottom_right_bits[] = { 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x1f, 0x03 }; | 60 | static char bottom_right_bits[] = { 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x1f, 0x03 }; |
62 | 61 | ||
63 | const int borderw = win.borderWidth(); | 62 | const int borderw = m_win->borderWidth(); |
64 | const int win_width = win.width() + 2*borderw; | 63 | const int win_width = m_win->width() + (ignore_border?0:2*borderw); |
65 | const int win_height = win.height() + 2*borderw; | 64 | const int win_height = m_win->height() + (ignore_border?0:2*borderw); |
66 | const int pixmap_width = min(8, win_width); | 65 | const int pixmap_width = min(8, win_width); |
67 | const int pixmap_height = min(8, win_height); | 66 | const int pixmap_height = min(8, win_height); |
68 | 67 | ||
@@ -77,7 +76,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
77 | memset(data, 0xFF, data_size); | 76 | memset(data, 0xFF, data_size); |
78 | 77 | ||
79 | XImage *ximage = XCreateImage(disp, | 78 | XImage *ximage = XCreateImage(disp, |
80 | DefaultVisual(disp, win.screenNumber()), | 79 | DefaultVisual(disp, m_win->screenNumber()), |
81 | 1, | 80 | 1, |
82 | XYPixmap, 0, | 81 | XYPixmap, 0, |
83 | data, | 82 | data, |
@@ -90,7 +89,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
90 | 89 | ||
91 | // shape corners | 90 | // shape corners |
92 | 91 | ||
93 | if (place & Shape::TOPLEFT) { | 92 | if (m_shapeplaces & Shape::TOPLEFT) { |
94 | for (int y=0; y<pixmap_height; y++) { | 93 | for (int y=0; y<pixmap_height; y++) { |
95 | for (int x=0; x<pixmap_width; x++) { | 94 | for (int x=0; x<pixmap_width; x++) { |
96 | XPutPixel(ximage, x, y, (left_bits[y] & (0x01 << x)) ? 1 : 0); | 95 | XPutPixel(ximage, x, y, (left_bits[y] & (0x01 << x)) ? 1 : 0); |
@@ -98,7 +97,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
98 | } | 97 | } |
99 | } | 98 | } |
100 | 99 | ||
101 | if (place & Shape::TOPRIGHT) { | 100 | if (m_shapeplaces & Shape::TOPRIGHT) { |
102 | for (int y=0; y<pixmap_height; y++) { | 101 | for (int y=0; y<pixmap_height; y++) { |
103 | for (int x=0; x<pixmap_width; x++) { | 102 | for (int x=0; x<pixmap_width; x++) { |
104 | XPutPixel(ximage, x + win_width - pixmap_width, y, | 103 | XPutPixel(ximage, x + win_width - pixmap_width, y, |
@@ -107,7 +106,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
107 | } | 106 | } |
108 | } | 107 | } |
109 | 108 | ||
110 | if (place & Shape::BOTTOMLEFT) { | 109 | if (m_shapeplaces & Shape::BOTTOMLEFT) { |
111 | for (int y=0; y<pixmap_height; y++) { | 110 | for (int y=0; y<pixmap_height; y++) { |
112 | for (int x=0; x<pixmap_width; x++) { | 111 | for (int x=0; x<pixmap_width; x++) { |
113 | XPutPixel(ximage, x, y + win_height - pixmap_height, | 112 | XPutPixel(ximage, x, y + win_height - pixmap_height, |
@@ -116,7 +115,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
116 | } | 115 | } |
117 | } | 116 | } |
118 | 117 | ||
119 | if (place & Shape::BOTTOMRIGHT) { | 118 | if (m_shapeplaces & Shape::BOTTOMRIGHT) { |
120 | for (int y=0; y<pixmap_height; y++) { | 119 | for (int y=0; y<pixmap_height; y++) { |
121 | for (int x=0; x<pixmap_width; x++) { | 120 | for (int x=0; x<pixmap_width; x++) { |
122 | XPutPixel(ximage, x + win_width - pixmap_width, y + win_height - pixmap_height, | 121 | XPutPixel(ximage, x + win_width - pixmap_width, y + win_height - pixmap_height, |
@@ -125,7 +124,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
125 | } | 124 | } |
126 | } | 125 | } |
127 | 126 | ||
128 | FbTk::FbPixmap *pm = new FbTk::FbPixmap(win, win_width, win_height, 1); | 127 | FbTk::FbPixmap *pm = new FbTk::FbPixmap(*m_win, win_width, win_height, 1); |
129 | 128 | ||
130 | 129 | ||
131 | FbTk::GContext gc(*pm); | 130 | FbTk::GContext gc(*pm); |
@@ -139,13 +138,12 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
139 | 138 | ||
140 | } | 139 | } |
141 | 140 | ||
142 | } // end anonymous namespace | ||
143 | |||
144 | Shape::Shape(FbTk::FbWindow &win, int shapeplaces): | 141 | Shape::Shape(FbTk::FbWindow &win, int shapeplaces): |
145 | m_win(&win), | 142 | m_win(&win), |
146 | m_shapeplaces(shapeplaces) { | 143 | m_shapeplaces(shapeplaces) { |
147 | 144 | ||
148 | m_shape.reset(createShape(win, shapeplaces)); | 145 | m_clipshape.reset(createShape(true)); |
146 | m_boundingshape.reset(createShape(false)); | ||
149 | } | 147 | } |
150 | 148 | ||
151 | Shape::~Shape() { | 149 | Shape::~Shape() { |
@@ -155,11 +153,20 @@ Shape::~Shape() { | |||
155 | // Reset shape of window | 153 | // Reset shape of window |
156 | XShapeCombineMask(FbTk::App::instance()->display(), | 154 | XShapeCombineMask(FbTk::App::instance()->display(), |
157 | m_win->window(), | 155 | m_win->window(), |
158 | ShapeBounding, | 156 | ShapeClip, |
159 | 0, 0, | 157 | 0, 0, |
160 | 0, | 158 | 0, |
161 | ShapeSet); | 159 | ShapeSet); |
162 | } | 160 | // Reset shape of window |
161 | if (m_boundingshape.get()) { | ||
162 | XShapeCombineMask(FbTk::App::instance()->display(), | ||
163 | m_win->window(), | ||
164 | ShapeBounding, | ||
165 | 0, 0, | ||
166 | 0, | ||
167 | ShapeSet); | ||
168 | } | ||
169 | } | ||
163 | #endif // SHAPE | 170 | #endif // SHAPE |
164 | } | 171 | } |
165 | 172 | ||
@@ -171,19 +178,38 @@ void Shape::update() { | |||
171 | if (m_win == 0 || m_win->window() == 0) | 178 | if (m_win == 0 || m_win->window() == 0) |
172 | return; | 179 | return; |
173 | #ifdef SHAPE | 180 | #ifdef SHAPE |
174 | if (m_shape.get() == 0 || | 181 | if (m_clipshape.get() == 0 || |
175 | m_win->width() != width() || | 182 | m_win->width() != clipWidth() || |
176 | m_win->height() != height()) { | 183 | m_win->height() != clipHeight()) { |
177 | m_shape.reset(createShape(*m_win, m_shapeplaces)); | 184 | m_clipshape.reset(createShape(true)); |
185 | } | ||
186 | if (m_boundingshape.get() == 0 || | ||
187 | (m_win->width()+m_win->borderWidth()*2) != width() || | ||
188 | (m_win->height()+m_win->borderWidth()*2) != height()) { | ||
189 | if (m_win->borderWidth() != 0) | ||
190 | m_boundingshape.reset(createShape(false)); | ||
191 | else | ||
192 | m_boundingshape.reset(0); | ||
193 | |||
178 | } | 194 | } |
179 | 195 | ||
180 | // the m_shape can be = 0 which will just reset the shape mask | 196 | // the m_shape can be = 0 which will just raeset the shape mask |
197 | // and make the window normal | ||
198 | XShapeCombineMask(FbTk::App::instance()->display(), | ||
199 | m_win->window(), | ||
200 | ShapeClip, | ||
201 | 0, 0, | ||
202 | (m_clipshape.get() != 0)? m_clipshape->drawable() : 0, | ||
203 | ShapeSet); | ||
204 | |||
205 | // the m_shape can be = 0 which will just raeset the shape mask | ||
181 | // and make the window normal | 206 | // and make the window normal |
182 | XShapeCombineMask(FbTk::App::instance()->display(), | 207 | XShapeCombineMask(FbTk::App::instance()->display(), |
183 | m_win->window(), | 208 | m_win->window(), |
184 | ShapeBounding, | 209 | ShapeBounding, |
185 | -m_win->borderWidth(), -m_win->borderWidth(), | 210 | -m_win->borderWidth(), -m_win->borderWidth(), |
186 | m_shape.get() ? m_shape->drawable() : 0, | 211 | (m_boundingshape.get() != 0)? m_boundingshape->drawable() : |
212 | ((m_clipshape.get() != 0)? m_clipshape->drawable(): 0), | ||
187 | ShapeSet); | 213 | ShapeSet); |
188 | 214 | ||
189 | 215 | ||
@@ -223,9 +249,17 @@ bool Shape::isShaped(const FbTk::FbWindow &win) { | |||
223 | } | 249 | } |
224 | 250 | ||
225 | unsigned int Shape::width() const { | 251 | unsigned int Shape::width() const { |
226 | return m_shape.get() ? m_shape->width() : 0; | 252 | return m_boundingshape.get() ? m_boundingshape->width() : 0; |
227 | } | 253 | } |
228 | 254 | ||
229 | unsigned int Shape::height() const { | 255 | unsigned int Shape::height() const { |
230 | return m_shape.get() ? m_shape->height() : 0; | 256 | return m_boundingshape.get() ? m_boundingshape->height() : 0; |
257 | } | ||
258 | |||
259 | unsigned int Shape::clipWidth() const { | ||
260 | return m_clipshape.get() ? m_clipshape->width() : 0; | ||
261 | } | ||
262 | |||
263 | unsigned int Shape::clipHeight() const { | ||
264 | return m_clipshape.get() ? m_clipshape->height() : 0; | ||
231 | } | 265 | } |
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: | |||
53 | void setWindow(FbTk::FbWindow &win); | 53 | void setWindow(FbTk::FbWindow &win); |
54 | unsigned int width() const; | 54 | unsigned int width() const; |
55 | unsigned int height() const; | 55 | unsigned int height() const; |
56 | unsigned int clipWidth() const; | ||
57 | unsigned int clipHeight() const; | ||
56 | // sets shape notify mask | 58 | // sets shape notify mask |
57 | static void setShapeNotify(const FbTk::FbWindow &win); | 59 | static void setShapeNotify(const FbTk::FbWindow &win); |
58 | /// @return true if window has shape | 60 | /// @return true if window has shape |
59 | static bool isShaped(const FbTk::FbWindow &win); | 61 | static bool isShaped(const FbTk::FbWindow &win); |
60 | private: | 62 | private: |
63 | FbTk::FbPixmap *createShape(bool clipshape); // true for clip, false for bounding | ||
64 | |||
61 | FbTk::FbWindow *m_win; ///< window to be shaped | 65 | FbTk::FbWindow *m_win; ///< window to be shaped |
62 | std::auto_ptr<FbTk::FbPixmap> m_shape; ///< our shape pixmap | 66 | std::auto_ptr<FbTk::FbPixmap> m_clipshape; ///< our shape pixmap |
67 | std::auto_ptr<FbTk::FbPixmap> m_boundingshape; ///< our shape pixmap | ||
63 | int m_shapeplaces; ///< places to shape | 68 | int m_shapeplaces; ///< places to shape |
69 | |||
64 | }; | 70 | }; |
65 | 71 | ||
66 | #endif // SHAPE_HH | 72 | #endif // SHAPE_HH |
diff --git a/src/Window.cc b/src/Window.cc index 653032e..ab917da 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -562,6 +562,11 @@ void FluxboxWindow::shape() { | |||
562 | #ifdef SHAPE | 562 | #ifdef SHAPE |
563 | if (m_shaped) { | 563 | if (m_shaped) { |
564 | XShapeCombineShape(display, | 564 | XShapeCombineShape(display, |
565 | frame().window().window(), ShapeClip, | ||
566 | 0, frame().clientArea().y(), // xOff, yOff | ||
567 | m_client->window(), | ||
568 | ShapeClip, ShapeSet); | ||
569 | XShapeCombineShape(display, | ||
565 | frame().window().window(), ShapeBounding, | 570 | frame().window().window(), ShapeBounding, |
566 | 0, frame().clientArea().y(), // xOff, yOff | 571 | 0, frame().clientArea().y(), // xOff, yOff |
567 | m_client->window(), | 572 | m_client->window(), |
@@ -2347,6 +2352,10 @@ void FluxboxWindow::handleEvent(XEvent &event) { | |||
2347 | m_shaped = false; | 2352 | m_shaped = false; |
2348 | // set no shape | 2353 | // set no shape |
2349 | XShapeCombineMask(display, | 2354 | XShapeCombineMask(display, |
2355 | frame().window().window(), ShapeClip, | ||
2356 | 0, 0, | ||
2357 | None, ShapeSet); | ||
2358 | XShapeCombineMask(display, | ||
2350 | frame().window().window(), ShapeBounding, | 2359 | frame().window().window(), ShapeBounding, |
2351 | 0, 0, | 2360 | 0, 0, |
2352 | None, ShapeSet); | 2361 | None, ShapeSet); |
@@ -3204,10 +3213,11 @@ void FluxboxWindow::applyDecorations(bool initial) { | |||
3204 | } | 3213 | } |
3205 | 3214 | ||
3206 | frame().reconfigure(); | 3215 | frame().reconfigure(); |
3207 | if (!initial && client_move) { | 3216 | if (client_move) |
3208 | Fluxbox::instance()->updateFrameExtents(*this); | 3217 | Fluxbox::instance()->updateFrameExtents(*this); |
3218 | |||
3219 | if (!initial && client_move) | ||
3209 | sendConfigureNotify(); | 3220 | sendConfigureNotify(); |
3210 | } | ||
3211 | 3221 | ||
3212 | } | 3222 | } |
3213 | 3223 | ||