separate GuiPanel for each keyboard layout
This commit is contained in:
@@ -7,7 +7,7 @@ use smithay::{
|
|||||||
reexports::wayland_server,
|
reexports::wayland_server,
|
||||||
utils::SerialCounter,
|
utils::SerialCounter,
|
||||||
};
|
};
|
||||||
use xkbcommon::xkb::{self, KEYMAP_FORMAT_USE_ORIGINAL};
|
use xkbcommon::xkb;
|
||||||
|
|
||||||
use crate::backend::wayvr::{ExternalProcessRequest, WayVRTask};
|
use crate::backend::wayvr::{ExternalProcessRequest, WayVRTask};
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ use smithay::{
|
|||||||
selection::data_device::DataDeviceState,
|
selection::data_device::DataDeviceState,
|
||||||
shell::xdg::{ToplevelSurface, XdgShellState},
|
shell::xdg::{ToplevelSurface, XdgShellState},
|
||||||
shm::ShmState,
|
shm::ShmState,
|
||||||
xwayland_keyboard_grab::XWaylandKeyboardGrabHandler,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::{collections::HashMap, rc::Rc};
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
use glam::{Affine3A, FloatExt, Mat4, Quat, Vec2, Vec3, vec2, vec3};
|
use crate::{gui::panel::GuiPanel, state::AppState, subsystem::hid::XkbKeymap};
|
||||||
|
use glam::{FloatExt, Mat4, Vec2, Vec3, vec2};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
@@ -17,43 +18,22 @@ use wgui::{
|
|||||||
util::WLength,
|
util::WLength,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
gui::panel::GuiPanel,
|
|
||||||
state::AppState,
|
|
||||||
subsystem::hid::{ALT, CTRL, META, SHIFT, SUPER, XkbKeymap},
|
|
||||||
windowing::window::OverlayWindowConfig,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
KEYBOARD_NAME, KeyButtonData, KeyState, KeyboardBackend, KeyboardState, handle_press,
|
KeyButtonData, KeyState, KeyboardState, handle_press, handle_release,
|
||||||
handle_release,
|
layout::{self, KeyCapType},
|
||||||
layout::{self, AltModifier, KeyCapType},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const BACKGROUND_PADDING: f32 = 16.0;
|
const BACKGROUND_PADDING: f32 = 16.0;
|
||||||
const PIXELS_PER_UNIT: f32 = 80.;
|
const PIXELS_PER_UNIT: f32 = 80.;
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines, clippy::significant_drop_tightening)]
|
#[allow(clippy::too_many_lines, clippy::significant_drop_tightening)]
|
||||||
pub fn create_keyboard(
|
pub(super) fn create_keyboard_panel(
|
||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
mut keymap: Option<XkbKeymap>,
|
keymap: Option<&XkbKeymap>,
|
||||||
) -> anyhow::Result<OverlayWindowConfig> {
|
state: KeyboardState,
|
||||||
let layout = layout::Layout::load_from_disk();
|
layout: &layout::Layout,
|
||||||
let state = KeyboardState {
|
) -> anyhow::Result<GuiPanel<KeyboardState>> {
|
||||||
modifiers: 0,
|
|
||||||
alt_modifier: match layout.alt_modifier {
|
|
||||||
AltModifier::Shift => SHIFT,
|
|
||||||
AltModifier::Ctrl => CTRL,
|
|
||||||
AltModifier::Alt => ALT,
|
|
||||||
AltModifier::Super => SUPER,
|
|
||||||
AltModifier::Meta => META,
|
|
||||||
_ => 0,
|
|
||||||
},
|
|
||||||
processes: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut panel = GuiPanel::new_blank(app, state, Default::default())?;
|
let mut panel = GuiPanel::new_blank(app, state, Default::default())?;
|
||||||
|
|
||||||
let globals = app.wgui_globals.clone();
|
let globals = app.wgui_globals.clone();
|
||||||
@@ -75,11 +55,7 @@ pub fn create_keyboard(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let has_altgr = keymap.as_ref().is_some_and(XkbKeymap::has_altgr);
|
let has_altgr = keymap.as_ref().is_some_and(|m| XkbKeymap::has_altgr(*m));
|
||||||
|
|
||||||
if !layout.auto_labels.unwrap_or(true) {
|
|
||||||
keymap = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let parse_doc_params = wgui::parser::ParseDocumentParams {
|
let parse_doc_params = wgui::parser::ParseDocumentParams {
|
||||||
globals,
|
globals,
|
||||||
@@ -111,7 +87,7 @@ pub fn create_keyboard(
|
|||||||
height: length(PIXELS_PER_UNIT),
|
height: length(PIXELS_PER_UNIT),
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(key) = layout.get_key_data(keymap.as_ref(), has_altgr, col, row) else {
|
let Some(key) = layout.get_key_data(keymap, has_altgr, col, row) else {
|
||||||
let _ = panel.layout.add_child(
|
let _ = panel.layout.add_child(
|
||||||
div.id,
|
div.id,
|
||||||
WidgetDiv::create(),
|
WidgetDiv::create(),
|
||||||
@@ -273,24 +249,7 @@ pub fn create_keyboard(
|
|||||||
panel.layout.update(vec2(2048., 2048.), 0.0)?;
|
panel.layout.update(vec2(2048., 2048.), 0.0)?;
|
||||||
panel.parser_state = gui_state_key;
|
panel.parser_state = gui_state_key;
|
||||||
|
|
||||||
let width = layout.row_size * 0.05 * app.session.config.keyboard_scale;
|
Ok(panel)
|
||||||
|
|
||||||
Ok(OverlayWindowConfig {
|
|
||||||
name: KEYBOARD_NAME.into(),
|
|
||||||
default_state: OverlayWindowState {
|
|
||||||
grabbable: true,
|
|
||||||
positioning: Positioning::Anchored,
|
|
||||||
interactable: true,
|
|
||||||
curvature: Some(0.15),
|
|
||||||
transform: Affine3A::from_scale_rotation_translation(
|
|
||||||
Vec3::ONE * width,
|
|
||||||
Quat::from_rotation_x(-10f32.to_radians()),
|
|
||||||
vec3(0.0, -0.65, -0.5),
|
|
||||||
),
|
|
||||||
..OverlayWindowState::default()
|
|
||||||
},
|
|
||||||
..OverlayWindowConfig::from_backend(Box::new(KeyboardBackend { panel }))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const BUTTON_HOVER_SCALE: f32 = 0.1;
|
const BUTTON_HOVER_SCALE: f32 = 0.1;
|
||||||
|
|||||||
@@ -1,22 +1,29 @@
|
|||||||
use std::{
|
use std::{
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
|
collections::HashMap,
|
||||||
process::{Child, Command},
|
process::{Child, Command},
|
||||||
};
|
};
|
||||||
|
|
||||||
use wgui::{
|
|
||||||
drawing,
|
|
||||||
event::{InternalStateChangeEvent, MouseButton, MouseButtonIndex},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{HoverResult, PointerHit},
|
backend::input::{HoverResult, PointerHit},
|
||||||
gui::panel::GuiPanel,
|
gui::panel::GuiPanel,
|
||||||
|
overlays::keyboard::{builder::create_keyboard_panel, layout::AltModifier},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
subsystem::hid::{ALT, CTRL, KeyModifier, META, SHIFT, SUPER, VirtualKey, WheelDelta},
|
subsystem::hid::{
|
||||||
windowing::backend::{
|
ALT, CTRL, KeyModifier, META, SHIFT, SUPER, VirtualKey, WheelDelta, XkbKeymap,
|
||||||
FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender,
|
},
|
||||||
|
windowing::{
|
||||||
|
backend::{FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender},
|
||||||
|
window::OverlayWindowConfig,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use glam::{Affine3A, Quat, Vec3, vec3};
|
||||||
|
use slotmap::{SlotMap, new_key_type};
|
||||||
|
use wgui::{
|
||||||
|
drawing,
|
||||||
|
event::{InternalStateChangeEvent, MouseButton, MouseButtonIndex},
|
||||||
|
};
|
||||||
|
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
mod layout;
|
mod layout;
|
||||||
@@ -24,31 +31,147 @@ mod layout;
|
|||||||
pub const KEYBOARD_NAME: &str = "kbd";
|
pub const KEYBOARD_NAME: &str = "kbd";
|
||||||
const AUTO_RELEASE_MODS: [KeyModifier; 5] = [SHIFT, CTRL, ALT, SUPER, META];
|
const AUTO_RELEASE_MODS: [KeyModifier; 5] = [SHIFT, CTRL, ALT, SUPER, META];
|
||||||
|
|
||||||
|
pub fn create_keyboard(
|
||||||
|
app: &mut AppState,
|
||||||
|
mut keymap: Option<XkbKeymap>,
|
||||||
|
) -> anyhow::Result<OverlayWindowConfig> {
|
||||||
|
let layout = layout::Layout::load_from_disk();
|
||||||
|
let default_state = KeyboardState {
|
||||||
|
modifiers: 0,
|
||||||
|
alt_modifier: match layout.alt_modifier {
|
||||||
|
AltModifier::Shift => SHIFT,
|
||||||
|
AltModifier::Ctrl => CTRL,
|
||||||
|
AltModifier::Alt => ALT,
|
||||||
|
AltModifier::Super => SUPER,
|
||||||
|
AltModifier::Meta => META,
|
||||||
|
_ => 0,
|
||||||
|
},
|
||||||
|
processes: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
if !layout.auto_labels.unwrap_or(true) {
|
||||||
|
keymap = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let width = layout.row_size * 0.05 * app.session.config.keyboard_scale;
|
||||||
|
|
||||||
|
let mut backend = KeyboardBackend {
|
||||||
|
keymap_panels: SlotMap::default(),
|
||||||
|
keymap_ids: HashMap::default(),
|
||||||
|
active_keymap: KeyboardPanelKey::default(),
|
||||||
|
default_state,
|
||||||
|
layout,
|
||||||
|
};
|
||||||
|
|
||||||
|
backend.active_keymap = backend.add_new_keymap(keymap.as_ref(), app)?;
|
||||||
|
|
||||||
|
Ok(OverlayWindowConfig {
|
||||||
|
name: KEYBOARD_NAME.into(),
|
||||||
|
default_state: OverlayWindowState {
|
||||||
|
grabbable: true,
|
||||||
|
positioning: Positioning::Anchored,
|
||||||
|
interactable: true,
|
||||||
|
curvature: Some(0.15),
|
||||||
|
transform: Affine3A::from_scale_rotation_translation(
|
||||||
|
Vec3::ONE * width,
|
||||||
|
Quat::from_rotation_x(-10f32.to_radians()),
|
||||||
|
vec3(0.0, -0.65, -0.5),
|
||||||
|
),
|
||||||
|
..OverlayWindowState::default()
|
||||||
|
},
|
||||||
|
..OverlayWindowConfig::from_backend(Box::new(backend))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
new_key_type! {
|
||||||
|
struct KeyboardPanelKey;
|
||||||
|
}
|
||||||
|
|
||||||
struct KeyboardBackend {
|
struct KeyboardBackend {
|
||||||
panel: GuiPanel<KeyboardState>,
|
keymap_panels: SlotMap<KeyboardPanelKey, GuiPanel<KeyboardState>>,
|
||||||
|
keymap_ids: HashMap<String, KeyboardPanelKey>,
|
||||||
|
active_keymap: KeyboardPanelKey,
|
||||||
|
default_state: KeyboardState,
|
||||||
|
layout: layout::Layout,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyboardBackend {
|
||||||
|
fn add_new_keymap(
|
||||||
|
&mut self,
|
||||||
|
keymap: Option<&XkbKeymap>,
|
||||||
|
app: &mut AppState,
|
||||||
|
) -> anyhow::Result<KeyboardPanelKey> {
|
||||||
|
let panel = create_keyboard_panel(app, keymap, self.default_state.take(), &self.layout)?;
|
||||||
|
|
||||||
|
let id = self.keymap_panels.insert(panel);
|
||||||
|
if let Some(layout_name) = keymap.and_then(|k| k.inner.layouts().next()) {
|
||||||
|
self.keymap_ids.insert(layout_name.into(), id);
|
||||||
|
} else {
|
||||||
|
log::error!("XKB keymap without a layout!");
|
||||||
|
};
|
||||||
|
Ok(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn switch_keymap(&mut self, keymap: &XkbKeymap, app: &mut AppState) -> anyhow::Result<()> {
|
||||||
|
let Some(layout_name) = keymap.inner.layouts().next() else {
|
||||||
|
log::error!("XKB keymap without a layout!");
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(new_key) = self.keymap_ids.get(layout_name) {
|
||||||
|
if self.active_keymap.eq(new_key) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
self.internal_switch_keymap(*new_key);
|
||||||
|
} else {
|
||||||
|
let new_key = self.add_new_keymap(Some(keymap), app)?;
|
||||||
|
self.internal_switch_keymap(new_key);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_switch_keymap(&mut self, new_key: KeyboardPanelKey) {
|
||||||
|
let state_from = self
|
||||||
|
.keymap_panels
|
||||||
|
.get_mut(self.active_keymap)
|
||||||
|
.unwrap()
|
||||||
|
.state
|
||||||
|
.take();
|
||||||
|
|
||||||
|
self.active_keymap = new_key;
|
||||||
|
|
||||||
|
self.keymap_panels
|
||||||
|
.get_mut(self.active_keymap)
|
||||||
|
.unwrap()
|
||||||
|
.state = state_from;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn panel(&mut self) -> &mut GuiPanel<KeyboardState> {
|
||||||
|
self.keymap_panels.get_mut(self.active_keymap).unwrap() // want panic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayBackend for KeyboardBackend {
|
impl OverlayBackend for KeyboardBackend {
|
||||||
fn init(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
fn init(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
||||||
self.panel.init(app)
|
self.panel().init(app)
|
||||||
}
|
}
|
||||||
fn should_render(&mut self, app: &mut AppState) -> anyhow::Result<ShouldRender> {
|
fn should_render(&mut self, app: &mut AppState) -> anyhow::Result<ShouldRender> {
|
||||||
self.panel.should_render(app)
|
self.panel().should_render(app)
|
||||||
}
|
}
|
||||||
fn render(&mut self, app: &mut AppState, rdr: &mut RenderResources) -> anyhow::Result<()> {
|
fn render(&mut self, app: &mut AppState, rdr: &mut RenderResources) -> anyhow::Result<()> {
|
||||||
self.panel.render(app, rdr)
|
self.panel().render(app, rdr)
|
||||||
}
|
}
|
||||||
fn frame_meta(&mut self) -> Option<FrameMeta> {
|
fn frame_meta(&mut self) -> Option<FrameMeta> {
|
||||||
self.panel.frame_meta()
|
self.panel().frame_meta()
|
||||||
}
|
}
|
||||||
fn pause(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
fn pause(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
||||||
self.panel.state.modifiers = 0;
|
self.panel().state.modifiers = 0;
|
||||||
app.hid_provider.set_modifiers_routed(0);
|
app.hid_provider.set_modifiers_routed(0);
|
||||||
self.panel.pause(app)
|
self.panel().pause(app)
|
||||||
}
|
}
|
||||||
fn resume(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
fn resume(&mut self, app: &mut AppState) -> anyhow::Result<()> {
|
||||||
self.panel.resume(app)?;
|
self.panel().resume(app)?;
|
||||||
self.panel.push_event(
|
self.panel().push_event(
|
||||||
app,
|
app,
|
||||||
&wgui::event::Event::InternalStateChange(InternalStateChangeEvent { metadata: 0 }),
|
&wgui::event::Event::InternalStateChange(InternalStateChangeEvent { metadata: 0 }),
|
||||||
);
|
);
|
||||||
@@ -56,27 +179,27 @@ impl OverlayBackend for KeyboardBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn notify(&mut self, app: &mut AppState, event_data: OverlayEventData) -> anyhow::Result<()> {
|
fn notify(&mut self, app: &mut AppState, event_data: OverlayEventData) -> anyhow::Result<()> {
|
||||||
self.panel.notify(app, event_data)
|
self.panel().notify(app, event_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) {
|
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) {
|
||||||
self.panel.on_pointer(app, hit, pressed);
|
self.panel().on_pointer(app, hit, pressed);
|
||||||
self.panel.push_event(
|
self.panel().push_event(
|
||||||
app,
|
app,
|
||||||
&wgui::event::Event::InternalStateChange(InternalStateChangeEvent { metadata: 0 }),
|
&wgui::event::Event::InternalStateChange(InternalStateChangeEvent { metadata: 0 }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta) {
|
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta) {
|
||||||
self.panel.on_scroll(app, hit, delta);
|
self.panel().on_scroll(app, hit, delta);
|
||||||
}
|
}
|
||||||
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
||||||
self.panel.on_left(app, pointer);
|
self.panel().on_left(app, pointer);
|
||||||
}
|
}
|
||||||
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult {
|
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult {
|
||||||
self.panel.on_hover(app, hit)
|
self.panel().on_hover(app, hit)
|
||||||
}
|
}
|
||||||
fn get_interaction_transform(&mut self) -> Option<glam::Affine2> {
|
fn get_interaction_transform(&mut self) -> Option<glam::Affine2> {
|
||||||
self.panel.get_interaction_transform()
|
self.panel().get_interaction_transform()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +209,20 @@ struct KeyboardState {
|
|||||||
processes: Vec<Child>,
|
processes: Vec<Child>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl KeyboardState {
|
||||||
|
fn take(&mut self) -> Self {
|
||||||
|
Self {
|
||||||
|
modifiers: self.modifiers,
|
||||||
|
alt_modifier: self.alt_modifier,
|
||||||
|
processes: {
|
||||||
|
let mut processes = vec![];
|
||||||
|
std::mem::swap(&mut processes, &mut self.processes);
|
||||||
|
processes
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const KEY_AUDIO_WAV: &[u8] = include_bytes!("../../res/421581.wav");
|
const KEY_AUDIO_WAV: &[u8] = include_bytes!("../../res/421581.wav");
|
||||||
|
|
||||||
fn play_key_click(app: &mut AppState) {
|
fn play_key_click(app: &mut AppState) {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use glam::Affine3A;
|
use glam::Affine3A;
|
||||||
use idmap::IdMap;
|
use idmap::IdMap;
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{SmallVec, smallvec};
|
||||||
use smithay::backend::renderer::Texture;
|
use std::sync::Arc;
|
||||||
use std::{ops::Not, sync::Arc};
|
|
||||||
use wgui::{
|
use wgui::{
|
||||||
font_config::WguiFontConfig, gfx::WGfx, globals::WguiGlobals, parser::parse_color_hex,
|
font_config::WguiFontConfig, gfx::WGfx, globals::WguiGlobals, parser::parse_color_hex,
|
||||||
renderer_vk::context::SharedContext as WSharedContext,
|
renderer_vk::context::SharedContext as WSharedContext,
|
||||||
|
|||||||
@@ -574,12 +574,12 @@ pub const fn get_key_type(key: VirtualKey) -> KeyType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct XkbKeymap {
|
pub struct XkbKeymap {
|
||||||
pub keymap: xkb::Keymap,
|
pub inner: xkb::Keymap,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XkbKeymap {
|
impl XkbKeymap {
|
||||||
pub fn label_for_key(&self, key: VirtualKey, modifier: KeyModifier) -> String {
|
pub fn label_for_key(&self, key: VirtualKey, modifier: KeyModifier) -> String {
|
||||||
let mut state = xkb::State::new(&self.keymap);
|
let mut state = xkb::State::new(&self.inner);
|
||||||
if modifier > 0
|
if modifier > 0
|
||||||
&& let Some(mod_key) = MODS_TO_KEYS.get(modifier)
|
&& let Some(mod_key) = MODS_TO_KEYS.get(modifier)
|
||||||
{
|
{
|
||||||
@@ -592,8 +592,8 @@ impl XkbKeymap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_altgr(&self) -> bool {
|
pub fn has_altgr(&self) -> bool {
|
||||||
let state0 = xkb::State::new(&self.keymap);
|
let state0 = xkb::State::new(&self.inner);
|
||||||
let mut state1 = xkb::State::new(&self.keymap);
|
let mut state1 = xkb::State::new(&self.inner);
|
||||||
state1.update_key(
|
state1.update_key(
|
||||||
xkb::Keycode::from(VirtualKey::Meta as u32),
|
xkb::Keycode::from(VirtualKey::Meta as u32),
|
||||||
xkb::KeyDirection::Down,
|
xkb::KeyDirection::Down,
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ impl Dispatch<WlKeyboard, ()> for WlKeymapHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.keymap = Some(XkbKeymap { keymap });
|
state.keymap = Some(XkbKeymap { inner: keymap });
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
log::error!("Could not load keymap: no keymap");
|
log::error!("Could not load keymap: no keymap");
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ pub fn get_keymap_x11() -> anyhow::Result<XkbKeymap> {
|
|||||||
}
|
}
|
||||||
let keymap = keymap_new_from_device(&context, &conn, device_id, xkb::KEYMAP_COMPILE_NO_FLAGS);
|
let keymap = keymap_new_from_device(&context, &conn, device_id, xkb::KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
Ok(XkbKeymap { keymap })
|
Ok(XkbKeymap { inner: keymap })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use crate::{
|
|||||||
FRAME_COUNTER,
|
FRAME_COUNTER,
|
||||||
backend::task::OverlayTask,
|
backend::task::OverlayTask,
|
||||||
overlays::{
|
overlays::{
|
||||||
anchor::create_anchor, edit::EditWrapperManager, keyboard::builder::create_keyboard,
|
anchor::create_anchor, edit::EditWrapperManager, keyboard::create_keyboard,
|
||||||
screen::create_screens, toast::Toast, watch::create_watch,
|
screen::create_screens, toast::Toast, watch::create_watch,
|
||||||
},
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
|
|||||||
Reference in New Issue
Block a user