static void destroy_item(WHook *hk, WHookItem *item) { if(item->fn==NULL) extl_unref_fn(item->efn); UNLINK_ITEM(hk->items, item, next, prev); free(item); }
static WMenuEntry *preprocess_menu(ExtlTab tab, int *n_entries) { WMenuEntry *entries; ExtlTab entry; int i, n; n=extl_table_get_n(tab); *n_entries=n; if(n<=0) return NULL; entries=ALLOC_N(WMenuEntry, n); if(entries==NULL) return NULL; init_attr(); /* Initialise entries and check submenus */ for(i=1; i<=n; i++){ WMenuEntry *ent=&entries[i-1]; ent->title=NULL; ent->flags=0; gr_stylespec_init(&ent->attr); if(extl_table_geti_t(tab, i, &entry)){ char *attr; ExtlTab sub; ExtlFn fn; if(extl_table_gets_s(entry, "attr", &attr)){ gr_stylespec_load_(&ent->attr, attr, TRUE); free(attr); } if(extl_table_gets_f(entry, "submenu_fn", &fn)){ ent->flags|=WMENUENTRY_SUBMENU; extl_unref_fn(fn); }else if(extl_table_gets_t(entry, "submenu", &sub)){ ent->flags|=WMENUENTRY_SUBMENU; extl_unref_table(sub); } if(ent->flags&WMENUENTRY_SUBMENU) gr_stylespec_set(&ent->attr, GR_ATTR(submenu)); extl_unref_table(entry); } } return entries; }
static int try_read_savefile(const char *file, TryCallParam *param) { int ret=try_load(file, param); if(ret!=EXTL_TRYCONFIG_OK) return ret; ret=extl_call(param->fn, NULL, "t", &(param->tab)); extl_unref_fn(param->fn); return (ret ? EXTL_TRYCONFIG_OK : EXTL_TRYCONFIG_CALL_FAILED); }
void menu_deinit(WMenu *menu) { menu_typeahead_clear(menu); if(menu->submenu!=NULL) destroy_obj((Obj*)menu->submenu); /*if(menu->cycle_bindmap!=NULL) bindmap_destroy(menu->cycle_bindmap);*/ extl_unref_table(menu->tab); extl_unref_fn(menu->handler); deinit_entries(menu); menu_release_gr(menu); window_deinit((WWindow*)menu); }
static void menu_do_finish(WMenu *menu) { ExtlFn handler; ExtlTab tab; bool ok; WMenu *head=menu_head(menu); handler=menu->handler; menu->handler=extl_fn_none(); ok=extl_table_geti_t(menu->tab, menu->selected_entry+1, &tab); if(!region_rqdispose((WRegion*)head)){ if(head->submenu!=NULL) destroy_obj((Obj*)head->submenu); } if(ok) extl_call(handler, "t", NULL, tab); extl_unref_fn(handler); extl_unref_table(tab); }
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); }
bool menu_init(WMenu *menu, WWindow *par, const WFitParams *fp, const WMenuCreateParams *params) { Window win; int i; menu->entries=preprocess_menu(params->tab, &(menu->n_entries)); if(menu->entries==NULL){ warn(TR("Empty menu.")); return FALSE; } menu->tab=extl_ref_table(params->tab); menu->handler=extl_ref_fn(params->handler); menu->pmenu_mode=params->pmenu_mode; menu->big_mode=params->big_mode; /*menu->cycle_bindmap=NULL;*/ menu->last_fp=*fp; if(params->pmenu_mode){ menu->selected_entry=-1; }else{ menu->selected_entry=params->initial-1; if(menu->selected_entry<0) menu->selected_entry=0; if(params->initial > menu->n_entries) menu->selected_entry=0; } menu->max_entry_w=0; menu->entry_h=0; menu->brush=NULL; menu->entry_brush=NULL; menu->entry_spacing=0; menu->vis_entries=menu->n_entries; menu->first_entry=0; menu->submenu=NULL; menu->typeahead=NULL; menu->gm_kcb=0; menu->gm_state=0; if(!window_init((WWindow*)menu, par, fp)) goto fail; win=menu->win.win; if(!menu_init_gr(menu, region_rootwin_of((WRegion*)par), win)) goto fail2; init_attr(); menu_firstfit(menu, params->submenu_mode, &(params->refg)); window_select_input(&(menu->win), IONCORE_EVENTMASK_NORMAL); region_add_bindmap((WRegion*)menu, mod_menu_menu_bindmap); region_register((WRegion*)menu); return TRUE; fail2: window_deinit((WWindow*)menu); fail: extl_unref_table(menu->tab); extl_unref_fn(menu->handler); deinit_entries(menu); return FALSE; }
/*EXTL_DOC * Set ioncore basic settings. The table \var{tab} may contain the * following fields. * * \begin{tabularx}{\linewidth}{lX} * \tabhead{Field & Description} * \var{opaque_resize} & (boolean) Controls whether interactive move and * resize operations simply draw a rubberband during * the operation (false) or immediately affect the * object in question at every step (true). \\ * \var{warp} & (boolean) Should focusing operations move the * pointer to the object to be focused? \\ * \var{warp_margin} & (integer) Border offset in pixels to apply * to the cursor when warping. \\ * \var{warp_factor} & (double[2]) X & Y factor to offset the cursor. * between 0 and 1, where 0.5 is the center. \\ * \var{switchto} & (boolean) Should a managing \type{WMPlex} switch * to a newly mapped client window? \\ * \var{screen_notify} & (boolean) Should notification tooltips be displayed * for hidden workspaces with activity? \\ * \var{frame_default_index} & (string) Specifies where to add new regions * on the mutually exclusive list of a frame. One of * \codestr{last}, \codestr{next}, (for after current), * or \codestr{next-act} * (for after current and anything with activity right * after it). \\ * \var{dblclick_delay} & (integer) Delay between clicks of a double click.\\ * \var{kbresize_delay} & (integer) Delay in milliseconds for ending keyboard * resize mode after inactivity. \\ * \var{kbresize_t_max} & (integer) Controls keyboard resize acceleration. * See description below for details. \\ * \var{kbresize_t_min} & (integer) See below. \\ * \var{kbresize_step} & (floating point) See below. \\ * \var{kbresize_maxacc} & (floating point) See below. \\ * \var{edge_resistance} & (integer) Resize edge resistance in pixels. \\ * \var{framed_transients} & (boolean) Put transients in nested frames. \\ * \var{float_placement_method} & (string) How to place floating frames. * One of \codestr{udlr} (up-down, then left-right), * \codestr{lrud} (left-right, then up-down), or * \codestr{random}. \\ * \var{float_placement_padding} & (integer) Pixels between frames when * \var{float_placement_method} is \codestr{udlr} or * \codestr{lrud}. \\ * \var{mousefocus} & (string) Mouse focus mode: * \codestr{disabled} or \codestr{sloppy}. \\ * \var{unsqueeze} & (boolean) Auto-unsqueeze transients/menus/queries/etc. \\ * \var{autoraise} & (boolean) Autoraise regions in groups on goto. \\ * \var{usertime_diff_current} & (integer) Controls switchto timeout. \\ * \var{usertime_diff_new} & (integer) Controls switchto timeout. \\ * \var{autosave_layout} & (boolean) Automatically save layout on restart and exit. \\ * \var{window_stacking_request} & (string) How to respond to window-stacking * requests. \codestr{ignore} to do nothing, * \codestr{activate} to set the activity flag on a * window requesting to be stacked Above. \\ * \var{focuslist_insert_delay} & (integer) Time (in ms) that a window must * stay focused in order to be added to the focus list. * If this value is set <=0, this logic is disabled: * the focus list is updated immediately \\ * \var{activity_notification_on_all_screens} & (boolean) If enabled, activity * notifiers are displayed on ALL the screens, not just * the screen that contains the window producing the * notification. This is only relevant on multi-head * setups. By default this is disabled \\ * \var{workspace_indicator_timeout} & (integer) If enabled, a workspace * indicator comes up at the bottom-left of the screen * when a new workspace is selected. This indicator * stays active for only as long as indicated by this * variable (in ms). Timeout values <=0 disable the * indicator altogether. This is disabled by default \\ * \end{tabularx} * * When a keyboard resize function is called, and at most \var{kbresize_t_max} * milliseconds has passed from a previous call, acceleration factor is reset * to 1.0. Otherwise, if at least \var{kbresize_t_min} milliseconds have * passed from the from previous acceleration update or reset the squere root * of the acceleration factor is incremented by \var{kbresize_step}. The * maximum acceleration factor (pixels/call modulo size hints) is given by * \var{kbresize_maxacc}. The default values are (200, 50, 30, 100). */ EXTL_EXPORT void ioncore_set(ExtlTab tab) { int dd; char *tmp; ExtlFn fn; extl_table_gets_b(tab, "opaque_resize", &(ioncore_g.opaque_resize)); extl_table_gets_b(tab, "warp", &(ioncore_g.warp_enabled)); extl_table_gets_i(tab, "warp_margin", &(ioncore_g.warp_margin)); extl_table_gets_d(tab, "warp_factor_x", &(ioncore_g.warp_factor[0])); extl_table_gets_d(tab, "warp_factor_y", &(ioncore_g.warp_factor[1])); extl_table_gets_b(tab, "switchto", &(ioncore_g.switchto_new)); extl_table_gets_b(tab, "screen_notify", &(ioncore_g.screen_notify)); extl_table_gets_b(tab, "framed_transients", &(ioncore_g.framed_transients)); extl_table_gets_b(tab, "unsqueeze", &(ioncore_g.unsqueeze_enabled)); extl_table_gets_b(tab, "autoraise", &(ioncore_g.autoraise)); extl_table_gets_b(tab, "autosave_layout", &(ioncore_g.autosave_layout)); if(extl_table_gets_s(tab, "window_stacking_request", &tmp)){ ioncore_g.window_stacking_request=stringintmap_value(win_stackrq, tmp, ioncore_g.window_stacking_request); free(tmp); } if(extl_table_gets_s(tab, "frame_default_index", &tmp)){ ioncore_g.frame_default_index=stringintmap_value(frame_idxs, tmp, ioncore_g.frame_default_index); free(tmp); } if(extl_table_gets_s(tab, "mousefocus", &tmp)){ if(strcmp(tmp, "disabled")==0) ioncore_g.no_mousefocus=TRUE; else if(strcmp(tmp, "sloppy")==0) ioncore_g.no_mousefocus=FALSE; free(tmp); } if(extl_table_gets_i(tab, "dblclick_delay", &dd)) ioncore_g.dblclick_delay=MAXOF(0, dd); if(extl_table_gets_i(tab, "usertime_diff_current", &dd)) ioncore_g.usertime_diff_current=MAXOF(0, dd); if(extl_table_gets_i(tab, "usertime_diff_new", &dd)) ioncore_g.usertime_diff_new=MAXOF(0, dd); if(extl_table_gets_i(tab, "focuslist_insert_delay", &dd)) ioncore_g.focuslist_insert_delay=MAXOF(0, dd); if(extl_table_gets_i(tab, "workspace_indicator_timeout", &dd)) ioncore_g.workspace_indicator_timeout=MAXOF(0, dd); extl_table_gets_b(tab, "activity_notification_on_all_screens", &(ioncore_g.activity_notification_on_all_screens)); ioncore_set_moveres_accel(tab); ioncore_groupws_set(tab); /* Internal -- therefore undocumented above */ if(extl_table_gets_f(tab, "_get_winprop", &fn)){ if(get_winprop_fn_set) extl_unref_fn(get_winprop_fn); get_winprop_fn=fn; get_winprop_fn_set=TRUE; } if(extl_table_gets_f(tab, "_get_layout", &fn)){ if(get_layout_fn_set) extl_unref_fn(get_layout_fn); get_layout_fn=fn; get_layout_fn_set=TRUE; } }