X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=ioncore%2Fframe.c;h=4f82aa4fa951a37b7b0d6601a569a542f5c811e9;hp=6937b3d21b27b20d70c234b21c20de07f9527d30;hb=HEAD;hpb=a91cc07e7f876e79a733f25c266073c0b9afda1d diff --git a/ioncore/frame.c b/ioncore/frame.c index 6937b3d..4f82aa4 100644 --- a/ioncore/frame.c +++ b/ioncore/frame.c @@ -1,7 +1,7 @@ /* * ion/ioncore/frame.c * - * Copyright (c) Tuomo Valkonen 1999-2007. + * Copyright (c) Tuomo Valkonen 1999-2009. * * See the included file LICENSE for details. */ @@ -50,11 +50,32 @@ static void frame_add_mode_bindmaps(WFrame *frame); WHook *frame_managed_changed_hook=NULL; -#define IS_FLOATING_MODE(FRAME) \ - ((FRAME)->mode==FRAME_MODE_FLOATING || (FRAME)->mode==FRAME_MODE_TRANSIENT) -#define FORWARD_CWIN_RQGEOM(FRAME) IS_FLOATING_MODE(FRAME) -#define USE_MINMAX(FRAME) IS_FLOATING_MODE(FRAME) -#define DEST_EMPTY(FRAME) IS_FLOATING_MODE(FRAME) +#define FORWARD_CWIN_RQGEOM(FRAME) framemode_is_floating(frame_mode(FRAME)) +#define USE_MINMAX(FRAME) framemode_is_floating(frame_mode(FRAME)) +#define DEST_EMPTY(FRAME) framemode_is_floating(frame_mode(FRAME)) + + +WFrameMode framemode_unalt(WFrameMode mode) +{ + if(mode==FRAME_MODE_UNKNOWN_ALT) + return FRAME_MODE_UNKNOWN; + else if(mode==FRAME_MODE_TILED_ALT) + return FRAME_MODE_TILED; + else if(mode==FRAME_MODE_FLOATING_ALT) + return FRAME_MODE_FLOATING; + else if(mode==FRAME_MODE_TRANSIENT_ALT) + return FRAME_MODE_TRANSIENT; + else + return mode; +} + + +static WFrameMode framemode_is_floating(WFrameMode mode) +{ + WFrameMode modea=framemode_unalt(mode); + + return (modea==FRAME_MODE_FLOATING || modea==FRAME_MODE_TRANSIENT); +} /*{{{ Destroy/create frame */ @@ -81,7 +102,6 @@ bool frame_init(WFrame *frame, WWindow *parent, const WFitParams *fp, frame->mode=mode; frame->tab_min_w=0; frame->bar_max_width_q=1.0; - frame->quasiact_source=NULL; gr_stylespec_init(&frame->baseattr); @@ -130,13 +150,13 @@ void frame_deinit(WFrame *frame) static void frame_add_mode_bindmaps(WFrame *frame) { - WFrameMode mode=frame->mode; + WFrameMode modea=framemode_unalt(frame->mode); - if(mode==FRAME_MODE_FLOATING){ + if(modea==FRAME_MODE_FLOATING){ region_add_bindmap((WRegion*)frame, ioncore_mplex_toplevel_bindmap); region_add_bindmap((WRegion*)frame, ioncore_frame_toplevel_bindmap); region_add_bindmap((WRegion*)frame, ioncore_frame_floating_bindmap); - }else if(mode==FRAME_MODE_TRANSIENT){ + }else if(modea==FRAME_MODE_TRANSIENT){ region_add_bindmap((WRegion*)frame, ioncore_frame_transient_bindmap); region_add_bindmap((WRegion*)frame, ioncore_frame_floating_bindmap); }else{ @@ -164,14 +184,10 @@ void frame_set_mode(WFrame *frame, WFrameMode mode) region_remove_bindmap((WRegion*)frame, ioncore_frame_transient_bindmap); frame->mode=mode; - - frame_add_mode_bindmaps(frame); - frame_initialise_gr(frame); + frame_add_mode_bindmaps(frame); - mplex_fit_managed(&frame->mplex); - frame_recalc_bar(frame); - frame_set_background(frame, TRUE); + frame_updategr(frame); } @@ -181,12 +197,15 @@ WFrameMode frame_mode(WFrame *frame) } -StringIntMap frame_modes[]={ +static StringIntMap frame_modes[]={ {"unknown", FRAME_MODE_UNKNOWN}, + {"unknown-alt", FRAME_MODE_UNKNOWN_ALT}, {"tiled", FRAME_MODE_TILED}, {"tiled-alt", FRAME_MODE_TILED_ALT}, {"floating", FRAME_MODE_FLOATING}, + {"floating-alt", FRAME_MODE_FLOATING_ALT}, {"transient", FRAME_MODE_TRANSIENT}, + {"transient-alt", FRAME_MODE_TRANSIENT_ALT}, END_STRINGINTMAP }; @@ -203,7 +222,9 @@ const char *frame_mode_extl(WFrame *frame) /*EXTL_DOC - * Set frame mode. + * Set frame mode (one of + * \codestr{unknown}, \codestr{tiled}, \codestr{floating}, \codestr{transient}, + * or any of these suffixed with \codestr{-alt}). */ EXTL_EXPORT_AS(WFrame, set_mode) bool frame_set_mode_extl(WFrame *frame, const char *modestr) @@ -386,7 +407,7 @@ static bool frame_initialise_titles(WFrame *frame) } } - frame_recalc_bar(frame); + frame_recalc_bar(frame, FALSE); return TRUE; } @@ -406,7 +427,8 @@ bool frame_fitrep(WFrame *frame, WWindow *par, const WFitParams *fp) old_geom=REGION_GEOM(frame); - window_do_fitrep(&(frame->mplex.win), par, &(fp->g)); + if(!window_fitrep(&(frame->mplex.win), par, fp)) + return FALSE; mplex_managed_geom((WMPlex*)frame, &mg); @@ -453,36 +475,36 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret) woff=maxof(REGION_GEOM(frame).w-subgeom.w, 0); hoff=maxof(REGION_GEOM(frame).h-subgeom.h, 0); - if(FRAME_CURRENT(frame)!=NULL){ + if(FRAME_CURRENT(frame)!=NULL) region_size_hints(FRAME_CURRENT(frame), hints_ret); - if(!USE_MINMAX(frame)){ - hints_ret->max_set=0; - hints_ret->min_set=0; - /*hints_ret->base_set=0;*/ - hints_ret->aspect_set=0; - hints_ret->no_constrain=FALSE; - /*hints_ret->no_constrain=TRUE;*/ - } - }else{ + else sizehints_clear(hints_ret); - } FRAME_MX_FOR_ALL(sub, frame, tmp){ sizehints_adjust_for(hints_ret, sub); } - if(!hints_ret->base_set){ - hints_ret->base_width=0; - hints_ret->base_height=0; - hints_ret->base_set=TRUE; + if(!USE_MINMAX(frame)){ + hints_ret->max_set=0; + hints_ret->min_set=0; + /*hints_ret->base_set=0;*/ + hints_ret->aspect_set=0; + hints_ret->no_constrain=FALSE; + /*hints_ret->no_constrain=TRUE;*/ } - + if(!hints_ret->min_set){ hints_ret->min_width=0; hints_ret->min_height=0; hints_ret->min_set=TRUE; } + if(!hints_ret->base_set){ + hints_ret->base_width=0; + hints_ret->base_height=0; + hints_ret->base_set=TRUE; + } + hints_ret->base_width+=woff; hints_ret->base_height+=hoff; hints_ret->max_width+=woff; @@ -490,13 +512,14 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret) hints_ret->min_width+=woff; hints_ret->min_height+=hoff; - if(frame->barmode==FRAME_BAR_SHAPED){ + /* shaded */ { int f=frame->flags&(FRAME_SHADED|FRAME_SHADED_TOGGLE); if(f==FRAME_SHADED || f==FRAME_SHADED_TOGGLE){ - hints_ret->min_height=frame->bar_h; - hints_ret->max_height=frame->bar_h; - hints_ret->base_height=frame->bar_h; + int h=frame_shaded_height(frame); + hints_ret->min_height=h; + hints_ret->max_height=h; + hints_ret->base_height=h; if(!hints_ret->max_set){ hints_ret->max_width=INT_MAX; hints_ret->max_set=TRUE; @@ -509,97 +532,6 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret) /*}}}*/ -/*{{{ Focus */ - - -static void frame_quasiactivation(WFrame *frame, Obj *src, bool act) -{ - if(frame->quasiact_source==src || act){ - bool was, is; - - was=(frame->quasiact_source!=NULL); - - frame->quasiact_source=(act ? src : NULL); - - is=(frame->quasiact_source!=NULL); - - if(was!=is){ - frame_quasiactivity_change(frame); - if(!REGION_IS_ACTIVE(frame)) - window_draw((WWindow*)frame, FALSE); - } - } -} - - -static bool actinact(WRegion *reg, bool act) -{ - WPHolder *returnph=region_get_return(reg); - WFrame *frame=NULL; - Obj *src=NULL; - WRegion *tgt; - - if(returnph==NULL || pholder_stale(returnph)) - return FALSE; - - tgt=pholder_target(returnph); - - frame=OBJ_CAST(tgt, WFrame); - - if(frame!=NULL){ - src=(Obj*)returnph; - }else{ - /* Show quasiactivation for stuff detached from - * groups contained in the frame as well. - */ - WGroup *grp=OBJ_CAST(tgt, WGroup); - if(grp!=NULL){ - frame=REGION_MANAGER_CHK(grp, WFrame); - src=(Obj*)grp; - } - } - - if(frame!=NULL) - frame_quasiactivation(frame, src, act); - - return TRUE; -} - - -static bool activated(WRegion *reg) -{ - return actinact(reg, TRUE); -} - - -static bool inactivated(WRegion *reg) -{ - return actinact(reg, FALSE); -} - - -void ioncore_frame_quasiactivation_notify(WRegion *reg, - WRegionNotify how) -{ - if(how==ioncore_g.notifies.activated || - how==ioncore_g.notifies.pseudoactivated){ - activated(reg); - }else if(how==ioncore_g.notifies.inactivated || - how==ioncore_g.notifies.pseudoinactivated){ - inactivated(reg); - }else if(how==ioncore_g.notifies.set_return){ - if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg)) - activated(reg); - }else if(how==ioncore_g.notifies.unset_return){ - if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg)) - inactivated(reg); - } -} - - -/*}}}*/ - - /*{{{ Client window rqgeom */ @@ -669,75 +601,78 @@ static void frame_managed_rqgeom_absolute(WFrame *frame, WRegion *sub, /*{{{ Frame recreate pholder stuff */ -static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame) +static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame, WPHolder *rph) { - WPHolder *ph; - WFramedPHolder *fph; WFramedParam fparam=FRAMEDPARAM_INIT; + WFramedPHolder *fph=NULL; - ph=region_make_return_pholder((WRegion*)frame); - - if(ph==NULL){ - return NULL; - } - - fparam.mode=frame->mode; + if(rph!=NULL){ + fparam.mode=frame->mode; - fph=create_framedpholder(ph, &fparam); + fph=create_framedpholder(rph, &fparam); - if(fph==NULL){ - destroy_obj((Obj*)ph); - return NULL; + if(fph==NULL) + destroy_obj((Obj*)rph); } return fph; } -static void mplex_flatten_phs(WMPlex *mplex) +static void mplex_migrate_phs_to_fph(WMPlex *mplex, WFramedPHolder *fph) { - WLListNode *node; - WLListIterTmp tmp; - - FOR_ALL_NODES_ON_LLIST(node, mplex->mx_list, tmp){ - WMPlexPHolder *last=(mplex->mx_phs==NULL ? NULL : mplex->mx_phs->prev); - mplex_move_phs(mplex, node, last, NULL); - } -} - - -static void frame_modify_pholders(WFrame *frame) -{ - WFramedPHolder *fph; WMPlexPHolder *phs, *ph; - mplex_flatten_phs(&frame->mplex); - - if(frame->mplex.mx_phs==NULL) - return; - - fph=frame_make_recreate_pholder(frame); - - if(fph==NULL) - return; - - phs=frame->mplex.mx_phs; - frame->mplex.mx_phs=NULL; + phs=mplex->misc_phs; + mplex->misc_phs=NULL; phs->recreate_pholder=fph; for(ph=phs; ph!=NULL; ph=ph->next) - watch_reset(&ph->mplex_watch); + ph->mplex=NULL; } + bool frame_rescue_clientwins(WFrame *frame, WRescueInfo *info) { - frame_modify_pholders(frame); - return mplex_rescue_clientwins(&frame->mplex, info); + bool ret; + + ret=mplex_rescue_clientwins(&frame->mplex, info); + + /* Now, do placeholders. + * We can't currently be arsed to keep them ordered with regions... + * First we check if we can simply recreate this frame, which takes + * care of e.g. floating frames being destroyed when entering full + * screen mode. If not, we check if the target would be a WMPlex, and + * migrate there. This takes care of frames destroyed in tilings. + */ + mplex_flatten_phs(&frame->mplex); + + if(frame->mplex.misc_phs!=NULL){ + WPHolder *ret_ph=region_make_return_pholder((WRegion*)frame); + WFramedPHolder *fph=frame_make_recreate_pholder(frame, ret_ph); + + if(fph!=NULL){ + mplex_migrate_phs_to_fph(&frame->mplex, fph); + }else{ + WPHolder *rescueph=rescueinfo_pholder(info); + if(rescueph!=NULL){ + WRegion *target=pholder_target(rescueph); + WMPlex *other_mplex=OBJ_CAST(target, WMPlex); + + if(other_mplex!=NULL){ + assert(other_mplex!=&frame->mplex); + mplex_migrate_phs(&frame->mplex, other_mplex); + } + } + } + } + + return ret; } - + /*}}}*/ @@ -763,17 +698,9 @@ bool frame_set_shaded(WFrame *frame, int sp) return FALSE; rq.geom.h=frame->saved_h; }else{ - if(frame->barmode==FRAME_BAR_NONE){ + if(frame->barmode==FRAME_BAR_NONE) return FALSE; - }else if(frame->barmode==FRAME_BAR_SHAPED){ - rq.geom.h=frame->bar_h; - }else{ - WRectangle tmp; - - frame_border_inner_geom(frame, &tmp); - - rq.geom.h=rq.geom.h-tmp.h; - } + rq.geom.h=frame_shaded_height(frame); } frame->flags|=FRAME_SHADED_TOGGLE; @@ -868,7 +795,7 @@ void frame_managed_notify(WFrame *frame, WRegion *sub, WRegionNotify how) how==ioncore_g.notifies.tag){ frame_update_attrs(frame); - frame_recalc_bar(frame); + frame_recalc_bar(frame, FALSE); frame_draw_bar(frame, FALSE); } } @@ -880,7 +807,7 @@ static void frame_size_changed_default(WFrame *frame, int bar_w=frame->bar_w; if(wchg) - frame_recalc_bar(frame); + frame_recalc_bar(frame, TRUE); if(frame->barmode==FRAME_BAR_SHAPED && ((!wchg && hchg) || (wchg && bar_w==frame->bar_w))){ @@ -894,14 +821,6 @@ static void frame_managed_changed(WFrame *frame, int mode, bool sw, { bool need_draw=TRUE; - if(mode==MPLEX_CHANGE_REMOVE && (Obj*)reg==frame->quasiact_source){ - /* Reset indirect quasiactivation through group that - * is being removed. - */ - frame->quasiact_source=NULL; - frame_quasiactivity_change(frame); - } - if(mode!=MPLEX_CHANGE_SWITCHONLY) frame_initialise_titles(frame); else @@ -953,7 +872,7 @@ WPHolder *frame_prepare_manage_transient(WFrame *frame, /* Transient manager searches should not cross tiled frames * unless explicitly floated. */ - if(IS_FLOATING_MODE(frame) || + if(framemode_is_floating(frame_mode(frame)) || extl_table_is_bool_set(transient->proptab, "float")){ return region_prepare_manage_transient_default((WRegion*)frame, transient, @@ -1020,7 +939,13 @@ WRegion *frame_load(WWindow *par, const WFitParams *fp, ExtlTab tab) int mode=FRAME_MODE_UNKNOWN; WFrame *frame; - extl_table_gets_i(tab, "mode", &mode); + if(!extl_table_gets_i(tab, "mode", &mode)){ + char *tmp; + if(extl_table_gets_s(tab, "mode", &tmp)){ + mode=stringintmap_value(frame_modes, tmp, mode); + free(tmp); + } + } frame=create_frame(par, fp, mode); @@ -1028,6 +953,14 @@ WRegion *frame_load(WWindow *par, const WFitParams *fp, ExtlTab tab) frame_do_load(frame, tab); if(DEST_EMPTY(frame) && frame->mplex.mgd==NULL){ + if(frame->mplex.misc_phs!=NULL){ + /* Session management hack */ + WFramedPHolder *fph; + fph=frame_make_recreate_pholder(frame, ioncore_get_load_pholder()); + if(fph!=NULL) + mplex_migrate_phs_to_fph(&frame->mplex, fph); + } + destroy_obj((Obj*)frame); return NULL; }