Skip to content

Inconsistent virtual_keycode on macOS and OpenBSD #2032

@afh

Description

@afh

While using alacritty on macOS and OpenBSD I notice a difference in the keybinding configuration, where some keybindings working on macOS are not working on OpenBSD.
The helpful folks in the #alacritty Libera.Chat channel pointed me to this repository and suggested that the issue that I run into might be related to a missing (platform) mapping in this repository, which alacritty uses as a dependency.

I modified the examples/resizable.rs in order to provide a Minimal Working Example (MWE) (see below).

Note that on OpenBSD I am using the us.swapctrlcaps keyboard layout, have assigned the physical Control left of the spacebar to Hyper_L using keycode 37 = Hyper_L in ~/.Xmodmap (this should not matter though as the tests below only use the Command key), and have swapped the left logo key with the left alt key in order to match macOS' layout where the left Command key is left of the space bar and the left Alt (Option) key is to the left of the left Command key resulting in: Alt Command Space

OpenBSD macOS
sw_vers -productVersion 11.6
uname -r 6.9 20.6.0
rustc --version 1.51.0 1.51.0

I've tested the MWE on both macOS and OpenBSD as follows:

  • Place the Cargo.toml and src/main.rs files (see below) in a separate directory for testing
  • Build and run the MWE: cargo build && ./target/debug/winit-key-test on macOS and OpenBSD
  • Press the keys as shown in the table below and compare the output of the MWE on macOS and OpenBSD
  • I would expect the following keycodes (also highlighted in bold in the MWE Keycode Comparison table below) to be the same across platforms:
Key(s) OpenBSD macOS
Shift + 8 Asterisk Key8
Command + Shift + 8 Asterisk Key8
Shift + [ None LBracket
Shift + ] None RBracket
Command + Shift + [ None LBracket
Command + Shift + ] None RBracket
Detailed MWE Keycode Comparison Between OpenBSD and macOS
Key(s) OpenBSD macOS
Command (Key left of the spacebar) scancode: 56, keycode: None, modifiers: LOGO scancode: 55, keycode: Some(LWin), modifiers: LOGO
Alt (Key left of Command) scancode: 107, keycode: Some(LAlt), modifiers: ALT scancode: 58, keycode: Some(LAlt), modifiers: ALT
Shift scancode: 42, keycode: Some(LShift), modifiers: SHIFT scancode: 56, keycode: Some(LShift), modifiers: SHIFT
8 scancode: 9, keycode: Some(Key8), modifiers: (empty) scancode: 28, keycode: Some(Key8), modifiers: (empty)
Shift + 8 scancode: 9, keycode: Some(Asterisk), modifiers: SHIFT scancode: 28, keycode: Some(Key8), modifiers: SHIFT
Command + Shift + 8 scancode: 9, keycode: Some(Asterisk), modifiers: SHIFT | LOGO scancode: 28, keycode: Some(Key8), modifiers: SHIFT | LOGO
[ scancode: 26, keycode: Some(LBracket), modifiers: (empty) scancode: 33, keycode: Some(LBracket), modifiers: (empty)
] scancode: 27, keycode: Some(LBracket), modifiers: (empty) scancode: 30, keycode: Some(LBracket), modifiers: (empty)
Shift + [ scancode: 26, keycode: None, modifiers: SHIFT scancode: 33, keycode: Some(LBracket), modifiers: SHIFT
Shift + ] scancode: 26, keycode: None, modifiers: SHIFT scancode: 30, keycode: Some(LBracket), modifiers: SHIFT
Command + Shift + [ scancode: 26, keycode: None, modifiers: SHIFT | LOGO scancode: 33, keycode: Some(LBracket), modifiers: SHIFT | LOGO
Command + Shift + ] scancode: 27, keycode: None, modifiers: SHIFT | LOGO scancode: 30, keycode: Some(LBracket), modifiers: SHIFT | LOGO

Minimal Working Example

Cargo.toml
[package]
name = "winit-key-test"
version = "0.1.0"
edition = "2018"

[dependencies]
winit = "0.25.0"
src/main.rs
// Adapted from examples/resizable.rs
use winit::{
    dpi::LogicalSize,
    event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::WindowBuilder,
};

fn main() {
    let event_loop = EventLoop::new();

    let mut resizable = false;

    let window = WindowBuilder::new()
        .with_title("Displaying KeyboardInput")
        .with_inner_size(LogicalSize::new(400.0, 200.0))
        .with_resizable(resizable)
        .build(&event_loop)
        .unwrap();

    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Wait;

        match event {
            Event::WindowEvent { event, .. } => match event {
                WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
                WindowEvent::KeyboardInput {
                    input, ..
                } => {
                    if input.state != ElementState::Pressed {
                        return;
                    }
                    println!("scancode: {scancode:>sw$}, keycode: {keycode:?}, modifiers: {modifiers:?}"
                             , scancode=input.scancode, sw=3
                             , keycode=input.virtual_keycode
                             , modifiers=input.modifiers);
                }
                _ => (),
            },
            _ => (),
        };
    });
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    DS - appkitAffects the AppKit/macOS backendDS - x11Affects the X11 backend, or generally free Unix platforms

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions