feat(config): add options to configure keyboard layout on Wayland

This commit is contained in:
Federico Terzi 2021-08-09 22:53:32 +02:00
parent c68d59797e
commit 47eb2b0b69
5 changed files with 84 additions and 11 deletions

View File

@ -107,6 +107,10 @@ pub trait Config: Send + Sync {
// If false, avoid applying the built-in patches to the current config.
fn apply_patch(&self) -> bool;
// On Wayland, overrides the auto-detected keyboard configuration (RMLVO)
// which is used both for the detection and injection process.
fn keyboard_layout(&self) -> Option<RMLVOConfig>;
fn is_match<'a>(&self, app: &AppProperties<'a>) -> bool;
fn pretty_dump(&self) -> String {
@ -192,6 +196,15 @@ pub enum ToggleKey {
LeftMeta,
}
#[derive(Debug, Clone)]
pub struct RMLVOConfig {
pub rules: Option<String>,
pub model: Option<String>,
pub layout: Option<String>,
pub variant: Option<String>,
pub options: Option<String>,
}
pub fn load_store(config_dir: &Path) -> Result<(impl ConfigStore, Vec<NonFatalErrorSet>)> {
store::DefaultConfigStore::load(config_dir)
}

View File

@ -18,7 +18,7 @@
*/
use anyhow::Result;
use std::{convert::TryInto, path::Path};
use std::{collections::BTreeMap, convert::TryInto, path::Path};
use thiserror::Error;
mod yaml;
@ -43,6 +43,7 @@ pub(crate) struct ParsedConfig {
pub paste_shortcut_event_delay: Option<usize>,
pub inject_delay: Option<usize>,
pub key_delay: Option<usize>,
pub keyboard_layout: Option<BTreeMap<String, String>>,
// Includes
@ -73,4 +74,4 @@ impl ParsedConfig {
pub enum ParsedConfigError {
#[error("can't load config `{0}`")]
LoadFailed(#[from] anyhow::Error),
}
}

View File

@ -19,6 +19,7 @@
use anyhow::Result;
use serde::{Deserialize, Serialize};
use serde_yaml::Mapping;
use std::convert::TryFrom;
use crate::util::is_yaml_empty;
@ -53,7 +54,7 @@ pub(crate) struct YAMLConfig {
#[serde(default)]
pub paste_shortcut_event_delay: Option<usize>,
#[serde(default)]
pub paste_shortcut: Option<String>,
@ -78,6 +79,9 @@ pub(crate) struct YAMLConfig {
#[serde(default)]
pub apply_patch: Option<bool>,
#[serde(default)]
pub keyboard_layout: Option<Mapping>,
// Include/Exclude
#[serde(default)]
pub includes: Option<Vec<String>>,
@ -139,6 +143,18 @@ impl TryFrom<YAMLConfig> for ParsedConfig {
word_separators: yaml_config.word_separators,
backspace_limit: yaml_config.backspace_limit,
apply_patch: yaml_config.apply_patch,
keyboard_layout: yaml_config.keyboard_layout.map(|mapping| {
mapping
.into_iter()
.filter_map(|(key, value)| {
if let (Some(key), Some(value)) = (key.as_str(), value.as_str()) {
Some((key.to_string(), value.to_string()))
} else {
None
}
})
.collect()
}),
pre_paste_delay: yaml_config.pre_paste_delay,
restore_clipboard_delay: yaml_config.restore_clipboard_delay,
@ -161,7 +177,7 @@ impl TryFrom<YAMLConfig> for ParsedConfig {
#[cfg(test)]
mod tests {
use super::*;
use std::convert::TryInto;
use std::{collections::BTreeMap, convert::TryInto};
#[test]
fn conversion_to_parsed_config_works_correctly() {
@ -183,6 +199,13 @@ mod tests {
backspace_delay: 30
word_separators: ["'", "."]
backspace_limit: 10
apply_patch: false
keyboard_layout:
rules: test_rule
model: test_model
layout: test_layout
variant: test_variant
options: test_options
use_standard_includes: true
includes: ["test1"]
@ -199,6 +222,15 @@ mod tests {
.unwrap();
let parsed_config: ParsedConfig = config.try_into().unwrap();
let keyboard_layout: BTreeMap<String, String> =
vec![
("rules".to_string(), "test_rule".to_string()),
("model".to_string(), "test_model".to_string()),
("layout".to_string(), "test_layout".to_string()),
("variant".to_string(), "test_variant".to_string()),
("options".to_string(), "test_options".to_string()),
].into_iter().collect();
assert_eq!(
parsed_config,
ParsedConfig {
@ -216,9 +248,10 @@ mod tests {
key_delay: Some(20),
backspace_limit: Some(10),
apply_patch: Some(false),
keyboard_layout: Some(keyboard_layout),
pre_paste_delay: Some(300),
toggle_key: Some("CTRL".to_string()),
word_separators: Some(vec!["'".to_owned(), ".".to_owned()]),

View File

@ -25,14 +25,14 @@ use super::{
parse::ParsedConfig,
path::calculate_paths,
util::os_matches,
AppProperties, Backend, Config, ToggleKey,
AppProperties, Backend, Config, RMLVOConfig, ToggleKey,
};
use crate::{counter::next_id, merge};
use anyhow::Result;
use log::error;
use regex::Regex;
use std::{iter::FromIterator, path::PathBuf};
use std::{collections::HashSet, path::Path};
use std::{iter::FromIterator, path::PathBuf};
use thiserror::Error;
const STANDARD_INCLUDES: &[&str] = &["../match/**/*.yml"];
@ -79,7 +79,7 @@ impl Config for ResolvedConfig {
if let Some(source_path) = self.source_path.as_ref() {
if let Some(source_path) = source_path.to_str() {
return source_path
return source_path;
}
}
@ -264,6 +264,16 @@ impl Config for ResolvedConfig {
fn apply_patch(&self) -> bool {
self.parsed.apply_patch.unwrap_or(true)
}
fn keyboard_layout(&self) -> Option<RMLVOConfig> {
self.parsed.keyboard_layout.as_ref().map(|layout| RMLVOConfig {
rules: layout.get("rules").map(String::from),
model: layout.get("model").map(String::from),
layout: layout.get("layout").map(String::from),
variant: layout.get("variant").map(String::from),
options: layout.get("options").map(String::from),
})
}
}
impl ResolvedConfig {
@ -336,6 +346,7 @@ impl ResolvedConfig {
key_delay,
word_separators,
backspace_limit,
keyboard_layout,
includes,
excludes,
extra_includes,

View File

@ -23,7 +23,13 @@ use regex::Regex;
use std::{collections::HashMap, path::Path, sync::Arc};
use self::config::LegacyConfig;
use crate::matches::{MatchEffect, group::loader::yaml::{parse::{YAMLMatch, YAMLVariable}, try_convert_into_match, try_convert_into_variable}};
use crate::matches::{
group::loader::yaml::{
parse::{YAMLMatch, YAMLVariable},
try_convert_into_match, try_convert_into_variable,
},
MatchEffect,
};
use crate::{config::store::DefaultConfigStore, counter::StructId};
use crate::{
config::Config,
@ -333,16 +339,25 @@ impl Config for LegacyInteropConfig {
}
fn word_separators(&self) -> Vec<String> {
self.config.word_separators.iter().map(|c| String::from(*c)).collect()
self
.config
.word_separators
.iter()
.map(|c| String::from(*c))
.collect()
}
fn backspace_limit(&self) -> usize {
self.config.backspace_limit.try_into().unwrap()
}
fn apply_patch(&self) -> bool {
true
}
fn keyboard_layout(&self) -> Option<crate::config::RMLVOConfig> {
None
}
}
struct LegacyMatchGroup {