@@ -2368,6 +2368,85 @@ xkb_state_machine_options_shortcuts_set_mapping(
23682368 source , target );
23692369}
23702370
2371+ static bool
2372+ state_machine_set_shortcuts (struct xkb_state_machine * sm ,
2373+ const struct xkb_shortcuts_config_options * options );
2374+
2375+ static bool
2376+ get_shortcuts_config_from_env (struct xkb_keymap * keymap ,
2377+ struct xkb_shortcuts_config_options * config )
2378+ {
2379+ /*
2380+ * Modifier mask
2381+ */
2382+
2383+ const char * config_str = xkb_context_getenv (
2384+ keymap -> ctx , "XKB_UNSTABLE_EXPERIMENTAL_SHORTCUT_MASK"
2385+ );
2386+ xkb_mod_mask_t mask = 0 ;
2387+ if (isempty (config_str )) {
2388+ /* Use default mask */
2389+ xkb_mod_index_t mod ;
2390+ mod = xkb_keymap_mod_get_index (keymap , XKB_MOD_NAME_CTRL );
2391+ if (mod != XKB_MOD_INVALID )
2392+ mask |= (UINT32_C (1 ) << mod );
2393+ mod = xkb_keymap_mod_get_index (keymap , XKB_VMOD_NAME_ALT );
2394+ if (mod != XKB_MOD_INVALID )
2395+ mask |= (UINT32_C (1 ) << mod );
2396+ mod = xkb_keymap_mod_get_index (keymap , XKB_VMOD_NAME_SUPER );
2397+ if (mod != XKB_MOD_INVALID )
2398+ mask |= (UINT32_C (1 ) << mod );
2399+ } else {
2400+ char * endptr = NULL ;
2401+ const unsigned long raw_mask = strtoul (config_str , & endptr , 16 );
2402+ if (endptr [0 ] != '\0' || raw_mask > UINT32_MAX ) {
2403+ log_err (keymap -> ctx , XKB_LOG_MESSAGE_NO_ID ,
2404+ "Cannot parse shortcut tweak mod mask\n" );
2405+ return true;
2406+ }
2407+ mask = (xkb_mod_mask_t ) raw_mask ;
2408+ }
2409+
2410+ mask = mod_mask_get_effective (keymap , mask );
2411+ config -> mask = mask ;
2412+
2413+ if (!mask )
2414+ return true;
2415+
2416+ /*
2417+ * Layout mappings
2418+ */
2419+
2420+ config_str = xkb_context_getenv (
2421+ keymap -> ctx , "XKB_UNSTABLE_EXPERIMENTAL_SHORTCUT_TARGET_LAYOUTS"
2422+ );
2423+ if (isempty (config_str ))
2424+ return true;
2425+ const char * start = config_str ;
2426+ xkb_layout_index_t layout = 0 ;
2427+ /* Parse comma-separated list of layout indexes */
2428+ while (start [0 ] != '\0' ) {
2429+ char * endptr = NULL ;
2430+ const unsigned long raw_layout = strtoul (start , & endptr , 10 );
2431+ if ((endptr [0 ] != '\0' && endptr [0 ] != ',' ) ||
2432+ raw_layout < 1 || raw_layout > XKB_MAX_GROUPS ||
2433+ state_machine_set_shortcuts_reference_layout (
2434+ config , layout , (xkb_layout_index_t ) raw_layout - 1 )) {
2435+ log_err (keymap -> ctx , XKB_LOG_MESSAGE_NO_ID ,
2436+ "Cannot parse shortcut tweak layout index #%" PRIu32 "\n" ,
2437+ layout );
2438+ return false;
2439+ }
2440+ fprintf (stderr , "~~~ %u -> %lu - %s\n" , layout , raw_layout , endptr );
2441+ layout ++ ;
2442+ if (endptr [0 ] == '\0' )
2443+ break ;
2444+ start = endptr + 1 ;
2445+ }
2446+
2447+ return true;
2448+ }
2449+
23712450static bool
23722451state_machine_set_shortcuts (struct xkb_state_machine * sm ,
23732452 const struct xkb_shortcuts_config_options * options )
@@ -2441,6 +2520,19 @@ xkb_state_machine_new(struct xkb_keymap *keymap,
24412520 if (!darray_empty (options -> shortcuts .targets )) {
24422521 if (!state_machine_set_shortcuts (sm , & options -> shortcuts ))
24432522 goto error ;
2523+ } else {
2524+ // FIXME: remove after experimentation
2525+ struct xkb_shortcuts_config_options config = {
2526+ .mask = 0 ,
2527+ .targets = darray_new ()
2528+ };
2529+ if (get_shortcuts_config_from_env (keymap , & config )) {
2530+ if (!state_machine_set_shortcuts (sm , & config )) {
2531+ darray_free (config .targets );
2532+ goto error ;
2533+ }
2534+ }
2535+ darray_free (config .targets );
24442536 }
24452537
24462538 return sm ;
0 commit comments