From 1aea1261f0b378651d5865b7bcbd64a548845a39 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Mon, 9 Aug 2021 21:57:01 +0200 Subject: [PATCH] feat(detect): add active layout detection on Gnome (wayland) --- espanso-detect/src/layout/gnome.rs | 56 ++++++++++++++++++++++++++++++ espanso-detect/src/layout/mod.rs | 11 +++++- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 espanso-detect/src/layout/gnome.rs diff --git a/espanso-detect/src/layout/gnome.rs b/espanso-detect/src/layout/gnome.rs new file mode 100644 index 0000000..2425258 --- /dev/null +++ b/espanso-detect/src/layout/gnome.rs @@ -0,0 +1,56 @@ +/* + * This file is part of espanso. + * + * Copyright (C) 2019-2021 Federico Terzi + * + * espanso is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * espanso is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with espanso. If not, see . + */ + +use std::process::Command; + +use log::error; +use regex::Regex; +use std::path::PathBuf; + +lazy_static! { + static ref LAYOUT_EXTRACT_REGEX: Regex = Regex::new(r"^\[\('.*?', '(.*?)'\)").unwrap(); +} + +pub fn get_active_layout() -> Option { + match Command::new("gsettings") + .arg("get") + .arg("org.gnome.desktop.input-sources") + .arg("mru-sources") + .output() + { + Ok(output) => { + let output_str = String::from_utf8_lossy(&output.stdout); + let captures = LAYOUT_EXTRACT_REGEX.captures(&output_str)?; + let layout = captures.get(1)?.as_str(); + Some(layout.to_string()) + } + Err(err) => { + error!( + "unable to retrieve current keyboard layout with 'gsettings': {}", + err + ); + None + } + } +} + +pub fn is_gnome() -> bool { + let target_session_file = PathBuf::from("/usr/bin/gnome-session"); + target_session_file.exists() +} diff --git a/espanso-detect/src/layout/mod.rs b/espanso-detect/src/layout/mod.rs index 1a2d54e..d24fe7e 100644 --- a/espanso-detect/src/layout/mod.rs +++ b/espanso-detect/src/layout/mod.rs @@ -21,6 +21,10 @@ #[cfg(not(feature = "wayland"))] mod x11; +#[cfg(target_os = "linux")] +#[cfg(feature = "wayland")] +mod gnome; + #[cfg(target_os = "linux")] #[cfg(not(feature = "wayland"))] pub fn get_active_layout() -> Option { @@ -30,7 +34,12 @@ pub fn get_active_layout() -> Option { #[cfg(target_os = "linux")] #[cfg(feature = "wayland")] pub fn get_active_layout() -> Option { - todo!() + if gnome::is_gnome() { + gnome::get_active_layout() + } else { + log::warn!("unable to determine the currently active layout, you might need to explicitly specify the layout in the config for espanso to work correctly."); + None + } } #[cfg(not(target_os = "linux"))]