2 * ion/mod_tiling/splitext.c
4 * Copyright (c) Tuomo Valkonen 1999-2008.
6 * See the included file LICENSE for details.
11 #include <libtu/objp.h>
12 #include <libtu/minmax.h>
13 #include <ioncore/common.h>
14 #include <ioncore/global.h>
15 #include <ioncore/rootwin.h>
16 #include <ioncore/xwindow.h>
17 #include <ioncore/window.h>
21 #include "splitfloat.h"
22 #include "panehandle.h"
25 #define GEOM(X) (((WSplit*)(X))->geom)
31 static void splitfloat_set_borderlines(WSplitFloat *split)
33 int dir=split->ssplit.dir;
35 split->tlpwin->bline=(dir==SPLIT_HORIZONTAL
37 : GR_BORDERLINE_BOTTOM);
39 split->brpwin->bline=(dir==SPLIT_HORIZONTAL
45 bool splitfloat_init(WSplitFloat *split, const WRectangle *geom,
49 WWindow *par=REGION_PARENT(ws);
54 fp.mode=REGION_FIT_EXACT;
55 split->tlpwin=create_panehandle(par, &fp);
56 if(split->tlpwin==NULL)
60 fp.mode=REGION_FIT_EXACT;
61 split->brpwin=create_panehandle(par, &fp);
62 if(split->brpwin==NULL){
63 destroy_obj((Obj*)split->tlpwin);
67 ((WRegion*)split->brpwin)->flags|=REGION_SKIP_FOCUS;
68 ((WRegion*)split->tlpwin)->flags|=REGION_SKIP_FOCUS;
70 if(!splitsplit_init(&(split->ssplit), geom, dir)){
71 destroy_obj((Obj*)split->brpwin);
72 destroy_obj((Obj*)split->tlpwin);
76 split->tlpwin->splitfloat=split;
77 split->brpwin->splitfloat=split;
79 splitfloat_set_borderlines(split);
81 if(REGION_IS_MAPPED(ws)){
82 region_map((WRegion*)(split->tlpwin));
83 region_map((WRegion*)(split->brpwin));
90 WSplitFloat *create_splitfloat(const WRectangle *geom, WTiling *ws, int dir)
92 CREATEOBJ_IMPL(WSplitFloat, splitfloat, (p, geom, ws, dir));
96 void splitfloat_deinit(WSplitFloat *split)
98 if(split->tlpwin!=NULL){
99 WPaneHandle *tmp=split->tlpwin;
101 tmp->splitfloat=NULL;
102 destroy_obj((Obj*)tmp);
105 if(split->brpwin!=NULL){
106 WPaneHandle *tmp=split->brpwin;
108 tmp->splitfloat=NULL;
109 destroy_obj((Obj*)tmp);
112 splitsplit_deinit(&(split->ssplit));
119 /*{{{ X window handling */
122 static void stack_stacking_reg(WRegion *reg,
123 Window *bottomret, Window *topret)
125 Window b=None, t=None;
128 region_stacking(reg, &b, &t);
137 static void stack_stacking_split(WSplit *split,
138 Window *bottomret, Window *topret)
140 Window b=None, t=None;
143 split_stacking(split, &b, &t);
152 static void splitfloat_stacking(WSplitFloat *split,
153 Window *bottomret, Window *topret)
158 if(split->ssplit.current!=SPLIT_CURRENT_TL){
159 stack_stacking_reg((WRegion*)split->tlpwin, bottomret, topret);
160 stack_stacking_split(split->ssplit.tl, bottomret, topret);
161 stack_stacking_reg((WRegion*)split->brpwin, bottomret, topret);
162 stack_stacking_split(split->ssplit.br, bottomret, topret);
164 stack_stacking_reg((WRegion*)split->brpwin, bottomret, topret);
165 stack_stacking_split(split->ssplit.br, bottomret, topret);
166 stack_stacking_reg((WRegion*)split->tlpwin, bottomret, topret);
167 stack_stacking_split(split->ssplit.tl, bottomret, topret);
172 static void stack_restack_reg(WRegion *reg, Window *other, int *mode)
174 Window b=None, t=None;
177 region_restack(reg, *other, *mode);
178 region_stacking(reg, &b, &t);
187 static void stack_restack_split(WSplit *split, Window *other, int *mode)
189 Window b=None, t=None;
192 split_restack(split, *other, *mode);
193 split_stacking(split, &b, &t);
203 static void splitfloat_restack(WSplitFloat *split, Window other, int mode)
205 if(split->ssplit.current!=SPLIT_CURRENT_TL){
206 stack_restack_reg((WRegion*)split->tlpwin, &other, &mode);
207 stack_restack_split(split->ssplit.tl, &other, &mode);
208 stack_restack_reg((WRegion*)split->brpwin, &other, &mode);
209 stack_restack_split(split->ssplit.br, &other, &mode);
211 stack_restack_reg((WRegion*)split->brpwin, &other, &mode);
212 stack_restack_split(split->ssplit.br, &other, &mode);
213 stack_restack_reg((WRegion*)split->tlpwin, &other, &mode);
214 stack_restack_split(split->ssplit.tl, &other, &mode);
219 static void splitfloat_map(WSplitFloat *split)
221 region_map((WRegion*)(split->tlpwin));
222 region_map((WRegion*)(split->brpwin));
223 splitinner_forall((WSplitInner*)split, split_map);
227 static void splitfloat_unmap(WSplitFloat *split)
229 region_unmap((WRegion*)(split->tlpwin));
230 region_unmap((WRegion*)(split->brpwin));
231 splitinner_forall((WSplitInner*)split, split_unmap);
235 static void reparentreg(WRegion *reg, WWindow *target)
237 WRectangle g=REGION_GEOM(reg);
238 region_reparent(reg, target, &g, REGION_FIT_EXACT);
242 static void splitfloat_reparent(WSplitFloat *split, WWindow *target)
244 if(split->ssplit.current!=SPLIT_CURRENT_TL){
245 reparentreg((WRegion*)split->tlpwin, target);
246 split_reparent(split->ssplit.tl, target);
247 reparentreg((WRegion*)split->brpwin, target);
248 split_reparent(split->ssplit.br, target);
250 reparentreg((WRegion*)split->brpwin, target);
251 split_reparent(split->ssplit.br, target);
252 reparentreg((WRegion*)split->tlpwin, target);
253 split_reparent(split->ssplit.tl, target);
264 #define TL_BORDER(SF) ((SF)->ssplit.dir==SPLIT_VERTICAL \
265 ? (SF)->tlpwin->bdw.bottom \
266 : (SF)->tlpwin->bdw.right)
268 #define BR_BORDER(SF) ((SF)->ssplit.dir==SPLIT_VERTICAL \
269 ? (SF)->brpwin->bdw.top \
270 : (SF)->brpwin->bdw.left)
273 void splitfloat_tl_pwin_to_cnt(WSplitFloat *split, WRectangle *g)
275 if(split->ssplit.dir==SPLIT_HORIZONTAL)
276 g->w=maxof(1, g->w-split->tlpwin->bdw.right);
278 g->h=maxof(1, g->h-split->tlpwin->bdw.bottom);
282 void splitfloat_br_pwin_to_cnt(WSplitFloat *split, WRectangle *g)
284 if(split->ssplit.dir==SPLIT_HORIZONTAL){
285 int delta=split->tlpwin->bdw.left;
286 g->w=maxof(1, g->w-delta);
289 int delta=split->tlpwin->bdw.top;
290 g->h=maxof(1, g->h-delta);
296 void splitfloat_tl_cnt_to_pwin(WSplitFloat *split, WRectangle *g)
298 if(split->ssplit.dir==SPLIT_HORIZONTAL)
299 g->w=maxof(1, g->w+split->tlpwin->bdw.right);
301 g->h=maxof(1, g->h+split->tlpwin->bdw.bottom);
305 void splitfloat_br_cnt_to_pwin(WSplitFloat *split, WRectangle *g)
307 if(split->ssplit.dir==SPLIT_HORIZONTAL){
308 int delta=split->tlpwin->bdw.left;
309 g->w=maxof(1, g->w+delta);
312 int delta=split->tlpwin->bdw.top;
313 g->h=maxof(1, g->h+delta);
319 static int infadd(int x, int y)
321 return ((x==INT_MAX || y==INT_MAX) ? INT_MAX : (x+y));
325 static int splitfloat_get_handle(WSplitFloat *split, int dir,
328 assert(other==split->ssplit.tl || other==split->ssplit.br);
330 if(dir!=split->ssplit.dir)
333 if(dir==SPLIT_VERTICAL){
334 if(other==split->ssplit.tl)
335 return split->tlpwin->bdw.right;
336 else if(other==split->ssplit.br)
337 return split->tlpwin->bdw.left;
339 if(other==split->ssplit.tl)
340 return split->tlpwin->bdw.bottom;
341 else if(other==split->ssplit.br)
342 return split->tlpwin->bdw.top;
349 static int splitfloat_get_max(WSplitFloat *split, int dir, WSplit *other)
351 return infadd((dir==SPLIT_VERTICAL ? other->max_h : other->max_w),
352 splitfloat_get_handle(split, dir, other));
356 static int splitfloat_get_min(WSplitFloat *split, int dir, WSplit *other)
358 return ((dir==SPLIT_VERTICAL ? other->min_h : other->min_w)
359 +splitfloat_get_handle(split, dir, other));
363 static void splitfloat_update_bounds(WSplitFloat *split, bool recursive)
365 WSplit *tl=split->ssplit.tl, *br=split->ssplit.br;
366 WSplit *node=(WSplit*)split;
367 int tl_max_w, br_max_w, tl_max_h, br_max_h;
368 int tl_min_w, br_min_w, tl_min_h, br_min_h;
371 split_update_bounds(tl, recursive);
372 split_update_bounds(br, recursive);
375 tl_max_w=splitfloat_get_max(split, SPLIT_HORIZONTAL, tl);
376 br_max_w=splitfloat_get_max(split, SPLIT_HORIZONTAL, br);
377 tl_max_h=splitfloat_get_max(split, SPLIT_VERTICAL, tl);
378 br_max_h=splitfloat_get_max(split, SPLIT_VERTICAL, br);
379 tl_min_w=splitfloat_get_min(split, SPLIT_HORIZONTAL, tl);
380 br_min_w=splitfloat_get_min(split, SPLIT_HORIZONTAL, br);
381 tl_min_h=splitfloat_get_min(split, SPLIT_VERTICAL, tl);
382 br_min_h=splitfloat_get_min(split, SPLIT_VERTICAL, br);
384 if(split->ssplit.dir==SPLIT_HORIZONTAL){
385 node->max_w=infadd(tl_max_w, br_max_w);
386 node->min_w=minof(tl_min_w, br_min_w);
388 node->min_h=maxof(tl_min_h, br_min_h);
389 node->max_h=maxof(minof(tl_max_h, br_max_h), node->min_h);
390 node->unused_h=minof(tl->unused_h, br->unused_h);
392 node->max_h=infadd(tl_max_h, br_max_h);
393 node->min_h=minof(tl_min_h, br_min_h);
395 node->min_w=maxof(tl_min_w, br_min_w);
396 node->max_w=maxof(minof(tl_max_w, br_max_w), node->min_w);
397 node->unused_w=minof(tl->unused_w, br->unused_w);
402 void splitfloat_update_handles(WSplitFloat *split, const WRectangle *tlg_,
403 const WRectangle *brg_)
405 WRectangle tlg=*tlg_, brg=*brg_;
407 if(split->ssplit.dir==SPLIT_HORIZONTAL){
408 tlg.w=split->tlpwin->bdw.right;
409 tlg.x=tlg_->x+tlg_->w-tlg.w;
410 brg.w=split->brpwin->bdw.left;
412 tlg.h=split->tlpwin->bdw.bottom;
413 tlg.y=tlg_->y+tlg_->h-tlg.h;
414 brg.h=split->brpwin->bdw.top;
417 region_fit((WRegion*)split->tlpwin, &tlg, REGION_FIT_EXACT);
418 region_fit((WRegion*)split->brpwin, &brg, REGION_FIT_EXACT);
422 static void bound(int *what, int min, int max)
431 static void adjust_sizes(int *tls_, int *brs_, int nsize,
432 int tlmin, int brmin, int tlmax, int brmax,
435 int tls=maxof(0, *tls_);
436 int brs=maxof(0, *brs_);
437 nsize=maxof(1, nsize);
440 tls=maxof(1, nsize-brs);
441 bound(&tls, tlmin, tlmax);
443 bound(&brs, brmin, brmax);
445 bound(&tls, tlmin, tlmax);
446 }else if(primn==PRIMN_BR){
447 brs=maxof(1, nsize-tls);
448 bound(&brs, brmin, brmax);
450 bound(&tls, tlmin, tlmax);
452 bound(&brs, brmin, brmax);
453 }else{ /* && PRIMN_ANY */
454 tls=tls*nsize/maxof(2, tls+brs);
455 bound(&tls, tlmin, tlmax);
457 bound(&brs, brmin, brmax);
459 bound(&tls, tlmin, tlmax);
467 static void adjust_size(int *sz, int dir, WSplitFloat *f, WSplit *s)
469 int mi=splitfloat_get_min(f, dir, s);
470 int ma=splitfloat_get_max(f, dir, s);
471 *sz=maxof(mi, minof(*sz, ma));
475 static void splitfloat_do_resize(WSplitFloat *split, const WRectangle *ng,
476 int hprimn, int vprimn, bool transpose)
478 WRectangle tlg=GEOM(split->ssplit.tl);
479 WRectangle brg=GEOM(split->ssplit.br);
480 WRectangle ntlg=*ng, nbrg=*ng;
481 WRectangle *og=&((WSplit*)split)->geom;
482 int dir=split->ssplit.dir;
485 splitfloat_tl_cnt_to_pwin(split, &tlg);
486 splitfloat_br_cnt_to_pwin(split, &brg);
489 if(dir==SPLIT_VERTICAL){
490 dir=SPLIT_HORIZONTAL;
491 split->tlpwin->bline=GR_BORDERLINE_RIGHT;
492 split->brpwin->bline=GR_BORDERLINE_LEFT;
495 split->tlpwin->bline=GR_BORDERLINE_BOTTOM;
496 split->brpwin->bline=GR_BORDERLINE_TOP;
498 split->ssplit.dir=dir;
501 if(dir==SPLIT_VERTICAL){
502 if(ng->h<=tlg.h+brg.h){
504 ntlg.h=minof(tlg.w, ng->h*2/3);
505 nbrg.h=minof(brg.w, ng->h*2/3);
506 adjust_size(&ntlg.h, dir, split, split->ssplit.tl);
507 adjust_size(&nbrg.h, dir, split, split->ssplit.br);
508 adjust=(ng->h>ntlg.h+nbrg.h);
510 ntlg.h=minof(ng->h, tlg.h);
511 nbrg.h=minof(ng->h, brg.h);
520 adjust_sizes(&ntlg.h, &nbrg.h, ng->h,
521 splitfloat_get_min(split, dir, split->ssplit.tl),
522 splitfloat_get_min(split, dir, split->ssplit.br),
523 splitfloat_get_max(split, dir, split->ssplit.tl),
524 splitfloat_get_max(split, dir, split->ssplit.br),
528 nbrg.y=ng->y+ng->h-nbrg.h;
530 if(ng->w<=tlg.w+brg.w){
532 ntlg.w=minof(tlg.h, ng->w*2/3);
533 nbrg.w=minof(brg.h, ng->w*2/3);
534 adjust_size(&ntlg.w, dir, split, split->ssplit.tl);
535 adjust_size(&nbrg.w, dir, split, split->ssplit.br);
536 adjust=(ng->w>ntlg.w+nbrg.w);
538 ntlg.w=minof(ng->w, tlg.w);
539 nbrg.w=minof(ng->w, brg.w);
548 adjust_sizes(&ntlg.w, &nbrg.w, ng->w,
549 splitfloat_get_min(split, dir, split->ssplit.tl),
550 splitfloat_get_min(split, dir, split->ssplit.br),
551 splitfloat_get_max(split, dir, split->ssplit.tl),
552 splitfloat_get_max(split, dir, split->ssplit.br),
556 nbrg.x=ng->x+ng->w-nbrg.w;
561 splitfloat_update_handles(split, &ntlg, &nbrg);
563 splitfloat_tl_pwin_to_cnt(split, &ntlg);
564 split_do_resize(split->ssplit.tl, &ntlg, hprimn, vprimn, transpose);
565 splitfloat_br_pwin_to_cnt(split, &nbrg);
566 split_do_resize(split->ssplit.br, &nbrg, hprimn, vprimn, transpose);
570 static void calc_amount(int *amount, int *oamount,
571 int rs, WSplitSplit *p, int omax,
572 const WRectangle *ng, const WRectangle *og)
577 if(p->dir==SPLIT_VERTICAL)
578 *amount=maxof(0, minof(rs, GEOM(p).h-ng->h));
580 *amount=maxof(0, minof(rs, GEOM(p).w-ng->w));
582 if(p->dir==SPLIT_VERTICAL){
583 int overlap=maxof(0, og->h-(GEOM(p).h-ng->h));
584 *amount=-minof(-rs, overlap);
585 *oamount=maxof(0, minof(*amount-rs, omax-og->h));
588 int overlap=maxof(0, og->w-(GEOM(p).w-ng->w));
589 *amount=-minof(-rs, overlap);
590 *oamount=maxof(0, minof(*amount-rs, omax-og->w));
597 static void splitfloat_do_rqsize(WSplitFloat *split, WSplit *node,
598 RootwardAmount *ha, RootwardAmount *va,
599 WRectangle *rg, bool tryonly)
601 int hprimn=PRIMN_ANY, vprimn=PRIMN_ANY;
602 WRectangle pg, og, ng, nog, nng;
605 int amount=0, oamount=0, omax;
607 WSplitSplit *p=&(split->ssplit);
609 assert(!ha->any || ha->tl==0);
610 assert(!va->any || va->tl==0);
611 assert(p->tl==node || p->br==node);
624 if(thisnode==PRIMN_TL){
625 splitfloat_tl_cnt_to_pwin(split, &ng);
626 splitfloat_br_cnt_to_pwin(split, &og);
628 splitfloat_br_cnt_to_pwin(split, &ng);
629 splitfloat_tl_cnt_to_pwin(split, &og);
632 ca=(p->dir==SPLIT_VERTICAL ? va : ha);
634 omax=splitfloat_get_max(split, p->dir, other);
636 if(thisnode==PRIMN_TL || ca->any){
637 calc_amount(&amount, &oamount, ca->br, p, omax, &ng, &og);
639 }else/*if(thisnode==PRIMN_BR)*/{
640 calc_amount(&amount, &oamount, ca->tl, p, omax, &ng, &og);
644 if(((WSplit*)p)->parent==NULL /*||
645 (ha->tl==0 && ha->br==0 && va->tl==0 && va->br==0)*/){
646 pg=((WSplit*)p)->geom;
648 splitinner_do_rqsize(((WSplit*)p)->parent, (WSplit*)p, ha, va,
652 assert(pg.w>=0 && pg.h>=0);
657 if(p->dir==SPLIT_VERTICAL){
658 nog.h=minof(pg.h, maxof(0, og.h+oamount));
659 nng.h=minof(pg.h, maxof(0, ng.h+amount+pg.h-GEOM(p).h));
660 if(thisnode==PRIMN_TL)
661 nog.y=pg.y+pg.h-nog.h;
663 nng.y=pg.y+pg.h-nng.h;
666 nog.w=minof(pg.w, maxof(0, og.w+oamount));
667 nng.w=minof(pg.w, maxof(0, ng.w+amount+pg.w-GEOM(p).w));
668 if(thisnode==PRIMN_TL)
669 nog.x=pg.x+pg.w-nog.w;
671 nng.x=pg.x+pg.w-nng.w;
678 if(thisnode==PRIMN_TL){
679 splitfloat_update_handles(split, &nng, &nog);
680 splitfloat_br_pwin_to_cnt(split, &nog);
682 splitfloat_update_handles(split, &nog, &nng);
683 splitfloat_tl_pwin_to_cnt(split, &nog);
686 /* Entä jos 'other' on stdisp? */
687 split_do_resize(other, &nog, hprimn, vprimn, FALSE);
691 if(thisnode==PRIMN_TL)
692 splitfloat_tl_pwin_to_cnt(split, rg);
694 splitfloat_br_pwin_to_cnt(split, rg);
698 void splitfloat_flip(WSplitFloat *split)
702 splitsplit_flip_default(&split->ssplit);
704 tlg=split->ssplit.tl->geom;
705 brg=split->ssplit.br->geom;
707 splitfloat_tl_cnt_to_pwin(split, &tlg);
708 splitfloat_br_cnt_to_pwin(split, &brg);
709 splitfloat_update_handles(split, &tlg, &brg);
716 /*{{{ Loading code */
721 static void adjust_tls_brs(int *tls, int *brs, int total)
729 *tls=total*(*tls)/(*tls+*brs);
733 *tls=minof(maxof(MINS, *tls), total);
734 *brs=minof(maxof(MINS, *brs), total);
738 static void calc_tlg_brg(const WRectangle *geom, int tls, int brs, int dir,
739 WRectangle *tlg, WRectangle *brg)
744 if(dir==SPLIT_HORIZONTAL){
745 adjust_tls_brs(&tls, &brs, geom->w);
748 brg->x=geom->x+geom->w-brs;
750 adjust_tls_brs(&tls, &brs, geom->h);
753 brg->y=geom->y+geom->h-brs;
758 WSplit *load_splitfloat(WTiling *ws, const WRectangle *geom, ExtlTab tab)
760 WSplit *tl=NULL, *br=NULL;
768 set+=(extl_table_gets_i(tab, "tls", &tls)==TRUE);
769 set+=(extl_table_gets_i(tab, "brs", &brs)==TRUE);
770 set+=(extl_table_gets_s(tab, "dir", &dir_str)==TRUE);
775 if(strcmp(dir_str, "vertical")==0){
777 }else if(strcmp(dir_str, "horizontal")==0){
778 dir=SPLIT_HORIZONTAL;
780 warn(TR("Invalid direction."));
786 split=create_splitfloat(geom, ws, dir);
790 if(!extl_table_is_bool_set(tab, "tls_brs_incl_handles")){
791 if(split->ssplit.dir==SPLIT_HORIZONTAL){
792 tls+=split->tlpwin->bdw.right;
793 brs+=split->brpwin->bdw.left;
795 tls+=split->tlpwin->bdw.bottom;
796 brs+=split->brpwin->bdw.top;
800 calc_tlg_brg(geom, tls, brs, dir, &tlg, &brg);
802 splitfloat_update_handles(split, &tlg, &brg);
804 if(extl_table_gets_t(tab, "tl", &subtab)){
806 splitfloat_tl_pwin_to_cnt(split, &g);
807 tl=tiling_load_node(ws, &g, subtab);
808 extl_unref_table(subtab);
811 if(extl_table_gets_t(tab, "br", &subtab)){
817 splitfloat_br_pwin_to_cnt(split, &g);
819 br=tiling_load_node(ws, &g, subtab);
820 extl_unref_table(subtab);
823 if(tl==NULL || br==NULL){
824 destroy_obj((Obj*)split);
826 split_do_resize(tl, geom, PRIMN_ANY, PRIMN_ANY, FALSE);
830 split_do_resize(br, geom, PRIMN_ANY, PRIMN_ANY, FALSE);
836 tl->parent=(WSplitInner*)split;
837 br->parent=(WSplitInner*)split;
842 return (WSplit*)split;
852 WSplitRegion *splittree_split_floating(WSplit *node, int dir, int primn,
853 int nmins, WRegionSimpleCreateFn *fn,
860 WRectangle gn, go, gnc, goc;
866 if(primn!=PRIMN_TL && primn!=PRIMN_BR)
869 split_update_bounds(split_find_root(node), TRUE);
871 sf=create_splitfloat(&node->geom, ws, dir);
876 omins=(dir==SPLIT_VERTICAL ? node->min_h : node->min_w);
877 s=split_size(node, dir);
887 mins=maxof(omins+bo, nmins+bn);
889 /* Potentially resize old node. */
891 splittree_begin_resize();
894 WRectangle ng=node->geom, rg;
895 if(dir==SPLIT_VERTICAL)
900 split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, TRUE);
901 rs=(dir==SPLIT_VERTICAL ? rg.h : rg.w);
903 warn(TR("Unable to split: not enough free space."));
904 destroy_obj((Obj*)sf);
907 split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, FALSE);
908 s=split_size(node, dir);
910 splittree_scan_stdisp_rootward(node);
913 /* Calculate geometries. */
915 sn=maxof(nmins+bn, s/2);
916 so=maxof(omins+bo, s-s/2);
918 ((WSplit*)sf)->geom=node->geom;
921 calc_tlg_brg(&(node->geom), sn, so, dir, &gn, &go);
922 splitfloat_update_handles(sf, &gn, &go);
923 gnc=gn; splitfloat_tl_pwin_to_cnt(sf, &gnc);
924 goc=go; splitfloat_br_pwin_to_cnt(sf, &goc);
926 calc_tlg_brg(&(node->geom), so, sn, dir, &go, &gn);
927 splitfloat_update_handles(sf, &go, &gn);
928 goc=go; splitfloat_tl_pwin_to_cnt(sf, &goc);
929 gnc=gn; splitfloat_br_pwin_to_cnt(sf, &gnc);
932 /* Create the region. */
934 fp.mode=REGION_FIT_EXACT;
937 nreg=fn(REGION_PARENT(ws), &fp);
940 destroy_obj((Obj*)sf);
944 nnode=create_splitregion(&(fp.g), nreg);
946 destroy_obj((Obj*)nreg);
947 destroy_obj((Obj*)sf);
951 /* Now that everything's ok, resize and move original node. */
953 split_do_resize(node, &goc,
954 (dir==SPLIT_HORIZONTAL ? primn : PRIMN_ANY),
955 (dir==SPLIT_VERTICAL ? primn : PRIMN_ANY),
958 /* Set up split structure. */
963 splitinner_replace(psplit, node, (WSplit*)sf);
965 splittree_changeroot(node, (WSplit*)sf);
967 node->parent=(WSplitInner*)sf;
968 ((WSplit*)nnode)->parent=(WSplitInner*)sf;
972 sf->ssplit.br=(WSplit*)nnode;
974 sf->ssplit.tl=(WSplit*)nnode;
978 /*splittree_end_resize();*/
990 static DynFunTab splitfloat_dynfuntab[]={
991 {split_update_bounds, splitfloat_update_bounds},
992 {split_do_resize, splitfloat_do_resize},
993 {splitinner_do_rqsize, splitfloat_do_rqsize},
994 {split_stacking, splitfloat_stacking},
995 {split_restack, splitfloat_restack},
996 {split_reparent, splitfloat_reparent},
997 {split_map, splitfloat_map},
998 {split_unmap, splitfloat_unmap},
999 {splitsplit_flip, splitfloat_flip},
1005 IMPLCLASS(WSplitFloat, WSplitSplit, splitfloat_deinit, splitfloat_dynfuntab);