From 5287b659e8b47ec00c55dac34a0eaeeb63add568 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Tue, 23 Dec 2025 13:29:01 +0900 Subject: [PATCH] customization via wayvr_ipc --- wayvr-ipc/src/packet_client.rs | 17 +++ wgui/src/renderer_vk/text/custom_glyph.rs | 2 +- wgui/src/widget/rectangle.rs | 7 +- wgui/src/widget/sprite.rs | 9 +- wlx-overlay-s/src/backend/task.rs | 17 +++ wlx-overlay-s/src/backend/wayvr/mod.rs | 6 +- wlx-overlay-s/src/backend/wayvr/server_ipc.rs | 32 +++++ wlx-overlay-s/src/overlays/custom.rs | 128 +++++++++++++++++- wlx-overlay-s/src/overlays/edit/sprite_tab.rs | 2 +- wlx-overlay-s/src/overlays/watch.rs | 4 +- wlx-overlay-s/src/overlays/wayvr.rs | 4 + wlx-overlay-s/src/windowing/backend.rs | 9 +- wlx-overlay-s/src/windowing/manager.rs | 21 +++ 13 files changed, 247 insertions(+), 11 deletions(-) diff --git a/wayvr-ipc/src/packet_client.rs b/wayvr-ipc/src/packet_client.rs index 5378f93..6f8a81f 100644 --- a/wayvr-ipc/src/packet_client.rs +++ b/wayvr-ipc/src/packet_client.rs @@ -48,6 +48,22 @@ pub struct WlxHapticsParams { pub frequency: f32, } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum WlxCustomCommand { + SetText(String), + SetColor(String), + SetSprite(String), + SetVisible(bool), + SetStickyState(bool), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct WlxCustomParams { + pub overlay: String, + pub element: String, + pub command: WlxCustomCommand, +} + #[derive(Debug, Serialize, Deserialize)] pub enum PacketClient { Handshake(Handshake), @@ -68,4 +84,5 @@ pub enum PacketClient { WvrProcessTerminate(packet_server::WvrProcessHandle), WlxHaptics(WlxHapticsParams), WlxInputState(Serial), + WlxCustom(WlxCustomParams), } diff --git a/wgui/src/renderer_vk/text/custom_glyph.rs b/wgui/src/renderer_vk/text/custom_glyph.rs index 4f3412c..ed4fd57 100644 --- a/wgui/src/renderer_vk/text/custom_glyph.rs +++ b/wgui/src/renderer_vk/text/custom_glyph.rs @@ -1,8 +1,8 @@ use std::{ f32, sync::{ - Arc, atomic::{AtomicUsize, Ordering}, + Arc, }, }; diff --git a/wgui/src/widget/rectangle.rs b/wgui/src/widget/rectangle.rs index e10778f..aae553e 100644 --- a/wgui/src/widget/rectangle.rs +++ b/wgui/src/widget/rectangle.rs @@ -2,8 +2,9 @@ use slotmap::Key; use crate::{ drawing::{self, GradientMode, PrimitiveExtent}, + event::CallbackDataCommon, layout::WidgetID, - widget::{WidgetStateFlags, util::WLength}, + widget::{util::WLength, WidgetStateFlags}, }; use super::{WidgetObj, WidgetState}; @@ -35,6 +36,10 @@ impl WidgetRectangle { }), ) } + pub fn set_color(&mut self, common: &mut CallbackDataCommon, color: drawing::Color) { + self.params.color = color; + common.mark_widget_dirty(self.id); + } } impl WidgetObj for WidgetRectangle { diff --git a/wgui/src/widget/sprite.rs b/wgui/src/widget/sprite.rs index c344b28..f64f947 100644 --- a/wgui/src/widget/sprite.rs +++ b/wgui/src/widget/sprite.rs @@ -5,11 +5,12 @@ use slotmap::Key; use crate::{ drawing::{self, PrimitiveExtent}, + event::CallbackDataCommon, globals::Globals, layout::WidgetID, renderer_vk::text::{ - DEFAULT_METRICS, custom_glyph::{CustomGlyph, CustomGlyphData}, + DEFAULT_METRICS, }, widget::WidgetStateFlags, }; @@ -39,16 +40,18 @@ impl WidgetSprite { ) } - pub fn set_color(&mut self, color: drawing::Color) { + pub fn set_color(&mut self, common: &mut CallbackDataCommon, color: drawing::Color) { self.params.color = Some(color); + common.mark_widget_dirty(self.id); } pub fn get_color(&self) -> Option { self.params.color } - pub fn set_content(&mut self, content: Option) { + pub fn set_content(&mut self, common: &mut CallbackDataCommon, content: Option) { self.params.glyph_data = content; + common.mark_widget_dirty(self.id); } pub fn get_content(&self) -> Option { diff --git a/wlx-overlay-s/src/backend/task.rs b/wlx-overlay-s/src/backend/task.rs index 1a82d51..7a13451 100644 --- a/wlx-overlay-s/src/backend/task.rs +++ b/wlx-overlay-s/src/backend/task.rs @@ -54,6 +54,22 @@ pub enum PlayspaceTask { FixFloor, } +#[derive(Debug, Clone)] +pub enum OverlayCustomCommand { + SetText(String), + SetColor(String), + SetSprite(String), + SetVisible(bool), + SetStickyState(bool), +} + +#[derive(Debug, Clone)] +pub struct OverlayCustomTask { + pub overlay: String, + pub element: String, + pub command: OverlayCustomCommand, +} + pub type ModifyOverlayTask = dyn FnOnce(&mut AppState, &mut OverlayWindowConfig) + Send; pub type CreateOverlayTask = dyn FnOnce(&mut AppState) -> Option + Send; pub enum OverlayTask { @@ -66,6 +82,7 @@ pub enum OverlayTask { CleanupMirrors, Modify(OverlaySelector, Box), Create(OverlaySelector, Box), + Custom(OverlayCustomTask), Drop(OverlaySelector), } diff --git a/wlx-overlay-s/src/backend/wayvr/mod.rs b/wlx-overlay-s/src/backend/wayvr/mod.rs index 66919a4..bde633b 100644 --- a/wlx-overlay-s/src/backend/wayvr/mod.rs +++ b/wlx-overlay-s/src/backend/wayvr/mod.rs @@ -41,7 +41,10 @@ use std::{ sync::Arc, }; use time::get_millis; -use wayvr_ipc::{packet_client, packet_server}; +use wayvr_ipc::{ + packet_client::{self}, + packet_server, +}; use xkbcommon::xkb; use crate::{ @@ -94,6 +97,7 @@ pub enum WayVRSignal { BroadcastStateChanged(packet_server::WvrStateChanged), DropOverlay(crate::windowing::OverlayID), Haptics(super::input::Haptics), + CustomTask(crate::backend::task::OverlayCustomTask), } pub enum BlitMethod { diff --git a/wlx-overlay-s/src/backend/wayvr/server_ipc.rs b/wlx-overlay-s/src/backend/wayvr/server_ipc.rs index 5fdf463..9ead83a 100644 --- a/wlx-overlay-s/src/backend/wayvr/server_ipc.rs +++ b/wlx-overlay-s/src/backend/wayvr/server_ipc.rs @@ -479,6 +479,35 @@ impl Connection { )); } + fn handle_wlx_custom(params: &mut TickParams, custom_params: packet_client::WlxCustomParams) { + use crate::backend::task::{OverlayCustomCommand, OverlayCustomTask}; + + params + .state + .signals + .send(super::WayVRSignal::CustomTask(OverlayCustomTask { + overlay: custom_params.overlay, + element: custom_params.element, + command: match custom_params.command { + packet_client::WlxCustomCommand::SetText(text) => { + OverlayCustomCommand::SetText(text) + } + packet_client::WlxCustomCommand::SetSprite(sprite) => { + OverlayCustomCommand::SetSprite(sprite) + } + packet_client::WlxCustomCommand::SetStickyState(sticky) => { + OverlayCustomCommand::SetStickyState(sticky) + } + packet_client::WlxCustomCommand::SetVisible(visible) => { + OverlayCustomCommand::SetVisible(visible) + } + packet_client::WlxCustomCommand::SetColor(color) => { + OverlayCustomCommand::SetColor(color) + } + }, + })); + } + fn process_payload(&mut self, params: &mut TickParams, payload: Payload) -> anyhow::Result<()> { let packet: PacketClient = ipc::data_decode(&payload)?; @@ -531,6 +560,9 @@ impl Connection { PacketClient::WlxHaptics(haptics_params) => { Self::handle_wlx_haptics(params, haptics_params); } + PacketClient::WlxCustom(custom_params) => { + Self::handle_wlx_custom(params, custom_params); + } } Ok(()) diff --git a/wlx-overlay-s/src/overlays/custom.rs b/wlx-overlay-s/src/overlays/custom.rs index 1a6a592..da842f4 100644 --- a/wlx-overlay-s/src/overlays/custom.rs +++ b/wlx-overlay-s/src/overlays/custom.rs @@ -1,15 +1,29 @@ use std::{sync::Arc, time::Duration}; +use anyhow::Context; use glam::{Affine3A, Quat, Vec3, vec3}; +use wgui::{ + components::button::ComponentButton, + event::{CallbackDataCommon, EventAlterables}, + i18n::Translation, + parser::{Fetchable, parse_color_hex}, + renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData}, + taffy, + widget::{label::WidgetLabel, rectangle::WidgetRectangle, sprite::WidgetSprite}, +}; use wlx_common::windowing::OverlayWindowState; use crate::{ + backend::task::OverlayCustomCommand, gui::{ panel::{GuiPanel, NewGuiPanelParams}, timer::GuiTimer, }, state::AppState, - windowing::window::{OverlayCategory, OverlayWindowConfig}, + windowing::{ + backend::OverlayEventData, + window::{OverlayCategory, OverlayWindowConfig}, + }, }; struct CustomPanelState {} @@ -36,6 +50,21 @@ pub fn create_custom(app: &mut AppState, name: Arc) -> Option) -> Option, + app: &mut AppState, + element: &str, + command: &OverlayCustomCommand, +) -> anyhow::Result<()> { + let mut alterables = EventAlterables::default(); + let mut com = CallbackDataCommon { + alterables: &mut alterables, + state: &panel.layout.state, + }; + + match command { + OverlayCustomCommand::SetText(text) => { + if let Ok(mut label) = panel + .parser_state + .fetch_widget_as::(&panel.layout.state, element) + { + label.set_text(&mut com, Translation::from_raw_text(text)); + } else if let Ok(button) = panel + .parser_state + .fetch_component_as::(&element) + { + button.set_text(&mut com, Translation::from_raw_text(text)); + } else { + anyhow::bail!("No