SIGUSR1 to trigger fcitx layout change
This commit is contained in:
62
Cargo.lock
generated
62
Cargo.lock
generated
@@ -764,15 +764,6 @@ dependencies = [
|
||||
"objc2 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block2"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
|
||||
dependencies = [
|
||||
"objc2 0.6.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "1.6.2"
|
||||
@@ -1360,17 +1351,6 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790"
|
||||
dependencies = [
|
||||
"dispatch2",
|
||||
"nix 0.30.1",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cursor-icon"
|
||||
version = "1.2.0"
|
||||
@@ -1583,8 +1563,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.6.2",
|
||||
"libc",
|
||||
"objc2 0.6.3",
|
||||
]
|
||||
|
||||
@@ -3617,7 +3595,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"libc",
|
||||
"objc2 0.5.2",
|
||||
"objc2-core-data",
|
||||
@@ -3648,7 +3626,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-core-location",
|
||||
"objc2-foundation 0.2.2",
|
||||
@@ -3660,7 +3638,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
|
||||
dependencies = [
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
]
|
||||
@@ -3694,7 +3672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
]
|
||||
@@ -3716,7 +3694,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
|
||||
dependencies = [
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
"objc2-metal 0.2.2",
|
||||
@@ -3728,7 +3706,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
|
||||
dependencies = [
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-contacts",
|
||||
"objc2-foundation 0.2.2",
|
||||
@@ -3747,7 +3725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"dispatch",
|
||||
"libc",
|
||||
"objc2 0.5.2",
|
||||
@@ -3780,7 +3758,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
|
||||
dependencies = [
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation 0.2.2",
|
||||
@@ -3793,7 +3771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
]
|
||||
@@ -3816,7 +3794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
"objc2-metal 0.2.2",
|
||||
@@ -3852,7 +3830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-cloud-kit",
|
||||
"objc2-core-data",
|
||||
@@ -3872,7 +3850,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
|
||||
dependencies = [
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
]
|
||||
@@ -3884,7 +3862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"objc2 0.5.2",
|
||||
"objc2-core-location",
|
||||
"objc2-foundation 0.2.2",
|
||||
@@ -5052,6 +5030,16 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.7"
|
||||
@@ -6768,7 +6756,7 @@ dependencies = [
|
||||
"android-activity",
|
||||
"atomic-waker",
|
||||
"bitflags 2.10.0",
|
||||
"block2 0.5.1",
|
||||
"block2",
|
||||
"bytemuck",
|
||||
"calloop 0.13.0",
|
||||
"cfg_aliases",
|
||||
@@ -6872,7 +6860,6 @@ dependencies = [
|
||||
"chrono-tz",
|
||||
"clap",
|
||||
"config",
|
||||
"ctrlc",
|
||||
"dbus",
|
||||
"futures",
|
||||
"glam",
|
||||
@@ -6899,6 +6886,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_json5",
|
||||
"serde_yaml",
|
||||
"signal-hook",
|
||||
"slotmap",
|
||||
"smallvec",
|
||||
"smithay",
|
||||
|
||||
@@ -26,7 +26,6 @@ chrono = "0.4.42"
|
||||
chrono-tz = "0.10.4"
|
||||
clap = { version = "4.5.53", features = ["derive"] }
|
||||
config = "0.15.19"
|
||||
ctrlc = { version = "3.5.1", features = ["termination"] }
|
||||
dbus = { version = "0.9.9" }
|
||||
futures = "0.3.31"
|
||||
glam = { workspace = true, features = ["mint", "serde"] }
|
||||
@@ -99,6 +98,7 @@ wayland-egl = { version = "0.32.8", optional = true }
|
||||
bytes = { version = "1.11.0", optional = true }
|
||||
wayvr_ipc = { git = "https://github.com/olekolek1000/wayvr-ipc.git", rev = "a72587d23f3bb8624d9aeb1f13c0a21e65350f51", default-features = false, optional = true }
|
||||
rust-embed = { workspace = true }
|
||||
signal-hook = "0.3.18"
|
||||
################################
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -50,6 +50,7 @@ pub struct GuiPanel<S> {
|
||||
pub max_size: Vec2,
|
||||
pub gui_scale: f32,
|
||||
pub on_notify: Option<OnNotifyFunc<S>>,
|
||||
pub initialized: bool,
|
||||
interaction_transform: Option<Affine2>,
|
||||
context: WguiContext,
|
||||
timestep: Timestep,
|
||||
@@ -165,6 +166,7 @@ impl<S: 'static> GuiPanel<S> {
|
||||
interaction_transform: None,
|
||||
on_notify: None,
|
||||
gui_scale: params.gui_scale,
|
||||
initialized: false,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -194,6 +196,7 @@ impl<S: 'static> GuiPanel<S> {
|
||||
on_notify: None,
|
||||
interaction_transform: None,
|
||||
gui_scale: params.gui_scale,
|
||||
initialized: false,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -230,6 +233,7 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
|
||||
self.layout.content_size.x as _,
|
||||
self.layout.content_size.y as _,
|
||||
]));
|
||||
self.initialized = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -36,7 +36,10 @@ use std::{
|
||||
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
use libc::{SIGINT, SIGTERM, SIGUSR1};
|
||||
use signal_hook::iterator::Signals;
|
||||
use sysinfo::Pid;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
|
||||
@@ -45,6 +48,7 @@ use crate::subsystem::dbus::DbusConnector;
|
||||
|
||||
pub static FRAME_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||
pub static RUNNING: AtomicBool = AtomicBool::new(true);
|
||||
pub static KEYMAP_CHANGE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// The lightweight desktop overlay for OpenVR and OpenXR
|
||||
#[derive(Default, Parser, Debug)]
|
||||
@@ -114,11 +118,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let _ = ctrlc::set_handler({
|
||||
|| {
|
||||
RUNNING.store(false, Ordering::Relaxed);
|
||||
}
|
||||
});
|
||||
setup_signal_hooks()?;
|
||||
|
||||
auto_run(args);
|
||||
|
||||
@@ -200,6 +200,27 @@ const fn args_get_openxr(args: &Args) -> bool {
|
||||
ret
|
||||
}
|
||||
|
||||
fn setup_signal_hooks() -> anyhow::Result<()> {
|
||||
let mut signals = Signals::new([SIGINT, SIGTERM, SIGUSR1])?;
|
||||
|
||||
std::thread::spawn(move || {
|
||||
for signal in signals.forever() {
|
||||
match signal {
|
||||
SIGUSR1 => {
|
||||
log::info!("SIGUSR1 received (keymap changed)");
|
||||
KEYMAP_CHANGE.store(true, Ordering::Relaxed);
|
||||
continue;
|
||||
}
|
||||
_ => {
|
||||
RUNNING.store(false, Ordering::Relaxed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn logging_init(args: &mut Args) {
|
||||
let log_file_path = args
|
||||
.log_to
|
||||
|
||||
@@ -2,22 +2,24 @@ use std::{
|
||||
cell::Cell,
|
||||
collections::HashMap,
|
||||
process::{Child, Command},
|
||||
sync::atomic::Ordering,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
KEYMAP_CHANGE,
|
||||
backend::input::{HoverResult, PointerHit},
|
||||
gui::panel::GuiPanel,
|
||||
overlays::keyboard::{builder::create_keyboard_panel, layout::AltModifier},
|
||||
state::AppState,
|
||||
subsystem::hid::{
|
||||
ALT, CTRL, KeyModifier, META, SHIFT, SUPER, VirtualKey, WheelDelta, XkbKeymap,
|
||||
wayland::WlKeymapMonitor,
|
||||
},
|
||||
windowing::{
|
||||
backend::{FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender},
|
||||
window::OverlayWindowConfig,
|
||||
},
|
||||
};
|
||||
use anyhow::Context;
|
||||
use glam::{Affine3A, Quat, Vec3, vec3};
|
||||
use slotmap::{SlotMap, new_key_type};
|
||||
use wgui::{
|
||||
@@ -66,7 +68,6 @@ pub fn create_keyboard(
|
||||
active_keymap: KeyboardPanelKey::default(),
|
||||
default_state,
|
||||
layout,
|
||||
wkm: WlKeymapMonitor::new()?,
|
||||
};
|
||||
|
||||
backend.active_keymap = backend.add_new_keymap(keymap.as_ref(), app)?;
|
||||
@@ -99,7 +100,6 @@ struct KeyboardBackend {
|
||||
active_keymap: KeyboardPanelKey,
|
||||
default_state: KeyboardState,
|
||||
layout: layout::Layout,
|
||||
wkm: WlKeymapMonitor,
|
||||
}
|
||||
|
||||
impl KeyboardBackend {
|
||||
@@ -167,10 +167,28 @@ impl OverlayBackend for KeyboardBackend {
|
||||
self.panel().init(app)
|
||||
}
|
||||
fn should_render(&mut self, app: &mut AppState) -> anyhow::Result<ShouldRender> {
|
||||
if let Some(keymap) = self.wkm.check() {
|
||||
while KEYMAP_CHANGE.swap(false, Ordering::Relaxed) {
|
||||
let keymap: XkbKeymap;
|
||||
if let Ok(fcitx_layout) = app
|
||||
.dbus
|
||||
.fcitx_keymap()
|
||||
.context("Could not fetch Fcitx5 keymap")
|
||||
.inspect_err(|e| log::warn!("{e:?}"))
|
||||
&& fcitx_layout.starts_with("keyboard-")
|
||||
&& let Some(fcitx_keymap) = XkbKeymap::from_layout_str(&fcitx_layout[9..])
|
||||
{
|
||||
keymap = fcitx_keymap;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
app.hid_provider.keymap_changed(&keymap);
|
||||
if self.switch_keymap(&keymap, app)? {
|
||||
return Ok(match self.panel().should_render(app)? {
|
||||
let panel = self.panel();
|
||||
if !panel.initialized {
|
||||
panel.init(app)?;
|
||||
}
|
||||
return Ok(match panel.should_render(app)? {
|
||||
ShouldRender::Should | ShouldRender::Can => ShouldRender::Should,
|
||||
ShouldRender::Unable => ShouldRender::Unable,
|
||||
});
|
||||
|
||||
548
wlx-overlay-s/src/subsystem/dbus/fcitx5.rs
Normal file
548
wlx-overlay-s/src/subsystem/dbus/fcitx5.rs
Normal file
@@ -0,0 +1,548 @@
|
||||
// This code was autogenerated with `dbus-codegen-rust -g -m None -d org.fcitx.Fcitx5 -p /controller`, see https://github.com/diwic/dbus-rs
|
||||
use dbus;
|
||||
#[allow(unused_imports)]
|
||||
use dbus::arg;
|
||||
use dbus::blocking;
|
||||
|
||||
pub trait OrgFreedesktopDBusIntrospectable {
|
||||
fn introspect(&self) -> Result<String, dbus::Error>;
|
||||
}
|
||||
|
||||
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>>
|
||||
OrgFreedesktopDBusIntrospectable for blocking::Proxy<'a, C>
|
||||
{
|
||||
fn introspect(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.freedesktop.DBus.Introspectable", "Introspect", ())
|
||||
.and_then(|r: (String,)| Ok(r.0))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait OrgFcitxFcitxController1 {
|
||||
fn activate(&self) -> Result<(), dbus::Error>;
|
||||
fn add_input_method_group(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn addon_for_im(&self, arg0: &str) -> Result<String, dbus::Error>;
|
||||
fn available_input_methods(
|
||||
&self,
|
||||
) -> Result<Vec<(String, String, String, String, String, String, bool)>, dbus::Error>;
|
||||
fn available_keyboard_layouts(
|
||||
&self,
|
||||
) -> Result<
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
Vec<String>,
|
||||
Vec<(String, String, Vec<String>)>,
|
||||
)>,
|
||||
dbus::Error,
|
||||
>;
|
||||
fn can_restart(&self) -> Result<bool, dbus::Error>;
|
||||
fn check_update(&self) -> Result<bool, dbus::Error>;
|
||||
fn configure(&self) -> Result<(), dbus::Error>;
|
||||
fn configure_addon(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn configure_im(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn current_input_method(&self) -> Result<String, dbus::Error>;
|
||||
fn current_input_method_group(&self) -> Result<String, dbus::Error>;
|
||||
fn current_input_method_info(
|
||||
&self,
|
||||
) -> Result<
|
||||
(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
bool,
|
||||
String,
|
||||
arg::PropMap,
|
||||
),
|
||||
dbus::Error,
|
||||
>;
|
||||
fn current_ui(&self) -> Result<String, dbus::Error>;
|
||||
fn deactivate(&self) -> Result<(), dbus::Error>;
|
||||
fn debug_info(&self) -> Result<String, dbus::Error>;
|
||||
fn exit(&self) -> Result<(), dbus::Error>;
|
||||
fn full_input_method_group_info(
|
||||
&self,
|
||||
arg0: &str,
|
||||
) -> Result<
|
||||
(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
arg::PropMap,
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
bool,
|
||||
String,
|
||||
arg::PropMap,
|
||||
)>,
|
||||
),
|
||||
dbus::Error,
|
||||
>;
|
||||
fn get_addons(&self) -> Result<Vec<(String, String, String, i32, bool, bool)>, dbus::Error>;
|
||||
fn get_addons_v2(
|
||||
&self,
|
||||
) -> Result<
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
i32,
|
||||
bool,
|
||||
bool,
|
||||
bool,
|
||||
Vec<String>,
|
||||
Vec<String>,
|
||||
)>,
|
||||
dbus::Error,
|
||||
>;
|
||||
fn get_config<R0: for<'b> arg::Get<'b> + 'static>(
|
||||
&self,
|
||||
arg0: &str,
|
||||
) -> Result<
|
||||
(
|
||||
R0,
|
||||
Vec<(
|
||||
String,
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
arg::Variant<Box<dyn arg::RefArg + 'static>>,
|
||||
arg::PropMap,
|
||||
)>,
|
||||
)>,
|
||||
),
|
||||
dbus::Error,
|
||||
>;
|
||||
fn input_method_group_info(
|
||||
&self,
|
||||
arg0: &str,
|
||||
) -> Result<(String, Vec<(String, String)>), dbus::Error>;
|
||||
fn input_method_groups(&self) -> Result<Vec<String>, dbus::Error>;
|
||||
fn open_wayland_connection(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn open_wayland_connection_socket(&self, arg0: arg::OwnedFd) -> Result<(), dbus::Error>;
|
||||
fn open_x11_connection(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn refresh(&self) -> Result<(), dbus::Error>;
|
||||
fn reload_addon_config(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn reload_config(&self) -> Result<(), dbus::Error>;
|
||||
fn remove_input_method_group(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn reopen_wayland_connection_socket(
|
||||
&self,
|
||||
arg0: &str,
|
||||
arg1: arg::OwnedFd,
|
||||
) -> Result<(), dbus::Error>;
|
||||
fn reset_imlist(&self) -> Result<(), dbus::Error>;
|
||||
fn restart(&self) -> Result<(), dbus::Error>;
|
||||
fn save(&self) -> Result<(), dbus::Error>;
|
||||
fn set_addons_state(&self, arg0: Vec<(&str, bool)>) -> Result<(), dbus::Error>;
|
||||
fn set_config<I1: arg::Arg + arg::Append>(
|
||||
&self,
|
||||
arg0: &str,
|
||||
arg1: I1,
|
||||
) -> Result<(), dbus::Error>;
|
||||
fn set_current_im(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn set_input_method_group_info(
|
||||
&self,
|
||||
arg0: &str,
|
||||
arg1: &str,
|
||||
arg2: Vec<(&str, &str)>,
|
||||
) -> Result<(), dbus::Error>;
|
||||
fn set_log_rule(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn state(&self) -> Result<i32, dbus::Error>;
|
||||
fn switch_input_method_group(&self, arg0: &str) -> Result<(), dbus::Error>;
|
||||
fn toggle(&self) -> Result<(), dbus::Error>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OrgFcitxFcitxController1InputMethodGroupsChanged {}
|
||||
|
||||
impl arg::AppendAll for OrgFcitxFcitxController1InputMethodGroupsChanged {
|
||||
fn append(&self, _: &mut arg::IterAppend) {}
|
||||
}
|
||||
|
||||
impl arg::ReadAll for OrgFcitxFcitxController1InputMethodGroupsChanged {
|
||||
fn read(_: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
|
||||
Ok(OrgFcitxFcitxController1InputMethodGroupsChanged {})
|
||||
}
|
||||
}
|
||||
|
||||
impl dbus::message::SignalArgs for OrgFcitxFcitxController1InputMethodGroupsChanged {
|
||||
const NAME: &'static str = "InputMethodGroupsChanged";
|
||||
const INTERFACE: &'static str = "org.fcitx.Fcitx.Controller1";
|
||||
}
|
||||
|
||||
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgFcitxFcitxController1
|
||||
for blocking::Proxy<'a, C>
|
||||
{
|
||||
fn activate(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "Activate", ())
|
||||
}
|
||||
|
||||
fn add_input_method_group(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"AddInputMethodGroup",
|
||||
(arg0,),
|
||||
)
|
||||
}
|
||||
|
||||
fn addon_for_im(&self, arg0: &str) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "AddonForIM", (arg0,))
|
||||
.and_then(|r: (String,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn available_input_methods(
|
||||
&self,
|
||||
) -> Result<Vec<(String, String, String, String, String, String, bool)>, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "AvailableInputMethods", ())
|
||||
.and_then(|r: (Vec<(String, String, String, String, String, String, bool)>,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn available_keyboard_layouts(
|
||||
&self,
|
||||
) -> Result<
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
Vec<String>,
|
||||
Vec<(String, String, Vec<String>)>,
|
||||
)>,
|
||||
dbus::Error,
|
||||
> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"AvailableKeyboardLayouts",
|
||||
(),
|
||||
)
|
||||
.and_then(
|
||||
|r: (
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
Vec<String>,
|
||||
Vec<(String, String, Vec<String>)>,
|
||||
)>,
|
||||
)| Ok(r.0),
|
||||
)
|
||||
}
|
||||
|
||||
fn can_restart(&self) -> Result<bool, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "CanRestart", ())
|
||||
.and_then(|r: (bool,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn check_update(&self) -> Result<bool, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "CheckUpdate", ())
|
||||
.and_then(|r: (bool,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn configure(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "Configure", ())
|
||||
}
|
||||
|
||||
fn configure_addon(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "ConfigureAddon", (arg0,))
|
||||
}
|
||||
|
||||
fn configure_im(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "ConfigureIM", (arg0,))
|
||||
}
|
||||
|
||||
fn current_input_method(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "CurrentInputMethod", ())
|
||||
.and_then(|r: (String,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn current_input_method_group(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "CurrentInputMethodGroup", ())
|
||||
.and_then(|r: (String,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn current_input_method_info(
|
||||
&self,
|
||||
) -> Result<
|
||||
(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
bool,
|
||||
String,
|
||||
arg::PropMap,
|
||||
),
|
||||
dbus::Error,
|
||||
> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "CurrentInputMethodInfo", ())
|
||||
}
|
||||
|
||||
fn current_ui(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "CurrentUI", ())
|
||||
.and_then(|r: (String,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn deactivate(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "Deactivate", ())
|
||||
}
|
||||
|
||||
fn debug_info(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "DebugInfo", ())
|
||||
.and_then(|r: (String,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn exit(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "Exit", ())
|
||||
}
|
||||
|
||||
fn full_input_method_group_info(
|
||||
&self,
|
||||
arg0: &str,
|
||||
) -> Result<
|
||||
(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
arg::PropMap,
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
bool,
|
||||
String,
|
||||
arg::PropMap,
|
||||
)>,
|
||||
),
|
||||
dbus::Error,
|
||||
> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"FullInputMethodGroupInfo",
|
||||
(arg0,),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_addons(&self) -> Result<Vec<(String, String, String, i32, bool, bool)>, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "GetAddons", ())
|
||||
.and_then(|r: (Vec<(String, String, String, i32, bool, bool)>,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn get_addons_v2(
|
||||
&self,
|
||||
) -> Result<
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
i32,
|
||||
bool,
|
||||
bool,
|
||||
bool,
|
||||
Vec<String>,
|
||||
Vec<String>,
|
||||
)>,
|
||||
dbus::Error,
|
||||
> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "GetAddonsV2", ())
|
||||
.and_then(
|
||||
|r: (
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
i32,
|
||||
bool,
|
||||
bool,
|
||||
bool,
|
||||
Vec<String>,
|
||||
Vec<String>,
|
||||
)>,
|
||||
)| Ok(r.0),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_config<R0: for<'b> arg::Get<'b> + 'static>(
|
||||
&self,
|
||||
arg0: &str,
|
||||
) -> Result<
|
||||
(
|
||||
R0,
|
||||
Vec<(
|
||||
String,
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
arg::Variant<Box<dyn arg::RefArg + 'static>>,
|
||||
arg::PropMap,
|
||||
)>,
|
||||
)>,
|
||||
),
|
||||
dbus::Error,
|
||||
> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "GetConfig", (arg0,))
|
||||
.and_then(
|
||||
|r: (
|
||||
arg::Variant<R0>,
|
||||
Vec<(
|
||||
String,
|
||||
Vec<(
|
||||
String,
|
||||
String,
|
||||
String,
|
||||
arg::Variant<Box<dyn arg::RefArg + 'static>>,
|
||||
arg::PropMap,
|
||||
)>,
|
||||
)>,
|
||||
)| Ok(((r.0).0, r.1)),
|
||||
)
|
||||
}
|
||||
|
||||
fn input_method_group_info(
|
||||
&self,
|
||||
arg0: &str,
|
||||
) -> Result<(String, Vec<(String, String)>), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"InputMethodGroupInfo",
|
||||
(arg0,),
|
||||
)
|
||||
}
|
||||
|
||||
fn input_method_groups(&self) -> Result<Vec<String>, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "InputMethodGroups", ())
|
||||
.and_then(|r: (Vec<String>,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn open_wayland_connection(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"OpenWaylandConnection",
|
||||
(arg0,),
|
||||
)
|
||||
}
|
||||
|
||||
fn open_wayland_connection_socket(&self, arg0: arg::OwnedFd) -> Result<(), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"OpenWaylandConnectionSocket",
|
||||
(arg0,),
|
||||
)
|
||||
}
|
||||
|
||||
fn open_x11_connection(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "OpenX11Connection", (arg0,))
|
||||
}
|
||||
|
||||
fn refresh(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "Refresh", ())
|
||||
}
|
||||
|
||||
fn reload_addon_config(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "ReloadAddonConfig", (arg0,))
|
||||
}
|
||||
|
||||
fn reload_config(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "ReloadConfig", ())
|
||||
}
|
||||
|
||||
fn remove_input_method_group(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"RemoveInputMethodGroup",
|
||||
(arg0,),
|
||||
)
|
||||
}
|
||||
|
||||
fn reopen_wayland_connection_socket(
|
||||
&self,
|
||||
arg0: &str,
|
||||
arg1: arg::OwnedFd,
|
||||
) -> Result<(), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"ReopenWaylandConnectionSocket",
|
||||
(arg0, arg1),
|
||||
)
|
||||
}
|
||||
|
||||
fn reset_imlist(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "ResetIMList", ())
|
||||
}
|
||||
|
||||
fn restart(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "Restart", ())
|
||||
}
|
||||
|
||||
fn save(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "Save", ())
|
||||
}
|
||||
|
||||
fn set_addons_state(&self, arg0: Vec<(&str, bool)>) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "SetAddonsState", (arg0,))
|
||||
}
|
||||
|
||||
fn set_config<I1: arg::Arg + arg::Append>(
|
||||
&self,
|
||||
arg0: &str,
|
||||
arg1: I1,
|
||||
) -> Result<(), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"SetConfig",
|
||||
(arg0, arg::Variant(arg1)),
|
||||
)
|
||||
}
|
||||
|
||||
fn set_current_im(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "SetCurrentIM", (arg0,))
|
||||
}
|
||||
|
||||
fn set_input_method_group_info(
|
||||
&self,
|
||||
arg0: &str,
|
||||
arg1: &str,
|
||||
arg2: Vec<(&str, &str)>,
|
||||
) -> Result<(), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"SetInputMethodGroupInfo",
|
||||
(arg0, arg1, arg2),
|
||||
)
|
||||
}
|
||||
|
||||
fn set_log_rule(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "SetLogRule", (arg0,))
|
||||
}
|
||||
|
||||
fn state(&self) -> Result<i32, dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "State", ())
|
||||
.and_then(|r: (i32,)| Ok(r.0))
|
||||
}
|
||||
|
||||
fn switch_input_method_group(&self, arg0: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call(
|
||||
"org.fcitx.Fcitx.Controller1",
|
||||
"SwitchInputMethodGroup",
|
||||
(arg0,),
|
||||
)
|
||||
}
|
||||
|
||||
fn toggle(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.fcitx.Fcitx.Controller1", "Toggle", ())
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,11 @@ use dbus::{
|
||||
message::MatchRule,
|
||||
};
|
||||
|
||||
use crate::subsystem::dbus::notifications::OrgFreedesktopNotifications;
|
||||
use crate::subsystem::dbus::{
|
||||
fcitx5::OrgFcitxFcitxController1, notifications::OrgFreedesktopNotifications,
|
||||
};
|
||||
|
||||
mod fcitx5;
|
||||
mod notifications;
|
||||
|
||||
pub type DbusReceiveCallback = Box<dyn FnMut(Message, &Connection) -> bool + Send>;
|
||||
@@ -74,6 +77,20 @@ impl DbusConnector {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn fcitx_keymap(&mut self) -> anyhow::Result<String> {
|
||||
let connection = Connection::new_session()?;
|
||||
let proxy = connection.with_proxy(
|
||||
"org.fcitx.Fcitx5",
|
||||
"/controller",
|
||||
Duration::from_millis(500),
|
||||
);
|
||||
|
||||
let result = proxy
|
||||
.current_input_method()
|
||||
.context("Could not get D-Bus response");
|
||||
result
|
||||
}
|
||||
|
||||
pub fn notify_send(
|
||||
&mut self,
|
||||
summary: &str,
|
||||
@@ -83,16 +100,12 @@ impl DbusConnector {
|
||||
replaces_id: u32,
|
||||
transient: bool,
|
||||
) -> anyhow::Result<u32> {
|
||||
let connection = self
|
||||
.connection
|
||||
.take()
|
||||
.context("Not connected")
|
||||
.or_else(|_| Connection::new_session())?;
|
||||
let connection = Connection::new_session()?;
|
||||
|
||||
let proxy = connection.with_proxy(
|
||||
"org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
Duration::from_millis(1000),
|
||||
Duration::from_millis(500),
|
||||
);
|
||||
|
||||
let mut hints = PropMap::new();
|
||||
@@ -109,25 +122,19 @@ impl DbusConnector {
|
||||
hints,
|
||||
timeout,
|
||||
)?;
|
||||
self.connection = Some(connection);
|
||||
|
||||
Ok(retval)
|
||||
}
|
||||
|
||||
pub fn notify_close(&mut self, id: u32) -> anyhow::Result<()> {
|
||||
let connection = self
|
||||
.connection
|
||||
.take()
|
||||
.context("Not connected")
|
||||
.or_else(|_| Connection::new_session())?;
|
||||
let connection = Connection::new_session()?;
|
||||
|
||||
let proxy = connection.with_proxy(
|
||||
"org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
Duration::from_millis(1000),
|
||||
Duration::from_millis(500),
|
||||
);
|
||||
|
||||
proxy.close_notification(id)?;
|
||||
self.connection = Some(connection);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,6 +578,12 @@ pub struct XkbKeymap {
|
||||
}
|
||||
|
||||
impl XkbKeymap {
|
||||
pub fn from_layout_str(layout: &str) -> Option<Self> {
|
||||
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
|
||||
xkb::Keymap::new_from_names(&context, "", "", layout, "", None, xkb::COMPILE_NO_FLAGS)
|
||||
.map(|inner| XkbKeymap { inner })
|
||||
}
|
||||
|
||||
pub fn label_for_key(&self, key: VirtualKey, modifier: KeyModifier) -> String {
|
||||
let mut state = xkb::State::new(&self.inner);
|
||||
if modifier > 0
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use anyhow::Context;
|
||||
use wayland_client::{EventQueue, globals::GlobalList};
|
||||
use wlx_capture::wayland::wayland_client::{
|
||||
Connection, Dispatch, Proxy, QueueHandle,
|
||||
globals::{GlobalListContents, registry_queue_init},
|
||||
@@ -13,62 +12,6 @@ use xkbcommon::xkb;
|
||||
|
||||
use super::XkbKeymap;
|
||||
|
||||
pub struct WlKeymapMonitor {
|
||||
connection: Connection,
|
||||
globals: GlobalList,
|
||||
queue: EventQueue<MonitorState>,
|
||||
state: MonitorState,
|
||||
}
|
||||
|
||||
impl WlKeymapMonitor {
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
let connection = Connection::connect_to_env()?;
|
||||
let (globals, mut queue) = registry_queue_init::<MonitorState>(&connection)?;
|
||||
let qh = queue.handle();
|
||||
let seat: WlSeat = globals
|
||||
.bind(&qh, 4..=9, ())
|
||||
.unwrap_or_else(|_| panic!("{}", WlSeat::interface().name));
|
||||
|
||||
let mut state = MonitorState {
|
||||
seat,
|
||||
keyboard: None,
|
||||
keymap: None,
|
||||
};
|
||||
|
||||
// this gets us the wl_seat
|
||||
let _ = queue.blocking_dispatch(&mut state);
|
||||
|
||||
// this gets us the wl_keyboard
|
||||
let _ = queue.blocking_dispatch(&mut state);
|
||||
|
||||
Ok(Self {
|
||||
connection,
|
||||
globals,
|
||||
queue,
|
||||
state,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn check(&mut self) -> Option<XkbKeymap> {
|
||||
let Some(read_guard) = self.connection.prepare_read() else {
|
||||
return None;
|
||||
};
|
||||
read_guard
|
||||
.read()
|
||||
.context("could not read wayland events")
|
||||
.inspect_err(|e| log::warn!("{e:?}"))
|
||||
.ok()?;
|
||||
|
||||
self.queue.dispatch_pending(&mut self.state).ok()?;
|
||||
|
||||
self.take_keymap()
|
||||
}
|
||||
|
||||
pub fn take_keymap(&mut self) -> Option<XkbKeymap> {
|
||||
self.state.keymap.take()
|
||||
}
|
||||
}
|
||||
|
||||
struct MonitorState {
|
||||
seat: WlSeat,
|
||||
keyboard: Option<WlKeyboard>,
|
||||
|
||||
Reference in New Issue
Block a user