rust-windowing / winit

Window handling library in pure Rust

Home Page:https://docs.rs/winit/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"The other" modifier key press is not being detected

junglie85 opened this issue · comments

What's the deal with modifier keys?

The keyboard input event does not detect when a second version of a modifier is pressed if the first version is already pressed. e.g. if holding left shift, the press of right shift is not detected. It's then possible whilst holding right shift to release left shift and this will not be detected either. The release is recorded when the right shift is finally released. This gives a key sequence of Left-Shift pressed -> Right Shift released.

Having experimented, the modifiers do not handle this either. It's the same for Alt, Ctrl and Super.

Should it be possible to detect when the same key in a different location is pressed? I'm on Windows, I don't know if this happens elsewhere.

The button itself has a position attached to it, so you can detect from KeyEvent whether you've pressed left/right shift. There's no state as double/single shift, because it doesn't matter.

If you want to detect double shift, check for Shift with the Shift modifier applied to it.

So from what I can say everything is detected and consistent, unless you don't have KeyboardInput for left/right shift when you press them.

[age\src\app.rs:165] &event = KeyEvent {
    physical_key: Code(
        ShiftLeft,
    ),
    logical_key: Named(
        Shift,
    ),
    text: None,
    location: Left,
    state: Pressed,
    repeat: false,
    platform_specific: KeyEventExtra {
        text_with_all_modifers: None,
        key_without_modifiers: Named(
            Shift,
        ),
    },
}
[age\src\app.rs:165] &event = KeyEvent {
    physical_key: Code(
        ShiftRight,
    ),
    logical_key: Named(
        Shift,
    ),
    text: None,
    location: Right,
    state: Pressed,
    repeat: true,
    platform_specific: KeyEventExtra {
        text_with_all_modifers: None,
        key_without_modifiers: Named(
            Shift,
        ),
    },
}
[age\src\app.rs:165] &event = KeyEvent {
    physical_key: Code(
        ShiftLeft,
    ),
    logical_key: Named(
        Shift,
    ),
    text: None,
    location: Left,
    state: Released,
    repeat: false,
    platform_specific: KeyEventExtra {
        text_with_all_modifers: None,
        key_without_modifiers: Named(
            Shift,
        ),
    },
}

But these are 2 separate keys, so I'd expect 2 pressed events and 2 released events. Yes, there are 2 pressed events, but why is the second a repeat, when it is a different key?

That just sounds like a windows specific issue, which you should open a separate issue for.

The modifiers are delevired via the ModifiersChanged event anyway.

So why have modifier info in both keyboard input and modifier changed events? That's pretty confusing.

[age\src\os.rs:270] _modifiers = Modifiers {
    state: ModifiersState(
        SHIFT,
    ),
    pressed_mods: ModifiersKeys(
        0x0,
    ),
}
[age\src\os.rs:271] _modifiers.lshift_state() == winit::keyboard::ModifiersKeyState::Pressed = false
[age\src\os.rs:272] _modifiers.rshift_state() == winit::keyboard::ModifiersKeyState::Pressed = false
[age\src\os.rs:270] _modifiers = Modifiers {
    state: ModifiersState(
        0x0,
    ),
    pressed_mods: ModifiersKeys(
        0x0,
    ),
}
[age\src\os.rs:271] _modifiers.lshift_state() == winit::keyboard::ModifiersKeyState::Pressed = false
[age\src\os.rs:272] _modifiers.rshift_state() == winit::keyboard::ModifiersKeyState::Pressed = false

So it's not possible to get a modifier changed notification when a different version of the modifier is already down? Nor is it possible to know which one is held down?

So why have modifier info in both keyboard input and modifier changed events? That's pretty confusing.

Button press like Shift doesn't mean that the modifier is actually pressed, button release of Shift, doesn't mean that modifier was released. Consider for example sticky keys, which you get by press/release the Shift, and then the next key is with Shift modifier, however the Shift itself is no longer held.

So if you want to get a regular button, you use key itself, it may not be a modifier at all, but you care about a button, so it doesn't matter.

If you want to work with modifiers, as in, with the bindings, you use the ModifiersChanged event.

Yes, maybe on windows, it's not like that, but on linux modifiers and keys itself are detached, the modifier can also change for synthetic input without any change in the modifier itself.

So it's not possible to get a modifier changed notification when a different version of the modifier is already down? Nor is it possible to know which one is held down?

Yes, because there's no change, pressing more shift won't make a change because you already are holding a shift(you can try to detect left/right shift if you really want to), relying on this behavior is error prone, because on linux (xkbcommon) once you press modifier one more time there's no change in modifiers state at all.