static void get_outer_geom(WMenu *menu, WRectangle *geom) { geom->x=0; geom->y=0; geom->w=REGION_GEOM(menu).w; geom->h=REGION_GEOM(menu).h; }
static WRegion *recreate_handler(WWindow *par, const WFitParams *fp, void *rp_) { WGroupPHolder *phtmp; RP *rp=(RP*)rp_; WGroup *grp; grp=(WGroup*)create_groupcw(par, fp); if(grp==NULL) return NULL; rp->ph->param.whatever=(fp->mode®ION_FIT_WHATEVER ? 1 : 0); rp->reg_ret=group_do_attach(grp, &rp->ph->param, rp->data); rp->ph->param.whatever=0; if(rp->reg_ret==NULL){ destroy_obj((Obj*)grp); return NULL; }else{ grp->phs=rp->ph_head; for(phtmp=grp->phs; phtmp!=NULL; phtmp=phtmp->next) phtmp->group=grp; } if(fp->mode®ION_FIT_WHATEVER) REGION_GEOM(grp)=REGION_GEOM(rp->reg_ret); return (WRegion*)grp; }
/*EXTL_DOC * Attempt to toggle horizontal maximisation of \var{frame}. */ EXTL_EXPORT_MEMBER void frame_maximize_horiz(WFrame *frame) { WRegion *mp=REGION_MANAGER(frame); int ox, ow; if(frame->flags&FRAME_MIN_HORIZ || frame->flags&FRAME_MAXED_HORIZ){ if(frame->flags&FRAME_SAVED_HORIZ){ if(mp!=NULL && region_managed_maximize(mp, (WRegion*)frame, HORIZONTAL, VERIFY)) region_managed_maximize(mp, (WRegion*)frame, HORIZONTAL, RESTORE); else rqw(frame, frame->saved_geom.x, frame->saved_geom.w); } frame->flags&=~(FRAME_MAXED_HORIZ|FRAME_SAVED_HORIZ); region_goto((WRegion*)frame); return; } if(mp==NULL) return; ox=REGION_GEOM(frame).x; ow=REGION_GEOM(frame).w; region_managed_maximize(mp, (WRegion*)frame, HORIZONTAL, SAVE); rqw(frame, 0, REGION_GEOM(mp).w); region_managed_maximize(mp, (WRegion*)frame, HORIZONTAL, RM_KEEP); frame->flags|=(FRAME_MAXED_HORIZ|FRAME_SAVED_HORIZ); frame->saved_geom.x=ox; frame->saved_geom.w=ow; region_goto((WRegion*)frame); }
static void window_notify_subs_rootpos(WWindow *wwin, int x, int y) { WRegion *sub; FOR_ALL_CHILDREN(wwin, sub){ region_notify_rootpos(sub, x+REGION_GEOM(sub).x, y+REGION_GEOM(sub).y); }
void frame_border_geom(const WFrame *frame, WRectangle *geom) { geom->x=0; geom->y=0; geom->w=REGION_GEOM(frame).w; geom->h=REGION_GEOM(frame).h; if(!BAR_INSIDE_BORDER(frame) && frame->brush!=NULL){ geom->y+=frame->bar_h; geom->h=MAXOF(0, geom->h-frame->bar_h); } }
WScreen *clientwin_find_suitable_screen(WClientWin *cwin, const WManageParams *param) { WScreen *scr=NULL, *found=NULL; bool respectpos=(param->tfor!=NULL || param->userpos); FOR_ALL_SCREENS(scr){ if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin)) continue; if(REGION_IS_ACTIVE(scr)){ found=scr; if(!respectpos) break; } if(rectangle_contains(®ION_GEOM(scr), param->geom.x, param->geom.y)){ found=scr; if(respectpos) break; } if(found==NULL) found=scr; } return found; }
void region_managed_rqgeom_unallow(WRegion *UNUSED(mgr), WRegion *reg, const WRQGeomParams *UNUSED(rq), WRectangle *geomret) { if(geomret!=NULL) *geomret=REGION_GEOM(reg); }
bool tiling_fitrep(WTiling *ws, WWindow *par, const WFitParams *fp) { WTilingIterTmp tmp; bool ok=FALSE; if(par!=NULL){ if(!region_same_rootwin((WRegion*)ws, (WRegion*)par)) return FALSE; region_unset_parent((WRegion*)ws); XReparentWindow(ioncore_g.dpy, ws->dummywin, par->win, fp->g.x, fp->g.y); region_set_parent((WRegion*)ws, par); if(ws->split_tree!=NULL) split_reparent(ws->split_tree, par); } REGION_GEOM(ws)=fp->g; if(ws->split_tree!=NULL){ bool done=FALSE; if(fp->mode®ION_FIT_ROTATE) ok=split_rotate_to(ws->split_tree, &(fp->g), fp->rotation); if(!ok) split_resize(ws->split_tree, &(fp->g), PRIMN_ANY, PRIMN_ANY); } return TRUE; }
static void check_scroll(WMenu *menu, int x, int y) { WRegion *parent=REGION_PARENT_REG(menu); int rx, ry; WTimerHandler *fn=NULL; if(!menu->pmenu_mode) return; if(parent==NULL){ end_scroll(menu); return; } region_rootpos(parent, &rx, &ry); x-=rx; y-=ry; if(x<=SCROLL_OFFSET){ fn=(WTimerHandler*)scroll_right; }else if(y<=SCROLL_OFFSET){ fn=(WTimerHandler*)scroll_down; }else if(x>=REGION_GEOM(parent).w-SCROLL_OFFSET){ fn=(WTimerHandler*)scroll_left; }else if(y>=REGION_GEOM(parent).h-SCROLL_OFFSET){ fn=(WTimerHandler*)scroll_up; }else{ end_scroll(menu); return; } assert(fn!=NULL); if(scroll_timer!=NULL){ if(scroll_timer->handler==(WTimerHandler*)fn && timer_is_set(scroll_timer)){ return; } }else{ scroll_timer=create_timer(); if(scroll_timer==NULL) return; } fn(scroll_timer, (Obj*)menu_head(menu)); }
void infowin_draw(WInfoWin *p, bool complete) { WRectangle g; if(p->brush==NULL) return; g.x=0; g.y=0; g.w=REGION_GEOM(p).w; g.h=REGION_GEOM(p).h; grbrush_begin(p->brush, &g, GRBRUSH_NO_CLEAR_OK); grbrush_init_attr(p->brush, &p->attr); grbrush_draw_textbox(p->brush, &g, p->buffer, TRUE); grbrush_end(p->brush); }
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); }
void window_p_resize_prepare(WWindow *wwin, XButtonEvent *ev) { int ww=REGION_GEOM(wwin).w/2; int hh=REGION_GEOM(wwin).h/2; int xdiv, ydiv; int tmpx, tmpy, atmpx, atmpy; p_dx1mul=0; p_dx2mul=0; p_dy1mul=0; p_dy2mul=0; tmpx=ev->x-ww; tmpy=hh-ev->y; xdiv=ww/2; ydiv=hh/2; atmpx=abs(tmpx); atmpy=abs(tmpy); if(xdiv<MINCORNER && xdiv>1){ xdiv=ww-MINCORNER; if(xdiv<1) xdiv=1; } if(ydiv<MINCORNER && ydiv>1){ ydiv=hh-MINCORNER; if(ydiv<1) ydiv=1; } if(xdiv==0){ p_dx2mul=1; }else if(hh*atmpx/xdiv>=tmpy && -hh*atmpx/xdiv<=tmpy){ p_dx1mul=(tmpx<0); p_dx2mul=(tmpx>=0); } if(ydiv==0){ p_dy2mul=1; }else if(ww*atmpy/ydiv>=tmpx && -ww*atmpy/ydiv<=tmpx){ p_dy1mul=(tmpy>0); p_dy2mul=(tmpy<=0); } }
static int scrolld_subs(WMenu *menu, int d) { int diff=0; WRegion *p=REGION_PARENT_REG(menu); const WRectangle *pg; if(p==NULL) return 0; pg=®ION_GEOM(p); while(menu!=NULL){ diff=maxof(diff, calc_diff(®ION_GEOM(menu), pg, d)); menu=menu->submenu; } return minof(maxof(0, diff), scroll_amount); }
bool groupws_handle_drop(WGroupWS *ws, int x, int y, WRegion *dropped) { WGroupAttachParams ap=GROUPATTACHPARAMS_INIT; WFramedParam fp=FRAMEDPARAM_INIT; ap.switchto_set=TRUE; ap.switchto=TRUE; fp.inner_geom_gravity_set=TRUE; fp.inner_geom.x=x; fp.inner_geom.y=y; fp.inner_geom.w=REGION_GEOM(dropped).w; fp.inner_geom.h=REGION_GEOM(dropped).h; fp.gravity=NorthWestGravity; return groupws_attach_framed(ws, &ap, &fp, dropped); }
static void panehandle_draw(WPaneHandle *pwin, bool complete) { WRectangle g; if(pwin->brush==NULL) return; g.x=0; g.y=0; g.w=REGION_GEOM(pwin).w; g.h=REGION_GEOM(pwin).h; grbrush_begin(pwin->brush, &g, (complete ? 0 : GRBRUSH_NO_CLEAR_OK)); grbrush_draw_borderline(pwin->brush, &g, pwin->bline); grbrush_end(pwin->brush); }
static int scrolld_subs(WMenu *menu, int d) { int diff=0; WRegion *p=REGION_PARENT_REG(menu); const WRectangle *pg; if(p==NULL) return 0; pg=®ION_GEOM(p); while(menu!=NULL){ int new_diff = calc_diff(®ION_GEOM(menu), pg, d); diff=MAXOF(diff, new_diff); menu=menu->submenu; } return MINOF(MAXOF(0, diff), scroll_amount); }
static void reparent_mgd(WRegion *sub, WWindow *par) { WFitParams subfp; subfp.g=REGION_GEOM(sub); subfp.mode=REGION_FIT_EXACT; if(!region_fitrep(sub, par, &subfp)){ warn(TR("Error reparenting %s."), region_name(sub)); region_detach_manager(sub); } }
ExtlTab region_rqgeom_extl(WRegion *reg, ExtlTab g) { WRQGeomParams rq=RQGEOMPARAMS_INIT; WRectangle res; rqgeomparams_from_table(&rq, ®ION_GEOM(reg), g); region_rqgeom(reg, &rq, &res); return extl_table_from_rectangle(&res); }
static bool rqh(WFrame *frame, int y, int h) { WRQGeomParams rq=RQGEOMPARAMS_INIT; WRectangle rgeom; int dummy_w; rq.flags=REGION_RQGEOM_VERT_ONLY; rq.geom.x=REGION_GEOM(frame).x; rq.geom.w=REGION_GEOM(frame).w; rq.geom.y=y; rq.geom.h=h; dummy_w=rq.geom.w; region_size_hints_correct((WRegion*)frame, &dummy_w, &(rq.geom.h), TRUE); region_rqgeom((WRegion*)frame, &rq, &rgeom); return (abs(rgeom.y-REGION_GEOM(frame).y)>1 || abs(rgeom.h-REGION_GEOM(frame).h)>1); }
static bool rqw(WFrame *frame, int x, int w) { WRQGeomParams rq=RQGEOMPARAMS_INIT; WRectangle rgeom; int dummy_h; rq.flags=REGION_RQGEOM_HORIZ_ONLY; rq.geom.x=x; rq.geom.w=w; rq.geom.y=REGION_GEOM(frame).y; rq.geom.h=REGION_GEOM(frame).h; dummy_h=rq.geom.h; region_size_hints_correct((WRegion*)frame, &(rq.geom.w), &dummy_h, TRUE); region_rqgeom((WRegion*)frame, &rq, &rgeom); return (abs(rgeom.x-REGION_GEOM(frame).x)>1 || abs(rgeom.w-REGION_GEOM(frame).w)>1); }
static void infowin_resize(WInfoWin *p) { WRQGeomParams rq=RQGEOMPARAMS_INIT; const char *str=INFOWIN_BUFFER(p); GrBorderWidths bdw; GrFontExtents fnte; rq.flags=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y; rq.geom.x=REGION_GEOM(p).x; rq.geom.y=REGION_GEOM(p).y; grbrush_get_border_widths(p->brush, &bdw); grbrush_get_font_extents(p->brush, &fnte); rq.geom.w=bdw.left+bdw.right; rq.geom.w+=grbrush_get_text_width(p->brush, str, strlen(str)); rq.geom.h=fnte.max_height+bdw.top+bdw.bottom; if(rectangle_compare(&rq.geom, ®ION_GEOM(p))!=RECTANGLE_SAME) region_rqgeom((WRegion*)p, &rq, NULL); }
static void dock_draw(WDock *dock, bool complete) { int outline_style; WRectangle g; if(dock->brush==NULL) return; g.x=0; g.y=0; g.w=REGION_GEOM(dock).w; g.h=REGION_GEOM(dock).h; grbrush_begin(dock->brush, &g, (complete ? 0 : GRBRUSH_NO_CLEAR_OK)); dock_get_outline_style(dock, &outline_style); switch(outline_style){ case DOCK_OUTLINE_STYLE_NONE: break; case DOCK_OUTLINE_STYLE_ALL: { WRectangle geom=REGION_GEOM(dock); geom.x=geom.y=0; grbrush_draw_border(dock->brush, &geom); } break; case DOCK_OUTLINE_STYLE_EACH: { WDockApp *dockapp; for(dockapp=dock->dockapps; dockapp!=NULL; dockapp=dockapp->next){ grbrush_draw_border(dock->brush, &dockapp->tile_geom); } } break; } grbrush_end(dock->brush); }
WScreen *clientwin_fullscreen_chkrq(WClientWin *cwin, int w, int h) { WScreen *scr; WMwmHints *mwm; mwm=xwindow_get_mwmhints(cwin->win); if(mwm==NULL || !(mwm->flags&MWM_HINTS_DECORATIONS) || mwm->decorations!=0) return NULL; FOR_ALL_SCREENS(scr){ if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin)) continue; /* Only Mplayer supports single Xinerama region FS to my knowledge, * and doesn't set position, so we also don't check position here, * and instead take the first screen with matching size. */ if(REGION_GEOM(scr).w==w && REGION_GEOM(scr).h==h) return scr; } return NULL; }
static void menu_do_refit(WMenu *menu, WWindow *par, const WFitParams *oldfp) { 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=REGION_GEOM(menu).x; geom.y=REGION_GEOM(menu).y; }else{ const WRectangle *maxg=&(menu->last_fp.g); int xdiff=REGION_GEOM(menu).x-oldfp->g.x; int ydiff=(REGION_GEOM(menu).y+REGION_GEOM(menu).h -(oldfp->g.y+oldfp->g.h)); geom.x=maxof(0, minof(maxg->x+xdiff, maxg->x+maxg->w-geom.w)); geom.y=maxof(0, minof(maxg->y+maxg->h+ydiff, maxg->y+maxg->h)-geom.h); } window_do_fitrep(&menu->win, par, &geom); }
static WInfoWin *setup_moveres_display(WWindow *parent, int cx, int cy) { GrBorderWidths bdw; GrFontExtents fnte; WInfoWin *infowin; WFitParams fp; fp.mode=REGION_FIT_EXACT; fp.g.x=0; fp.g.y=0; fp.g.w=1; fp.g.h=1; infowin=create_infowin(parent, &fp, "moveres_display"); if(infowin==NULL) return NULL; grbrush_get_border_widths(INFOWIN_BRUSH(infowin), &bdw); grbrush_get_font_extents(INFOWIN_BRUSH(infowin), &fnte); /* Create move/resize position/size display window */ fp.g.w=3; fp.g.w+=chars_for_num(REGION_GEOM(parent).w); fp.g.w+=chars_for_num(REGION_GEOM(parent).h); fp.g.w*=max_width(INFOWIN_BRUSH(infowin), "0123456789x+"); fp.g.w+=bdw.left+bdw.right; fp.g.h=fnte.max_height+bdw.top+bdw.bottom;; fp.g.x=cx-fp.g.w/2; fp.g.y=cy-fp.g.h/2; region_fitrep((WRegion*)infowin, NULL, &fp); region_map((WRegion*)infowin); return infowin; }
/*EXTL_DOC * Attempt to toggle vertical maximisation of \var{frame}. */ EXTL_EXPORT_MEMBER void frame_maximize_vert(WFrame *frame) { WRegion *mp=REGION_MANAGER(frame); int oy, oh; if(frame->flags&FRAME_SHADED || frame->flags&FRAME_MAXED_VERT){ if(frame->flags&FRAME_SHADED) frame->flags|=FRAME_SHADED_TOGGLE; if(frame->flags&FRAME_SAVED_VERT){ if(mp!=NULL && region_managed_maximize(mp, (WRegion*)frame, VERTICAL, VERIFY)) region_managed_maximize(mp, (WRegion*)frame, VERTICAL, RESTORE); else rqh(frame, frame->saved_geom.y, frame->saved_geom.h); } frame->flags&=~(FRAME_MAXED_VERT|FRAME_SAVED_VERT|FRAME_SHADED_TOGGLE); region_goto((WRegion*)frame); return; } if(mp==NULL) return; oy=REGION_GEOM(frame).y; oh=REGION_GEOM(frame).h; region_managed_maximize(mp, (WRegion*)frame, VERTICAL, SAVE); rqh(frame, 0, REGION_GEOM(mp).h); region_managed_maximize(mp, (WRegion*)frame, VERTICAL, RM_KEEP); frame->flags|=(FRAME_MAXED_VERT|FRAME_SAVED_VERT); frame->saved_geom.y=oy; frame->saved_geom.h=oh; region_goto((WRegion*)frame); }
static bool dock_do_attach_final(WDock *dock, WRegion *reg, void *UNUSED(unused)) { WDockApp *dockapp, *before_dockapp; WRectangle geom; bool draw_border=TRUE; int pos=INT_MAX; /* Create and initialise a new WDockApp struct */ dockapp=ALLOC(WDockApp); if(dockapp==NULL) return FALSE; if(OBJ_IS(reg, WClientWin)){ ExtlTab proptab=((WClientWin*)reg)->proptab; extl_table_gets_b(proptab, CLIENTWIN_WINPROP_BORDER, &draw_border); extl_table_gets_i(proptab, CLIENTWIN_WINPROP_POSITION, &pos); } dockapp->reg=reg; dockapp->draw_border=draw_border; dockapp->pos=pos; dockapp->tile=FALSE; /* Insert the dockapp at the correct relative position */ before_dockapp=dock->dockapps; for(before_dockapp=dock->dockapps; before_dockapp!=NULL && dockapp->pos>=before_dockapp->pos; before_dockapp=before_dockapp->next){ } if(before_dockapp!=NULL){ LINK_ITEM_BEFORE(dock->dockapps, before_dockapp, dockapp, next, prev); }else{ LINK_ITEM(dock->dockapps, dockapp, next, prev); } region_set_manager(reg, (WRegion*)dock); geom=REGION_GEOM(reg); dock_managed_rqgeom_(dock, reg, REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y, &geom, NULL, FALSE); region_map(reg); return TRUE; }
int frame_press(WFrame *frame, XButtonEvent *ev, WRegion **reg_ret) { WRegion *sub=NULL; WRectangle g; p_tabnum=-1; window_p_resize_prepare((WWindow*)frame, ev); /* Check tab */ frame_bar_geom(frame, &g); /* Borders act like tabs at top of the parent region */ if(REGION_GEOM(frame).y==0){ g.h+=g.y; g.y=0; } if(frame->barmode!=FRAME_BAR_NONE && rectangle_contains(&g, ev->x, ev->y)){ p_tabnum=frame_tab_at_x(frame, ev->x); region_rootpos((WRegion*)frame, &p_tab_x, &p_tab_y); p_tab_x+=frame_nth_tab_x(frame, p_tabnum); p_tab_y+=g.y; sub=mplex_mx_nth(&(frame->mplex), p_tabnum); if(reg_ret!=NULL) *reg_ret=sub; return FRAME_AREA_TAB; }else{ WLListIterTmp tmp; FRAME_MX_FOR_ALL(sub, frame, tmp){ p_tabnum++; if(sub==FRAME_CURRENT(frame)) break; } if(sub!=NULL){ p_tab_x=ev->x_root-frame_nth_tab_w(frame, p_tabnum)/2; p_tab_y=ev->y_root-frame->bar_h/2; }else{ p_tabnum=-1; } }
bool grouppholder_init(WGroupPHolder *ph, WGroup *ws, const WStacking *st, const WGroupAttachParams *param) { WRegion *stack_above=NULL; pholder_init(&(ph->ph)); watch_init(&(ph->stack_above_watch)); ph->next=NULL; ph->prev=NULL; ph->group=NULL; ph->recreate_pholder=NULL; ph->param=(param==NULL ? dummy_param : *param); if(st!=NULL){ /* TODO? Just link to the stacking structure to remember * stacking order? */ ph->param.szplcy_set=TRUE; ph->param.szplcy=st->szplcy; ph->param.level_set=TRUE; ph->param.level=st->level; if(st->reg!=NULL){ ph->param.geom_set=TRUE; ph->param.geom=REGION_GEOM(st->reg); } if(st->above!=NULL && st->above->reg!=NULL) ph->param.stack_above=st->above->reg; ph->param.bottom=(st==ws->bottom); } ph->param.switchto_set=FALSE; stack_above=ph->param.stack_above; ph->param.stack_above=NULL; grouppholder_do_link(ph, ws, stack_above); return TRUE; }
bool tiling_do_attach_initial(WTiling *ws, WRegion *reg) { assert(ws->split_tree==NULL); ws->split_tree=(WSplit*)create_splitregion(®ION_GEOM(reg), reg); if(ws->split_tree==NULL) return FALSE; ws->split_tree->ws_if_root=ws; if(!tiling_managed_add(ws, reg)){ destroy_obj((Obj*)ws->split_tree); ws->split_tree=NULL; return FALSE; } return TRUE; }