use built in clipboard, add to settings menu, start gating swipe to type behind feature

This commit is contained in:
oneshinyboi 2026-07-27 23:54:26 -05:00
parent b62a4fde28
commit 18d3dc5e93
No known key found for this signature in database
GPG Key ID: A494E206A095F0C0
7 changed files with 47 additions and 105 deletions

97
Cargo.lock generated
View File

@ -252,26 +252,6 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
[[package]]
name = "arboard"
version = "3.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf"
dependencies = [
"clipboard-win",
"image",
"log",
"objc2 0.6.4",
"objc2-app-kit 0.3.2",
"objc2-core-foundation",
"objc2-core-graphics",
"objc2-foundation 0.3.2",
"parking_lot",
"percent-encoding",
"windows-sys 0.59.0",
"x11rb",
]
[[package]]
name = "arg_enum_proc_macro"
version = "0.3.4"
@ -1080,15 +1060,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "clipboard-win"
version = "5.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4"
dependencies = [
"error-code",
]
[[package]]
name = "cmake"
version = "0.1.58"
@ -1936,12 +1907,6 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "error-code"
version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
[[package]]
name = "etagere"
version = "0.3.0"
@ -2014,12 +1979,6 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
[[package]]
name = "fax"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a"
[[package]]
name = "fdeflate"
version = "0.3.7"
@ -2845,7 +2804,6 @@ dependencies = [
"png",
"ravif",
"rayon",
"tiff",
"zune-core",
"zune-jpeg",
]
@ -3840,18 +3798,6 @@ dependencies = [
"objc2-quartz-core 0.2.2",
]
[[package]]
name = "objc2-app-kit"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
dependencies = [
"bitflags 2.13.0",
"objc2 0.6.4",
"objc2-core-graphics",
"objc2-foundation 0.3.2",
]
[[package]]
name = "objc2-audio-toolbox"
version = "0.3.2"
@ -3949,19 +3895,6 @@ dependencies = [
"objc2 0.6.4",
]
[[package]]
name = "objc2-core-graphics"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807"
dependencies = [
"bitflags 2.13.0",
"dispatch2",
"objc2 0.6.4",
"objc2-core-foundation",
"objc2-io-surface",
]
[[package]]
name = "objc2-core-image"
version = "0.2.2"
@ -4028,17 +3961,6 @@ dependencies = [
"objc2-core-foundation",
]
[[package]]
name = "objc2-io-surface"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
dependencies = [
"bitflags 2.13.0",
"objc2 0.6.4",
"objc2-core-foundation",
]
[[package]]
name = "objc2-link-presentation"
version = "0.2.2"
@ -4047,7 +3969,7 @@ checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
dependencies = [
"block2 0.5.1",
"objc2 0.5.2",
"objc2-app-kit 0.2.2",
"objc2-app-kit",
"objc2-foundation 0.2.2",
]
@ -6426,20 +6348,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "tiff"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52"
dependencies = [
"fax",
"flate2",
"half",
"quick-error",
"weezl",
"zune-jpeg",
]
[[package]]
name = "time"
version = "0.3.53"
@ -7317,7 +7225,6 @@ name = "wayvr"
version = "26.7.1"
dependencies = [
"anyhow",
"arboard",
"ash",
"bytes",
"calloop 0.14.4",
@ -7899,7 +7806,7 @@ dependencies = [
"memmap2",
"ndk",
"objc2 0.5.2",
"objc2-app-kit 0.2.2",
"objc2-app-kit",
"objc2-foundation 0.2.2",
"objc2-ui-kit",
"orbclient",

View File

@ -152,6 +152,8 @@ impl State {
options_checkbox(par.mp, c, SettingType::NotificationsEnabled)?;
options_checkbox(par.mp, c, SettingType::NotificationsSoundEnabled)?;
options_checkbox(par.mp, c, SettingType::KeyboardSoundEnabled)?;
options_checkbox(par.mp, c, SettingType::KeyboardSwipeToTypeEnabled)?;
if !par.feats.openxr || par.feats.monado {
// monado or openvr
options_checkbox(par.mp, c, SettingType::BlockGameInput)?;

View File

@ -127,8 +127,7 @@ xkbcommon = {
calloop = { version = "0.14.4", optional = true }
calloop-wayland-source = { version = "0.4.1", optional = true }
evdev = "0.13.2"
super-swipe-type = "0.3.2"
arboard = "3.6.1"
super-swipe-type = { version = "0.3.2", optional = true }
[build-dependencies]
regex.workspace = true
@ -149,5 +148,6 @@ whisper = [
"dep:pipewire",
"dep:whisper-rs"
]
swipe-to-type = ["dep:super-swipe-type"]
x11 = ["dep:xcb", "wlx-capture/xshm", "xkbcommon/x11"]
xcb = ["dep:xcb"]

View File

@ -51,6 +51,8 @@ use crate::overlays::keyboard::swipe_type::SwipeTypingManager;
pub mod builder;
mod layout;
#[cfg(feature = "swipe-to-type ")]
mod swipe_type;
pub const KEYBOARD_NAME: &str = "kbd";
@ -123,7 +125,7 @@ pub fn create_keyboard(app: &mut AppState, wayland: bool) -> anyhow::Result<Over
transform: Affine3A::from_scale_rotation_translation(
Vec3::ONE * width,
Quat::from_rotation_x(-10f32.to_radians()),
vec3(0.0, -0.65, -0.5),
vec3(0.0, -0.69, -0.5),
),
..OverlayWindowState::default()
},
@ -187,9 +189,9 @@ impl KeyboardBackend {
if app.session.config.keyboard_swipe_to_type_enabled {
init_swipe_type_manager(&mut state);
log::info!("swipe engine created");
}
log::info!("swipe engine created");
let mut panel =
create_keyboard_panel(app, keymap, state, &self.wlx_layout)?;
@ -577,11 +579,19 @@ fn handle_release(app: &mut AppState, key: &KeyState, k_cap_type: &KeyCapType, k
};
swipe_manager.reset(); // drop swipe tracking that was started on press
app.hid_provider
.set_modifiers_routed(app.wvr_server.as_mut(), keyboard.modifiers);
app.hid_provider
.send_key_routed(app.wvr_server.as_mut(), *vk, true);
pressed.set(true);
app.hid_provider
.send_key_routed(app.wvr_server.as_mut(), *vk, false);
for m in &AUTO_RELEASE_MODS {
if keyboard.modifiers & *m != 0 {
keyboard.modifiers &= !*m;
}
}
play_key_click(app);
}
}

View File

@ -1,7 +1,6 @@
use crate::state::AppState;
use crate::subsystem::hid::{KeyModifier, VirtualKey, CTRL};
use anyhow::{bail};
use arboard::Clipboard;
use glam::Vec2;
use std::mem;
use std::sync::mpsc::{sync_channel, Receiver, SyncSender, channel, Sender};
@ -11,6 +10,9 @@ use super_swipe_type::keyboard_manager::QwertyKeyboardGrid;
use super_swipe_type::swipe_orchestrator::SwipeOrchestrator;
use super_swipe_type::{SwipePoint};
use wgui::event::{DeviceBitmask, MouseButtonIndex};
use wgui::log::LogErr;
use crate::subsystem::clipboard;
use crate::subsystem::clipboard::ClipboardProvider;
use crate::subsystem::input::InputFocus;
const PREDICTION_SUGGESTION_COUNT: usize = 5;
@ -22,7 +24,6 @@ enum PredictionTask {
},
Shutdown,
}
pub struct SwipeTypingManager {
keyboard_gird: QwertyKeyboardGrid,
current_swipe: Vec<SwipePoint>,
@ -30,7 +31,7 @@ pub struct SwipeTypingManager {
prediction_task_sender: Sender<PredictionTask>,
worker_thread: Option<JoinHandle<()>>,
swipe_start_time: Option<Instant>,
clipboard: Clipboard,
clipboard: Option<Box<dyn ClipboardProvider>>,
swipe_left_first_key: bool,
first_swipe_char: char,
current_swipe_device: Option<DeviceBitmask>,
@ -50,7 +51,8 @@ impl SwipeTypingManager {
match app.hid_provider.get_input_focus() {
InputFocus::PhysicalScreen => {
if let Ok(_) = self.clipboard.set_text(text_to_paste) {
if let Some(clipboard) = self.clipboard.as_mut() {
clipboard.set_clipboard_utf8(&*text_to_paste);
Self::paste(app, original_keyboard_mods);
}
},
@ -122,7 +124,27 @@ impl SwipeTypingManager {
}
}
});
let clipboard_provider: Option<Box<dyn ClipboardProvider>> = {
#[cfg(feature = "wayland")]
{
clipboard::wl::Provider::new()
.log_err("Could not create Wayland clipboard provider")
.ok()
.map(|p| Box::new(p) as Box<dyn ClipboardProvider>);
}
#[cfg(feature = "x11")]
{
clipboard::x11::Provider::new()
.log_err("Could not create X11 clipboard provider")
.ok()
.map(|p| Box::new(p) as Box<dyn ClipboardProvider>)
}
#[cfg(not(any(feature = "wayland", feature = "x11")))]
{
None
}
};
Ok((
Self {
keyboard_gird: QwertyKeyboardGrid::new(),
@ -131,7 +153,7 @@ impl SwipeTypingManager {
prediction_task_sender: task_sender,
worker_thread: Some(worker_thread),
swipe_start_time: None,
clipboard: Clipboard::new()?,
clipboard: clipboard_provider,
swipe_left_first_key: false,
first_swipe_char: char::default(),
current_swipe_device: None,

View File

@ -6,3 +6,4 @@ pub mod x11;
pub trait ClipboardProvider {
fn set_clipboard_utf8(&mut self, content: &str);
}

View File

@ -3,7 +3,7 @@ pub mod hid;
pub mod input;
pub mod notifications;
#[cfg(feature = "whisper")]
#[cfg(any(feature = "whisper", feature = "swipe-to-type"))]
pub mod clipboard;
#[cfg(feature = "whisper")]