aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMathias Gumz <akira@fluxbox.org>2015-02-04 20:06:51 (GMT)
committerMathias Gumz <akira@fluxbox.org>2015-02-04 20:06:51 (GMT)
commite79228cc08ee1d0d20d7ef27103a5d167fb8f133 (patch)
treeb1ae97ca223704044df0518a8f45b4067411ef46 /src
parent53b3120b322603c317a0ea9cd88e5a7cefe604ee (diff)
downloadfluxbox-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.cc124
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())
150void WinButton::drawType() { 150void 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}
261void WinButton::updateAll() { 274void 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