Skip to content

Commit

Permalink
Get stuff to compile
Browse files Browse the repository at this point in the history
WIP

Add some keysym mappings and move the keymap.rs file

Add key location and some minor corrections

Also add a `Meta` key (code) value.

Use xkbcommon-dl rather than xkbcommon

Hoist keyboard handling code from sctk into Winit

Wire up the new events properly

Fix creation of key value strings

Use `xkb_keysym_to_utf8` rather than `xkb_state_key_get_utf8` to create
key value strings, as the latter performs keysym transformations, while
the former doesn't.

Add missing keysym mapping

I accidentally skipped over `XKB_KEY_Page_Down` while initially mapping
keysyms.

Fix `key_without_modifiers`

I forgot about the offset between evdev keycodes and xkb keycodes.

Feature-gate things which depend on memmap2

Be more consistent with what `keycode` means

Improve key string handling

Add initial X11 support

Address compilation errors

Improve debug printing of `NativeKeyCode`

Hook up X11 XKB modifier keys

Use XInput2 for regular key events

Implement dead-key handling

Remove unused module

Update xkbcommon-dl

Update xkbcommon-dl again

Remove accidentally included attribute

Use `as u32` to cast `i32`s to `u32`s

Put more things behind the "wayland" feature

Remove superfluous scope

Separate out loading of the X11 keymap

Wire up X11 IME support

Use the currently active keyboard layout on X11

Enable keysym mapping for "Alt Graph"

Actually respect keyboard layout changes

9486ac0 did not work for me

Make `xkb_state` more internally consistent

Improve the safety of `KbState`

Make a decision on control characters and dead keys

Store keycodes with X11's keycode offset

Log an error if we can't select XKB events

Remove superfluous call to `Vec::set_len`

Send a warning if the server doesn't send a keymap

Implement `KeyCodeExtScancode` on Wayland and X11

Implement `reset_dead_keys` (poorly)

Split the native XKB keycode enum variant in two

`XkbCode` now contains keycodes while `XkbSym` contains keysyms.
This may change sooner rather than later.

Add a TODO regarding the `ModifiersChanged` event.

fix: meta mod key on focus handling for gnome/x11

This patch addresses an issue in the modifier key handling appearing on
gnome/x11 while focussing a winit window using a meta/super/logo key
shortcut.

As soon as the window gained focus via a shortcut using a meta key,
gnome/x11 reports a meta modifier as pressed in the focus event, even
though it was just released. No key release events were sent afterwards,
so the meta modifier remained "stuck" in the winit state.

This patch refactors the modifier key handling following this goals:
 - Only rely on winit's own modifier state tracking for key and focus
   events, do not mix it with x11's modifier reporting
 - Track modifiers only via non-raw key events, so winit does not track
   modifier changes when not focussed
 - Integrate modifier handling with the synthetic key events mechanism
   in order to report release of all currently held modifiers when
   unfocussed and report set for all currently held modifiers when
   focussed.

Remove the `XkbStateNotify` handler

The only thing we did in response to said event is update the
`xkb_state`, but we throw that away on every keypress anyway due to the
keyeyboard layout change detection hack. This commit also removes
associated code which let us recieve and react to the event in the first
place. If a fix is ever introduced, then this commit ought to be
reverted.

X11: Only fetch virtual keyboard events from master devices

We must not report virtual keyboard events for keys that were grabbed by
other applications (XGrabKey, etc.). Since grabs only affect master
devices, we must consume virtual events from master devices only.

Revert "fix: meta mod key on focus handling for gnome/x11"

It's not clear if this change is working properly

This reverts commit 333c5bc.

General clippy fixes and formatting

Improve libxkbcommon string handling

Add `WindowBuilder::transparent`

This is required to help hardware accelerated libraries like glutin
that accept WindowBuilder instead of RawWindowHandle, since the api
to access builder properties directly was removed.

Follow up to 44288f6.

Fix doubled device events on X11

Fixes rust-windowing#2332

Don't reload the keymap on every keypress

Turns out I was an idiot when initially working on this.

Don't listen to XkbMapNotify

This event appears to be subsumed by XkbNewKeyboardNotify when we start
listening to XkbNewKeyboardNotify, although the documentation feels a
little unclear on the matter.

Use XkbStateNotify to track the active set of modifiers

This commit retains the old code-path for doing this tracking in order
to test for regressions introduced by this change.

It appears that we manage to avoid any visible regressions due to having
already removed the long since deprecated `modifiers` field from
keyboard events, which hides the fact that using XkbStateNotify makes
ModifiersChanged events arrive _after_ the WindowEvent for the keypress
instead of between the DeviceEvent and the WindowEvent.

Rip out the old code-path for modifier state tracking on X11

Rip out some vestigial parts

In particular, this removes the X11_EVPROC_NEXT_COMPOSE hack now that
our IME event code-path seems to ignore compose sequences.

Deal with various TODOs
  • Loading branch information
maroider authored and tomKPZ committed Aug 10, 2022
1 parent 5789778 commit 574383f
Show file tree
Hide file tree
Showing 23 changed files with 2,578 additions and 1,682 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ And please only add new entries to the top of this list, right below the `# Unre

- Build docs on `docs.rs` for iOS and Android as well.
- **Breaking:** Removed the `WindowAttributes` struct, since all its functionality is accessible from `WindowBuilder`.
- Added `WindowBuilder::transparent` getter to check if the user set `transparent` attribute.
- On macOS, Fix emitting `Event::LoopDestroyed` on CMD+Q.
- On macOS, fixed an issue where having multiple windows would prevent run_return from ever returning.
- On Wayland, fix bug where the cursor wouldn't hide in GNOME.
Expand Down
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ targets = [

[features]
default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"]
x11 = ["x11-dl", "mio", "percent-encoding", "parking_lot"]
wayland = ["wayland-client", "wayland-protocols", "sctk"]
x11 = ["x11-dl", "mio", "percent-encoding", "parking_lot", "xkbcommon-dl/x11"]
wayland = ["wayland-client", "wayland-protocols", "sctk", "memmap2"]
wayland-dlopen = ["sctk/dlopen", "wayland-client/dlopen"]
wayland-csd-adwaita = ["sctk-adwaita", "sctk-adwaita/title"]
wayland-csd-adwaita-notitle = ["sctk-adwaita"]
Expand Down Expand Up @@ -112,6 +112,8 @@ x11-dl = { version = "2.18.5", optional = true }
percent-encoding = { version = "2.0", optional = true }
parking_lot = { version = "0.12.0", optional = true }
libc = "0.2.64"
memmap2 = { version = "0.2.1", optional = true }
xkbcommon-dl = { git = "https://github.com/maroider/xkbcommon-dl", rev = "900832888ad6f11011d1369befb344a9aa8a9610" }

[target.'cfg(target_arch = "wasm32")'.dependencies.web_sys]
package = "web-sys"
Expand Down
21 changes: 16 additions & 5 deletions src/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,12 @@ pub enum NativeKeyCode {
Unidentified,
Windows(u16),
MacOS(u32),
XKB(u32),
XkbCode(u32),
XkbSym(u32),
}
impl std::fmt::Debug for NativeKeyCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use NativeKeyCode::{MacOS, Unidentified, Windows, XKB};
use NativeKeyCode::{MacOS, Unidentified, Windows, XkbCode, XkbSym};
let mut debug_tuple;
match self {
Unidentified => {
Expand All @@ -193,9 +194,13 @@ impl std::fmt::Debug for NativeKeyCode {
debug_tuple = f.debug_tuple(name_of!(MacOS));
debug_tuple.field(v);
}
XKB(v) => {
debug_tuple = f.debug_tuple(name_of!(XKB));
debug_tuple.field(v);
XkbCode(v) => {
debug_tuple = f.debug_tuple(name_of!(XkbCode));
debug_tuple.field(&format_args!("0x{:04X}", v));
}
XkbSym(v) => {
debug_tuple = f.debug_tuple(name_of!(XkbSym));
debug_tuple.field(&format_args!("0x{:04X}", v));
}
}
debug_tuple.finish()
Expand Down Expand Up @@ -536,6 +541,9 @@ pub enum KeyCode {
AudioVolumeMute,
AudioVolumeUp,
WakeUp,
// Legacy modifier key. Also called "Super" in certain places.
Meta,
// Legacy modifier key.
Hyper,
Turbo,
Abort,
Expand Down Expand Up @@ -731,6 +739,9 @@ pub enum Key<'a> {
/// The Symbol modifier key (used on some virtual keyboards).
Symbol,
SymbolLock,
// Legacy modifier key. Also called "Super" in certain places.
Meta,
// Legacy modifier key.
Hyper,
/// Used to enable "super" modifier function for interpreting concurrent or subsequent keyboard
/// input. This key value is used for the "Windows Logo" key and the Apple `Command` or `⌘` key.
Expand Down
1 change: 1 addition & 0 deletions src/platform/scancode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub trait KeyCodeExtScancode {
///
/// ## Platform-specific
/// - **Windows:** A 16bit extended scancode
/// - **Wayland/X11**: A 32-bit X11-style keycode.
// TODO: Describe what this value contains for each platform
fn to_scancode(self) -> Option<u32>;

Expand Down
26 changes: 26 additions & 0 deletions src/platform/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ use std::os::raw;
use std::{ptr, sync::Arc};

use crate::{
event::KeyEvent,
event_loop::{EventLoopBuilder, EventLoopWindowTarget},
keyboard::{Key, KeyCode},
monitor::MonitorHandle,
platform::{modifier_supplement::KeyEventExtModifierSupplement, scancode::KeyCodeExtScancode},
platform_impl::common::keymap,
window::{Window, WindowBuilder},
};

Expand Down Expand Up @@ -434,3 +438,25 @@ impl MonitorHandleExtUnix for MonitorHandle {
self.inner.native_identifier()
}
}

impl KeyEventExtModifierSupplement for KeyEvent {
#[inline]
fn text_with_all_modifiers(&self) -> Option<&str> {
self.platform_specific.text_with_all_modifiers
}

#[inline]
fn key_without_modifiers(&self) -> Key<'static> {
self.platform_specific.key_without_modifiers
}
}

impl KeyCodeExtScancode for KeyCode {
fn from_scancode(scancode: u32) -> KeyCode {
keymap::raw_keycode_to_keycode(scancode)
}

fn to_scancode(self) -> Option<u32> {
keymap::keycode_to_raw(self)
}
}
Loading

0 comments on commit 574383f

Please sign in to comment.