Skip to content

feat: add xkeyboardconfig settings #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ zbus = { version = "5.1.0", features = ["tokio"] }
tokio = { version = "1.42.0", features = ["rt-multi-thread", "process"] }
eyre = "0.6.12"
nom = "8"
url = "2.5.2"
reqwest = { version = "0.12.8", features = ["json"] }
thiserror = "2"
libc = "0.2.159"
Expand All @@ -38,6 +37,7 @@ tauri-plugin-shell = "2.0.0"
tauri-plugin-dialog = "2.0.0"
tauri-plugin-cli = "2.0.0"
libaosc = { version = "0.3", default-features = false, features = ["arch"] }
serde-xml-rs = "0.8.0"

[features]
# this feature is used for production builds or when `devPath` points to the filesystem
Expand Down
12 changes: 10 additions & 2 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ use axum::Router;
use eyre::ContextCompat;
use eyre::OptionExt;
use eyre::Result;
use parser::list_zoneinfo;
use parser::ZoneInfo;
use parser::timezone::list_zoneinfo;
use parser::timezone::ZoneInfo;
use parser::xkeyboard::get_keyboard_layouts;
use parser::xkeyboard::KeyboardLayouts;
use rand::prelude::SliceRandom;
use rand::rng;
use reqwest::Client;
Expand Down Expand Up @@ -302,6 +304,11 @@ fn list_timezone() -> TauriResult<Vec<ZoneInfo>> {
Ok(list_zoneinfo()?)
}

#[tauri::command]
fn list_xkeyboard_config() -> TauriResult<KeyboardLayouts> {
Ok(get_keyboard_layouts()?)
}

#[tauri::command]
async fn set_config(state: State<'_, DkState<'_>>, config: &str) -> TauriResult<()> {
let proxy = &state.proxy;
Expand Down Expand Up @@ -928,6 +935,7 @@ pub async fn run() {
is_lang_already_set,
is_offline_install,
is_block_username,
list_xkeyboard_config,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod timezone;
pub mod xkeyboard;
File renamed without changes.
100 changes: 100 additions & 0 deletions src-tauri/src/parser/xkeyboard.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copy from https://github.com/pop-os/distinst/blob/8322c936a91ba5812ac9cbef79282a04bad738ea/crates/locales/src/keyboard_layout.rs#L82

use eyre::Result;
use serde::{Deserialize, Serialize};
use serde_xml_rs as xml;
use std::{fs::File, io::BufReader};

/// A list of keyboard layouts parsed from `/usr/share/X11/xkb/rules/base.xml`.
#[derive(Debug, Deserialize, Serialize)]
pub struct KeyboardLayouts {
#[serde(rename = "layoutList")]
pub layout_list: LayoutList,
}

impl KeyboardLayouts {
/// Fetch the layouts from the layout list.
pub fn get_layouts(&self) -> &[KeyboardLayout] {
&self.layout_list.layout
}

/// Fetch the layouts from the layout list.
pub fn get_layouts_mut(&mut self) -> &mut [KeyboardLayout] {
&mut self.layout_list.layout
}
}

/// A list of keyboard layouts.
#[derive(Debug, Deserialize, Serialize)]
pub struct LayoutList {
pub layout: Vec<KeyboardLayout>,
}

/// A keyboard layout, which contains an optional list of variants, a name, and a description.
#[derive(Debug, Deserialize, Serialize)]
pub struct KeyboardLayout {
#[serde(rename = "configItem")]
pub config_item: ConfigItem,
#[serde(rename = "variantList")]
pub variant_list: Option<VariantList>,
}

impl KeyboardLayout {
/// Fetches the name of the keyboard layout.
pub fn get_name(&self) -> &str {
&self.config_item.name
}

/// Fetches a description of the layout.
pub fn get_description(&self) -> &str {
&self.config_item.description
}

/// Fetches a list of possible layout variants.
pub fn get_variants(&self) -> Option<&Vec<KeyboardVariant>> {
self.variant_list.as_ref().and_then(|x| x.variant.as_ref())
}
}

/// Contains the name and description of a keyboard layout.
#[derive(Debug, Deserialize, Serialize)]
pub struct ConfigItem {
pub name: String,
#[serde(rename = "shortDescription")]
pub short_description: Option<String>,
pub description: String,
}

/// A list of possible variants of a keyboard layout.
#[derive(Debug, Deserialize, Serialize)]
pub struct VariantList {
pub variant: Option<Vec<KeyboardVariant>>,
}

/// A variant of a keyboard layout.
#[derive(Debug, Deserialize, Serialize)]
pub struct KeyboardVariant {
#[serde(rename = "configItem")]
pub config_item: ConfigItem,
}

impl KeyboardVariant {
/// The name of this variant of a keybaord layout.
pub fn get_name(&self) -> &str {
&self.config_item.name
}

/// A description of this variant of a keyboard layout.
pub fn get_description(&self) -> &str {
&self.config_item.description
}
}

const X11_BASE_RULES: &str = "/usr/share/X11/xkb/rules/base.xml";

/// Fetches a list of keyboard layouts from `/usr/share/X11/xkb/rules/base.xml`.
pub fn get_keyboard_layouts() -> Result<KeyboardLayouts> {
Ok(xml::from_reader(BufReader::new(File::open(
X11_BASE_RULES,
)?))?)
}
2 changes: 1 addition & 1 deletion src-tauri/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ use std::path::Path;
use eyre::{OptionExt, Result};
use libaosc::arch::get_arch_name;
use reqwest::Client;
use reqwest::Url;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::time::Instant;
use url::Url;
use x11rb::connection::Connection;
use x11rb::protocol::xproto::{
AtomEnum, ClientMessageEvent, ConnectionExt as ConnectionExtB, EventMask,
Expand Down