4 * Copyright (c) Tuomo Valkonen 1999-2001.
5 * See the included file LICENSE for details.
20 #define XOR_RESIZE (!wglobal.opaque_resize)
22 static bool resize_handler(WThing
*thing
, XEvent
*ev
);
24 static bool resize_mode
=FALSE
;
26 static WResizeTmp rtmp
;
32 static void tmr_end_resize(WTimer
*unused
)
38 holder
=grab_get_holder(resize_handler
);
39 assert(holder
&& WTHING_IS(holder
, WWindow
));
41 end_resize((WWindow
*)holder
);
44 static WTimer resize_timer
=INIT_TIMER(tmr_end_resize
);
50 /*{{{ Rubberband and size display */
53 static void res_draw_rubberband(WScreen
*scr
, WRectangle geom
)
55 if(rtmp
.startnode
!=NULL
){
56 if(WOBJ_IS(rtmp
.startnode
, WWindow
))
57 geom
=((WWindow
*)rtmp
.startnode
)->geom
;
59 geom
=((WWsSplit
*)rtmp
.startnode
)->geom
;
62 if(rtmp
.dir
==HORIZONTAL
){
63 geom
.x
=rtmp
.winpostmp
;
64 geom
.w
=rtmp
.winsizetmp
;
66 geom
.y
=rtmp
.winpostmp
;
67 geom
.h
=rtmp
.winsizetmp
;
70 draw_rubberband(scr
, geom
, rtmp
.dir
==VERTICAL
);
74 static void cwin_size(WScreen
*scr
, int *w
, int *h
, XSizeHints
*sh
)
76 correct_size(w
, h
, sh
, FALSE
);
78 if(sh
->flags
&PBaseSize
){
83 if(sh
->flags
&PResizeInc
){
93 static void res_draw_moveres(WScreen
*scr
, WWindow
*wwin
)
98 if(rtmp
.dir
==HORIZONTAL
){
110 if(WTHING_IS(wwin
, WFrame
)){
111 w
+=FRAME_CLIENT_WOFF(scr
);
112 h
+=FRAME_CLIENT_HOFF(scr
);
113 if(((WFrame
*)wwin
)->current_client
!=NULL
&&
114 (cwin
=FIRST_THING(((WFrame
*)wwin
)->current_client
,
116 cwin_size(scr
, &w
, &h
, &(cwin
->size_hints
));
123 set_moveres_size(scr
, w
, h
);
130 /*{{{ Resize/common */
133 static int do_calc_resize(int s
, int unit
, int off
)
141 static int calc_resize(WScreen
*scr
, int s
, int dir
)
144 return do_calc_resize(s
, scr
->h_unit
, FRAME_CLIENT_HOFF(scr
));
146 return do_calc_resize(s
, scr
->w_unit
, FRAME_CLIENT_WOFF(scr
));
150 void begin_resize(WWindow
*wwin
, int dir
, int primn
)
152 WScreen
*scr
=SCREEN_OF(wwin
);
154 tmpsize
=wwin_size(wwin
, dir
);
158 XGrabServer(wglobal
.dpy
);
160 XMoveWindow(wglobal
.dpy
, scr
->grdata
.moveres_win
,
161 wwin
->geom
.x
+(wwin
->geom
.w
-scr
->grdata
.moveres_geom
.w
)/2,
162 wwin
->geom
.y
+(wwin
->geom
.h
-scr
->grdata
.moveres_geom
.h
)/2);
163 XMapRaised(wglobal
.dpy
, scr
->grdata
.moveres_win
);
165 calcresize_window(wwin
, dir
, primn
, tmpsize
, &rtmp
);
167 res_draw_moveres(scr
, wwin
);
170 res_draw_rubberband(scr
, wwin
->geom
);
174 void resize(WWindow
*wwin
, int delta
, int primn
, bool settmp
)
176 WScreen
*scr
=SCREEN_OF(wwin
);
181 res_draw_rubberband(scr
, wwin
->geom
);
184 s
=calc_resize(SCREEN_OF(wwin
), tmpsize
, dir
);
187 calcresize_window(wwin
, dir
, primn
, s
, &rtmp
);
190 tmpsize
=rtmp
.winsizetmp
;
192 res_draw_moveres(scr
, wwin
);
195 res_draw_rubberband(scr
, wwin
->geom
);
201 void end_resize(WWindow
*wwin
)
203 WScreen
*scr
=SCREEN_OF(wwin
);
210 reset_timer(&resize_timer
);
213 res_draw_rubberband(scr
, wwin
->geom
);
215 XUngrabServer(wglobal
.dpy
);
217 XUnmapWindow(wglobal
.dpy
, scr
->grdata
.moveres_win
);
221 void cancel_resize(WWindow
*wwin
)
223 WScreen
*scr
=SCREEN_OF(wwin
);
230 reset_timer(&resize_timer
);
233 res_draw_rubberband(scr
, wwin
->geom
);
234 XUngrabServer(wglobal
.dpy
);
236 XUnmapWindow(wglobal
.dpy
, scr
->grdata
.moveres_win
);
243 /*{{{ Keyboard resize */
245 static bool resize_handler(WThing
*thing
, XEvent
*xev
)
247 XKeyEvent
*ev
=&xev
->xkey
;
249 WBinding
*binding
=NULL
;
256 if(ev
->type
==KeyRelease
)
259 assert(thing
&& WTHING_IS(thing
, WWindow
));
260 binding
=lookup_binding(&wglobal
.moveres_bindmap
, ACT_KEYPRESS
, ev
->state
, ev
->keycode
);
266 /* Get the screen now for waitrel grab - the thing might
267 * have been destroyed when call_binding returns.
269 scr
=SCREEN_OF(thing
);
270 call_binding(binding
, thing
);
276 static void begin_keyresize(WWindow
*wwin
, int dir
)
281 begin_resize(wwin
, dir
, ANY
);
283 grab_establish((WThing
*)wwin
, resize_handler
, FocusChangeMask
);
284 change_grab_cursor(CURSOR_RESIZE
);
288 static int get_unit(WWindow
*wwin
)
290 WScreen
*scr
=SCREEN_OF(wwin
);
291 return (rtmp
.dir
==VERTICAL
? scr
->h_unit
: scr
->w_unit
);
295 void grow(WWindow
*wwin
)
299 resize(wwin
, get_unit(wwin
), ANY
, TRUE
);
300 set_timer(&resize_timer
, wglobal
.resize_delay
);
304 void shrink(WWindow
*wwin
)
308 resize(wwin
, -get_unit(wwin
), ANY
, TRUE
);
309 set_timer(&resize_timer
, wglobal
.resize_delay
);
313 void resize_vert(WWindow
*wwin
)
315 begin_keyresize(wwin
, VERTICAL
);
319 void resize_horiz(WWindow
*wwin
)
321 begin_keyresize(wwin
, HORIZONTAL
);
331 static void do_maximize(WWindow
*wwin
, int dir
, int flag
,
332 int *saved_size
, int max_size
)
336 if(wwin
->flags
&flag
){
337 calcresize_window(wwin
, dir
, ANY
, *saved_size
, &rtmp
);
341 *saved_size
=wwin_size(wwin
, dir
);
342 calcresize_window(wwin
, dir
, ANY
, max_size
, &rtmp
);
349 void maximize_vert(WWindow
*wwin
)
351 WScreen
*scr
=SCREEN_OF(wwin
);
354 do_maximize(wwin
, VERTICAL
, WWINDOW_HFORCED
,
355 &(wwin
->saved_h
), scr
->root
.geom
.h
);
360 void maximize_horiz(WWindow
*wwin
)
362 WScreen
*scr
=SCREEN_OF(wwin
);
365 do_maximize(wwin
, HORIZONTAL
, WWINDOW_WFORCED
,
366 &(wwin
->saved_w
), scr
->root
.geom
.w
);
377 void set_height(WWindow
*wwin
, uint h
)
380 calcresize_window(wwin
, VERTICAL
, ANY
, h
, &rtmp
);
385 void set_width(WWindow
*wwin
, uint w
)
388 calcresize_window(wwin
, HORIZONTAL
, ANY
, w
, &rtmp
);
392 void set_heightq(WWindow
*wwin
, double q
)
394 WScreen
*scr
=SCREEN_OF(wwin
);
395 set_height(wwin
, q
*(double)scr
->root
.geom
.h
);
398 void set_widthq(WWindow
*wwin
, double q
)
400 WScreen
*scr
=SCREEN_OF(wwin
);
401 set_width(wwin
, q
*(double)scr
->root
.geom
.w
);