X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=mod_tiling%2Ftiling.c;h=bbefef74855029cbab2a722fed77d5e87d29b6dc;hp=159f001a0a9af20f7980469f19dc9f3fc0ae10f1;hb=de22e45179cb3bafa490294d31d47f361047a30a;hpb=803afbc1cd633f6c025bcd9537e9b7e9aedadd0d diff --git a/mod_tiling/tiling.c b/mod_tiling/tiling.c index 159f001..bbefef7 100644 --- a/mod_tiling/tiling.c +++ b/mod_tiling/tiling.c @@ -48,10 +48,6 @@ static WTilingIterTmp tiling_iter_default_tmp; /*{{{ Some helper routines */ -#define STDISP_OF(WS) \ - ((WS)->stdispnode!=NULL ? (WS)->stdispnode->regnode.reg : NULL) - - static WSplitRegion *get_node_check(WTiling *ws, WRegion *reg) { WSplitRegion *node; @@ -266,13 +262,6 @@ Window tiling_xwindow(const WTiling *ws) } -/* -WRegion *tiling_rqclose_propagate(WTiling *ws, WRegion *maybe_sub) -{ - return (region_rqclose((WRegion*)ws, FALSE) ? (WRegion*)ws : NULL); -} -*/ - WPHolder *tiling_prepare_manage_transient(WTiling *ws, const WClientWin *transient, const WManageParams *param, @@ -500,7 +489,7 @@ bool tiling_managed_add_default(WTiling *ws, WRegion *reg) Window bottom=None, top=None; WFrame *frame; - if(STDISP_OF(ws)!=reg){ + if(TILING_STDISP_OF(ws)!=reg){ if(!ptrlist_insert_last(&(ws->managed_list), reg)) return FALSE; } @@ -535,30 +524,25 @@ bool tiling_managed_add(WTiling *ws, WRegion *reg) } -static WRegion *create_initial_frame(WTiling *ws, WWindow *parent, - const WFitParams *fp) +bool tiling_do_attach_initial(WTiling *ws, WRegion *reg) { - WRegion *reg=ws->create_frame_fn(parent, fp); - - if(reg==NULL) - return NULL; + assert(ws->split_tree==NULL); + + ws->split_tree=(WSplit*)create_splitregion(®ION_GEOM(reg), reg); + if(ws->split_tree==NULL) + return FALSE; - ws->split_tree=(WSplit*)create_splitregion(&(fp->g), reg); - if(ws->split_tree==NULL){ - destroy_obj((Obj*)reg); - return NULL; - } ws->split_tree->ws_if_root=ws; if(!tiling_managed_add(ws, reg)){ - destroy_obj((Obj*)reg); destroy_obj((Obj*)ws->split_tree); - return NULL; + ws->split_tree=NULL; + return FALSE; } - - return reg; + + return TRUE; } - + static WRegion *create_frame_tiling(WWindow *parent, const WFitParams *fp) { @@ -575,7 +559,8 @@ bool tiling_init(WTiling *ws, WWindow *parent, const WFitParams *fp, : create_frame_tiling); ws->stdispnode=NULL; ws->managed_list=NULL; - + ws->batchop=FALSE; + ws->dummywin=XCreateWindow(ioncore_g.dpy, parent->win, fp->g.x, fp->g.y, 1, 1, 0, CopyFromParent, InputOnly, @@ -589,7 +574,18 @@ bool tiling_init(WTiling *ws, WWindow *parent, const WFitParams *fp, REGION_PLEASE_WARP); if(ci){ - if(create_initial_frame(ws, parent, fp)==NULL){ + WRegionAttachData data; + WRegion *res; + + data.type=REGION_ATTACH_NEW; + data.u.n.fn=(WRegionCreateFn*)ws->create_frame_fn; + data.u.n.param=NULL; + + res=region_attach_helper((WRegion*)ws, parent, fp, + (WRegionDoAttachFn*)tiling_do_attach_initial, + NULL, &data); + + if(res==NULL){ XDestroyWindow(ioncore_g.dpy, ws->dummywin); return FALSE; } @@ -648,44 +644,30 @@ void tiling_deinit(WTiling *ws) } -bool tiling_managed_may_destroy(WTiling *ws, WRegion *reg) +WRegion *tiling_managed_disposeroot(WTiling *ws, WRegion *reg) { WTilingIterTmp tmp; WRegion *mgd; - - FOR_ALL_MANAGED_BY_TILING(mgd, ws, tmp){ - if(mgd!=STDISP_OF(ws) && mgd!=reg){ - return TRUE; - } - } - return region_manager_allows_destroying((WRegion*)ws); -} - - -bool tiling_may_destroy(WTiling *ws, WRegion *reg) -{ - WTilingIterTmp tmp; - WRegion *mgd; + if(ws->batchop) + return reg; FOR_ALL_MANAGED_BY_TILING(mgd, ws, tmp){ - if(mgd!=STDISP_OF(ws)){ - warn(TR("Workspace not empty - refusing to destroy.")); - return FALSE; - } + if(mgd!=TILING_STDISP_OF(ws) && mgd!=reg) + return reg; } - return TRUE; + return region_disposeroot((WRegion*)ws); } -bool tiling_rescue_clientwins(WTiling *ws, WPHolder *ph) +bool tiling_rescue_clientwins(WTiling *ws, WRescueInfo *info) { WTilingIterTmp tmp; ptrlist_iter_init(&tmp, ws->managed_list); - return region_rescue_some_clientwins((WRegion*)ws, ph, + return region_rescue_some_clientwins((WRegion*)ws, info, (WRegionIterator*)ptrlist_iter, &tmp); } @@ -693,7 +675,7 @@ bool tiling_rescue_clientwins(WTiling *ws, WPHolder *ph) void tiling_do_managed_remove(WTiling *ws, WRegion *reg) { - if(STDISP_OF(ws)==reg){ + if(TILING_STDISP_OF(ws)==reg){ ws->stdispnode->regnode.reg=NULL; }else{ ptrlist_remove(&(ws->managed_list), reg); @@ -711,30 +693,49 @@ static bool nostdispfilter(WSplit *node) void tiling_managed_remove(WTiling *ws, WRegion *reg) { - bool ds=OBJ_IS_BEING_DESTROYED(ws); bool act=REGION_IS_ACTIVE(reg); bool mcf=region_may_control_focus((WRegion*)ws); WSplitRegion *node=get_node_check(ws, reg); - WRegion *other; + bool norestore=(OBJ_IS_BEING_DESTROYED(ws) || ws->batchop); + WRegion *other=NULL; - other=tiling_do_navi_next(ws, reg, REGION_NAVI_ANY, TRUE, FALSE); + if(!norestore) + other=tiling_do_navi_next(ws, reg, REGION_NAVI_ANY, TRUE, FALSE); tiling_do_managed_remove(ws, reg); if(node==(WSplitRegion*)(ws->stdispnode)) ws->stdispnode=NULL; - if(node==NULL) - return; - - splittree_remove((WSplit*)node, (!ds && other!=NULL)); - - if(!ds){ - if(other==NULL) - region_dispose((WRegion*)ws, mcf); - else if(act && mcf) - region_warp(other); + if(node!=NULL){ + bool reused=FALSE; + + if(other==NULL && !norestore){ + WWindow *par=REGION_PARENT(ws); + WFitParams fp; + + assert(par!=NULL); + + fp.g=node->split.geom; + fp.mode=REGION_FIT_EXACT; + + other=(ws->create_frame_fn)(par, &fp); + + if(other!=NULL){ + node->reg=other; + tiling_managed_add(ws, other); + reused=TRUE; + }else{ + warn(TR("Tiling in useless state.")); + } + } + + if(!reused) + splittree_remove((WSplit*)node, (!norestore && other!=NULL)); } + + if(!norestore && other!=NULL && act && mcf) + region_warp(other); } @@ -1086,24 +1087,45 @@ WFrame *tiling_split_at(WTiling *ws, WFrame *frame, const char *dirstr, } -/*EXTL_DOC - * Try to relocate regions managed by \var{frame} to another frame - * and, if possible, destroy the frame. - */ -EXTL_EXPORT_MEMBER -bool tiling_unsplit_at(WTiling *ws, WFrame *frame) +void do_unsplit(WRegion *reg) { - if(frame==NULL){ - warn(TR("Nil frame.")); - return FALSE; + WTiling *ws=REGION_MANAGER_CHK(reg, WTiling); + WPHolder *ph; + bool res; + + if(ws==NULL) + return; + + ph=region_get_rescue_pholder_for((WRegion*)ws, reg); + + if(ph==NULL){ + res=!region_rescue_needed(reg); + }else{ + res=region_rescue(reg, ph); + destroy_obj((Obj*)ph); } - if(REGION_MANAGER(frame)!=(WRegion*)ws){ - warn(TR("The frame is not managed by the workspace.")); - return FALSE; + if(!res){ + warn(TR("Unable to unsplit: Could not move client windows " + "elsewhere within the tiling.")); + return; } - return region_rqclose((WRegion*)frame, TRUE); + destroy_obj((Obj*)reg); +} + + +/*EXTL_DOC + * Try to relocate regions managed by \var{reg} to another frame + * and, if possible, destroy it. + */ +EXTL_EXPORT_MEMBER +void tiling_unsplit_at(WTiling *ws, WRegion *reg) +{ + if(reg==NULL || REGION_MANAGER(reg)!=(WRegion*)ws) + return; + + mainloop_defer_action((Obj*)reg, (WDeferredAction*)do_unsplit); } @@ -1716,11 +1738,8 @@ static DynFunTab tiling_dynfuntab[]={ {(DynFun*)region_get_configuration, (DynFun*)tiling_get_configuration}, - {(DynFun*)region_managed_may_destroy, - (DynFun*)tiling_managed_may_destroy}, - - {(DynFun*)region_may_destroy, - (DynFun*)tiling_may_destroy}, + {(DynFun*)region_managed_disposeroot, + (DynFun*)tiling_managed_disposeroot}, {(DynFun*)region_current, (DynFun*)tiling_current},