@@ -374,6 +374,82 @@ test_explicit_actions(struct xkb_context *ctx)
374
374
}
375
375
}
376
376
377
+ static void
378
+ test_simultaneous_modifier_clear (struct xkb_context * context )
379
+ {
380
+ struct xkb_keymap * keymap ;
381
+
382
+ keymap = test_compile_rules (context , "evdev" , "pc104" ,
383
+ "simultaneous-mods-latches" , "" , "" );
384
+ assert (keymap );
385
+
386
+ /*
387
+ * Github issue #583: simultaneous latches of *different* modifiers should
388
+ * not affect each other when clearing their mods.
389
+ */
390
+
391
+ /* Original key sequence reported in the issue */
392
+ assert (test_key_seq (keymap ,
393
+ KEY_LEFTCTRL , DOWN , XKB_KEY_Control_L , NEXT , /* Set Control */
394
+ KEY_RIGHTALT , BOTH , XKB_KEY_ISO_Level5_Latch , NEXT , /* Latch Level5 */
395
+ KEY_LEFTCTRL , UP , XKB_KEY_Control_L , NEXT , /* Unset Control */
396
+ KEY_RIGHTALT , BOTH , XKB_KEY_ISO_Level3_Latch , NEXT , /* Latch Level3 */
397
+ KEY_Z , BOTH , XKB_KEY_ydiaeresis , NEXT , /* Unlatch Level3, unlatch Level5 */
398
+ KEY_Z , BOTH , XKB_KEY_z , NEXT ,
399
+ KEY_Z , BOTH , XKB_KEY_z , FINISH
400
+ ));
401
+
402
+ /* Alternative key sequence with only mod latches */
403
+ assert (test_key_seq (keymap ,
404
+ KEY_RIGHTCTRL , BOTH , XKB_KEY_Control_R , NEXT , /* Latch Control */
405
+ KEY_RIGHTALT , BOTH , XKB_KEY_ISO_Level5_Latch , NEXT , /* Latch Level5 */
406
+ KEY_LEFTMETA , BOTH , XKB_KEY_ISO_Level3_Latch , NEXT , /* Latch Level3 */
407
+ KEY_Z , BOTH , XKB_KEY_ydiaeresis , NEXT , /* Unlatch Control, Level3 and Level5 */
408
+ KEY_Z , BOTH , XKB_KEY_z , NEXT ,
409
+ KEY_Z , BOTH , XKB_KEY_z , NEXT ,
410
+ KEY_X , BOTH , XKB_KEY_x , FINISH
411
+ ));
412
+
413
+ /* Alternative simplier key sequence */
414
+ assert (test_key_seq (keymap ,
415
+ KEY_LEFTMETA , BOTH , XKB_KEY_ISO_Level3_Latch , NEXT , /* Latch Level3 */
416
+ KEY_RIGHTMETA , BOTH , XKB_KEY_ISO_Level5_Latch , NEXT , /* Latch Level5 */
417
+ KEY_Z , BOTH , XKB_KEY_ydiaeresis , NEXT , /* Unlatch Level3, unlatch Level5 */
418
+ KEY_Z , BOTH , XKB_KEY_z , NEXT ,
419
+ KEY_Z , BOTH , XKB_KEY_z , FINISH
420
+ ));
421
+
422
+ /*
423
+ * Test same modifier latch but on a different key
424
+ */
425
+
426
+ /* Level 3 */
427
+ assert (test_key_seq (keymap ,
428
+ KEY_LEFTMETA , BOTH , XKB_KEY_ISO_Level3_Latch , NEXT , /* Latch Level3 */
429
+ KEY_RIGHTALT , BOTH , XKB_KEY_ISO_Level3_Latch , NEXT , /* Lock Level3 via latch */
430
+ KEY_Z , BOTH , XKB_KEY_y , NEXT , /* Locked Level3 */
431
+ KEY_Z , BOTH , XKB_KEY_y , NEXT ,
432
+ KEY_RIGHTALT , BOTH , XKB_KEY_ISO_Level3_Latch , NEXT , /* Unlock Level3 via latch */
433
+ KEY_Z , BOTH , XKB_KEY_z , NEXT ,
434
+ KEY_Z , BOTH , XKB_KEY_z , FINISH
435
+ ));
436
+
437
+ /* Level 5, via Control latch */
438
+ assert (test_key_seq (keymap ,
439
+ KEY_RIGHTCTRL , BOTH , XKB_KEY_Control_R , NEXT , /* Latch Control */
440
+ KEY_RIGHTALT , BOTH , XKB_KEY_ISO_Level5_Latch , NEXT , /* Lock Level5 via latch */
441
+ KEY_RIGHTMETA , BOTH , XKB_KEY_ISO_Level5_Latch , NEXT , /* Latch Level5 */
442
+ KEY_Z , BOTH , XKB_KEY_ezh , NEXT , /* Locked Level5 */
443
+ KEY_Z , BOTH , XKB_KEY_ezh , NEXT ,
444
+ KEY_RIGHTMETA , BOTH , XKB_KEY_ISO_Level5_Latch , NEXT , /* Unlock Level5 via latch */
445
+ KEY_Z , BOTH , XKB_KEY_z , NEXT ,
446
+ KEY_Z , BOTH , XKB_KEY_z , NEXT ,
447
+ KEY_X , BOTH , XKB_KEY_x , FINISH
448
+ ));
449
+
450
+ xkb_keymap_unref (keymap );
451
+ }
452
+
377
453
int
378
454
main (void )
379
455
{
@@ -384,6 +460,7 @@ main(void)
384
460
385
461
assert (ctx );
386
462
463
+ test_simultaneous_modifier_clear (ctx );
387
464
test_group_latch (ctx );
388
465
test_explicit_actions (ctx );
389
466
@@ -839,5 +916,5 @@ main(void)
839
916
840
917
xkb_keymap_unref (keymap );
841
918
xkb_context_unref (ctx );
842
- return 0 ;
919
+ return EXIT_SUCCESS ;
843
920
}
0 commit comments