X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=ioncore%2Fframedpholder.c;h=60c6291ba6c894a58520427b742c2778993cdab1;hp=de437a23c6921ae10cbd132f93697f7f0691ffc4;hb=HEAD;hpb=ae4260bb64817c11f9a7140324cd3e3ba113e297 diff --git a/ioncore/framedpholder.c b/ioncore/framedpholder.c index de437a2..60c6291 100644 --- a/ioncore/framedpholder.c +++ b/ioncore/framedpholder.c @@ -1,7 +1,7 @@ /* * ion/ioncore/framedpholder.c * - * Copyright (c) Tuomo Valkonen 2005-2007. + * Copyright (c) Tuomo Valkonen 2005-2009. * * See the included file LICENSE for details. */ @@ -13,6 +13,7 @@ #include "frame.h" #include "framedpholder.h" #include "sizehint.h" +#include "resize.h" /*{{{ Init/deinit */ @@ -28,6 +29,8 @@ bool framedpholder_init(WFramedPHolder *ph, WPHolder *cont, ph->cont=cont; ph->param=*param; + watch_init(&ph->frame_watch); + return TRUE; } @@ -47,6 +50,7 @@ void framedpholder_deinit(WFramedPHolder *ph) } pholder_deinit(&(ph->ph)); + watch_reset(&ph->frame_watch); } @@ -59,6 +63,7 @@ void framedpholder_deinit(WFramedPHolder *ph) typedef struct{ WRegionAttachData *data; WFramedParam *param; + WRegion *reg_ret; } AP; @@ -66,32 +71,46 @@ void frame_adjust_to_initial(WFrame *frame, const WFitParams *fp, const WFramedParam *param, WRegion *reg) { WRectangle rqg, mg; + WSizeHints szh; + int iw, ih; if(!(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER))) return; mplex_managed_geom((WMPlex*)frame, &mg); - + /* Adjust geometry */ if(!param->inner_geom_gravity_set){ + iw=REGION_GEOM(reg).w; + ih=REGION_GEOM(reg).h; rqg.x=REGION_GEOM(frame).x; rqg.y=REGION_GEOM(frame).y; - rqg.w=maxof(1, REGION_GEOM(reg).w+(REGION_GEOM(frame).w-mg.w)); - rqg.h=maxof(1, REGION_GEOM(reg).h+(REGION_GEOM(frame).h-mg.h)); }else{ int bl=mg.x; int br=REGION_GEOM(frame).w-(mg.x+mg.w); int bt=mg.y; int bb=REGION_GEOM(frame).h-(mg.y+mg.h); + iw=param->inner_geom.w; + ih=param->inner_geom.h; + rqg.x=(/*fp->g.x+*/param->inner_geom.x+ xgravity_deltax(param->gravity, bl, br)); rqg.y=(/*fp->g.y+*/param->inner_geom.y+ xgravity_deltay(param->gravity, bt, bb)); - rqg.w=maxof(1, param->inner_geom.w+(REGION_GEOM(frame).w-mg.w)); - rqg.h=maxof(1, param->inner_geom.h+(REGION_GEOM(frame).h-mg.h)); } - + + /* Some apps seem to request geometries inconsistent with their size hints, + * so correct for that here. + * Because WGroup(CW) sets no_constrain on the size hints, we have + * to set override_no_constrain to force the frame to have the size + * of the 'bottom' of the group. + */ + region_size_hints(reg, &szh); + sizehints_correct(&szh, &iw, &ih, TRUE, TRUE); + rqg.w=maxof(1, iw+(REGION_GEOM(frame).w-mg.w)); + rqg.h=maxof(1, ih+(REGION_GEOM(frame).h-mg.h)); + if(!(fp->mode®ION_FIT_WHATEVER)) rectangle_constrain(&rqg, &fp->g); @@ -119,6 +138,8 @@ WRegion *framed_handler(WWindow *par, reg=mplex_do_attach(&frame->mplex, &mp, ap->data); + ap->reg_ret=reg; + if(reg==NULL){ destroy_obj((Obj*)frame); return NULL; @@ -143,6 +164,7 @@ WRegion *region_attach_framed(WRegion *reg, WFramedParam *param, ap.data=data; ap.param=param; + ap.reg_ret=NULL; return fn(reg, fn_param, &data2); } @@ -152,8 +174,16 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags, WRegionAttachData *data) { WRegionAttachData data2; + WFrame *frame; AP ap; + frame=(WFrame*)ph->frame_watch.obj; + + if(frame!=NULL){ + WMPlexAttachParams mp=MPLEXATTACHPARAMS_INIT; + return mplex_do_attach(&frame->mplex, &mp, data); + } + if(ph->cont==NULL) return FALSE; @@ -163,8 +193,18 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags, ap.data=data; ap.param=&ph->param; + ap.reg_ret=NULL; - return pholder_do_attach(ph->cont, flags, &data2); + frame=(WFrame*)pholder_do_attach(ph->cont, flags, &data2); + + if(frame!=NULL){ + assert(OBJ_IS(frame, WFrame)); + watch_setup(&ph->frame_watch, (Obj*)frame, NULL); + } + + return (flags&PHOLDER_ATTACH_RETURN_CREATEROOT + ? (WRegion*)frame + : ap.reg_ret); } @@ -176,32 +216,34 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags, bool framedpholder_do_goto(WFramedPHolder *ph) { - return (ph->cont!=NULL - ? pholder_goto(ph->cont) - : FALSE); + WRegion *frame=(WRegion*)ph->frame_watch.obj; + + if(frame!=NULL) + return region_goto((WRegion*)frame); + else if(ph->cont!=NULL) + return pholder_goto(ph->cont); + else + return FALSE; } WRegion *framedpholder_do_target(WFramedPHolder *ph) { - return (ph->cont!=NULL - ? pholder_target(ph->cont) - : NULL); + WRegion *frame=(WRegion*)ph->frame_watch.obj; + + return (frame!=NULL + ? frame + : (ph->cont!=NULL + ? pholder_target(ph->cont) + : NULL)); } -WPHolder *framedpholder_do_root(WFramedPHolder *ph) +bool framedpholder_stale(WFramedPHolder *ph) { - WPHolder *root; - - if(ph->cont==NULL) - return NULL; - - root=pholder_root(ph->cont); + WRegion *frame=(WRegion*)ph->frame_watch.obj; - return (root!=ph->cont - ? root - : &ph->ph); + return (frame==NULL && (ph->cont==NULL || pholder_stale(ph->cont))); } @@ -221,8 +263,8 @@ static DynFunTab framedpholder_dynfuntab[]={ {(DynFun*)pholder_do_target, (DynFun*)framedpholder_do_target}, - {(DynFun*)pholder_do_root, - (DynFun*)framedpholder_do_root}, + {(DynFun*)pholder_stale, + (DynFun*)framedpholder_stale}, END_DYNFUNTAB };