/*
* ion/ioncore/mplex.c
*
- * Copyright (c) Tuomo Valkonen 1999-2007.
+ * Copyright (c) Tuomo Valkonen 1999-2008.
*
- * 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 <limits.h>
#include "saveload.h"
#include "xwindow.h"
#include "mplexpholder.h"
+#include "grouppholder.h"
#include "llist.h"
#include "names.h"
#include "sizepolicy.h"
#include "stacking.h"
#include "group.h"
#include "navi.h"
-#include "groupedpholder.h"
#define SUBS_MAY_BE_MAPPED(MPLEX) \
mplex->mx_list=NULL;
mplex->mx_current=NULL;
- mplex->mx_phs=NULL;
+ mplex->misc_phs=NULL;
mplex->mx_count=0;
mplex->mgd=NULL;
assert(mplex->mgd==NULL);
assert(mplex->mx_list==NULL);
- while(mplex->mx_phs!=NULL){
- assert(mplexpholder_move(mplex->mx_phs, NULL, NULL, NULL));
+ while(mplex->misc_phs!=NULL){
+ assert(mplexpholder_move(mplex->misc_phs, NULL, NULL, NULL));
}
window_deinit((WWindow*)mplex);
/*EXTL_DOC
- * Returns the \var{n}:th object managed by \var{mplex} on the
- * \var{l}:th layer.
+ * Returns the \var{n}:th object on the mutually exclusive
+ * list of \var{mplex}.
*/
EXTL_SAFE
EXTL_EXPORT_MEMBER
/*EXTL_DOC
* Iterate over numbered/mutually exclusive region list of \var{mplex}
* until \var{iterfn} returns \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
* without this happening.
*/
EXTL_SAFE
/*EXTL_DOC
* Iterate over managed regions of \var{mplex} until \var{iterfn} returns
* \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
* without this happening.
*/
EXTL_SAFE
/*EXTL_DOC
- * Move \var{r} ''right'' within objects managed by \var{mplex} on list 1.
+ * Move \var{r} ``right'' within objects managed by \var{mplex} on list 1.
*/
EXTL_EXPORT_MEMBER
void mplex_inc_index(WMPlex *mplex, WRegion *r)
/*EXTL_DOC
- * Move \var{r} ''right'' within objects managed by \var{mplex} on list 1.
+ * Move \var{r} ``left'' within objects managed by \var{mplex} on list 1.
*/
EXTL_EXPORT_MEMBER
void mplex_dec_index(WMPlex *mplex, WRegion *r)
bool wchg=(REGION_GEOM(mplex).w!=fp->g.w);
bool hchg=(REGION_GEOM(mplex).h!=fp->g.h);
- window_do_fitrep(&(mplex->win), par, &(fp->g));
+ if(!window_fitrep(&(mplex->win), par, fp))
+ return FALSE;
if(wchg || hchg){
mplex_fit_managed(mplex);
node=mplex_find_stacking(mplex, sub);
assert(node!=NULL);
-
+
+ fp.mode=0;
mplex_managed_geom(mplex, &fp.g);
-
+
sizepolicy(&node->szplcy, sub, &rq->geom, rq->flags, &fp);
if(geomret!=NULL)
}
+void mplex_set_szplcy(WMPlex *mplex, WRegion *sub, WSizePolicy szplcy)
+{
+ WStacking *node;
+
+ node=mplex_find_stacking(mplex, sub);
+
+ if(node!=NULL)
+ node->szplcy=szplcy;
+}
+
+
+WSizePolicy mplex_get_szplcy(WMPlex *mplex, WRegion *sub)
+{
+ WStacking *node;
+
+ node=mplex_find_stacking(mplex, sub);
+
+ return (node==NULL ? SIZEPOLICY_DEFAULT : node->szplcy);
+}
+
+
/*}}}*/
/*{{{ Focus */
-static WStacking *mplex_do_to_focus(WMPlex *mplex, WStacking *to_try)
+typedef struct{
+ WMPlex *mplex;
+ WStacking *to_try;
+ WStacking *group_st;
+ PtrList **hidelist;
+ bool try_hard;
+} FiltData;
+
+
+static WRegion *manager_within(WMPlex *mplex, WStacking *st)
{
+ return region_managed_within((WRegion*)mplex, st->reg);
+}
+
+
+static WStacking *stacking_within(WMPlex *mplex, WStacking *st)
+{
+ WRegion *reg=manager_within(mplex, st);
+
+ return (reg==NULL
+ ? NULL
+ : (reg==st->reg
+ ? st
+ : ioncore_find_stacking(reg)));
+}
+
+
+/* Mutually exclusive regions can't be pseudomodal */
+#define IS_PSEUDOMODAL(ST) ((ST)->lnode==NULL && (ST)->pseudomodal)
+
+
+static bool mapped_pseudomodal_include_filt(WStacking *st, void *data_)
+{
+ FiltData *data=(FiltData*)data_;
+ WStacking *stw;
+
+ if(st->reg==NULL || !REGION_IS_MAPPED(st->reg))
+ return FALSE;
+
+ if(!data->hidelist
+ || (data->to_try==NULL && data->group_st==NULL)
+ || st->level<STACKING_LEVEL_MODAL1){
+ return TRUE;
+ }
+
+ /* Ok, modal node in the way. Let's see if it is pseudomodal
+ * and can be hidden.
+ */
+
+ stw=stacking_within(data->mplex, st);
+
+ /* This should not happen */
+ if(stw==NULL || stw->reg==NULL)
+ return FALSE;
+
+ /* The node is within the same group, so it can not be hidden.
+ * Latter case should not happen.
+ */
+ if(stw==data->group_st || stw==data->to_try)
+ return TRUE;
+
+ if(IS_PSEUDOMODAL(stw)){
+ /* Don't insert multiple times. */
+ return !ptrlist_reinsert_first(data->hidelist, stw);
+ }
+
+ return TRUE;
+}
+
+
+static bool mgr_pseudomodal_approve_filt(WStacking *st, void *data_)
+{
+ FiltData *data=(FiltData*)data_;
+
+ return (data->group_st==NULL || st==data->group_st ||
+ manager_within(data->mplex, st)==data->group_st->reg);
+}
+
+
+WStacking *mplex_find_to_focus(WMPlex *mplex,
+ WStacking *to_try,
+ WStacking *group_st,
+ PtrList **hidelist)
+{
+ WStackingFilter *fi=mapped_pseudomodal_include_filt;
+ WStackingFilter *fa=mgr_pseudomodal_approve_filt;
WStacking *stacking=mplex_get_stacking(mplex);
- WStacking *st=NULL;
+ FiltData data;
+ WStacking *st;
if(stacking==NULL)
return NULL;
-
+
if(to_try!=NULL && (to_try->reg==NULL || !REGION_IS_MAPPED(to_try->reg)))
to_try=NULL;
+
+ data.mplex=mplex;
+ data.to_try=to_try;
+ data.group_st=group_st;
+ data.hidelist=hidelist;
+
+ st=stacking_find_to_focus(stacking, to_try, fi, fa, &data);
+
+ if(st==NULL && hidelist!=NULL)
+ ptrlist_clear(hidelist);
+
+ return st;
+}
- st=stacking_find_to_focus_mapped(stacking, to_try, NULL);
+
+static WStacking *mplex_do_to_focus(WMPlex *mplex, WStacking *to_try,
+ PtrList **hidelist)
+{
+ return mplex_find_to_focus(mplex, to_try, NULL, hidelist);
+}
+
+
+static WStacking *mplex_do_to_focus_on(WMPlex *mplex, WStacking *node,
+ WStacking *to_try,
+ PtrList **hidelist, bool *within)
+{
+ WGroup *grp=OBJ_CAST(node->reg, WGroup);
+ WStacking *st;
- if(st!=NULL)
- return st;
- else if(mplex->mx_current!=NULL)
- return mplex->mx_current->st;
- else
- return NULL;
+ if(grp!=NULL){
+ if(to_try==NULL)
+ to_try=grp->current_managed;
+ /* Only will return stuff within 'node' */
+ st=mplex_find_to_focus(mplex, to_try, node, hidelist);
+ if(st!=NULL){
+ if(within!=NULL)
+ *within=TRUE;
+ return st;
+ }
+ }
+
+ st=mplex_do_to_focus(mplex, node, hidelist);
+
+ if(st==node && within!=NULL)
+ *within=TRUE;
+
+ return st;
}
}
-static WStacking *stacking_within(WMPlex *mplex, WRegion *reg)
+static WStacking *has_stacking_within(WMPlex *mplex, WRegion *reg)
{
while(reg!=NULL && REGION_MANAGER(reg)!=(WRegion*)mplex)
reg=REGION_MANAGER(reg);
-
+
return maybe_focusable(reg);
}
{
WStacking *to_try=NULL;
WRegion *reg=NULL;
+ WStacking *st;
to_try=maybe_focusable(REGION_ACTIVE_SUB(mplex));
if(to_try==NULL){
/* Search focus history */
for(reg=ioncore_g.focus_current; reg!=NULL; reg=reg->active_next){
- to_try=stacking_within(mplex, reg);
+ to_try=has_stacking_within(mplex, reg);
if(to_try!=NULL)
break;
}
}
- return mplex_do_to_focus(mplex, to_try);
-}
-
-
-static WStacking *mplex_do_to_focus_on(WMPlex *mplex, WStacking *node,
- WStacking *to_try)
-{
- WStacking *stacking=mplex_get_stacking(mplex);
- WStacking *st=NULL;
-
- if(stacking==NULL)
- return NULL;
-
- if(to_try!=NULL && (to_try->reg==NULL || !REGION_IS_MAPPED(to_try->reg)))
- to_try=NULL;
+ st=mplex_do_to_focus(mplex, to_try, NULL);
- return stacking_find_to_focus_mapped(stacking, to_try, node->reg);
-}
-
-
-static WStacking *mplex_to_focus_on(WMPlex *mplex, WStacking *node,
- WStacking *to_try)
-{
- WGroup *grp=OBJ_CAST(node->reg, WGroup);
- WStacking *st;
-
- if(grp!=NULL){
- if(to_try==NULL)
- to_try=grp->current_managed;
- st=mplex_do_to_focus_on(mplex, node, to_try);
- if(st!=NULL || to_try!=NULL)
- return st;
- /* We don't know whether something is blocking focus here,
- * or if there was nothing to focus (as node->reg itself
- * isn't on the stacking list).
- */
- }
-
- st=mplex_do_to_focus(mplex, node);
- return (st==node ? st : NULL);
+ return (st!=NULL
+ ? st
+ : (mplex->mx_current!=NULL
+ ? mplex->mx_current->st
+ : NULL));
}
static bool mplex_refocus(WMPlex *mplex, WStacking *node, bool warp)
{
WStacking *foc=NULL;
- bool ret=TRUE;
+ bool within=FALSE;
- if(node!=NULL){
- foc=mplex_to_focus_on(mplex, node, NULL);
- ret=(foc!=NULL);
- }
+ if(node!=NULL)
+ foc=mplex_do_to_focus_on(mplex, node, NULL, NULL, &within);
- if(foc==NULL){
- ret=FALSE;
+ if(foc==NULL || !within)
foc=mplex_to_focus(mplex);
- }
if(foc!=NULL)
region_maybewarp(foc->reg, warp);
- return ret;
+ return within;
}
WStacking *sub, int flags,
WPrepareFocusResult *res)
{
+ bool ew=(flags®ION_GOTO_ENTERWINDOW);
+ PtrList *hidelist=NULL;
+ PtrList **hidelistp=(ew ? NULL : &hidelist);
WStacking *foc;
+ /*bool within=FALSE;*/
if(sub==NULL && node==NULL)
return FALSE;
/* Display the node in any case */
- if(node!=NULL && !(flags®ION_GOTO_ENTERWINDOW))
+ if(node!=NULL && !ew)
mplex_do_node_display(mplex, node, TRUE);
if(!region_prepare_focus((WRegion*)mplex, flags, res))
return FALSE;
- if(node!=NULL)
- foc=mplex_to_focus_on(mplex, node, sub);
- else
- foc=mplex_do_to_focus(mplex, sub);
+ foc=mplex_do_to_focus_on(mplex, node, sub, hidelistp, NULL /*&within*/);
if(foc!=NULL){
+ while(hidelist!=NULL){
+ WStacking *st=(WStacking*)ptrlist_take_first(&hidelist);
+ st->hidden=TRUE;
+ region_unmap(st->reg);
+ }
+
if(ioncore_g.autoraise &&
!(flags®ION_GOTO_ENTERWINDOW) &&
foc->level>STACKING_LEVEL_BOTTOM){
res->reg=foc->reg;
res->flags=flags;
- if(sub==NULL)
- return (foc==node);
- else
- return (foc==sub);
+ return (foc==sub || (sub==NULL && foc==node));
}else{
return FALSE;
}
/*EXTL_DOC
* Set the visibility of the region \var{reg} on \var{mplex}
- * as specified with the parameter \var{how} (set/unset/toggle).
+ * as specified with the parameter \var{how}
+ * (one of \codestr{set}, \codestr{unset}, or \codestr{toggle}).
* The resulting state is returned.
*/
EXTL_EXPORT_AS(WMPlex, set_hidden)
static bool mplex_stack(WMPlex *mplex, WStacking *st)
{
WStacking *tmp=NULL;
- Window bottom=None, top=None;
WStacking **stackingp=mplex_get_stackingp(mplex);
if(stackingp==NULL)
: SIZEPOLICY_FULL_EXACT));
modal=(param->flags&MPLEX_ATTACH_LEVEL
- ? param->level>=STACKING_LEVEL_MODAL1
- : param->flags&MPLEX_ATTACH_MODAL);
+ && param->level>=STACKING_LEVEL_MODAL1);
level=(param->flags&MPLEX_ATTACH_LEVEL
? param->level
- : (param->flags&MPLEX_ATTACH_MODAL
- ? STACKING_LEVEL_MODAL1
- : (param->flags&MPLEX_ATTACH_UNNUMBERED
- ? STACKING_LEVEL_NORMAL
- : STACKING_LEVEL_BOTTOM)));
+ : (param->flags&MPLEX_ATTACH_UNNUMBERED
+ ? STACKING_LEVEL_NORMAL
+ : STACKING_LEVEL_BOTTOM));
hidden=(param->flags&MPLEX_ATTACH_HIDDEN
&& (param->flags&MPLEX_ATTACH_UNNUMBERED
sw=(!hidden && (param->flags&MPLEX_ATTACH_SWITCHTO
|| (param->flags&MPLEX_ATTACH_UNNUMBERED
- ? modal
+ ? FALSE
: (mplex_current_node(mplex)==NULL))));
hidden=(hidden || (!sw && !(param->flags&MPLEX_ATTACH_UNNUMBERED)));
node->hidden=TRUE;
node->szplcy=szplcy;
node->level=level;
+ node->pseudomodal=(param->flags&MPLEX_ATTACH_PSEUDOMODAL ? 1 : 0);
if(lnode!=NULL){
+ WMPlexPHolder *ph2, *phn, *php;
+
llist_link_after(&(mplex->mx_list),
(ph!=NULL ? ph->after : NULL),
lnode);
mplex->mx_count++;
- /* Move following placeholders after new node */
- while(ph->next!=NULL)
- mplexpholder_move(ph->next, mplex, NULL, lnode);
+
+ /* Move placeholders after new node */
+ for(php=NULL, ph2=ph; ph2!=NULL; php=ph2, ph2=phn){
+ phn=ph2->next;
+ mplexpholder_move(ph2, mplex, php, lnode);
+ }
}
LINK_ITEM(mplex->mgd, node, mgr_next, mgr_prev);
region_set_manager(reg, (WRegion*)mplex);
+ if(param->flags&MPLEX_ATTACH_PASSIVE)
+ reg->flags|=REGION_SKIP_FOCUS;
+
if(!(param->flags&MPLEX_ATTACH_WHATEVER)){
WFitParams fp;
+ fp.mode=0;
mplex_managed_geom(mplex, &(fp.g));
sizepolicy(&node->szplcy, reg,
mplex_do_node_display(mplex, node, FALSE);
else
region_unmap(reg);
-
- if(sw && mcf)
- mplex_refocus(mplex, node, FALSE);
+
+ if(mcf){
+ if(sw){
+ mplex_refocus(mplex, node, FALSE);
+ }else if(!hidden &&
+ (level>=STACKING_LEVEL_MODAL1 || OBJ_IS(reg, WGroup))){
+ /* New modal regions may require focusing, so try to
+ * give focus back to currently active object.
+ * (There seems to be some problem with uncontained
+ * client windows still..)
+ */
+ mplex_refocus(mplex, NULL, FALSE);
+ }else if(!hidden){
+ region_pointer_focus_hack(reg);
+ }
+ }else if(!hidden){
+ region_pointer_focus_hack(reg);
+ }
if(lnode!=NULL)
mplex_managed_changed(mplex, MPLEX_CHANGE_ADD, sw, reg);
}
+static void mplex_attach_fp(WMPlex *mplex, const WMPlexAttachParams *param,
+ WFitParams *fp)
+{
+ if(param->flags&MPLEX_ATTACH_GEOM)
+ fp->g=param->geom;
+ else
+ mplex_managed_geom(mplex, &(fp->g));
+
+ fp->mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS;
+}
+
+
WRegion *mplex_do_attach_pholder(WMPlex *mplex, WMPlexPHolder *ph,
WRegionAttachData *data)
{
- WMPlexAttachParams *param=&(ph->param);
WFitParams fp;
- if(param->flags&MPLEX_ATTACH_GEOM)
- fp.g=param->geom;
- else
- mplex_managed_geom(mplex, &(fp.g));
-
- fp.mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS;
+ mplex_attach_fp(mplex, &ph->param, &fp);
return region_attach_helper((WRegion*)mplex,
(WWindow*)mplex, &fp,
static void get_params(WMPlex *mplex, ExtlTab tab, int mask,
WMPlexAttachParams *par)
{
- int layer=1;
int tmp;
+ char *tmpstr;
int ok=~mask;
- if(extl_table_gets_i(tab, "level", &tmp)){
- if(tmp>=0 && ok&MPLEX_ATTACH_LEVEL){
- par->flags|=MPLEX_ATTACH_LEVEL;
- par->level=tmp;
+ if(ok&MPLEX_ATTACH_LEVEL){
+ if(extl_table_gets_i(tab, "level", &tmp)){
+ if(tmp>=0){
+ par->flags|=MPLEX_ATTACH_LEVEL;
+ par->level=tmp;
+ }
}
- }
- if(extl_table_is_bool_set(tab, "modal"))
- par->flags|=MPLEX_ATTACH_MODAL&ok;
+ if(extl_table_is_bool_set(tab, "modal"))
+ par->level=maxof(par->level, STACKING_LEVEL_MODAL1);
+ }
if(extl_table_is_bool_set(tab, "unnumbered"))
par->flags|=MPLEX_ATTACH_UNNUMBERED&ok;
if(extl_table_is_bool_set(tab, "hidden"))
par->flags|=MPLEX_ATTACH_HIDDEN&ok;
+
+ if(extl_table_is_bool_set(tab, "passive"))
+ par->flags|=MPLEX_ATTACH_PASSIVE&ok;
+
+ if(extl_table_is_bool_set(tab, "pseudomodal"))
+ par->flags|=MPLEX_ATTACH_PSEUDOMODAL&ok;
if(extl_table_gets_i(tab, "index", &(par->index)))
par->flags|=MPLEX_ATTACH_INDEX&ok;
- if(extl_table_gets_i(tab, "sizepolicy", &tmp)){
- if(ok&MPLEX_ATTACH_SIZEPOLICY){
+ if(ok&MPLEX_ATTACH_SIZEPOLICY){
+ if(extl_table_gets_s(tab, "sizepolicy", &tmpstr)){
+ WSizePolicy tmpp;
+ if(string2sizepolicy(tmpstr, &tmpp)){
+ par->flags|=MPLEX_ATTACH_SIZEPOLICY;
+ par->szplcy=tmpp;
+ }
+ free(tmpstr);
+ }else if(extl_table_gets_i(tab, "sizepolicy", &tmp)){
+ /* Backwards compat. numeric version */
par->flags|=MPLEX_ATTACH_SIZEPOLICY;
par->szplcy=tmp;
}
* \var{hidden} & (boolean) Attach hidden, if not prevented
* by e.g. the mutually exclusive list being empty.
* This option overrides \var{switchto}. \\
- * \var{sizepolicy} & (integer) Size policy. \\
+ * \var{passive} & (boolean) Skip in certain focusing operations. \\
+ * \var{pseudomodal} & (boolean) The attached region is ``pseudomodal''
+ * if the stacking level dictates it to be modal.
+ * This means that the region may be hidden to display
+ * regions with lesser stacking levels. \\
+ * \var{sizepolicy} & (string) Size policy; see Section \ref{sec:sizepolicies}. \\
* \var{geom} & (table) Geometry specification. \\
* \end{tabularx}
*
WPHolder *mplex_prepare_manage(WMPlex *mplex, const WClientWin *cwin,
- const WManageParams *param, int redir)
+ const WManageParams *param, int priority)
{
+ int cpriority=MANAGE_PRIORITY_SUB(priority, MANAGE_PRIORITY_NORMAL);
WMPlexAttachParams ap;
WPHolder *ph=NULL;
WMPlexPHolder *mph;
WLListNode *after;
- if(redir==MANAGE_REDIR_STRICT_YES || redir==MANAGE_REDIR_PREFER_YES){
+ /* Check current */ {
WStacking *cur=mplex_current_node(mplex);
if(cur!=NULL){
- ph=region_prepare_manage(cur->reg, cwin, param,
- MANAGE_REDIR_PREFER_YES);
+ ph=region_prepare_manage(cur->reg, cwin, param, cpriority);
if(ph!=NULL)
return ph;
}
if(mplex->mx_current!=NULL && mplex->mx_current->st!=cur){
ph=region_prepare_manage(mplex->mx_current->st->reg,
- cwin, param,
- MANAGE_REDIR_PREFER_YES);
+ cwin, param, cpriority);
if(ph!=NULL)
return ph;
}
}
- if(redir==MANAGE_REDIR_STRICT_YES)
+ if(!MANAGE_PRIORITY_OK(priority, MANAGE_PRIORITY_NORMAL))
return NULL;
ap.flags=((param->switchto ? MPLEX_ATTACH_SWITCHTO : 0)
mph=create_mplexpholder(mplex, NULL, &ap);
if(mph!=NULL){
- WGroupedPHolder *gph=create_groupedpholder((WPHolder*)mph);
- if(gph!=NULL)
+ WGroupPHolder *gph;
+ WGroupAttachParams gp=GROUPATTACHPARAMS_INIT;
+
+ gp.switchto_set=1;
+ gp.switchto=1;
+ gp.bottom=1;
+
+ gph=create_grouppholder(NULL, NULL, &gp);
+
+ if(gph!=NULL){
+ gph->recreate_pholder=(WPHolder*)mph;
return (WPHolder*)gph;
+ }
}
return (WPHolder*)mph;
}
+void mplex_child_removed(WMPlex *mplex, WRegion *sub)
+{
+ if(sub!=NULL && sub==(WRegion*)(mplex->stdispwatch.obj)){
+ watch_reset(&(mplex->stdispwatch));
+ mplex_set_stdisp(mplex, NULL, NULL);
+ }
+}
+
+
+/*}}}*/
+
+
+/*{{{ Rescue */
+
+
bool mplex_rescue_clientwins(WMPlex *mplex, WRescueInfo *info)
{
bool ret1, ret2;
WMPlexIterTmp tmp;
+ WLListIterTmp ltmp;
+ WLListNode *lnode, *was_current=mplex->mx_current;
+
+
+ /* First all mx stuff to move them nicely to another mplex (when that
+ * is the case), switching to the current region in the target if
+ * allowed by ph_flags_mask region_rescue.
+ */
+ FOR_ALL_NODES_ON_LLIST(lnode, mplex->mx_list, ltmp){
+ int sw=(lnode==was_current ? PHOLDER_ATTACH_SWITCHTO : 0);
+ region_do_rescue_this(lnode->st->reg, info, sw);
+ }
+ /* Then the rest (possibly retrying failed mx stuff).
+ */
mplex_iter_init(&tmp, mplex);
ret1=region_rescue_some_clientwins((WRegion*)mplex, info,
(WRegionIterator*)mplex_iter,
}
-
-void mplex_child_removed(WMPlex *mplex, WRegion *sub)
-{
- if(sub!=NULL && sub==(WRegion*)(mplex->stdispwatch.obj)){
- watch_reset(&(mplex->stdispwatch));
- mplex_set_stdisp(mplex, NULL, NULL);
- }
-}
-
-
/*}}}*/
/*{{{ Status display support */
-#ifndef offsetof
-# define offsetof(T,F) ((size_t)((char*)&((T*)0L)->F-(char*)0L))
-#endif
-
-#define STRUCTOF(T, F, FADDR) \
- ((T*)((char*)(FADDR)-offsetof(T, F)))
-
-
-static void stdisp_watch_handler(Watch *watch, Obj *obj)
-{
- /*WMPlex *mplex=STRUCTOF(WMPlex, stdispinfo,
- STRUCTOF(WMPlexSTDispInfo, regwatch, watch));
- WMPlexSTDispInfo *di=&(mplex->stdispinfo);
- WGenWS *ws=OBJ_CAST(REGION_MANAGER(obj), WGenWS);
- *
- if(ioncore_g.opmode!=IONCORE_OPMODE_DEINIT && ws!=NULL)
- genws_unmanage_stdisp(ws, TRUE, FALSE);*/
-}
-
bool mplex_set_stdisp(WMPlex *mplex, WRegion *reg,
const WMPlexSTDispInfo *din)
region_detach_manager(oldstdisp);
}
}else{
- watch_setup(&(mplex->stdispwatch), (Obj*)reg, stdisp_watch_handler);
+ watch_setup(&(mplex->stdispwatch), (Obj*)reg, NULL);
mplex_remanage_stdisp(mplex);
}
*
* \begin{tabularx}{\linewidth}{lX}
* \tabhead{Field & Description}
- * \var{pos} & The corner of the screen to place the status display
- * in. One of \code{tl}, \code{tr}, \var{bl} or \var{br}. \\
- * \var{action} & If this field is set to \code{keep}, \var{corner}
- * and \var{orientation} are changed for the existing
- * status display. If this field is set to \var{remove},
+ * \var{pos} & (string) The corner of the screen to place the status
+ * display in: one of \codestr{tl}, \codestr{tr}, \codestr{bl}
+ * or \codestr{br}. \\
+ * \var{fullsize} & (boolean) Waste all available space. \\
+ * \var{action} & (string) If this field is set to \codestr{keep},
+ * \var{pos} and \var{fullsize} are changed for the existing
+ * status display. If this field is set to \codestr{remove},
* the existing status display is removed. If this
- * field is not set or is set to \code{replace}, a
+ * field is not set or is set to \codestr{replace}, a
* new status display is created and the old, if any,
* removed. \\
* \end{tabularx}
data.type=REGION_ATTACH_LOAD;
data.u.tab=t;
-
+
stdisp=region_attach_helper((WRegion*)mplex,
(WWindow*)mplex, &fp,
do_attach_stdisp, NULL,
if(st!=extl_table_none()){
if(mplex->mx_current!=NULL && node==mplex->mx_current->st)
extl_table_sets_b(st, "switchto", TRUE);
- extl_table_sets_i(st, "sizepolicy", node->szplcy);
+ extl_table_sets_s(st, "sizepolicy",
+ sizepolicy2string(node->szplcy));
extl_table_sets_i(st, "level", node->level);
g=extl_table_from_rectangle(®ION_GEOM(node->reg));
extl_table_sets_t(st, "geom", g);
extl_unref_table(g);
if(STACKING_IS_HIDDEN(node))
extl_table_sets_b(st, "hidden", TRUE);
+ if(STACKING_IS_PSEUDOMODAL(node))
+ extl_table_sets_b(st, "pseudomodal", TRUE);
if(unnumbered)
extl_table_sets_b(st, "unnumbered", TRUE);
}
-static WMPlex *tmp_mplex=NULL;
-static WMPlexAttachParams *tmp_par=NULL;
-
-static WPHolder *pholder_callback()
-{
- assert(tmp_mplex!=NULL);
- return (WPHolder*)create_mplexpholder(tmp_mplex, NULL, tmp_par);
-}
-
-
void mplex_load_contents(WMPlex *mplex, ExtlTab tab)
{
ExtlTab substab, subtab;
n=extl_table_get_n(substab);
for(i=1; i<=n; i++){
if(extl_table_geti_t(substab, i, &subtab)){
- /*mplex_attach_new(mplex, subtab);*/
WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT;
- WRegionAttachData data;
- char *tmp=NULL;
+ WFitParams fp;
+ WPHolder *ph;
get_params(mplex, subtab, 0, &par);
+ mplex_attach_fp(mplex, &par, &fp);
par.flags|=MPLEX_ATTACH_INDEX;
par.index=LLIST_INDEX_LAST;
- tmp_par=∥
- tmp_mplex=mplex;
-
- data.type=REGION_ATTACH_LOAD;
- data.u.tab=subtab;
+ ph=(WPHolder*)create_mplexpholder(mplex, NULL, &par);
- ioncore_set_sm_pholder_callback(pholder_callback);
-
- mplex_do_attach(mplex, &par, &data);
-
- tmp_mplex=NULL;
+ if(ph!=NULL){
+ region_attach_load_helper((WRegion*)mplex, (WWindow*)mplex, &fp,
+ (WRegionDoAttachFn*)mplex_do_attach_final,
+ (void*)ph, subtab, &ph);
+
+ if(ph!=NULL)
+ destroy_obj((Obj*)ph);
+ }
extl_unref_table(subtab);
}