From ccf72b16c5b963f217265efc5863d3d4d0497495 Mon Sep 17 00:00:00 2001 From: Aleksander Date: Thu, 25 Dec 2025 14:57:10 +0100 Subject: [PATCH] move `add_display::View` -> `add_window::View` & `display_options::View` -> `window_options::VIew`, remove displays logic and replace it with window ones [skip ci] --- Cargo.lock | 4 +- Cargo.toml | 1 - dash-frontend/Cargo.toml | 2 +- dash-frontend/assets/gui/tab/processes.xml | 4 +- dash-frontend/assets/gui/view/add_display.xml | 34 --- .../assets/gui/view/app_launcher.xml | 7 +- .../{display_list.xml => window_list.xml} | 1 - ...display_options.xml => window_options.xml} | 5 +- dash-frontend/assets/lang/de.json | 10 +- dash-frontend/assets/lang/en.json | 14 +- dash-frontend/assets/lang/es.json | 10 +- dash-frontend/assets/lang/ja.json | 136 +++++----- dash-frontend/assets/lang/pl.json | 10 +- dash-frontend/src/frontend.rs | 1 + dash-frontend/src/tab/processes.rs | 10 +- dash-frontend/src/util/popup_manager.rs | 4 + dash-frontend/src/util/various.rs | 19 -- dash-frontend/src/views/add_display.rs | 247 ------------------ dash-frontend/src/views/app_launcher.rs | 58 +--- dash-frontend/src/views/mod.rs | 5 +- dash-frontend/src/views/process_list.rs | 80 +----- .../views/{display_list.rs => window_list.rs} | 135 +++------- .../{display_options.rs => window_options.rs} | 68 +++-- wlx-common/Cargo.toml | 2 +- wlx-common/src/dash_interface.rs | 21 +- wlx-common/src/dash_interface_emulated.rs | 173 +++++------- wlx-overlay-s/Cargo.toml | 2 +- 27 files changed, 293 insertions(+), 770 deletions(-) delete mode 100644 dash-frontend/assets/gui/view/add_display.xml rename dash-frontend/assets/gui/view/{display_list.xml => window_list.xml} (69%) rename dash-frontend/assets/gui/view/{display_options.xml => window_options.xml} (61%) delete mode 100644 dash-frontend/src/views/add_display.rs rename dash-frontend/src/views/{display_list.rs => window_list.rs} (59%) rename dash-frontend/src/views/{display_options.rs => window_options.rs} (53%) diff --git a/Cargo.lock b/Cargo.lock index f9b2ae9..51d64ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1479,7 +1479,7 @@ dependencies = [ "rust-embed", "serde", "serde_json", - "wayvr_ipc", + "wayvr-ipc", "wgui", "wlx-common", ] @@ -6990,7 +6990,7 @@ dependencies = [ "idmap", "idmap-derive", "serde", - "wayvr_ipc", + "wayvr-ipc", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e718939..e144805 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,4 +39,3 @@ vulkano = { version = "0.35.2", default-features = false, features = [ ] } vulkano-shaders = "0.35.0" wayland-client = { version = "0.31.11" } -wayvr_ipc = { git = "https://github.com/olekolek1000/wayvr-ipc.git", rev = "6d253ef9e36db0f181566030a4990454ecb60395", default-features = false } diff --git a/dash-frontend/Cargo.toml b/dash-frontend/Cargo.toml index 463d61c..9bed73f 100644 --- a/dash-frontend/Cargo.toml +++ b/dash-frontend/Cargo.toml @@ -15,4 +15,4 @@ gtk = "0.18.2" serde.workspace = true serde_json.workspace = true wlx-common = { path = "../wlx-common" } -wayvr_ipc = { workspace = true } +wayvr-ipc = { path = "../wayvr-ipc", default-features = false } diff --git a/dash-frontend/assets/gui/tab/processes.xml b/dash-frontend/assets/gui/tab/processes.xml index 147ad71..f9449d9 100644 --- a/dash-frontend/assets/gui/tab/processes.xml +++ b/dash-frontend/assets/gui/tab/processes.xml @@ -2,8 +2,8 @@ - -
+ +
diff --git a/dash-frontend/assets/gui/view/add_display.xml b/dash-frontend/assets/gui/view/add_display.xml deleted file mode 100644 index 9575946..0000000 --- a/dash-frontend/assets/gui/view/add_display.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
- - - -
-
-
\ No newline at end of file diff --git a/dash-frontend/assets/gui/view/app_launcher.xml b/dash-frontend/assets/gui/view/app_launcher.xml index 35583da..5f136b2 100644 --- a/dash-frontend/assets/gui/view/app_launcher.xml +++ b/dash-frontend/assets/gui/view/app_launcher.xml @@ -26,13 +26,10 @@ - - -
diff --git a/dash-frontend/assets/gui/view/display_list.xml b/dash-frontend/assets/gui/view/window_list.xml similarity index 69% rename from dash-frontend/assets/gui/view/display_list.xml rename to dash-frontend/assets/gui/view/window_list.xml index 200b77a..3794906 100644 --- a/dash-frontend/assets/gui/view/display_list.xml +++ b/dash-frontend/assets/gui/view/window_list.xml @@ -4,7 +4,6 @@
-
diff --git a/dash-frontend/assets/lang/de.json b/dash-frontend/assets/lang/de.json index 6a42bc3..dad7ee6 100644 --- a/dash-frontend/assets/lang/de.json +++ b/dash-frontend/assets/lang/de.json @@ -46,25 +46,23 @@ "ACTIONS": { "RECENTER_PLAYSPACE": "Playspace neu zentrieren" }, - "LIST_OF_DISPLAYS": "Anzeigeliste", "LIST_OF_PROCESSES": "Prozessliste", - "NO_DISPLAYS_FOUND": "Keine Displays gefunden", - "ADD_DISPLAY": "Bildschirm hinzufügen", "POPUP_ADD_DISPLAY": { "RESOLUTION": "Auflösung" }, "WIDTH": "Breite", "HEIGHT": "Höhe", - "DISPLAY_PORTRAIT_MODE": "Porträtmodus", "HIDE": "Verbergen", "REMOVE": "Entfernen", "SHOW": "Anzeigen", - "DISPLAY_OPTIONS": "Anzeigeeinstellungen", "PROCESS_LIST": { "NO_PROCESSES_FOUND": "Keine Prozesse gefunden", "LOCATED_ON": "auf", "TERMINATE_PROCESS_NAMED_X": "Prozess \"{PROCESS_NAME}\" beenden" }, "FAILED_TO_LAUNCH_APPLICATION": "Fehler beim Starten der Anwendung:", - "APPLICATION_LAUNCHED_ON": "Anwendung wurde auf {DISPLAY_NAME} gestartet." + "NO_WINDOWS_FOUND": "Keine Fenster gefunden", + "WINDOW_OPTIONS": "Fensteroptionen", + "APPLICATION_STARTED": "Anwendung gestartet", + "LIST_OF_WINDOWS": "Fensterliste" } \ No newline at end of file diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json index e678f77..f5e84f1 100644 --- a/dash-frontend/assets/lang/en.json +++ b/dash-frontend/assets/lang/en.json @@ -2,7 +2,6 @@ "ACTIONS": { "RECENTER_PLAYSPACE": "Re-center playspace" }, - "ADD_DISPLAY": "Add display", "APP_SETTINGS": { "BRIGHTNESS": "Brightness", "HEADSET_SETTINGS": "Headset settings", @@ -22,8 +21,8 @@ }, "WLX_OVERLAY_S_SETTINGS": "WlxOverlay-S settings" }, - "APPLICATION_LAUNCHED_ON": "Application launched on {DISPLAY_NAME}.", "APPLICATION_LAUNCHER": "Application launcher", + "APPLICATION_STARTED": "Application started", "APPLICATIONS": "Applications", "AUDIO": { "AUTO_SWITCH_TO_VR_AUDIO": "Auto-switch to VR audio", @@ -40,8 +39,7 @@ "SPEAKERS_SET_SUCCESSFULLY": "Speakers set successfully", "VOLUME": "Volume" }, - "DISPLAY_OPTIONS": "Display options", - "DISPLAY_PORTRAIT_MODE": "Portrait mode", + "CLOSE_WINDOW": "Close window", "FAILED_TO_LAUNCH_APPLICATION": "Failed to launcha application:", "GAMES": "Games", "GENERAL_SETTINGS": "General settings", @@ -50,10 +48,10 @@ "HELLO_USER": "Hello, {USER}!", "HIDE": "Hide", "HOME_SCREEN": "Home", - "LIST_OF_DISPLAYS": "Display list", "LIST_OF_PROCESSES": "Process list", + "LIST_OF_WINDOWS": "Window list", "MONADO_RUNTIME": "„Monado” runtime", - "NO_DISPLAYS_FOUND": "No displays found", + "NO_WINDOWS_FOUND": "No windows found", "POPUP_ADD_DISPLAY": { "RESOLUTION": "Resolution" }, @@ -66,5 +64,7 @@ "REMOVE": "Remove", "SETTINGS": "Settings", "SHOW": "Show", - "WIDTH": "Width" + "TERMINATE_PROCESS": "Terminate process", + "WIDTH": "Width", + "WINDOW_OPTIONS": "Window options" } diff --git a/dash-frontend/assets/lang/es.json b/dash-frontend/assets/lang/es.json index a625689..194f80f 100644 --- a/dash-frontend/assets/lang/es.json +++ b/dash-frontend/assets/lang/es.json @@ -46,25 +46,23 @@ "ACTIONS": { "RECENTER_PLAYSPACE": "Re-centrar espacio de juego" }, - "LIST_OF_DISPLAYS": "Lista de pantallas", "LIST_OF_PROCESSES": "Lista de procesos", - "NO_DISPLAYS_FOUND": "No se encontraron pantallas", - "ADD_DISPLAY": "Agregar pantalla", "POPUP_ADD_DISPLAY": { "RESOLUTION": "Resolución" }, "WIDTH": "Ancho", "HEIGHT": "Altura", - "DISPLAY_PORTRAIT_MODE": "Modo retrato", "HIDE": "Ocultar", "REMOVE": "Eliminar", "SHOW": "Mostrar", - "DISPLAY_OPTIONS": "Opciones de pantalla", "PROCESS_LIST": { "NO_PROCESSES_FOUND": "No se encontraron procesos", "LOCATED_ON": "en", "TERMINATE_PROCESS_NAMED_X": "Terminar proceso \"{PROCESS_NAME}\"" }, "FAILED_TO_LAUNCH_APPLICATION": "No se pudo iniciar la aplicación:", - "APPLICATION_LAUNCHED_ON": "Aplicación iniciada en {DISPLAY_NAME}." + "NO_WINDOWS_FOUND": "No se encontraron ventanas", + "WINDOW_OPTIONS": "Opciones de ventana", + "APPLICATION_STARTED": "Aplicación iniciada", + "LIST_OF_WINDOWS": "Lista de ventanas" } \ No newline at end of file diff --git a/dash-frontend/assets/lang/ja.json b/dash-frontend/assets/lang/ja.json index e357ec4..808dcd7 100644 --- a/dash-frontend/assets/lang/ja.json +++ b/dash-frontend/assets/lang/ja.json @@ -1,70 +1,68 @@ { - "HOME_SCREEN": "ホーム", - "MONADO_RUNTIME": "「Monado」ランタイム", - "APPLICATIONS": "アプリケーション", - "GAMES": "ゲーム", - "SETTINGS": "設定", - "PROCESSES": "プロセス", - "HELLO_USER": "こんにちは、{USER}!", - "GENERAL_SETTINGS": "全般設定", - "APPLICATION_LAUNCHER": "アプリケーションランチャー", - "APP_SETTINGS": { - "HIDE_USERNAME": "ユーザー名を表示しない", - "OPAQUE_BACKGROUND": "不透明な背景", - "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "XWaylandモードでデフォルトで実行する", - "WLX_OVERLAY_S_SETTINGS": "WlxOverlay-Sの設定", - "HEADSET_SETTINGS": "ヘッドセット設定", - "BRIGHTNESS": "明るさ", - "WLX": { - "NOTIFICATIONS_ENABLED": "通知", - "NOTIFICATIONS_SOUND_ENABLED": "通知音", - "KEYBOARD_SOUND_ENABLED": "キーボード音", - "BLOCK_GAME_INPUT": "ゲーム入力をブロック", - "SPACE_DRAG_MULTIPLIER": "スペースドラッグ乗数", - "SPACE_DRAG_ROTATION_ENABLED": "スペースドラッグでの回転", - "SHOW_SKYBOX": "スカイボックス", - "ENABLE_PASSTHROUGH": "パススルー" - }, - "RESTART_SOFTWARE": "ソフトウェアを再起動" - }, - "HELLO": "こんにちは!", - "AUDIO": { - "VOLUME": "音量", - "SETTINGS": "オーディオ設定", - "AUTO_SWITCH_TO_VR_AUDIO": "VRオーディオに自動切り替え", - "SPEAKERS": "スピーカー", - "MICROPHONES": "マイク", - "CARDS": "カード", - "SELECT_AUDIO_CARD_PROFILE": "オーディオカードプロファイルを選択", - "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "VRスピーカーが見つかりませんでした。手動で切り替えてください。", - "NO_VR_MICROPHONE_SWITCH_MANUALLY": "VRマイクが見つかりませんでした。手動で切り替えてください。", - "FAILED_TO_SWITCH_MICROPHONE": "マイクの切り替えに失敗しました", - "MICROPHONE_SET_SUCCESSFULLY": "マイクの設定が完了しました", - "SPEAKERS_SET_SUCCESSFULLY": "スピーカーを設定しました", - "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "デバイスが見つかり、初期化されましたが、切り替えられていません" - }, - "ACTIONS": { - "RECENTER_PLAYSPACE": "プレイスペースを再中央" - }, - "LIST_OF_DISPLAYS": "ディスプレイリスト", - "LIST_OF_PROCESSES": "プロセスのリスト", - "NO_DISPLAYS_FOUND": "ディスプレイが見つかりません", - "ADD_DISPLAY": "ディスプレイを追加", - "POPUP_ADD_DISPLAY": { - "RESOLUTION": "解像度" - }, - "WIDTH": "幅", - "HEIGHT": "高さ", - "DISPLAY_PORTRAIT_MODE": "縦向きモード", - "HIDE": "隠す", - "REMOVE": "削除", - "SHOW": "表示", - "DISPLAY_OPTIONS": "表示オプション", - "PROCESS_LIST": { - "NO_PROCESSES_FOUND": "プロセスが見つかりませんでした", - "LOCATED_ON": "に", - "TERMINATE_PROCESS_NAMED_X": "プロセス \"{PROCESS_NAME}\" を終了します" - }, - "FAILED_TO_LAUNCH_APPLICATION": "アプリケーションの起動に失敗しました:", - "APPLICATION_LAUNCHED_ON": "{DISPLAY_NAME}でアプリケーションが起動しました。" -} + "HOME_SCREEN": "ホーム", + "MONADO_RUNTIME": "「Monado」ランタイム", + "APPLICATIONS": "アプリケーション", + "GAMES": "ゲーム", + "SETTINGS": "設定", + "PROCESSES": "プロセス", + "HELLO_USER": "こんにちは、{USER}!", + "GENERAL_SETTINGS": "全般設定", + "APPLICATION_LAUNCHER": "アプリケーションランチャー", + "APP_SETTINGS": { + "HIDE_USERNAME": "ユーザー名を表示しない", + "OPAQUE_BACKGROUND": "不透明な背景", + "RUN_IN_XWAYLAND_MODE_BY_DEFAULT": "XWaylandモードでデフォルトで実行する", + "WLX_OVERLAY_S_SETTINGS": "WlxOverlay-Sの設定", + "HEADSET_SETTINGS": "ヘッドセット設定", + "BRIGHTNESS": "明るさ", + "WLX": { + "NOTIFICATIONS_ENABLED": "通知", + "NOTIFICATIONS_SOUND_ENABLED": "通知音", + "KEYBOARD_SOUND_ENABLED": "キーボード音", + "BLOCK_GAME_INPUT": "ゲーム入力をブロック", + "SPACE_DRAG_MULTIPLIER": "スペースドラッグ乗数", + "SPACE_DRAG_ROTATION_ENABLED": "スペースドラッグでの回転", + "SHOW_SKYBOX": "スカイボックス", + "ENABLE_PASSTHROUGH": "パススルー" + }, + "RESTART_SOFTWARE": "ソフトウェアを再起動" + }, + "HELLO": "こんにちは!", + "AUDIO": { + "VOLUME": "音量", + "SETTINGS": "オーディオ設定", + "AUTO_SWITCH_TO_VR_AUDIO": "VRオーディオに自動切り替え", + "SPEAKERS": "スピーカー", + "MICROPHONES": "マイク", + "CARDS": "カード", + "SELECT_AUDIO_CARD_PROFILE": "オーディオカードプロファイルを選択", + "NO_VR_SPEAKERS_FOUND_SWITCH_MANUALLY": "VRスピーカーが見つかりませんでした。手動で切り替えてください。", + "NO_VR_MICROPHONE_SWITCH_MANUALLY": "VRマイクが見つかりませんでした。手動で切り替えてください。", + "FAILED_TO_SWITCH_MICROPHONE": "マイクの切り替えに失敗しました", + "MICROPHONE_SET_SUCCESSFULLY": "マイクの設定が完了しました", + "SPEAKERS_SET_SUCCESSFULLY": "スピーカーを設定しました", + "DEVICE_FOUND_AND_INITIALIZED_BUT_NOT_SWITCHED": "デバイスが見つかり、初期化されましたが、切り替えられていません" + }, + "ACTIONS": { + "RECENTER_PLAYSPACE": "プレイスペースを再中央" + }, + "LIST_OF_PROCESSES": "プロセスのリスト", + "POPUP_ADD_DISPLAY": { + "RESOLUTION": "解像度" + }, + "WIDTH": "幅", + "HEIGHT": "高さ", + "HIDE": "隠す", + "REMOVE": "削除", + "SHOW": "表示", + "PROCESS_LIST": { + "NO_PROCESSES_FOUND": "プロセスが見つかりませんでした", + "LOCATED_ON": "に", + "TERMINATE_PROCESS_NAMED_X": "プロセス \"{PROCESS_NAME}\" を終了します" + }, + "FAILED_TO_LAUNCH_APPLICATION": "アプリケーションの起動に失敗しました:", + "NO_WINDOWS_FOUND": "ウィンドウが見つかりませんでした", + "WINDOW_OPTIONS": "ウィンドウオプション", + "APPLICATION_STARTED": "アプリケーションが起動しました", + "LIST_OF_WINDOWS": "ウィンドウ一覧" +} \ No newline at end of file diff --git a/dash-frontend/assets/lang/pl.json b/dash-frontend/assets/lang/pl.json index 653843a..aafb4fa 100644 --- a/dash-frontend/assets/lang/pl.json +++ b/dash-frontend/assets/lang/pl.json @@ -2,7 +2,6 @@ "ACTIONS": { "RECENTER_PLAYSPACE": "Wycentruj przestrzeń" }, - "ADD_DISPLAY": "Dodaj monitor", "APP_SETTINGS": { "BRIGHTNESS": "Jasność", "HEADSET_SETTINGS": "Ustawienia HMD", @@ -39,8 +38,6 @@ "SPEAKERS_SET_SUCCESSFULLY": "Głośniki ustawiono pomyślnie", "VOLUME": "Głośność" }, - "DISPLAY_OPTIONS": "Opcje monitora", - "DISPLAY_PORTRAIT_MODE": "Tryb pionowy", "GAMES": "Gry", "GENERAL_SETTINGS": "Ustawienia ogólne", "HEIGHT": "Wysokość", @@ -48,10 +45,8 @@ "HELLO_USER": "Witaj, {USER}!", "HIDE": "Ukryj", "HOME_SCREEN": "Ekran główny", - "LIST_OF_DISPLAYS": "Lista monitorów", "LIST_OF_PROCESSES": "Lista procesów", "MONADO_RUNTIME": "Środowisko Monado", - "NO_DISPLAYS_FOUND": "Brak monitorów", "POPUP_ADD_DISPLAY": { "RESOLUTION": "Rozdzielczość" }, @@ -66,5 +61,8 @@ "TERMINATE_PROCESS_NAMED_X": "Zakończ proces \"{PROCESS_NAME}\"" }, "FAILED_TO_LAUNCH_APPLICATION": "Nie udało się uruchomić aplikacji:", - "APPLICATION_LAUNCHED_ON": "Aplikacja uruchomiona na {DISPLAY_NAME}." + "NO_WINDOWS_FOUND": "Nie znaleziono okien", + "WINDOW_OPTIONS": "Opcje okna", + "APPLICATION_STARTED": "Aplikacja uruchomiona", + "LIST_OF_WINDOWS": "Lista okien" } \ No newline at end of file diff --git a/dash-frontend/src/frontend.rs b/dash-frontend/src/frontend.rs index b335cd2..0cb0c54 100644 --- a/dash-frontend/src/frontend.rs +++ b/dash-frontend/src/frontend.rs @@ -236,6 +236,7 @@ impl Frontend { self.globals.clone(), self.settings.as_ref(), &mut layout, + &mut self.interface, self.tasks.clone(), params, )?; diff --git a/dash-frontend/src/tab/processes.rs b/dash-frontend/src/tab/processes.rs index 668bb7f..a4a6db0 100644 --- a/dash-frontend/src/tab/processes.rs +++ b/dash-frontend/src/tab/processes.rs @@ -5,14 +5,14 @@ use wgui::{ use crate::{ tab::{Tab, TabParams, TabType, TabUpdateParams}, - views::{display_list, process_list}, + views::{process_list, window_list}, }; pub struct TabProcesses { #[allow(dead_code)] pub state: ParserState, - view_display_list: display_list::View, + view_window_list: window_list::View, view_process_list: process_list::View, } @@ -22,7 +22,7 @@ impl Tab for TabProcesses { } fn update(&mut self, params: TabUpdateParams) -> anyhow::Result<()> { - self.view_display_list.update(params.layout, params.interface)?; + self.view_window_list.update(params.layout, params.interface)?; self.view_process_list.update(params.layout, params.interface)?; Ok(()) } @@ -41,9 +41,9 @@ impl TabProcesses { )?; Ok(Self { - view_display_list: display_list::View::new(display_list::Params { + view_window_list: window_list::View::new(window_list::Params { layout: params.layout, - parent_id: state.get_widget_id("display_list_parent")?, + parent_id: state.get_widget_id("window_list_parent")?, globals: params.globals, frontend_tasks: params.frontend_tasks.clone(), on_click: None, diff --git a/dash-frontend/src/util/popup_manager.rs b/dash-frontend/src/util/popup_manager.rs index 95b63ec..3f5c922 100644 --- a/dash-frontend/src/util/popup_manager.rs +++ b/dash-frontend/src/util/popup_manager.rs @@ -14,6 +14,7 @@ use wgui::{ taffy::Display, widget::label::WidgetLabel, }; +use wlx_common::dash_interface::BoxDashInterface; use crate::{ frontend::{FrontendTask, FrontendTasks}, @@ -60,6 +61,7 @@ pub struct PopupContentFuncData<'a> { pub layout: &'a mut Layout, pub settings: &'a dyn SettingsIO, pub handle: PopupHandle, + pub interface: &'a mut BoxDashInterface, pub id_content: WidgetID, } @@ -125,6 +127,7 @@ impl PopupManager { globals: WguiGlobals, settings: &dyn SettingsIO, layout: &mut Layout, + interface: &mut BoxDashInterface, frontend_tasks: FrontendTasks, params: MountPopupParams, ) -> anyhow::Result<()> { @@ -181,6 +184,7 @@ impl PopupManager { handle: popup_handle.clone(), id_content, settings, + interface, })?; Ok(()) diff --git a/dash-frontend/src/util/various.rs b/dash-frontend/src/util/various.rs index b0a3424..8296009 100644 --- a/dash-frontend/src/util/various.rs +++ b/dash-frontend/src/util/various.rs @@ -1,6 +1,4 @@ use std::{path::PathBuf, str::FromStr}; - -use wayvr_ipc::packet_server; use wgui::{ assets::{AssetPath, AssetPathOwned}, globals::WguiGlobals, @@ -13,7 +11,6 @@ use wgui::{ sprite::{WidgetSprite, WidgetSpriteParams}, }, }; -use wlx_common::dash_interface::BoxDashInterface; use crate::util::desktop_finder; @@ -33,22 +30,6 @@ pub fn get_desktop_file_icon_path(desktop_file: &desktop_finder::DesktopFile) -> AssetPathOwned::BuiltIn(PathBuf::from_str("dashboard/terminal.svg").unwrap()) } -pub fn get_all_windows(interface: &mut BoxDashInterface) -> anyhow::Result> { - let mut windows = Vec::::new(); - - for display in interface.display_list()? { - let Ok(window_list) = interface.display_window_list(display.handle) else { - continue; - }; - - for window in window_list { - windows.push(window) - } - } - - Ok(windows) -} - pub fn mount_simple_label( globals: &WguiGlobals, layout: &mut Layout, diff --git a/dash-frontend/src/views/add_display.rs b/dash-frontend/src/views/add_display.rs deleted file mode 100644 index ea60c8f..0000000 --- a/dash-frontend/src/views/add_display.rs +++ /dev/null @@ -1,247 +0,0 @@ -use std::rc::Rc; - -use anyhow::Context; -use wgui::{ - assets::AssetPath, - components::{button::ComponentButton, checkbox::ComponentCheckbox, slider::ComponentSlider}, - event::StyleSetRequest, - globals::WguiGlobals, - i18n::Translation, - layout::{Layout, WidgetID}, - parser::{Fetchable, ParseDocumentParams, ParserState}, - taffy::prelude::length, - widget::label::WidgetLabel, -}; - -use crate::task::Tasks; - -#[derive(Clone)] -enum Task { - Confirm, - SetWidth(u16), - SetHeight(u16), - SetPortrait(bool), -} - -pub struct View { - #[allow(dead_code)] - pub state: ParserState, - tasks: Tasks, - on_submit: Rc, - - cur_raw_width: u16, - cur_raw_height: u16, - cur_display_name: String, - cur_portrait: bool, - - id_label_width: WidgetID, - id_label_height: WidgetID, - id_label_display_name: WidgetID, - id_rect_display: WidgetID, - id_label_display: WidgetID, -} - -#[derive(Clone)] -pub struct Result { - pub width: u16, - pub height: u16, - pub display_name: String, -} - -pub struct Params<'a> { - pub globals: WguiGlobals, - pub layout: &'a mut Layout, - pub parent_id: WidgetID, - pub on_submit: Rc, -} - -const RES_COUNT: usize = 7; -const RES_WIDTHS: [u16; RES_COUNT] = [512, 854, 1280, 1600, 1920, 2560, 3840]; -const RES_HEIGHTS: [u16; 7] = [256, 480, 720, 900, 1080, 1440, 2160]; - -impl View { - pub fn new(params: Params) -> anyhow::Result { - let doc_params = &ParseDocumentParams { - globals: params.globals.clone(), - path: AssetPath::BuiltIn("gui/view/add_display.xml"), - extra: Default::default(), - }; - - let state = wgui::parser::parse_from_assets(doc_params, params.layout, params.parent_id)?; - - let tasks = Tasks::new(); - - let slider_width = state.fetch_component_as::("slider_width")?; - let slider_height = state.fetch_component_as::("slider_height")?; - let id_label_width = state.get_widget_id("label_width")?; - let id_label_height = state.get_widget_id("label_height")?; - let id_label_display_name = state.get_widget_id("label_display_name")?; - let id_rect_display = state.get_widget_id("rect_display")?; - let id_label_display = state.get_widget_id("label_display")?; - let btn_confirm = state.fetch_component_as::("btn_confirm")?; - let cb_portrait = state.fetch_component_as::("cb_portrait")?; - - tasks.handle_button(btn_confirm, Task::Confirm); - - // width - slider_width.on_value_changed({ - let tasks = tasks.clone(); - Box::new(move |_c, e| { - tasks.push(Task::SetWidth(RES_WIDTHS[e.value as usize])); - Ok(()) - }) - }); - - // height - slider_height.on_value_changed({ - let tasks = tasks.clone(); - Box::new(move |_c, e| { - tasks.push(Task::SetHeight(RES_HEIGHTS[e.value as usize])); - Ok(()) - }) - }); - - cb_portrait.on_toggle({ - let tasks = tasks.clone(); - Box::new(move |_c, e| { - tasks.push(Task::SetPortrait(e.checked)); - Ok(()) - }) - }); - - let mut res = Self { - state, - tasks, - on_submit: params.on_submit, - cur_raw_width: RES_WIDTHS[2], - cur_raw_height: RES_HEIGHTS[2], - cur_display_name: String::new(), - cur_portrait: false, - id_label_width, - id_label_height, - id_label_display_name, - id_rect_display, - id_label_display, - }; - - res.update_ui(params.layout); - - Ok(res) - } - - pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> { - for task in self.tasks.drain() { - match task { - Task::Confirm => self.confirm(), - Task::SetWidth(w) => { - self.cur_raw_width = w; - self.update_ui_res(layout)?; - } - Task::SetHeight(h) => { - self.cur_raw_height = h; - self.update_ui_res(layout)?; - } - Task::SetPortrait(p) => { - self.cur_portrait = p; - self.update_ui_res(layout)?; - } - } - } - Ok(()) - } -} - -// greatest common divisor -fn gcd(a: u16, b: u16) -> u16 { - let (mut a, mut b) = (a, b); - while b != 0 { - let temp = b; - b = a % b; - a = temp; - } - a -} - -// aspect ratio calculation -// e.g. returns (16, 9) for input values [1280, 720] -fn aspect_ratio(width: u16, height: u16) -> (u16, u16) { - let gcd = gcd(width, height); - (width / gcd, height / gcd) -} - -impl View { - fn confirm(&mut self) { - let (width, height) = self.get_wh(); - (*self.on_submit)(Result { - width, - height, - display_name: self.cur_display_name.clone(), - }); - } - - fn update_ui(&mut self, layout: &mut Layout) -> Option<()> { - let mut c = layout.start_common(); - - let (cur_width, cur_height) = self.get_wh(); - - { - let mut common = c.common(); - - let mut label_width = common.state.widgets.get_as::(self.id_label_width)?; - let mut label_height = common.state.widgets.get_as::(self.id_label_height)?; - let mut label_display_name = common.state.widgets.get_as::(self.id_label_display_name)?; - let mut label_display = common.state.widgets.get_as::(self.id_label_display)?; - - // todo? - self.cur_display_name = format!("wvr-{}x{}", cur_width, cur_height); - - label_width.set_text( - &mut common, - Translation::from_raw_text_string(format!("{}px", self.cur_raw_width)), - ); - - label_height.set_text( - &mut common, - Translation::from_raw_text_string(format!("{}px", self.cur_raw_height)), - ); - - let aspect = aspect_ratio(cur_width, cur_height); - - label_display.set_text( - &mut common, - Translation::from_raw_text_string(format!("{}x{}\n{}:{}", cur_width, cur_height, aspect.0, aspect.1)), - ); - - label_display_name.set_text(&mut common, Translation::from_raw_text(&self.cur_display_name)); - - let mult = 0.1; - - common.alterables.set_style( - self.id_rect_display, - StyleSetRequest::Width(length(cur_width as f32 * mult)), - ); - - common.alterables.set_style( - self.id_rect_display, - StyleSetRequest::Height(length(cur_height as f32 * mult)), - ); - } - - c.finish().ok()?; - - Some(()) - } - - fn update_ui_res(&mut self, layout: &mut Layout) -> anyhow::Result<()> { - self.update_ui(layout).context("failed to update ui")?; - Ok(()) - } - - fn get_wh(&self) -> (u16, u16) { - if self.cur_portrait { - (self.cur_raw_height, self.cur_raw_width) - } else { - (self.cur_raw_width, self.cur_raw_height) - } - } -} diff --git a/dash-frontend/src/views/app_launcher.rs b/dash-frontend/src/views/app_launcher.rs index bf97f52..52265e3 100644 --- a/dash-frontend/src/views/app_launcher.rs +++ b/dash-frontend/src/views/app_launcher.rs @@ -1,10 +1,9 @@ use std::{collections::HashMap, rc::Rc}; -use anyhow::Context; use wayvr_ipc::{packet_client::WvrProcessLaunchParams, packet_server::WvrDisplayHandle}; use wgui::{ assets::AssetPath, - components::checkbox::ComponentCheckbox, + components::{button::ComponentButton, checkbox::ComponentCheckbox}, globals::WguiGlobals, i18n::Translation, layout::{Layout, WidgetID}, @@ -18,7 +17,6 @@ use crate::{ settings::SettingsIO, task::Tasks, util::desktop_finder::DesktopEntry, - views::display_list, }; #[derive(Clone, Eq, PartialEq)] @@ -27,13 +25,13 @@ enum RunMode { Wayland, } +#[derive(Clone)] enum Task { SetRunMode(RunMode), - DisplayClick(WvrDisplayHandle), + Launch, } struct LaunchParams<'a> { - display_handle: WvrDisplayHandle, application: &'a DesktopEntry, run_mode: RunMode, globals: &'a WguiGlobals, @@ -46,7 +44,6 @@ pub struct View { #[allow(dead_code)] state: ParserState, entry: DesktopEntry, - view_display_list: display_list::View, tasks: Tasks, frontend_tasks: FrontendTasks, globals: WguiGlobals, @@ -80,6 +77,7 @@ impl View { let cb_cage_mode = state.fetch_component_as::("cb_cage_mode")?; let cb_wayland_mode = state.fetch_component_as::("cb_wayland_mode")?; + let btn_launch = state.fetch_component_as::("btn_launch")?; { let mut label_exec = state.fetch_widget_as::(¶ms.layout.state, "label_exec")?; @@ -96,24 +94,9 @@ impl View { ); } - let display_list_parent = state.fetch_widget(¶ms.layout.state, "display_list_parent")?.id; - let tasks = Tasks::new(); - let on_display_click = { - let tasks = tasks.clone(); - Box::new(move |disp_handle: WvrDisplayHandle| { - tasks.push(Task::DisplayClick(disp_handle)); - }) - }; - - let view_display_list = display_list::View::new(display_list::Params { - frontend_tasks: params.frontend_tasks.clone(), - globals: params.globals, - layout: params.layout, - parent_id: display_list_parent, - on_click: Some(on_display_click), - })?; + tasks.handle_button(btn_launch, Task::Launch); let id_icon_parent = state.get_widget_id("icon_parent")?; @@ -163,7 +146,6 @@ impl View { Ok(Self { state, - view_display_list, tasks, cb_cage_mode, cb_wayland_mode, @@ -184,13 +166,11 @@ impl View { for task in tasks { match task { Task::SetRunMode(run_mode) => self.action_set_run_mode(layout, run_mode)?, - Task::DisplayClick(disp_handle) => self.action_display_click(disp_handle, interface), + Task::Launch => self.action_launch(interface), } } } - self.view_display_list.update(layout, interface)?; - Ok(()) } @@ -208,10 +188,9 @@ impl View { Ok(()) } - fn action_display_click(&mut self, handle: WvrDisplayHandle, interface: &mut BoxDashInterface) { + fn action_launch(&mut self, interface: &mut BoxDashInterface) { View::try_launch(LaunchParams { application: &self.entry, - display_handle: handle, frontend_tasks: &self.frontend_tasks, globals: &self.globals, run_mode: self.run_mode.clone(), @@ -253,10 +232,6 @@ impl View { let exec_args_str = desktop_file.exec_args.join(" "); - params - .interface - .display_set_visible(params.display_handle.clone(), true)?; - let args = match params.run_mode { RunMode::Cage => format!("-- {} {}", desktop_file.exec_path, exec_args_str), RunMode::Wayland => exec_args_str, @@ -267,29 +242,22 @@ impl View { RunMode::Wayland => &desktop_file.name, }; - let display = params - .interface - .display_get(params.display_handle.clone()) - .context("Display not found")?; - params.interface.process_launch(WvrProcessLaunchParams { env, exec: String::from(exec), name: desktop_file.name, - target_display: params.display_handle, + target_display: WvrDisplayHandle { + generation: 12345, // stub + idx: 12345, + }, args, userdata, })?; - let str_launched_on = params - .globals - .i18n() - .translate_and_replace("APPLICATION_LAUNCHED_ON", ("{DISPLAY_NAME}", &display.name)); - params .frontend_tasks - .push(FrontendTask::PushToast(Translation::from_raw_text_string( - str_launched_on, + .push(FrontendTask::PushToast(Translation::from_translation_key( + "APPLICATION_STARTED", ))); (*params.on_launched)(); diff --git a/dash-frontend/src/views/mod.rs b/dash-frontend/src/views/mod.rs index 64c3260..736d510 100644 --- a/dash-frontend/src/views/mod.rs +++ b/dash-frontend/src/views/mod.rs @@ -1,6 +1,5 @@ -pub mod add_display; pub mod app_launcher; pub mod audio_settings; -pub mod display_list; -pub mod display_options; pub mod process_list; +pub mod window_list; +pub mod window_options; diff --git a/dash-frontend/src/views/process_list.rs b/dash-frontend/src/views/process_list.rs index fdc17c0..5a93863 100644 --- a/dash-frontend/src/views/process_list.rs +++ b/dash-frontend/src/views/process_list.rs @@ -91,29 +91,18 @@ impl View { } } -fn get_desktop_file_from_process( - windows: &Vec, - process: &packet_server::WvrProcess, -) -> Option { - for window in windows { - if window.process_handle != process.handle { - continue; - } +fn get_desktop_file_from_process(process: &packet_server::WvrProcess) -> Option { + // TODO: refactor this after we ditch old wayvr-dashboard completely + let Some(dfile_str) = process.userdata.get("desktop_file") else { + return None; + }; - // TODO: refactor this after we ditch old wayvr-dashboard completely - let Some(dfile_str) = process.userdata.get("desktop_file") else { - continue; - }; + let Ok(desktop_file) = serde_json::from_str::(dfile_str) else { + debug_assert!(false); // invalid json??? + return None; + }; - let Ok(desktop_file) = serde_json::from_str::(dfile_str) else { - debug_assert!(false); // invalid json??? - continue; - }; - - return Some(desktop_file); - } - - None + Some(desktop_file) } struct ProcessEntryResult { @@ -124,8 +113,6 @@ fn construct_process_entry( ess: &mut ConstructEssentials, globals: &WguiGlobals, process: &packet_server::WvrProcess, - display: Option<&packet_server::WvrDisplay>, - all_windows: &Vec, ) -> anyhow::Result { let (cell, _) = ess.layout.add_child( ess.parent, @@ -159,7 +146,7 @@ fn construct_process_entry( }, )?; - if let Some(desktop_file) = get_desktop_file_from_process(all_windows, process) { + if let Some(desktop_file) = get_desktop_file_from_process(process) { // desktop file icon and process name util::various::mount_simple_sprite_square( globals, @@ -185,35 +172,6 @@ fn construct_process_entry( )?; } - if let Some(display) = display { - // show display icon if available - - // "on" text - util::various::mount_simple_label( - globals, - ess.layout, - cell.id, - Translation::from_translation_key("PROCESS_LIST.LOCATED_ON"), - )?; - - // "display" icon - util::various::mount_simple_sprite_square( - globals, - ess.layout, - cell.id, - 24.0, - AssetPath::BuiltIn("dashboard/display.svg"), - )?; - - // display name itself - util::various::mount_simple_label( - globals, - ess.layout, - cell.id, - Translation::from_raw_text_string(display.name.clone()), - )?; - } - Ok(ProcessEntryResult { btn_terminate }) } @@ -222,18 +180,9 @@ fn fill_process_list( ess: &mut ConstructEssentials, tasks: &Tasks, list: &Vec, - displays: &Vec, - all_windows: &Vec, ) -> anyhow::Result<()> { for process_entry in list { - let mut matching_display = None; - for display in displays { - if process_entry.display_handle == display.handle { - matching_display = Some(display); - } - } - - let entry_res = construct_process_entry(ess, globals, process_entry, matching_display, all_windows)?; + let entry_res = construct_process_entry(ess, globals, process_entry)?; entry_res.btn_terminate.on_click({ let tasks = tasks.clone(); @@ -252,9 +201,6 @@ impl View { fn refresh(&mut self, layout: &mut Layout, interface: &mut BoxDashInterface) -> anyhow::Result<()> { layout.remove_children(self.id_list_parent); - let displays = interface.display_list()?; - let all_windows = util::various::get_all_windows(interface)?; - let mut text: Option = None; match interface.process_list() { Ok(list) => { @@ -269,8 +215,6 @@ impl View { }, &self.tasks, &list, - &displays, - &all_windows, )?; } } diff --git a/dash-frontend/src/views/display_list.rs b/dash-frontend/src/views/window_list.rs similarity index 59% rename from dash-frontend/src/views/display_list.rs rename to dash-frontend/src/views/window_list.rs index 17a502c..05c1db9 100644 --- a/dash-frontend/src/views/display_list.rs +++ b/dash-frontend/src/views/window_list.rs @@ -1,9 +1,6 @@ use std::{cell::RefCell, rc::Rc}; -use wayvr_ipc::{ - packet_client::{self}, - packet_server::{self, WvrDisplayHandle}, -}; +use wayvr_ipc::packet_server::{self, WvrWindowHandle}; use wgui::{ assets::AssetPath, components::{self, button::ComponentButton}, @@ -24,15 +21,13 @@ use crate::{ frontend::{FrontendTask, FrontendTasks}, task::Tasks, util::popup_manager::{MountPopupParams, PopupHandle}, - views::{add_display, display_options}, + views::window_options, }; #[derive(Clone)] enum Task { - AddDisplay, - AddDisplayFinish(add_display::Result), - DisplayClicked(packet_server::WvrDisplay), - DisplayOptionsFinish, + WindowClicked(packet_server::WvrWindow), + WindowOptionsFinish, Refresh, } @@ -41,12 +36,11 @@ pub struct Params<'a> { pub frontend_tasks: FrontendTasks, pub layout: &'a mut Layout, pub parent_id: WidgetID, - pub on_click: Option>, + pub on_click: Option>, } struct State { - view_add_display: Option<(PopupHandle, add_display::View)>, - view_display_options: Option<(PopupHandle, display_options::View)>, + view_window_options: Option<(PopupHandle, window_options::View)>, } pub struct View { @@ -57,14 +51,14 @@ pub struct View { globals: WguiGlobals, state: Rc>, id_list_parent: WidgetID, - on_click: Option>, + on_click: Option>, } impl View { pub fn new(params: Params) -> anyhow::Result { let doc_params = &ParseDocumentParams { globals: params.globals.clone(), - path: AssetPath::BuiltIn("gui/view/display_list.xml"), + path: AssetPath::BuiltIn("gui/view/window_list.xml"), extra: Default::default(), }; @@ -73,13 +67,10 @@ impl View { let tasks = Tasks::new(); - let btn_add = parser_state.fetch_component_as::("btn_add")?; - tasks.handle_button(btn_add, Task::AddDisplay); tasks.push(Task::Refresh); let state = Rc::new(RefCell::new(State { - view_add_display: None, - view_display_options: None, + view_window_options: None, })); Ok(Self { @@ -101,21 +92,15 @@ impl View { } for task in tasks { match task { - Task::AddDisplay => self.action_add_display(), - Task::AddDisplayFinish(result) => self.action_add_display_finish(interface, result)?, - Task::DisplayOptionsFinish => self.action_display_options_finish(), + Task::WindowClicked(display) => self.action_window_clicked(display)?, + Task::WindowOptionsFinish => self.action_window_options_finish(), Task::Refresh => self.refresh(layout, interface)?, - Task::DisplayClicked(display) => self.action_display_clicked(display)?, } } } let mut state = self.state.borrow_mut(); - if let Some((_, view)) = &mut state.view_add_display { - view.update(layout)?; - } - - if let Some((_, view)) = &mut state.view_display_options { + if let Some((_, view)) = &mut state.view_window_options { view.update(layout, interface)?; } @@ -123,12 +108,13 @@ impl View { } } -pub fn construct_display_button( +pub fn construct_window_button( ess: &mut ConstructEssentials, + interface: &mut BoxDashInterface, globals: &WguiGlobals, - display: &packet_server::WvrDisplay, + window: &packet_server::WvrWindow, ) -> anyhow::Result<(WidgetPair, Rc)> { - let aspect = display.width as f32 / display.height as f32; + let aspect = window.size_x as f32 / window.size_y as f32; let height = 96.0; let width = height * aspect; let accent_color = globals.defaults().accent_color; @@ -151,10 +137,15 @@ pub fn construct_display_button( }, )?; + let process_name = match interface.process_get(window.process_handle.clone()) { + Some(process) => process.name.clone(), + None => String::from("Unknown"), + }; + let label_name = WidgetLabel::create( &mut globals.get(), WidgetLabelParams { - content: Translation::from_raw_text(&display.name), + content: Translation::from_raw_text(&process_name), style: TextStyle { weight: Some(FontWeight::Bold), wrap: true, @@ -180,19 +171,20 @@ pub fn construct_display_button( Ok((widget_button, button)) } -fn fill_display_list( +fn fill_window_list( globals: &WguiGlobals, ess: &mut ConstructEssentials, - list: Vec, + interface: &mut BoxDashInterface, + list: Vec, tasks: &Tasks, ) -> anyhow::Result<()> { for entry in list { - let (_, button) = construct_display_button(ess, globals, &entry)?; + let (_, button) = construct_window_button(ess, interface, globals, &entry)?; button.on_click({ let tasks = tasks.clone(); Box::new(move |_, _| { - tasks.push(Task::DisplayClicked(entry.clone())); + tasks.push(Task::WindowClicked(entry.clone())); Ok(()) }) }); @@ -202,55 +194,8 @@ fn fill_display_list( } impl View { - fn action_add_display(&mut self) { - self.frontend_tasks.push(FrontendTask::MountPopup(MountPopupParams { - title: Translation::from_translation_key("ADD_DISPLAY"), - on_content: { - let globals = self.globals.clone(); - let state = self.state.clone(); - - let on_submit = { - let tasks = self.tasks.clone(); - Rc::new(move |result| { - tasks.push(Task::AddDisplayFinish(result)); - tasks.push(Task::Refresh); - }) - }; - - Rc::new(move |data| { - state.borrow_mut().view_add_display = Some(( - data.handle, - add_display::View::new(add_display::Params { - globals: globals.clone(), - layout: data.layout, - parent_id: data.id_content, - on_submit: on_submit.clone(), - })?, - )); - Ok(()) - }) - }, - })); - } - - fn action_add_display_finish( - &mut self, - interface: &mut BoxDashInterface, - result: add_display::Result, - ) -> anyhow::Result<()> { - interface.display_create(packet_client::WvrDisplayCreateParams { - width: result.width, - height: result.height, - name: result.display_name, - attach_to: packet_client::AttachTo::None, - scale: None, - })?; - self.state.borrow_mut().view_add_display = None; - Ok(()) - } - - fn action_display_options_finish(&mut self) { - self.state.borrow_mut().view_display_options = None; + fn action_window_options_finish(&mut self) { + self.state.borrow_mut().view_window_options = None; self.tasks.push(Task::Refresh); } @@ -258,17 +203,18 @@ impl View { layout.remove_children(self.id_list_parent); let mut text: Option = None; - match interface.display_list() { + match interface.window_list() { Ok(list) => { if list.is_empty() { - text = Some(Translation::from_translation_key("NO_DISPLAYS_FOUND")) + text = Some(Translation::from_translation_key("NO_WINDOWS_FOUND")) } else { - fill_display_list( + fill_window_list( &self.globals, &mut ConstructEssentials { layout, parent: self.id_list_parent, }, + interface, list, &self.tasks, )? @@ -294,12 +240,12 @@ impl View { Ok(()) } - fn action_display_clicked(&mut self, display: packet_server::WvrDisplay) -> anyhow::Result<()> { + fn action_window_clicked(&mut self, window: packet_server::WvrWindow) -> anyhow::Result<()> { if let Some(on_click) = &mut self.on_click { - (*on_click)(display.handle); + (*on_click)(window.handle); } else { self.frontend_tasks.push(FrontendTask::MountPopup(MountPopupParams { - title: Translation::from_translation_key("DISPLAY_OPTIONS"), + title: Translation::from_translation_key("WINDOW_OPTIONS"), on_content: { let frontend_tasks = self.frontend_tasks.clone(); let globals = self.globals.clone(); @@ -307,15 +253,16 @@ impl View { let tasks = self.tasks.clone(); Rc::new(move |data| { - state.borrow_mut().view_display_options = Some(( + state.borrow_mut().view_window_options = Some(( data.handle, - display_options::View::new(display_options::Params { + window_options::View::new(window_options::Params { globals: globals.clone(), layout: data.layout, parent_id: data.id_content, - on_submit: tasks.make_callback(Task::DisplayOptionsFinish), - display: display.clone(), + on_submit: tasks.make_callback(Task::WindowOptionsFinish), + window: window.clone(), frontend_tasks: frontend_tasks.clone(), + interface: data.interface, })?, )); Ok(()) diff --git a/dash-frontend/src/views/display_options.rs b/dash-frontend/src/views/window_options.rs similarity index 53% rename from dash-frontend/src/views/display_options.rs rename to dash-frontend/src/views/window_options.rs index 46bcf02..054f06f 100644 --- a/dash-frontend/src/views/display_options.rs +++ b/dash-frontend/src/views/window_options.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use std::rc::Rc; use wayvr_ipc::packet_server; use wgui::{ @@ -14,13 +15,14 @@ use wlx_common::dash_interface::BoxDashInterface; use crate::{ frontend::{FrontendTask, FrontendTasks}, task::Tasks, - views::display_list::construct_display_button, + views::window_list::construct_window_button, }; #[derive(Clone)] enum Task { SetVisible(bool), - Remove, + Kill, + Close, } pub struct View { @@ -28,7 +30,7 @@ pub struct View { pub state: ParserState, tasks: Tasks, frontend_tasks: FrontendTasks, - display: packet_server::WvrDisplay, + window: packet_server::WvrWindow, on_submit: Rc, } @@ -38,14 +40,15 @@ pub struct Params<'a> { pub layout: &'a mut Layout, pub parent_id: WidgetID, pub on_submit: Rc, - pub display: packet_server::WvrDisplay, + pub window: packet_server::WvrWindow, + pub interface: &'a mut BoxDashInterface, } impl View { pub fn new(params: Params) -> anyhow::Result { let doc_params = &ParseDocumentParams { globals: params.globals.clone(), - path: AssetPath::BuiltIn("gui/view/display_options.xml"), + path: AssetPath::BuiltIn("gui/view/window_options.xml"), extra: Default::default(), }; @@ -53,35 +56,38 @@ impl View { let tasks = Tasks::new(); - let display_parent = state.get_widget_id("display_parent")?; - let btn_remove = state.fetch_component_as::("btn_remove")?; + let window_parent = state.get_widget_id("window_parent")?; + let btn_close = state.fetch_component_as::("btn_close")?; + let btn_kill = state.fetch_component_as::("btn_kill")?; let btn_show_hide = state.fetch_component_as::("btn_show_hide")?; - construct_display_button( + construct_window_button( &mut ConstructEssentials { layout: params.layout, - parent: display_parent, + parent: window_parent, }, + params.interface, ¶ms.globals, - ¶ms.display, + ¶ms.window, )?; { let mut c = params.layout.start_common(); btn_show_hide.set_text( &mut c.common(), - Translation::from_translation_key(if params.display.visible { "HIDE" } else { "SHOW" }), + Translation::from_translation_key(if params.window.visible { "HIDE" } else { "SHOW" }), ); c.finish()?; } - tasks.handle_button(btn_remove, Task::Remove); - tasks.handle_button(btn_show_hide, Task::SetVisible(!params.display.visible)); + tasks.handle_button(btn_close, Task::Close); + tasks.handle_button(btn_kill, Task::Kill); + tasks.handle_button(btn_show_hide, Task::SetVisible(!params.window.visible)); Ok(Self { state, tasks, - display: params.display, + window: params.window, frontend_tasks: params.frontend_tasks, on_submit: params.on_submit, }) @@ -91,7 +97,8 @@ impl View { for task in self.tasks.drain() { match task { Task::SetVisible(v) => self.action_set_visible(interface, v), - Task::Remove => self.action_remove(interface), + Task::Close => self.action_close(interface), + Task::Kill => self.action_kill(interface), } } Ok(()) @@ -100,11 +107,11 @@ impl View { impl View { fn action_set_visible(&mut self, interface: &mut BoxDashInterface, visible: bool) { - if let Err(e) = interface.display_set_visible(self.display.handle.clone(), visible) { + if let Err(e) = interface.window_set_visible(self.window.handle.clone(), visible) { self .frontend_tasks .push(FrontendTask::PushToast(Translation::from_raw_text_string(format!( - "Failed to remove display: {:?}", + "Failed to set window visibility: {:?}", e )))); }; @@ -112,12 +119,33 @@ impl View { (*self.on_submit)(); } - fn action_remove(&mut self, interface: &mut BoxDashInterface) { - if let Err(e) = interface.display_remove(self.display.handle.clone()) { + fn action_close(&mut self, interface: &mut BoxDashInterface) { + if let Err(e) = interface.window_request_close(self.window.handle.clone()) { self .frontend_tasks .push(FrontendTask::PushToast(Translation::from_raw_text_string(format!( - "Failed to remove display: {:?}", + "Failed to close window: {:?}", + e + )))); + }; + + (*self.on_submit)(); + } + + fn action_kill_process(&mut self, interface: &mut BoxDashInterface) -> anyhow::Result<()> { + let process = interface + .process_get(self.window.process_handle.clone()) + .context("Process not found")?; + interface.process_terminate(process.handle)?; + Ok(()) + } + + fn action_kill(&mut self, interface: &mut BoxDashInterface) { + if let Err(e) = self.action_kill_process(interface) { + self + .frontend_tasks + .push(FrontendTask::PushToast(Translation::from_raw_text_string(format!( + "Failed to kill process: {:?}", e )))); }; diff --git a/wlx-common/Cargo.toml b/wlx-common/Cargo.toml index 73a8225..50bd84c 100644 --- a/wlx-common/Cargo.toml +++ b/wlx-common/Cargo.toml @@ -10,5 +10,5 @@ glam = { workspace = true } chrono = "0.4.42" idmap = { workspace = true, features = ["serde"] } idmap-derive = { workspace = true } -wayvr_ipc = { workspace = true } +wayvr-ipc = { path = "../wayvr-ipc", default-features = false } anyhow = { workspace = true } diff --git a/wlx-common/src/dash_interface.rs b/wlx-common/src/dash_interface.rs index 2bd914b..23473fb 100644 --- a/wlx-common/src/dash_interface.rs +++ b/wlx-common/src/dash_interface.rs @@ -1,27 +1,16 @@ use wayvr_ipc::{ - packet_client::{WvrDisplayCreateParams, WvrProcessLaunchParams}, - packet_server::{ - WvrDisplay, WvrDisplayHandle, WvrDisplayWindowLayout, WvrProcess, WvrProcessHandle, WvrWindow, WvrWindowHandle, - }, + packet_client::WvrProcessLaunchParams, + packet_server::{WvrProcess, WvrProcessHandle, WvrWindow, WvrWindowHandle}, }; pub trait DashInterface { - fn display_create(&mut self, params: WvrDisplayCreateParams) -> anyhow::Result; - fn display_get(&mut self, handle: WvrDisplayHandle) -> Option; - fn display_list(&mut self) -> anyhow::Result>; - fn display_remove(&mut self, handle: WvrDisplayHandle) -> anyhow::Result<()>; - fn display_set_visible(&mut self, handle: WvrDisplayHandle, visible: bool) -> anyhow::Result<()>; - fn display_set_window_layout( - &mut self, - handle: WvrDisplayHandle, - layout: WvrDisplayWindowLayout, - ) -> anyhow::Result<()>; - fn display_window_list(&mut self, handle: WvrDisplayHandle) -> anyhow::Result>; + fn window_list(&mut self) -> anyhow::Result>; + fn window_set_visible(&mut self, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()>; + fn window_request_close(&mut self, handle: WvrWindowHandle) -> anyhow::Result<()>; fn process_get(&mut self, handle: WvrProcessHandle) -> Option; fn process_launch(&mut self, params: WvrProcessLaunchParams) -> anyhow::Result; fn process_list(&mut self) -> anyhow::Result>; fn process_terminate(&mut self, handle: WvrProcessHandle) -> anyhow::Result<()>; - fn window_set_visible(&mut self, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()>; fn recenter_playspace(&mut self) -> anyhow::Result<()>; } diff --git a/wlx-common/src/dash_interface_emulated.rs b/wlx-common/src/dash_interface_emulated.rs index 46111f7..fa14898 100644 --- a/wlx-common/src/dash_interface_emulated.rs +++ b/wlx-common/src/dash_interface_emulated.rs @@ -1,22 +1,18 @@ use wayvr_ipc::{ - packet_client::{WvrDisplayCreateParams, WvrProcessLaunchParams}, - packet_server::{ - WvrDisplay, WvrDisplayHandle, WvrDisplayWindowLayout, WvrProcess, WvrProcessHandle, WvrWindow, WvrWindowHandle, - }, + packet_client::WvrProcessLaunchParams, + packet_server::{WvrProcess, WvrProcessHandle, WvrWindow, WvrWindowHandle}, }; use crate::{dash_interface::DashInterface, gen_id}; #[derive(Debug)] pub struct EmuProcess { - display_handle: WvrDisplayHandle, name: String, } impl EmuProcess { fn to(&self, handle: EmuProcessHandle) -> WvrProcess { WvrProcess { - display_handle: self.display_handle.clone(), handle: WvrProcessHandle { generation: handle.generation, idx: handle.idx, @@ -28,58 +24,52 @@ impl EmuProcess { } #[derive(Debug)] -pub struct EmuDisplay { - width: u16, - height: u16, - name: String, +pub struct EmuWindow { visible: bool, - layout: WvrDisplayWindowLayout, + process_handle: EmuProcessHandle, } -impl EmuDisplay { - fn to(&self, handle: EmuDisplayHandle) -> WvrDisplay { - WvrDisplay { - width: self.width, - height: self.height, - name: self.name.clone(), - visible: self.visible, - handle: WvrDisplayHandle { +impl EmuWindow { + fn to(&self, handle: EmuWindowHandle) -> WvrWindow { + WvrWindow { + size_x: 1280, /* stub */ + size_y: 720, /* stub */ + visible: true, + handle: WvrWindowHandle { generation: handle.generation, idx: handle.idx, }, + process_handle: WvrProcessHandle { + generation: self.process_handle.generation, + idx: self.process_handle.idx, + }, } } } -gen_id!(EmuDisplayVec, EmuDisplay, EmuDisplayCell, EmuDisplayHandle); +gen_id!(EmuWindowVec, EmuWindow, EmuWindowCell, EmuWindowHandle); + gen_id!(EmuProcessVec, EmuProcess, EmuProcessCell, EmuProcessHandle); pub struct DashInterfaceEmulated { - displays: EmuDisplayVec, processes: EmuProcessVec, + windows: EmuWindowVec, } impl DashInterfaceEmulated { pub fn new() -> Self { - let mut displays = EmuDisplayVec::new(); - let disp_handle = displays.add(EmuDisplay { - width: 1280, - height: 720, - layout: WvrDisplayWindowLayout::Tiling, - name: String::from("Emulated display"), + let mut processes = EmuProcessVec::new(); + let process_handle = processes.add(EmuProcess { + name: String::from("My app"), + }); + + let mut windows = EmuWindowVec::new(); + windows.add(EmuWindow { + process_handle, visible: true, }); - let mut processes = EmuProcessVec::new(); - processes.add(EmuProcess { - display_handle: WvrDisplayHandle { - idx: disp_handle.idx, - generation: disp_handle.generation, - }, - name: String::from("Emulated process"), - }); - - Self { displays, processes } + Self { processes, windows } } } @@ -90,86 +80,31 @@ impl Default for DashInterfaceEmulated { } impl DashInterface for DashInterfaceEmulated { - fn display_create(&mut self, params: WvrDisplayCreateParams) -> anyhow::Result { - let res = self.displays.add(EmuDisplay { - width: params.width, - height: params.height, - name: params.name, - visible: true, - layout: WvrDisplayWindowLayout::Tiling, + fn window_list(&mut self) -> anyhow::Result> { + Ok(self.windows.iter().map(|(handle, w)| w.to(handle)).collect()) + } + + fn window_request_close(&mut self, handle: WvrWindowHandle) -> anyhow::Result<()> { + self.windows.remove(&EmuWindowHandle { + generation: handle.generation, + idx: handle.idx, }); - - Ok(WvrDisplayHandle { - generation: res.generation, - idx: res.idx, - }) - } - - fn display_get(&mut self, handle: WvrDisplayHandle) -> Option { - let emu_handle = EmuDisplayHandle::new(handle.idx, handle.generation); - self.displays.get(&emu_handle).map(|disp| disp.to(emu_handle)) - } - - fn display_list(&mut self) -> anyhow::Result> { - Ok(self.displays.iter().map(|(handle, disp)| disp.to(handle)).collect()) - } - - fn display_remove(&mut self, wvr_handle: WvrDisplayHandle) -> anyhow::Result<()> { - let handle = EmuDisplayHandle::new(wvr_handle.idx, wvr_handle.generation); - - for (_, process) in self.processes.iter() { - if process.display_handle == wvr_handle { - anyhow::bail!("Cannot remove display: stop {} process first.", process.name); - } - } - - self.displays.remove(&handle); Ok(()) } - fn display_set_visible(&mut self, handle: WvrDisplayHandle, visible: bool) -> anyhow::Result<()> { - let Some(disp) = self - .displays - .get_mut(&EmuDisplayHandle::new(handle.idx, handle.generation)) - else { - anyhow::bail!("Display not found"); - }; - - disp.visible = visible; - Ok(()) - } - - fn display_set_window_layout( - &mut self, - handle: WvrDisplayHandle, - layout: WvrDisplayWindowLayout, - ) -> anyhow::Result<()> { - let Some(disp) = self - .displays - .get_mut(&EmuDisplayHandle::new(handle.idx, handle.generation)) - else { - anyhow::bail!("Display not found"); - }; - - disp.layout = layout; - Ok(()) - } - - fn display_window_list(&mut self, _handle: WvrDisplayHandle) -> anyhow::Result> { - // stub! - Ok(Vec::new()) - } - fn process_get(&mut self, handle: WvrProcessHandle) -> Option { let emu_handle = EmuProcessHandle::new(handle.idx, handle.generation); self.processes.get(&emu_handle).map(|process| process.to(emu_handle)) } fn process_launch(&mut self, params: WvrProcessLaunchParams) -> anyhow::Result { - let res = self.processes.add(EmuProcess { - display_handle: params.target_display, - name: params.name, + let res = self.processes.add(EmuProcess { name: params.name }); + + self.windows.add(EmuWindow { + process_handle: res, + visible: true, }); + Ok(WvrProcessHandle { generation: res.generation, idx: res.idx, @@ -187,15 +122,35 @@ impl DashInterface for DashInterfaceEmulated { } fn process_terminate(&mut self, handle: WvrProcessHandle) -> anyhow::Result<()> { + let mut to_remove = None; + + for (wh, w) in self.windows.iter() { + if w.process_handle == EmuProcessHandle::new(handle.idx, handle.generation) { + to_remove = Some(wh); + } + } + + if let Some(wh) = to_remove { + self.windows.remove(&wh); + } + self .processes .remove(&EmuProcessHandle::new(handle.idx, handle.generation)); Ok(()) } - fn window_set_visible(&mut self, _handle: WvrWindowHandle, _visible: bool) -> anyhow::Result<()> { - // stub! - Ok(()) + fn window_set_visible(&mut self, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()> { + match self.windows.get_mut(&EmuWindowHandle { + generation: handle.generation, + idx: handle.idx, + }) { + Some(w) => { + w.visible = visible; + Ok(()) + } + None => anyhow::bail!("Window not found"), + } } fn recenter_playspace(&mut self) -> anyhow::Result<()> { diff --git a/wlx-overlay-s/Cargo.toml b/wlx-overlay-s/Cargo.toml index 75e0a36..13762a8 100644 --- a/wlx-overlay-s/Cargo.toml +++ b/wlx-overlay-s/Cargo.toml @@ -81,7 +81,7 @@ tracing = "0.1.43" vulkano = { workspace = true } vulkano-shaders = { workspace = true } wgui = { path = "../wgui" } -wayvr_ipc = { workspace = true } +wayvr-ipc = { path = "../wayvr-ipc", default-features = false } bytes = { version = "1.11.0" } ################################