Merge branch 'fallback' into 'master'

Better fallbacks

See merge request Librem5/squeekboard!415
This commit is contained in:
Sebastian Krzyszkowiak
2020-12-05 04:16:44 +00:00

View File

@ -97,6 +97,8 @@ impl fmt::Display for DataSource {
} }
} }
type LayoutSource = (ArrangementKind, DataSource);
/// Lists possible sources, with 0 as the most preferred one /// Lists possible sources, with 0 as the most preferred one
/// Trying order: native lang of the right kind, native base, /// Trying order: native lang of the right kind, native base,
/// fallback lang of the right kind, fallback base /// fallback lang of the right kind, fallback base
@ -104,19 +106,13 @@ fn list_layout_sources(
name: &str, name: &str,
kind: ArrangementKind, kind: ArrangementKind,
keyboards_path: Option<PathBuf>, keyboards_path: Option<PathBuf>,
) -> Vec<(ArrangementKind, DataSource)> { ) -> Vec<LayoutSource> {
let mut ret = Vec::new(); // Just a simplification of often called code.
{ let add_by_name = |
fn name_with_arrangement(name: String, kind: &ArrangementKind) mut ret: Vec<LayoutSource>,
-> String name: &str,
{ kind: &ArrangementKind,
match kind { | -> Vec<LayoutSource> {
ArrangementKind::Base => name,
ArrangementKind::Wide => name + "_wide",
}
}
let mut add_by_name = |name: &str, kind: &ArrangementKind| {
if let Some(path) = keyboards_path.clone() { if let Some(path) = keyboards_path.clone() {
ret.push(( ret.push((
kind.clone(), kind.clone(),
@ -130,29 +126,56 @@ fn list_layout_sources(
kind.clone(), kind.clone(),
DataSource::Resource(name.into()) DataSource::Resource(name.into())
)); ));
};
match &kind {
ArrangementKind::Base => {},
kind => add_by_name(
&name_with_arrangement(name.into(), &kind),
&kind,
),
};
add_by_name(name, &ArrangementKind::Base);
match &kind {
ArrangementKind::Base => {},
kind => add_by_name(
&name_with_arrangement(FALLBACK_LAYOUT_NAME.into(), &kind),
&kind,
),
};
add_by_name(FALLBACK_LAYOUT_NAME, &ArrangementKind::Base);
}
ret ret
};
// Another grouping.
let add_by_kind = |ret, name: &str, kind| {
let ret = match kind {
&ArrangementKind::Base => ret,
kind => add_by_name(
ret,
&name_with_arrangement(name.into(), kind),
kind,
),
};
add_by_name(ret, name, &ArrangementKind::Base)
};
fn name_with_arrangement(name: String, kind: &ArrangementKind) -> String {
match kind {
ArrangementKind::Base => name,
ArrangementKind::Wide => name + "_wide",
}
}
let ret = Vec::new();
// Name as given takes priority.
let ret = add_by_kind(ret, name, &kind);
// Then try non-alternative name if applicable (`us` for `us+colemak`).
let ret = {
let mut parts = name.splitn(2, '+');
match parts.next() {
Some(base) => {
// The name is already equal to base, so it was already added.
if base == name { ret }
else {
add_by_kind(ret, base, &kind)
}
},
// The layout's base name starts with a "+". Weird but OK.
None => {
log_print!(logging::Level::Surprise, "Base layout name is empty: {}", name);
ret
}
}
};
// No other choices left, so give anything.
add_by_kind(ret, FALLBACK_LAYOUT_NAME.into(), &kind)
} }
fn load_layout_data(source: DataSource) fn load_layout_data(source: DataSource)
@ -918,6 +941,25 @@ mod tests {
); );
} }
/// If layout contains a "+", it should reach for what's in front of it too.
#[test]
fn fallbacks_order_base() {
let sources = list_layout_sources("nb+aliens", ArrangementKind::Base, None);
assert_eq!(
sources,
vec!(
(ArrangementKind::Base, DataSource::Resource("nb+aliens".into())),
(ArrangementKind::Base, DataSource::Resource("nb".into())),
(
ArrangementKind::Base,
DataSource::Resource(FALLBACK_LAYOUT_NAME.into())
),
)
);
}
#[test] #[test]
fn unicode_keysym() { fn unicode_keysym() {
let keysym = xkb::keysym_from_name( let keysym = xkb::keysym_from_name(