From 841851623667ef69a9df7d61046870c9b4e8df67 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Sun, 14 Dec 2025 13:11:03 +0900 Subject: [PATCH] wayvr: interface to set keymap --- wlx-overlay-s/src/backend/wayvr/client.rs | 12 ++++++++++++ wlx-overlay-s/src/backend/wayvr/mod.rs | 6 ++++++ wlx-overlay-s/src/subsystem/hid/wayland.rs | 5 +++++ wlx-overlay-s/src/subsystem/input.rs | 19 +++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/wlx-overlay-s/src/backend/wayvr/client.rs b/wlx-overlay-s/src/backend/wayvr/client.rs index 838e05b..de5a793 100644 --- a/wlx-overlay-s/src/backend/wayvr/client.rs +++ b/wlx-overlay-s/src/backend/wayvr/client.rs @@ -1,11 +1,13 @@ use std::{io::Read, os::unix::net::UnixStream, path::PathBuf, sync::Arc}; +use anyhow::Context; use smithay::{ backend::input::Keycode, input::{keyboard::KeyboardHandle, pointer::PointerHandle}, reexports::wayland_server, utils::SerialCounter, }; +use xkbcommon::xkb::{self, KEYMAP_FORMAT_USE_ORIGINAL}; use crate::backend::wayvr::{ExternalProcessRequest, WayVRTask}; @@ -207,6 +209,16 @@ impl WayVRCompositor { |_, _, _| smithay::input::keyboard::FilterResult::Forward, ); } + + pub fn set_keymap(&mut self, keymap: &xkb::Keymap) -> anyhow::Result<()> { + // Smithay only accepts keymaps in a string form due to thread safety concerns + self.seat_keyboard + .set_keymap_from_string( + &mut self.state, + keymap.get_as_string(xkb::KEYMAP_FORMAT_USE_ORIGINAL), + ) + .context("Failed to set keymap") + } } const STARTING_WAYLAND_ADDR_IDX: u32 = 20; diff --git a/wlx-overlay-s/src/backend/wayvr/mod.rs b/wlx-overlay-s/src/backend/wayvr/mod.rs index 89fcb99..401d5f3 100644 --- a/wlx-overlay-s/src/backend/wayvr/mod.rs +++ b/wlx-overlay-s/src/backend/wayvr/mod.rs @@ -32,6 +32,7 @@ use smithay::{ selection::data_device::DataDeviceState, shell::xdg::{ToplevelSurface, XdgShellState}, shm::ShmState, + xwayland_keyboard_grab::XWaylandKeyboardGrabHandler, }, }; use std::{ @@ -42,6 +43,7 @@ use std::{ }; use time::get_millis; use wayvr_ipc::{packet_client, packet_server}; +use xkbcommon::xkb; use crate::{ state::AppState, @@ -519,6 +521,10 @@ impl WayVRState { self.manager.send_key(virtual_key, down); } + pub fn set_keymap(&mut self, keymap: &xkb::Keymap) -> anyhow::Result<()> { + self.manager.set_keymap(keymap) + } + pub fn set_modifiers(&mut self, modifiers: u8) { let changed = self.cur_modifiers ^ modifiers; for i in 0..8 { diff --git a/wlx-overlay-s/src/subsystem/hid/wayland.rs b/wlx-overlay-s/src/subsystem/hid/wayland.rs index 17d2aa3..052b134 100644 --- a/wlx-overlay-s/src/subsystem/hid/wayland.rs +++ b/wlx-overlay-s/src/subsystem/hid/wayland.rs @@ -117,6 +117,11 @@ impl Dispatch for WlKeymapHandler { match maybe_keymap { Ok(Some(keymap)) => { + for l in keymap.layouts() { + log::info!("wayland keymap: {l}"); + break; + } + state.keymap = Some(XkbKeymap { keymap }); } Ok(None) => { diff --git a/wlx-overlay-s/src/subsystem/input.rs b/wlx-overlay-s/src/subsystem/input.rs index 97fad82..e19a8ce 100644 --- a/wlx-overlay-s/src/subsystem/input.rs +++ b/wlx-overlay-s/src/subsystem/input.rs @@ -1,5 +1,7 @@ use super::hid::{self, HidProvider, VirtualKey}; +use xkbcommon::xkb; + #[cfg(feature = "wayvr")] use crate::overlays::wayvr::WayVRData; #[cfg(feature = "wayvr")] @@ -48,6 +50,23 @@ impl HidWrapper { } } + pub fn keymap_changed(&self, keymap: &xkb::Keymap) { + #[cfg(feature = "wayvr")] + if let Some(wayvr) = &self.wayvr { + let _ = wayvr + .borrow_mut() + .data + .state + .set_keymap(keymap) + .inspect_err(|e| log::error!("Could not set WayVR keymap: {e:?}")); + } + + log::info!( + "Keymap changed: {}", + keymap.layouts().next().unwrap_or("Unknown") + ); + } + pub fn set_modifiers_routed(&mut self, mods: u8) { match self.keyboard_focus { KeyboardFocus::PhysicalScreen => self.inner.set_modifiers(mods),