X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=ioncore%2Fframe.c;h=f85a29624e04ffcb2ecd2fa7239a000b89e3ca2d;hb=720e6978185b09f2b2f60a6b96018238085a7238;hp=f0e786e77cdc1560e4dd5b92de6bac8a0e0d8efd;hpb=de22e45179cb3bafa490294d31d47f361047a30a;p=ion3.git diff --git a/ioncore/frame.c b/ioncore/frame.c index f0e786e..f85a296 100644 --- a/ioncore/frame.c +++ b/ioncore/frame.c @@ -3,10 +3,7 @@ * * Copyright (c) Tuomo Valkonen 1999-2007. * - * Ion is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. + * See the included file LICENSE for details. */ #include @@ -53,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 */ @@ -84,6 +102,9 @@ 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); if(!mplex_init((WMPlex*)frame, parent, fp)) return FALSE; @@ -117,6 +138,7 @@ void frame_deinit(WFrame *frame) { frame_free_titles(frame); frame_release_brushes(frame); + gr_stylespec_unalloc(&frame->baseattr); mplex_deinit((WMPlex*)frame); } @@ -129,13 +151,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{ @@ -169,7 +191,7 @@ void frame_set_mode(WFrame *frame, WFrameMode mode) frame_initialise_gr(frame); mplex_fit_managed(&frame->mplex); - frame_recalc_bar(frame); + frame_recalc_bar(frame, TRUE); frame_set_background(frame, TRUE); } @@ -180,12 +202,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 }; @@ -202,7 +227,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) @@ -385,7 +412,7 @@ static bool frame_initialise_titles(WFrame *frame) } } - frame_recalc_bar(frame); + frame_recalc_bar(frame, FALSE); return TRUE; } @@ -452,36 +479,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; @@ -511,51 +538,56 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret) /*{{{ Focus */ -void frame_inactivated(WFrame *frame) +static void frame_quasiactivation(WFrame *frame, Obj *src, bool act) { - window_draw((WWindow*)frame, FALSE); -} - - -void frame_activated(WFrame *frame) -{ - window_draw((WWindow*)frame, FALSE); -} - - -void frame_quasiactivation(WFrame *frame, WRegion *reg, bool act) -{ - bool was, is; - - was=(frame->quasiactive_count>0); + if(frame->quasiact_source==src || act){ + bool was, is; + + was=(frame->quasiact_source!=NULL); - frame->quasiactive_count=maxof(0, frame->quasiactive_count - + (act ? 1 : -1)); - - is=(frame->quasiactive_count>0); + frame->quasiact_source=(act ? src : NULL); - if(was!=is && !REGION_IS_ACTIVE(frame)) - window_draw((WWindow*)frame, FALSE); + 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; + WFrame *frame=NULL; + Obj *src=NULL; + WRegion *tgt; if(returnph==NULL || pholder_stale(returnph)) return FALSE; - frame=OBJ_CAST(pholder_target(returnph), WFrame); + tgt=pholder_target(returnph); + + frame=OBJ_CAST(tgt, WFrame); if(frame!=NULL){ - /* Ok, reg has return placeholder set to a frame: - * do quasiactivation/inactivation + src=(Obj*)returnph; + }else{ + /* Show quasiactivation for stuff detached from + * groups contained in the frame as well. */ - frame_quasiactivation(frame, reg, act); + 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; } @@ -671,9 +703,10 @@ static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame) ph=region_make_return_pholder((WRegion*)frame); - if(ph==NULL) + if(ph==NULL){ return NULL; - + } + fparam.mode=frame->mode; fph=create_framedpholder(ph, &fparam); @@ -724,6 +757,13 @@ static void frame_modify_pholders(WFrame *frame) } +bool frame_rescue_clientwins(WFrame *frame, WRescueInfo *info) +{ + frame_modify_pholders(frame); + return mplex_rescue_clientwins(&frame->mplex, info); +} + + /*}}}*/ @@ -774,7 +814,8 @@ bool frame_set_shaded(WFrame *frame, int sp) /*EXTL_DOC * Set shading state according to the parameter \var{how} - * (set/unset/toggle). Resulting state is returned, which may not be + * (\codestr{set}, \codestr{unset}, or \codestr{toggle}). + * Resulting state is returned, which may not be * what was requested. */ EXTL_EXPORT_AS(WFrame, set_shaded) @@ -795,39 +836,51 @@ bool frame_is_shaded(WFrame *frame) } -bool frame_set_numbers(WFrame *frame, int sp) +/* EXTL_DOC + * Is the attribute \var{attr} set? + */ +bool frame_is_grattr(WFrame *frame, const char *attr) { - bool set=frame->flags&FRAME_SHOW_NUMBERS; - bool nset=libtu_do_setparam(sp, set); - - if(XOR(nset, set)){ - frame->flags^=FRAME_SHOW_NUMBERS; - frame_recalc_bar(frame); - frame_draw_bar(frame, TRUE); - } - - return frame->flags&FRAME_SHOW_NUMBERS; + GrAttr a=stringstore_alloc(attr); + bool set=gr_stylespec_isset(&frame->baseattr, a); + stringstore_free(a); + return set; } -/*EXTL_DOC - * Control whether tabs show numbers (set/unset/toggle). - * Resulting state is returned, which may not be what was - * requested. - */ -EXTL_EXPORT_AS(WFrame, set_numbers) -bool frame_set_numbers_extl(WFrame *frame, const char *how) +bool frame_set_grattr(WFrame *frame, GrAttr a, int sp) { - return frame_set_numbers(frame, libtu_string_to_setparam(how)); + bool set=gr_stylespec_isset(&frame->baseattr, a); + bool nset=libtu_do_setparam(sp, set); + + if(XOR(set, nset)){ + if(nset) + gr_stylespec_set(&frame->baseattr, a); + else + gr_stylespec_unset(&frame->baseattr, a); + window_draw((WWindow*)frame, TRUE); + } + + return nset; } /*EXTL_DOC - * Does \var{frame} show numbers for tabs? + * Set extra drawing engine attributes for the frame. + * The parameter \var{attr} is the attribute, and \var{how} is + * one of \codestr{set}, \codestr{unset}, or \codestr{toggle}. */ -bool frame_is_numbers(WFrame *frame) +EXTL_EXPORT_AS(WFrame, set_grattr) +bool frame_set_grattr_extl(WFrame *frame, const char *attr, const char *how) { - return frame->flags&FRAME_SHOW_NUMBERS; + if(attr!=NULL){ + GrAttr a=stringstore_alloc(attr); + bool ret=frame_set_grattr(frame, a, libtu_string_to_setparam(how)); + stringstore_free(a); + return ret; + }else{ + return FALSE; + } } @@ -841,7 +894,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); } } @@ -853,7 +906,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))){ @@ -867,6 +920,14 @@ 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 @@ -889,7 +950,7 @@ WRegion *frame_managed_disposeroot(WFrame *frame, WRegion *reg) if(DEST_EMPTY(frame) && frame->mplex.mgd!=NULL && frame->mplex.mgd->reg==reg && - frame->mplex.mgd->next==NULL){ + frame->mplex.mgd->mgr_next==NULL){ WRegion *tmp=region_disposeroot((WRegion*)frame); return (tmp!=NULL ? tmp : reg); } @@ -907,6 +968,32 @@ int frame_default_index(WFrame *frame) /*}}}*/ +/*{{{ prepare_manage_transient */ + + +WPHolder *frame_prepare_manage_transient(WFrame *frame, + const WClientWin *transient, + const WManageParams *param, + int unused) +{ + /* Transient manager searches should not cross tiled frames + * unless explicitly floated. + */ + if(framemode_is_floating(frame_mode(frame)) || + extl_table_is_bool_set(transient->proptab, "float")){ + return region_prepare_manage_transient_default((WRegion*)frame, + transient, + param, + unused); + }else{ + return NULL; + } +} + + +/*}}}*/ + + /*{{{ Save/load */ @@ -1016,6 +1103,12 @@ static DynFunTab frame_dynfuntab[]={ {(DynFun*)mplex_default_index, (DynFun*)frame_default_index}, + + {(DynFun*)region_prepare_manage_transient, + (DynFun*)frame_prepare_manage_transient}, + + {(DynFun*)region_rescue_clientwins, + (DynFun*)frame_rescue_clientwins}, END_DYNFUNTAB };