/*EXTL_DOC * Go to and return to a previously active region (if any). * * Note that this function is asynchronous; the region will not * actually have received the focus when this function returns. */ EXTL_EXPORT WRegion *ioncore_goto_previous() { WRegion *next; if(ioncore_g.focuslist==NULL) return NULL; /* We're trying to access the focus list from lua (likely from the UI). I * thus force any pending focuslist updates to complete now */ region_focuslist_awaiting_insertion_trigger(); /* Find the first region on focus history list that isn't currently * active. */ for(next=ioncore_g.focuslist->active_next; next!=NULL; next=next->active_next){ if(!REGION_IS_ACTIVE(next)) break; } if(next!=NULL) region_goto(next); return next; }
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; }
static void menu_draw_entry(WMenu *menu, int i, const WRectangle *igeom, bool complete) { WRectangle geom; GrAttr sa, aa; aa=(REGION_IS_ACTIVE(menu) ? GR_ATTR(active) : GR_ATTR(inactive)); sa=(menu->selected_entry==i ? GR_ATTR(selected) : GR_ATTR(unselected)); if(menu->entry_brush==NULL) return; geom=*igeom; geom.h=menu->entry_h; geom.y+=(i-menu->first_entry)*(menu->entry_h+menu->entry_spacing); grbrush_begin(menu->entry_brush, &geom, GRBRUSH_AMEND|GRBRUSH_KEEP_ATTR); grbrush_init_attr(menu->entry_brush, &menu->entries[i].attr); grbrush_set_attr(menu->entry_brush, aa); grbrush_set_attr(menu->entry_brush, sa); grbrush_draw_textbox(menu->entry_brush, &geom, menu->entries[i].title, complete); grbrush_end(menu->entry_brush); }
bool region_set_activity(WRegion *reg, int sp) { bool set=(reg->flags®ION_ACTIVITY); bool nset=libtu_do_setparam(sp, set); if(!XOR(set, nset)) return nset; if(nset){ if(REGION_IS_ACTIVE(reg)) return FALSE; reg->flags|=REGION_ACTIVITY; objlist_insert_last(&actlist, (Obj*)reg); if(reg->mgd_activity==0) propagate_activity(reg); }else{ reg->flags&=~REGION_ACTIVITY; objlist_remove(&actlist, (Obj*)reg); if(reg->mgd_activity==0) propagate_clear(reg); } region_notify_change(reg, ioncore_g.notifies.activity); return nset; }
bool tiling_managed_add_default(WTiling *ws, WRegion *reg) { Window bottom=None, top=None; WFrame *frame; if(TILING_STDISP_OF(ws)!=reg){ if(!ptrlist_insert_last(&(ws->managed_list), reg)) return FALSE; } region_set_manager(reg, (WRegion*)ws); frame=OBJ_CAST(reg, WFrame); if(frame!=NULL){ if(framemode_unalt(frame_mode(frame))!=FRAME_MODE_TILED) frame_set_mode(frame, FRAME_MODE_TILED); } if(REGION_IS_MAPPED(ws)) region_map(reg); if(region_may_control_focus((WRegion*)ws)){ WRegion *curr=tiling_current(ws); if(curr==NULL || !REGION_IS_ACTIVE(curr)) region_warp(reg); } return TRUE; }
/*EXTL_DOC * Returns previously active screen on root window \var{rootwin}. */ EXTL_SAFE EXTL_EXPORT_MEMBER WScreen *rootwin_current_scr(WRootWin *rootwin) { WScreen *scr, *fb=NULL; FOR_ALL_SCREENS(scr){ if(REGION_MANAGER(scr)==(WRegion*)rootwin && REGION_IS_MAPPED(scr)){ fb=scr; if(REGION_IS_ACTIVE(scr)) return scr; } } return (fb ? fb : &rootwin->scr); }
void region_got_focus(WRegion *reg) { WRegion *par; check_clear_await(reg); region_set_activity(reg, SETPARAM_UNSET); if(reg->active_sub==NULL) { /* I update the current focus indicator right now. The focuslist is * updated on a timer to keep the list ordered by importance (to keep * windows that the user quickly cycles through at the bottom of the list) */ ioncore_g.focus_current = reg; schedule_focuslist_insert_timer(reg); } if(!REGION_IS_ACTIVE(reg)){ D(fprintf(stderr, "got focus (inact) %s [%p]\n", OBJ_TYPESTR(reg), reg);)
void menu_draw(WMenu *menu, bool complete) { GrAttr aa=(REGION_IS_ACTIVE(menu) ? GR_ATTR(active) : GR_ATTR(inactive)); WRectangle geom; if(menu->brush==NULL) return; get_outer_geom(menu, &geom); grbrush_begin(menu->brush, &geom, (complete ? 0 : GRBRUSH_NO_CLEAR_OK)); grbrush_set_attr(menu->brush, aa); grbrush_draw_border(menu->brush, &geom); menu_draw_entries(menu, FALSE); grbrush_end(menu->brush); }
void tiling_unmanage_stdisp(WTiling *ws, bool permanent, bool nofocus) { WSplitRegion *tofocus=NULL; bool setfocus=FALSE; WRegion *od; if(ws->stdispnode==NULL) return; od=ws->stdispnode->regnode.reg; if(od!=NULL){ if(!nofocus && REGION_IS_ACTIVE(od) && region_may_control_focus((WRegion*)ws)){ setfocus=TRUE; tofocus=(WSplitRegion*)split_nextto((WSplit*)(ws->stdispnode), PRIMN_ANY, PRIMN_ANY, regnodefilter); } /* Reset node_of info here so tiling_managed_remove will not * remove the node. */ splittree_set_node_of(od, NULL); tiling_do_managed_remove(ws, od); } if(permanent){ WSplit *node=(WSplit*)ws->stdispnode; ws->stdispnode=NULL; splittree_remove(node, TRUE); } if(setfocus){ if(tofocus!=NULL) region_set_focus(tofocus->reg); else tiling_fallback_focus(ws, FALSE); } }
bool clientwin_fullscreen_may_switchto(WClientWin *cwin) { return (region_may_control_focus((WRegion*)cwin) || !REGION_IS_ACTIVE(region_screen_of((WRegion*)cwin))); }
void tiling_manage_stdisp(WTiling *ws, WRegion *stdisp, const WMPlexSTDispInfo *di) { bool mcf=region_may_control_focus((WRegion*)ws); int flags=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y; int orientation=region_orientation(stdisp); bool act=FALSE; WRectangle dg, *stdg; if(orientation!=REGION_ORIENTATION_VERTICAL /*&& orientation!=REGION_ORIENTATION_HORIZONTAL*/){ orientation=REGION_ORIENTATION_HORIZONTAL; } if(ws->stdispnode==NULL || ws->stdispnode->regnode.reg!=stdisp) region_detach_manager(stdisp); /* Remove old stdisp if corner and orientation don't match. */ if(ws->stdispnode!=NULL && (di->pos!=ws->stdispnode->corner || orientation!=ws->stdispnode->orientation)){ tiling_unmanage_stdisp(ws, TRUE, TRUE); } if(ws->stdispnode==NULL){ tiling_create_stdispnode(ws, stdisp, di->pos, orientation, di->fullsize); if(ws->stdispnode==NULL) return; }else{ WRegion *od=ws->stdispnode->regnode.reg; if(od!=NULL){ act=REGION_IS_ACTIVE(od); splittree_set_node_of(od, NULL); tiling_managed_remove(ws, od); assert(ws->stdispnode->regnode.reg==NULL); } ws->stdispnode->fullsize=di->fullsize; ws->stdispnode->regnode.reg=stdisp; splittree_set_node_of(stdisp, &(ws->stdispnode->regnode)); } if(!tiling_managed_add(ws, stdisp)){ tiling_unmanage_stdisp(ws, TRUE, TRUE); return; } stdisp->flags|=REGION_SKIP_FOCUS; dg=((WSplit*)(ws->stdispnode))->geom; dg.h=stdisp_recommended_h(ws->stdispnode); dg.w=stdisp_recommended_w(ws->stdispnode); splittree_rqgeom((WSplit*)(ws->stdispnode), flags, &dg, FALSE); stdg=&(((WSplit*)ws->stdispnode)->geom); if(stdisp->geom.x!=stdg->x || stdisp->geom.y!=stdg->y || stdisp->geom.w!=stdg->w || stdisp->geom.h!=stdg->h){ region_fit(stdisp, stdg, REGION_FIT_EXACT); } /* Restack to ensure the split tree is stacked in the expected order. */ if(ws->split_tree!=NULL) split_restack(ws->split_tree, ws->dummywin, Above); if(mcf && act) region_set_focus(stdisp); }