diff --git a/dash-frontend/assets/lang/en.csv b/dash-frontend/assets/lang/en.csv index 4f6f43cf..70d7a88a 100644 --- a/dash-frontend/assets/lang/en.csv +++ b/dash-frontend/assets/lang/en.csv @@ -274,7 +274,7 @@ DONATE.BUTTON_TOOLTIP,Donate via Open Collective,Tooltip on the donate button on DONATE.CURRENT_SUPPORTERS,Current Supporters,Section header on the donate tab listing supporters. DONATE.BROUGHT_TO_YOU_VARIANTS_OFTEN,Supported by {USER}|Special thanks to {USER}|Sponsored by {USER}|Backed by {USER}|Driven by community members like {USER}|Made possible by {USER}|Sustained by {USER}|Contributed by {USER}|Funded by {USER},This text will show up a random person from donations page - line below this string will display the supporter user. There are many variants of it. DONATE.BROUGHT_TO_YOU_VARIANTS_RARE,Coffee provided by {USER}|Fuelled by {USER}|Shoutout to {USER}!|Keeping us going: {USER}|Helping us grow: {USER}|Keeping the servers running: {USER}|With gratitude to {USER}|Powered by {USER}|Supported by friends like {USER},This text will show up a random person from donations page - line below this string will display the supporter user. There are many variants of it (rare versions). -DONATE.BROUGHT_TO_YOU_VARIANTS_VERY_RARE,Supported by legends like {USER}|Caffeine supplied by {USER}|A true legend: {USER}|Our hero of the day: {USER}|An absolute superstar: {USER}|Paying for the electricity bill: {USER}|The savior of our sanity: {USER}|Mental stability sponsored by: {USER}|Caffeine-to-code converter provided by {USER}|Keeping the production stable: {USER}|The one and only: {USER}|Passing dmabuf buffers: {USER},This text will show up a random person from donations page - line below this string will display the supporter user. There are many variants of it (rare versions). +DONATE.BROUGHT_TO_YOU_VARIANTS_VERY_RARE,Supported by legends like {USER}|Caffeine supplied by {USER}|A true legend: {USER}|Our hero of the day: {USER}|An absolute superstar: {USER}|Paying for the electricity bill: {USER}|The savior of our sanity: {USER}|Leading the way: {USER}|Caffeine-to-code converter provided by {USER}|Keeping the production stable: {USER}|The one and only: {USER}|Passing dmabuf buffers: {USER},This text will show up a random person from donations page - line below this string will display the supporter user. There are many variants of it (rare versions). DOWNLOAD,Download,Button in the Whisper model download dialog to confirm downloading a model. DOWNLOADER,Downloader,Window title for the file download popup. WELCOME.ALL_SET,You're all set!,Main heading on the final welcome/tutorial page. diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json index 892cff8b..c1008b36 100644 --- a/dash-frontend/assets/lang/en.json +++ b/dash-frontend/assets/lang/en.json @@ -274,7 +274,7 @@ "CURRENT_SUPPORTERS": "Current Supporters", "BROUGHT_TO_YOU_VARIANTS_OFTEN": "Supported by {USER}|Special thanks to {USER}|Sponsored by {USER}|Backed by {USER}|Driven by community members like {USER}|Made possible by {USER}|Sustained by {USER}|Contributed by {USER}|Funded by {USER}", "BROUGHT_TO_YOU_VARIANTS_RARE": "Coffee provided by {USER}|Fuelled by {USER}|Shoutout to {USER}!|Keeping us going: {USER}|Helping us grow: {USER}|Keeping the servers running: {USER}|With gratitude to {USER}|Powered by {USER}|Supported by friends like {USER}", - "BROUGHT_TO_YOU_VARIANTS_VERY_RARE": "Supported by legends like {USER}|Caffeine supplied by {USER}|A true legend: {USER}|Our hero of the day: {USER}|An absolute superstar: {USER}|Paying for the electricity bill: {USER}|The savior of our sanity: {USER}|Leading the way: {USER}|Caffeine-to-code converter provided by {USER}|Keeping the production stable: {USER}|The one and only: {USER}|Passing dmabuf buffers: {USER}" + "BROUGHT_TO_YOU_VARIANTS_VERY_RARE": "Supported by legends like {USER}|Caffeine supplied by {USER}|A true legend: {USER}|Our hero of the day: {USER}|An absolute superstar: {USER}|Paying for the electricity bill: {USER}|Leading the way: {USER}|Caffeine-to-code converter provided by {USER}|Keeping the production stable: {USER}|The one and only: {USER}|Passing dmabuf buffers: {USER}" }, "DOWNLOAD": "Download", "DOWNLOADER": "Downloader", diff --git a/wayvr/src/assets/lang/de.json b/wayvr/src/assets/lang/de.json index 35b970c6..fcff7f0a 100644 --- a/wayvr/src/assets/lang/de.json +++ b/wayvr/src/assets/lang/de.json @@ -166,5 +166,15 @@ "INITIAL_TEXT": "Mic-Taste gedrückt halten, um die Transkription zu starten...", "INIT_ERROR": "Fehler beim Starten der Whisper-Engine", "ENTER_KEY": "Enter-Taste" + }, + "NOTIFICATION": { + "NOT_RUNNING_XR_VR": "Stelle sicher, dass Monado, WiVRn oder SteamVR läuft.", + "NOT_RUNNING_VR": "Stelle sicher, dass Monado, WiVRn oder SteamVR läuft.", + "NOT_RUNNING_XR": "Stelle sicher, dass Monado oder WiVRn läuft.", + "INVALID_ARGS": "Prüfe deine Startargumente.", + "COUD_NOT_CONNECT_TO_VR_RUNTIME": "Verbindung zum VR-Runtime fehlgeschlagen.", + "SELECT_SCREEN_CAST_FOR": "Screen-Cast für Display {DISPLAY} auswählen", + "CANNOT_CAPTURE_KBD_MOUSE": "Tastatur/Maus-Erfassung konnte nicht initialisiert werden!\nPrüfe, ob dein Benutzer in der Gruppe 'input' ist.", + "WE_ARE_GRABBING": "WayVR steuert jetzt deine Tastatur und Maus!\nDrücke Super+Z, um die Steuerung freizugeben." } } \ No newline at end of file diff --git a/wayvr/src/assets/lang/en.csv b/wayvr/src/assets/lang/en.csv index 4c8e3e7e..2a7e9b23 100644 --- a/wayvr/src/assets/lang/en.csv +++ b/wayvr/src/assets/lang/en.csv @@ -144,3 +144,13 @@ WHISPER.DOWNLOAD_GUIDANCE,"Set up speech-to-text under settings, features!",Help WHISPER.INITIAL_TEXT,Press and hold the mic button to start transcribing...,Help message prompting the user to hold down the button with the microphone icon. WHISPER.INIT_ERROR,Error while starting Whisper engine,Error message. WHISPER.ENTER_KEY,Enter key,Button to send an Enter key on the emulated keyboard +NOTIFICATION.COUD_NOT_CONNECT_TO_VR_RUNTIME,"Could not connect to VR runtime.",A system notification which shows up on initialization failure. +NOTIFICATION.NOT_RUNNING_XR_VR,"Make sure that Monado, WiVRn or SteamVR is running.",A system notification which shows up on initialization failure. +NOTIFICATION.NOT_RUNNING_VR,"Make sure that Monado, WiVRn or SteamVR is running.",A system notification which shows up on initialization failure. +NOTIFICATION.NOT_RUNNING_XR,"Make sure that Monado or WiVRn is running.",A system notification which shows up on initialization failure. +NOTIFICATION.INVALID_ARGS,"Check your launch arguments.",A system notification which shows up on initialization failure. +NOTIFICATION.SELECT_SCREEN_CAST_FOR,"Select screen cast for display {DISPLAY}",A system notification which shows up on monitor selection request. DISPLAY is the monitor name. +NOTIFICATION.CANNOT_CAPTURE_KBD_MOUSE,"Could not initialize keyboard/mouse capture! +Check that your user is in the 'input' group.",A system notification which shows up in case if we can't control the computer via keyboard or mouse. Leave `input` key as-is - it's a linux group name. +NOTIFICATION.WE_ARE_GRABBING,"WayVR has your keyboard and mouse! +Press Super+Z to release.",A system notification which shows up in case if WayVR starts capturing physical keyboard and mouse events. The user consciously chose this option - it's just a message for him how to exit the mode later. Emphasis on user discretion diff --git a/wayvr/src/assets/lang/en.json b/wayvr/src/assets/lang/en.json index 82a29bd3..efabb1ae 100644 --- a/wayvr/src/assets/lang/en.json +++ b/wayvr/src/assets/lang/en.json @@ -166,5 +166,15 @@ "INITIAL_TEXT": "Press and hold the mic button to start transcribing...", "INIT_ERROR": "Error while starting Whisper engine", "ENTER_KEY": "Enter key" + }, + "NOTIFICATION": { + "COUD_NOT_CONNECT_TO_VR_RUNTIME": "Could not connect to VR runtime.", + "NOT_RUNNING_XR_VR": "Make sure that Monado, WiVRn or SteamVR is running.", + "NOT_RUNNING_VR": "Make sure that Monado, WiVRn or SteamVR is running.", + "NOT_RUNNING_XR": "Make sure that Monado or WiVRn is running.", + "INVALID_ARGS": "Check your launch arguments.", + "SELECT_SCREEN_CAST_FOR": "Select screen cast for display {DISPLAY}", + "CANNOT_CAPTURE_KBD_MOUSE": "Could not initialize keyboard/mouse capture!\nCheck that your user is in the 'input' group.", + "WE_ARE_GRABBING": "WayVR has your keyboard and mouse!\nPress Super+Z to release." } } \ No newline at end of file diff --git a/wayvr/src/assets/lang/es.json b/wayvr/src/assets/lang/es.json index e22161c4..a4c0835d 100644 --- a/wayvr/src/assets/lang/es.json +++ b/wayvr/src/assets/lang/es.json @@ -166,5 +166,15 @@ "INITIAL_TEXT": "Mantén pulsado el botón del micro para empezar a transcribir...", "INIT_ERROR": "Error al iniciar el motor Whisper", "ENTER_KEY": "Tecla Enter" + }, + "NOTIFICATION": { + "NOT_RUNNING_XR_VR": "Asegúrate de que Monado, WiVRn o SteamVR estén ejecutándose.", + "NOT_RUNNING_VR": "Asegúrate de que Monado, WiVRn o SteamVR estén ejecutándose.", + "NOT_RUNNING_XR": "Asegúrate de que Monado o WiVRn se estén ejecutando.", + "INVALID_ARGS": "Revisa tus argumentos de lanzamiento.", + "COUD_NOT_CONNECT_TO_VR_RUNTIME": "No se pudo conectar al entorno de ejecución de VR.", + "SELECT_SCREEN_CAST_FOR": "Seleccionar transmisión de pantalla para la pantalla {DISPLAY}", + "CANNOT_CAPTURE_KBD_MOUSE": "¡No se pudo inicializar la captura de teclado/ratón!\nComprueba que tu usuario esté en el grupo 'input'.", + "WE_ARE_GRABBING": "¡WayVR tiene el control de tu teclado y ratón!\nPulsa Super+Z para liberarlos." } } \ No newline at end of file diff --git a/wayvr/src/assets/lang/it.json b/wayvr/src/assets/lang/it.json index b4abf3f9..cdb7dfe2 100644 --- a/wayvr/src/assets/lang/it.json +++ b/wayvr/src/assets/lang/it.json @@ -166,5 +166,15 @@ "INITIAL_TEXT": "Tieni premuto il tasto del microfono per trascrivere...", "INIT_ERROR": "Errore durante l'avvio del motore Whisper", "ENTER_KEY": "Tasto Invio" + }, + "NOTIFICATION": { + "NOT_RUNNING_XR_VR": "Assicurati che Monado, WiVRn o SteamVR siano attivi.", + "NOT_RUNNING_VR": "Assicurati che Monado, WiVRn o SteamVR siano attivi.", + "NOT_RUNNING_XR": "Assicurati che Monado o WiVRn siano attivi.", + "INVALID_ARGS": "Controlla gli argomenti di avvio.", + "COUD_NOT_CONNECT_TO_VR_RUNTIME": "Impossibile connettersi al VR runtime.", + "SELECT_SCREEN_CAST_FOR": "Seleziona la trasmissione schermo per il display {DISPLAY}", + "CANNOT_CAPTURE_KBD_MOUSE": "Impossibile inizializzare la cattura di tastiera/mouse!\nControlla che il tuo utente sia nel gruppo 'input'.", + "WE_ARE_GRABBING": "WayVR sta controllando tastiera e mouse!\nPremi Super+Z per rilasciare il controllo." } } \ No newline at end of file diff --git a/wayvr/src/assets/lang/ja.json b/wayvr/src/assets/lang/ja.json index 22215067..031702dd 100644 --- a/wayvr/src/assets/lang/ja.json +++ b/wayvr/src/assets/lang/ja.json @@ -166,5 +166,15 @@ "INITIAL_TEXT": "マイクボタンを長押しして文字起こしを開始...", "INIT_ERROR": "Whisperエンジンの起動中にエラーが発生しました", "ENTER_KEY": "Enterキー" + }, + "NOTIFICATION": { + "NOT_RUNNING_XR_VR": "Monado、WiVRn、またはSteamVRが実行されていることを確認してください。", + "NOT_RUNNING_VR": "Monado、WiVRn、またはSteamVRが実行されているか確認してください。", + "NOT_RUNNING_XR": "Monado または WiVRn が実行されているか確認してください。", + "INVALID_ARGS": "起動引数を確認してください。", + "COUD_NOT_CONNECT_TO_VR_RUNTIME": "VRランタイムに接続できませんでした。", + "SELECT_SCREEN_CAST_FOR": "ディスプレイ {DISPLAY} のスクリーンキャストを選択してください", + "CANNOT_CAPTURE_KBD_MOUSE": "キーボード/マウスのキャプチャを初期化できませんでした!\nユーザーが 'input' グループに所属しているか確認してください。", + "WE_ARE_GRABBING": "WayVR がキーボードとマウスを制御しています。\n解除するには、Super+Zを押してください。" } -} \ No newline at end of file +} diff --git a/wayvr/src/assets/lang/pl.json b/wayvr/src/assets/lang/pl.json index 63ca7f54..0d7ad0ca 100644 --- a/wayvr/src/assets/lang/pl.json +++ b/wayvr/src/assets/lang/pl.json @@ -166,5 +166,15 @@ "INITIAL_TEXT": "Przytrzymaj przycisk mikrofonu, aby rozpocząć transkrypcję...", "INIT_ERROR": "Błąd podczas uruchamiania silnika Whisper", "ENTER_KEY": "Klawisz Enter" + }, + "NOTIFICATION": { + "NOT_RUNNING_XR_VR": "Upewnij się, że Monado, WiVRn lub SteamVR jest uruchomione.", + "NOT_RUNNING_VR": "Upewnij się, że Monado, WiVRn lub SteamVR są uruchomione.", + "NOT_RUNNING_XR": "Upewnij się, że Monado lub WiVRn są uruchomione.", + "INVALID_ARGS": "Sprawdź argumenty uruchamiania.", + "COUD_NOT_CONNECT_TO_VR_RUNTIME": "Nie można połączyć się z runtime VR.", + "SELECT_SCREEN_CAST_FOR": "Wybierz przesyłanie ekranu dla wyświetlacza {DISPLAY}", + "CANNOT_CAPTURE_KBD_MOUSE": "Nie można zainicjować przechwytywania klawiatury/myszy!\nSprawdź, czy Twój użytkownik należy do grupy 'input'.", + "WE_ARE_GRABBING": "WayVR przejął kontrolę nad klawiaturą i myszą!\nNaciśnij Super+Z, aby zwolnić." } } \ No newline at end of file diff --git a/wayvr/src/assets/lang/zh_CN.json b/wayvr/src/assets/lang/zh_CN.json index 7f60cb18..7a66d604 100644 --- a/wayvr/src/assets/lang/zh_CN.json +++ b/wayvr/src/assets/lang/zh_CN.json @@ -166,5 +166,15 @@ "INITIAL_TEXT": "按住麦克风按钮开始转写...", "INIT_ERROR": "启动 Whisper 引擎时出错", "ENTER_KEY": "回车键" + }, + "NOTIFICATION": { + "NOT_RUNNING_XR_VR": "请确保 Monado、WiVRn 或 SteamVR 正在运行。", + "NOT_RUNNING_VR": "请确保 Monado、WiVRn 或 SteamVR 正在运行。", + "NOT_RUNNING_XR": "请确保 Monado 或 WiVRn 正在运行。", + "INVALID_ARGS": "检查你的启动参数。", + "COUD_NOT_CONNECT_TO_VR_RUNTIME": "无法连接到 VR 运行时。", + "SELECT_SCREEN_CAST_FOR": "为显示器 {DISPLAY} 选择屏幕投射", + "CANNOT_CAPTURE_KBD_MOUSE": "无法初始化键盘/鼠标捕获!\n请检查您的用户是否在 'input' 组中。", + "WE_ARE_GRABBING": "WayVR 正在接管你的键盘和鼠标!\n按 Super+Z 释放。" } } \ No newline at end of file diff --git a/wayvr/src/backend/mod.rs b/wayvr/src/backend/mod.rs index 4e34f525..d63fbdc8 100644 --- a/wayvr/src/backend/mod.rs +++ b/wayvr/src/backend/mod.rs @@ -14,6 +14,8 @@ pub mod set; pub mod task; use thiserror::Error; +use wgui::globals::WguiGlobals; +use wlx_common::config::GeneralConfig; #[derive(Error, Debug)] pub enum BackendError { @@ -31,3 +33,8 @@ pub enum BackendError { #[error("Fatal: {0:?}")] Fatal(#[from] anyhow::Error), } + +pub struct RunParams { + pub wgui_globals: WguiGlobals, + pub config: GeneralConfig, +} diff --git a/wayvr/src/backend/openvr/mod.rs b/wayvr/src/backend/openvr/mod.rs index 5c729869..b4b64f65 100644 --- a/wayvr/src/backend/openvr/mod.rs +++ b/wayvr/src/backend/openvr/mod.rs @@ -18,7 +18,7 @@ use wlx_common::{dash_interface::InterfaceFeats, overlays::ToastTopic}; use crate::{ Args, FRAME_COUNTER, RUNNING, XrBackend, backend::{ - BackendError, + BackendError, RunParams, input::interact, openvr::{ helpers::adjust_gain, @@ -58,7 +58,7 @@ pub fn openvr_uninstall() { } #[allow(clippy::too_many_lines, clippy::cognitive_complexity)] -pub fn openvr_run(args: &Args) -> Result<(), BackendError> { +pub fn openvr_run(args: &Args, params: RunParams) -> Result<(), BackendError> { let app_type = EVRApplicationType::VRApplication_Overlay; let Ok(context) = ovr_overlay::Context::init(app_type) else { if !args.wait { @@ -92,7 +92,7 @@ pub fn openvr_run(args: &Args) -> Result<(), BackendError> { let mut app = { let (gfx, gfx_extras) = init_openvr_graphics(instance_extensions, device_extensions_fn)?; - AppState::from_graphics(gfx, gfx_extras, feats)? + AppState::from_graphics(gfx, gfx_extras, feats, params)? }; app.session.no_autostart = args.no_autostart; @@ -196,7 +196,7 @@ pub fn openvr_run(args: &Args) -> Result<(), BackendError> { log::info!("IPD: {:.1} mm -> {:.1} mm", app.input_state.ipd, ipd); Toast::new( ToastTopic::IpdChange, - Some(Translation::from_translation_key("IPD")), + Some(Translation::from_raw_text("IPD")), Translation::from_raw_text_string(format!("{ipd:.1} mm")), ) .submit(&mut app); diff --git a/wayvr/src/backend/openxr/mod.rs b/wayvr/src/backend/openxr/mod.rs index adbe5bdd..beec847a 100644 --- a/wayvr/src/backend/openxr/mod.rs +++ b/wayvr/src/backend/openxr/mod.rs @@ -19,7 +19,7 @@ use wlx_common::{ use crate::{ Args, FRAME_COUNTER, RUNNING, XrBackend, backend::{ - BackendError, + BackendError, RunParams, input::interact, openxr::{helpers::try_apply_chroma_key, lines::LinePool, overlay::OpenXrOverlayData}, task::{OpenXrTask, OverlayTask, TaskType}, @@ -56,7 +56,7 @@ struct XrState { } #[allow(clippy::too_many_lines, clippy::cognitive_complexity)] -pub fn openxr_run(args: &Args) -> Result<(), BackendError> { +pub fn openxr_run(args: &Args, params: RunParams) -> Result<(), BackendError> { let (xr_instance, system) = match helpers::init_xr() { Ok((xr_instance, system)) => (xr_instance, system), Err(e) => { @@ -77,7 +77,7 @@ pub fn openxr_run(args: &Args) -> Result<(), BackendError> { let mut app = { let (gfx, gfx_extras) = init_openxr_graphics(xr_instance.clone(), system)?; - AppState::from_graphics(gfx, gfx_extras, feats)? + AppState::from_graphics(gfx, gfx_extras, feats, params)? }; app.session.no_autostart = args.no_autostart; @@ -325,7 +325,7 @@ pub fn openxr_run(args: &Args) -> Result<(), BackendError> { app.input_state.ipd = ipd; Toast::new( ToastTopic::IpdChange, - Some(Translation::from_translation_key("IPD")), + Some(Translation::from_raw_text("IPD")), Translation::from_raw_text_string(format!("{ipd:.1} mm")), ) .submit(&mut app); diff --git a/wayvr/src/backend/wayvr/input_capture.rs b/wayvr/src/backend/wayvr/input_capture.rs index 0ef3df69..3e92505f 100644 --- a/wayvr/src/backend/wayvr/input_capture.rs +++ b/wayvr/src/backend/wayvr/input_capture.rs @@ -486,10 +486,12 @@ fn worker_main( } } Err(error) => { - //TODO: translate + //TODO: we can't easily translate it at this stage, i18n lies on a separate thread let _ = DbusConnector::notify_send( - "Could not capture input", - &format!("Linux user must be in input group!\n Error: \n{error}"), + "WayVR", + &format!( + "Could not capture input! Linux user must be in 'input' group!\n Error: \n{error}" + ), 1, 5000, 0, diff --git a/wayvr/src/backend/wayvr/mod.rs b/wayvr/src/backend/wayvr/mod.rs index 1b4a2060..0af1c39d 100644 --- a/wayvr/src/backend/wayvr/mod.rs +++ b/wayvr/src/backend/wayvr/mod.rs @@ -54,7 +54,7 @@ use std::{ use vulkano::image::view::ImageView; use wayland_protocols::xdg::shell::server::xdg_toplevel; use wayvr_ipc::packet_client::PositionMode; -use wgui::{gfx::WGfx, log::LogErr}; +use wgui::{gfx::WGfx, globals::WguiGlobals, log::LogErr}; use wlx_capture::frame::Transform; use wlx_common::{ audio::{AudioSystem, SamplePlayer}, @@ -654,6 +654,7 @@ impl WvrServerState { &mut app.hid_provider, &mut app.audio_sample_player, &mut app.audio_system, + &app.wgui_globals, &app.session.config, ); @@ -767,6 +768,7 @@ impl WvrServerState { self.manager.seat_pointer.is_grabbed() } + #[allow(clippy::too_many_arguments)] pub fn process_input_capture( &mut self, input_state: &mut InputState, @@ -774,6 +776,7 @@ impl WvrServerState { hid_wrapper: &mut HidWrapper, audio_sample_player: &mut SamplePlayer, audio_system: &mut AudioSystem, + globals: &WguiGlobals, config: &GeneralConfig, ) { let input_capture = match (self.input_capture.as_mut(), config.wvr_input_capture) { @@ -790,14 +793,10 @@ impl WvrServerState { if let Some(cap) = self.input_capture.as_mut() { cap } else { - let _ = DbusConnector::notify_send( - "Could not initialize keyboard/mouse capture!", - "Check that your user is in the input group.", - 1, - 5000, - 0, - true, - ); + let text = &globals + .i18n() + .translate("NOTIFICATION.CANNOT_CAPTURE_KBD_MOUSE"); + let _ = DbusConnector::notify_send("WayVR", text, 1, 5000, 0, true); return; } } @@ -928,15 +927,8 @@ impl WvrServerState { audio_sample_player.play_sample(audio_system, "input_grab"); if !self.grab_toast_sent { self.grab_toast_sent = true; - //TODO: translate - let _ = DbusConnector::notify_send( - "WayVR has your keyboard and mouse!", - "Super+Z to release", - 1, - 5000, - 0, - true, - ); + let text = &globals.i18n().translate("NOTIFICATION.WE_ARE_GRABBING"); + let _ = DbusConnector::notify_send("WayVR", &text, 1, 5000, 0, true); } } input_capture::CapturedEvent::Ungrabbed => { diff --git a/wayvr/src/main.rs b/wayvr/src/main.rs index d85a0ddc..e9e07763 100644 --- a/wayvr/src/main.rs +++ b/wayvr/src/main.rs @@ -44,9 +44,16 @@ use signal_hook::iterator::Signals; use sysinfo::Pid; use tracing::level_filters::LevelFilter; use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt}; +use wgui::{font_config::WguiFontConfig, globals::WguiGlobals}; -use crate::subsystem::dbus::DbusConnector; -use wlx_common::XrBackend; +use crate::{config::load_general_config, subsystem::dbus::DbusConnector}; +use wlx_common::{ + XrBackend, + config::GeneralConfig, + config_io::{self, get_config_file_path}, + locale::WayVRLangProvider, + palette::load_palette, +}; pub static FRAME_COUNTER: AtomicUsize = AtomicUsize::new(0); pub static RUNNING: AtomicBool = AtomicBool::new(true); @@ -104,6 +111,33 @@ struct Args { log_to: Option, } +fn load_config() -> GeneralConfig { + let config_root_path = config_io::ConfigRoot::Generic.ensure_dir(); + log::info!("Config root path: {}", config_root_path.display()); + load_general_config() +} + +fn init_run_params() -> backend::RunParams { + let assets = Box::new(gui::asset::GuiAsset {}); + let config = load_config(); + let lang_provider = WayVRLangProvider::from_config(&config); + let theme_path = config.theme_path.clone(); + + let wgui_globals = WguiGlobals::new( + assets, + &lang_provider, + &WguiFontConfig::default(), + get_config_file_path(&theme_path), + load_palette(&config.color_palette), + ) + .expect("Failed to init Globals, can't proceed"); + + backend::RunParams { + wgui_globals, + config, + } +} + #[allow(clippy::unnecessary_wraps)] fn main() -> Result<(), Box> { let mut args = if std::env::args().skip(1).any(|a| !a.is_empty()) { @@ -141,7 +175,6 @@ fn main() -> Result<(), Box> { setup_signal_hooks()?; let mut used_backend = None; - auto_run(args, &mut used_backend); if RESTART.load(Ordering::Relaxed) { @@ -171,7 +204,7 @@ fn auto_run(args: Args, used_backend: &mut Option) { if !args_get_openvr(&args) { use crate::backend::{BackendError, openxr::openxr_run}; tried_xr = true; - match openxr_run(&args) { + match openxr_run(&args, init_run_params()) { Ok(()) => { used_backend.replace(XrBackend::OpenXR); return; @@ -189,7 +222,7 @@ fn auto_run(args: Args, used_backend: &mut Option) { if !args_get_openxr(&args) { use crate::backend::{BackendError, openvr::openvr_run}; tried_vr = true; - match openvr_run(&args) { + match openvr_run(&args, init_run_params()) { Ok(()) => { used_backend.replace(XrBackend::OpenVR); return; @@ -219,14 +252,23 @@ fn auto_run(args: Args, used_backend: &mut Option) { log::error!("No more backends to try"); - let instructions = match (tried_xr, tried_vr) { - (true, true) => "Make sure that Monado, WiVRn or SteamVR is running.", - (false, true) => "Make sure that SteamVR is running.", - (true, false) => "Make sure that Monado or WiVRn is running.", - _ => "Check your launch arguments.", + let instructions_key = match (tried_xr, tried_vr) { + (true, true) => "NOTIFICATION.NOT_RUNNING_XR_VR", + (false, true) => "NOTIFICATION.NOT_RUNNING_VR", + (true, false) => "NOTIFICATION.NOT_RUNNING_XR", + _ => "NOTIFICATION.INVALID_ARGS", }; - let instructions = format!("Could not connect to runtime.\n{instructions}"); + let run_params = init_run_params(); + + let instructions_str = run_params.wgui_globals.i18n().translate(instructions_key); + + let instructions_title = run_params + .wgui_globals + .i18n() + .translate("NOTIFICATION.COUD_NOT_CONNECT_TO_VR_RUNTIME"); + + let instructions = format!("{instructions_title}\n{instructions_str}"); let _ = DbusConnector::notify_send("WayVR", &instructions, 1, 30000, 0, false); diff --git a/wayvr/src/overlays/screen/pw.rs b/wayvr/src/overlays/screen/pw.rs index 3d612fdb..dffba280 100644 --- a/wayvr/src/overlays/screen/pw.rs +++ b/wayvr/src/overlays/screen/pw.rs @@ -320,15 +320,15 @@ fn check(mut par: CheckParams, finalize_fn: ScreenCastFinalizeFn) { | ScreenCastResult::WaitingForUser => { let user_wait_add = if matches!(new_result, ScreenCastResult::WaitingForUser) { if par.user_wait == 2 { - par.notify_id = DbusConnector::notify_send( - "Select screen cast for:", - format!("{} {}", par.name, par.description).as_str(), - 1, - 30000, - 0, - true, - ) - .ok(); + let text = par.app.wgui_globals.i18n().translate_and_replace( + "NOTIFICATION.SELECT_SCREEN_CAST_FOR", + ( + "{DISPLAY}", + format!("{} {}", par.name, par.description).as_str(), + ), + ); + par.notify_id = + DbusConnector::notify_send("WayVR", &text, 1, 30000, 0, true).ok(); } 1 } else { diff --git a/wayvr/src/state.rs b/wayvr/src/state.rs index fa4f08af..fb2363fc 100644 --- a/wayvr/src/state.rs +++ b/wayvr/src/state.rs @@ -1,3 +1,4 @@ +use crate::backend::RunParams; use glam::Affine3A; use idmap::IdMap; use serde::{Deserialize, Serialize}; @@ -8,18 +9,15 @@ use std::sync::Arc; use wgui::log::LogErr; use wgui::theme::WguiTheme; use wgui::{ - font_config::WguiFontConfig, gfx::WGfx, globals::WguiGlobals, - renderer_vk::context::SharedContext as WSharedContext, + gfx::WGfx, globals::WguiGlobals, renderer_vk::context::SharedContext as WSharedContext, }; #[cfg(feature = "pipewire")] use wlx_capture::pipewire::ScreenCastManager; use wlx_common::config::PwTokenMap; -use wlx_common::locale::WayVRLangProvider; -use wlx_common::palette::load_palette; use wlx_common::{ audio, config::GeneralConfig, - config_io::{self, get_config_file_path}, + config_io::{self}, desktop_finder::DesktopFinder, overlays::{ToastDisplayMethod, ToastTopic}, }; @@ -37,9 +35,7 @@ use crate::subsystem::osc::OscSender; use crate::subsystem::whisper_stt::WhisperStt; use crate::{ backend::{input::InputState, task::TaskContainer}, - config::load_general_config, graphics::WGfxExtras, - gui, ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal}, subsystem::{dbus::DbusConnector, input::HidWrapper}, }; @@ -101,11 +97,12 @@ impl AppState { gfx: Arc, gfx_extras: WGfxExtras, mut feats: InterfaceFeats, + mut params: RunParams, ) -> anyhow::Result { // insert shared resources let mut tasks = TaskContainer::new(); - let session = AppSession::load(); + let session = AppSession::load(params.config); let wvr_signals = SyncEventQueue::new(); let wvr_server = { @@ -124,7 +121,6 @@ impl AppState { let osc_sender = crate::subsystem::osc::OscSender::new(session.config.osc_out_port).ok(); let wgui_shared = WSharedContext::new(gfx.clone())?; - let theme_path = session.config.theme_path.clone(); let mut audio_sample_player = audio::SamplePlayer::new(); audio_sample_player.register_sample( @@ -167,8 +163,7 @@ impl AppState { ))?, )?; - let mut assets = Box::new(gui::asset::GuiAsset {}); - audio_sample_player.register_wgui_samples(assets.as_mut())?; + audio_sample_player.register_wgui_samples(params.wgui_globals.assets_builtin().as_mut())?; let mut theme = WguiTheme { animation_mult: 1. / session.config.ui_animation_speed, @@ -183,8 +178,6 @@ impl AppState { let mut desktop_finder = DesktopFinder::new(); desktop_finder.refresh(); - let lang_provider = WayVRLangProvider::from_config(&session.config); - #[cfg(feature = "pipewire")] let screencast_manager = ScreenCastManager::new() .log_err( @@ -212,14 +205,8 @@ impl AppState { screens: smallvec![], anchor: Affine3A::IDENTITY, anchor_grabbed: false, - wgui_globals: WguiGlobals::new( - assets, - &lang_provider, - &WguiFontConfig::default(), - get_config_file_path(&theme_path), - load_palette(&session.config.color_palette), - )?, wgui_theme: Rc::new(theme), + wgui_globals: params.wgui_globals, executor, dbus, feats, @@ -310,11 +297,7 @@ pub struct AppSession { } impl AppSession { - pub fn load() -> Self { - let config_root_path = config_io::ConfigRoot::Generic.ensure_dir(); - log::info!("Config root path: {}", config_root_path.display()); - let config = load_general_config(); - + pub fn load(config: GeneralConfig) -> Self { let mut toast_topics = IdMap::new(); toast_topics.insert(ToastTopic::System, ToastDisplayMethod::Center); toast_topics.insert(ToastTopic::Error, ToastDisplayMethod::Center); diff --git a/wayvr/src/test.rs b/wayvr/src/test.rs index 9e7b6f7a..f7b11692 100644 --- a/wayvr/src/test.rs +++ b/wayvr/src/test.rs @@ -20,7 +20,7 @@ mod tests { let text = std::str::from_utf8(data).expect("en.csv is not valid UTF-8"); let mut keys = Vec::new(); let mut chars = text.chars().peekable(); - while let Some(_) = chars.peek() { + while chars.peek().is_some() { let key = read_csv_field(&mut chars); // skip comma separator if chars.peek() == Some(&',') { diff --git a/wgui/src/color.rs b/wgui/src/color.rs index b5f90513..cc89cbfa 100644 --- a/wgui/src/color.rs +++ b/wgui/src/color.rs @@ -3,7 +3,7 @@ use strum::{EnumCount, EnumString}; // Primary: button color // OnPrimary: text color placed on the Primary-colored button -#[derive(Debug, Copy, Clone, PartialEq, EnumCount, EnumString)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, EnumCount, EnumString)] #[repr(usize)] #[strum(serialize_all = "snake_case")] pub enum WguiColorName {