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
== TS_NEW
) {
132 } else if (wPreferences
.new_style
== TS_OLD
) {
138 if (fwin
->titlebar
) {
139 /* if we had a titlebar and is requesting for one,
140 * check if the size has changed and resize it */
141 if (flags
& WFF_TITLEBAR
) {
142 fwin
->top_width
= theight
;
144 fwin
->flags
.need_texture_remake
= 1;
146 if (wPreferences
.new_style
== TS_NEW
) {
147 if (fwin
->left_button
) {
148 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
150 #ifdef XKB_BUTTON_HINT
151 if (fwin
->language_button
) {
152 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
153 || fwin
->flags
.lbutton_dont_fit
) {
154 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
156 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
161 if (fwin
->right_button
) {
162 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
164 } else { /* !new_style */
165 if (fwin
->left_button
) {
166 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
168 #ifdef XKB_BUTTON_HINT
169 if (fwin
->language_button
) {
170 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
175 if (fwin
->right_button
) {
176 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
177 (theight
- bsize
) / 2, bsize
, bsize
);
180 updateTitlebar(fwin
);
182 /* we had a titlebar, but now we don't need it anymore */
183 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
184 FREE_PIXMAP(fwin
->title_back
[i
]);
185 if (wPreferences
.new_style
== TS_NEW
) {
186 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
187 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
188 #ifdef XKB_BUTTON_HINT
189 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
193 if (fwin
->left_button
)
194 wCoreDestroy(fwin
->left_button
);
195 fwin
->left_button
= NULL
;
197 #ifdef XKB_BUTTON_HINT
198 if (fwin
->language_button
)
199 wCoreDestroy(fwin
->language_button
);
200 fwin
->language_button
= NULL
;
203 if (fwin
->right_button
)
204 wCoreDestroy(fwin
->right_button
);
205 fwin
->right_button
= NULL
;
207 wCoreDestroy(fwin
->titlebar
);
208 fwin
->titlebar
= NULL
;
213 /* if we didn't have a titlebar and are being requested for
215 if (flags
& WFF_TITLEBAR
) {
216 fwin
->top_width
= theight
;
218 fwin
->flags
.titlebar
= 1;
219 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
221 if (flags
& WFF_LEFT_BUTTON
) {
222 fwin
->flags
.left_button
= 1;
223 if (wPreferences
.new_style
== TS_NEW
) {
224 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
225 if (width
< theight
* 4) {
226 fwin
->flags
.lbutton_dont_fit
= 1;
228 XMapRaised(dpy
, fwin
->left_button
->window
);
230 } else if (wPreferences
.new_style
== TS_OLD
) {
232 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
234 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
235 scr
->widget_texture
->normal
.pixel
);
237 if (width
< theight
* 3) {
238 fwin
->flags
.lbutton_dont_fit
= 1;
240 XMapRaised(dpy
, fwin
->left_button
->window
);
244 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
247 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
248 scr
->widget_texture
->dark
.pixel
);
250 if (width
< theight
*3) {
251 fwin
->flags
.lbutton_dont_fit
= 1;
253 XMapRaised(dpy
, fwin
->left_button
->window
);
257 #ifdef XKB_BUTTON_HINT
258 if (flags
& WFF_LANGUAGE_BUTTON
) {
259 fwin
->flags
.language_button
= 1;
260 if (wPreferences
.new_style
== TS_NEW
) {
261 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
263 if (width
< theight
* 4) {
264 fwin
->flags
.languagebutton_dont_fit
= 1;
266 XMapRaised(dpy
, fwin
->language_button
->window
);
269 fwin
->language_button
=
270 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
273 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
274 scr
->widget_texture
->normal
.pixel
);
276 if (width
< theight
* 3) {
277 fwin
->flags
.languagebutton_dont_fit
= 1;
279 XMapRaised(dpy
, fwin
->language_button
->window
);
285 if (flags
& WFF_RIGHT_BUTTON
) {
286 fwin
->flags
.right_button
= 1;
287 if (wPreferences
.new_style
== TS_NEW
) {
289 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
290 } else if (wPreferences
.new_style
== TS_OLD
) {
292 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
293 (theight
- bsize
) / 2, bsize
, bsize
);
294 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
295 scr
->widget_texture
->normal
.pixel
);
298 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
299 (theight
-bsize
)/2, bsize
, bsize
);
300 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
301 scr
->widget_texture
->dark
.pixel
);
304 if (width
< theight
* 2) {
305 fwin
->flags
.rbutton_dont_fit
= 1;
307 XMapRaised(dpy
, fwin
->right_button
->window
);
311 if (wPreferences
.new_style
== TS_NEW
)
312 updateTitlebar(fwin
);
314 XMapRaised(dpy
, fwin
->titlebar
->window
);
316 fwin
->flags
.need_texture_remake
= 1;
319 checkTitleSize(fwin
);
321 if (flags
& WFF_RESIZEBAR
) {
322 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
324 if (!fwin
->resizebar
) {
325 fwin
->flags
.resizebar
= 1;
326 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
327 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
328 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
329 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
330 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
331 if (fwin
->resizebar_corner_width
< 0)
332 fwin
->resizebar_corner_width
= 0;
335 XMapWindow(dpy
, fwin
->resizebar
->window
);
336 XLowerWindow(dpy
, fwin
->resizebar
->window
);
338 fwin
->flags
.need_texture_remake
= 1;
340 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
) {
341 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
342 width
, RESIZEBAR_HEIGHT
);
346 fwin
->bottom_width
= 0;
348 if (fwin
->resizebar
) {
349 fwin
->bottom_width
= 0;
350 wCoreDestroy(fwin
->resizebar
);
351 fwin
->resizebar
= NULL
;
355 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
)) {
356 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
359 if (flags
& WFF_BORDER
) {
360 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
362 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
365 /* setup object descriptors */
367 if (fwin
->titlebar
) {
368 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
369 fwin
->titlebar
->descriptor
.parent
= fwin
;
370 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
371 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
374 if (fwin
->resizebar
) {
375 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
376 fwin
->resizebar
->descriptor
.parent
= fwin
;
377 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
378 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
381 if (fwin
->left_button
) {
382 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
383 fwin
->left_button
->descriptor
.parent
= fwin
;
384 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
385 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
387 #ifdef XKB_BUTTON_HINT
388 if (fwin
->language_button
) {
389 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
390 fwin
->language_button
->descriptor
.parent
= fwin
;
391 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
392 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
396 if (fwin
->right_button
) {
397 fwin
->right_button
->descriptor
.parent
= fwin
;
398 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
399 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
400 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
403 checkTitleSize(fwin
);
406 void wFrameWindowDestroy(WFrameWindow
* fwin
)
410 if (fwin
->left_button
)
411 wCoreDestroy(fwin
->left_button
);
413 #ifdef XKB_BUTTON_HINT
414 if (fwin
->language_button
)
415 wCoreDestroy(fwin
->language_button
);
418 if (fwin
->right_button
)
419 wCoreDestroy(fwin
->right_button
);
422 wCoreDestroy(fwin
->resizebar
);
425 wCoreDestroy(fwin
->titlebar
);
427 RemoveFromStackList(fwin
->core
);
429 wCoreDestroy(fwin
->core
);
434 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
435 FREE_PIXMAP(fwin
->title_back
[i
]);
436 if (wPreferences
.new_style
== TS_NEW
) {
437 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
438 #ifdef XKB_BUTTON_HINT
439 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
441 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
448 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
450 if (fwin
->flags
.state
== state
)
453 fwin
->flags
.state
= state
;
454 fwin
->flags
.need_texture_change
= 1;
456 wFrameWindowPaint(fwin
);
459 static void updateTitlebar(WFrameWindow
* fwin
)
464 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
467 w
= fwin
->core
->width
+ 1;
469 if (wPreferences
.new_style
== TS_NEW
) {
470 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
472 #ifdef XKB_BUTTON_HINT
473 if (fwin
->language_button
)
474 wCoreConfigure(fwin
->language_button
, 0, 0,
475 fwin
->language_button
->width
, fwin
->language_button
->width
);
478 #ifdef XKB_BUTTON_HINT
479 if (fwin
->language_button
)
480 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
481 fwin
->language_button
->width
, fwin
->language_button
->width
);
483 x
= fwin
->left_button
->width
;
484 w
-= fwin
->left_button
->width
;
486 #ifdef XKB_BUTTON_HINT
487 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
488 || fwin
->flags
.languagebutton_dont_fit
) {
490 x
+= fwin
->language_button
->width
;
491 w
-= fwin
->language_button
->width
;
495 #ifdef XKB_BUTTON_HINT
497 int bsize
= theight
- 7;
498 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
499 if (fwin
->language_button
)
500 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
501 fwin
->language_button
->width
, fwin
->language_button
->width
);
503 if (fwin
->language_button
)
504 wCoreConfigure(fwin
->language_button
,
505 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
506 fwin
->language_button
->width
, fwin
->language_button
->width
);
511 if (wPreferences
.new_style
== TS_NEW
) {
512 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
) {
513 w
-= fwin
->right_button
->width
;
517 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
518 fwin
->flags
.need_texture_remake
= 1;
520 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
523 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
525 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
526 XUnmapWindow(dpy
, fwin
->right_button
->window
);
527 fwin
->flags
.hide_right_button
= 1;
530 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
531 XUnmapWindow(dpy
, fwin
->left_button
->window
);
532 fwin
->flags
.hide_left_button
= 1;
534 #ifdef XKB_BUTTON_HINT
535 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
536 XUnmapWindow(dpy
, fwin
->language_button
->window
);
537 fwin
->flags
.hide_language_button
= 1;
541 if (fwin
->titlebar
) {
542 if (wPreferences
.new_style
== TS_NEW
) {
543 updateTitlebar(fwin
);
545 #ifdef XKB_BUTTON_HINT
546 updateTitlebar(fwin
);
548 XClearWindow(dpy
, fwin
->titlebar
->window
);
549 wFrameWindowPaint(fwin
);
552 checkTitleSize(fwin
);
556 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
558 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
560 if (!fwin
->flags
.rbutton_dont_fit
)
561 XMapWindow(dpy
, fwin
->right_button
->window
);
563 fwin
->flags
.hide_right_button
= 0;
565 #ifdef XKB_BUTTON_HINT
566 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
568 if (!fwin
->flags
.languagebutton_dont_fit
)
569 XMapWindow(dpy
, fwin
->language_button
->window
);
571 fwin
->flags
.hide_language_button
= 0;
575 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
577 if (!fwin
->flags
.lbutton_dont_fit
)
578 XMapWindow(dpy
, fwin
->left_button
->window
);
580 fwin
->flags
.hide_left_button
= 0;
583 if (fwin
->titlebar
) {
584 if (wPreferences
.new_style
== TS_NEW
) {
585 updateTitlebar(fwin
);
587 XClearWindow(dpy
, fwin
->titlebar
->window
);
588 wFrameWindowPaint(fwin
);
590 checkTitleSize(fwin
);
595 #ifdef XKB_BUTTON_HINT
596 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
597 int bwidth
, int bheight
, int left
, int language
, int right
,
598 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
600 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
601 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
605 RImage
*limg
, *rimg
, *mimg
;
606 #ifdef XKB_BUTTON_HINT
614 #ifdef XKB_BUTTON_HINT
615 *languagebutton
= None
;
618 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
620 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
624 if (wPreferences
.new_style
== TS_NEW
) {
626 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
633 #ifdef XKB_BUTTON_HINT
635 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
641 RBevelImage(limg
, RBEV_RAISED2
);
642 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
643 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
649 #ifdef XKB_BUTTON_HINT
651 RBevelImage(timg
, RBEV_RAISED2
);
652 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
)) {
653 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
662 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
667 RBevelImage(rimg
, RBEV_RAISED2
);
668 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
669 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
676 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
677 RBevelImage(mimg
, RBEV_RAISED2
);
679 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
680 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
684 RBevelImage(img
, RBEV_RAISED2
);
686 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
687 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
691 RBevelImage(img
, RBEV_RAISED2
);
693 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
694 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
702 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
710 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
712 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
717 light
.red
= light
.green
= light
.blue
= 80;
720 dark
.red
= dark
.green
= dark
.blue
= 40;
722 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
723 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
725 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
726 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
729 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
730 width
- cwidth
- 2, height
- 1, &dark
);
731 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
733 #ifdef SHADOW_RESIZEBAR
734 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
735 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
736 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
737 #endif /* SHADOW_RESIZEBAR */
739 if (!RConvertImage(scr
->rcontext
, img
, pmap
)) {
740 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
746 static void updateTexture(WFrameWindow
* fwin
)
751 i
= fwin
->flags
.state
;
752 if (fwin
->titlebar
) {
753 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
754 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
755 if (wPreferences
.new_style
== TS_NEW
) {
756 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
757 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
758 fwin
->lbutton_back
[i
]);
760 #ifdef XKB_BUTTON_HINT
761 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
]) {
762 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
763 fwin
->languagebutton_back
[i
]);
767 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
768 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
769 fwin
->rbutton_back
[i
]);
772 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
773 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
774 if (wPreferences
.new_style
== TS_NEW
) {
775 if (fwin
->left_button
)
776 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
777 #ifdef XKB_BUTTON_HINT
778 if (fwin
->language_button
)
779 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
781 if (fwin
->right_button
)
782 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
785 XClearWindow(dpy
, fwin
->titlebar
->window
);
787 if (fwin
->left_button
) {
788 XClearWindow(dpy
, fwin
->left_button
->window
);
789 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
791 #ifdef XKB_BUTTON_HINT
792 if (fwin
->language_button
) {
793 XClearWindow(dpy
, fwin
->language_button
->window
);
794 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
797 if (fwin
->right_button
) {
798 XClearWindow(dpy
, fwin
->right_button
->window
);
799 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
804 static void remakeTexture(WFrameWindow
* fwin
, int state
)
806 Pixmap pmap
, lpmap
, rpmap
;
807 #ifdef XKB_BUTTON_HINT
811 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
812 FREE_PIXMAP(fwin
->title_back
[state
]);
813 if (wPreferences
.new_style
== TS_NEW
) {
814 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
815 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
816 #ifdef XKB_BUTTON_HINT
817 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
821 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
824 #ifdef XKB_BUTTON_HINT
828 /* eventually surrounded by if new_style */
829 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
830 #ifdef XKB_BUTTON_HINT
831 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
832 && !fwin
->flags
.languagebutton_dont_fit
;
834 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
835 && !fwin
->flags
.rbutton_dont_fit
;
837 width
= fwin
->core
->width
+ 1;
839 #ifdef XKB_BUTTON_HINT
840 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
841 width
, fwin
->titlebar
->height
,
842 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
843 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
845 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
846 width
, fwin
->titlebar
->height
,
847 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
848 left
, right
, &pmap
, &lpmap
, &rpmap
);
851 fwin
->title_back
[state
] = pmap
;
852 if (wPreferences
.new_style
== TS_NEW
) {
853 fwin
->lbutton_back
[state
] = lpmap
;
854 fwin
->rbutton_back
[state
] = rpmap
;
855 #ifdef XKB_BUTTON_HINT
856 fwin
->languagebutton_back
[state
] = tpmap
;
861 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
862 && fwin
->resizebar
&& state
== 0) {
864 FREE_PIXMAP(fwin
->resizebar_back
[0]);
866 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
868 renderResizebarTexture(fwin
->screen_ptr
,
869 fwin
->resizebar_texture
[0],
870 fwin
->resizebar
->width
,
871 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
873 fwin
->resizebar_back
[0] = pmap
;
876 /* this part should be in updateTexture() */
877 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
878 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
880 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
881 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
883 XClearWindow(dpy
, fwin
->resizebar
->window
);
887 void wFrameWindowPaint(WFrameWindow
* fwin
)
889 WScreen
*scr
= fwin
->screen_ptr
;
892 state
= fwin
->flags
.state
;
894 if (fwin
->flags
.is_client_window_frame
)
895 fwin
->flags
.justification
= wPreferences
.title_justification
;
897 if (fwin
->flags
.need_texture_remake
) {
900 fwin
->flags
.need_texture_remake
= 0;
901 fwin
->flags
.need_texture_change
= 0;
903 if (fwin
->flags
.single_texture
) {
904 remakeTexture(fwin
, 0);
907 /* first render the texture for the current state... */
908 remakeTexture(fwin
, state
);
909 /* ... and paint it */
912 for (i
= 0; i
< 3; i
++) {
914 remakeTexture(fwin
, i
);
920 if (fwin
->flags
.need_texture_change
) {
921 fwin
->flags
.need_texture_change
= 0;
926 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
927 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
928 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
929 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
932 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
933 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
938 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
940 w
= fwin
->resizebar
->width
;
941 h
= fwin
->resizebar
->height
;
942 cw
= fwin
->resizebar_corner_width
;
943 light_gc
= texture
->light_gc
;
944 dim_gc
= texture
->dim_gc
;
945 win
= fwin
->resizebar
->window
;
947 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
948 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
950 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
951 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
953 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
954 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
956 #ifdef SHADOW_RESIZEBAR
957 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
958 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
959 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
960 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
961 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
962 #endif /* SHADOW_RESIZEBAR */
965 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
967 int lofs
= 6, rofs
= 6;
971 if (!wPreferences
.new_style
== TS_NEW
) {
972 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
973 lofs
+= fwin
->left_button
->width
+ 3;
977 #ifdef XKB_BUTTON_HINT
978 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
979 && !fwin
->flags
.languagebutton_dont_fit
)
980 lofs
+= fwin
->language_button
->width
;
985 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
986 rofs
+= fwin
->right_button
->width
+ 3;
990 #ifdef XKB_BUTTON_HINT
991 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
998 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
999 titlelen
= strlen(title
);
1000 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1002 switch (fwin
->flags
.justification
) {
1008 x
= fwin
->titlebar
->width
- w
- rofs
;
1013 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1015 x
= (fwin
->titlebar
->width
- w
) / 2;
1019 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1020 h
= WMFontHeight(*fwin
->font
);
1022 /* We use a w+2 buffer to have an extra pixel on the left and
1023 * another one on the right. This is because for some odd reason,
1024 * sometimes when using AA fonts (when libfreetype2 is compiled
1025 * with bytecode interpreter turned off), some fonts are drawn
1026 * starting from x = -1 not from 0 as requested. Observed with
1027 * capital A letter on the bold 'trebuchet ms' font. -Dan
1029 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1031 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1033 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1034 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1035 x
- 1, y
, w
+ 2, h
, 0, 0);
1037 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1038 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1041 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1042 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1043 *fwin
->font
, 1, 0, title
, titlelen
);
1045 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1047 XFreePixmap(dpy
, buf
);
1052 if (fwin
->left_button
)
1053 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1054 if (fwin
->right_button
)
1055 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1056 #ifdef XKB_BUTTON_HINT
1057 if (fwin
->language_button
)
1058 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1063 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1065 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1066 int resizedHorizontally
= 0;
1069 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1071 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1074 if (fwin->core->height != height && fwin->resizebar)
1075 XMoveWindow(dpy, fwin->resizebar->window, 0,
1076 height - fwin->resizebar->height);
1078 if (fwin
->core
->width
!= width
) {
1079 fwin
->flags
.need_texture_remake
= 1;
1080 resizedHorizontally
= 1;
1083 fwin
->core
->width
= width
;
1084 fwin
->core
->height
= height
;
1086 if (fwin
->titlebar
&& resizedHorizontally
) {
1087 /* Check if the titlebar is wide enough to hold the buttons.
1088 * Temporarily remove them if can't
1090 if (fwin
->left_button
) {
1091 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1093 if (!fwin
->flags
.hide_left_button
) {
1094 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1096 fwin
->flags
.lbutton_dont_fit
= 1;
1097 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1099 if (!fwin
->flags
.hide_left_button
) {
1100 XMapWindow(dpy
, fwin
->left_button
->window
);
1102 fwin
->flags
.lbutton_dont_fit
= 0;
1105 #ifdef XKB_BUTTON_HINT
1106 if (fwin
->language_button
) {
1107 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1109 if (!fwin
->flags
.hide_language_button
) {
1110 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1112 fwin
->flags
.languagebutton_dont_fit
= 1;
1113 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1115 if (!fwin
->flags
.hide_language_button
) {
1116 XMapWindow(dpy
, fwin
->language_button
->window
);
1118 fwin
->flags
.languagebutton_dont_fit
= 0;
1123 if (fwin
->right_button
) {
1124 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1126 if (!fwin
->flags
.hide_right_button
) {
1127 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1129 fwin
->flags
.rbutton_dont_fit
= 1;
1130 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1132 if (!fwin
->flags
.hide_right_button
) {
1133 XMapWindow(dpy
, fwin
->right_button
->window
);
1135 fwin
->flags
.rbutton_dont_fit
= 0;
1139 if (wPreferences
.new_style
== TS_NEW
) {
1140 if (fwin
->right_button
)
1141 XMoveWindow(dpy
, fwin
->right_button
->window
,
1142 width
- fwin
->right_button
->width
+ 1, 0);
1144 if (fwin
->right_button
)
1145 XMoveWindow(dpy
, fwin
->right_button
->window
,
1146 width
- fwin
->right_button
->width
- 3,
1147 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1149 updateTitlebar(fwin
);
1150 checkTitleSize(fwin
);
1153 if (fwin
->resizebar
) {
1154 wCoreConfigure(fwin
->resizebar
, 0,
1155 fwin
->core
->height
- fwin
->resizebar
->height
,
1156 fwin
->core
->width
, fwin
->resizebar
->height
);
1158 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1159 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
1160 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1165 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1167 reconfigure(fwin
, x
, y
, width
, height
, False
);
1170 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1172 reconfigure(fwin
, 0, 0, width
, height
, True
);
1175 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1177 /* check if the title is the same as before */
1179 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
1190 fwin
->title
= wstrdup(new_title
);
1192 if (fwin
->titlebar
) {
1193 XClearWindow(dpy
, fwin
->titlebar
->window
);
1195 wFrameWindowPaint(fwin
);
1197 checkTitleSize(fwin
);
1202 #ifdef XKB_BUTTON_HINT
1203 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1205 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1206 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1208 #endif /* XKB_BUTTON_HINT */
1210 /*********************************************************************/
1212 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1214 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1216 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1217 fwin
->flags
.repaint_only_titlebar
= 1;
1218 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1219 fwin
->flags
.repaint_only_resizebar
= 1;
1220 wFrameWindowPaint(fwin
);
1221 fwin
->flags
.repaint_only_titlebar
= 0;
1222 fwin
->flags
.repaint_only_resizebar
= 0;
1225 static void checkTitleSize(WFrameWindow
* fwin
)
1230 fwin
->flags
.incomplete_title
= 0;
1234 if (!fwin
->titlebar
) {
1235 fwin
->flags
.incomplete_title
= 1;
1238 width
= fwin
->titlebar
->width
- 6 - 6;
1241 if (!wPreferences
.new_style
== TS_NEW
) {
1242 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1243 width
-= fwin
->left_button
->width
+ 3;
1245 #ifdef XKB_BUTTON_HINT
1246 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1247 && !fwin
->flags
.languagebutton_dont_fit
)
1248 width
-= fwin
->language_button
->width
+ 3;
1251 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1252 width
-= fwin
->right_button
->width
+ 3;
1254 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
) {
1255 fwin
->flags
.incomplete_title
= 1;
1257 fwin
->flags
.incomplete_title
= 0;
1261 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1263 WScreen
*scr
= button
->screen_ptr
;
1264 GC copy_gc
= scr
->copy_gc
;
1265 int x
= 0, y
= 0, d
= 0;
1266 int left
= 0, width
= 0;
1268 /* setup stuff according to the state */
1271 if (image
->width
>= image
->height
* 2) {
1272 /* the image contains 2 pictures: the second is for the
1274 width
= image
->width
/ 2;
1275 left
= image
->width
/ 2;
1277 width
= image
->width
;
1280 XSetClipMask(dpy
, copy_gc
, None
);
1281 if (wPreferences
.new_style
== TS_NEXT
) {
1282 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1284 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1287 if (wPreferences
.new_style
== TS_NEW
) {
1288 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1289 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1290 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1291 } else if (wPreferences
.new_style
== TS_OLD
) {
1292 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1293 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1294 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1296 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1297 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1298 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1301 XClearWindow(dpy
, button
->window
);
1304 if (image
->width
>= image
->height
* 2)
1305 width
= image
->width
/ 2;
1307 width
= image
->width
;
1311 if (wPreferences
.new_style
== TS_NEW
) {
1312 if (texture
->any
.type
== WTEX_SOLID
|| pushed
) {
1313 wDrawBevel(button
->window
, button
->width
, button
->height
,
1314 (WTexSolid
*) texture
, WREL_RAISED
);
1317 wDrawBevel(button
->window
, button
->width
, button
->height
,
1318 scr
->widget_texture
, WREL_RAISED
);
1324 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1325 x
= (button
->width
- width
) / 2 + d
;
1326 y
= (button
->height
- image
->height
) / 2 + d
;
1327 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1328 if (!wPreferences
.new_style
== TS_NEW
) {
1329 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1331 if (image
->depth
== 1)
1332 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1333 left
, 0, width
, image
->height
, x
, y
, 1);
1335 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1336 left
, 0, width
, image
->height
, x
, y
);
1338 if (wPreferences
.new_style
== TS_OLD
) {
1339 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1340 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1341 button
->width
, button
->height
);
1343 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1344 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1345 left
, 0, width
, image
->height
, x
, y
);
1350 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1352 XSetForeground(dpy
, copy_gc
, color
);
1353 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1355 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1360 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1362 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1363 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1365 #ifdef XKB_BUTTON_HINT
1366 if (button
== fwin
->language_button
) {
1367 if (wPreferences
.modelock
) {
1368 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1369 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1370 fwin
->languagebutton_image
, False
);
1374 if (button
== fwin
->left_button
) {
1375 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1376 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1378 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1379 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1383 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1385 WFrameWindow
*fwin
= desc
->parent
;
1386 WCoreWindow
*titlebar
= desc
->self
;
1388 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1389 if (fwin
->on_dblclick_titlebar
) {
1390 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1393 if (fwin
->on_mousedown_titlebar
) {
1394 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1399 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1401 WFrameWindow
*fwin
= desc
->parent
;
1402 WCoreWindow
*resizebar
= desc
->self
;
1404 if (fwin
->on_mousedown_resizebar
)
1405 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1408 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1410 WFrameWindow
*fwin
= desc
->parent
;
1411 WCoreWindow
*button
= desc
->self
;
1414 int done
= 0, execute
= 1;
1416 unsigned long pixel
;
1417 int clickButton
= event
->xbutton
.button
;
1419 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1420 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1421 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1426 if (button
== fwin
->left_button
) {
1427 image
= fwin
->lbutton_image
;
1429 image
= fwin
->rbutton_image
;
1431 #ifdef XKB_BUTTON_HINT
1432 if (button
== fwin
->language_button
) {
1433 if (!wPreferences
.modelock
)
1435 image
= fwin
->languagebutton_image
;
1439 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1440 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1441 paintButton(button
, texture
, pixel
, image
, True
);
1444 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1445 | ButtonPressMask
| ExposureMask
, &ev
);
1449 paintButton(button
, texture
, pixel
, image
, False
);
1454 paintButton(button
, texture
, pixel
, image
, True
);
1461 if (ev
.xbutton
.button
== clickButton
)
1469 paintButton(button
, texture
, pixel
, image
, False
);
1472 if (button
== fwin
->left_button
) {
1473 if (fwin
->on_click_left
)
1474 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1475 } else if (button
== fwin
->right_button
) {
1476 if (fwin
->on_click_right
)
1477 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1479 #ifdef XKB_BUTTON_HINT
1480 else if (button
== fwin
->language_button
) {
1481 if (fwin
->on_click_language
)
1482 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);