2 * Window Maker window manager
4 * Copyright (c) 1997, 1998 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>
32 #include "WindowMaker.h"
41 #define DBLCLICK_TIME wPreferences.dblclick_time
43 extern WPreferences wPreferences
;
45 static void handleExpose(WObjDescriptor
*desc
, XEvent
*event
);
46 static void handleButtonExpose(WObjDescriptor
*desc
, XEvent
*event
);
48 static void buttonMouseDown(WObjDescriptor
*desc
, XEvent
*event
);
49 static void titlebarMouseDown(WObjDescriptor
*desc
, XEvent
*event
);
50 static void resizebarMouseDown(WObjDescriptor
*desc
, XEvent
*event
);
52 static void checkTitleSize(WFrameWindow
*fwin
);
55 static void paintButton(WCoreWindow
*button
, WTexture
*texture
,
56 unsigned long color
, WPixmap
*image
, int pushed
);
58 static void updateTitlebar(WFrameWindow
*fwin
);
62 wFrameWindowCreate(WScreen
*scr
, int wlevel
, int x
, int y
,
63 int width
, int height
, int flags
,
64 WTexture
**title_texture
, WTexture
**resize_texture
,
65 unsigned long *color
, GC
*gc
, WFont
**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_pixel
= color
;
82 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
,
84 if (wPreferences
.use_saveunders
) {
86 XSetWindowAttributes attribs
;
89 attribs
.save_under
= True
;
90 XChangeWindowAttributes(dpy
, fwin
->core
->window
, vmask
, &attribs
);
93 /* setup stacking information */
94 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
95 fwin
->core
->stacking
->above
= NULL
;
96 fwin
->core
->stacking
->under
= NULL
;
97 fwin
->core
->stacking
->child_of
= NULL
;
98 fwin
->core
->stacking
->window_level
= wlevel
;
100 AddToStackList(fwin
->core
);
102 wFrameWindowUpdateBorders(fwin
, flags
);
110 wFrameWindowUpdateBorders(WFrameWindow
*fwin
, int flags
)
116 WScreen
*scr
= fwin
->screen_ptr
;
118 width
= fwin
->core
->width
;
119 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
121 if (flags
& WFF_TITLEBAR
)
122 theight
= (*fwin
->font
)->height
+ TITLEBAR_EXTRA_HEIGHT
;
126 if (wPreferences
.new_style
) {
132 if (fwin
->titlebar
) {
133 /* if we had a titlebar and is requesting for one,
134 * check if the size has changed and resize it */
135 if (flags
& WFF_TITLEBAR
) {
136 fwin
->top_width
= theight
;
138 fwin
->flags
.need_texture_remake
= 1;
140 if (wPreferences
.new_style
) {
141 if (fwin
->left_button
) {
142 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
145 if (fwin
->right_button
) {
146 wCoreConfigure(fwin
->right_button
, width
-bsize
+1,
149 } else { /* !new_style */
150 if (fwin
->left_button
) {
151 wCoreConfigure(fwin
->left_button
, 3, (theight
-bsize
)/2,
155 if (fwin
->right_button
) {
156 wCoreConfigure(fwin
->right_button
, width
-bsize
-3,
157 (theight
-bsize
)/2, bsize
, bsize
);
160 updateTitlebar(fwin
);
162 /* we had a titlebar, but now we don't need it anymore */
163 for (i
=0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
164 FREE_PIXMAP(fwin
->title_back
[i
]);
165 if (wPreferences
.new_style
) {
166 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
167 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
170 if (fwin
->left_button
)
171 wCoreDestroy(fwin
->left_button
);
172 fwin
->left_button
= NULL
;
174 if (fwin
->right_button
)
175 wCoreDestroy(fwin
->right_button
);
176 fwin
->right_button
= NULL
;
178 wCoreDestroy(fwin
->titlebar
);
179 fwin
->titlebar
= NULL
;
184 /* if we didn't have a titlebar and are being requested for
186 if (flags
& WFF_TITLEBAR
) {
187 fwin
->top_width
= theight
;
189 fwin
->flags
.titlebar
= 1;
190 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+1, theight
);
192 if (flags
& WFF_LEFT_BUTTON
) {
193 fwin
->flags
.left_button
= 1;
194 if (wPreferences
.new_style
) {
195 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0,
197 if (width
< theight
*4) {
198 fwin
->flags
.lbutton_dont_fit
= 1;
200 XMapRaised(dpy
, fwin
->left_button
->window
);
204 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
207 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
208 scr
->widget_texture
->normal
.pixel
);
210 if (width
< theight
*3) {
211 fwin
->flags
.lbutton_dont_fit
= 1;
213 XMapRaised(dpy
, fwin
->left_button
->window
);
219 if (flags
& WFF_RIGHT_BUTTON
) {
220 fwin
->flags
.right_button
= 1;
221 if (wPreferences
.new_style
) {
223 wCoreCreate(fwin
->core
, width
-bsize
+1, 0,
227 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
228 (theight
-bsize
)/2, bsize
, bsize
);
229 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
230 scr
->widget_texture
->normal
.pixel
);
233 if (width
< theight
*2) {
234 fwin
->flags
.rbutton_dont_fit
= 1;
236 XMapRaised(dpy
, fwin
->right_button
->window
);
240 if (wPreferences
.new_style
)
241 updateTitlebar(fwin
);
243 XMapRaised(dpy
, fwin
->titlebar
->window
);
245 fwin
->flags
.need_texture_remake
= 1;
248 checkTitleSize(fwin
);
250 if (flags
& WFF_RESIZEBAR
) {
251 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
253 fwin
->bottom_width
= 0;
256 if (flags
& WFF_RESIZEBAR
) {
257 if (!fwin
->resizebar
) {
258 fwin
->flags
.resizebar
= 1;
259 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
260 height
+ fwin
->top_width
,
261 width
, RESIZEBAR_HEIGHT
);
262 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
263 if (width
< RESIZEBAR_CORNER_WIDTH
*2 + RESIZEBAR_MIN_WIDTH
) {
264 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
)/2;
265 if (fwin
->resizebar_corner_width
< 0)
266 fwin
->resizebar_corner_width
= 0;
269 XMapWindow(dpy
, fwin
->resizebar
->window
);
270 XLowerWindow(dpy
, fwin
->resizebar
->window
);
272 fwin
->flags
.need_texture_remake
= 1;
274 if (height
+fwin
->top_width
+fwin
->bottom_width
!= fwin
->core
->height
) {
275 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
276 width
, RESIZEBAR_HEIGHT
);
280 if (fwin
->resizebar
) {
281 fwin
->bottom_width
= 0;
282 wCoreDestroy(fwin
->resizebar
);
283 fwin
->resizebar
= NULL
;
287 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
) {
288 wFrameWindowResize(fwin
, width
,
289 height
+ fwin
->top_width
+ fwin
->bottom_width
);
292 /* setup object descriptors */
294 if (fwin
->titlebar
) {
295 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
296 fwin
->titlebar
->descriptor
.parent
= fwin
;
297 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
298 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
301 if (fwin
->resizebar
) {
302 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
303 fwin
->resizebar
->descriptor
.parent
= fwin
;
304 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
305 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
308 if (fwin
->left_button
) {
309 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
310 fwin
->left_button
->descriptor
.parent
= fwin
;
311 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
312 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
315 if (fwin
->right_button
) {
316 fwin
->right_button
->descriptor
.parent
= fwin
;
317 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
318 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
319 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
322 checkTitleSize(fwin
);
328 wFrameWindowDestroy(WFrameWindow
*fwin
)
332 if (fwin
->left_button
)
333 wCoreDestroy(fwin
->left_button
);
335 if (fwin
->right_button
)
336 wCoreDestroy(fwin
->right_button
);
339 wCoreDestroy(fwin
->resizebar
);
342 wCoreDestroy(fwin
->titlebar
);
344 RemoveFromStackList(fwin
->core
);
346 wCoreDestroy(fwin
->core
);
351 for (i
=0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
352 FREE_PIXMAP(fwin
->title_back
[i
]);
353 if (wPreferences
.new_style
) {
354 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
355 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
364 wFrameWindowChangeState(WFrameWindow
*fwin
, int state
)
366 if (fwin
->flags
.state
==state
)
369 fwin
->flags
.state
= state
;
370 fwin
->flags
.need_texture_change
= 1;
372 wFrameWindowPaint(fwin
);
377 updateTitlebar(WFrameWindow
*fwin
)
382 theight
= (*fwin
->font
)->height
+ TITLEBAR_EXTRA_HEIGHT
;
385 w
= fwin
->core
->width
+ 1;
387 if (wPreferences
.new_style
) {
388 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
389 || fwin
->flags
.lbutton_dont_fit
) {
392 x
= fwin
->left_button
->width
;
393 w
-= fwin
->left_button
->width
;
397 if (wPreferences
.new_style
) {
398 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
399 && !fwin
->flags
.rbutton_dont_fit
) {
400 w
-= fwin
->right_button
->width
;
404 if (wPreferences
.new_style
|| fwin
->titlebar
->width
!=w
)
405 fwin
->flags
.need_texture_remake
= 1;
407 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
412 wFrameWindowHideButton(WFrameWindow
*fwin
, int flags
)
414 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
415 XUnmapWindow(dpy
, fwin
->right_button
->window
);
416 fwin
->flags
.hide_right_button
= 1;
419 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
420 XUnmapWindow(dpy
, fwin
->left_button
->window
);
421 fwin
->flags
.hide_left_button
= 1;
424 if (fwin
->titlebar
) {
425 if (wPreferences
.new_style
) {
426 updateTitlebar(fwin
);
428 XClearWindow(dpy
, fwin
->titlebar
->window
);
429 wFrameWindowPaint(fwin
);
431 checkTitleSize(fwin
);
437 wFrameWindowShowButton(WFrameWindow
*fwin
, int flags
)
439 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
440 && fwin
->flags
.hide_right_button
) {
442 if (!fwin
->flags
.rbutton_dont_fit
)
443 XMapWindow(dpy
, fwin
->right_button
->window
);
445 fwin
->flags
.hide_right_button
= 0;
448 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
449 && fwin
->flags
.hide_left_button
) {
451 if (!fwin
->flags
.lbutton_dont_fit
)
452 XMapWindow(dpy
, fwin
->left_button
->window
);
454 fwin
->flags
.hide_left_button
= 0;
458 if (fwin
->titlebar
) {
459 if (wPreferences
.new_style
) {
460 updateTitlebar(fwin
);
462 XClearWindow(dpy
, fwin
->titlebar
->window
);
463 wFrameWindowPaint(fwin
);
465 checkTitleSize(fwin
);
471 renderTexture(WScreen
*scr
, WTexture
*texture
, int width
, int height
,
472 int bwidth
, int bheight
, int left
, int right
,
473 Pixmap
*title
, Pixmap
*lbutton
, Pixmap
*rbutton
)
476 RImage
*limg
, *rimg
, *mimg
;
483 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
485 wwarning(_("could not render gradient: %s"), RMessageForError(RErrorCode
));
489 if (wPreferences
.new_style
) {
491 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
499 RBevelImage(limg
, RBEV_RAISED2
);
500 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
501 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
509 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
514 RBevelImage(rimg
, RBEV_RAISED2
);
515 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
516 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
523 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
524 RBevelImage(mimg
, RBEV_RAISED2
);
526 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
527 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
531 RBevelImage(img
, RBEV_RAISED2
);
533 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
534 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
538 RBevelImage(img
, RBEV_RAISED2
);
540 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
541 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
550 updateTexture(WFrameWindow
*fwin
)
555 i
= fwin
->flags
.state
;
556 if (fwin
->titlebar
) {
557 if (fwin
->title_texture
[i
]->any
.type
!=WTEX_SOLID
) {
558 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
,
559 fwin
->title_back
[i
]);
560 if (wPreferences
.new_style
) {
561 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
562 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
563 fwin
->lbutton_back
[i
]);
565 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
566 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
567 fwin
->rbutton_back
[i
]);
570 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
571 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
572 if (wPreferences
.new_style
) {
573 if (fwin
->left_button
)
574 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
576 if (fwin
->right_button
)
577 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
581 XClearWindow(dpy
, fwin
->titlebar
->window
);
583 if (fwin
->left_button
) {
584 XClearWindow(dpy
, fwin
->left_button
->window
);
585 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
587 if (fwin
->right_button
) {
588 XClearWindow(dpy
, fwin
->right_button
->window
);
589 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
593 if (fwin
->resizebar
) {
594 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
595 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
596 XClearWindow(dpy
, fwin
->resizebar
->window
);
603 remakeTexture(WFrameWindow
*fwin
, int state
)
605 Pixmap pmap
, lpmap
, rpmap
;
607 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
608 FREE_PIXMAP(fwin
->title_back
[state
]);
609 if (wPreferences
.new_style
) {
610 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
611 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
614 if (fwin
->title_texture
[state
]->any
.type
!=WTEX_SOLID
) {
618 /* eventually surrounded by if new_style */
619 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
620 && !fwin
->flags
.lbutton_dont_fit
;
621 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
622 && !fwin
->flags
.rbutton_dont_fit
;
624 width
= fwin
->core
->width
+1;
626 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
627 width
, fwin
->titlebar
->height
,
628 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
629 left
, right
, &pmap
, &lpmap
, &rpmap
);
631 fwin
->title_back
[state
] = pmap
;
632 if (wPreferences
.new_style
) {
633 fwin
->lbutton_back
[state
] = lpmap
;
634 fwin
->rbutton_back
[state
] = rpmap
;
642 wFrameWindowPaint(WFrameWindow
*fwin
)
645 if (fwin
->flags
.is_client_window_frame
)
646 fwin
->flags
.justification
= wPreferences
.title_justification
;
648 if (fwin
->flags
.need_texture_remake
) {
651 fwin
->flags
.need_texture_remake
= 0;
652 fwin
->flags
.need_texture_change
= 0;
654 if (fwin
->flags
.single_texture
) {
655 remakeTexture(fwin
, 0);
658 /* first render the texture for the current state... */
659 remakeTexture(fwin
, fwin
->flags
.state
);
660 /* ... and paint it */
663 for (i
=0; i
< 3; i
++) {
664 if (i
!=fwin
->flags
.state
)
665 remakeTexture(fwin
, i
);
670 if (fwin
->flags
.need_texture_change
) {
671 fwin
->flags
.need_texture_change
= 0;
676 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
677 && fwin
->title_texture
[fwin
->flags
.state
]->any
.type
==WTEX_SOLID
) {
678 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
679 fwin
->titlebar
->height
,
680 (WTexSolid
*)fwin
->title_texture
[fwin
->flags
.state
],
684 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
) {
689 WTexSolid
*texture
= (WTexSolid
*)fwin
->resizebar_texture
[0];
691 w
= fwin
->resizebar
->width
;
692 h
= fwin
->resizebar
->height
;
693 cw
= fwin
->resizebar_corner_width
;
694 light_gc
= texture
->light_gc
;
695 dim_gc
= texture
->dim_gc
;
696 win
= fwin
->resizebar
->window
;
698 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
699 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
701 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
702 XDrawLine(dpy
, win
, light_gc
, cw
+1, 2, cw
+1, h
);
704 XDrawLine(dpy
, win
, dim_gc
, w
-cw
-2, 2, w
-cw
-2, h
);
705 XDrawLine(dpy
, win
, light_gc
, w
-cw
-1, 2, w
-cw
-1, h
);
707 #ifdef SHADOW_RESIZEBAR
708 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
-1);
709 XDrawLine(dpy
, win
, dim_gc
, w
-1, 2, w
-1, h
-1);
710 XDrawLine(dpy
, win
, dim_gc
, 1, h
-1, cw
, h
-1);
711 XDrawLine(dpy
, win
, dim_gc
, cw
+2, h
-1, w
-cw
-2, h
-1);
712 XDrawLine(dpy
, win
, dim_gc
, w
-cw
, h
-1, w
-1, h
-1);
713 #endif /* SHADOW_RESIZEBAR */
717 if (fwin
->title
&& fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
719 int lofs
= 6, rofs
= 6;
725 if (!wPreferences
.new_style
) {
726 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
727 && !fwin
->flags
.lbutton_dont_fit
)
728 lofs
+= fwin
->left_button
->width
+ 3;
732 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
733 && !fwin
->flags
.rbutton_dont_fit
)
734 rofs
+= fwin
->right_button
->width
+ 3;
738 title
= ShrinkString(*fwin
->font
, fwin
->title
,
739 fwin
->titlebar
->width
- lofs
- rofs
);
740 titlelen
= strlen(title
);
741 w
= wTextWidth((*fwin
->font
)->font
, title
, titlelen
);
743 switch (fwin
->flags
.justification
) {
749 x
= fwin
->titlebar
->width
- w
- rofs
;
754 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
756 x
= (fwin
->titlebar
->width
- w
) / 2;
760 XSetForeground(dpy
, *fwin
->title_gc
,
761 fwin
->title_pixel
[fwin
->flags
.state
]);
763 wDrawString(fwin
->titlebar
->window
, *fwin
->font
,
765 (*fwin
->font
)->y
+ TITLEBAR_EXTRA_HEIGHT
/2, title
,
774 reconfigure(WFrameWindow
*fwin
, int x
, int y
, int width
, int height
,
777 int k
= (wPreferences
.new_style
? 4 : 3);
778 int resizedHorizontally
= 0;
781 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
783 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
786 if (fwin->core->height != height && fwin->resizebar)
787 XMoveWindow(dpy, fwin->resizebar->window, 0,
788 height - fwin->resizebar->height);
790 if (fwin
->core
->width
!= width
) {
791 fwin
->flags
.need_texture_remake
= 1;
792 resizedHorizontally
= 1;
795 fwin
->core
->width
= width
;
796 fwin
->core
->height
= height
;
798 if (fwin
->titlebar
&& resizedHorizontally
) {
799 /* Check if the titlebar is wide enough to hold the buttons.
800 * Temporarily remove them if can't
802 if (fwin
->left_button
) {
803 if (width
< fwin
->top_width
*k
&& !fwin
->flags
.lbutton_dont_fit
) {
805 if (!fwin
->flags
.hide_left_button
) {
806 XUnmapWindow(dpy
, fwin
->left_button
->window
);
808 fwin
->flags
.lbutton_dont_fit
= 1;
809 } else if (width
>= fwin
->top_width
*k
&& fwin
->flags
.lbutton_dont_fit
) {
811 if (!fwin
->flags
.hide_left_button
) {
812 XMapWindow(dpy
, fwin
->left_button
->window
);
814 fwin
->flags
.lbutton_dont_fit
= 0;
818 if (fwin
->right_button
) {
819 if (width
< fwin
->top_width
*2 && !fwin
->flags
.rbutton_dont_fit
) {
821 if (!fwin
->flags
.hide_right_button
) {
822 XUnmapWindow(dpy
, fwin
->right_button
->window
);
824 fwin
->flags
.rbutton_dont_fit
= 1;
825 } else if (width
>= fwin
->top_width
*2 && fwin
->flags
.rbutton_dont_fit
) {
827 if (!fwin
->flags
.hide_right_button
) {
828 XMapWindow(dpy
, fwin
->right_button
->window
);
830 fwin
->flags
.rbutton_dont_fit
= 0;
834 if (wPreferences
.new_style
) {
835 if (fwin
->right_button
)
836 XMoveWindow(dpy
, fwin
->right_button
->window
,
837 width
- fwin
->right_button
->width
+ 1, 0);
839 if (fwin
->right_button
)
840 XMoveWindow(dpy
, fwin
->right_button
->window
,
841 width
- fwin
->right_button
->width
- 3,
842 (fwin
->titlebar
->height
- fwin
->right_button
->height
)/2);
844 updateTitlebar(fwin
);
845 checkTitleSize(fwin
);
848 if (fwin
->resizebar
) {
849 wCoreConfigure(fwin
->resizebar
, 0,
850 fwin
->core
->height
- fwin
->resizebar
->height
,
851 fwin
->core
->width
, fwin
->resizebar
->height
);
853 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
854 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
*2 + RESIZEBAR_MIN_WIDTH
) {
855 fwin
->resizebar_corner_width
= fwin
->core
->width
/2;
861 wFrameWindowConfigure(WFrameWindow
*fwin
, int x
, int y
, int width
, int height
)
863 reconfigure(fwin
, x
, y
, width
, height
, False
);
867 wFrameWindowResize(WFrameWindow
*fwin
, int width
, int height
)
869 reconfigure(fwin
, 0, 0, width
, height
, True
);
875 wFrameWindowChangeTitle(WFrameWindow
*fwin
, char *new_title
)
877 /* check if the title is the same as before */
879 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
890 fwin
->title
= wstrdup(new_title
);
892 if (fwin
->titlebar
) {
893 XClearWindow(dpy
, fwin
->titlebar
->window
);
895 wFrameWindowPaint(fwin
);
897 checkTitleSize(fwin
);
903 /*********************************************************************/
906 handleExpose(WObjDescriptor
*desc
, XEvent
*event
)
908 WFrameWindow
*fwin
= (WFrameWindow
*)desc
->parent
;
911 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
912 fwin
->flags
.repaint_only_titlebar
= 1;
913 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
914 fwin
->flags
.repaint_only_resizebar
= 1;
915 wFrameWindowPaint(fwin
);
916 fwin
->flags
.repaint_only_titlebar
= 0;
917 fwin
->flags
.repaint_only_resizebar
= 0;
922 checkTitleSize(WFrameWindow
*fwin
)
927 fwin
->flags
.incomplete_title
= 0;
931 if (!fwin
->titlebar
) {
932 fwin
->flags
.incomplete_title
= 1;
935 width
= fwin
->titlebar
->width
- 6 - 6;
938 if (!wPreferences
.new_style
) {
939 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
940 && !fwin
->flags
.lbutton_dont_fit
)
941 width
-= fwin
->left_button
->width
+ 3;
943 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
944 && !fwin
->flags
.rbutton_dont_fit
)
945 width
-= fwin
->right_button
->width
+ 3;
947 if (wTextWidth((*fwin
->font
)->font
, fwin
->title
,
948 strlen(fwin
->title
)) > width
) {
949 fwin
->flags
.incomplete_title
= 1;
951 fwin
->flags
.incomplete_title
= 0;
956 paintButton(WCoreWindow
*button
, WTexture
*texture
, unsigned long color
,
957 WPixmap
*image
, int pushed
)
959 WScreen
*scr
= button
->screen_ptr
;
960 GC copy_gc
= scr
->copy_gc
;
964 /* setup stuff according to the state */
967 if (image
->width
>=image
->height
*2) {
968 /* the image contains 2 pictures: the second is for the
970 width
= image
->width
/2;
971 left
= image
->width
/2;
973 width
= image
->width
;
976 XSetClipMask(dpy
, copy_gc
, None
);
977 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
979 if (wPreferences
.new_style
) {
980 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
981 button
->width
-1, button
->height
-1);
982 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
983 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
984 button
->width
-1, button
->height
-1);
986 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
987 button
->width
, button
->height
);
988 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
989 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
990 button
->width
, button
->height
);
993 XClearWindow(dpy
, button
->window
);
996 if (image
->width
>=image
->height
*2)
997 width
= image
->width
/2;
999 width
= image
->width
;
1003 if (wPreferences
.new_style
) {
1004 if (texture
->any
.type
==WTEX_SOLID
|| pushed
) {
1005 wDrawBevel(button
->window
, button
->width
, button
->height
,
1006 (WTexSolid
*)texture
, WREL_RAISED
);
1009 wDrawBevel(button
->window
, button
->width
, button
->height
,
1010 scr
->widget_texture
, WREL_RAISED
);
1016 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1017 x
= (button
->width
- width
)/2 + d
;
1018 y
= (button
->height
- image
->height
)/2 + d
;
1019 XSetClipOrigin(dpy
, copy_gc
, x
-left
, y
);
1020 if (!wPreferences
.new_style
) {
1021 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1023 if (image
->depth
==1)
1024 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1025 left
, 0, width
, image
->height
, x
, y
, 1);
1027 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1028 left
, 0, width
, image
->height
, x
, y
);
1030 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1031 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1032 button
->width
, button
->height
);
1036 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1038 XSetForeground(dpy
, copy_gc
, color
);
1039 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1041 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1042 button
->width
, button
->height
);
1049 handleButtonExpose(WObjDescriptor
*desc
, XEvent
*event
)
1051 WFrameWindow
*fwin
= (WFrameWindow
*)desc
->parent
;
1052 WCoreWindow
*button
= (WCoreWindow
*)desc
->self
;
1054 if (button
== fwin
->left_button
) {
1055 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1056 fwin
->title_pixel
[fwin
->flags
.state
],
1057 fwin
->lbutton_image
, False
);
1059 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1060 fwin
->title_pixel
[fwin
->flags
.state
],
1061 fwin
->rbutton_image
, False
);
1067 titlebarMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
1069 WFrameWindow
*fwin
= desc
->parent
;
1070 WCoreWindow
*titlebar
= desc
->self
;
1072 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1073 if (fwin
->on_dblclick_titlebar
)
1074 (*fwin
->on_dblclick_titlebar
)(titlebar
, fwin
->child
, event
);
1076 if (fwin
->on_mousedown_titlebar
)
1077 (*fwin
->on_mousedown_titlebar
)(titlebar
, fwin
->child
, event
);
1083 resizebarMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
1085 WFrameWindow
*fwin
= desc
->parent
;
1086 WCoreWindow
*resizebar
= desc
->self
;
1088 if (fwin
->on_mousedown_resizebar
)
1089 (*fwin
->on_mousedown_resizebar
)(resizebar
, fwin
->child
, event
);
1094 buttonMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
1096 WFrameWindow
*fwin
= desc
->parent
;
1097 WCoreWindow
*button
= desc
->self
;
1100 int done
=0, execute
=1;
1102 unsigned long pixel
;
1103 int clickButton
= event
->xbutton
.button
;
1105 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1106 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1107 (*fwin
->on_dblclick_right
)(button
, fwin
->child
, event
);
1112 if (button
== fwin
->left_button
) {
1113 image
= fwin
->lbutton_image
;
1115 image
= fwin
->rbutton_image
;
1118 pixel
= fwin
->title_pixel
[fwin
->flags
.state
];
1119 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1120 paintButton(button
, texture
, pixel
, image
, True
);
1123 WMMaskEvent(dpy
, LeaveWindowMask
|EnterWindowMask
|ButtonReleaseMask
1124 |ButtonPressMask
|ExposureMask
, &ev
);
1128 paintButton(button
, texture
, pixel
, image
, False
);
1133 paintButton(button
, texture
, pixel
, image
, True
);
1140 if (ev
.xbutton
.button
== clickButton
)
1148 paintButton(button
, texture
, pixel
, image
, False
);
1151 if (button
== fwin
->left_button
) {
1152 if (fwin
->on_click_left
)
1153 (*fwin
->on_click_left
)(button
, fwin
->child
, &ev
);
1154 } else if (button
== fwin
->right_button
) {
1155 if (fwin
->on_click_right
)
1156 (*fwin
->on_click_right
)(button
, fwin
->child
, &ev
);