WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin, const WManageParams *param, int UNUSED(unused)) { WGroupAttachParams ap=GROUPATTACHPARAMS_INIT; WFramedParam fp=FRAMEDPARAM_INIT; WPHolder *ph; ap.stack_above=OBJ_CAST(REGION_PARENT(param->tfor), WRegion); if(ap.stack_above==NULL) return NULL; fp.inner_geom_gravity_set=TRUE; fp.inner_geom=param->geom; fp.gravity=param->gravity; fp.mode=FRAME_MODE_TRANSIENT; groupattachparams_get(&ap, cwin->proptab, "attach_params"); if(!ap.geom_weak_set || param->userpos || !param->maprq || ioncore_g.opmode==IONCORE_OPMODE_INIT){ ap.geom_weak_set=1; ap.geom_weak=0; } ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap); return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph); }
static void dock_get_pos_grow(WDock *dock, int *pos, int *grow) { WMPlex *mplex=OBJ_CAST(REGION_PARENT(dock), WMPlex); WRegion *mplex_stdisp; WMPlexSTDispInfo din; if(mplex!=NULL){ mplex_get_stdisp(mplex, &mplex_stdisp, &din); if(mplex_stdisp==(WRegion*)dock){ /* Ok, we're assigned as a status display for mplex, so * get parameters from there. */ *pos=((din.pos==MPLEX_STDISP_TL || din.pos==MPLEX_STDISP_BL) ? DOCK_HPOS_LEFT : DOCK_HPOS_RIGHT) | ((din.pos==MPLEX_STDISP_TL || din.pos==MPLEX_STDISP_TR) ? DOCK_VPOS_TOP : DOCK_VPOS_BOTTOM); *grow=dock->grow; return; } } *grow=dock->grow; *pos=dock->pos; }
WStacking *group_get_stacking(WGroup *ws) { WWindow *par=REGION_PARENT(ws); return (par==NULL ? NULL : window_get_stacking(par)); }
static void menu_firstfit(WMenu *menu, bool submenu, const WRectangle *refg) { WRectangle geom; calc_size(menu, &(geom.w), &(geom.h)); if(!(menu->last_fp.mode®ION_FIT_BOUNDS)){ geom.x=menu->last_fp.g.x; geom.y=menu->last_fp.g.y; }else if(menu->pmenu_mode){ geom.x=refg->x; geom.y=refg->y; if(!submenu){ const WRectangle *maxg = ®ION_GEOM(REGION_PARENT((WRegion*)menu)); geom.x-=geom.w/2; geom.y+=POINTER_OFFSET; if(geom.y+MINIMUM_Y_VISIBILITY>maxg->y+maxg->h){ geom.y=maxg->y+maxg->h-MINIMUM_Y_VISIBILITY; geom.x=refg->x+POINTER_OFFSET; if(geom.x+geom.w>maxg->x+maxg->w) geom.x=refg->x-geom.w-POINTER_OFFSET; }else{ if(geom.x<0) geom.x=0; else if(geom.x+geom.w>maxg->x+maxg->w) geom.x=maxg->x+maxg->w-geom.w; } } }else{ const WRectangle *maxg=&(menu->last_fp.g); if(submenu){ int l, r, t, b, xoff, yoff; get_placement_offs(menu, &xoff, &yoff); l=refg->x+xoff; r=refg->x+refg->w+xoff; t=refg->y-yoff; b=refg->y+refg->h-yoff; geom.x=maxof(l, r-geom.w); if(geom.x+geom.w>maxg->x+maxg->w) geom.x=maxg->x; geom.y=minof(b-geom.h, t); if(geom.y<maxg->y) geom.y=maxg->y; }else{ geom.x=maxg->x; geom.y=maxg->y+maxg->h-geom.h; } } window_do_fitrep(&menu->win, NULL, &geom); }
static void dock_do_set(WDock *dock, ExtlTab conftab, bool resize) { char *s; bool b; bool growset=FALSE; bool posset=FALSE; bool save=FALSE; if(extl_table_gets_s(conftab, dock_param_name.key, &s)){ if(!region_set_name((WRegion*)dock, s)){ warn_obj(modname, "Can't set name to \"%s\"", s); } free(s); } if(extl_table_gets_b(conftab, "save", &save)) dock->save=save; if(dock_param_extl_table_set(&dock_param_pos, conftab, &dock->pos)) posset=TRUE; if(dock_param_extl_table_set(&dock_param_grow, conftab, &dock->grow)) growset=TRUE; if(extl_table_gets_b(conftab, dock_param_is_auto.key, &b)) dock->is_auto=b; if(resize && (growset || posset)){ WMPlex *par=OBJ_CAST(REGION_PARENT(dock), WMPlex); WRegion *stdisp=NULL; WMPlexSTDispInfo din; if(par!=NULL){ mplex_get_stdisp(par, &stdisp, &din); din.fullsize=FALSE; /* not supported. */ if(stdisp==(WRegion*)dock){ if(posset) mplexpos(dock->pos, &din.pos); if(growset){ /* Update min/max first */ dock_managed_rqgeom_(dock, NULL, 0, NULL, NULL, TRUE); } mplex_set_stdisp(par, (WRegion*)dock, &din); }else if((WRegion*)par==REGION_MANAGER(dock)){ WSizePolicy szplcy; mplexszplcy(dock->pos, &szplcy); mplex_set_szplcy(par, (WRegion*)dock, szplcy); } } dock_resize(dock); } }
bool splitfloat_init(WSplitFloat *split, const WRectangle *geom, WTiling *ws, int dir) { WFitParams fp; WWindow *par=REGION_PARENT(ws); assert(par!=NULL); fp.g=*geom; fp.mode=REGION_FIT_EXACT; split->tlpwin=create_panehandle(par, &fp); if(split->tlpwin==NULL) return FALSE; fp.g=*geom; fp.mode=REGION_FIT_EXACT; split->brpwin=create_panehandle(par, &fp); if(split->brpwin==NULL){ destroy_obj((Obj*)split->tlpwin); return FALSE; } ((WRegion*)split->brpwin)->flags|=REGION_SKIP_FOCUS; ((WRegion*)split->tlpwin)->flags|=REGION_SKIP_FOCUS; if(!splitsplit_init(&(split->ssplit), geom, dir)){ destroy_obj((Obj*)split->brpwin); destroy_obj((Obj*)split->tlpwin); return FALSE; } split->tlpwin->splitfloat=split; split->brpwin->splitfloat=split; splitfloat_set_borderlines(split); if(REGION_IS_MAPPED(ws)){ region_map((WRegion*)(split->tlpwin)); region_map((WRegion*)(split->brpwin)); } return TRUE; }
bool group_fitrep(WGroup *ws, WWindow *par, const WFitParams *fp) { WGroupIterTmp tmp; WStacking *unweaved=NULL; int xdiff=0, ydiff=0; WStacking *st; WWindow *oldpar; WRectangle g; oldpar=REGION_PARENT(ws); if(par==NULL){ if(fp->mode®ION_FIT_WHATEVER) return TRUE; REGION_GEOM(ws)=fp->g; }else{ if(!region_same_rootwin((WRegion*)ws, (WRegion*)par)) return FALSE; if(ws->managed_stdisp!=NULL && ws->managed_stdisp->reg!=NULL) region_detach_manager(ws->managed_stdisp->reg); assert(ws->managed_stdisp==NULL); xdiff=fp->g.x-REGION_GEOM(ws).x; ydiff=fp->g.y-REGION_GEOM(ws).y; region_unset_parent((WRegion*)ws); XReparentWindow(ioncore_g.dpy, ws->dummywin, par->win, -1, -1); region_set_parent((WRegion*)ws, par); REGION_GEOM(ws).x=fp->g.x; REGION_GEOM(ws).y=fp->g.y; if(!(fp->mode®ION_FIT_WHATEVER)){ REGION_GEOM(ws).w=fp->g.w; REGION_GEOM(ws).h=fp->g.h; } if(oldpar!=NULL) unweaved=stacking_unweave(&oldpar->stacking, wsfilt, (void*)ws); } FOR_ALL_NODES_IN_GROUP(ws, st, tmp){ WFitParams fp2=*fp; if(st->reg==NULL) continue; g=REGION_GEOM(st->reg); g.x+=xdiff; g.y+=ydiff; if(fp->mode®ION_FIT_WHATEVER){ fp2.g=g; }else{ fp2.g=REGION_GEOM(ws); sizepolicy(&st->szplcy, st->reg, &g, REGION_RQGEOM_WEAK_ALL, &fp2); } if(!region_fitrep(st->reg, par, &fp2)){ warn(TR("Error reparenting %s."), region_name(st->reg)); region_detach_manager(st->reg); } }
WSplitRegion *splittree_split_floating(WSplit *node, int dir, int primn, int nmins, WRegionSimpleCreateFn *fn, WTiling *ws) { WSplitFloat *sf; int omins, mins; int sn, so, s, rs; int bn, bo; WRectangle gn, go, gnc, goc; WFitParams fp; WRegion *nreg; WSplitRegion *nnode; WSplitInner *psplit; if(primn!=PRIMN_TL && primn!=PRIMN_BR) primn=PRIMN_BR; split_update_bounds(split_find_root(node), TRUE); sf=create_splitfloat(&node->geom, ws, dir); if(sf==NULL) return NULL; omins=(dir==SPLIT_VERTICAL ? node->min_h : node->min_w); s=split_size(node, dir); if(primn==PRIMN_BR){ bn=BR_BORDER(sf); bo=TL_BORDER(sf); }else{ bn=TL_BORDER(sf); bo=BR_BORDER(sf); } mins=MAXOF(omins+bo, nmins+bn); /* Potentially resize old node. */ splittree_begin_resize(); if(mins>s){ WRectangle ng=node->geom, rg; if(dir==SPLIT_VERTICAL) ng.h=mins; else ng.w=mins; split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, TRUE); rs=(dir==SPLIT_VERTICAL ? rg.h : rg.w); if(rs<mins){ warn(TR("Unable to split: not enough free space.")); destroy_obj((Obj*)sf); return NULL; } split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, FALSE); s=split_size(node, dir); }else{ splittree_scan_stdisp_rootward(node); } /* Calculate geometries. */ sn=MAXOF(nmins+bn, s/2); so=MAXOF(omins+bo, s-s/2); ((WSplit*)sf)->geom=node->geom; if(primn==PRIMN_TL){ calc_tlg_brg(&(node->geom), sn, so, dir, &gn, &go); splitfloat_update_handles(sf, &gn, &go); gnc=gn; splitfloat_tl_pwin_to_cnt(sf, &gnc); goc=go; splitfloat_br_pwin_to_cnt(sf, &goc); }else{ calc_tlg_brg(&(node->geom), so, sn, dir, &go, &gn); splitfloat_update_handles(sf, &go, &gn); goc=go; splitfloat_tl_pwin_to_cnt(sf, &goc); gnc=gn; splitfloat_br_pwin_to_cnt(sf, &gnc); } /* Create the region. */ fp.mode=REGION_FIT_EXACT; fp.g=gnc; nreg=fn(REGION_PARENT(ws), &fp); if(nreg==NULL){ destroy_obj((Obj*)sf); return NULL; } nnode=create_splitregion(&(fp.g), nreg); if(nnode==NULL){ destroy_obj((Obj*)nreg); destroy_obj((Obj*)sf); return NULL; } /* Now that everything's ok, resize and move original node. */ split_do_resize(node, &goc, (dir==SPLIT_HORIZONTAL ? primn : PRIMN_ANY), (dir==SPLIT_VERTICAL ? primn : PRIMN_ANY), FALSE); /* Set up split structure. */ psplit=node->parent; if(psplit!=NULL) splitinner_replace(psplit, node, (WSplit*)sf); else splittree_changeroot(node, (WSplit*)sf); node->parent=(WSplitInner*)sf; ((WSplit*)nnode)->parent=(WSplitInner*)sf; if(primn==PRIMN_BR){ sf->ssplit.tl=node; sf->ssplit.br=(WSplit*)nnode; }else{ sf->ssplit.tl=(WSplit*)nnode; sf->ssplit.br=node; } /*splittree_end_resize();*/ return nnode; }
static void show_sub(WMenu *menu, int n) { WFitParams fp; WMenuCreateParams fnp; WMenu *submenu; WWindow *par; par=REGION_PARENT(menu); if(par==NULL) return; fp=menu->last_fp; fnp.pmenu_mode=menu->pmenu_mode; fnp.big_mode=menu->big_mode; fnp.submenu_mode=TRUE; if(menu->pmenu_mode){ fnp.refg.x=REGION_GEOM(menu).x+REGION_GEOM(menu).w; fnp.refg.y=REGION_GEOM(menu).y+get_sub_y_off(menu, n); fnp.refg.w=0; fnp.refg.h=0; }else{ fnp.refg=REGION_GEOM(menu); } fnp.tab=extl_table_none(); { ExtlFn fn; if(extl_table_getis(menu->tab, n+1, "submenu_fn", 'f', &fn)){ extl_protect(NULL); extl_call(fn, NULL, "t", &(fnp.tab)); extl_unprotect(NULL); extl_unref_fn(fn); }else{ extl_table_getis(menu->tab, n+1, "submenu", 't', &(fnp.tab)); } if(fnp.tab==extl_table_none()) return; } fnp.handler=extl_ref_fn(menu->handler); fnp.initial=0; { ExtlFn fn; if(extl_table_getis(menu->tab, n+1, "initial", 'f', &fn)){ extl_protect(NULL); extl_call(fn, NULL, "i", &(fnp.initial)); extl_unprotect(NULL); extl_unref_fn(fn); }else{ extl_table_getis(menu->tab, n+1, "initial", 'i', &(fnp.initial)); } } submenu=create_menu(par, &fp, &fnp); if(submenu==NULL) return; menu->submenu=submenu; region_set_manager((WRegion*)submenu, (WRegion*)menu); region_restack((WRegion*)submenu, MENU_WIN(menu), Above); region_map((WRegion*)submenu); if(!menu->pmenu_mode && region_may_control_focus((WRegion*)menu)) region_do_set_focus((WRegion*)submenu, FALSE); }
static bool moveresmode_init(WMoveresMode *mode, WRegion *reg, WDrawRubberbandFn *rubfn, bool cumulative) { WWindow *parent; WRegion *mgr; if(tmpmode!=NULL) return FALSE; parent=REGION_PARENT(reg); if(parent==NULL) return FALSE; tmpmode=mode; mode->snap_enabled=FALSE; region_size_hints(reg, &mode->hints); region_rootpos((WRegion*)parent, &mode->parent_rx, &mode->parent_ry); mode->geom=REGION_GEOM(reg); mode->origgeom=REGION_GEOM(reg); mode->dx1=0; mode->dx2=0; mode->dy1=0; mode->dy2=0; mode->rubfn=rubfn; mode->resize_cumulative=cumulative; mode->rqflags=(XOR_RESIZE ? REGION_RQGEOM_TRYONLY : 0); mode->reg=reg; mode->mode=MOVERES_SIZE; /* Get snapping geometry */ mgr=REGION_MANAGER(reg); if(mgr!=NULL){ mode->snapgeom=REGION_GEOM(mgr); if(mgr==(WRegion*)parent){ mode->snapgeom.x=0; mode->snapgeom.y=0; /*mode->snap_enabled=FALSE;*/ } mode->snap_enabled=TRUE; } if(!mode->hints.min_set || mode->hints.min_width<1) mode->hints.min_width=1; if(!mode->hints.min_set || mode->hints.min_height<1) mode->hints.min_height=1; /* Set up info window */ { int x=mode->geom.x+mode->geom.w/2; int y=mode->geom.y+mode->geom.h/2; mode->infowin=setup_moveres_display(parent, x, y); } moveres_draw_infowin(mode); if(XOR_RESIZE){ XGrabServer(ioncore_g.dpy); moveres_draw_rubberband(mode); } return TRUE; }