diff options
author | Mathias Gumz <akira@fluxbox.org> | 2015-02-04 20:06:51 (GMT) |
---|---|---|
committer | Mathias Gumz <akira@fluxbox.org> | 2015-02-04 20:06:51 (GMT) |
commit | e79228cc08ee1d0d20d7ef27103a5d167fb8f133 (patch) | |
tree | b1ae97ca223704044df0518a8f45b4067411ef46 /src | |
parent | 53b3120b322603c317a0ea9cd88e5a7cefe604ee (diff) | |
download | fluxbox-e79228cc08ee1d0d20d7ef27103a5d167fb8f133.zip fluxbox-e79228cc08ee1d0d20d7ef27103a5d167fb8f133.tar.bz2 |
Fix problem with too small WinButtons
Under some circumstances a WinButton might be tiny (1x1 pixel). Substracting
values > 1 yields either 0 or something reaaaaly big (UINT_MAX). This will
make fluxbox either crash or make it act weird. We don't want this.
Diffstat (limited to 'src')
-rw-r--r-- | src/WinButton.cc | 124 |
1 files changed, 71 insertions, 53 deletions
diff --git a/src/WinButton.cc b/src/WinButton.cc index bb841fb..c790a03 100644 --- a/src/WinButton.cc +++ b/src/WinButton.cc | |||
@@ -149,11 +149,12 @@ Pixmap WinButton::getPixmap(const FbTk::ThemeProxy<WinButtonTheme> &theme) const | |||
149 | // clear is used to force this to clear the window (e.g. called from clear()) | 149 | // clear is used to force this to clear the window (e.g. called from clear()) |
150 | void WinButton::drawType() { | 150 | void WinButton::drawType() { |
151 | 151 | ||
152 | // if it's odd and we're centring, we need to add one | 152 | int w = width(); |
153 | int oddW = width()%2; | 153 | int h = height(); |
154 | int oddH = height()%2; | 154 | int oddW = w % 2; // if it's odd and we're centring, we need to add one |
155 | 155 | int oddH = h % 2; | |
156 | bool is_pressed = pressed(); | 156 | bool is_pressed = pressed(); |
157 | |||
157 | if (is_pressed && overrode_pressed && !m_icon_pixmap.drawable()) | 158 | if (is_pressed && overrode_pressed && !m_icon_pixmap.drawable()) |
158 | return; | 159 | return; |
159 | if (!is_pressed && overrode_bg && !m_icon_pixmap.drawable()) | 160 | if (!is_pressed && overrode_bg && !m_icon_pixmap.drawable()) |
@@ -164,31 +165,35 @@ void WinButton::drawType() { | |||
164 | // otherwise draw old style imagery | 165 | // otherwise draw old style imagery |
165 | switch (m_type) { | 166 | switch (m_type) { |
166 | case MAXIMIZE: | 167 | case MAXIMIZE: |
167 | drawRectangle(gc(), 2, 2, width() - 5, height() - 5); | 168 | if ((w < 6) || (h < 6)) { |
168 | drawLine(gc(), 2, 3, width() - 3, 3); | 169 | return; |
170 | } | ||
171 | drawRectangle(gc(), 2, 2, w - 5, h - 5); | ||
172 | drawLine(gc(), 2, 3, w - 3, 3); | ||
169 | break; | 173 | break; |
170 | 174 | ||
171 | case MINIMIZE: | 175 | case MINIMIZE: |
172 | drawRectangle(gc(), 2, height() - 5, width() - 5, 2); | 176 | if ((w < 6) || (h < 6)) { |
177 | return; | ||
178 | } | ||
179 | drawRectangle(gc(), 2, w - 5, h - 5, 2); | ||
173 | break; | 180 | break; |
174 | 181 | ||
175 | case STICK: | 182 | case STICK: { |
176 | // width/4 != width/2, so we use /4*2 so that it's properly centred | 183 | int s = 4; |
177 | if (m_listen_to.isStuck()) { | 184 | if (!m_listen_to.isStuck()) |
178 | fillRectangle(gc(), | 185 | s = 8; |
179 | width()/2 - width()/4, height()/2 - height()/4, | 186 | |
180 | width()/4*2 + oddW, height()/4*2 + oddH); | 187 | fillRectangle(gc(), (w / 2) - (w / s), (h / 2) - (h / s), |
181 | } else { | 188 | 2*(w / s) + oddW, 2*(h / s) + oddH); |
182 | fillRectangle(gc(), | ||
183 | width()/2 - width()/10, height()/2 - height()/10, | ||
184 | width()/10*2 + oddW, height()/10*2 + oddH); | ||
185 | } | 189 | } |
186 | break; | 190 | break; |
187 | 191 | ||
188 | case CLOSE: | 192 | case CLOSE: |
189 | drawLine(gc(), | 193 | if ((w < 4) || (h < 4)) { |
190 | 2, 2, | 194 | return; |
191 | width() - 3, height() - 3); | 195 | } |
196 | drawLine(gc(), 2, 2, w - 3, h - 3); | ||
192 | // I can't figure out why this second one needs a y offset of 1????? | 197 | // I can't figure out why this second one needs a y offset of 1????? |
193 | // but it does - at least on my box: | 198 | // but it does - at least on my box: |
194 | // XFree86 Version 4.2.1.1 (Debian 4.2.1-12.1 20031003005825) | 199 | // XFree86 Version 4.2.1.1 (Debian 4.2.1-12.1 20031003005825) |
@@ -200,56 +205,64 @@ void WinButton::drawType() { | |||
200 | // XFree86 Version 4.3.0.1 (Debian 4.3.0.dfsg.1-1 20040428170728) | 205 | // XFree86 Version 4.3.0.1 (Debian 4.3.0.dfsg.1-1 20040428170728) |
201 | // (X Protocol Version 11, Revision 0, Release 6.6) | 206 | // (X Protocol Version 11, Revision 0, Release 6.6) |
202 | 207 | ||
203 | drawLine(gc(), 2, height() - 3, width() - 3, 2); | 208 | drawLine(gc(), 2, w - 3, h - 3, 2); |
204 | break; | 209 | break; |
205 | 210 | ||
206 | case SHADE: | 211 | case SHADE: { |
207 | { | 212 | int size = w - 5 - oddW; |
208 | int size = width() - 5 - oddW; | 213 | if (size < 4) { |
214 | return; | ||
215 | } | ||
216 | |||
217 | FbTk::FbDrawable::TriangleType dir = (m_listen_to.isShaded() ? FbTk::FbDrawable::DOWN: FbTk::FbDrawable::UP); | ||
218 | |||
209 | drawRectangle(gc(), 2, 2, size, 2); | 219 | drawRectangle(gc(), 2, 2, size, 2); |
210 | 220 | ||
211 | // draw a one-quarter triangle below the rectangle | 221 | // draw a one-quarter triangle below the rectangle |
212 | drawTriangle(gc(), (m_listen_to.isShaded() ? | 222 | drawTriangle(gc(), dir, 4, 6, size-2, size/2 - 1, 100); |
213 | FbTk::FbDrawable::DOWN: | ||
214 | FbTk::FbDrawable::UP), | ||
215 | 4, 6, | ||
216 | size-2, size/2 - 1, | ||
217 | 100); | ||
218 | |||
219 | break; | 223 | break; |
220 | } | 224 | } |
221 | 225 | ||
222 | case MENUICON: | 226 | case MENUICON: |
223 | if (m_icon_pixmap.drawable()) { | 227 | if (m_icon_pixmap.drawable()) { |
224 | 228 | ||
229 | Display* disp = m_listen_to.fbWindow().display(); | ||
230 | |||
225 | if (m_icon_mask.drawable()) { | 231 | if (m_icon_mask.drawable()) { |
226 | XSetClipMask(m_listen_to.fbWindow().display(), | 232 | XSetClipMask(disp, gc(), m_icon_mask.drawable()); |
227 | gc(), m_icon_mask.drawable()); | 233 | XSetClipOrigin(disp, gc(), 2, 2); |
228 | XSetClipOrigin(m_listen_to.fbWindow().display(), | ||
229 | gc(), 2, 2); | ||
230 | } | 234 | } |
231 | 235 | ||
232 | copyArea(m_icon_pixmap.drawable(), | 236 | copyArea(m_icon_pixmap.drawable(), gc(), |
233 | gc(), | 237 | 0, 0, 2, 2, |
234 | 0, 0, | ||
235 | 2, 2, | ||
236 | m_icon_pixmap.width(), m_icon_pixmap.height()); | 238 | m_icon_pixmap.width(), m_icon_pixmap.height()); |
237 | 239 | ||
238 | if (m_icon_mask.drawable()) | 240 | if (m_icon_mask.drawable()) |
239 | XSetClipMask(m_listen_to.fbWindow().display(), gc(), None); | 241 | XSetClipMask(disp, gc(), None); |
240 | } else { | 242 | } else { |
241 | for (unsigned int y = height()/3; y <= height() - height()/3; y+=3) { | 243 | if ((w < 6) || (h < 6)) { |
242 | drawLine(gc(), width()/4, y, width() - width()/4 - oddW - 1, y); | 244 | return; |
245 | } | ||
246 | |||
247 | int y = h / 3; | ||
248 | for ( ; y <= h; y += 3) { | ||
249 | drawLine(gc(), w / 4, y, w - (w / 4) - 1, y); | ||
243 | } | 250 | } |
244 | drawRectangle(gc(), 2, 2, width() - 5, height() - 5); | 251 | drawRectangle(gc(), 2, 2, w - 5, h - 5); |
245 | } | 252 | } |
246 | break; | 253 | break; |
247 | 254 | ||
248 | case LEFT_HALF: | 255 | case LEFT_HALF: |
249 | fillRectangle(gc(), 2, 2, (width() / 2) - oddW, height() - 4); | 256 | if ((w < 4) || (h < 5)) { |
257 | return; | ||
258 | } | ||
259 | fillRectangle(gc(), 2, 2, (w / 2) - oddW, h - 4); | ||
250 | break; | 260 | break; |
251 | case RIGHT_HALF: | 261 | case RIGHT_HALF: |
252 | fillRectangle(gc(), width() / 2, 2, (width() / 2) - 2 + oddW, height() - 4); | 262 | if ((w < 5) || (h < 5)) { |
263 | return; | ||
264 | } | ||
265 | fillRectangle(gc(), w / 2, 2, (w / 2) - 2 + oddW, h - 4); | ||
253 | break; | 266 | break; |
254 | } | 267 | } |
255 | } | 268 | } |
@@ -260,21 +273,26 @@ void WinButton::clear() { | |||
260 | } | 273 | } |
261 | void WinButton::updateAll() { | 274 | void WinButton::updateAll() { |
262 | 275 | ||
276 | int w = static_cast<int>(width()) - 4; | ||
277 | int h = static_cast<int>(height()) - 4; | ||
278 | |||
263 | // update the menu icon | 279 | // update the menu icon |
264 | if (m_type == MENUICON && !m_listen_to.empty()) { | 280 | if ((w > 0 && h > 0) && m_type == MENUICON && !m_listen_to.empty()) { |
265 | 281 | ||
266 | Display* display = m_listen_to.fbWindow().display(); | 282 | Display* display = m_listen_to.fbWindow().display(); |
267 | int screen = m_listen_to.screen().screenNumber(); | 283 | int screen = m_listen_to.screen().screenNumber(); |
268 | if (m_listen_to.icon().pixmap().drawable() != None) { | 284 | |
269 | m_icon_pixmap.copy(m_listen_to.icon().pixmap().drawable(), | 285 | Drawable d = m_listen_to.icon().pixmap().drawable(); |
270 | DefaultDepth(display, screen), screen); | 286 | if (d != None) { |
271 | m_icon_pixmap.scale(width() - 4, height() - 4); | 287 | m_icon_pixmap.copy(d, DefaultDepth(display, screen), screen); |
288 | m_icon_pixmap.scale(w, h); | ||
272 | } else | 289 | } else |
273 | m_icon_pixmap.release(); | 290 | m_icon_pixmap.release(); |
274 | 291 | ||
275 | if (m_listen_to.icon().mask().drawable() != None) { | 292 | d = m_listen_to.icon().mask().drawable(); |
276 | m_icon_mask.copy(m_listen_to.icon().mask().drawable(), 0, 0); | 293 | if (d != None) { |
277 | m_icon_mask.scale(width() - 4, height() - 4); | 294 | m_icon_mask.copy(d, 0, 0); |
295 | m_icon_mask.scale(w, h); | ||
278 | } else | 296 | } else |
279 | m_icon_mask.release(); | 297 | m_icon_mask.release(); |
280 | 298 | ||