feat: add input sources applet
This commit is contained in:
parent
1abc466f49
commit
a1ad3c5f87
16 changed files with 508 additions and 36 deletions
110
Cargo.lock
generated
110
Cargo.lock
generated
|
|
@ -442,9 +442,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.2.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
|
|
@ -643,9 +643,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.96"
|
version = "1.0.97"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd"
|
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-expr"
|
name = "cfg-expr"
|
||||||
|
|
@ -962,6 +962,26 @@ dependencies = [
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cosmic-applet-input-sources"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"cosmic-comp-config",
|
||||||
|
"cosmic-time",
|
||||||
|
"i18n-embed",
|
||||||
|
"i18n-embed-fl",
|
||||||
|
"libcosmic",
|
||||||
|
"libpulse-binding",
|
||||||
|
"once_cell",
|
||||||
|
"rust-embed",
|
||||||
|
"serde",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"tracing-log",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"xkb-data",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-applet-minimize"
|
name = "cosmic-applet-minimize"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
@ -1071,6 +1091,7 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
"xkb-data",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1116,6 +1137,7 @@ dependencies = [
|
||||||
"cosmic-applet-audio",
|
"cosmic-applet-audio",
|
||||||
"cosmic-applet-battery",
|
"cosmic-applet-battery",
|
||||||
"cosmic-applet-bluetooth",
|
"cosmic-applet-bluetooth",
|
||||||
|
"cosmic-applet-input-sources",
|
||||||
"cosmic-applet-minimize",
|
"cosmic-applet-minimize",
|
||||||
"cosmic-applet-network",
|
"cosmic-applet-network",
|
||||||
"cosmic-applet-notifications",
|
"cosmic-applet-notifications",
|
||||||
|
|
@ -1227,7 +1249,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-panel-config"
|
name = "cosmic-panel-config"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/cosmic-panel#d1d656d6b2a4faaee34d72ed86bc0073dcd4da89"
|
source = "git+https://github.com/pop-os/cosmic-panel#683a204ef81bd17c2b35264521e5145df3518ee5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cosmic-config",
|
"cosmic-config",
|
||||||
|
|
@ -1272,7 +1294,7 @@ dependencies = [
|
||||||
"rangemap",
|
"rangemap",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"rustybuzz",
|
"rustybuzz",
|
||||||
"self_cell 1.0.3",
|
"self_cell 1.0.4",
|
||||||
"swash",
|
"swash",
|
||||||
"sys-locale",
|
"sys-locale",
|
||||||
"ttf-parser",
|
"ttf-parser",
|
||||||
|
|
@ -2011,9 +2033,9 @@ checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluent"
|
name = "fluent"
|
||||||
version = "0.16.0"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61f69378194459db76abd2ce3952b790db103ceb003008d3d50d97c41ff847a7"
|
checksum = "bb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluent-bundle",
|
"fluent-bundle",
|
||||||
"unic-langid",
|
"unic-langid",
|
||||||
|
|
@ -2021,9 +2043,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluent-bundle"
|
name = "fluent-bundle"
|
||||||
version = "0.15.2"
|
version = "0.15.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd"
|
checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluent-langneg",
|
"fluent-langneg",
|
||||||
"fluent-syntax",
|
"fluent-syntax",
|
||||||
|
|
@ -2046,9 +2068,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluent-syntax"
|
name = "fluent-syntax"
|
||||||
version = "0.11.0"
|
version = "0.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78"
|
checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
@ -2351,9 +2373,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.14"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -3046,9 +3068,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "intl-memoizer"
|
name = "intl-memoizer"
|
||||||
version = "0.5.1"
|
version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f"
|
checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"type-map",
|
"type-map",
|
||||||
"unic-langid",
|
"unic-langid",
|
||||||
|
|
@ -3720,9 +3742,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-iter"
|
name = "num-iter"
|
||||||
version = "0.1.44"
|
version = "0.1.45"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
|
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
|
|
@ -3743,9 +3765,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.18"
|
version = "0.2.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"libm",
|
"libm",
|
||||||
|
|
@ -4617,14 +4639,14 @@ version = "0.10.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"
|
checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"self_cell 1.0.3",
|
"self_cell 1.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "self_cell"
|
name = "self_cell"
|
||||||
version = "1.0.3"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba"
|
checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
|
|
@ -4635,6 +4657,18 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde-xml-rs"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
"xml-rs",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.200"
|
version = "1.0.200"
|
||||||
|
|
@ -4798,7 +4832,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-clipboard"
|
name = "smithay-clipboard"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "git+https://github.com/pop-os/smithay-clipboard?tag=pop-dnd-4#eefa50c3df5135d98df7f4192e2e9b07eeafe56b"
|
source = "git+https://github.com/pop-os/smithay-clipboard?tag=pop-dnd-4#9b995a33a88c496a90259dd207367a998c95ac98"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"raw-window-handle 0.6.1",
|
"raw-window-handle 0.6.1",
|
||||||
|
|
@ -5295,7 +5329,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow 0.6.7",
|
"winnow 0.6.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -5367,9 +5401,9 @@ checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "type-map"
|
name = "type-map"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46"
|
checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
]
|
]
|
||||||
|
|
@ -6167,9 +6201,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.6.7"
|
version = "0.6.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578"
|
checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
@ -6226,6 +6260,16 @@ dependencies = [
|
||||||
"wayland-protocols-wlr",
|
"wayland-protocols-wlr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xkb-data"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "294a599fc9e6a43c9f44f5d6c560b89fd751be413717442b31c17fa367d3c764"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde-xml-rs",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xkbcommon"
|
name = "xkbcommon"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
|
@ -6358,18 +6402,18 @@ checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.32"
|
version = "0.7.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
|
checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.7.32"
|
version = "0.7.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
checksum = "6f4b6c273f496d8fd4eaf18853e6b448760225dc030ff2c485a786859aea6393"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ members = [
|
||||||
"cosmic-applet-time",
|
"cosmic-applet-time",
|
||||||
"cosmic-applet-workspaces",
|
"cosmic-applet-workspaces",
|
||||||
"cosmic-panel-button",
|
"cosmic-panel-button",
|
||||||
|
"cosmic-applet-input-sources",
|
||||||
]
|
]
|
||||||
|
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
|
||||||
20
cosmic-applet-input-sources/Cargo.toml
Normal file
20
cosmic-applet-input-sources/Cargo.toml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
[package]
|
||||||
|
name = "cosmic-applet-input-sources"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cosmic-time.workspace = true
|
||||||
|
cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp.git", rev = "5eb5af4" }
|
||||||
|
i18n-embed-fl.workspace = true
|
||||||
|
i18n-embed.workspace = true
|
||||||
|
libcosmic.workspace = true
|
||||||
|
libpulse-binding = "2.28.1"
|
||||||
|
rust-embed.workspace = true
|
||||||
|
tokio = { version = "1.36.0", features=["full"] }
|
||||||
|
tracing-log.workspace = true
|
||||||
|
tracing-subscriber.workspace = true
|
||||||
|
tracing.workspace = true
|
||||||
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
|
once_cell = "1.19.0"
|
||||||
|
xkb-data = "0.1.0"
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Cosmic Applet Input Sources
|
||||||
|
Comment=Applet for Cosmic Panel
|
||||||
|
Type=Application
|
||||||
|
Exec=cosmic-applet-input-sources
|
||||||
|
Terminal=false
|
||||||
|
Categories=Cosmic;Iced;
|
||||||
|
Keywords=Cosmic;Iced;
|
||||||
|
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||||
|
Icon=com.system76.CosmicAppletInputSources
|
||||||
|
StartupNotify=true
|
||||||
|
NoDisplay=true
|
||||||
|
X-CosmicApplet=true
|
||||||
4
cosmic-applet-input-sources/i18n.toml
Normal file
4
cosmic-applet-input-sources/i18n.toml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
fallback_language = "en"
|
||||||
|
|
||||||
|
[fluent]
|
||||||
|
assets_dir = "i18n"
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
show-keyboard-layout = Show Keyboard Layout...
|
||||||
|
keyboard-settings = Keyboard Settings...
|
||||||
15
cosmic-applet-input-sources/src/config.rs
Normal file
15
cosmic-applet-input-sources/src/config.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
use cosmic::cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry};
|
||||||
|
use cosmic_comp_config::XkbConfig;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
pub const CONFIG_VERSION: u64 = 1;
|
||||||
|
#[derive(Clone, CosmicConfigEntry, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||||
|
pub struct Config {}
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Clone, CosmicConfigEntry, Debug, Deserialize, PartialEq, Serialize, Default)]
|
||||||
|
pub struct CosmicCompConfig {
|
||||||
|
pub xkb_config: XkbConfig,
|
||||||
|
}
|
||||||
53
cosmic-applet-input-sources/src/lib.rs
Normal file
53
cosmic-applet-input-sources/src/lib.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
use crate::window::Window;
|
||||||
|
use config::{Config, CONFIG_VERSION};
|
||||||
|
use cosmic::cosmic_config;
|
||||||
|
use cosmic::cosmic_config::CosmicConfigEntry;
|
||||||
|
mod config;
|
||||||
|
use cosmic_comp_config::CosmicCompConfig;
|
||||||
|
use window::Flags;
|
||||||
|
mod localize;
|
||||||
|
mod window;
|
||||||
|
pub fn run() -> cosmic::iced::Result {
|
||||||
|
localize::localize();
|
||||||
|
let (config_handler, config) = match cosmic_config::Config::new(window::ID, CONFIG_VERSION) {
|
||||||
|
Ok(config_handler) => {
|
||||||
|
let config = match Config::get_entry(&config_handler) {
|
||||||
|
Ok(ok) => ok,
|
||||||
|
Err((errs, config)) => {
|
||||||
|
eprintln!("errors loading config: {:?}", errs);
|
||||||
|
config
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(Some(config_handler), config)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to create config handler: {}", err);
|
||||||
|
(None, Config::default())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let (comp_config_handler, comp_config) =
|
||||||
|
match cosmic_config::Config::new("com.system76.CosmicComp", CosmicCompConfig::VERSION) {
|
||||||
|
Ok(config_handler) => {
|
||||||
|
let config = match CosmicCompConfig::get_entry(&config_handler) {
|
||||||
|
Ok(ok) => ok,
|
||||||
|
Err((errs, config)) => {
|
||||||
|
eprintln!("errors loading config: {:?}", errs);
|
||||||
|
config
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(Some(config_handler), config)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to create config handler: {}", err);
|
||||||
|
(None, CosmicCompConfig::default())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let flags = Flags {
|
||||||
|
comp_config,
|
||||||
|
comp_config_handler,
|
||||||
|
config_handler: config_handler,
|
||||||
|
config: config,
|
||||||
|
};
|
||||||
|
cosmic::applet::run::<Window>(true, flags)
|
||||||
|
}
|
||||||
36
cosmic-applet-input-sources/src/localize.rs
Normal file
36
cosmic-applet-input-sources/src/localize.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
use i18n_embed::{
|
||||||
|
fluent::{fluent_language_loader, FluentLanguageLoader},
|
||||||
|
DefaultLocalizer, LanguageLoader, Localizer,
|
||||||
|
};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use rust_embed::RustEmbed;
|
||||||
|
#[derive(RustEmbed)]
|
||||||
|
#[folder = "i18n/"]
|
||||||
|
struct Localizations;
|
||||||
|
pub static LANGUAGE_LOADER: Lazy<FluentLanguageLoader> = Lazy::new(|| {
|
||||||
|
let loader: FluentLanguageLoader = fluent_language_loader!();
|
||||||
|
loader
|
||||||
|
.load_fallback_language(&Localizations)
|
||||||
|
.expect("Error while loading fallback language");
|
||||||
|
loader
|
||||||
|
});
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! fl {
|
||||||
|
($message_id:literal) => {{
|
||||||
|
i18n_embed_fl::fl!($crate::localize::LANGUAGE_LOADER, $message_id)
|
||||||
|
}};
|
||||||
|
($message_id:literal, $($args:expr),*) => {{
|
||||||
|
i18n_embed_fl::fl!($crate::localize::LANGUAGE_LOADER, $message_id, $($args), *)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
// Get the `Localizer` to be used for localizing this library.
|
||||||
|
pub fn localizer() -> Box<dyn Localizer> {
|
||||||
|
Box::from(DefaultLocalizer::new(&*LANGUAGE_LOADER, &Localizations))
|
||||||
|
}
|
||||||
|
pub fn localize() {
|
||||||
|
let localizer = localizer();
|
||||||
|
let requested_languages = i18n_embed::DesktopLanguageRequester::requested_languages();
|
||||||
|
if let Err(error) = localizer.select(&requested_languages) {
|
||||||
|
eprintln!("Error while loading language for App List {}", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
cosmic-applet-input-sources/src/main.rs
Normal file
3
cosmic-applet-input-sources/src/main.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() -> cosmic::iced::Result {
|
||||||
|
cosmic_applet_input_sources::run()
|
||||||
|
}
|
||||||
277
cosmic-applet-input-sources/src/window.rs
Normal file
277
cosmic-applet-input-sources/src/window.rs
Normal file
|
|
@ -0,0 +1,277 @@
|
||||||
|
use crate::config::{Config, CONFIG_VERSION};
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use crate::fl;
|
||||||
|
use cosmic::app::Core;
|
||||||
|
use cosmic::applet::{self};
|
||||||
|
use cosmic::cosmic_config::{self, ConfigSet};
|
||||||
|
use cosmic::iced::wayland::popup::{destroy_popup, get_popup};
|
||||||
|
use cosmic::iced::window::Id;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use cosmic::iced::{alignment, Alignment, Length};
|
||||||
|
use cosmic::iced::{Command, Limits};
|
||||||
|
use cosmic::iced_futures::Subscription;
|
||||||
|
use cosmic::iced_runtime::core::window;
|
||||||
|
use cosmic::iced_style::application;
|
||||||
|
use cosmic::prelude::*;
|
||||||
|
use cosmic::widget;
|
||||||
|
use cosmic_comp_config::CosmicCompConfig;
|
||||||
|
use xkb_data::KeyboardLayouts;
|
||||||
|
pub const ID: &str = "com.system76.CosmicAppletInputSources";
|
||||||
|
|
||||||
|
pub struct Window {
|
||||||
|
core: Core,
|
||||||
|
popup: Option<Id>,
|
||||||
|
config: Config,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
config_handler: Option<cosmic_config::Config>,
|
||||||
|
comp_config: CosmicCompConfig,
|
||||||
|
comp_config_handler: Option<cosmic_config::Config>,
|
||||||
|
layouts: KeyboardLayouts,
|
||||||
|
active_layouts: Vec<ActiveLayout>,
|
||||||
|
}
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum Message {
|
||||||
|
Config(Config),
|
||||||
|
TogglePopup,
|
||||||
|
PopupClosed(Id),
|
||||||
|
CompConfig(CosmicCompConfig),
|
||||||
|
SetActiveLayout(ActiveLayout),
|
||||||
|
KeyboardSettings,
|
||||||
|
}
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Flags {
|
||||||
|
pub config_handler: Option<cosmic_config::Config>,
|
||||||
|
pub config: Config,
|
||||||
|
pub comp_config: CosmicCompConfig,
|
||||||
|
pub comp_config_handler: Option<cosmic_config::Config>,
|
||||||
|
}
|
||||||
|
impl cosmic::Application for Window {
|
||||||
|
type Executor = cosmic::SingleThreadExecutor;
|
||||||
|
type Flags = Flags;
|
||||||
|
type Message = Message;
|
||||||
|
const APP_ID: &'static str = ID;
|
||||||
|
fn core(&self) -> &Core {
|
||||||
|
&self.core
|
||||||
|
}
|
||||||
|
fn core_mut(&mut self) -> &mut Core {
|
||||||
|
&mut self.core
|
||||||
|
}
|
||||||
|
fn init(
|
||||||
|
core: Core,
|
||||||
|
flags: Self::Flags,
|
||||||
|
) -> (Self, Command<cosmic::app::Message<Self::Message>>) {
|
||||||
|
let layouts = xkb_data::keyboard_layouts().unwrap();
|
||||||
|
let window = Window {
|
||||||
|
comp_config_handler: flags.comp_config_handler,
|
||||||
|
layouts,
|
||||||
|
core,
|
||||||
|
config: flags.config,
|
||||||
|
config_handler: flags.config_handler,
|
||||||
|
popup: None,
|
||||||
|
comp_config: flags.comp_config,
|
||||||
|
active_layouts: Vec::new(),
|
||||||
|
};
|
||||||
|
(window, Command::none())
|
||||||
|
}
|
||||||
|
fn on_close_requested(&self, id: window::Id) -> Option<Message> {
|
||||||
|
Some(Message::PopupClosed(id))
|
||||||
|
}
|
||||||
|
fn update(&mut self, message: Self::Message) -> Command<cosmic::app::Message<Self::Message>> {
|
||||||
|
match message {
|
||||||
|
Message::Config(config) => self.config = config,
|
||||||
|
Message::TogglePopup => {
|
||||||
|
return if let Some(p) = self.popup.take() {
|
||||||
|
destroy_popup(p)
|
||||||
|
} else {
|
||||||
|
let new_id = Id::unique();
|
||||||
|
self.popup.replace(new_id);
|
||||||
|
let mut popup_settings =
|
||||||
|
self.core
|
||||||
|
.applet
|
||||||
|
.get_popup_settings(Id::MAIN, new_id, None, None, None);
|
||||||
|
popup_settings.positioner.size_limits = Limits::NONE
|
||||||
|
.max_width(372.0)
|
||||||
|
.min_width(300.0)
|
||||||
|
.min_height(200.0)
|
||||||
|
.max_height(1080.0);
|
||||||
|
get_popup(popup_settings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::PopupClosed(id) => {
|
||||||
|
if self.popup.as_ref() == Some(&id) {
|
||||||
|
self.popup = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::CompConfig(config) => {
|
||||||
|
self.comp_config = config;
|
||||||
|
self.active_layouts = self.update_xkb();
|
||||||
|
}
|
||||||
|
Message::KeyboardSettings => {
|
||||||
|
let mut cmd = std::process::Command::new("cosmic-settings");
|
||||||
|
cmd.arg("keyboard");
|
||||||
|
cosmic::process::spawn(cmd);
|
||||||
|
}
|
||||||
|
Message::SetActiveLayout(active_layout) => {
|
||||||
|
let Some(i) = self
|
||||||
|
.active_layouts
|
||||||
|
.iter()
|
||||||
|
.position(|layout| layout == &active_layout)
|
||||||
|
else {
|
||||||
|
return Command::none();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.active_layouts.swap(0, i);
|
||||||
|
let mut new_layout = String::new();
|
||||||
|
let mut new_variant = String::new();
|
||||||
|
|
||||||
|
for layout in &self.active_layouts {
|
||||||
|
new_layout.push_str(&layout.layout);
|
||||||
|
new_layout.push(',');
|
||||||
|
new_variant.push_str(&layout.variant);
|
||||||
|
new_variant.push(',');
|
||||||
|
}
|
||||||
|
let _excess_comma = new_layout.pop();
|
||||||
|
let _excess_comma = new_variant.pop();
|
||||||
|
|
||||||
|
self.comp_config.xkb_config.layout = new_layout;
|
||||||
|
self.comp_config.xkb_config.variant = new_variant;
|
||||||
|
if let Some(comp_config_handler) = &self.comp_config_handler {
|
||||||
|
if let Err(err) =
|
||||||
|
comp_config_handler.set("xkb_config", &self.comp_config.xkb_config)
|
||||||
|
{
|
||||||
|
eprint!("Failed to set config 'xkb_config' {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Command::none()
|
||||||
|
}
|
||||||
|
fn view(&self) -> Element<Self::Message> {
|
||||||
|
let suggested = self.core.applet.suggested_padding();
|
||||||
|
widget::button(
|
||||||
|
widget::text(
|
||||||
|
self.active_layouts
|
||||||
|
.first()
|
||||||
|
.map_or(String::new(), |l| l.layout.clone()),
|
||||||
|
)
|
||||||
|
.size(14),
|
||||||
|
)
|
||||||
|
.style(cosmic::theme::Button::AppletIcon)
|
||||||
|
.padding([suggested / 2, suggested])
|
||||||
|
.on_press(Message::TogglePopup)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
fn view_window(&self, _id: Id) -> Element<Self::Message> {
|
||||||
|
let mut content_list =
|
||||||
|
widget::column::with_capacity(4 + self.active_layouts.len()).padding([8, 0]);
|
||||||
|
for layout in &self.active_layouts {
|
||||||
|
let group = widget::column::with_capacity(2)
|
||||||
|
.push(widget::text(layout.description.clone()).size(16))
|
||||||
|
.push(widget::text(layout.layout.clone()).size(14));
|
||||||
|
content_list = content_list.push(
|
||||||
|
applet::menu_button(group).on_press(Message::SetActiveLayout(layout.clone())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
content_list = content_list.extend(
|
||||||
|
[
|
||||||
|
applet::padded_control(widget::divider::horizontal::default()).apply(Element::from),
|
||||||
|
applet::menu_button(widget::text(fl!("show-keyboard-layout"))).into(),
|
||||||
|
applet::padded_control(widget::divider::horizontal::default()).into(),
|
||||||
|
applet::menu_button(widget::text(fl!("keyboard-settings")))
|
||||||
|
.on_press(Message::KeyboardSettings)
|
||||||
|
.into(),
|
||||||
|
]
|
||||||
|
.into_iter(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.core.applet.popup_container(content_list).into()
|
||||||
|
}
|
||||||
|
fn subscription(&self) -> Subscription<Self::Message> {
|
||||||
|
struct ConfigSubscription;
|
||||||
|
let config = cosmic_config::config_subscription(
|
||||||
|
std::any::TypeId::of::<ConfigSubscription>(),
|
||||||
|
Self::APP_ID.into(),
|
||||||
|
CONFIG_VERSION,
|
||||||
|
)
|
||||||
|
.map(|update| {
|
||||||
|
if !update.errors.is_empty() {
|
||||||
|
eprintln!(
|
||||||
|
"errors loading config {:?}: {:?}",
|
||||||
|
update.keys, update.errors
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Message::Config(update.config)
|
||||||
|
});
|
||||||
|
let xbg_config = self
|
||||||
|
.core
|
||||||
|
.watch_config("com.system76.CosmicComp")
|
||||||
|
.map(|update| {
|
||||||
|
if !update.errors.is_empty() {
|
||||||
|
eprintln!(
|
||||||
|
"errors loading config {:?}: {:?}",
|
||||||
|
update.keys, update.errors
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Message::CompConfig(update.config)
|
||||||
|
});
|
||||||
|
Subscription::batch(vec![config, xbg_config])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn style(&self) -> Option<<Theme as application::StyleSheet>::Style> {
|
||||||
|
Some(cosmic::applet::style())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Window {
|
||||||
|
fn update_xkb(&self) -> Vec<ActiveLayout> {
|
||||||
|
let mut active_layouts = Vec::new();
|
||||||
|
let xkb = &self.comp_config.xkb_config;
|
||||||
|
|
||||||
|
let layouts = xkb.layout.split_terminator(',');
|
||||||
|
|
||||||
|
let variants = xkb
|
||||||
|
.variant
|
||||||
|
.split_terminator(',')
|
||||||
|
.chain(std::iter::repeat(""));
|
||||||
|
|
||||||
|
for (layout, variant) in layouts.zip(variants) {
|
||||||
|
println!("{} : {}", layout, variant);
|
||||||
|
for xkb_layout in self.layouts.layouts() {
|
||||||
|
if layout != xkb_layout.name() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if variant.is_empty() {
|
||||||
|
let active_layout = ActiveLayout {
|
||||||
|
description: xkb_layout.description().to_owned(),
|
||||||
|
layout: layout.to_owned(),
|
||||||
|
variant: variant.to_owned(),
|
||||||
|
};
|
||||||
|
active_layouts.push(active_layout);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(xkb_variants) = xkb_layout.variants() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
for xkb_variant in xkb_variants {
|
||||||
|
if variant != xkb_variant.name() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let active_layout = ActiveLayout {
|
||||||
|
description: xkb_variant.description().to_owned(),
|
||||||
|
layout: layout.to_owned(),
|
||||||
|
variant: variant.to_owned(),
|
||||||
|
};
|
||||||
|
active_layouts.push(active_layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
active_layouts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
pub struct ActiveLayout {
|
||||||
|
layout: String,
|
||||||
|
description: String,
|
||||||
|
variant: String,
|
||||||
|
}
|
||||||
|
|
@ -21,3 +21,4 @@ tokio = { version = "1.36.0", features = ["sync", "rt"] }
|
||||||
tracing-log.workspace = true
|
tracing-log.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
|
xkb-data = "0.1.0"
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ cosmic-applet-status-area = { path = "../cosmic-applet-status-area" }
|
||||||
cosmic-applet-tiling = { path = "../cosmic-applet-tiling" }
|
cosmic-applet-tiling = { path = "../cosmic-applet-tiling" }
|
||||||
cosmic-applet-time = { path = "../cosmic-applet-time" }
|
cosmic-applet-time = { path = "../cosmic-applet-time" }
|
||||||
cosmic-applet-workspaces = { path = "../cosmic-applet-workspaces" }
|
cosmic-applet-workspaces = { path = "../cosmic-applet-workspaces" }
|
||||||
|
cosmic-applet-input-sources = { path = "../cosmic-applet-input-sources"}
|
||||||
libcosmic.workspace = true
|
libcosmic.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber.workspace = true
|
||||||
tracing-log.workspace = true
|
tracing-log.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ fn main() -> cosmic::iced::Result {
|
||||||
"cosmic-applet-tiling" => cosmic_applet_tiling::run(),
|
"cosmic-applet-tiling" => cosmic_applet_tiling::run(),
|
||||||
"cosmic-applet-time" => cosmic_applet_time::run(),
|
"cosmic-applet-time" => cosmic_applet_time::run(),
|
||||||
"cosmic-applet-workspaces" => cosmic_applet_workspaces::run(),
|
"cosmic-applet-workspaces" => cosmic_applet_workspaces::run(),
|
||||||
|
"cosmic-applet-input-sources" => cosmic_applet_input_sources::run(),
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
debian/links
vendored
3
debian/links
vendored
|
|
@ -9,4 +9,5 @@
|
||||||
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-status-area
|
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-status-area
|
||||||
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-tiling
|
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-tiling
|
||||||
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-time
|
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-time
|
||||||
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-workspaces
|
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-workspaces
|
||||||
|
/usr/bin/cosmic-applets /usr/bin/cosmic-applet-input-sources
|
||||||
|
|
|
||||||
2
justfile
2
justfile
|
|
@ -51,7 +51,7 @@ _install_applet id name: (_install_icons name) \
|
||||||
_install_button id name: (_install_icons name) (_install_desktop name + '/data/' + id + '.desktop')
|
_install_button id name: (_install_icons name) (_install_desktop name + '/data/' + id + '.desktop')
|
||||||
|
|
||||||
# Installs files into the system
|
# Installs files into the system
|
||||||
install: (_install_bin 'cosmic-applets') (_install_applet 'com.system76.CosmicAppList' 'cosmic-app-list') (_install_default_schema 'cosmic-app-list') (_install_applet 'com.system76.CosmicAppletAudio' 'cosmic-applet-audio') (_install_applet 'com.system76.CosmicAppletBattery' 'cosmic-applet-battery') (_install_applet 'com.system76.CosmicAppletBluetooth' 'cosmic-applet-bluetooth') (_install_applet 'com.system76.CosmicAppletMinimize' 'cosmic-applet-minimize') (_install_applet 'com.system76.CosmicAppletNetwork' 'cosmic-applet-network') (_install_applet 'com.system76.CosmicAppletNotifications' 'cosmic-applet-notifications') (_install_applet 'com.system76.CosmicAppletPower' 'cosmic-applet-power') (_install_applet 'com.system76.CosmicAppletStatusArea' 'cosmic-applet-status-area') (_install_applet 'com.system76.CosmicAppletTiling' 'cosmic-applet-tiling') (_install_applet 'com.system76.CosmicAppletTime' 'cosmic-applet-time') (_install_applet 'com.system76.CosmicAppletWorkspaces' 'cosmic-applet-workspaces') (_install_bin 'cosmic-panel-button') (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button') (_install_button 'com.system76.CosmicPanelLauncherButton' 'cosmic-panel-launcher-button') (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button')
|
install: (_install_bin 'cosmic-applets') (_install_applet 'com.system76.CosmicAppList' 'cosmic-app-list') (_install_default_schema 'cosmic-app-list') (_install_applet 'com.system76.CosmicAppletAudio' 'cosmic-applet-audio') (_install_applet 'com.system76.CosmicAppletInputSources' 'cosmic-applet-input-sources') (_install_applet 'com.system76.CosmicAppletBattery' 'cosmic-applet-battery') (_install_applet 'com.system76.CosmicAppletBluetooth' 'cosmic-applet-bluetooth') (_install_applet 'com.system76.CosmicAppletMinimize' 'cosmic-applet-minimize') (_install_applet 'com.system76.CosmicAppletNetwork' 'cosmic-applet-network') (_install_applet 'com.system76.CosmicAppletNotifications' 'cosmic-applet-notifications') (_install_applet 'com.system76.CosmicAppletPower' 'cosmic-applet-power') (_install_applet 'com.system76.CosmicAppletStatusArea' 'cosmic-applet-status-area') (_install_applet 'com.system76.CosmicAppletTiling' 'cosmic-applet-tiling') (_install_applet 'com.system76.CosmicAppletTime' 'cosmic-applet-time') (_install_applet 'com.system76.CosmicAppletWorkspaces' 'cosmic-applet-workspaces') (_install_bin 'cosmic-panel-button') (_install_button 'com.system76.CosmicPanelAppButton' 'cosmic-panel-app-button') (_install_button 'com.system76.CosmicPanelLauncherButton' 'cosmic-panel-launcher-button') (_install_button 'com.system76.CosmicPanelWorkspacesButton' 'cosmic-panel-workspaces-button')
|
||||||
|
|
||||||
# Vendor Cargo dependencies locally
|
# Vendor Cargo dependencies locally
|
||||||
vendor:
|
vendor:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue