config: Add keymap_from_names for RMLVO keymaps
This commit is contained in:
parent
bc9f2aef69
commit
0dfa6bc74b
5 changed files with 135 additions and 4 deletions
|
|
@ -19,7 +19,7 @@ use {
|
|||
acceleration::AccelProfile, capability::Capability, clickmethod::ClickMethod,
|
||||
},
|
||||
keyboard::{
|
||||
Keymap,
|
||||
Group, Keymap,
|
||||
mods::{Modifiers, RELEASE},
|
||||
syms::KeySym,
|
||||
},
|
||||
|
|
@ -1385,6 +1385,23 @@ impl ConfigClient {
|
|||
keymap
|
||||
}
|
||||
|
||||
pub fn keymap_from_names(
|
||||
&self,
|
||||
rules: Option<&str>,
|
||||
model: Option<&str>,
|
||||
groups: Option<&[Group<'_>]>,
|
||||
options: Option<&[&str]>,
|
||||
) -> Keymap {
|
||||
let res = self.send_with_response(&ClientMessage::KeymapFromNames {
|
||||
rules,
|
||||
model,
|
||||
groups: groups.map(|v| v.to_vec()),
|
||||
options: options.map(|v| v.to_vec()),
|
||||
});
|
||||
get_response!(res, Keymap(0), KeymapFromNames { keymap });
|
||||
keymap
|
||||
}
|
||||
|
||||
pub fn set_ei_socket_enabled(&self, enabled: bool) {
|
||||
self.send(&ClientMessage::SetEiSocketEnabled { enabled })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use {
|
|||
FocusFollowsMouseMode, InputDevice, LayerDirection, Seat, SwitchEvent, Timeline,
|
||||
acceleration::AccelProfile, capability::Capability, clickmethod::ClickMethod,
|
||||
},
|
||||
keyboard::{Keymap, mods::Modifiers, syms::KeySym},
|
||||
keyboard::{Group, Keymap, mods::Modifiers, syms::KeySym},
|
||||
logging::LogLevel,
|
||||
theme::{BarPosition, Color, colors::Colorable, sized::Resizable},
|
||||
timer::Timer,
|
||||
|
|
@ -820,6 +820,12 @@ pub enum ClientMessage<'a> {
|
|||
connector: Connector,
|
||||
use_native_gamut: bool,
|
||||
},
|
||||
KeymapFromNames {
|
||||
rules: Option<&'a str>,
|
||||
model: Option<&'a str>,
|
||||
groups: Option<Vec<Group<'a>>>,
|
||||
options: Option<Vec<&'a str>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
@ -1067,6 +1073,9 @@ pub enum Response {
|
|||
GetBarPosition {
|
||||
position: BarPosition,
|
||||
},
|
||||
KeymapFromNames {
|
||||
keymap: Keymap,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
|
|||
|
|
@ -70,6 +70,15 @@ impl Keymap {
|
|||
}
|
||||
}
|
||||
|
||||
/// An RMLVO group consisting of a layout and a variant.
|
||||
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct Group<'a> {
|
||||
/// The layout of the group.
|
||||
pub layout: &'a str,
|
||||
/// The variant of the group. Can be an empty string.
|
||||
pub variant: &'a str,
|
||||
}
|
||||
|
||||
/// Parses a keymap.
|
||||
///
|
||||
/// The returned keymap can later be used to set the keymap of a seat. If the keymap cannot
|
||||
|
|
@ -109,3 +118,39 @@ impl Keymap {
|
|||
pub fn parse_keymap(keymap: &str) -> Keymap {
|
||||
get!(Keymap::INVALID).parse_keymap(keymap)
|
||||
}
|
||||
|
||||
/// Creates a keymap from RMLVO names.
|
||||
///
|
||||
/// If a parameter is not given, a value from the environment or a default is used:
|
||||
///
|
||||
/// | name | default |
|
||||
/// | ---------------------- | ---------------------- |
|
||||
/// | `XKB_DEFAULT_RULES` | `evdev` |
|
||||
/// | `XKB_DEFAULT_MODEL` | `pc105` |
|
||||
/// | `XKB_DEFAULT_LAYOUT` | `us` |
|
||||
/// | `XKB_DEFAULT_VARIANTS` | |
|
||||
/// | `XKB_DEFAULT_OPTIONS` | |
|
||||
///
|
||||
/// `XKB_DEFAULT_LAYOUT` and `XKB_DEFAULT_VARIANTS` are parsed into the `groups` parameter like this example:
|
||||
/// ```
|
||||
/// XKB_DEFAULT_LAYOUT = "us,il,ru,de,jp"
|
||||
/// XKB_DEFAULT_VARIANTS = ",,phonetic,neo"
|
||||
/// ```
|
||||
/// produces:
|
||||
/// ```
|
||||
/// [
|
||||
/// Group { layout: "us", variant: "" },
|
||||
/// Group { layout: "il", variant: "" },
|
||||
/// Group { layout: "ru", variant: "phonetic" },
|
||||
/// Group { layout: "de", variant: "neo" },
|
||||
/// Group { layout: "jp", variant: "" },
|
||||
/// ]
|
||||
/// ```
|
||||
pub fn keymap_from_names(
|
||||
rules: Option<&str>,
|
||||
model: Option<&str>,
|
||||
groups: Option<&[Group<'_>]>,
|
||||
options: Option<&[&str]>,
|
||||
) -> Keymap {
|
||||
get!(Keymap::INVALID).keymap_from_names(rules, model, groups, options)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ use {
|
|||
CLICK_METHOD_BUTTON_AREAS, CLICK_METHOD_CLICKFINGER, CLICK_METHOD_NONE, ClickMethod,
|
||||
},
|
||||
},
|
||||
keyboard::{Keymap, mods::Modifiers, syms::KeySym},
|
||||
keyboard::{Group, Keymap, mods::Modifiers, syms::KeySym},
|
||||
logging::LogLevel,
|
||||
theme::{BarPosition, colors::Colorable, sized::Resizable},
|
||||
timer::Timer as JayTimer,
|
||||
|
|
@ -316,6 +316,39 @@ impl ConfigProxyHandler {
|
|||
res
|
||||
}
|
||||
|
||||
fn handle_keymap_from_names(
|
||||
&self,
|
||||
rules: Option<&str>,
|
||||
model: Option<&str>,
|
||||
groups: Option<Vec<Group<'_>>>,
|
||||
options: Option<Vec<&str>>,
|
||||
) -> Result<(), CphError> {
|
||||
let kbvm_groups = groups.map(|groups| {
|
||||
groups
|
||||
.iter()
|
||||
.map(|g| kbvm::xkb::rmlvo::Group {
|
||||
layout: g.layout,
|
||||
variant: g.variant,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let (keymap, res) = match self.state.kb_ctx.keymap_from_names(
|
||||
rules,
|
||||
model,
|
||||
kbvm_groups.as_deref(),
|
||||
options.as_deref(),
|
||||
) {
|
||||
Ok(keymap) => {
|
||||
let id = Keymap(self.id());
|
||||
self.keymaps.set(id, keymap);
|
||||
(id, Ok(()))
|
||||
}
|
||||
Err(e) => (Keymap::INVALID, Err(CphError::ParseKeymapError(e))),
|
||||
};
|
||||
self.respond(Response::KeymapFromNames { keymap });
|
||||
res
|
||||
}
|
||||
|
||||
fn handle_get_connectors(
|
||||
&self,
|
||||
dev: Option<DrmDevice>,
|
||||
|
|
@ -3332,6 +3365,14 @@ impl ConfigProxyHandler {
|
|||
} => self
|
||||
.handle_connector_set_use_native_gamut(connector, use_native_gamut)
|
||||
.wrn("connector_set_use_native_gamut")?,
|
||||
ClientMessage::KeymapFromNames {
|
||||
rules,
|
||||
model,
|
||||
groups,
|
||||
options,
|
||||
} => self
|
||||
.handle_keymap_from_names(rules, model, groups, options)
|
||||
.wrn("keymap_from_names")?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
21
src/kbvm.rs
21
src/kbvm.rs
|
|
@ -92,6 +92,25 @@ impl KbvmContext {
|
|||
.ctx
|
||||
.keymap_from_bytes(WriteToLog, None, keymap)
|
||||
.map_err(KbvmError::CouldNotParseKeymap)?;
|
||||
let id = KbvmMapId(*blake3::hash(keymap).as_bytes());
|
||||
self.create_keymap(id, map)
|
||||
}
|
||||
|
||||
pub fn keymap_from_names(
|
||||
&self,
|
||||
rules: Option<&str>,
|
||||
model: Option<&str>,
|
||||
groups: Option<&[xkb::rmlvo::Group<'_>]>,
|
||||
options: Option<&[&str]>,
|
||||
) -> Result<Rc<KbvmMap>, KbvmError> {
|
||||
let map = self
|
||||
.ctx
|
||||
.keymap_from_names(WriteToLog, rules, model, groups, options);
|
||||
let id = KbvmMapId(*blake3::hash(map.format().to_string().as_bytes()).as_bytes());
|
||||
self.create_keymap(id, map)
|
||||
}
|
||||
|
||||
fn create_keymap(&self, id: KbvmMapId, map: Keymap) -> Result<Rc<KbvmMap>, KbvmError> {
|
||||
let mut has_indicators = false;
|
||||
let mut num_lock = None;
|
||||
let mut caps_lock = None;
|
||||
|
|
@ -111,7 +130,7 @@ impl KbvmContext {
|
|||
}
|
||||
let builder = map.to_builder();
|
||||
Ok(Rc::new(KbvmMap {
|
||||
id: KbvmMapId(*blake3::hash(keymap).as_bytes()),
|
||||
id,
|
||||
state_machine: builder.build_state_machine(),
|
||||
map: create_keymap_memfd(&map, false).map_err(KbvmError::KeymapMemfd)?,
|
||||
xwayland_map: create_keymap_memfd(&map, true).map_err(KbvmError::KeymapMemfd)?,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue