Monado app switcher, lang update
This commit is contained in:
@@ -1,7 +1,35 @@
|
||||
<layout>
|
||||
<include src="t_tab_title.xml" />
|
||||
<include src="../t_group_box.xml" />
|
||||
|
||||
|
||||
<!-- key: str, value: str -->
|
||||
<template name="BoolFlag">
|
||||
<div flex_direction="row" gap="4">
|
||||
<label text="${key}" />
|
||||
<label weight="bold" text="${value}" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- name, checked, flag_* -->
|
||||
<template name="Cell">
|
||||
<rectangle macro="group_box">
|
||||
<CheckBox id="checkbox" text="${name}" checked="${checked}" />
|
||||
<div flex_direction="row" gap="8">
|
||||
<BoolFlag key="Active:" value="${flag_active}" />
|
||||
<BoolFlag key="Focused:" value="${flag_focused}" />
|
||||
<BoolFlag key="IO active:" value="${flag_io_active}" />
|
||||
<BoolFlag key="Overlay:" value="${flag_overlay}" />
|
||||
<BoolFlag key="Primary:" value="${flag_primary}" />
|
||||
<BoolFlag key="Visible:" value="${flag_visible}" />
|
||||
</div>
|
||||
</rectangle>
|
||||
</template>
|
||||
|
||||
<elements>
|
||||
<TabTitle translation="MONADO_RUNTIME" icon="dashboard/monado.svg" />
|
||||
<div id="list_parent" flex_direction="column" gap="8">
|
||||
<!-- filled at runtime -->
|
||||
</div>
|
||||
</elements>
|
||||
</layout>
|
||||
@@ -14,11 +14,11 @@
|
||||
<include src="../t_group_box.xml" />
|
||||
|
||||
<elements>
|
||||
<div flex_direction="row" gap="16">
|
||||
<div flex_direction="row" gap="16" flex_grow="1">
|
||||
<rectangle macro="group_box" id="icon_parent" padding="16" color="#0033aa66" color2="#00000022" gradient="vertical" justify_content="center">
|
||||
|
||||
</rectangle>
|
||||
<div flex_direction="column" gap="8" min_width="720" max_width="720">
|
||||
<div flex_direction="column" gap="8" flex_grow="1">
|
||||
<label id="label_title" weight="bold" size="32" overflow="hidden" />
|
||||
<Subtext label_id="label_exec" overflow="hidden" />
|
||||
<Separator />
|
||||
@@ -61,4 +61,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</elements>
|
||||
</layout>
|
||||
</layout>
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"HOME_SCREEN": "Startbildschirm",
|
||||
"MONADO_RUNTIME": "„Monado”-Laufzeitumgebung",
|
||||
"MONADO_RUNTIME": "Monado-Laufzeitumgebung",
|
||||
"APPLICATIONS": "Anwendungen",
|
||||
"GAMES": "Spiele",
|
||||
"SETTINGS": "Einstellungen",
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
"HOME_SCREEN": "Home",
|
||||
"LIST_OF_PROCESSES": "Process list",
|
||||
"LIST_OF_WINDOWS": "Window list",
|
||||
"MONADO_RUNTIME": "„Monado” runtime",
|
||||
"MONADO_RUNTIME": "Monado runtime",
|
||||
"NO_WINDOWS_FOUND": "No windows found",
|
||||
"POPUP_ADD_DISPLAY": {
|
||||
"RESOLUTION": "Resolution"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"HOME_SCREEN": "Inicio",
|
||||
"MONADO_RUNTIME": "„Monado” tiempo de ejecución",
|
||||
"MONADO_RUNTIME": "Monado tiempo de ejecución",
|
||||
"APPLICATIONS": "Aplicaciones",
|
||||
"GAMES": "Juegos",
|
||||
"SETTINGS": "Ajustes",
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
"USE_SKYBOX_HELP": "Wyświetlaj niebo, jeśli nie ma aplikacji sceny lub passthrough",
|
||||
"USE_PASSTHROUGH_HELP": "Pozwól na passthrough, jeśli runtime XR to obsługuje",
|
||||
"SCREEN_RENDER_DOWN_HELP": "Pomaga redukować aliasing na ekranach o wysokiej rozdzielczości",
|
||||
"SETS_ON_WATCH": "Lista zestawówna zegarku",
|
||||
"SETS_ON_WATCH": "Lista zestawów na zegarku",
|
||||
"TROUBLESHOOTING": "Rozwiązywanie problemów",
|
||||
"CLEAR_SAVED_STATE": "Wyczyść zapisany stan",
|
||||
"CLEAR_PIPEWIRE_TOKENS": "Wyczyść tokeny PipeWire",
|
||||
|
||||
@@ -1,43 +1,163 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::{collections::HashMap, marker::PhantomData, rc::Rc};
|
||||
|
||||
use wgui::{
|
||||
assets::AssetPath,
|
||||
components::checkbox::ComponentCheckbox,
|
||||
globals::WguiGlobals,
|
||||
layout::WidgetID,
|
||||
parser::{ParseDocumentParams, ParserState},
|
||||
parser::{self, Fetchable, ParseDocumentParams, ParserState},
|
||||
task::Tasks,
|
||||
};
|
||||
use wlx_common::dash_interface;
|
||||
|
||||
use crate::{
|
||||
frontend::Frontend,
|
||||
tab::{Tab, TabType},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Task {
|
||||
Refresh,
|
||||
FocusClient(String),
|
||||
}
|
||||
|
||||
pub struct TabMonado<T> {
|
||||
#[allow(dead_code)]
|
||||
pub state: ParserState,
|
||||
state: ParserState,
|
||||
tasks: Tasks<Task>,
|
||||
|
||||
marker: PhantomData<T>,
|
||||
|
||||
globals: WguiGlobals,
|
||||
id_list_parent: WidgetID,
|
||||
|
||||
cells: Vec<parser::ParserData>,
|
||||
|
||||
ticks: u32,
|
||||
}
|
||||
|
||||
impl<T> Tab<T> for TabMonado<T> {
|
||||
fn get_type(&self) -> TabType {
|
||||
TabType::Games
|
||||
}
|
||||
|
||||
fn update(&mut self, frontend: &mut Frontend<T>, data: &mut T) -> anyhow::Result<()> {
|
||||
for task in self.tasks.drain() {
|
||||
match task {
|
||||
Task::Refresh => self.refresh(frontend, data)?,
|
||||
Task::FocusClient(name) => self.focus_client(frontend, data, name)?,
|
||||
}
|
||||
}
|
||||
|
||||
// every few seconds
|
||||
if self.ticks.is_multiple_of(500) {
|
||||
self.tasks.push(Task::Refresh);
|
||||
}
|
||||
|
||||
self.ticks += 1;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn doc_params(globals: &'_ WguiGlobals) -> ParseDocumentParams<'_> {
|
||||
ParseDocumentParams {
|
||||
globals: globals.clone(),
|
||||
path: AssetPath::BuiltIn("gui/tab/monado.xml"),
|
||||
extra: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn yesno(n: bool) -> &'static str {
|
||||
match n {
|
||||
true => "yes",
|
||||
false => "no",
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TabMonado<T> {
|
||||
pub fn new(frontend: &mut Frontend<T>, parent_id: WidgetID) -> anyhow::Result<Self> {
|
||||
let state = wgui::parser::parse_from_assets(
|
||||
&ParseDocumentParams {
|
||||
globals: frontend.layout.state.globals.clone(),
|
||||
path: AssetPath::BuiltIn("gui/tab/monado.xml"),
|
||||
extra: Default::default(),
|
||||
},
|
||||
&mut frontend.layout,
|
||||
parent_id,
|
||||
)?;
|
||||
let globals = frontend.layout.state.globals.clone();
|
||||
let state = wgui::parser::parse_from_assets(&doc_params(&globals), &mut frontend.layout, parent_id)?;
|
||||
|
||||
let id_list_parent = state.get_widget_id("list_parent")?;
|
||||
|
||||
let tasks = Tasks::<Task>::new();
|
||||
|
||||
tasks.push(Task::Refresh);
|
||||
|
||||
Ok(Self {
|
||||
state,
|
||||
marker: PhantomData,
|
||||
tasks,
|
||||
globals,
|
||||
id_list_parent,
|
||||
ticks: 0,
|
||||
cells: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
fn mount_client(&mut self, frontend: &mut Frontend<T>, client: &dash_interface::MonadoClient) -> anyhow::Result<()> {
|
||||
let mut par = HashMap::<Rc<str>, Rc<str>>::new();
|
||||
par.insert(
|
||||
"checked".into(),
|
||||
if client.is_primary {
|
||||
Rc::from("1")
|
||||
} else {
|
||||
Rc::from("0")
|
||||
},
|
||||
);
|
||||
par.insert("name".into(), client.name.clone().into());
|
||||
par.insert("flag_active".into(), yesno(client.is_active).into());
|
||||
par.insert("flag_focused".into(), yesno(client.is_focused).into());
|
||||
par.insert("flag_io_active".into(), yesno(client.is_io_active).into());
|
||||
par.insert("flag_overlay".into(), yesno(client.is_overlay).into());
|
||||
par.insert("flag_primary".into(), yesno(client.is_primary).into());
|
||||
par.insert("flag_visible".into(), yesno(client.is_visible).into());
|
||||
|
||||
let state_cell = self.state.parse_template(
|
||||
&doc_params(&self.globals),
|
||||
"Cell",
|
||||
&mut frontend.layout,
|
||||
self.id_list_parent,
|
||||
par,
|
||||
)?;
|
||||
|
||||
let checkbox = state_cell.fetch_component_as::<ComponentCheckbox>("checkbox")?;
|
||||
checkbox.on_toggle({
|
||||
let tasks = self.tasks.clone();
|
||||
let client_name = client.name.clone();
|
||||
Box::new(move |_common, e| {
|
||||
if e.checked {
|
||||
tasks.push(Task::FocusClient(client_name.clone()));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
});
|
||||
|
||||
self.cells.push(state_cell);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn refresh(&mut self, frontend: &mut Frontend<T>, data: &mut T) -> anyhow::Result<()> {
|
||||
log::debug!("refreshing monado client list");
|
||||
|
||||
let clients = frontend.interface.monado_client_list(data)?;
|
||||
|
||||
frontend.layout.remove_children(self.id_list_parent);
|
||||
self.cells.clear();
|
||||
|
||||
for client in clients {
|
||||
self.mount_client(frontend, &client)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn focus_client(&mut self, frontend: &mut Frontend<T>, data: &mut T, name: String) -> anyhow::Result<()> {
|
||||
frontend.interface.monado_client_focus(data, &name)?;
|
||||
self.tasks.push(Task::Refresh);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ pub fn stop(app_id: AppID, force_kill: bool) -> anyhow::Result<()> {
|
||||
|
||||
log::info!("Killing process with PID {} and its children", game.pid);
|
||||
let _ = std::process::Command::new("pkill")
|
||||
.arg(if force_kill { "-9" } else { "-11" })
|
||||
.arg(if force_kill { "-9" } else { "-15" })
|
||||
.arg("-P")
|
||||
.arg(format!("{}", game.pid))
|
||||
.spawn()?;
|
||||
|
||||
Reference in New Issue
Block a user