2 * Window Maker window manager
4 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 #include <X11/Xutil.h>
26 #ifdef KEEP_XKB_LOCK_STATUS
27 #include <X11/XKBlib.h>
28 #endif /* KEEP_XKB_LOCK_STATUS */
35 #include "WindowMaker.h"
44 #define DBLCLICK_TIME wPreferences.dblclick_time
46 extern WPreferences wPreferences
;
48 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
);
49 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
);
51 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
52 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
53 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
55 static void checkTitleSize(WFrameWindow
* fwin
);
57 static void paintButton(WCoreWindow
* button
, WTexture
* texture
,
58 unsigned long color
, WPixmap
* image
, int pushed
);
60 static void updateTitlebar(WFrameWindow
* fwin
);
62 WFrameWindow
*wFrameWindowCreate(WScreen
* scr
, int wlevel
, int x
, int y
,
63 int width
, int height
, int *clearance
, int flags
,
64 WTexture
** title_texture
, WTexture
** resize_texture
,
65 WMColor
** color
, WMFont
** font
)
69 fwin
= wmalloc(sizeof(WFrameWindow
));
70 memset(fwin
, 0, sizeof(WFrameWindow
));
72 fwin
->screen_ptr
= scr
;
74 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
76 fwin
->title_texture
= title_texture
;
77 fwin
->resizebar_texture
= resize_texture
;
78 fwin
->title_color
= color
;
79 fwin
->title_clearance
= clearance
;
81 #ifdef KEEP_XKB_LOCK_STATUS
82 fwin
->languagemode
= XkbGroup1Index
;
83 fwin
->last_languagemode
= XkbGroup2Index
;
86 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
87 ? FRAME_BORDER_WIDTH
: 0);
88 if (wPreferences
.use_saveunders
) {
90 XSetWindowAttributes attribs
;
93 attribs
.save_under
= True
;
94 XChangeWindowAttributes(dpy
, fwin
->core
->window
, vmask
, &attribs
);
97 /* setup stacking information */
98 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
99 fwin
->core
->stacking
->above
= NULL
;
100 fwin
->core
->stacking
->under
= NULL
;
101 fwin
->core
->stacking
->child_of
= NULL
;
102 fwin
->core
->stacking
->window_level
= wlevel
;
104 AddToStackList(fwin
->core
);
106 wFrameWindowUpdateBorders(fwin
, flags
);
111 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
117 WScreen
*scr
= fwin
->screen_ptr
;
119 width
= fwin
->core
->width
;
120 if (flags
& WFF_IS_SHADED
)
123 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
125 if (flags
& WFF_TITLEBAR
)
126 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
130 if (wPreferences
.new_style
) {
136 if (fwin
->titlebar
) {
137 /* if we had a titlebar and is requesting for one,
138 * check if the size has changed and resize it */
139 if (flags
& WFF_TITLEBAR
) {
140 fwin
->top_width
= theight
;
142 fwin
->flags
.need_texture_remake
= 1;
144 if (wPreferences
.new_style
) {
145 if (fwin
->left_button
) {
146 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
148 #ifdef XKB_BUTTON_HINT
149 if (fwin
->language_button
)
150 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
151 || fwin
->flags
.lbutton_dont_fit
) {
152 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
154 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
158 if (fwin
->right_button
) {
159 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
161 } else { /* !new_style */
162 if (fwin
->left_button
) {
163 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
165 #ifdef XKB_BUTTON_HINT
166 if (fwin
->language_button
) {
167 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
172 if (fwin
->right_button
) {
173 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
174 (theight
- bsize
) / 2, bsize
, bsize
);
177 updateTitlebar(fwin
);
179 /* we had a titlebar, but now we don't need it anymore */
180 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
181 FREE_PIXMAP(fwin
->title_back
[i
]);
182 if (wPreferences
.new_style
) {
183 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
184 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
185 #ifdef XKB_BUTTON_HINT
186 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
190 if (fwin
->left_button
)
191 wCoreDestroy(fwin
->left_button
);
192 fwin
->left_button
= NULL
;
194 #ifdef XKB_BUTTON_HINT
195 if (fwin
->language_button
)
196 wCoreDestroy(fwin
->language_button
);
197 fwin
->language_button
= NULL
;
200 if (fwin
->right_button
)
201 wCoreDestroy(fwin
->right_button
);
202 fwin
->right_button
= NULL
;
204 wCoreDestroy(fwin
->titlebar
);
205 fwin
->titlebar
= NULL
;
210 /* if we didn't have a titlebar and are being requested for
212 if (flags
& WFF_TITLEBAR
) {
213 fwin
->top_width
= theight
;
215 fwin
->flags
.titlebar
= 1;
216 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
218 if (flags
& WFF_LEFT_BUTTON
) {
219 fwin
->flags
.left_button
= 1;
220 if (wPreferences
.new_style
) {
221 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
222 if (width
< theight
* 4) {
223 fwin
->flags
.lbutton_dont_fit
= 1;
225 XMapRaised(dpy
, fwin
->left_button
->window
);
229 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
231 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
232 scr
->widget_texture
->normal
.pixel
);
234 if (width
< theight
* 3) {
235 fwin
->flags
.lbutton_dont_fit
= 1;
237 XMapRaised(dpy
, fwin
->left_button
->window
);
241 #ifdef XKB_BUTTON_HINT
242 if (flags
& WFF_LANGUAGE_BUTTON
) {
243 fwin
->flags
.language_button
= 1;
244 if (wPreferences
.new_style
) {
245 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
247 if (width
< theight
* 4) {
248 fwin
->flags
.languagebutton_dont_fit
= 1;
250 XMapRaised(dpy
, fwin
->language_button
->window
);
253 fwin
->language_button
=
254 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
257 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
258 scr
->widget_texture
->normal
.pixel
);
260 if (width
< theight
* 3) {
261 fwin
->flags
.languagebutton_dont_fit
= 1;
263 XMapRaised(dpy
, fwin
->language_button
->window
);
269 if (flags
& WFF_RIGHT_BUTTON
) {
270 fwin
->flags
.right_button
= 1;
271 if (wPreferences
.new_style
) {
273 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
276 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
277 (theight
- bsize
) / 2, bsize
, bsize
);
278 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
279 scr
->widget_texture
->normal
.pixel
);
282 if (width
< theight
* 2) {
283 fwin
->flags
.rbutton_dont_fit
= 1;
285 XMapRaised(dpy
, fwin
->right_button
->window
);
289 if (wPreferences
.new_style
)
290 updateTitlebar(fwin
);
292 XMapRaised(dpy
, fwin
->titlebar
->window
);
294 fwin
->flags
.need_texture_remake
= 1;
297 checkTitleSize(fwin
);
299 if (flags
& WFF_RESIZEBAR
) {
300 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
302 if (!fwin
->resizebar
) {
303 fwin
->flags
.resizebar
= 1;
304 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
305 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
306 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
307 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
308 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
309 if (fwin
->resizebar_corner_width
< 0)
310 fwin
->resizebar_corner_width
= 0;
313 XMapWindow(dpy
, fwin
->resizebar
->window
);
314 XLowerWindow(dpy
, fwin
->resizebar
->window
);
316 fwin
->flags
.need_texture_remake
= 1;
318 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
) {
319 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
320 width
, RESIZEBAR_HEIGHT
);
324 fwin
->bottom_width
= 0;
326 if (fwin
->resizebar
) {
327 fwin
->bottom_width
= 0;
328 wCoreDestroy(fwin
->resizebar
);
329 fwin
->resizebar
= NULL
;
333 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
)) {
334 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
337 if (flags
& WFF_BORDER
) {
338 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
340 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
343 /* setup object descriptors */
345 if (fwin
->titlebar
) {
346 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
347 fwin
->titlebar
->descriptor
.parent
= fwin
;
348 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
349 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
352 if (fwin
->resizebar
) {
353 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
354 fwin
->resizebar
->descriptor
.parent
= fwin
;
355 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
356 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
359 if (fwin
->left_button
) {
360 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
361 fwin
->left_button
->descriptor
.parent
= fwin
;
362 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
363 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
365 #ifdef XKB_BUTTON_HINT
366 if (fwin
->language_button
) {
367 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
368 fwin
->language_button
->descriptor
.parent
= fwin
;
369 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
370 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
374 if (fwin
->right_button
) {
375 fwin
->right_button
->descriptor
.parent
= fwin
;
376 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
377 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
378 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
381 checkTitleSize(fwin
);
384 void wFrameWindowDestroy(WFrameWindow
* fwin
)
388 if (fwin
->left_button
)
389 wCoreDestroy(fwin
->left_button
);
391 #ifdef XKB_BUTTON_HINT
392 if (fwin
->language_button
)
393 wCoreDestroy(fwin
->language_button
);
396 if (fwin
->right_button
)
397 wCoreDestroy(fwin
->right_button
);
400 wCoreDestroy(fwin
->resizebar
);
403 wCoreDestroy(fwin
->titlebar
);
405 RemoveFromStackList(fwin
->core
);
407 wCoreDestroy(fwin
->core
);
412 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
413 FREE_PIXMAP(fwin
->title_back
[i
]);
414 if (wPreferences
.new_style
) {
415 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
416 #ifdef XKB_BUTTON_HINT
417 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
419 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
426 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
428 if (fwin
->flags
.state
== state
)
431 fwin
->flags
.state
= state
;
432 fwin
->flags
.need_texture_change
= 1;
434 wFrameWindowPaint(fwin
);
437 static void updateTitlebar(WFrameWindow
* fwin
)
442 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
445 w
= fwin
->core
->width
+ 1;
447 if (wPreferences
.new_style
) {
448 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
450 #ifdef XKB_BUTTON_HINT
451 if (fwin
->language_button
)
452 wCoreConfigure(fwin
->language_button
, 0, 0,
453 fwin
->language_button
->width
, fwin
->language_button
->width
);
456 #ifdef XKB_BUTTON_HINT
457 if (fwin
->language_button
)
458 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
459 fwin
->language_button
->width
, fwin
->language_button
->width
);
461 x
= fwin
->left_button
->width
;
462 w
-= fwin
->left_button
->width
;
464 #ifdef XKB_BUTTON_HINT
465 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
466 || fwin
->flags
.languagebutton_dont_fit
) {
468 x
+= fwin
->language_button
->width
;
469 w
-= fwin
->language_button
->width
;
473 #ifdef XKB_BUTTON_HINT
475 int bsize
= theight
- 7;
476 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
477 if (fwin
->language_button
)
478 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
479 fwin
->language_button
->width
, fwin
->language_button
->width
);
481 if (fwin
->language_button
)
482 wCoreConfigure(fwin
->language_button
,
483 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
484 fwin
->language_button
->width
, fwin
->language_button
->width
);
489 if (wPreferences
.new_style
) {
490 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
) {
491 w
-= fwin
->right_button
->width
;
495 if (wPreferences
.new_style
|| fwin
->titlebar
->width
!= w
)
496 fwin
->flags
.need_texture_remake
= 1;
498 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
501 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
503 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
504 XUnmapWindow(dpy
, fwin
->right_button
->window
);
505 fwin
->flags
.hide_right_button
= 1;
508 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
509 XUnmapWindow(dpy
, fwin
->left_button
->window
);
510 fwin
->flags
.hide_left_button
= 1;
512 #ifdef XKB_BUTTON_HINT
513 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
514 XUnmapWindow(dpy
, fwin
->language_button
->window
);
515 fwin
->flags
.hide_language_button
= 1;
519 if (fwin
->titlebar
) {
520 if (wPreferences
.new_style
) {
521 updateTitlebar(fwin
);
523 #ifdef XKB_BUTTON_HINT
524 updateTitlebar(fwin
);
526 XClearWindow(dpy
, fwin
->titlebar
->window
);
527 wFrameWindowPaint(fwin
);
530 checkTitleSize(fwin
);
534 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
536 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
538 if (!fwin
->flags
.rbutton_dont_fit
)
539 XMapWindow(dpy
, fwin
->right_button
->window
);
541 fwin
->flags
.hide_right_button
= 0;
543 #ifdef XKB_BUTTON_HINT
544 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
546 if (!fwin
->flags
.languagebutton_dont_fit
)
547 XMapWindow(dpy
, fwin
->language_button
->window
);
549 fwin
->flags
.hide_language_button
= 0;
553 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
555 if (!fwin
->flags
.lbutton_dont_fit
)
556 XMapWindow(dpy
, fwin
->left_button
->window
);
558 fwin
->flags
.hide_left_button
= 0;
561 if (fwin
->titlebar
) {
562 if (wPreferences
.new_style
) {
563 updateTitlebar(fwin
);
565 XClearWindow(dpy
, fwin
->titlebar
->window
);
566 wFrameWindowPaint(fwin
);
568 checkTitleSize(fwin
);
573 #ifdef XKB_BUTTON_HINT
574 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
575 int bwidth
, int bheight
, int left
, int language
, int right
,
576 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
578 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
579 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
583 RImage
*limg
, *rimg
, *mimg
;
584 #ifdef XKB_BUTTON_HINT
592 #ifdef XKB_BUTTON_HINT
593 *languagebutton
= None
;
596 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
598 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
602 if (wPreferences
.new_style
) {
604 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
611 #ifdef XKB_BUTTON_HINT
613 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
619 RBevelImage(limg
, RBEV_RAISED2
);
620 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
621 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
627 #ifdef XKB_BUTTON_HINT
629 RBevelImage(timg
, RBEV_RAISED2
);
630 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
)) {
631 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
640 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
645 RBevelImage(rimg
, RBEV_RAISED2
);
646 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
647 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
654 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
655 RBevelImage(mimg
, RBEV_RAISED2
);
657 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
658 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
662 RBevelImage(img
, RBEV_RAISED2
);
664 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
665 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
669 RBevelImage(img
, RBEV_RAISED2
);
671 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
672 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
680 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
688 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
690 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
695 light
.red
= light
.green
= light
.blue
= 80;
698 dark
.red
= dark
.green
= dark
.blue
= 40;
700 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
701 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
703 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
704 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
707 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
708 width
- cwidth
- 2, height
- 1, &dark
);
709 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
711 #ifdef SHADOW_RESIZEBAR
712 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
713 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
714 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
715 #endif /* SHADOW_RESIZEBAR */
717 if (!RConvertImage(scr
->rcontext
, img
, pmap
)) {
718 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
724 static void updateTexture(WFrameWindow
* fwin
)
729 i
= fwin
->flags
.state
;
730 if (fwin
->titlebar
) {
731 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
732 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
733 if (wPreferences
.new_style
) {
734 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
735 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
736 fwin
->lbutton_back
[i
]);
738 #ifdef XKB_BUTTON_HINT
739 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
]) {
740 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
741 fwin
->languagebutton_back
[i
]);
745 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
746 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
747 fwin
->rbutton_back
[i
]);
750 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
751 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
752 if (wPreferences
.new_style
) {
753 if (fwin
->left_button
)
754 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
755 #ifdef XKB_BUTTON_HINT
756 if (fwin
->language_button
)
757 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
759 if (fwin
->right_button
)
760 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
763 XClearWindow(dpy
, fwin
->titlebar
->window
);
765 if (fwin
->left_button
) {
766 XClearWindow(dpy
, fwin
->left_button
->window
);
767 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
769 #ifdef XKB_BUTTON_HINT
770 if (fwin
->language_button
) {
771 XClearWindow(dpy
, fwin
->language_button
->window
);
772 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
775 if (fwin
->right_button
) {
776 XClearWindow(dpy
, fwin
->right_button
->window
);
777 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
782 static void remakeTexture(WFrameWindow
* fwin
, int state
)
784 Pixmap pmap
, lpmap
, rpmap
;
785 #ifdef XKB_BUTTON_HINT
789 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
790 FREE_PIXMAP(fwin
->title_back
[state
]);
791 if (wPreferences
.new_style
) {
792 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
793 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
794 #ifdef XKB_BUTTON_HINT
795 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
799 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
802 #ifdef XKB_BUTTON_HINT
806 /* eventually surrounded by if new_style */
807 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
808 #ifdef XKB_BUTTON_HINT
809 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
810 && !fwin
->flags
.languagebutton_dont_fit
;
812 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
813 && !fwin
->flags
.rbutton_dont_fit
;
815 width
= fwin
->core
->width
+ 1;
817 #ifdef XKB_BUTTON_HINT
818 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
819 width
, fwin
->titlebar
->height
,
820 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
821 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
823 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
824 width
, fwin
->titlebar
->height
,
825 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
826 left
, right
, &pmap
, &lpmap
, &rpmap
);
829 fwin
->title_back
[state
] = pmap
;
830 if (wPreferences
.new_style
) {
831 fwin
->lbutton_back
[state
] = lpmap
;
832 fwin
->rbutton_back
[state
] = rpmap
;
833 #ifdef XKB_BUTTON_HINT
834 fwin
->languagebutton_back
[state
] = tpmap
;
839 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
840 && fwin
->resizebar
&& state
== 0) {
842 FREE_PIXMAP(fwin
->resizebar_back
[0]);
844 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
846 renderResizebarTexture(fwin
->screen_ptr
,
847 fwin
->resizebar_texture
[0],
848 fwin
->resizebar
->width
,
849 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
851 fwin
->resizebar_back
[0] = pmap
;
854 /* this part should be in updateTexture() */
855 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
856 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
858 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
859 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
861 XClearWindow(dpy
, fwin
->resizebar
->window
);
865 void wFrameWindowPaint(WFrameWindow
* fwin
)
867 WScreen
*scr
= fwin
->screen_ptr
;
870 state
= fwin
->flags
.state
;
872 if (fwin
->flags
.is_client_window_frame
)
873 fwin
->flags
.justification
= wPreferences
.title_justification
;
875 if (fwin
->flags
.need_texture_remake
) {
878 fwin
->flags
.need_texture_remake
= 0;
879 fwin
->flags
.need_texture_change
= 0;
881 if (fwin
->flags
.single_texture
) {
882 remakeTexture(fwin
, 0);
885 /* first render the texture for the current state... */
886 remakeTexture(fwin
, state
);
887 /* ... and paint it */
890 for (i
= 0; i
< 3; i
++) {
892 remakeTexture(fwin
, i
);
898 if (fwin
->flags
.need_texture_change
) {
899 fwin
->flags
.need_texture_change
= 0;
904 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
905 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
906 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
907 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
910 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
911 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
916 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
918 w
= fwin
->resizebar
->width
;
919 h
= fwin
->resizebar
->height
;
920 cw
= fwin
->resizebar_corner_width
;
921 light_gc
= texture
->light_gc
;
922 dim_gc
= texture
->dim_gc
;
923 win
= fwin
->resizebar
->window
;
925 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
926 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
928 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
929 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
931 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
932 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
934 #ifdef SHADOW_RESIZEBAR
935 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
936 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
937 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
938 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
939 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
940 #endif /* SHADOW_RESIZEBAR */
943 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
945 int lofs
= 6, rofs
= 6;
949 if (!wPreferences
.new_style
) {
950 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
951 lofs
+= fwin
->left_button
->width
+ 3;
955 #ifdef XKB_BUTTON_HINT
956 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
957 && !fwin
->flags
.languagebutton_dont_fit
)
958 lofs
+= fwin
->language_button
->width
;
963 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
964 rofs
+= fwin
->right_button
->width
+ 3;
968 #ifdef XKB_BUTTON_HINT
969 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
976 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
977 titlelen
= strlen(title
);
978 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
980 switch (fwin
->flags
.justification
) {
986 x
= fwin
->titlebar
->width
- w
- rofs
;
991 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
993 x
= (fwin
->titlebar
->width
- w
) / 2;
997 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
998 h
= WMFontHeight(*fwin
->font
);
1000 /* We use a w+2 buffer to have an extra pixel on the left and
1001 * another one on the right. This is because for some odd reason,
1002 * sometimes when using AA fonts (when libfreetype2 is compiled
1003 * with bytecode interpreter turned off), some fonts are drawn
1004 * starting from x = -1 not from 0 as requested. Observed with
1005 * capital A letter on the bold 'trebuchet ms' font. -Dan
1007 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1009 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1011 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1012 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1013 x
- 1, y
, w
+ 2, h
, 0, 0);
1015 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1016 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1019 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1020 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1021 *fwin
->font
, 1, 0, title
, titlelen
);
1023 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1025 XFreePixmap(dpy
, buf
);
1030 if (fwin
->left_button
)
1031 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1032 if (fwin
->right_button
)
1033 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1034 #ifdef XKB_BUTTON_HINT
1035 if (fwin
->language_button
)
1036 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1041 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1043 int k
= (wPreferences
.new_style
? 4 : 3);
1044 int resizedHorizontally
= 0;
1047 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1049 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1052 if (fwin->core->height != height && fwin->resizebar)
1053 XMoveWindow(dpy, fwin->resizebar->window, 0,
1054 height - fwin->resizebar->height);
1056 if (fwin
->core
->width
!= width
) {
1057 fwin
->flags
.need_texture_remake
= 1;
1058 resizedHorizontally
= 1;
1061 fwin
->core
->width
= width
;
1062 fwin
->core
->height
= height
;
1064 if (fwin
->titlebar
&& resizedHorizontally
) {
1065 /* Check if the titlebar is wide enough to hold the buttons.
1066 * Temporarily remove them if can't
1068 if (fwin
->left_button
) {
1069 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1071 if (!fwin
->flags
.hide_left_button
) {
1072 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1074 fwin
->flags
.lbutton_dont_fit
= 1;
1075 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1077 if (!fwin
->flags
.hide_left_button
) {
1078 XMapWindow(dpy
, fwin
->left_button
->window
);
1080 fwin
->flags
.lbutton_dont_fit
= 0;
1083 #ifdef XKB_BUTTON_HINT
1084 if (fwin
->language_button
) {
1085 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1087 if (!fwin
->flags
.hide_language_button
) {
1088 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1090 fwin
->flags
.languagebutton_dont_fit
= 1;
1091 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1093 if (!fwin
->flags
.hide_language_button
) {
1094 XMapWindow(dpy
, fwin
->language_button
->window
);
1096 fwin
->flags
.languagebutton_dont_fit
= 0;
1101 if (fwin
->right_button
) {
1102 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1104 if (!fwin
->flags
.hide_right_button
) {
1105 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1107 fwin
->flags
.rbutton_dont_fit
= 1;
1108 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1110 if (!fwin
->flags
.hide_right_button
) {
1111 XMapWindow(dpy
, fwin
->right_button
->window
);
1113 fwin
->flags
.rbutton_dont_fit
= 0;
1117 if (wPreferences
.new_style
) {
1118 if (fwin
->right_button
)
1119 XMoveWindow(dpy
, fwin
->right_button
->window
,
1120 width
- fwin
->right_button
->width
+ 1, 0);
1122 if (fwin
->right_button
)
1123 XMoveWindow(dpy
, fwin
->right_button
->window
,
1124 width
- fwin
->right_button
->width
- 3,
1125 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1127 updateTitlebar(fwin
);
1128 checkTitleSize(fwin
);
1131 if (fwin
->resizebar
) {
1132 wCoreConfigure(fwin
->resizebar
, 0,
1133 fwin
->core
->height
- fwin
->resizebar
->height
,
1134 fwin
->core
->width
, fwin
->resizebar
->height
);
1136 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1137 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
1138 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1143 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1145 reconfigure(fwin
, x
, y
, width
, height
, False
);
1148 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1150 reconfigure(fwin
, 0, 0, width
, height
, True
);
1153 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1155 /* check if the title is the same as before */
1157 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
1168 fwin
->title
= wstrdup(new_title
);
1170 if (fwin
->titlebar
) {
1171 XClearWindow(dpy
, fwin
->titlebar
->window
);
1173 wFrameWindowPaint(fwin
);
1175 checkTitleSize(fwin
);
1180 #ifdef XKB_BUTTON_HINT
1181 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1183 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1184 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1186 #endif /* XKB_BUTTON_HINT */
1188 /*********************************************************************/
1190 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1192 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1194 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1195 fwin
->flags
.repaint_only_titlebar
= 1;
1196 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1197 fwin
->flags
.repaint_only_resizebar
= 1;
1198 wFrameWindowPaint(fwin
);
1199 fwin
->flags
.repaint_only_titlebar
= 0;
1200 fwin
->flags
.repaint_only_resizebar
= 0;
1203 static void checkTitleSize(WFrameWindow
* fwin
)
1208 fwin
->flags
.incomplete_title
= 0;
1212 if (!fwin
->titlebar
) {
1213 fwin
->flags
.incomplete_title
= 1;
1216 width
= fwin
->titlebar
->width
- 6 - 6;
1219 if (!wPreferences
.new_style
) {
1220 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1221 width
-= fwin
->left_button
->width
+ 3;
1223 #ifdef XKB_BUTTON_HINT
1224 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1225 && !fwin
->flags
.languagebutton_dont_fit
)
1226 width
-= fwin
->language_button
->width
+ 3;
1229 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1230 width
-= fwin
->right_button
->width
+ 3;
1232 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
) {
1233 fwin
->flags
.incomplete_title
= 1;
1235 fwin
->flags
.incomplete_title
= 0;
1239 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1241 WScreen
*scr
= button
->screen_ptr
;
1242 GC copy_gc
= scr
->copy_gc
;
1243 int x
= 0, y
= 0, d
= 0;
1244 int left
= 0, width
= 0;
1246 /* setup stuff according to the state */
1249 if (image
->width
>= image
->height
* 2) {
1250 /* the image contains 2 pictures: the second is for the
1252 width
= image
->width
/ 2;
1253 left
= image
->width
/ 2;
1255 width
= image
->width
;
1258 XSetClipMask(dpy
, copy_gc
, None
);
1259 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1261 if (wPreferences
.new_style
) {
1262 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1263 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1264 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1266 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1267 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1268 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1271 XClearWindow(dpy
, button
->window
);
1274 if (image
->width
>= image
->height
* 2)
1275 width
= image
->width
/ 2;
1277 width
= image
->width
;
1281 if (wPreferences
.new_style
) {
1282 if (texture
->any
.type
== WTEX_SOLID
|| pushed
) {
1283 wDrawBevel(button
->window
, button
->width
, button
->height
,
1284 (WTexSolid
*) texture
, WREL_RAISED
);
1287 wDrawBevel(button
->window
, button
->width
, button
->height
,
1288 scr
->widget_texture
, WREL_RAISED
);
1294 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1295 x
= (button
->width
- width
) / 2 + d
;
1296 y
= (button
->height
- image
->height
) / 2 + d
;
1297 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1298 if (!wPreferences
.new_style
) {
1299 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1301 if (image
->depth
== 1)
1302 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1303 left
, 0, width
, image
->height
, x
, y
, 1);
1305 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1306 left
, 0, width
, image
->height
, x
, y
);
1308 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1309 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1313 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1315 XSetForeground(dpy
, copy_gc
, color
);
1316 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1318 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1323 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1325 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1326 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1328 #ifdef XKB_BUTTON_HINT
1329 if (button
== fwin
->language_button
) {
1330 if (wPreferences
.modelock
) {
1331 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1332 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1333 fwin
->languagebutton_image
, False
);
1337 if (button
== fwin
->left_button
) {
1338 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1339 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1341 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1342 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1346 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1348 WFrameWindow
*fwin
= desc
->parent
;
1349 WCoreWindow
*titlebar
= desc
->self
;
1351 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1352 if (fwin
->on_dblclick_titlebar
) {
1353 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1356 if (fwin
->on_mousedown_titlebar
) {
1357 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1362 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1364 WFrameWindow
*fwin
= desc
->parent
;
1365 WCoreWindow
*resizebar
= desc
->self
;
1367 if (fwin
->on_mousedown_resizebar
)
1368 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1371 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1373 WFrameWindow
*fwin
= desc
->parent
;
1374 WCoreWindow
*button
= desc
->self
;
1377 int done
= 0, execute
= 1;
1379 unsigned long pixel
;
1380 int clickButton
= event
->xbutton
.button
;
1382 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1383 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1384 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1389 if (button
== fwin
->left_button
) {
1390 image
= fwin
->lbutton_image
;
1392 image
= fwin
->rbutton_image
;
1394 #ifdef XKB_BUTTON_HINT
1395 if (button
== fwin
->language_button
) {
1396 if (!wPreferences
.modelock
)
1398 image
= fwin
->languagebutton_image
;
1402 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1403 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1404 paintButton(button
, texture
, pixel
, image
, True
);
1407 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1408 | ButtonPressMask
| ExposureMask
, &ev
);
1412 paintButton(button
, texture
, pixel
, image
, False
);
1417 paintButton(button
, texture
, pixel
, image
, True
);
1424 if (ev
.xbutton
.button
== clickButton
)
1432 paintButton(button
, texture
, pixel
, image
, False
);
1435 if (button
== fwin
->left_button
) {
1436 if (fwin
->on_click_left
)
1437 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1438 } else if (button
== fwin
->right_button
) {
1439 if (fwin
->on_click_right
)
1440 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1442 #ifdef XKB_BUTTON_HINT
1443 else if (button
== fwin
->language_button
) {
1444 if (fwin
->on_click_language
)
1445 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);