@@ -2413,6 +2413,85 @@ xkb_state_machine_options_shortcuts_set_mapping(
24132413 source , target );
24142414}
24152415
2416+ static bool
2417+ state_machine_set_shortcuts (struct xkb_state_machine * sm ,
2418+ const struct xkb_shortcuts_config_options * options );
2419+
2420+ static bool
2421+ get_shortcuts_config_from_env (struct xkb_keymap * keymap ,
2422+ struct xkb_shortcuts_config_options * config )
2423+ {
2424+ /*
2425+ * Modifier mask
2426+ */
2427+
2428+ const char * config_str = xkb_context_getenv (
2429+ keymap -> ctx , "XKB_UNSTABLE_EXPERIMENTAL_SHORTCUT_MASK"
2430+ );
2431+ xkb_mod_mask_t mask = 0 ;
2432+ if (isempty (config_str )) {
2433+ /* Use default mask */
2434+ xkb_mod_index_t mod ;
2435+ mod = xkb_keymap_mod_get_index (keymap , XKB_MOD_NAME_CTRL );
2436+ if (mod != XKB_MOD_INVALID )
2437+ mask |= (UINT32_C (1 ) << mod );
2438+ mod = xkb_keymap_mod_get_index (keymap , XKB_VMOD_NAME_ALT );
2439+ if (mod != XKB_MOD_INVALID )
2440+ mask |= (UINT32_C (1 ) << mod );
2441+ mod = xkb_keymap_mod_get_index (keymap , XKB_VMOD_NAME_SUPER );
2442+ if (mod != XKB_MOD_INVALID )
2443+ mask |= (UINT32_C (1 ) << mod );
2444+ } else {
2445+ char * endptr = NULL ;
2446+ const unsigned long raw_mask = strtoul (config_str , & endptr , 16 );
2447+ if (endptr [0 ] != '\0' || raw_mask > UINT32_MAX ) {
2448+ log_err (keymap -> ctx , XKB_LOG_MESSAGE_NO_ID ,
2449+ "Cannot parse shortcut tweak mod mask\n" );
2450+ return true;
2451+ }
2452+ mask = (xkb_mod_mask_t ) raw_mask ;
2453+ }
2454+
2455+ mask = mod_mask_get_effective (keymap , mask );
2456+ config -> mask = mask ;
2457+
2458+ if (!mask )
2459+ return true;
2460+
2461+ /*
2462+ * Layout mappings
2463+ */
2464+
2465+ config_str = xkb_context_getenv (
2466+ keymap -> ctx , "XKB_UNSTABLE_EXPERIMENTAL_SHORTCUT_TARGET_LAYOUTS"
2467+ );
2468+ if (isempty (config_str ))
2469+ return true;
2470+ const char * start = config_str ;
2471+ xkb_layout_index_t layout = 0 ;
2472+ /* Parse comma-separated list of layout indexes */
2473+ while (start [0 ] != '\0' ) {
2474+ char * endptr = NULL ;
2475+ const unsigned long raw_layout = strtoul (start , & endptr , 10 );
2476+ if ((endptr [0 ] != '\0' && endptr [0 ] != ',' ) ||
2477+ raw_layout < 1 || raw_layout > XKB_MAX_GROUPS ||
2478+ state_machine_set_shortcuts_reference_layout (
2479+ config , layout , (xkb_layout_index_t ) raw_layout - 1 )) {
2480+ log_err (keymap -> ctx , XKB_LOG_MESSAGE_NO_ID ,
2481+ "Cannot parse shortcut tweak layout index #%" PRIu32 "\n" ,
2482+ layout );
2483+ return false;
2484+ }
2485+ fprintf (stderr , "~~~ %u -> %lu - %s\n" , layout , raw_layout , endptr );
2486+ layout ++ ;
2487+ if (endptr [0 ] == '\0' )
2488+ break ;
2489+ start = endptr + 1 ;
2490+ }
2491+
2492+ return true;
2493+ }
2494+
24162495static bool
24172496state_machine_set_shortcuts (struct xkb_state_machine * sm ,
24182497 const struct xkb_shortcuts_config_options * options )
@@ -2485,6 +2564,19 @@ xkb_state_machine_new(struct xkb_keymap *keymap,
24852564 if (!darray_empty (options -> shortcuts .targets )) {
24862565 if (!state_machine_set_shortcuts (sm , & options -> shortcuts ))
24872566 goto error ;
2567+ } else {
2568+ // FIXME: remove after experimentation
2569+ struct xkb_shortcuts_config_options config = {
2570+ .mask = 0 ,
2571+ .targets = darray_new ()
2572+ };
2573+ if (get_shortcuts_config_from_env (keymap , & config )) {
2574+ if (!state_machine_set_shortcuts (sm , & config )) {
2575+ darray_free (config .targets );
2576+ goto error ;
2577+ }
2578+ }
2579+ darray_free (config .targets );
24882580 }
24892581
24902582 return sm ;
0 commit comments