X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=ioncore%2Fmplexpholder.c;h=3cbf5fdc2fa46a87471482c2d71502780fcae14a;hp=8bb7ddb1e89ee279d3f99ec0229b68dd3e956d63;hb=f869221ce49f0fb7cca48eee28daff8684305963;hpb=720e6978185b09f2b2f60a6b96018238085a7238 diff --git a/ioncore/mplexpholder.c b/ioncore/mplexpholder.c index 8bb7ddb..3cbf5fd 100644 --- a/ioncore/mplexpholder.c +++ b/ioncore/mplexpholder.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "common.h" #include "mplex.h" @@ -18,9 +19,6 @@ #include "basicpholder.h" -static void mplex_watch_handler(Watch *watch, Obj *mplex); - - /*{{{ Primitives */ @@ -35,7 +33,7 @@ static void mplexpholder_do_link(WMPlexPHolder *ph, WMPlexPHolder *after, WLListNode *or_after) { - assert(mplex==(WMPlex*)ph->mplex_watch.obj && mplex!=NULL); + assert(mplex==(WMPlex*)ph->mplex && mplex!=NULL); if(after!=NULL){ assert(after->after==or_after); @@ -43,44 +41,60 @@ static void mplexpholder_do_link(WMPlexPHolder *ph, if(after->after!=NULL){ LINK_ITEM_AFTER(after->after->phs, after, ph, next, prev); }else{ - assert(on_ph_list(mplex->mx_phs, after)); - LINK_ITEM_AFTER(mplex->mx_phs, after, ph, next, prev); + assert(on_ph_list(mplex->misc_phs, after)); + LINK_ITEM_AFTER(mplex->misc_phs, after, ph, next, prev); } ph->after=after->after; }else if(or_after!=NULL){ LINK_ITEM_FIRST(or_after->phs, ph, next, prev); ph->after=or_after; }else{ - LINK_ITEM_FIRST(mplex->mx_phs, ph, next, prev); + LINK_ITEM_FIRST(mplex->misc_phs, ph, next, prev); ph->after=NULL; } } +static WMPlexPHolder *get_head(WMPlexPHolder *ph) +{ + while(1){ + /* ph->prev==NULL should not happen.. */ + if(ph->prev==NULL || ph->prev->next==NULL) + break; + ph=ph->prev; + } + + return ph; +} + + void mplexpholder_do_unlink(WMPlexPHolder *ph, WMPlex *mplex) { if(ph->recreate_pholder!=NULL){ - if(ph->prev!=NULL) - ph->prev->recreate_pholder=ph->recreate_pholder; - else - destroy_obj((Obj*)ph->recreate_pholder); + if(ph->next!=NULL){ + ph->next->recreate_pholder=ph->recreate_pholder; + }else{ + /* It might be in use in attach chain! So defer. */ + mainloop_defer_destroy((Obj*)ph->recreate_pholder); + } ph->recreate_pholder=NULL; } if(ph->after!=NULL){ UNLINK_ITEM(ph->after->phs, ph, next, prev); - }else if(mplex!=NULL && on_ph_list(mplex->mx_phs, ph)){ - UNLINK_ITEM(mplex->mx_phs, ph, next, prev); + }else if(mplex!=NULL && on_ph_list(mplex->misc_phs, ph)){ + UNLINK_ITEM(mplex->misc_phs, ph, next, prev); }else{ WMPlexPHolder *next=ph->next; - - assert((ph->next==NULL && ph->prev==NULL) - || ph->mplex_watch.obj==NULL); - if(ph->next!=NULL) - ph->next->prev=ph->prev; if(ph->prev!=NULL) ph->prev->next=next; + + if(next==NULL){ + next=get_head(ph); + assert(next->prev==ph); + } + next->prev=ph->prev; } ph->after=NULL; @@ -95,14 +109,6 @@ void mplexpholder_do_unlink(WMPlexPHolder *ph, WMPlex *mplex) /*{{{ Init/deinit */ -static void mplex_watch_handler(Watch *watch, Obj *mplex) -{ - WMPlexPHolder *ph=FIELD_TO_STRUCT(WMPlexPHolder, mplex_watch, watch); - mplexpholder_do_unlink(ph, (WMPlex*)mplex); - pholder_redirect(&(ph->ph), (WRegion*)mplex); -} - - static void mplex_get_attach_params(WMPlex *mplex, WStacking *st, WMPlexAttachParams *param) { @@ -120,27 +126,24 @@ static void mplex_get_attach_params(WMPlex *mplex, WStacking *st, bool mplexpholder_init(WMPlexPHolder *ph, WMPlex *mplex, WStacking *st, WMPlexAttachParams *param) { + WLListNode *or_after=NULL; + WMPlexPHolder *after=NULL; + pholder_init(&(ph->ph)); - watch_init(&(ph->mplex_watch)); + ph->mplex=mplex; ph->after=NULL; ph->next=NULL; ph->prev=NULL; ph->param.flags=0; ph->recreate_pholder=NULL; - - if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler)){ - pholder_deinit(&(ph->ph)); - return FALSE; - } if(st!=NULL){ mplex_get_attach_params(mplex, st, &ph->param); if(st->lnode!=NULL){ - mplexpholder_do_link(ph, mplex, - LIST_LAST(st->lnode->phs, next, prev), - st->lnode); + after=LIST_LAST(st->lnode->phs, next, prev); + or_after=st->lnode; } }else{ static WMPlexAttachParams dummy_param={0, 0, {0, 0, 0, 0}, 0, 0}; @@ -154,18 +157,17 @@ bool mplexpholder_init(WMPlexPHolder *ph, WMPlex *mplex, WStacking *st, int index=(param->flags&MPLEX_ATTACH_INDEX ? param->index : mplex_default_index(mplex)); - WLListNode *or_after=llist_index_to_after(mplex->mx_list, - mplex->mx_current, - index); - WMPlexPHolder *after=(index==LLIST_INDEX_LAST - ? (or_after!=NULL - ? LIST_LAST(or_after->phs, next, prev) - : LIST_LAST(mplex->mx_phs, next, prev)) - : NULL); - - mplexpholder_do_link(ph, mplex, after, or_after); + or_after=llist_index_to_after(mplex->mx_list, + mplex->mx_current, index); + after=(index==LLIST_INDEX_LAST + ? (or_after!=NULL + ? LIST_LAST(or_after->phs, next, prev) + : LIST_LAST(mplex->misc_phs, next, prev)) + : NULL); } } + + mplexpholder_do_link(ph, mplex, after, or_after); return TRUE; } @@ -181,8 +183,7 @@ WMPlexPHolder *create_mplexpholder(WMPlex *mplex, void mplexpholder_deinit(WMPlexPHolder *ph) { - mplexpholder_do_unlink(ph, (WMPlex*)ph->mplex_watch.obj); - watch_reset(&(ph->mplex_watch)); + mplexpholder_do_unlink(ph, ph->mplex); pholder_deinit(&(ph->ph)); } @@ -197,18 +198,18 @@ typedef struct{ WMPlexPHolder *ph, *ph_head; WRegionAttachData *data; WFramedParam *param; + WRegion *reg_ret; } RP; -WRegion *recreate_handler(WWindow *par, - const WFitParams *fp, - void *rp_) +static WRegion *recreate_handler(WWindow *par, + const WFitParams *fp, + void *rp_) { RP *rp=(RP*)rp_; WMPlexPHolder *ph=rp->ph, *ph_head=rp->ph_head, *phtmp; WFramedParam *param=rp->param; WFrame *frame; - WRegion *reg; frame=create_frame(par, fp, param->mode); @@ -216,49 +217,37 @@ WRegion *recreate_handler(WWindow *par, return NULL; /* Move pholders to frame */ - frame->mplex.mx_phs=ph_head; + frame->mplex.misc_phs=ph_head; - for(phtmp=frame->mplex.mx_phs; phtmp!=NULL; phtmp=phtmp->next) - watch_setup(&(phtmp->mplex_watch), (Obj*)frame, mplex_watch_handler); + for(phtmp=frame->mplex.misc_phs; phtmp!=NULL; phtmp=phtmp->next) + phtmp->mplex=&frame->mplex; /* Attach */ if(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER)) ph->param.flags|=MPLEX_ATTACH_WHATEVER; - reg=mplex_do_attach_pholder(&frame->mplex, ph, rp->data); + rp->reg_ret=mplex_do_attach_pholder(&frame->mplex, ph, rp->data); ph->param.flags&=~MPLEX_ATTACH_WHATEVER; - if(reg==NULL){ + if(rp->reg_ret==NULL){ /* Try to recover */ - for(phtmp=frame->mplex.mx_phs; phtmp!=NULL; phtmp=phtmp->next) - watch_reset(&(phtmp->mplex_watch)); - frame->mplex.mx_phs=NULL; + for(phtmp=frame->mplex.misc_phs; phtmp!=NULL; phtmp=phtmp->next) + phtmp->mplex=NULL; + + frame->mplex.misc_phs=NULL; destroy_obj((Obj*)frame); return NULL; }else{ - frame_adjust_to_initial(frame, fp, param, reg); + frame_adjust_to_initial(frame, fp, param, rp->reg_ret); return (WRegion*)frame; } } -static WMPlexPHolder *get_head(WMPlexPHolder *ph) -{ - while(1){ - /* ph->prev==NULL should not happen.. */ - if(ph->prev==NULL || ph->prev->next==NULL) - break; - ph=ph->prev; - } - - return ph; -} - - static WFramedPHolder *get_recreate_ph(WMPlexPHolder *ph) { return get_head(ph)->recreate_pholder; @@ -271,7 +260,7 @@ static WRegion *mplexpholder_attach_recreate(WMPlexPHolder *ph, int flags, WRegionAttachData data2; WFramedPHolder *fph; WPHolder *root; - WRegion *reg; + WRegion *frame; RP rp; rp.ph_head=get_head(ph); @@ -286,26 +275,28 @@ static WRegion *mplexpholder_attach_recreate(WMPlexPHolder *ph, int flags, rp.ph=ph; rp.data=data; rp.param=&fph->param; + rp.reg_ret=NULL; data2.type=REGION_ATTACH_NEW; data2.u.n.fn=recreate_handler; data2.u.n.param=&rp; - reg=pholder_do_attach(fph->cont, flags, &data2); /* == frame */ + frame=pholder_do_attach(fph->cont, flags, &data2); - if(reg!=NULL){ - destroy_obj((Obj*)fph); + if(frame!=NULL){ rp.ph_head->recreate_pholder=NULL; + /* It might be in use in attach chain! So defer. */ + mainloop_defer_destroy((Obj*)fph); } - - return reg; + + return rp.reg_ret; } WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags, WRegionAttachData *data) { - WMPlex *mplex=(WMPlex*)ph->mplex_watch.obj; + WMPlex *mplex=ph->mplex; if(mplex==NULL) return mplexpholder_attach_recreate(ph, flags, data); @@ -322,18 +313,14 @@ WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags, bool mplexpholder_move(WMPlexPHolder *ph, WMPlex *mplex, WMPlexPHolder *after, WLListNode *or_after) - { - mplexpholder_do_unlink(ph, (WMPlex*)ph->mplex_watch.obj); + mplexpholder_do_unlink(ph, ph->mplex); - watch_reset(&(ph->mplex_watch)); - + ph->mplex=mplex; + if(mplex==NULL) return TRUE; - if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler)) - return FALSE; - mplexpholder_do_link(ph, mplex, after, or_after); return TRUE; @@ -342,7 +329,7 @@ bool mplexpholder_move(WMPlexPHolder *ph, WMPlex *mplex, bool mplexpholder_do_goto(WMPlexPHolder *ph) { - WRegion *reg=(WRegion*)ph->mplex_watch.obj; + WRegion *reg=(WRegion*)ph->mplex; if(reg!=NULL){ return region_goto(reg); @@ -358,7 +345,7 @@ bool mplexpholder_do_goto(WMPlexPHolder *ph) WRegion *mplexpholder_do_target(WMPlexPHolder *ph) { - WRegion *reg=(WRegion*)ph->mplex_watch.obj; + WRegion *reg=(WRegion*)ph->mplex; if(reg!=NULL){ return reg; @@ -372,24 +359,16 @@ WRegion *mplexpholder_do_target(WMPlexPHolder *ph) } -WPHolder *mplexpholder_do_root(WMPlexPHolder *ph) +bool mplexpholder_stale(WMPlexPHolder *ph) { - WRegion *reg=(WRegion*)ph->mplex_watch.obj; + WRegion *reg=(WRegion*)ph->mplex; if(reg!=NULL){ - return &ph->ph; + return FALSE; }else{ WFramedPHolder *fph=get_recreate_ph(ph); - WPHolder *root; - if(fph==NULL) - return NULL; - - root=pholder_root((WPHolder*)fph); - - return (root!=(WPHolder*)fph - ? root - : &ph->ph); + return (fph==NULL || pholder_stale((WPHolder*)fph)); } } @@ -427,7 +406,7 @@ void mplex_move_phs_before(WMPlex *mplex, WLListNode *node) after=(or_after!=NULL ? LIST_LAST(or_after->phs, next, prev) - : LIST_LAST(mplex->mx_phs, next, prev)); + : LIST_LAST(mplex->misc_phs, next, prev)); mplex_move_phs(mplex, node, after, or_after); } @@ -444,6 +423,33 @@ WMPlexPHolder *mplex_managed_get_pholder(WMPlex *mplex, WRegion *mgd) } +void mplex_flatten_phs(WMPlex *mplex) +{ + WLListNode *node; + WLListIterTmp tmp; + + FOR_ALL_NODES_ON_LLIST(node, mplex->mx_list, tmp){ + WMPlexPHolder *last=(mplex->misc_phs==NULL ? NULL : mplex->misc_phs->prev); + mplex_move_phs(mplex, node, last, NULL); + } +} + + +void mplex_migrate_phs(WMPlex *src, WMPlex *dst) +{ + WLListNode *or_after=LIST_LAST(dst->mx_list, next, prev); + WMPlexPHolder *after=(or_after!=NULL + ? LIST_LAST(or_after->phs, next, prev) + : LIST_LAST(dst->misc_phs, next, prev)); + + while(src->misc_phs!=NULL){ + WMPlexPHolder *ph=src->misc_phs; + mplexpholder_move(ph, dst, after, or_after); + after=ph; + } +} + + /*}}}*/ @@ -508,8 +514,8 @@ static DynFunTab mplexpholder_dynfuntab[]={ {(DynFun*)pholder_do_target, (DynFun*)mplexpholder_do_target}, - {(DynFun*)pholder_do_root, - (DynFun*)mplexpholder_do_root}, + {(DynFun*)pholder_stale, + (DynFun*)mplexpholder_stale}, END_DYNFUNTAB };