Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create virtual input device to allow the use of kloak #194

Merged
merged 24 commits into from Sep 19, 2023

Conversation

skyzzuu
Copy link
Contributor

@skyzzuu skyzzuu commented Aug 26, 2023

Partial resolution of issue QubesOS/qubes-issues#1850. Keyboard events are sent to the virtual input device, but mouse events are not yet.

This creates an input device with the name "Qubes Virtual Input Device" on gui agent startup and translates KeyPress events into EV_KEY events and writes them to /dev/uinput. This allows the use of kloak within a qube.

Mouse events are currently not translated or written to /dev/uinput yet as I'm having trouble getting the cursor in the right location, they are still handled by the feed_xdriver function.

@skyzzuu
Copy link
Contributor Author

skyzzuu commented Aug 26, 2023

When the input device is created, notifications are generated mentioning that qubes.InputKeyboard and qubes.InputMouse were denied originating from the qube that started. The input device still works fine.

This pull request in qubes-app-linux-input-proxy repository stops qubes-input-trigger from running on the virtual input device created, preventing the notifications from being triggered.

QubesOS/qubes-app-linux-input-proxy#30

@marmarek
Copy link
Member

Mouse events are currently not translated or written to /dev/uinput yet as I'm having trouble getting the cursor in the right location, they are still handled by the feed_xdriver function.

You may want to use a device with absolute events (EV_ABS) instead of relative ones. Otherwise it will be quite easy to get out of sync. But if going with relative events anyway, maybe query the current mouse position and move based on that? (be careful about race conditions then: some movement being already queued to the device, but not handled by Xorg yet).

gui-agent/vmside.c Show resolved Hide resolved
gui-agent/vmside.c Outdated Show resolved Hide resolved
@skyzzuu
Copy link
Contributor Author

skyzzuu commented Aug 27, 2023

I'll get those changes implemented. One thing I forgot is that I had to add user to the input group so that xinit had enough permissions to be able to access the device. I'll find the correct repository to implement that and send a pull for that as well. This pull request will be dependent on that request as well once it's in.

@marmarek
Copy link
Member

I'll get those changes implemented. One thing I forgot is that I had to add user to the input group so that xinit had enough permissions to be able to access the device. I'll find the correct repository to implement that and send a pull for that as well. This pull request will be dependent on that request as well once it's in.

It's probably just about adding appropriate udev rule, it can be done in this repo.

… to user so xinit can access the device when it's created
…the qvm-service 'gui-agent-virtual-input-device'
…tual input device creation was requested or not.
@qubesos-bot
Copy link

qubesos-bot commented Aug 29, 2023

OpenQA test summary

Complete test suite and dependencies: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.2&build=2023091804-4.2&flavor=pull-requests

New failures, excluding unstable

Compared to: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.2&build=2023071104-4.2&flavor=update

  • system_tests_pvgrub_salt_storage

    • TC_41_HVMGrub_fedora-38-xfce: test_010_template_based_vm (error)
      qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
  • system_tests_basic_vm_qrexec_gui_xfs

  • system_tests_whonix@hw1

Failed tests

8 failures
  • system_tests_pvgrub_salt_storage

    • [unstable] TC_41_HVMGrub_fedora-38-xfce: test_000_standalone_vm (error)
      qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...

    • TC_41_HVMGrub_fedora-38-xfce: test_010_template_based_vm (error)
      qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...

  • system_tests_splitgpg

  • system_tests_basic_vm_qrexec_gui_zfs

  • system_tests_basic_vm_qrexec_gui_xfs

  • system_tests_whonix@hw1

    • [unstable] whonix_torbrowser: unnamed test (unknown)

    • [unstable] whonix_torbrowser: Failed (test died)
      # Test died: no candidate needle with tag(s) 'anon-whonix-tor-brows...

    • whonix_torbrowser: unnamed test (unknown)

Fixed failures

Compared to: https://openqa.qubes-os.org/tests/77326#dependencies

23 fixed
  • system_tests_whonix

  • system_tests_network

  • system_tests_splitgpg

  • system_tests_manager

    • VMSettingsTest: test_26_default_dispvm (failure)
      self.assertTrue(self.vm.property_... AssertionError: False is not true
  • system_tests_guivm_gui_interactive

    • update_templates: Failed (test died)
      # Test died: command 'curl --form upload=@template-fedora-38-xfce-v...
  • system_tests_qrexec

  • system_tests_network_ipv6

    • VmIPv6Networking_fedora-38: test_040_inter_vm (error)
      qubes.exc.QubesMemoryError: Not enough memory to start domain 'test...

    • VmIPv6Networking_fedora-38: test_203_fake_ip_inter_vm_allow (error)
      qubes.exc.QubesMemoryError: Not enough memory to start domain 'test...

  • system_tests_dispvm

Unstable tests

  • system_tests_whonix

    whonix_torbrowser/ (1/5 times with errors)
    whonix_torbrowser/ (1/5 times with errors)
    whonix_torbrowser/Failed (1/5 times with errors)
    • job 80225 # Test died: no candidate needle with tag(s) 'anon-whonix-tor-brows...
  • system_tests_basic_vm_qrexec_gui

    TC_00_Basic/test_120_start_standalone_with_cdrom_dom0 (1/5 times with errors)
    • job 80971 AssertionError: 1 != 0 : b'Timeout waiting for dom0:loop4 device to...
    TC_20_AudioVM_Pulse_debian-12-xfce/test_221_audio_rec_muted_pulseaudio (1/5 times with errors)
    • job 80238 AssertionError: source-output for VM test-inst-vm1 not found
    TC_20_AudioVM_PipeWire_fedora-38-xfce/test_226_audio_playback_pipewire (1/5 times with errors)
    • job 80839 AssertionError: Command 'pw-play --format=f32 --rate=44100 --channe...
    TC_20_AudioVM_PipeWire_fedora-38-xfce/test_227_audio_rec_muted_pipewire (1/5 times with errors)
    • job 80839 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
    TC_20_AudioVM_PipeWire_fedora-38-xfce/test_228_audio_rec_unmuted_pipewire (1/5 times with errors)
    • job 80839 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
  • system_tests_network

    VmNetworking_debian-12-xfce/test_212_custom_ip_firewall (1/5 times with errors)
    • job 80247 raise exceptions.TimeoutError() from exc... TimeoutError
  • system_tests_pvgrub_salt_storage

    TC_10_VMSalt_fedora-38-xfce/test_000_simple_sls (1/5 times with errors)
    TC_40_PVGrub_debian-12-xfce/test_000_standalone_vm (1/5 times with errors)
    • job 80250 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_41_HVMGrub_debian-12-xfce/test_000_standalone_vm (1/5 times with errors)
    • job 80250 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_41_HVMGrub_fedora-38-xfce/test_000_standalone_vm (4/5 times with errors)
    • job 80250 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    • job 80851 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    • job 80858 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    • job 81879 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_42_PVHGrub_debian-12-xfce/test_000_standalone_vm (1/5 times with errors)
    • job 80250 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_10_VMSalt_fedora-38-xfce/test_001_multi_state_highstate (1/5 times with errors)
    TC_10_VMSalt_fedora-38-xfce/test_003_update (1/5 times with errors)
    TC_40_PVGrub_debian-12-xfce/test_010_template_based_vm (1/5 times with errors)
    • job 80250 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_41_HVMGrub_debian-12-xfce/test_010_template_based_vm (1/5 times with errors)
    • job 80250 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_42_PVHGrub_debian-12-xfce/test_010_template_based_vm (1/5 times with errors)
    • job 80250 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
  • system_tests_splitgpg

    TC_10_Thunderbird_whonix-workstation-17/test_000_send_receive_default (1/5 times with errors)
    • job 79574 ValueError: Namespace Gtk not available for version 3.0
    TC_20_Evolution_debian-12/test_000_send_receive_signed_encrypted (1/5 times with errors)
    • job 79574 dogtail.tree.SearchError: child of [desktop frame | main]: "evoluti...
    TC_10_Thunderbird_whonix-workstation-17/test_010_send_receive_inline_signed_only (1/5 times with errors)
    • job 79574 ValueError: Namespace Gtk not available for version 3.0
    TC_20_Evolution_debian-12/test_010_send_receive_signed_only (1/5 times with errors)
    • job 79574 dogtail.tree.SearchError: child of [desktop frame | main]: "evoluti...
    TC_10_Thunderbird_whonix-workstation-17/test_020_send_receive_inline_with_attachment (5/5 times with errors)
    • job 79574 ValueError: Namespace Gtk not available for version 3.0
    • job 80084 dogtail.tree.SearchError: descendent of [application | Thunderbird]...
    • job 80853 dogtail.tree.SearchError: descendent of [application | Thunderbird]...
    • job 80985 dogtail.tree.SearchError: descendent of [application | Thunderbird]...
    • job 81881 dogtail.tree.SearchError: descendent of [application | Thunderbird]...
  • system_tests_usbproxy

    TC_20_USBProxy_core3_fedora-38-xfce/test_070_attach_not_installed_front (1/5 times with errors)
    • job 80056 qubesusbproxy.core3ext.QubesUSBException: Device attach failed: 202...
    TC_20_USBProxy_core3_whonix-workstation-17/test_070_attach_not_installed_front (1/5 times with errors)
    • job 81882 qubesusbproxy.core3ext.QubesUSBException: Device attach failed: 202...
  • system_tests_qrexec

    TC_00_Qrexec_whonix-workstation-17/test_081_qrexec_service_argument_allow_specific (1/5 times with errors)
    • job 80852 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_00_Qrexec_whonix-gateway-17/test_090_qrexec_service_socket_dom0 (1/5 times with errors)
    • job 80251 AssertionError: service timeout, probably EOF wasn't transferred to...
    TC_00_Qrexec_whonix-workstation-17/test_090_qrexec_service_socket_dom0 (1/5 times with errors)
    • job 80251 AssertionError: service timeout, probably EOF wasn't transferred to...
  • system_tests_network_ipv6

    VmIPv6Networking_fedora-38-xfce/test_540_ipv6_inter_vm (2/5 times with errors)
    • job 80080 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    • job 80991 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
  • system_tests_dispvm

    TC_20_DispVM_whonix-gateway-17/test_010_simple_dvm_run (1/5 times with errors)
    TC_20_DispVM_whonix-workstation-17/test_010_simple_dvm_run (1/5 times with errors)
    • job 81874 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... AssertionError
    TC_20_DispVM_whonix-gateway-17/test_020_gui_app (1/5 times with errors)
    TC_20_DispVM_fedora-38-xfce/test_030_edit_file (1/5 times with errors)
    • job 81874 AssertionError: Timeout while waiting for disp[0-9]* window to show
    TC_20_DispVM_whonix-gateway-17/test_030_edit_file (1/5 times with errors)
    TC_20_DispVM_whonix-workstation-17/test_030_edit_file (3/5 times with errors)
    • job 80075 AssertionError: Timeout while waiting for disp[0-9]* window to show
    • job 80844 AssertionError: Timeout while waiting for disp[0-9]* window to show
    • job 81874 AssertionError: Timeout while waiting for disp[0-9]* window to show
    TC_20_DispVM_fedora-38-xfce/test_100_open_in_dispvm (1/5 times with errors)
    • job 81874 AssertionError: Timeout while waiting for disp[0-9]* window to show
    TC_20_DispVM_whonix-gateway-17/test_100_open_in_dispvm (1/5 times with errors)
    TC_20_DispVM_whonix-workstation-17/test_100_open_in_dispvm (3/5 times with errors)
    • job 80075 AssertionError: Timeout while waiting for disp[0-9]* window to show
    • job 80243 AssertionError: Timeout while waiting for disp[0-9]* window to show
    • job 81874 AssertionError: Timeout while waiting for disp[0-9]* window to show
  • system_tests_basic_vm_qrexec_gui_zfs

    TC_00_Basic/test_120_start_standalone_with_cdrom_dom0 (2/5 times with errors)
    • job 80857 AssertionError: 1 != 0 : b'Timeout waiting for dom0:loop4 device to...
    • job 81872 AssertionError: 1 != 0 : b'Timeout waiting for dom0:loop4 device to...
    TC_06_AppVM_debian-12-xfce-pool/test_121_start_standalone_with_cdrom_vm (1/5 times with errors)
    • job 80226 AssertionError: 1 != 0 : b"Not enough memory to start domain 'test-...
    TC_00_Basic/test_202_udev_block_exclude_default (1/5 times with errors)
    • job 81872 raise exceptions.TimeoutError() from exc... TimeoutError
    TC_20_AudioVM_Pulse_debian-12-xfce-pool/test_222_audio_rec_unmuted_pulseaudio (1/5 times with errors)
    • job 81872 AssertionError: frequency 3379.6121459556007 not in specified range...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_226_audio_playback_pipewire (1/5 times with errors)
    • job 80857 AssertionError: Command 'pw-play --format=f32 --rate=44100 --channe...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_227_audio_rec_muted_pipewire (1/5 times with errors)
    • job 80857 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_228_audio_rec_unmuted_pipewire (1/5 times with errors)
    • job 80857 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
  • system_tests_basic_vm_qrexec_gui_btrfs

    TC_20_AudioVM_Pulse_debian-12-xfce-pool/test_220_audio_play_pulseaudio (1/4 times with errors)
    • job 81808 AssertionError: Command 'paplay --format=float32le --rate=44100 --c...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_226_audio_playback_pipewire (1/4 times with errors)
    • job 80840 AssertionError: Command 'pw-play --format=f32 --rate=44100 --channe...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_227_audio_rec_muted_pipewire (1/4 times with errors)
    • job 80840 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_228_audio_rec_unmuted_pipewire (1/4 times with errors)
    • job 80840 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
  • system_tests_basic_vm_qrexec_gui@hw1

    TC_00_Basic/test_120_start_standalone_with_cdrom_dom0 (1/5 times with errors)
    • job 80971 AssertionError: 1 != 0 : b'Timeout waiting for dom0:loop4 device to...
    TC_20_AudioVM_Pulse_debian-12-xfce/test_221_audio_rec_muted_pulseaudio (1/5 times with errors)
    • job 80238 AssertionError: source-output for VM test-inst-vm1 not found
    TC_20_AudioVM_PipeWire_fedora-38-xfce/test_226_audio_playback_pipewire (1/5 times with errors)
    • job 80839 AssertionError: Command 'pw-play --format=f32 --rate=44100 --channe...
    TC_20_AudioVM_PipeWire_fedora-38-xfce/test_227_audio_rec_muted_pipewire (1/5 times with errors)
    • job 80839 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
    TC_20_AudioVM_PipeWire_fedora-38-xfce/test_228_audio_rec_unmuted_pipewire (1/5 times with errors)
    • job 80839 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
  • system_tests_basic_vm_qrexec_gui_ext4

    TC_30_Gui_daemon/test_000_clipboard (1/5 times with errors)
    • job 80996 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_20_AudioVM_PipeWire_debian-12-xfce-pool/test_226_audio_playback_pipewire (1/5 times with errors)
    • job 81870 AssertionError: Command 'pw-play --format=f32 --rate=44100 --channe...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_226_audio_playback_pipewire (1/5 times with errors)
    • job 80855 AssertionError: Command 'pw-play --format=f32 --rate=44100 --channe...
    TC_20_AudioVM_PipeWire_debian-12-xfce-pool/test_227_audio_rec_muted_pipewire (1/5 times with errors)
    • job 80855 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_227_audio_rec_muted_pipewire (1/5 times with errors)
    • job 80855 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_228_audio_rec_unmuted_pipewire (1/5 times with errors)
    • job 80855 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
  • system_tests_basic_vm_qrexec_gui_xfs

    TC_20_NonAudio_whonix-workstation-17-pool/test_100_qrexec_filecopy (1/5 times with errors)
    • job 79563 self.fail('source file got ... AssertionError: source file got removed
    TC_20_NonAudio_whonix-gateway-17-pool/test_105_qrexec_filemove (1/5 times with errors)
    • job 79563 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_20_NonAudio_whonix-workstation-17-pool/test_105_qrexec_filemove (1/5 times with errors)
    • job 79563 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_20_NonAudio_whonix-gateway-17-pool/test_110_qrexec_filecopy_deny (1/5 times with errors)
    • job 79563 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_20_NonAudio_fedora-38-pool/test_210_time_sync (1/5 times with errors)
    • job 79563 qubes.exc.QubesVMError: Cannot connect to qrexec agent for 120 seco...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_226_audio_playback_pipewire (1/5 times with errors)
    • job 80856 AssertionError: Command 'pw-play --format=f32 --rate=44100 --channe...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_227_audio_rec_muted_pipewire (1/5 times with errors)
    • job 80856 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
    TC_20_AudioVM_PipeWire_fedora-38-xfce-pool/test_228_audio_rec_unmuted_pipewire (1/5 times with errors)
    • job 80856 subprocess.CalledProcessError: Command 'pkill pw-record' returned n...
    TC_20_NonAudio_whonix-gateway-17-pool/test_300_bug_1028_gui_memory_pinning (1/5 times with errors)
    • job 81871 AssertionError: Dom0 window doesn't match VM window content, saved ...
  • system_tests_network_updates

    TC_10_QvmTemplate_whonix-workstation-17/test_000_template_list (1/3 times with errors)
    • job 78831 AssertionError: qvm-template failed: [Qrexec]
    TC_11_QvmTemplateMgmtVM_whonix-workstation-17/test_000_template_list (1/3 times with errors)
    • job 78831 AssertionError: qvm-template failed: ERROR: [Errno 2] No such file ...
    TC_10_QvmTemplate_whonix-workstation-17/test_010_template_install (1/3 times with errors)
    • job 78831 AssertionError: qvm-template failed: [Qrexec]
    TC_11_QvmTemplateMgmtVM_debian-11/test_010_template_install (1/3 times with errors)
    • job 78831 AssertionError: libvirt event impl drain timeout
    TC_11_QvmTemplateMgmtVM_whonix-workstation-17/test_010_template_install (1/3 times with errors)
    • job 78831 AssertionError: qvm-template failed: ERROR: [Errno 2] No such file ...
  • system_tests_whonix@hw1

    whonix_torbrowser/ (1/5 times with errors)
    whonix_torbrowser/ (1/5 times with errors)
    whonix_torbrowser/Failed (1/5 times with errors)
    • job 80225 # Test died: no candidate needle with tag(s) 'anon-whonix-tor-brows...

@skyzzuu skyzzuu requested a review from marmarek August 30, 2023 22:59

feed_xdriver(g, 'K', key.keycode, key.type == KeyPress ? 1 : 0);

if(!g->createdInputDevice) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this way, modifiers are set using Xorg-internal keyboard, while actual key using uinput. It's asking for race conditions, if it works at all (I haven't checked).

Consider following scenario:

  1. You press (and hold) shift
  2. You switch window focus (with a mouse for example)
  3. You press and release A
  4. You release shift

What should happen, is the VM seeing:

  1. press shift
  2. press A
  3. release A
  4. release shift

On the same input device.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I adjusted it now so when virtual input device creation has been requested, modifiers are synced through the uinput fd instead of the xserver fd.

They are completely separate from each other now:

if(virtual input device NOT requested){
// original handle_keypress
} else {
// new handle_keypress (only writes to the uinput fd, never to the xserver fd)
}

Before these changes, all of the modifiers worked correctly when switching between qubes, except when pressing down the modifier and switching into a qube.

Now, all of the following scenarios work as expected:

Start in qube 1
Hold down shift
Switch to qube 2
Start typing while still holding down shift
This results in uppercase characters being typed out into qube 2 as expected

Start in qube 1
Hold down shift
Switch to qube 2
Release shift
Switch back to qube 1
Start typing
This results in lowercase characters being typed out into qube 1 as expected

Open a text file in nano in qube 1
Switch to qube 2
Hold down ctrl
Switch back to qube 1
Press s while still holding down ctrl
nano receives a ctrl+s and attempts to save the file

Modifiers still work exactly as expected when not switching between qubes as well.

… to get that in this PR and will work on it in a future one
… the same naming convention as other variables
…esigned for the virtual input device. When input device creation is requested, modifier sync now happens through the uinput_fd instead of the xserver_fd. All modifiers are working as expected when switching between qubes.
@skyzzuu
Copy link
Contributor Author

skyzzuu commented Sep 8, 2023

I adjusted it now so when virtual input device creation has been requested, modifiers are synced through the uinput fd instead of the xserver fd.

They are completely separate from each other now:

if(virtual input device NOT requested){
// original handle_keypress
} else {
// new handle_keypress (only writes to the uinput fd, never to the xserver fd)
}

Before these changes, all of the modifiers worked correctly when switching between qubes, except when pressing down the modifier and switching into a qube.

Now, all of the following scenarios work as expected:

Start in qube 1
Hold down shift
Switch to qube 2
Start typing while still holding down shift
This results in uppercase characters being typed out into qube 2 as expected

Start in qube 1
Hold down shift
Switch to qube 2
Release shift
Switch back to qube 1
Start typing
This results in lowercase characters being typed out into qube 1 as expected

Open a text file in nano in qube 1
Switch to qube 2
Hold down ctrl
Switch back to qube 1
Press s while still holding down ctrl
nano receives a ctrl+s and attempts to save the file

Modifiers still work exactly as expected when not switching between qubes as well.

Copy link
Member

@marmarek marmarek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionally it looks mostly fine now (with remarks below). But last commits introduced several repeated blank lines and whitespaces at the end of empty lines. There is also small merge conflict now, please rebase on the updated main branch.

@@ -0,0 +1 @@
ATTRS{name}=="Qubes Virtual Input Device", ACTION=="add", GROUP="user"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is not installed anywhere (add it to makefile, and then both rpm spec file and debian "install" file).
And it should be GROUP="qubes"

@@ -285,6 +295,29 @@ static int compare_supported_cursors(const void *a,
((struct supported_cursor *)b)->name);
}


void send_event(Ghandles * g, const struct input_event *iev) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void send_event(Ghandles * g, const struct input_event *iev) {
static void send_event(Ghandles * g, const struct input_event *iev) {


// set all keys
for(int i = 1; i < KEY_MAX; i++) {
if(i != KEY_RESERVED && ioctl(g.uinput_fd, UI_SET_KEYBIT, i) < 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With all keys set, udev (and so Xorg) detects this as a combo keyboard+mouse device now. See udevadm info -q all -n /dev/input/event1 (or whatever device node it will get). It should not have ID_INPUT_MOUSE set. I guess you need to exclude BTN_* range (BTN_MISC .. BTN_GEAR_UP - various buttons of mouses, tablets, game pads etc)

… to install the file in Makefile, appvm-scripts/lib/udev/rules.d/90-qubes-virtual-input-device.rules, debian/qubes-gui-agent.install, and rpm_spec/gui-agent.spec.in
@marmarek
Copy link
Member

marmarek commented Sep 9, 2023

You still need to rebase to resolve the conflict.

skyzzuu and others added 2 commits September 9, 2023 16:55
…solved. Removed that line since the variable is unused and stops the build
@skyzzuu
Copy link
Contributor Author

skyzzuu commented Sep 9, 2023

It should be all set now.

@marmarek
Copy link
Member

I did some more tests and Caps Lock behaves funny. When it's enabled, only some letter are capital, not all. But disabling it when the VM has focus doesn't seems to work (then, all letters typed into VM are capital). I guess it's related to modifiers sync, as this one is press-and-release to change the state, not press-and-hold.

@skyzzuu
Copy link
Contributor Author

skyzzuu commented Sep 10, 2023

Got it working now. The line to flip its associated bit in last_known_modifier_states was missing and caps lock needed to be excluded from key press/release below.

iev.type = EV_KEY;
// only used in here to see if modifier is disabled
XModifierKeymap *modmap;
modmap = XGetModifierMapping(g->display);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to handle also when this call fails (see above).

}
}
}

if(key.keycode-8 != KEY_CAPSLOCK) {
XFreeModifiermap(modmap);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

freeing should be outside of this if, no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants