/*
* ion/ioncore/frame.c
*
- * Copyright (c) Tuomo Valkonen 1999-2007.
+ * Copyright (c) Tuomo Valkonen 1999-2008.
*
* See the included file LICENSE for details.
*/
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 */
frame->mode=mode;
frame->tab_min_w=0;
frame->bar_max_width_q=1.0;
- frame->quasiact_source=NULL;
gr_stylespec_init(&frame->baseattr);
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{
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);
}
}
-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
};
/*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)
}
}
- frame_recalc_bar(frame);
+ frame_recalc_bar(frame, FALSE);
return TRUE;
}
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);
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;
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;
/*}}}*/
-/*{{{ 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 */
/*{{{ 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;
}
-
+
/*}}}*/
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;
how==ioncore_g.notifies.tag){
frame_update_attrs(frame);
- frame_recalc_bar(frame);
+ frame_recalc_bar(frame, FALSE);
frame_draw_bar(frame, FALSE);
}
}
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))){
{
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
/* 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,
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);
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;
}