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
);
159 if (fwin
->right_button
) {
160 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
162 } else { /* !new_style */
163 if (fwin
->left_button
) {
164 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
166 #ifdef XKB_BUTTON_HINT
167 if (fwin
->language_button
) {
168 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
173 if (fwin
->right_button
) {
174 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
175 (theight
- bsize
) / 2, bsize
, bsize
);
178 updateTitlebar(fwin
);
180 /* we had a titlebar, but now we don't need it anymore */
181 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
182 FREE_PIXMAP(fwin
->title_back
[i
]);
183 if (wPreferences
.new_style
) {
184 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
185 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
186 #ifdef XKB_BUTTON_HINT
187 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
191 if (fwin
->left_button
)
192 wCoreDestroy(fwin
->left_button
);
193 fwin
->left_button
= NULL
;
195 #ifdef XKB_BUTTON_HINT
196 if (fwin
->language_button
)
197 wCoreDestroy(fwin
->language_button
);
198 fwin
->language_button
= NULL
;
201 if (fwin
->right_button
)
202 wCoreDestroy(fwin
->right_button
);
203 fwin
->right_button
= NULL
;
205 wCoreDestroy(fwin
->titlebar
);
206 fwin
->titlebar
= NULL
;
211 /* if we didn't have a titlebar and are being requested for
213 if (flags
& WFF_TITLEBAR
) {
214 fwin
->top_width
= theight
;
216 fwin
->flags
.titlebar
= 1;
217 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
219 if (flags
& WFF_LEFT_BUTTON
) {
220 fwin
->flags
.left_button
= 1;
221 if (wPreferences
.new_style
) {
222 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
223 if (width
< theight
* 4) {
224 fwin
->flags
.lbutton_dont_fit
= 1;
226 XMapRaised(dpy
, fwin
->left_button
->window
);
230 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
232 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
233 scr
->widget_texture
->normal
.pixel
);
235 if (width
< theight
* 3) {
236 fwin
->flags
.lbutton_dont_fit
= 1;
238 XMapRaised(dpy
, fwin
->left_button
->window
);
242 #ifdef XKB_BUTTON_HINT
243 if (flags
& WFF_LANGUAGE_BUTTON
) {
244 fwin
->flags
.language_button
= 1;
245 if (wPreferences
.new_style
) {
246 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
248 if (width
< theight
* 4) {
249 fwin
->flags
.languagebutton_dont_fit
= 1;
251 XMapRaised(dpy
, fwin
->language_button
->window
);
254 fwin
->language_button
=
255 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
258 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
259 scr
->widget_texture
->normal
.pixel
);
261 if (width
< theight
* 3) {
262 fwin
->flags
.languagebutton_dont_fit
= 1;
264 XMapRaised(dpy
, fwin
->language_button
->window
);
270 if (flags
& WFF_RIGHT_BUTTON
) {
271 fwin
->flags
.right_button
= 1;
272 if (wPreferences
.new_style
) {
274 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
277 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
278 (theight
- bsize
) / 2, bsize
, bsize
);
279 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
280 scr
->widget_texture
->normal
.pixel
);
283 if (width
< theight
* 2) {
284 fwin
->flags
.rbutton_dont_fit
= 1;
286 XMapRaised(dpy
, fwin
->right_button
->window
);
290 if (wPreferences
.new_style
)
291 updateTitlebar(fwin
);
293 XMapRaised(dpy
, fwin
->titlebar
->window
);
295 fwin
->flags
.need_texture_remake
= 1;
298 checkTitleSize(fwin
);
300 if (flags
& WFF_RESIZEBAR
) {
301 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
303 if (!fwin
->resizebar
) {
304 fwin
->flags
.resizebar
= 1;
305 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
306 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
307 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
308 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
309 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
310 if (fwin
->resizebar_corner_width
< 0)
311 fwin
->resizebar_corner_width
= 0;
314 XMapWindow(dpy
, fwin
->resizebar
->window
);
315 XLowerWindow(dpy
, fwin
->resizebar
->window
);
317 fwin
->flags
.need_texture_remake
= 1;
319 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
) {
320 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
321 width
, RESIZEBAR_HEIGHT
);
325 fwin
->bottom_width
= 0;
327 if (fwin
->resizebar
) {
328 fwin
->bottom_width
= 0;
329 wCoreDestroy(fwin
->resizebar
);
330 fwin
->resizebar
= NULL
;
334 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
)) {
335 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
338 if (flags
& WFF_BORDER
) {
339 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
341 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
344 /* setup object descriptors */
346 if (fwin
->titlebar
) {
347 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
348 fwin
->titlebar
->descriptor
.parent
= fwin
;
349 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
350 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
353 if (fwin
->resizebar
) {
354 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
355 fwin
->resizebar
->descriptor
.parent
= fwin
;
356 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
357 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
360 if (fwin
->left_button
) {
361 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
362 fwin
->left_button
->descriptor
.parent
= fwin
;
363 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
364 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
366 #ifdef XKB_BUTTON_HINT
367 if (fwin
->language_button
) {
368 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
369 fwin
->language_button
->descriptor
.parent
= fwin
;
370 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
371 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
375 if (fwin
->right_button
) {
376 fwin
->right_button
->descriptor
.parent
= fwin
;
377 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
378 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
379 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
382 checkTitleSize(fwin
);
385 void wFrameWindowDestroy(WFrameWindow
* fwin
)
389 if (fwin
->left_button
)
390 wCoreDestroy(fwin
->left_button
);
392 #ifdef XKB_BUTTON_HINT
393 if (fwin
->language_button
)
394 wCoreDestroy(fwin
->language_button
);
397 if (fwin
->right_button
)
398 wCoreDestroy(fwin
->right_button
);
401 wCoreDestroy(fwin
->resizebar
);
404 wCoreDestroy(fwin
->titlebar
);
406 RemoveFromStackList(fwin
->core
);
408 wCoreDestroy(fwin
->core
);
413 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
414 FREE_PIXMAP(fwin
->title_back
[i
]);
415 if (wPreferences
.new_style
) {
416 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
417 #ifdef XKB_BUTTON_HINT
418 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
420 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
427 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
429 if (fwin
->flags
.state
== state
)
432 fwin
->flags
.state
= state
;
433 fwin
->flags
.need_texture_change
= 1;
435 wFrameWindowPaint(fwin
);
438 static void updateTitlebar(WFrameWindow
* fwin
)
443 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
446 w
= fwin
->core
->width
+ 1;
448 if (wPreferences
.new_style
) {
449 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
451 #ifdef XKB_BUTTON_HINT
452 if (fwin
->language_button
)
453 wCoreConfigure(fwin
->language_button
, 0, 0,
454 fwin
->language_button
->width
, fwin
->language_button
->width
);
457 #ifdef XKB_BUTTON_HINT
458 if (fwin
->language_button
)
459 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
460 fwin
->language_button
->width
, fwin
->language_button
->width
);
462 x
= fwin
->left_button
->width
;
463 w
-= fwin
->left_button
->width
;
465 #ifdef XKB_BUTTON_HINT
466 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
467 || fwin
->flags
.languagebutton_dont_fit
) {
469 x
+= fwin
->language_button
->width
;
470 w
-= fwin
->language_button
->width
;
474 #ifdef XKB_BUTTON_HINT
476 int bsize
= theight
- 7;
477 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
478 if (fwin
->language_button
)
479 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
480 fwin
->language_button
->width
, fwin
->language_button
->width
);
482 if (fwin
->language_button
)
483 wCoreConfigure(fwin
->language_button
,
484 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
485 fwin
->language_button
->width
, fwin
->language_button
->width
);
490 if (wPreferences
.new_style
) {
491 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
) {
492 w
-= fwin
->right_button
->width
;
496 if (wPreferences
.new_style
|| fwin
->titlebar
->width
!= w
)
497 fwin
->flags
.need_texture_remake
= 1;
499 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
502 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
504 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
505 XUnmapWindow(dpy
, fwin
->right_button
->window
);
506 fwin
->flags
.hide_right_button
= 1;
509 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
510 XUnmapWindow(dpy
, fwin
->left_button
->window
);
511 fwin
->flags
.hide_left_button
= 1;
513 #ifdef XKB_BUTTON_HINT
514 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
515 XUnmapWindow(dpy
, fwin
->language_button
->window
);
516 fwin
->flags
.hide_language_button
= 1;
520 if (fwin
->titlebar
) {
521 if (wPreferences
.new_style
) {
522 updateTitlebar(fwin
);
524 #ifdef XKB_BUTTON_HINT
525 updateTitlebar(fwin
);
527 XClearWindow(dpy
, fwin
->titlebar
->window
);
528 wFrameWindowPaint(fwin
);
531 checkTitleSize(fwin
);
535 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
537 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
539 if (!fwin
->flags
.rbutton_dont_fit
)
540 XMapWindow(dpy
, fwin
->right_button
->window
);
542 fwin
->flags
.hide_right_button
= 0;
544 #ifdef XKB_BUTTON_HINT
545 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
547 if (!fwin
->flags
.languagebutton_dont_fit
)
548 XMapWindow(dpy
, fwin
->language_button
->window
);
550 fwin
->flags
.hide_language_button
= 0;
554 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
556 if (!fwin
->flags
.lbutton_dont_fit
)
557 XMapWindow(dpy
, fwin
->left_button
->window
);
559 fwin
->flags
.hide_left_button
= 0;
562 if (fwin
->titlebar
) {
563 if (wPreferences
.new_style
) {
564 updateTitlebar(fwin
);
566 XClearWindow(dpy
, fwin
->titlebar
->window
);
567 wFrameWindowPaint(fwin
);
569 checkTitleSize(fwin
);
574 #ifdef XKB_BUTTON_HINT
575 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
576 int bwidth
, int bheight
, int left
, int language
, int right
,
577 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
579 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
580 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
584 RImage
*limg
, *rimg
, *mimg
;
585 #ifdef XKB_BUTTON_HINT
593 #ifdef XKB_BUTTON_HINT
594 *languagebutton
= None
;
597 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
599 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
603 if (wPreferences
.new_style
) {
605 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
612 #ifdef XKB_BUTTON_HINT
614 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
620 RBevelImage(limg
, RBEV_RAISED2
);
621 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
622 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
628 #ifdef XKB_BUTTON_HINT
630 RBevelImage(timg
, RBEV_RAISED2
);
631 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
)) {
632 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
641 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
646 RBevelImage(rimg
, RBEV_RAISED2
);
647 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
648 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
655 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
656 RBevelImage(mimg
, RBEV_RAISED2
);
658 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
659 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
663 RBevelImage(img
, RBEV_RAISED2
);
665 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
666 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
670 RBevelImage(img
, RBEV_RAISED2
);
672 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
673 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
681 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
689 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
691 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
696 light
.red
= light
.green
= light
.blue
= 80;
699 dark
.red
= dark
.green
= dark
.blue
= 40;
701 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
702 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
704 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
705 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
708 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
709 width
- cwidth
- 2, height
- 1, &dark
);
710 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
712 #ifdef SHADOW_RESIZEBAR
713 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
714 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
715 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
716 #endif /* SHADOW_RESIZEBAR */
718 if (!RConvertImage(scr
->rcontext
, img
, pmap
)) {
719 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
725 static void updateTexture(WFrameWindow
* fwin
)
730 i
= fwin
->flags
.state
;
731 if (fwin
->titlebar
) {
732 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
733 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
734 if (wPreferences
.new_style
) {
735 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
736 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
737 fwin
->lbutton_back
[i
]);
739 #ifdef XKB_BUTTON_HINT
740 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
]) {
741 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
742 fwin
->languagebutton_back
[i
]);
746 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
747 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
748 fwin
->rbutton_back
[i
]);
751 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
752 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
753 if (wPreferences
.new_style
) {
754 if (fwin
->left_button
)
755 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
756 #ifdef XKB_BUTTON_HINT
757 if (fwin
->language_button
)
758 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
760 if (fwin
->right_button
)
761 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
764 XClearWindow(dpy
, fwin
->titlebar
->window
);
766 if (fwin
->left_button
) {
767 XClearWindow(dpy
, fwin
->left_button
->window
);
768 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
770 #ifdef XKB_BUTTON_HINT
771 if (fwin
->language_button
) {
772 XClearWindow(dpy
, fwin
->language_button
->window
);
773 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
776 if (fwin
->right_button
) {
777 XClearWindow(dpy
, fwin
->right_button
->window
);
778 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
783 static void remakeTexture(WFrameWindow
* fwin
, int state
)
785 Pixmap pmap
, lpmap
, rpmap
;
786 #ifdef XKB_BUTTON_HINT
790 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
791 FREE_PIXMAP(fwin
->title_back
[state
]);
792 if (wPreferences
.new_style
) {
793 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
794 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
795 #ifdef XKB_BUTTON_HINT
796 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
800 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
803 #ifdef XKB_BUTTON_HINT
807 /* eventually surrounded by if new_style */
808 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
809 #ifdef XKB_BUTTON_HINT
810 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
811 && !fwin
->flags
.languagebutton_dont_fit
;
813 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
814 && !fwin
->flags
.rbutton_dont_fit
;
816 width
= fwin
->core
->width
+ 1;
818 #ifdef XKB_BUTTON_HINT
819 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
820 width
, fwin
->titlebar
->height
,
821 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
822 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
824 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
825 width
, fwin
->titlebar
->height
,
826 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
827 left
, right
, &pmap
, &lpmap
, &rpmap
);
830 fwin
->title_back
[state
] = pmap
;
831 if (wPreferences
.new_style
) {
832 fwin
->lbutton_back
[state
] = lpmap
;
833 fwin
->rbutton_back
[state
] = rpmap
;
834 #ifdef XKB_BUTTON_HINT
835 fwin
->languagebutton_back
[state
] = tpmap
;
840 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
841 && fwin
->resizebar
&& state
== 0) {
843 FREE_PIXMAP(fwin
->resizebar_back
[0]);
845 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
847 renderResizebarTexture(fwin
->screen_ptr
,
848 fwin
->resizebar_texture
[0],
849 fwin
->resizebar
->width
,
850 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
852 fwin
->resizebar_back
[0] = pmap
;
855 /* this part should be in updateTexture() */
856 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
857 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
859 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
860 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
862 XClearWindow(dpy
, fwin
->resizebar
->window
);
866 void wFrameWindowPaint(WFrameWindow
* fwin
)
868 WScreen
*scr
= fwin
->screen_ptr
;
871 state
= fwin
->flags
.state
;
873 if (fwin
->flags
.is_client_window_frame
)
874 fwin
->flags
.justification
= wPreferences
.title_justification
;
876 if (fwin
->flags
.need_texture_remake
) {
879 fwin
->flags
.need_texture_remake
= 0;
880 fwin
->flags
.need_texture_change
= 0;
882 if (fwin
->flags
.single_texture
) {
883 remakeTexture(fwin
, 0);
886 /* first render the texture for the current state... */
887 remakeTexture(fwin
, state
);
888 /* ... and paint it */
891 for (i
= 0; i
< 3; i
++) {
893 remakeTexture(fwin
, i
);
899 if (fwin
->flags
.need_texture_change
) {
900 fwin
->flags
.need_texture_change
= 0;
905 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
906 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
907 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
908 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
911 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
912 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
917 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
919 w
= fwin
->resizebar
->width
;
920 h
= fwin
->resizebar
->height
;
921 cw
= fwin
->resizebar_corner_width
;
922 light_gc
= texture
->light_gc
;
923 dim_gc
= texture
->dim_gc
;
924 win
= fwin
->resizebar
->window
;
926 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
927 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
929 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
930 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
932 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
933 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
935 #ifdef SHADOW_RESIZEBAR
936 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
937 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
938 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
939 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
940 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
941 #endif /* SHADOW_RESIZEBAR */
944 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
946 int lofs
= 6, rofs
= 6;
950 if (!wPreferences
.new_style
) {
951 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
952 lofs
+= fwin
->left_button
->width
+ 3;
956 #ifdef XKB_BUTTON_HINT
957 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
958 && !fwin
->flags
.languagebutton_dont_fit
)
959 lofs
+= fwin
->language_button
->width
;
964 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
965 rofs
+= fwin
->right_button
->width
+ 3;
969 #ifdef XKB_BUTTON_HINT
970 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
977 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
978 titlelen
= strlen(title
);
979 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
981 switch (fwin
->flags
.justification
) {
987 x
= fwin
->titlebar
->width
- w
- rofs
;
992 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
994 x
= (fwin
->titlebar
->width
- w
) / 2;
998 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
999 h
= WMFontHeight(*fwin
->font
);
1001 /* We use a w+2 buffer to have an extra pixel on the left and
1002 * another one on the right. This is because for some odd reason,
1003 * sometimes when using AA fonts (when libfreetype2 is compiled
1004 * with bytecode interpreter turned off), some fonts are drawn
1005 * starting from x = -1 not from 0 as requested. Observed with
1006 * capital A letter on the bold 'trebuchet ms' font. -Dan
1008 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1010 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1012 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1013 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1014 x
- 1, y
, w
+ 2, h
, 0, 0);
1016 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1017 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1020 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1021 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1022 *fwin
->font
, 1, 0, title
, titlelen
);
1024 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1026 XFreePixmap(dpy
, buf
);
1031 if (fwin
->left_button
)
1032 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1033 if (fwin
->right_button
)
1034 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1035 #ifdef XKB_BUTTON_HINT
1036 if (fwin
->language_button
)
1037 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1042 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1044 int k
= (wPreferences
.new_style
? 4 : 3);
1045 int resizedHorizontally
= 0;
1048 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1050 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1053 if (fwin->core->height != height && fwin->resizebar)
1054 XMoveWindow(dpy, fwin->resizebar->window, 0,
1055 height - fwin->resizebar->height);
1057 if (fwin
->core
->width
!= width
) {
1058 fwin
->flags
.need_texture_remake
= 1;
1059 resizedHorizontally
= 1;
1062 fwin
->core
->width
= width
;
1063 fwin
->core
->height
= height
;
1065 if (fwin
->titlebar
&& resizedHorizontally
) {
1066 /* Check if the titlebar is wide enough to hold the buttons.
1067 * Temporarily remove them if can't
1069 if (fwin
->left_button
) {
1070 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1072 if (!fwin
->flags
.hide_left_button
) {
1073 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1075 fwin
->flags
.lbutton_dont_fit
= 1;
1076 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1078 if (!fwin
->flags
.hide_left_button
) {
1079 XMapWindow(dpy
, fwin
->left_button
->window
);
1081 fwin
->flags
.lbutton_dont_fit
= 0;
1084 #ifdef XKB_BUTTON_HINT
1085 if (fwin
->language_button
) {
1086 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1088 if (!fwin
->flags
.hide_language_button
) {
1089 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1091 fwin
->flags
.languagebutton_dont_fit
= 1;
1092 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1094 if (!fwin
->flags
.hide_language_button
) {
1095 XMapWindow(dpy
, fwin
->language_button
->window
);
1097 fwin
->flags
.languagebutton_dont_fit
= 0;
1102 if (fwin
->right_button
) {
1103 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1105 if (!fwin
->flags
.hide_right_button
) {
1106 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1108 fwin
->flags
.rbutton_dont_fit
= 1;
1109 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1111 if (!fwin
->flags
.hide_right_button
) {
1112 XMapWindow(dpy
, fwin
->right_button
->window
);
1114 fwin
->flags
.rbutton_dont_fit
= 0;
1118 if (wPreferences
.new_style
) {
1119 if (fwin
->right_button
)
1120 XMoveWindow(dpy
, fwin
->right_button
->window
,
1121 width
- fwin
->right_button
->width
+ 1, 0);
1123 if (fwin
->right_button
)
1124 XMoveWindow(dpy
, fwin
->right_button
->window
,
1125 width
- fwin
->right_button
->width
- 3,
1126 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1128 updateTitlebar(fwin
);
1129 checkTitleSize(fwin
);
1132 if (fwin
->resizebar
) {
1133 wCoreConfigure(fwin
->resizebar
, 0,
1134 fwin
->core
->height
- fwin
->resizebar
->height
,
1135 fwin
->core
->width
, fwin
->resizebar
->height
);
1137 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1138 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
1139 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1144 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1146 reconfigure(fwin
, x
, y
, width
, height
, False
);
1149 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1151 reconfigure(fwin
, 0, 0, width
, height
, True
);
1154 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1156 /* check if the title is the same as before */
1158 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
1169 fwin
->title
= wstrdup(new_title
);
1171 if (fwin
->titlebar
) {
1172 XClearWindow(dpy
, fwin
->titlebar
->window
);
1174 wFrameWindowPaint(fwin
);
1176 checkTitleSize(fwin
);
1181 #ifdef XKB_BUTTON_HINT
1182 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1184 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1185 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1187 #endif /* XKB_BUTTON_HINT */
1189 /*********************************************************************/
1191 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1193 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1195 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1196 fwin
->flags
.repaint_only_titlebar
= 1;
1197 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1198 fwin
->flags
.repaint_only_resizebar
= 1;
1199 wFrameWindowPaint(fwin
);
1200 fwin
->flags
.repaint_only_titlebar
= 0;
1201 fwin
->flags
.repaint_only_resizebar
= 0;
1204 static void checkTitleSize(WFrameWindow
* fwin
)
1209 fwin
->flags
.incomplete_title
= 0;
1213 if (!fwin
->titlebar
) {
1214 fwin
->flags
.incomplete_title
= 1;
1217 width
= fwin
->titlebar
->width
- 6 - 6;
1220 if (!wPreferences
.new_style
) {
1221 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1222 width
-= fwin
->left_button
->width
+ 3;
1224 #ifdef XKB_BUTTON_HINT
1225 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1226 && !fwin
->flags
.languagebutton_dont_fit
)
1227 width
-= fwin
->language_button
->width
+ 3;
1230 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1231 width
-= fwin
->right_button
->width
+ 3;
1233 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
) {
1234 fwin
->flags
.incomplete_title
= 1;
1236 fwin
->flags
.incomplete_title
= 0;
1240 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1242 WScreen
*scr
= button
->screen_ptr
;
1243 GC copy_gc
= scr
->copy_gc
;
1244 int x
= 0, y
= 0, d
= 0;
1245 int left
= 0, width
= 0;
1247 /* setup stuff according to the state */
1250 if (image
->width
>= image
->height
* 2) {
1251 /* the image contains 2 pictures: the second is for the
1253 width
= image
->width
/ 2;
1254 left
= image
->width
/ 2;
1256 width
= image
->width
;
1259 XSetClipMask(dpy
, copy_gc
, None
);
1260 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1262 if (wPreferences
.new_style
) {
1263 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1264 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1265 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1267 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1268 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1269 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1272 XClearWindow(dpy
, button
->window
);
1275 if (image
->width
>= image
->height
* 2)
1276 width
= image
->width
/ 2;
1278 width
= image
->width
;
1282 if (wPreferences
.new_style
) {
1283 if (texture
->any
.type
== WTEX_SOLID
|| pushed
) {
1284 wDrawBevel(button
->window
, button
->width
, button
->height
,
1285 (WTexSolid
*) texture
, WREL_RAISED
);
1288 wDrawBevel(button
->window
, button
->width
, button
->height
,
1289 scr
->widget_texture
, WREL_RAISED
);
1295 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1296 x
= (button
->width
- width
) / 2 + d
;
1297 y
= (button
->height
- image
->height
) / 2 + d
;
1298 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1299 if (!wPreferences
.new_style
) {
1300 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1302 if (image
->depth
== 1)
1303 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1304 left
, 0, width
, image
->height
, x
, y
, 1);
1306 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1307 left
, 0, width
, image
->height
, x
, y
);
1309 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1310 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1314 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1316 XSetForeground(dpy
, copy_gc
, color
);
1317 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1319 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1324 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1326 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1327 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1329 #ifdef XKB_BUTTON_HINT
1330 if (button
== fwin
->language_button
) {
1331 if (wPreferences
.modelock
) {
1332 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1333 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1334 fwin
->languagebutton_image
, False
);
1338 if (button
== fwin
->left_button
) {
1339 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1340 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1342 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1343 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1347 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1349 WFrameWindow
*fwin
= desc
->parent
;
1350 WCoreWindow
*titlebar
= desc
->self
;
1352 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1353 if (fwin
->on_dblclick_titlebar
) {
1354 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1357 if (fwin
->on_mousedown_titlebar
) {
1358 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1363 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1365 WFrameWindow
*fwin
= desc
->parent
;
1366 WCoreWindow
*resizebar
= desc
->self
;
1368 if (fwin
->on_mousedown_resizebar
)
1369 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1372 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1374 WFrameWindow
*fwin
= desc
->parent
;
1375 WCoreWindow
*button
= desc
->self
;
1378 int done
= 0, execute
= 1;
1380 unsigned long pixel
;
1381 int clickButton
= event
->xbutton
.button
;
1383 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1384 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1385 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1390 if (button
== fwin
->left_button
) {
1391 image
= fwin
->lbutton_image
;
1393 image
= fwin
->rbutton_image
;
1395 #ifdef XKB_BUTTON_HINT
1396 if (button
== fwin
->language_button
) {
1397 if (!wPreferences
.modelock
)
1399 image
= fwin
->languagebutton_image
;
1403 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1404 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1405 paintButton(button
, texture
, pixel
, image
, True
);
1408 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1409 | ButtonPressMask
| ExposureMask
, &ev
);
1413 paintButton(button
, texture
, pixel
, image
, False
);
1418 paintButton(button
, texture
, pixel
, image
, True
);
1425 if (ev
.xbutton
.button
== clickButton
)
1433 paintButton(button
, texture
, pixel
, image
, False
);
1436 if (button
== fwin
->left_button
) {
1437 if (fwin
->on_click_left
)
1438 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1439 } else if (button
== fwin
->right_button
) {
1440 if (fwin
->on_click_right
)
1441 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1443 #ifdef XKB_BUTTON_HINT
1444 else if (button
== fwin
->language_button
) {
1445 if (fwin
->on_click_language
)
1446 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);