refactor: InterfaceFeats in AppState

This commit is contained in:
galister 2026-08-01 23:09:57 +09:00
parent 98d8a3138d
commit 4ad6287efc
16 changed files with 65 additions and 38 deletions

View File

@ -182,7 +182,7 @@
<cell translation="BAR.EDIT_MODE_TOGGLE" _press="::EditToggle" _press2="::ContextMenuClose" />
<cell translation="BAR.HANDSFREE.TITLE" _press="::ContextMenuOpen menu_handsfree" />
<cell translation="BAR.ADD_MIRROR" _press="::NewMirror" skip="${not_wayland}" />
<cell translation="BAR.ADD_PASSTHRU" _press="::NewPassthru" skip="${openvr}" />
<cell translation="BAR.ADD_PASSTHRU" _press="::NewPassthru" skip="${not_passthru}" />
<cell translation="BAR.ADD_NEW_SET" _press="::AddSet" />
<cell translation="BAR.DELETE_CURRENT_SET" _press="::DeleteSet" />
</context_menu>

View File

@ -12,7 +12,7 @@ use ovr_overlay::{
};
use smallvec::smallvec;
use vulkano::{Handle, VulkanObject, device::physical::PhysicalDevice};
use wlx_common::overlays::ToastTopic;
use wlx_common::{dash_interface::InterfaceFeats, overlays::ToastTopic};
use crate::{
Args, FRAME_COUNTER, RUNNING, XrBackend,
@ -87,9 +87,11 @@ pub fn openvr_run(args: &Args) -> Result<(), BackendError> {
names.iter().map(std::string::String::as_str).collect()
};
let feats = InterfaceFeats::default_for_backend(XrBackend::OpenVR);
let mut app = {
let (gfx, gfx_extras) = init_openvr_graphics(instance_extensions, device_extensions_fn)?;
AppState::from_graphics(gfx, gfx_extras, XrBackend::OpenVR)?
AppState::from_graphics(gfx, gfx_extras, feats)?
};
app.session.no_autostart = args.no_autostart;

View File

@ -10,7 +10,10 @@ use input::OpenXrInputSource;
use openxr as xr;
use skybox::{Skybox, create_skybox};
use vulkano::{Handle, VulkanObject};
use wlx_common::overlays::{StereoMode, ToastTopic};
use wlx_common::{
dash_interface::InterfaceFeats,
overlays::{StereoMode, ToastTopic},
};
use crate::{
Args, FRAME_COUNTER, RUNNING, XrBackend,
@ -63,9 +66,17 @@ pub fn openxr_run(args: &Args) -> Result<(), BackendError> {
}
};
let feats = InterfaceFeats {
passthru: xr_instance
.exts()
.fb_composition_layer_alpha_blend
.is_some(),
..InterfaceFeats::default_for_backend(XrBackend::OpenXR)
};
let mut app = {
let (gfx, gfx_extras) = init_openxr_graphics(xr_instance.clone(), system)?;
AppState::from_graphics(gfx, gfx_extras, XrBackend::OpenXR)?
AppState::from_graphics(gfx, gfx_extras, feats)?
};
app.session.no_autostart = args.no_autostart;

View File

@ -91,7 +91,7 @@ impl DashFrontend {
interface: Box::new(interface),
lang_provider: &WayVRLangProvider::from_config(&app.session.config),
show_welcome: tutorial,
has_monado: app.xr_backend.is_open_xr(),
has_monado: app.feats.xr_backend.is_open_xr(),
theme: app.wgui_theme.clone(),
color_palette: &*app.session.config.color_palette,
executor: app.executor.clone(),
@ -578,18 +578,7 @@ impl DashInterface<AppState> for DashInterfaceLive {
}
fn get_feats(&mut self, data: &mut AppState) -> dash_interface::InterfaceFeats {
dash_interface::InterfaceFeats {
xr_backend: data.xr_backend,
desktop_backend: data.desktop_backend,
#[cfg(feature = "openxr")]
monado: data.monado_state.is_some(),
#[cfg(not(feature = "openxr"))]
monado: false,
#[cfg(feature = "whisper")]
whisper: true,
#[cfg(not(feature = "whisper"))]
whisper: false,
}
data.feats
}
#[cfg(feature = "openxr")]

View File

@ -58,12 +58,16 @@ pub(super) fn create_keyboard_panel(
layout: &layout::Layout,
) -> anyhow::Result<GuiPanel<KeyboardState>> {
let mut params = NewGuiPanelParams::default();
params.extra_vars.insert(
"openvr".into(),
bool_to_rc_str(app.feats.xr_backend.is_open_vr()),
);
params
.extra_vars
.insert("openvr".into(), bool_to_rc_str(app.xr_backend.is_open_vr()));
.insert("not_passthru".into(), bool_to_rc_str(!app.feats.passthru));
params.extra_vars.insert(
"not_wayland".into(),
bool_to_rc_str(!app.desktop_backend.is_wayland()),
bool_to_rc_str(!app.feats.desktop_backend.is_wayland()),
);
let mut panel = GuiPanel::new_from_template(app, "gui/keyboard.xml", state, params)?;

View File

@ -70,7 +70,7 @@ pub fn create_keyboard(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig
active_layout: KeyboardPanelKey::default(),
default_state,
wlx_layout: layout,
wayland: app.desktop_backend.is_wayland(),
wayland: app.feats.desktop_backend.is_wayland(),
re_fcitx: Regex::new(r"^keyboard-([^-]+)(?:-([^-]+))?$").unwrap(),
};

View File

@ -85,8 +85,12 @@ pub fn new_mirror(name: Arc<str>, app: &mut AppState) -> anyhow::Result<OverlayW
capture: Box<dyn WlxCapture<WlxCaptureIn, WlxCaptureOut>>,
app: &mut AppState,
) -> Box<dyn OverlayBackend> {
let renderer =
ScreenBackend::new_raw(name.clone(), app.xr_backend, CaptureType::PipeWire, capture);
let renderer = ScreenBackend::new_raw(
name.clone(),
app.feats.xr_backend,
CaptureType::PipeWire,
capture,
);
let backend = MirrorBackend(renderer);

View File

@ -81,7 +81,7 @@ impl ScreenCastBackend {
use wlx_capture::frame::Transform;
let mut backend =
ScreenBackend::new_raw(name, app.xr_backend, CaptureType::PipeWire, capture);
ScreenBackend::new_raw(name, app.feats.xr_backend, CaptureType::PipeWire, capture);
backend.logical_pos = logical_pos;
backend.logical_size = logical_size;

View File

@ -29,7 +29,7 @@ impl ScreenBackend {
);
Some(Self::new_raw(
output.name.clone(),
app.xr_backend,
app.feats.xr_backend,
CaptureType::ScreenCopy,
capture,
))

View File

@ -33,7 +33,7 @@ impl ScreenBackend {
);
Self::new_raw(
screen.name.clone(),
app.xr_backend,
app.feats.xr_backend,
CaptureType::Xshm,
capture,
)
@ -103,7 +103,7 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateDa
let mut backend = ScreenBackend::new_raw(
m.name.clone(),
app.xr_backend,
app.feats.xr_backend,
CaptureType::PipeWire,
new_wlx_capture!(
app.gfx_extras.queue_capture,

View File

@ -248,7 +248,11 @@ impl WvrWindowBackend {
just_resumed: false,
meta: None,
mouse: None,
stereo: app.xr_backend.is_open_xr().then_some(StereoMode::None),
stereo: app
.feats
.xr_backend
.is_open_xr()
.then_some(StereoMode::None),
stereo_full_frame: false,
stereo_adjust_mouse: false,
cur_image: None,

View File

@ -72,7 +72,7 @@ impl WhisperState {
}
pub fn create_whisper(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
let clipboard_provider: Option<Box<dyn ClipboardProvider>> = match app.desktop_backend {
let clipboard_provider: Option<Box<dyn ClipboardProvider>> = match app.feats.desktop_backend {
#[cfg(feature = "wayland")]
DesktopBackend::Wayland => clipboard::wl::Provider::new()
.log_err("Could not create Wayland clipboard provider")

View File

@ -27,7 +27,7 @@ use wlx_common::{
#[cfg(feature = "openxr")]
use crate::backend;
use crate::backend::wayvr::WvrServerState;
use wlx_common::DesktopBackend;
use wlx_common::dash_interface::InterfaceFeats;
use crate::subsystem::notifications::NotificationManager;
#[cfg(feature = "osc")]
@ -36,7 +36,6 @@ use crate::subsystem::osc::OscSender;
#[cfg(feature = "whisper")]
use crate::subsystem::whisper_stt::WhisperStt;
use crate::{
XrBackend,
backend::{input::InputState, task::TaskContainer},
config::load_general_config,
graphics::WGfxExtras,
@ -72,8 +71,7 @@ pub struct AppState {
pub dbus: DbusConnector,
pub xr_backend: XrBackend,
pub desktop_backend: DesktopBackend,
pub feats: InterfaceFeats,
pub ipc_server: ipc_server::WayVRServer,
pub wayvr_signals: SyncEventQueue<WayVRSignal>,
@ -102,7 +100,7 @@ impl AppState {
pub fn from_graphics(
gfx: Arc<WGfx>,
gfx_extras: WGfxExtras,
xr_backend: XrBackend,
feats: InterfaceFeats,
) -> anyhow::Result<Self> {
// insert shared resources
let mut tasks = TaskContainer::new();
@ -218,10 +216,9 @@ impl AppState {
wgui_theme: Rc::new(theme),
executor,
dbus,
xr_backend,
feats,
ipc_server,
wayvr_signals: wvr_signals,
desktop_backend: DesktopBackend::Headless, // set by OverlayWindowManager
desktop_finder,
notifications: NotificationManager::new(),
@ -253,7 +250,7 @@ impl AppState {
self.notifications.run_udp();
#[cfg(feature = "openxr")]
if self.xr_backend.is_open_xr() {
if self.feats.xr_backend.is_open_xr() {
use crate::backend::openxr::monado_state::MonadoState;
log::debug!("Connecting to Monado IPC");
@ -262,9 +259,11 @@ impl AppState {
match MonadoState::new() {
Ok(m) => {
self.monado_state = Some(m);
self.feats.monado = true;
}
Err(e) => {
log::error!("Will not use libmonado: {e:?}");
self.feats.monado = false;
}
}
}

View File

@ -89,7 +89,7 @@ where
// OverlayWindowManager::restore_layout down below
match create_screens(app) {
Ok((data, backend)) => {
app.desktop_backend = backend;
app.feats.desktop_backend = backend;
let last_idx = data.screens.len() - 1;
for (idx, (meta, mut config)) in data.screens.into_iter().enumerate() {
config.show_on_spawn = true;

View File

@ -50,9 +50,22 @@ pub struct InterfaceFeats {
pub xr_backend: XrBackend,
pub desktop_backend: DesktopBackend,
pub monado: bool,
pub passthru: bool,
pub whisper: bool,
}
impl InterfaceFeats {
pub fn default_for_backend(xr_backend: XrBackend) -> Self {
Self {
xr_backend,
desktop_backend: DesktopBackend::Headless,
monado: false,
passthru: false,
whisper: false,
}
}
}
pub trait DashInterface<T> {
fn window_list(&mut self, data: &mut T) -> anyhow::Result<Vec<WvrWindow>>;
fn window_set_visible(&mut self, data: &mut T, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()>;

View File

@ -238,6 +238,7 @@ impl DashInterface<()> for DashInterfaceEmulated {
xr_backend: crate::XrBackend::OpenXR,
desktop_backend: crate::DesktopBackend::Wayland,
monado: true,
passthru: false,
whisper: true,
}
}