mirror of https://github.com/wayvr-org/wayvr.git
gate swipe type behind feature, edit dashboard
This commit is contained in:
parent
404b5ea659
commit
ad89b44db2
|
|
@ -0,0 +1,10 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Ignored default folder with query files
|
||||
/queries/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
|
|
@ -227,11 +227,12 @@
|
|||
"WHISPER_MODEL": "Speech-to-text model",
|
||||
"WHISPER_MODEL_HELP": "Whisper model to use.\nLarger models produce more accurate\nresults, but consume more VRAM.",
|
||||
"SWIPE_TYPE": {
|
||||
"NEED_TO_DOWNLOAD_MODELS": "The swipe-to-type model needs to be downloaded.\nDownload them now?",
|
||||
"NEED_TO_DOWNLOAD_MODELS": "The swipe-to-type model needs to be downloaded.\nDownload it now?",
|
||||
"MODELS_DOWNLOADED": "Model downloaded",
|
||||
"MODELS_NOT_DOWNLOADED": "Model not downloaded",
|
||||
"REMOVE_MODELS": "Remove swipe to type model",
|
||||
"DOWNLOAD_MODELS": "Download swipe to type model ({} total)"
|
||||
"DOWNLOAD_MODELS": "Download swipe to type model",
|
||||
"DOWNLOAD_MODELS_HELP": "Swipe to type only works on qwerty layout keyboards"
|
||||
},
|
||||
"SWIPE_TYPE_MODELS": "Swipe-to-type models",
|
||||
"SWIPE_TYPE_MODELS_HELP": "Model files used by swipe-to-type.\nAll of them are required.",
|
||||
|
|
|
|||
|
|
@ -353,6 +353,7 @@ pub(crate) enum SettingType {
|
|||
InvertScrollDirectionY,
|
||||
KeyboardMiddleClick,
|
||||
KeyboardSoundEnabled,
|
||||
KeyboardSwipeToTypeEnabled,
|
||||
Language,
|
||||
LeftHandedMouse,
|
||||
LongPressDuration,
|
||||
|
|
@ -412,6 +413,7 @@ impl SettingType {
|
|||
Self::InvertScrollDirectionX => &mut config.invert_scroll_direction_x,
|
||||
Self::InvertScrollDirectionY => &mut config.invert_scroll_direction_y,
|
||||
Self::KeyboardSoundEnabled => &mut config.keyboard_sound_enabled,
|
||||
Self::KeyboardSwipeToTypeEnabled => &mut config.keyboard_swipe_to_type_enabled,
|
||||
Self::LeftHandedMouse => &mut config.left_handed_mouse,
|
||||
Self::NotificationsEnabled => &mut config.notifications_enabled,
|
||||
Self::NotificationsSoundEnabled => &mut config.notifications_sound_enabled,
|
||||
|
|
@ -550,6 +552,7 @@ impl SettingType {
|
|||
Self::InvertScrollDirectionY => Ok("APP_SETTINGS.INVERT_SCROLL_DIRECTION_Y"),
|
||||
Self::KeyboardMiddleClick => Ok("APP_SETTINGS.KEYBOARD_MIDDLE_CLICK"),
|
||||
Self::KeyboardSoundEnabled => Ok("APP_SETTINGS.KEYBOARD_SOUND_ENABLED"),
|
||||
Self::KeyboardSwipeToTypeEnabled => Ok("APP_SETTINGS.KEYBOARD_SWIPE_TYPE_ENABLED"),
|
||||
Self::Language => Ok("APP_SETTINGS.LANGUAGE"),
|
||||
Self::LeftHandedMouse => Ok("APP_SETTINGS.LEFT_HANDED_MOUSE"),
|
||||
Self::LongPressDuration => Ok("APP_SETTINGS.LONG_PRESS_DURATION"),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
use wgui::{
|
||||
|
|
@ -22,22 +23,23 @@ use crate::{
|
|||
util::{
|
||||
popup_manager::PopupHolder,
|
||||
swipe_type::{
|
||||
SWIPE_TYPE_MODELS, SwipeTypeModel, swipe_type_all_models_downloaded,
|
||||
SWIPE_TYPE_MODEL, swwipe_type_model_downloaded,
|
||||
swipe_type_delete_all_models, swipe_type_model_path,
|
||||
},
|
||||
whisper::{
|
||||
WHISPER_MODELS, WhisperModel, whisper_any_models_downloaded, whisper_delete_all_models, whisper_model_from_name,
|
||||
WHISPER_MODELS, whisper_any_models_downloaded, whisper_delete_all_models, whisper_model_from_name,
|
||||
whisper_model_path,
|
||||
},
|
||||
},
|
||||
views::{self, ViewUpdateParams},
|
||||
};
|
||||
use crate::util::downloadable_file::DownloadableFile;
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Task {
|
||||
WhisperDownloadClosed,
|
||||
WhisperRemoveUnused,
|
||||
WhisperDownload(&'static WhisperModel),
|
||||
WhisperDownload(&'static DownloadableFile),
|
||||
WhisperDownloadDone,
|
||||
SwipeTypeDownloadClosed,
|
||||
SwipeTypeRemoveAll,
|
||||
|
|
@ -54,8 +56,8 @@ pub struct State {
|
|||
globals: WguiGlobals,
|
||||
tasks: Tasks<Task>,
|
||||
parent_tasks: Tasks<ParentTask>,
|
||||
pending_whisper_download: Option<&'static WhisperModel>,
|
||||
pending_swipe_download: Option<&'static [SwipeTypeModel]>,
|
||||
pending_whisper_download: Option<&'static DownloadableFile>,
|
||||
pending_swipe_download: Option<&'static DownloadableFile>,
|
||||
}
|
||||
|
||||
impl SettingsTab for State {
|
||||
|
|
@ -81,7 +83,7 @@ impl SettingsTab for State {
|
|||
}
|
||||
Task::WhisperDownload(model) => {
|
||||
self.pending_whisper_download = Some(model);
|
||||
self.show_whisper_download_dialog(model, par.executor.clone());
|
||||
self.show_download_dialogue(model, par.executor.clone(), whisper_model_path(model.file_name), Task::WhisperDownloadClosed, Task::WhisperDownloadDone);
|
||||
}
|
||||
Task::WhisperDownloadDone => {
|
||||
if let Some(model) = self.pending_whisper_download.take() {
|
||||
|
|
@ -94,22 +96,22 @@ impl SettingsTab for State {
|
|||
}
|
||||
Task::SwipeTypeDownloadClosed => {
|
||||
self.pending_swipe_download = None;
|
||||
if !swipe_type_all_models_downloaded().unwrap_or_default() {
|
||||
par.general_config.swipe_type_models_downloaded = false;
|
||||
if !swwipe_type_model_downloaded().unwrap_or_default() {
|
||||
par.general_config.keyboard_swipe_to_type_enabled = false;
|
||||
par.config_change_kind.replace(ConfigChangeKind::Other);
|
||||
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
|
||||
}
|
||||
}
|
||||
Task::SwipeTypeRemoveAll => {
|
||||
let _ = swipe_type_delete_all_models().log_err("could not remove swipe type models");
|
||||
par.general_config.keyboard_swipe_to_type_enabled = false;
|
||||
}
|
||||
Task::SwipeTypeDownloadAll => {
|
||||
self.pending_swipe_download = Some(SWIPE_TYPE_MODELS);
|
||||
self.show_swipe_type_download_dialog(SWIPE_TYPE_MODELS, par.executor.clone());
|
||||
self.pending_swipe_download = Some(&SWIPE_TYPE_MODEL);
|
||||
self.show_download_dialogue(&SWIPE_TYPE_MODEL, par.executor.clone(), swipe_type_model_path(SWIPE_TYPE_MODEL.file_name), Task::SwipeTypeDownloadClosed, Task::SwipeTypeDownloadDone);
|
||||
}
|
||||
Task::SwipeTypeDownloadDone => {
|
||||
if let Some(_) = self.pending_swipe_download.take() {
|
||||
par.general_config.swipe_type_models_downloaded = true;
|
||||
par.config_change_kind.replace(ConfigChangeKind::Other);
|
||||
self.parent_tasks.push(ParentTask::SetTab(TabNameEnum::Features));
|
||||
}
|
||||
|
|
@ -204,7 +206,7 @@ impl State {
|
|||
if par.feats.swipe_to_type {
|
||||
swipe_type_models_button(par.mp, c)?;
|
||||
}
|
||||
|
||||
options_checkbox(par.mp, c, SettingType::KeyboardSwipeToTypeEnabled)?;
|
||||
options_checkbox(par.mp, c, SettingType::NotificationsEnabled)?;
|
||||
options_checkbox(par.mp, c, SettingType::NotificationsSoundEnabled)?;
|
||||
options_checkbox(par.mp, c, SettingType::KeyboardSoundEnabled)?;
|
||||
|
|
@ -240,27 +242,22 @@ impl State {
|
|||
})
|
||||
}
|
||||
|
||||
fn show_whisper_download_dialog(&mut self, model: &WhisperModel, executor: AsyncExecutor) {
|
||||
fn show_download_dialogue(&mut self, file: &DownloadableFile, executor: AsyncExecutor, target_path: PathBuf, on_closed: Task, on_downloaded: Task) {
|
||||
views::download_file::mount_popup(
|
||||
self.popup_download.clone(),
|
||||
self.frontend_tasks.clone(),
|
||||
self.tasks.make_callback_box(Task::WhisperDownloadClosed),
|
||||
self.tasks.make_callback_box(on_closed),
|
||||
views::download_file::Params {
|
||||
globals: self.globals.clone(),
|
||||
executor,
|
||||
target_path: whisper_model_path(model.file_name),
|
||||
url: model.url.into(),
|
||||
on_downloaded: self.tasks.make_callback_box(Task::WhisperDownloadDone),
|
||||
target_path,
|
||||
url: file.url.into(),
|
||||
on_downloaded: self.tasks.make_callback_box(on_downloaded),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn show_swipe_type_download_dialog(&mut self, models: &[SwipeTypeModel], executor: AsyncExecutor) {
|
||||
//TODO: create views::download_files and use that
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn show_whisper_model_dialog_box_download(&mut self, model: &'static WhisperModel) -> anyhow::Result<()> {
|
||||
fn show_whisper_model_dialog_box_download(&mut self, model: &'static DownloadableFile) -> anyhow::Result<()> {
|
||||
const ACTION_DOWNLOAD: &str = "download";
|
||||
const ACTION_CANCEL: &str = "cancel";
|
||||
|
||||
|
|
@ -464,7 +461,7 @@ fn swipe_type_models_button(mp: &mut MacroParams, parent: WidgetID) -> anyhow::R
|
|||
|
||||
let id_cell = horiz_cell(mp.layout, parent)?;
|
||||
|
||||
let all_downloaded = swipe_type_all_models_downloaded().unwrap_or_default();
|
||||
let all_downloaded = swwipe_type_model_downloaded().unwrap_or_default();
|
||||
let (translation, icon, action) = if all_downloaded {
|
||||
(
|
||||
"APP_SETTINGS.SWIPE_TYPE.REMOVE_MODELS",
|
||||
|
|
@ -473,7 +470,7 @@ fn swipe_type_models_button(mp: &mut MacroParams, parent: WidgetID) -> anyhow::R
|
|||
)
|
||||
} else {
|
||||
(
|
||||
"APP_SETTINGS.SWIPE_TYPE.DOWNLOAD_MODELS;5.0 MiB",
|
||||
"APP_SETTINGS.SWIPE_TYPE.DOWNLOAD_MODELS",
|
||||
"dashboard/download.svg",
|
||||
"swipe_type_download",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
pub struct DownloadableFile {
|
||||
pub file_name: &'static str,
|
||||
pub display_name: &'static str,
|
||||
pub url: &'static str,
|
||||
}
|
||||
|
|
@ -8,3 +8,4 @@ pub mod toast_manager;
|
|||
pub mod wgui_simple;
|
||||
pub mod whisper;
|
||||
pub mod swipe_type;
|
||||
pub mod downloadable_file;
|
||||
|
|
|
|||
|
|
@ -1,33 +1,13 @@
|
|||
use std::{fs, io, path::PathBuf};
|
||||
|
||||
use wlx_common::data_dir;
|
||||
use crate::util::downloadable_file::DownloadableFile;
|
||||
|
||||
/// The set of model files required by the swipe-to-type engine.
|
||||
/// These correspond to the assets that `super-swipe-type` currently
|
||||
/// downloads via `cached_path` in `SwipeOrchestrator::new()`.
|
||||
pub struct SwipeTypeModel {
|
||||
pub file_name: &'static str,
|
||||
pub url: &'static str,
|
||||
}
|
||||
|
||||
pub const SWIPE_TYPE_MODELS: &[SwipeTypeModel] = &[
|
||||
SwipeTypeModel {
|
||||
file_name: "swipe_encoder_android.onnx",
|
||||
url: "https://wayvr.org/files/swipe_type/swipe_encoder_android.onnx",
|
||||
},
|
||||
SwipeTypeModel {
|
||||
file_name: "swipe_decoder_android.onnx",
|
||||
url: "https://wayvr.org/files/swipe_type/swipe_decoder_android.onnx",
|
||||
},
|
||||
SwipeTypeModel {
|
||||
file_name: "en_wordlist.fst",
|
||||
url: "https://wayvr.org/files/swipe_type/en_wordlist.fst",
|
||||
},
|
||||
SwipeTypeModel {
|
||||
file_name: "en_bigrams.fst",
|
||||
url: "https://wayvr.org/files/swipe_type/en_bigrams.fst",
|
||||
},
|
||||
];
|
||||
pub const SWIPE_TYPE_MODEL: DownloadableFile = DownloadableFile {
|
||||
file_name: "en.tar",
|
||||
display_name: "English Qwerty (15 MiB)",
|
||||
url: "https://github.com/oneshinyboi/super-swipe-type/raw/refs/tags/v0.4.2/crates/super-swipe-type/assets/en.tar",
|
||||
};
|
||||
|
||||
pub fn swipe_type_model_folder() -> PathBuf {
|
||||
data_dir::get_path("swipe_type")
|
||||
|
|
@ -37,16 +17,13 @@ pub fn swipe_type_model_path(file_name: &str) -> PathBuf {
|
|||
swipe_type_model_folder().join(file_name)
|
||||
}
|
||||
|
||||
/// Returns true when every required model file is present on disk.
|
||||
pub fn swipe_type_all_models_downloaded() -> io::Result<bool> {
|
||||
pub fn swwipe_type_model_downloaded() -> io::Result<bool> {
|
||||
let path = swipe_type_model_folder();
|
||||
if !path.is_dir() {
|
||||
return Ok(false);
|
||||
}
|
||||
for model in SWIPE_TYPE_MODELS {
|
||||
if !path.join(model.file_name).exists() {
|
||||
return Ok(false);
|
||||
}
|
||||
if !path.join(SWIPE_TYPE_MODEL.file_name).exists() {
|
||||
return Ok(false);
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +1,37 @@
|
|||
use std::{fs, io, path::PathBuf};
|
||||
|
||||
use wlx_common::data_dir;
|
||||
use crate::util::downloadable_file::DownloadableFile;
|
||||
|
||||
pub struct WhisperModel {
|
||||
pub file_name: &'static str,
|
||||
pub display_name: &'static str,
|
||||
pub url: &'static str,
|
||||
}
|
||||
|
||||
pub const WHISPER_MODELS: &[WhisperModel] = &[
|
||||
WhisperModel {
|
||||
pub const WHISPER_MODELS: &[DownloadableFile] = &[
|
||||
DownloadableFile {
|
||||
file_name: "ggml-base-q8_0.bin",
|
||||
display_name: "Base Q8 (78MiB)",
|
||||
url: "https://wayvr.org/files/whisper/ggml-base-q8_0.bin",
|
||||
},
|
||||
WhisperModel {
|
||||
DownloadableFile {
|
||||
file_name: "ggml-small-q8_0.bin",
|
||||
display_name: "Small Q8 (252MiB)",
|
||||
url: "https://wayvr.org/files/whisper/ggml-small-q8_0.bin",
|
||||
},
|
||||
WhisperModel {
|
||||
DownloadableFile {
|
||||
file_name: "ggml-large-v3-turbo-q5_0.bin",
|
||||
display_name: "Turbo Q5 (574MiB)",
|
||||
url: "https://wayvr.org/files/whisper/ggml-large-v3-turbo-q5_0.bin",
|
||||
},
|
||||
WhisperModel {
|
||||
DownloadableFile {
|
||||
file_name: "ggml-large-v3-turbo-q8_0.bin",
|
||||
display_name: "Turbo Q8 (874MiB)",
|
||||
url: "https://wayvr.org/files/whisper/ggml-large-v3-turbo-q8_0.bin",
|
||||
},
|
||||
WhisperModel {
|
||||
DownloadableFile {
|
||||
file_name: "ggml-large-v3-turbo.bin",
|
||||
display_name: "Turbo (1.5GiB)",
|
||||
url: "https://wayvr.org/files/whisper/ggml-large-v3-turbo.bin",
|
||||
},
|
||||
];
|
||||
|
||||
pub fn whisper_model_from_name(file_name: &str) -> Option<&'static WhisperModel> {
|
||||
pub fn whisper_model_from_name(file_name: &str) -> Option<&'static DownloadableFile> {
|
||||
WHISPER_MODELS.iter().find(|x| x.file_name == file_name)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,11 @@ use wgui::{
|
|||
use wgui::event::StyleSetRequest;
|
||||
use wgui::layout::LayoutTask;
|
||||
use wgui::taffy::Display;
|
||||
use super::{KeyButtonData, KeyState, KeyboardState, handle_press, handle_release, layout::{self, KeyCapType}, handle_mouse_motion, init_swipe_type_manager};
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
use wlx_common::data_dir;
|
||||
use super::{KeyButtonData, KeyState, KeyboardState, handle_press, handle_release, layout::{self, KeyCapType}, handle_mouse_motion};
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
use super::init_swipe_type_manager;
|
||||
|
||||
const PIXELS_PER_UNIT: f32 = 60.;
|
||||
|
||||
|
|
@ -478,7 +482,8 @@ pub(super) fn create_keyboard_panel(
|
|||
}
|
||||
}
|
||||
if app.session.config.keyboard_swipe_to_type_enabled && panel.state.swipe_typing_manager.is_none() {
|
||||
init_swipe_type_manager(&mut panel.state);
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
init_swipe_type_manager(&mut panel.state, data_dir::get_path("swipe_type"));
|
||||
|
||||
let predictions_root = panel.parser_state
|
||||
.get_widget_id("swipe_predictions_root")
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ use wlx_common::{
|
|||
config::AltModifier,
|
||||
overlays::{BackendAttrib, BackendAttribValue},
|
||||
};
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
use wlx_common::data_dir;
|
||||
use crate::overlays::keyboard::builder::update_swipe_prediction_bar;
|
||||
use crate::overlays::keyboard::layout::KeyCapType;
|
||||
use crate::overlays::keyboard::swipe_type::SwipeTypingManager;
|
||||
|
|
@ -52,9 +54,32 @@ use crate::overlays::keyboard::swipe_type::SwipeTypingManager;
|
|||
pub mod builder;
|
||||
mod layout;
|
||||
|
||||
#[cfg(feature = "swipe-to-type ")]
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
mod swipe_type;
|
||||
|
||||
#[cfg(not(feature = "swipe-to-type"))]
|
||||
mod swipe_type {
|
||||
use std::sync::mpsc::Receiver;
|
||||
use wgui::event::{DeviceBitmask, MouseButtonIndex};
|
||||
use glam::Vec2;
|
||||
|
||||
pub struct SwipeTypingManager;
|
||||
|
||||
impl SwipeTypingManager {
|
||||
pub fn new(_model_folder: std::path::PathBuf) -> anyhow::Result<(Self, Receiver<Option<Vec<String>>>)> {
|
||||
Ok((Self, std::sync::mpsc::sync_channel(1).1))
|
||||
}
|
||||
pub fn add_swipe(&mut self, _within_key_pos_normalized: &Vec2, _key_label: char, _device: DeviceBitmask, _index: Option<MouseButtonIndex>) {}
|
||||
pub fn predict(&mut self) -> anyhow::Result<()> { Ok(()) }
|
||||
pub fn reset(&mut self) {}
|
||||
pub fn did_swipe_leave_first_key(&self) -> bool { false }
|
||||
pub fn is_current_swipe_empty(&self) -> bool { true }
|
||||
pub fn current_swipe_mouse_button_index(&self) -> Option<MouseButtonIndex> { None }
|
||||
pub fn select_word(&mut self, _word: &String, _app: &mut crate::state::AppState, _original_keyboard_mods: crate::subsystem::hid::KeyModifier) {}
|
||||
pub fn select_alternate_prediction(&mut self, _word: &String, _app: &mut crate::state::AppState, _original_keyboard_mods: crate::subsystem::hid::KeyModifier) {}
|
||||
}
|
||||
}
|
||||
|
||||
pub const KEYBOARD_NAME: &str = "kbd";
|
||||
const AUTO_RELEASE_MODS: [KeyModifier; 5] = [SHIFT, CTRL, ALT, SUPER, ALTGR];
|
||||
const SYSTEM_LAYOUT_ALIASES: [&str; 5] = ["mozc", "pinyin", "hangul", "sayura", "unikey"];
|
||||
|
|
@ -132,8 +157,9 @@ pub fn create_keyboard(app: &mut AppState, wayland: bool) -> anyhow::Result<Over
|
|||
..OverlayWindowConfig::from_backend(Box::new(backend))
|
||||
})
|
||||
}
|
||||
pub(self) fn init_swipe_type_manager(state: &mut KeyboardState) {
|
||||
match SwipeTypingManager::new() {
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
pub(self) fn init_swipe_type_manager(state: &mut KeyboardState, model_folder: std::path::PathBuf) {
|
||||
match SwipeTypingManager::new(model_folder) {
|
||||
Ok((engine, receiver)) => {
|
||||
state.swipe_typing_manager = Some(engine);
|
||||
state.swipe_candidate_receiver = Some(receiver);
|
||||
|
|
@ -143,6 +169,7 @@ pub(self) fn init_swipe_type_manager(state: &mut KeyboardState) {
|
|||
}
|
||||
};
|
||||
}
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
pub(self) fn hide_swipe_type_manager(panel: &mut GuiPanel<KeyboardState>) {
|
||||
let predictions_root = panel.parser_state
|
||||
.get_widget_id("swipe_predictions_root")
|
||||
|
|
@ -188,7 +215,8 @@ impl KeyboardBackend {
|
|||
let mut state = self.default_state.take();
|
||||
|
||||
if app.session.config.keyboard_swipe_to_type_enabled {
|
||||
init_swipe_type_manager(&mut state);
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
init_swipe_type_manager(&mut state, data_dir::get_path("swipe_type"));
|
||||
log::info!("swipe engine created");
|
||||
}
|
||||
|
||||
|
|
@ -196,6 +224,7 @@ impl KeyboardBackend {
|
|||
create_keyboard_panel(app, keymap, state, &self.wlx_layout)?;
|
||||
|
||||
if !app.session.config.keyboard_swipe_to_type_enabled {
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
hide_swipe_type_manager(&mut panel);
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +272,8 @@ impl KeyboardBackend {
|
|||
.take();
|
||||
|
||||
if app.session.config.keyboard_swipe_to_type_enabled {
|
||||
init_swipe_type_manager(&mut state_from);
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
init_swipe_type_manager(&mut state_from, data_dir::get_path("swipe_type"));
|
||||
}
|
||||
|
||||
self.active_layout = new_key;
|
||||
|
|
@ -254,6 +284,7 @@ impl KeyboardBackend {
|
|||
.state = state_from;
|
||||
|
||||
if !app.session.config.keyboard_swipe_to_type_enabled {
|
||||
#[cfg(feature = "swipe-to-type")]
|
||||
hide_swipe_type_manager(self.layout_panels
|
||||
.get_mut(self.active_layout)
|
||||
.unwrap()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use crate::subsystem::hid::{KeyModifier, VirtualKey, CTRL};
|
|||
use anyhow::{bail};
|
||||
use glam::Vec2;
|
||||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::{sync_channel, Receiver, SyncSender, channel, Sender};
|
||||
use std::thread::{self, JoinHandle};
|
||||
use std::time::Instant;
|
||||
|
|
@ -87,14 +88,14 @@ impl SwipeTypingManager {
|
|||
app.hid_provider
|
||||
.set_modifiers_routed(app.wvr_server.as_mut(), original_keyboard_mods);
|
||||
}
|
||||
pub fn new() -> anyhow::Result<(SwipeTypingManager, Receiver<Option<Vec<String>>>)> {
|
||||
pub fn new(model_folder: PathBuf) -> anyhow::Result<(SwipeTypingManager, Receiver<Option<Vec<String>>>)> {
|
||||
let (candidate_sender, candidate_receiver) = sync_channel(1);
|
||||
let (task_sender, task_receiver) = channel::<PredictionTask>();
|
||||
|
||||
// Spawn persistent worker thread
|
||||
let worker_candidate_sender = candidate_sender.clone();
|
||||
let worker_thread = thread::spawn(move || {
|
||||
let mut swipe_engine = match SwipeOrchestrator::new() {
|
||||
let mut swipe_engine = match SwipeOrchestrator::new_with_paths(&model_folder) {
|
||||
Ok(engine) => engine,
|
||||
Err(e) => {
|
||||
log::error!("Failed to initialize SwipeOrchestrator: {}", e);
|
||||
|
|
|
|||
Loading…
Reference in New Issue