summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--src/Shape.cc88
-rw-r--r--src/Shape.hh8
-rw-r--r--src/Window.cc14
4 files changed, 85 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 786269b..fed2ab2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.0.0: 2Changes 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
49using std::min; 49using std::min;
50 50
51namespace { 51// ignore_border basically means do clip shape instead of bounding shape
52 52FbTk::FbPixmap *Shape::createShape(bool ignore_border) {
53FbTk::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
144Shape::Shape(FbTk::FbWindow &win, int shapeplaces): 141Shape::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
151Shape::~Shape() { 149Shape::~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
225unsigned int Shape::width() const { 251unsigned 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
229unsigned int Shape::height() const { 255unsigned int Shape::height() const {
230 return m_shape.get() ? m_shape->height() : 0; 256 return m_boundingshape.get() ? m_boundingshape->height() : 0;
257}
258
259unsigned int Shape::clipWidth() const {
260 return m_clipshape.get() ? m_clipshape->width() : 0;
261}
262
263unsigned 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);
60private: 62private:
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