process_list::View done
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -6301,7 +6301,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "wayvr_ipc"
|
name = "wayvr_ipc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/olekolek1000/wayvr-ipc.git?rev=a72587d23f3bb8624d9aeb1f13c0a21e65350f51#a72587d23f3bb8624d9aeb1f13c0a21e65350f51"
|
source = "git+https://github.com/olekolek1000/wayvr-ipc.git?rev=6d253ef9e36db0f181566030a4990454ecb60395#6d253ef9e36db0f181566030a4990454ecb60395"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|||||||
@@ -34,4 +34,4 @@ vulkano = { version = "0.35.2", default-features = false, features = [
|
|||||||
] }
|
] }
|
||||||
vulkano-shaders = "0.35.0"
|
vulkano-shaders = "0.35.0"
|
||||||
wayland-client = { version = "0.31.11" }
|
wayland-client = { version = "0.31.11" }
|
||||||
wayvr_ipc = { git = "https://github.com/olekolek1000/wayvr-ipc.git", rev = "a72587d23f3bb8624d9aeb1f13c0a21e65350f51", default-features = false }
|
wayvr_ipc = { git = "https://github.com/olekolek1000/wayvr-ipc.git", rev = "6d253ef9e36db0f181566030a4990454ecb60395", default-features = false }
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
tooltip="${tooltip}"
|
tooltip="${tooltip}"
|
||||||
tooltip_side="${tooltip_side}"
|
tooltip_side="${tooltip_side}"
|
||||||
>
|
>
|
||||||
<sprite src="${src}" width="~side_sprite_size" height="~side_sprite_size" />
|
<sprite src_builtin="${src_builtin}" width="~side_sprite_size" height="~side_sprite_size" />
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -46,13 +46,13 @@
|
|||||||
align_items="center"
|
align_items="center"
|
||||||
gap="4"
|
gap="4"
|
||||||
>
|
>
|
||||||
<SideButton id="btn_side_home" src="dashboard/wayvr_dashboard_mono.svg" tooltip="HOME_SCREEN" tooltip_side="right" />
|
<SideButton id="btn_side_home" src_builtin="dashboard/wayvr_dashboard_mono.svg" tooltip="HOME_SCREEN" tooltip_side="right" />
|
||||||
<SideButton id="btn_side_apps" src="dashboard/apps.svg" tooltip="APPLICATIONS" tooltip_side="right" />
|
<SideButton id="btn_side_apps" src_builtin="dashboard/apps.svg" tooltip="APPLICATIONS" tooltip_side="right" />
|
||||||
<SideButton id="btn_side_games" src="dashboard/games.svg" tooltip="GAMES" tooltip_side="right" />
|
<SideButton id="btn_side_games" src_builtin="dashboard/games.svg" tooltip="GAMES" tooltip_side="right" />
|
||||||
<SideButton id="btn_side_monado" src="dashboard/monado.svg" tooltip="MONADO_RUNTIME" tooltip_side="right" />
|
<SideButton id="btn_side_monado" src_builtin="dashboard/monado.svg" tooltip="MONADO_RUNTIME" tooltip_side="right" />
|
||||||
<SideButton id="btn_side_processes" src="dashboard/window.svg" tooltip="PROCESSES" tooltip_side="right" />
|
<SideButton id="btn_side_processes" src_builtin="dashboard/window.svg" tooltip="PROCESSES" tooltip_side="right" />
|
||||||
<rectangle height="2" color="#FFFFFF33" width="~side_sprite_size" />
|
<rectangle height="2" color="#FFFFFF33" width="~side_sprite_size" />
|
||||||
<SideButton id="btn_side_settings" src="dashboard/settings.svg" tooltip="SETTINGS" tooltip_side="right" />
|
<SideButton id="btn_side_settings" src_builtin="dashboard/settings.svg" tooltip="SETTINGS" tooltip_side="right" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</div>
|
</div>
|
||||||
<!-- REST -->
|
<!-- REST -->
|
||||||
@@ -130,10 +130,10 @@
|
|||||||
<!-- Left bottom side -->
|
<!-- Left bottom side -->
|
||||||
<div margin_left="8">
|
<div margin_left="8">
|
||||||
<Button id="btn_audio" color="#FFFFFF00" border_color="#FFFFFF00" tooltip="AUDIO.VOLUME" tooltip_side="top">
|
<Button id="btn_audio" color="#FFFFFF00" border_color="#FFFFFF00" tooltip="AUDIO.VOLUME" tooltip_side="top">
|
||||||
<sprite src="dashboard/volume.svg" width="24" height="24" margin="8" />
|
<sprite src_builtin="dashboard/volume.svg" width="24" height="24" margin="8" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button id="btn_recenter" color="#FFFFFF00" border_color="#FFFFFF00" tooltip="ACTIONS.RECENTER_PLAYSPACE" tooltip_side="top">
|
<Button id="btn_recenter" color="#FFFFFF00" border_color="#FFFFFF00" tooltip="ACTIONS.RECENTER_PLAYSPACE" tooltip_side="top">
|
||||||
<sprite src="dashboard/recenter.svg" width="24" height="24" margin="8" />
|
<sprite src_builtin="dashboard/recenter.svg" width="24" height="24" margin="8" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<!-- src, text, translation -->
|
<!-- src, text, translation -->
|
||||||
<template name="GroupBoxTitle">
|
<template name="GroupBoxTitle">
|
||||||
<div flex_direction="row" align_items="center" gap="8">
|
<div flex_direction="row" align_items="center" gap="8">
|
||||||
<sprite src="${src}" width="24" height="24" />
|
<sprite src="${src}" src_builtin="${src_builtin}" width="24" height="24" />
|
||||||
<label text="${text}" translation="${translation}" weight="bold" size="18" />
|
<label text="${text}" translation="${translation}" weight="bold" size="18" />
|
||||||
</div>
|
</div>
|
||||||
<rectangle color="#FFFFFF44" width="100%" height="2" />
|
<rectangle color="#FFFFFF44" width="100%" height="2" />
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
align_items="center"
|
align_items="center"
|
||||||
justify_content="center"
|
justify_content="center"
|
||||||
flex_direction="column">
|
flex_direction="column">
|
||||||
<sprite src="${icon}" width="32" height="32" />
|
<sprite src_builtin="${icon}" width="32" height="32" />
|
||||||
<label weight="bold" size="18" text="${text}" translation="${translation}" />
|
<label weight="bold" size="18" text="${text}" translation="${translation}" />
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -19,12 +19,12 @@
|
|||||||
<!-- placeholders for now -->
|
<!-- placeholders for now -->
|
||||||
<div gap="4" align_items="center">
|
<div gap="4" align_items="center">
|
||||||
<Button width="48" height="38">
|
<Button width="48" height="38">
|
||||||
<sprite src="dashboard/alphabetical.svg" width="24" height="24" />
|
<sprite src_builtin="dashboard/alphabetical.svg" width="24" height="24" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button width="48" height="38">
|
<Button width="48" height="38">
|
||||||
<sprite src="dashboard/category_search.svg" width="24" height="24" />
|
<sprite src_builtin="dashboard/category_search.svg" width="24" height="24" />
|
||||||
</Button>
|
</Button>
|
||||||
<sprite src="dashboard/search.svg" width="24" height="24" />
|
<sprite src_builtin="dashboard/search.svg" width="24" height="24" />
|
||||||
<!-- placeholder editbox -->
|
<!-- placeholder editbox -->
|
||||||
<rectangle flex_grow="1" height="100%" color="#1d2e51" border_color="#294774" border="2" round="4" align_items="center" padding_left="12">
|
<rectangle flex_grow="1" height="100%" color="#1d2e51" border_color="#294774" border="2" round="4" align_items="center" padding_left="12">
|
||||||
<label text="Search" color="#FFFFFF88" weight="bold" />
|
<label text="Search" color="#FFFFFF88" weight="bold" />
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
align_items="center"
|
align_items="center"
|
||||||
flex_grow="1"
|
flex_grow="1"
|
||||||
gap="24">
|
gap="24">
|
||||||
<sprite src="dashboard/wayvr_dashboard.svg" width="96" height="96" />
|
<sprite src_builtin="dashboard/wayvr_dashboard.svg" width="96" height="96" />
|
||||||
<label id="label_hello" size="32" weight="bold" />
|
<label id="label_hello" size="32" weight="bold" />
|
||||||
|
|
||||||
<!-- main button list -->
|
<!-- main button list -->
|
||||||
|
|||||||
@@ -5,5 +5,6 @@
|
|||||||
<TabTitle translation="LIST_OF_DISPLAYS" icon="dashboard/window.svg" />
|
<TabTitle translation="LIST_OF_DISPLAYS" icon="dashboard/window.svg" />
|
||||||
<div id="display_list_parent" />
|
<div id="display_list_parent" />
|
||||||
<TabTitle translation="LIST_OF_PROCESSES" icon="dashboard/cpu.svg" />
|
<TabTitle translation="LIST_OF_PROCESSES" icon="dashboard/cpu.svg" />
|
||||||
|
<div id="process_list_parent" />
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -5,37 +5,36 @@
|
|||||||
<elements>
|
<elements>
|
||||||
<TabTitle translation="SETTINGS" icon="dashboard/settings.svg" />
|
<TabTitle translation="SETTINGS" icon="dashboard/settings.svg" />
|
||||||
|
|
||||||
|
|
||||||
<div flex_wrap="wrap" justify_content="stretch" gap="4">
|
<div flex_wrap="wrap" justify_content="stretch" gap="4">
|
||||||
<!-- Home screen -->
|
<!-- Home screen -->
|
||||||
<rectangle macro="group_box">
|
<rectangle macro="group_box">
|
||||||
<GroupBoxTitle translation="HOME_SCREEN" src="dashboard/wayvr_dashboard.svg" />
|
<GroupBoxTitle translation="HOME_SCREEN" src_builtin="dashboard/wayvr_dashboard.svg" />
|
||||||
<CheckBox id="cb_hide_username" translation="APP_SETTINGS.HIDE_USERNAME" />
|
<CheckBox id="cb_hide_username" translation="APP_SETTINGS.HIDE_USERNAME" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
|
|
||||||
<!-- General settings -->
|
<!-- General settings -->
|
||||||
<rectangle macro="group_box">
|
<rectangle macro="group_box">
|
||||||
<GroupBoxTitle translation="GENERAL_SETTINGS" src="dashboard/settings.svg" />
|
<GroupBoxTitle translation="GENERAL_SETTINGS" src_builtin="dashboard/settings.svg" />
|
||||||
<CheckBox id="cb_am_pm_clock" text="AM/PM clock" />
|
<CheckBox id="cb_am_pm_clock" text="AM/PM clock" />
|
||||||
<CheckBox id="cb_opaque_background" translation="APP_SETTINGS.OPAQUE_BACKGROUND" />
|
<CheckBox id="cb_opaque_background" translation="APP_SETTINGS.OPAQUE_BACKGROUND" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
|
|
||||||
<!-- Application launcher -->
|
<!-- Application launcher -->
|
||||||
<rectangle macro="group_box">
|
<rectangle macro="group_box">
|
||||||
<GroupBoxTitle translation="APPLICATION_LAUNCHER" src="dashboard/apps.svg" />
|
<GroupBoxTitle translation="APPLICATION_LAUNCHER" src_builtin="dashboard/apps.svg" />
|
||||||
<CheckBox id="cb_xwayland_by_default" translation="APP_SETTINGS.RUN_IN_XWAYLAND_MODE_BY_DEFAULT" />
|
<CheckBox id="cb_xwayland_by_default" translation="APP_SETTINGS.RUN_IN_XWAYLAND_MODE_BY_DEFAULT" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
|
|
||||||
<!-- headset settings -->
|
<!-- headset settings -->
|
||||||
<rectangle macro="group_box">
|
<rectangle macro="group_box">
|
||||||
<GroupBoxTitle translation="APP_SETTINGS.HEADSET_SETTINGS" src="dashboard/vr.svg" />
|
<GroupBoxTitle translation="APP_SETTINGS.HEADSET_SETTINGS" src_builtin="dashboard/vr.svg" />
|
||||||
<label translation="APP_SETTINGS.BRIGHTNESS" />
|
<label translation="APP_SETTINGS.BRIGHTNESS" />
|
||||||
<Slider width="100" height="24" min_value="0.0" max_value="100.0" />
|
<Slider width="100" height="24" min_value="0.0" max_value="100.0" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
|
|
||||||
<!-- wlx-overlay-s settings -->
|
<!-- wlx-overlay-s settings -->
|
||||||
<rectangle macro="group_box">
|
<rectangle macro="group_box">
|
||||||
<GroupBoxTitle translation="APP_SETTINGS.WLX_OVERLAY_S_SETTINGS" src="dashboard/vr.svg" />
|
<GroupBoxTitle translation="APP_SETTINGS.WLX_OVERLAY_S_SETTINGS" src_builtin="dashboard/vr.svg" />
|
||||||
<CheckBox translation="APP_SETTINGS.WLX.NOTIFICATIONS_ENABLED" />
|
<CheckBox translation="APP_SETTINGS.WLX.NOTIFICATIONS_ENABLED" />
|
||||||
<CheckBox translation="APP_SETTINGS.WLX.NOTIFICATIONS_SOUND_ENABLED" />
|
<CheckBox translation="APP_SETTINGS.WLX.NOTIFICATIONS_SOUND_ENABLED" />
|
||||||
<CheckBox translation="APP_SETTINGS.WLX.KEYBOARD_SOUND_ENABLED" />
|
<CheckBox translation="APP_SETTINGS.WLX.KEYBOARD_SOUND_ENABLED" />
|
||||||
@@ -49,13 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- TODO: icon support in buttons -->
|
<Button color="#AA3333" height="32" sprite_src_builtin="dashboard/refresh.svg" translation="APP_SETTINGS.RESTART_SOFTWARE" />
|
||||||
<Button color="#AA3333" height="32">
|
|
||||||
<div margin_left="8" margin_right="8" gap="4" align_items="center">
|
|
||||||
<sprite src="dashboard/refresh.svg" width="24" height="24" />
|
|
||||||
<label weight="bold" translation="APP_SETTINGS.RESTART_SOFTWARE" />
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<!-- translation, icon -->
|
<!-- translation, icon -->
|
||||||
<template name="TabTitle">
|
<template name="TabTitle">
|
||||||
<div gap="8" align_items="center">
|
<div gap="8" align_items="center">
|
||||||
<sprite src="${icon}" width="24" height="24" />
|
<sprite src_builtin="${icon}" width="24" height="24" />
|
||||||
<label translation="${translation}" size="18" weight="bold" />
|
<label translation="${translation}" size="18" weight="bold" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<template name="SelectAudioProfileText">
|
<template name="SelectAudioProfileText">
|
||||||
<div align_items="center" gap="8">
|
<div align_items="center" gap="8">
|
||||||
<Button width="48" height="32" id="btn_back">
|
<Button width="48" height="32" id="btn_back">
|
||||||
<sprite src="dashboard/back.svg" width="24" height="24" />
|
<sprite src_builtin="dashboard/back.svg" width="24" height="24" />
|
||||||
</Button>
|
</Button>
|
||||||
<label translation="AUDIO.SELECT_AUDIO_CARD_PROFILE" size="14" weight="bold" />
|
<label translation="AUDIO.SELECT_AUDIO_CARD_PROFILE" size="14" weight="bold" />
|
||||||
</div>
|
</div>
|
||||||
@@ -54,15 +54,15 @@
|
|||||||
<div flex_direction="row" gap="4">
|
<div flex_direction="row" gap="4">
|
||||||
<Button
|
<Button
|
||||||
id="btn_auto"
|
id="btn_auto"
|
||||||
sprite_src="dashboard/magic_wand.svg"
|
sprite_src_builtin="dashboard/magic_wand.svg"
|
||||||
min_width="32"
|
min_width="32"
|
||||||
tooltip="AUDIO.AUTO_SWITCH_TO_VR_AUDIO"
|
tooltip="AUDIO.AUTO_SWITCH_TO_VR_AUDIO"
|
||||||
color="~color_accent"
|
color="~color_accent"
|
||||||
tooltip_side="right" />
|
tooltip_side="right" />
|
||||||
|
|
||||||
<BottomButton id="btn_sinks" src="dashboard/volume.svg" translation="AUDIO.SPEAKERS" />
|
<BottomButton id="btn_sinks" src_builtin="dashboard/volume.svg" translation="AUDIO.SPEAKERS" />
|
||||||
<BottomButton id="btn_sources" src="dashboard/microphone.svg" translation="AUDIO.MICROPHONES" />
|
<BottomButton id="btn_sources" src_builtin="dashboard/microphone.svg" translation="AUDIO.MICROPHONES" />
|
||||||
<BottomButton id="btn_cards" src="dashboard/cpu.svg" translation="AUDIO.CARDS" />
|
<BottomButton id="btn_cards" src_builtin="dashboard/cpu.svg" translation="AUDIO.CARDS" />
|
||||||
</div>
|
</div>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
9
dash-frontend/assets/gui/view/process_list.xml
Normal file
9
dash-frontend/assets/gui/view/process_list.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<layout>
|
||||||
|
<include src="../t_group_box.xml" />
|
||||||
|
|
||||||
|
<elements>
|
||||||
|
<rectangle macro="group_box" flex_direction="row" align_items="center">
|
||||||
|
<div id="list_parent" gap="8" flex_direction="row" flex_wrap="wrap" flex_grow="1" />
|
||||||
|
</rectangle>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
@@ -59,5 +59,9 @@
|
|||||||
"HIDE": "Verbergen",
|
"HIDE": "Verbergen",
|
||||||
"REMOVE": "Entfernen",
|
"REMOVE": "Entfernen",
|
||||||
"SHOW": "Anzeigen",
|
"SHOW": "Anzeigen",
|
||||||
"DISPLAY_OPTIONS": "Anzeigeeinstellungen"
|
"DISPLAY_OPTIONS": "Anzeigeeinstellungen",
|
||||||
|
"PROCESS_LIST": {
|
||||||
|
"NO_PROCESSES_FOUND": "Keine Prozesse gefunden",
|
||||||
|
"LOCATED_ON": "auf"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -55,6 +55,11 @@
|
|||||||
"POPUP_ADD_DISPLAY": {
|
"POPUP_ADD_DISPLAY": {
|
||||||
"RESOLUTION": "Resolution"
|
"RESOLUTION": "Resolution"
|
||||||
},
|
},
|
||||||
|
"PROCESS_LIST": {
|
||||||
|
"LOCATED_ON": "on",
|
||||||
|
"NO_PROCESSES_FOUND": "No processes found",
|
||||||
|
"TERMINATE_PROCESS_NAMED_X": "Terminate process \"{PROCESS_NAME}\""
|
||||||
|
},
|
||||||
"PROCESSES": "Processes",
|
"PROCESSES": "Processes",
|
||||||
"REMOVE": "Remove",
|
"REMOVE": "Remove",
|
||||||
"SETTINGS": "Settings",
|
"SETTINGS": "Settings",
|
||||||
|
|||||||
@@ -59,5 +59,9 @@
|
|||||||
"HIDE": "Ocultar",
|
"HIDE": "Ocultar",
|
||||||
"REMOVE": "Eliminar",
|
"REMOVE": "Eliminar",
|
||||||
"SHOW": "Mostrar",
|
"SHOW": "Mostrar",
|
||||||
"DISPLAY_OPTIONS": "Opciones de pantalla"
|
"DISPLAY_OPTIONS": "Opciones de pantalla",
|
||||||
|
"PROCESS_LIST": {
|
||||||
|
"NO_PROCESSES_FOUND": "No se encontraron procesos",
|
||||||
|
"LOCATED_ON": "en"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -59,5 +59,9 @@
|
|||||||
"HIDE": "隠す",
|
"HIDE": "隠す",
|
||||||
"REMOVE": "削除",
|
"REMOVE": "削除",
|
||||||
"SHOW": "表示",
|
"SHOW": "表示",
|
||||||
"DISPLAY_OPTIONS": "表示オプション"
|
"DISPLAY_OPTIONS": "表示オプション",
|
||||||
|
"PROCESS_LIST": {
|
||||||
|
"NO_PROCESSES_FOUND": "プロセスが見つかりませんでした",
|
||||||
|
"LOCATED_ON": "に"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -59,5 +59,9 @@
|
|||||||
"SETTINGS": "Ustawienia",
|
"SETTINGS": "Ustawienia",
|
||||||
"SHOW": "Pokaż",
|
"SHOW": "Pokaż",
|
||||||
"WIDTH": "Szerokość",
|
"WIDTH": "Szerokość",
|
||||||
"PROCESSES": "Procesy"
|
"PROCESSES": "Procesy",
|
||||||
|
"PROCESS_LIST": {
|
||||||
|
"NO_PROCESSES_FOUND": "Nie znaleziono procesów",
|
||||||
|
"LOCATED_ON": "na"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -429,7 +429,7 @@ impl Frontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn action_recenter_playspace(&mut self) -> anyhow::Result<()> {
|
fn action_recenter_playspace(&mut self) -> anyhow::Result<()> {
|
||||||
log::info!("todo");
|
self.interface.recenter_playspace()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use wgui::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
tab::{Tab, TabParams, TabType, TabUpdateParams},
|
tab::{Tab, TabParams, TabType, TabUpdateParams},
|
||||||
views::display_list,
|
views::{display_list, process_list},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TabProcesses {
|
pub struct TabProcesses {
|
||||||
@@ -13,6 +13,7 @@ pub struct TabProcesses {
|
|||||||
pub state: ParserState,
|
pub state: ParserState,
|
||||||
|
|
||||||
view_display_list: display_list::View,
|
view_display_list: display_list::View,
|
||||||
|
view_process_list: process_list::View,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tab for TabProcesses {
|
impl Tab for TabProcesses {
|
||||||
@@ -22,6 +23,7 @@ impl Tab for TabProcesses {
|
|||||||
|
|
||||||
fn update(&mut self, params: TabUpdateParams) -> anyhow::Result<()> {
|
fn update(&mut self, params: TabUpdateParams) -> anyhow::Result<()> {
|
||||||
self.view_display_list.update(params.layout, params.interface)?;
|
self.view_display_list.update(params.layout, params.interface)?;
|
||||||
|
self.view_process_list.update(params.layout, params.interface)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,6 +47,12 @@ impl TabProcesses {
|
|||||||
globals: params.globals.clone(),
|
globals: params.globals.clone(),
|
||||||
frontend_tasks: params.frontend_tasks.clone(),
|
frontend_tasks: params.frontend_tasks.clone(),
|
||||||
})?,
|
})?,
|
||||||
|
view_process_list: process_list::View::new(process_list::Params {
|
||||||
|
layout: params.layout,
|
||||||
|
parent_id: state.get_widget_id("process_list_parent")?,
|
||||||
|
globals: params.globals.clone(),
|
||||||
|
frontend_tasks: params.frontend_tasks.clone(),
|
||||||
|
})?,
|
||||||
state,
|
state,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
use gio::prelude::{AppInfoExt, IconExt};
|
use gio::prelude::{AppInfoExt, IconExt};
|
||||||
use gtk::traits::IconThemeExt;
|
use gtk::traits::IconThemeExt;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
// compatibility with wayvr-ipc
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct DesktopFile {
|
||||||
|
pub name: String,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub exec_path: String,
|
||||||
|
pub exec_args: Vec<String>,
|
||||||
|
pub categories: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[allow(dead_code)] // TODO: remove this
|
#[allow(dead_code)] // TODO: remove this
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ pub mod desktop_finder;
|
|||||||
pub mod pactl_wrapper;
|
pub mod pactl_wrapper;
|
||||||
pub mod popup_manager;
|
pub mod popup_manager;
|
||||||
pub mod toast_manager;
|
pub mod toast_manager;
|
||||||
|
pub mod various;
|
||||||
|
|||||||
93
dash-frontend/src/util/various.rs
Normal file
93
dash-frontend/src/util/various.rs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
use std::{path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
|
use wayvr_ipc::packet_server;
|
||||||
|
use wgui::{
|
||||||
|
assets::{AssetPath, AssetPathOwned},
|
||||||
|
globals::WguiGlobals,
|
||||||
|
i18n::Translation,
|
||||||
|
layout::{Layout, WidgetID},
|
||||||
|
renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
||||||
|
taffy::{self, prelude::length},
|
||||||
|
widget::{
|
||||||
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
|
sprite::{WidgetSprite, WidgetSpriteParams},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use wlx_common::dash_interface::BoxDashInterface;
|
||||||
|
|
||||||
|
use crate::util::desktop_finder;
|
||||||
|
|
||||||
|
pub fn get_desktop_file_icon_path(desktop_file: &desktop_finder::DesktopFile) -> AssetPathOwned {
|
||||||
|
/*
|
||||||
|
FIXME: why is the compiler complaining about trailing irrefutable patterns there?!?!
|
||||||
|
looking at the PathBuf::from_str implementation, it always returns Ok() and it's inline, maybe that's why.
|
||||||
|
*/
|
||||||
|
if let Some(icon) = &desktop_file.icon
|
||||||
|
&& let Ok(path) = PathBuf::from_str(icon)
|
||||||
|
{
|
||||||
|
return AssetPathOwned::File(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetPathOwned::BuiltIn(PathBuf::from_str("dashboard/terminal.svg").unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_all_windows(interface: &mut BoxDashInterface) -> anyhow::Result<Vec<packet_server::WvrWindow>> {
|
||||||
|
let mut windows = Vec::<packet_server::WvrWindow>::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,
|
||||||
|
parent_id: WidgetID,
|
||||||
|
translation: Translation,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
layout.add_child(
|
||||||
|
parent_id,
|
||||||
|
WidgetLabel::create(
|
||||||
|
&mut globals.get(),
|
||||||
|
WidgetLabelParams {
|
||||||
|
content: translation,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
taffy::Style::default(),
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mount_simple_sprite_square(
|
||||||
|
globals: &WguiGlobals,
|
||||||
|
layout: &mut Layout,
|
||||||
|
parent_id: WidgetID,
|
||||||
|
size_px: f32,
|
||||||
|
path: AssetPath,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
layout.add_child(
|
||||||
|
parent_id,
|
||||||
|
WidgetSprite::create(WidgetSpriteParams {
|
||||||
|
glyph_data: Some(CustomGlyphData::new(CustomGlyphContent::from_assets(globals, path)?)),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
taffy::Style {
|
||||||
|
size: taffy::Size {
|
||||||
|
width: length(size_px),
|
||||||
|
height: length(size_px),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -3,3 +3,4 @@ pub mod app_launcher;
|
|||||||
pub mod audio_settings;
|
pub mod audio_settings;
|
||||||
pub mod display_list;
|
pub mod display_list;
|
||||||
pub mod display_options;
|
pub mod display_options;
|
||||||
|
pub mod process_list;
|
||||||
|
|||||||
310
dash-frontend/src/views/process_list.rs
Normal file
310
dash-frontend/src/views/process_list.rs
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use wayvr_ipc::packet_server::{self};
|
||||||
|
use wgui::{
|
||||||
|
assets::AssetPath,
|
||||||
|
components::{
|
||||||
|
self,
|
||||||
|
button::ComponentButton,
|
||||||
|
tooltip::{TooltipInfo, TooltipSide},
|
||||||
|
},
|
||||||
|
globals::WguiGlobals,
|
||||||
|
i18n::Translation,
|
||||||
|
layout::{Layout, WidgetID},
|
||||||
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
|
taffy::{self, prelude::length},
|
||||||
|
widget::{
|
||||||
|
ConstructEssentials,
|
||||||
|
div::WidgetDiv,
|
||||||
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use wlx_common::dash_interface::BoxDashInterface;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
frontend::FrontendTasks,
|
||||||
|
task::Tasks,
|
||||||
|
util::{
|
||||||
|
self,
|
||||||
|
desktop_finder::{self},
|
||||||
|
various::get_desktop_file_icon_path,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Task {
|
||||||
|
Refresh,
|
||||||
|
TerminateProcess(packet_server::WvrProcess),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Params<'a> {
|
||||||
|
pub globals: WguiGlobals,
|
||||||
|
pub frontend_tasks: FrontendTasks,
|
||||||
|
pub layout: &'a mut Layout,
|
||||||
|
pub parent_id: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct View {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub parser_state: ParserState,
|
||||||
|
tasks: Tasks<Task>,
|
||||||
|
frontend_tasks: FrontendTasks,
|
||||||
|
globals: WguiGlobals,
|
||||||
|
id_list_parent: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View {
|
||||||
|
pub fn new(params: Params) -> anyhow::Result<Self> {
|
||||||
|
let doc_params = &ParseDocumentParams {
|
||||||
|
globals: params.globals.clone(),
|
||||||
|
path: AssetPath::BuiltIn("gui/view/process_list.xml"),
|
||||||
|
extra: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let parser_state = wgui::parser::parse_from_assets(doc_params, params.layout, params.parent_id)?;
|
||||||
|
let list_parent = parser_state.fetch_widget(¶ms.layout.state, "list_parent")?;
|
||||||
|
|
||||||
|
let tasks = Tasks::new();
|
||||||
|
|
||||||
|
tasks.push(Task::Refresh);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
parser_state,
|
||||||
|
tasks,
|
||||||
|
frontend_tasks: params.frontend_tasks,
|
||||||
|
globals: params.globals,
|
||||||
|
id_list_parent: list_parent.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, layout: &mut Layout, interface: &mut BoxDashInterface) -> anyhow::Result<()> {
|
||||||
|
loop {
|
||||||
|
let tasks = self.tasks.drain();
|
||||||
|
if tasks.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for task in tasks {
|
||||||
|
match task {
|
||||||
|
Task::Refresh => self.refresh(layout, interface)?,
|
||||||
|
Task::TerminateProcess(process) => self.terminate_process(interface, process)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_desktop_file_from_process(
|
||||||
|
windows: &Vec<packet_server::WvrWindow>,
|
||||||
|
process: &packet_server::WvrProcess,
|
||||||
|
) -> Option<desktop_finder::DesktopFile> {
|
||||||
|
for window in windows {
|
||||||
|
if window.process_handle != process.handle {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: refactor this after we ditch wayvr-ipc completely
|
||||||
|
let Some(dfile_str) = process.userdata.get("desktop_file") else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(desktop_file) = serde_json::from_str::<desktop_finder::DesktopFile>(dfile_str) else {
|
||||||
|
debug_assert!(false); // invalid json???
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Some(desktop_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ProcessEntryResult {
|
||||||
|
btn_terminate: Rc<ComponentButton>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn construct_process_entry(
|
||||||
|
ess: &mut ConstructEssentials,
|
||||||
|
globals: &WguiGlobals,
|
||||||
|
process: &packet_server::WvrProcess,
|
||||||
|
display: Option<&packet_server::WvrDisplay>,
|
||||||
|
all_windows: &Vec<packet_server::WvrWindow>,
|
||||||
|
) -> anyhow::Result<ProcessEntryResult> {
|
||||||
|
let (cell, _) = ess.layout.add_child(
|
||||||
|
ess.parent,
|
||||||
|
WidgetDiv::create(),
|
||||||
|
taffy::Style {
|
||||||
|
flex_direction: taffy::FlexDirection::Row,
|
||||||
|
align_items: Some(taffy::AlignItems::Center),
|
||||||
|
gap: length(8.0),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let text_terminate_process = Translation::from_raw_text_string(globals.i18n().translate_and_replace(
|
||||||
|
"PROCESS_LIST.TERMINATE_PROCESS_NAMED_X",
|
||||||
|
("{PROCESS_NAME}", &process.name),
|
||||||
|
));
|
||||||
|
|
||||||
|
//"Terminate process" button
|
||||||
|
let (_, btn_terminate) = components::button::construct(
|
||||||
|
&mut ConstructEssentials {
|
||||||
|
layout: ess.layout,
|
||||||
|
parent: cell.id,
|
||||||
|
},
|
||||||
|
components::button::Params {
|
||||||
|
sprite_src: Some(AssetPath::BuiltIn("dashboard/remove_circle.svg")),
|
||||||
|
tooltip: Some(TooltipInfo {
|
||||||
|
text: text_terminate_process,
|
||||||
|
side: TooltipSide::Right,
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if let Some(desktop_file) = get_desktop_file_from_process(all_windows, process) {
|
||||||
|
// desktop file icon and process name
|
||||||
|
util::various::mount_simple_sprite_square(
|
||||||
|
globals,
|
||||||
|
ess.layout,
|
||||||
|
cell.id,
|
||||||
|
24.0,
|
||||||
|
get_desktop_file_icon_path(&desktop_file).as_ref(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
util::various::mount_simple_label(
|
||||||
|
globals,
|
||||||
|
ess.layout,
|
||||||
|
cell.id,
|
||||||
|
Translation::from_raw_text_string(desktop_file.name.clone()),
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
// just show a process name
|
||||||
|
util::various::mount_simple_label(
|
||||||
|
globals,
|
||||||
|
ess.layout,
|
||||||
|
cell.id,
|
||||||
|
Translation::from_raw_text_string(process.name.clone()),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill_process_list(
|
||||||
|
globals: &WguiGlobals,
|
||||||
|
ess: &mut ConstructEssentials,
|
||||||
|
tasks: &Tasks<Task>,
|
||||||
|
list: &Vec<packet_server::WvrProcess>,
|
||||||
|
displays: &Vec<packet_server::WvrDisplay>,
|
||||||
|
all_windows: &Vec<packet_server::WvrWindow>,
|
||||||
|
) -> 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)?;
|
||||||
|
|
||||||
|
entry_res.btn_terminate.on_click({
|
||||||
|
let tasks = tasks.clone();
|
||||||
|
let entry = process_entry.clone();
|
||||||
|
Box::new(move |_, _| {
|
||||||
|
tasks.push(Task::TerminateProcess(entry.clone()));
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Translation> = None;
|
||||||
|
match interface.process_list() {
|
||||||
|
Ok(list) => {
|
||||||
|
if list.is_empty() {
|
||||||
|
text = Some(Translation::from_translation_key("PROCESS_LIST.NO_PROCESSES_FOUND"))
|
||||||
|
} else {
|
||||||
|
fill_process_list(
|
||||||
|
&self.globals,
|
||||||
|
&mut ConstructEssentials {
|
||||||
|
layout,
|
||||||
|
parent: self.id_list_parent,
|
||||||
|
},
|
||||||
|
&self.tasks,
|
||||||
|
&list,
|
||||||
|
&displays,
|
||||||
|
&all_windows,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => text = Some(Translation::from_raw_text(&format!("Error: {:?}", e))),
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(text) = text.take() {
|
||||||
|
layout.add_child(
|
||||||
|
self.id_list_parent,
|
||||||
|
WidgetLabel::create(
|
||||||
|
&mut self.globals.get(),
|
||||||
|
WidgetLabelParams {
|
||||||
|
content: text,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Default::default(),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn terminate_process(
|
||||||
|
&mut self,
|
||||||
|
interface: &mut BoxDashInterface,
|
||||||
|
process: packet_server::WvrProcess,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
interface.process_terminate(process.handle)?;
|
||||||
|
self.tasks.push(Task::Refresh);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -443,7 +443,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
if let Some(sprite_path) = params.sprite_src {
|
if let Some(sprite_path) = params.sprite_src {
|
||||||
let sprite = WidgetSprite::create(WidgetSpriteParams {
|
let sprite = WidgetSprite::create(WidgetSpriteParams {
|
||||||
glyph_data: Some(CustomGlyphData::new(CustomGlyphContent::from_assets(
|
glyph_data: Some(CustomGlyphData::new(CustomGlyphContent::from_assets(
|
||||||
&mut globals,
|
&globals,
|
||||||
sprite_path,
|
sprite_path,
|
||||||
)?)),
|
)?)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -457,7 +457,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
width: length(20.0),
|
width: length(20.0),
|
||||||
height: length(20.0),
|
height: length(20.0),
|
||||||
},
|
},
|
||||||
margin: default_margin.clone(),
|
margin: default_margin,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pub fn parse_widget_sprite<'a>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if !value.is_empty() {
|
if !value.is_empty() {
|
||||||
glyph = match CustomGlyphContent::from_assets(&mut ctx.layout.state.globals, asset_path) {
|
glyph = match CustomGlyphContent::from_assets(&ctx.layout.state.globals, asset_path) {
|
||||||
Ok(glyph) => Some(glyph),
|
Ok(glyph) => Some(glyph),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("failed to load {value}: {e}");
|
log::warn!("failed to load {value}: {e}");
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ impl CustomGlyphContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::case_sensitive_file_extension_comparisons)]
|
#[allow(clippy::case_sensitive_file_extension_comparisons)]
|
||||||
pub fn from_assets(globals: &mut WguiGlobals, path: AssetPath) -> anyhow::Result<Self> {
|
pub fn from_assets(globals: &WguiGlobals, path: AssetPath) -> anyhow::Result<Self> {
|
||||||
let path_str = path.get_str();
|
let path_str = path.get_str();
|
||||||
let data = globals.get_asset(path)?;
|
let data = globals.get_asset(path)?;
|
||||||
if path_str.ends_with(".svg") || path_str.ends_with(".svgz") {
|
if path_str.ends_with(".svg") || path_str.ends_with(".svgz") {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ pub trait DashInterface {
|
|||||||
fn process_list(&mut self) -> anyhow::Result<Vec<WvrProcess>>;
|
fn process_list(&mut self) -> anyhow::Result<Vec<WvrProcess>>;
|
||||||
fn process_terminate(&mut self, handle: WvrProcessHandle) -> anyhow::Result<()>;
|
fn process_terminate(&mut self, handle: WvrProcessHandle) -> anyhow::Result<()>;
|
||||||
fn window_set_visible(&mut self, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()>;
|
fn window_set_visible(&mut self, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()>;
|
||||||
|
fn recenter_playspace(&mut self) -> anyhow::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BoxDashInterface = Box<dyn DashInterface>;
|
pub type BoxDashInterface = Box<dyn DashInterface>;
|
||||||
|
|||||||
@@ -61,10 +61,25 @@ pub struct DashInterfaceEmulated {
|
|||||||
|
|
||||||
impl DashInterfaceEmulated {
|
impl DashInterfaceEmulated {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
let mut displays = EmuDisplayVec::new();
|
||||||
displays: EmuDisplayVec::new(),
|
let disp_handle = displays.add(EmuDisplay {
|
||||||
processes: EmuProcessVec::new(),
|
width: 1280,
|
||||||
}
|
height: 720,
|
||||||
|
layout: WvrDisplayWindowLayout::Tiling,
|
||||||
|
name: String::from("Emulated display"),
|
||||||
|
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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,4 +185,9 @@ impl DashInterface for DashInterfaceEmulated {
|
|||||||
// stub!
|
// stub!
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn recenter_playspace(&mut self) -> anyhow::Result<()> {
|
||||||
|
// stub!
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user