Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
WStacking *group_get_stacking(WGroup *ws)
{
    WWindow *par=REGION_PARENT(ws);
    
    return (par==NULL 
            ? NULL
            : window_get_stacking(par));
}
Beispiel #4
0
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&REGION_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 = 
                &REGION_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);
}
Beispiel #5
0
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);
    }
}
Beispiel #6
0
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;
}
Beispiel #7
0
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&REGION_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&REGION_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&REGION_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);
        }
    }
Beispiel #8
0
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;
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}