Why `xev -root -event property` shows duplicate events? It breaks keyboard layout

Currently in R4.1 keyboard layout switch is applied and propagated by reacting on XKLAVIER_ALLOW_SECONDARY property being changed in dom0, this changes can be monitored with command:
xev -root -event property

Keyboard layout switch shortcut causes property change of XKLAVIER_ALLOW_SECONDARY appear in the output of this command. That is expected.

But it happens twice! And not in one moment, but sometimes even with time gap up to a second. It breaks keyboard layout switch sometimes, if user switches between active windows at that moment.

Does anybody know why almost all property events a duplicated in this output?

Example of output (I added a couple of new lines for grouping)
[dom0 ~]$ xev -root -event property

PropertyNotify event, serial 18, synthetic NO, window 0x544,
    atom 0x1ee (XKLAVIER_ALLOW_SECONDARY), time 3435915, state PropertyNewValue

PropertyNotify event, serial 19, synthetic NO, window 0x544,
    atom 0x1ee (XKLAVIER_ALLOW_SECONDARY), time 3435916, state PropertyNewValue

    
PropertyNotify event, serial 19, synthetic NO, window 0x544,
    atom 0x1a3 (_NET_CLIENT_LIST_STACKING), time 3442978, state PropertyNewValue

    
PropertyNotify event, serial 20, synthetic NO, window 0x544,
    atom 0x154 (_NET_ACTIVE_WINDOW), time 3443069, state PropertyNewValue

PropertyNotify event, serial 20, synthetic NO, window 0x544,
    atom 0x154 (_NET_ACTIVE_WINDOW), time 3443069, state PropertyNewValue

    
PropertyNotify event, serial 20, synthetic NO, window 0x544,
    atom 0x1ee (XKLAVIER_ALLOW_SECONDARY), time 3443081, state PropertyNewValue

PropertyNotify event, serial 21, synthetic NO, window 0x544,
    atom 0x1ee (XKLAVIER_ALLOW_SECONDARY), time 3443108, state PropertyNewValue

    
PropertyNotify event, serial 21, synthetic NO, window 0x544,
    atom 0x1a3 (_NET_CLIENT_LIST_STACKING), time 3443542, state PropertyNewValue

    
PropertyNotify event, serial 21, synthetic NO, window 0x544,
    atom 0x154 (_NET_ACTIVE_WINDOW), time 3443550, state PropertyNewValue

PropertyNotify event, serial 21, synthetic NO, window 0x544,
    atom 0x154 (_NET_ACTIVE_WINDOW), time 3443550, state PropertyNewValue

    
PropertyNotify event, serial 24, synthetic NO, window 0x544,
    atom 0x1ee (XKLAVIER_ALLOW_SECONDARY), time 3932489, state PropertyNewValue

PropertyNotify event, serial 24, synthetic NO, window 0x544,
    atom 0x1ee (XKLAVIER_ALLOW_SECONDARY), time 3932491, state PropertyNewValue

See also:

1 Like

Thank you, that is my issue ticket :slight_smile:

I solved this Capslock/Shift+Capslock (and two shortcuts for 2 layouts in general) problem. It is done with a source code hack (and may be broken on updates), but nonetheless now I have much more pleasant experience.

Now I am trying to fix minor layout switch issues of R4.1+, one of them being this one with property events being fired twice for some reason.

1 Like

It’s not the duplicate events that are causing this issue.
The same duplicate events are generated in Fedora 37 Xfce.
The second event is coming from Keyboard Layouts xfce panel item. If you remove it from the panel you’ll have a single XKLAVIER_ALLOW_SECONDARY event but the issue will persist.

1 Like

Hmm, not getting it. What issue exactly you mean?

Double events is an issue by itself, there are 2 events, separated by time gap (like a second) that causes Qubes OS to process layout change twice, the second time incorrectly (because the active qube can change during the time gap). Do you know a way to filter the second event (raised by xfce panel)? Maybe it has some difference in the raising that would allow to distinguish and ignore it.

Also, why xfce panel sends it the second time anyway?

I meant this issue:

Even if there is no double events (if you remove the Keyboard Layouts xfce panel item) you’ll still have the same issue with broken layout change.

Not sure how Xorg works, but it has the same behavior on Fedora/Debian and I don’t know if it’s a bug or not.

1 Like

I’ve tried to test this layout change issue in Qubes OS installed in VM with qubes running in PV mode and the layout change happens almost instantly without an issue compared to the Qubes OS installed on real hardware, where there seems to be something like a few seconds (~6?) timeout between the layout changes where it could be switched without an issue.
But even in Qubes OS running in VM the issue is present, if you press the layout change key very fast it’ll break as well.
So maybe this issue is somehow related to hardware.

1 Like

Well, there were 3-4 issues with keyboard layout switch in R4.1. Most of them are fixed (but maybe for R4.2 only, no backport?). This double even issue is still in place.

This doubled events issue is Qubes OS specific because Qubes OS reacts on this event calling propagation of keyboard layout switch to the active qube. Upstream Fedora does not do this, it does not require to react to this events (only for showing current layout in the tray), so 2+ events would not affect Fedora, it is just a problem for Qubes OS because it reacts to this (see qvm_start_deamon.py).

R4.2 or R4.1.?

I thought this as well but as I’ve said the double events seems to be unrelated to layout change breaking.
Try it yourself:

  • remove the Keyboard Layouts item from your xfce panel
  • run xev -root -event property
  • try to switch your keyboard layout and see it’s not switching properly in qubes if you switch it fast enough
  • at the same time xev output will show you only one XKLAVIER_ALLOW_SECONDARY event per key press

R4.2

Well, I am still on R4.1 with manually modified qvm_start_deamon.py (I did changes before it was fixed upstream). So, testing by me in this case will not be valuable.

Will the single event be instant in the output for you?

Maybe indeed there is another problem with Qubes OS catching and processing this event too slow on your hardware. Looks strange non the less. Do you know python? I was making simple changes to python files on the system (keeping original copies) to log what was happening in my case.

I’ve patched the qvm_start_daemon.py to print debug output:

--- /usr/lib/python3.11/site-packages/qubesadmin/tools/qvm_start_daemon.py.orig        2023-11-23 08:21:03.228338898 +0000
+++ /usr/lib/python3.11/site-packages/qubesadmin/tools/qvm_start_daemon.py        2023-11-23 08:15:06.660360923 +0000
@@ -253,12 +253,15 @@
 
         if new_property != current_property:
             self.current_vm.keyboard_layout = new_property
+        print("cur",current_property,"new",new_property)
 
     def event_reader(self, callback):
         """Poll for X events related to keyboard layout"""
         try:
             for event in iter(self.conn.poll_for_event, None):
                 if isinstance(event, xcffib.xproto.PropertyNotifyEvent):
+                    ev_attrs=vars(event)
+                    print(', '.join("%s: %s" % item for item in ev_attrs.items()))
                     if event.atom == self.atom_xklavier:
                         self.selected_layout = self.get_selected_layout()
                     elif event.atom == self.atom_xkb_rules:

And when I press the keyboard layout switch key I’m getting the event in xev instantly:

PropertyNotify event, serial 26, synthetic NO, window 0x7a2,
    atom 0x1ff (XKLAVIER_ALLOW_SECONDARY), time 253336665, state PropertyNewValue

And I’m getting this event in event_reader() in qvm_start_daemon.py instantly as well:

response_type: 28, sequence: 15, window: 1954, atom: 511, time: 253336665, state: 0, bufsize: 20

But the update_keyboard_layout() is called ~2 seconds later:

cur  XX++  new  us++

If I press keyboard layout switch key quickly then it’ll break the layout:
Instantly xev:

PropertyNotify event, serial 26, synthetic NO, window 0x7a2,
    atom 0x1ff (XKLAVIER_ALLOW_SECONDARY), time 253448297, state PropertyNewValue

PropertyNotify event, serial 26, synthetic NO, window 0x7a2,
    atom 0x1ff (XKLAVIER_ALLOW_SECONDARY), time 253448427, state PropertyNewValue

Instantly in qvm_start_daemon.py debug output:

response_type: 28, sequence: 16, window: 1954, atom: 511, time: 253448297, state: 0, bufsize: 20

~Two seconds delay and instantly all 3 lines:

cur  us++  new  XX++
response_type: 28, sequence: 17, window: 1954, atom: 511, time: 253448427, state: 0, bufsize: 20
cur  us++  new  us++
1 Like

It seems to be stuck for these few seconds in update_keyboard_layout() when executing this line:

self.current_vm.keyboard_layout = new_property

Well done! As I understand, you avoided the second event call with removing xfce panel widget, so you definitely have different bug. If you manage to profile the place where this 2 seconds are lost, it will help a lot. Because it can be related to your hardware, I have no such delay on R4.1, it seems.

Otherwise report it on github with all these valuable details.

Thanks for the info, I’ll try the R4.1 on this hardware if I won’t be able to trace the issue.
I’ll open the issue on github when I’ll get more info.

It probably calls _setter_kbd_layout() from qubesvm.py. Maybe you can add logs there.