DeviceHaptics task
This commit is contained in:
@@ -486,6 +486,15 @@ impl WayVRClient {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn fn_wlx_device_haptics(
|
||||||
|
client: WayVRClientMutex,
|
||||||
|
device: usize,
|
||||||
|
params: packet_client::WlxHapticsParams,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
send_only!(client, &PacketClient::WlxDeviceHaptics(device, params));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn fn_wlx_modify_panel(
|
pub async fn fn_wlx_modify_panel(
|
||||||
client: WayVRClientMutex,
|
client: WayVRClientMutex,
|
||||||
params: packet_client::WlxModifyPanelParams,
|
params: packet_client::WlxModifyPanelParams,
|
||||||
|
|||||||
@@ -85,4 +85,5 @@ pub enum PacketClient {
|
|||||||
WlxHaptics(WlxHapticsParams),
|
WlxHaptics(WlxHapticsParams),
|
||||||
WlxInputState(Serial),
|
WlxInputState(Serial),
|
||||||
WlxModifyPanel(WlxModifyPanelParams),
|
WlxModifyPanel(WlxModifyPanelParams),
|
||||||
|
WlxDeviceHaptics(usize, WlxHapticsParams),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,15 +214,17 @@ pub async fn wvr_process_launch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn wlx_haptics(
|
pub async fn wlx_device_haptics(
|
||||||
state: &mut WayVRClientState,
|
state: &mut WayVRClientState,
|
||||||
|
device: usize,
|
||||||
intensity: f32,
|
intensity: f32,
|
||||||
duration: f32,
|
duration: f32,
|
||||||
frequency: f32,
|
frequency: f32,
|
||||||
) {
|
) {
|
||||||
handle_empty_result(
|
handle_empty_result(
|
||||||
WayVRClient::fn_wlx_haptics(
|
WayVRClient::fn_wlx_device_haptics(
|
||||||
state.wayvr_client.clone(),
|
state.wayvr_client.clone(),
|
||||||
|
device,
|
||||||
packet_client::WlxHapticsParams {
|
packet_client::WlxHapticsParams {
|
||||||
intensity,
|
intensity,
|
||||||
duration,
|
duration,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use env_logger::Env;
|
|||||||
use wayvr_ipc::{client::WayVRClient, ipc, packet_client};
|
use wayvr_ipc::{client::WayVRClient, ipc, packet_client};
|
||||||
|
|
||||||
use crate::helper::{
|
use crate::helper::{
|
||||||
WayVRClientState, wlx_haptics, wlx_input_state, wlx_panel_modify, wvr_display_create,
|
WayVRClientState, wlx_device_haptics, wlx_input_state, wlx_panel_modify, wvr_display_create,
|
||||||
wvr_display_get, wvr_display_list, wvr_display_remove, wvr_display_set_visible,
|
wvr_display_get, wvr_display_list, wvr_display_remove, wvr_display_set_visible,
|
||||||
wvr_display_window_list, wvr_process_get, wvr_process_launch, wvr_process_list,
|
wvr_display_window_list, wvr_process_get, wvr_process_launch, wvr_process_list,
|
||||||
wvr_process_terminate, wvr_window_set_visible,
|
wvr_process_terminate, wvr_window_set_visible,
|
||||||
@@ -162,11 +162,12 @@ async fn run_once(state: &mut WayVRClientState, args: Args) -> anyhow::Result<()
|
|||||||
wvr_process_launch(state, exec, name, env, handle, args, HashMap::new()).await;
|
wvr_process_launch(state, exec, name, env, handle, args, HashMap::new()).await;
|
||||||
}
|
}
|
||||||
Subcommands::Haptics {
|
Subcommands::Haptics {
|
||||||
|
device,
|
||||||
intensity,
|
intensity,
|
||||||
duration,
|
duration,
|
||||||
frequency,
|
frequency,
|
||||||
} => {
|
} => {
|
||||||
wlx_haptics(state, intensity, duration, frequency).await;
|
wlx_device_haptics(state, device, intensity, duration, frequency).await;
|
||||||
}
|
}
|
||||||
Subcommands::PanelModify {
|
Subcommands::PanelModify {
|
||||||
overlay,
|
overlay,
|
||||||
@@ -283,6 +284,8 @@ enum Subcommands {
|
|||||||
},
|
},
|
||||||
/// Trigger haptics on the user's controller
|
/// Trigger haptics on the user's controller
|
||||||
Haptics {
|
Haptics {
|
||||||
|
/// 0 for left, 1 for right controller
|
||||||
|
device: usize,
|
||||||
#[arg(short, long, default_value = "0.25")]
|
#[arg(short, long, default_value = "0.25")]
|
||||||
intensity: f32,
|
intensity: f32,
|
||||||
#[arg(short, long, default_value = "0.1")]
|
#[arg(short, long, default_value = "0.1")]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use smallvec::{SmallVec, smallvec};
|
|||||||
use wlx_common::common::LeftRight;
|
use wlx_common::common::LeftRight;
|
||||||
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
||||||
|
|
||||||
use crate::backend::task::OverlayTask;
|
use crate::backend::task::{InputTask, OverlayTask};
|
||||||
use crate::overlays::anchor::{ANCHOR_NAME, GRAB_HELP_NAME};
|
use crate::overlays::anchor::{ANCHOR_NAME, GRAB_HELP_NAME};
|
||||||
use crate::overlays::watch::WATCH_NAME;
|
use crate::overlays::watch::WATCH_NAME;
|
||||||
use crate::state::{AppSession, AppState};
|
use crate::state::{AppSession, AppState};
|
||||||
@@ -65,6 +65,18 @@ impl InputState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_task(&mut self, task: InputTask) {
|
||||||
|
match task {
|
||||||
|
InputTask::Haptics { device, haptics } => {
|
||||||
|
if let Some(pointer) = self.pointers.get_mut(device) {
|
||||||
|
pointer.pending_haptics = Some(haptics);
|
||||||
|
} else {
|
||||||
|
log::warn!("Can't trigger haptics on non-existing device: {device}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn pre_update(&mut self) {
|
pub const fn pre_update(&mut self) {
|
||||||
self.pointers[0].before = self.pointers[0].now;
|
self.pointers[0].before = self.pointers[0].now;
|
||||||
self.pointers[1].before = self.pointers[1].now;
|
self.pointers[1].before = self.pointers[1].now;
|
||||||
@@ -218,6 +230,7 @@ pub struct Pointer {
|
|||||||
pub now: PointerState,
|
pub now: PointerState,
|
||||||
pub before: PointerState,
|
pub before: PointerState,
|
||||||
pub last_click: Instant,
|
pub last_click: Instant,
|
||||||
|
pub pending_haptics: Option<Haptics>,
|
||||||
pub(super) interaction: InteractionState,
|
pub(super) interaction: InteractionState,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +244,7 @@ impl Pointer {
|
|||||||
now: PointerState::default(),
|
now: PointerState::default(),
|
||||||
before: PointerState::default(),
|
before: PointerState::default(),
|
||||||
last_click: Instant::now(),
|
last_click: Instant::now(),
|
||||||
|
pending_haptics: None,
|
||||||
interaction: InteractionState::default(),
|
interaction: InteractionState::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,6 +354,8 @@ where
|
|||||||
{
|
{
|
||||||
// already grabbing, ignore everything else
|
// already grabbing, ignore everything else
|
||||||
let mut pointer = &mut app.input_state.pointers[idx];
|
let mut pointer = &mut app.input_state.pointers[idx];
|
||||||
|
let pending_haptics = pointer.pending_haptics.take();
|
||||||
|
|
||||||
if let Some(grab_data) = pointer.interaction.grabbed {
|
if let Some(grab_data) = pointer.interaction.grabbed {
|
||||||
if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) {
|
if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) {
|
||||||
handle_grabbed(idx, grabbed, app);
|
handle_grabbed(idx, grabbed, app);
|
||||||
@@ -347,13 +363,13 @@ where
|
|||||||
log::warn!("Grabbed overlay {:?} does not exist", grab_data.grabbed_id);
|
log::warn!("Grabbed overlay {:?} does not exist", grab_data.grabbed_id);
|
||||||
pointer.interaction.grabbed = None;
|
pointer.interaction.grabbed = None;
|
||||||
}
|
}
|
||||||
return (0.1, None);
|
return (0.1, pending_haptics);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hovered_id = pointer.interaction.hovered_id.take();
|
let hovered_id = pointer.interaction.hovered_id.take();
|
||||||
let (Some(mut hit), haptics) = get_nearest_hit(idx, overlays, app) else {
|
let (Some(mut hit), haptics) = get_nearest_hit(idx, overlays, app) else {
|
||||||
handle_no_hit(idx, hovered_id, overlays, app);
|
handle_no_hit(idx, hovered_id, overlays, app);
|
||||||
return (0.0, None); // no hit
|
return (0.0, pending_haptics); // no hit
|
||||||
};
|
};
|
||||||
|
|
||||||
// focus change
|
// focus change
|
||||||
@@ -378,7 +394,7 @@ where
|
|||||||
|
|
||||||
let Some(hovered) = overlays.mut_by_id(hit.overlay) else {
|
let Some(hovered) = overlays.mut_by_id(hit.overlay) else {
|
||||||
log::warn!("Hit overlay {:?} does not exist", hit.overlay);
|
log::warn!("Hit overlay {:?} does not exist", hit.overlay);
|
||||||
return (0.0, None); // no hit
|
return (0.0, pending_haptics); // no hit
|
||||||
};
|
};
|
||||||
pointer = &mut app.input_state.pointers[idx];
|
pointer = &mut app.input_state.pointers[idx];
|
||||||
pointer.interaction.hovered_id = Some(hit.overlay);
|
pointer.interaction.hovered_id = Some(hit.overlay);
|
||||||
@@ -447,7 +463,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(hit.dist, haptics)
|
(hit.dist, haptics.or(pending_haptics))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_no_hit<O>(
|
fn handle_no_hit<O>(
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use crate::{
|
|||||||
manifest::{install_manifest, uninstall_manifest},
|
manifest::{install_manifest, uninstall_manifest},
|
||||||
overlay::OpenVrOverlayData,
|
overlay::OpenVrOverlayData,
|
||||||
},
|
},
|
||||||
task::{OpenVrTask, OverlayTask, TaskType},
|
task::{InputTask, OpenVrTask, OverlayTask, TaskType},
|
||||||
},
|
},
|
||||||
config::save_state,
|
config::save_state,
|
||||||
graphics::{GpuFutures, init_openvr_graphics},
|
graphics::{GpuFutures, init_openvr_graphics},
|
||||||
@@ -220,6 +220,9 @@ pub fn openvr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
|
|||||||
|
|
||||||
while let Some(task) = due_tasks.pop_front() {
|
while let Some(task) = due_tasks.pop_front() {
|
||||||
match task {
|
match task {
|
||||||
|
TaskType::Input(task) => {
|
||||||
|
app.input_state.handle_task(task);
|
||||||
|
}
|
||||||
TaskType::Overlay(task) => {
|
TaskType::Overlay(task) => {
|
||||||
overlays.handle_task(&mut app, task)?;
|
overlays.handle_task(&mut app, task)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -489,6 +489,9 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
|
|||||||
app.tasks.retrieve_due(&mut due_tasks);
|
app.tasks.retrieve_due(&mut due_tasks);
|
||||||
while let Some(task) = due_tasks.pop_front() {
|
while let Some(task) = due_tasks.pop_front() {
|
||||||
match task {
|
match task {
|
||||||
|
TaskType::Input(task) => {
|
||||||
|
app.input_state.handle_task(task);
|
||||||
|
}
|
||||||
TaskType::Overlay(task) => {
|
TaskType::Overlay(task) => {
|
||||||
overlays.handle_task(&mut app, task)?;
|
overlays.handle_task(&mut app, task)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use std::{
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
backend::input,
|
||||||
state::AppState,
|
state::AppState,
|
||||||
windowing::{OverlaySelector, window::OverlayWindowConfig},
|
windowing::{OverlaySelector, window::OverlayWindowConfig},
|
||||||
};
|
};
|
||||||
@@ -43,6 +44,13 @@ impl Ord for AppTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum InputTask {
|
||||||
|
Haptics {
|
||||||
|
device: usize,
|
||||||
|
haptics: input::Haptics,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "openvr")]
|
#[cfg(feature = "openvr")]
|
||||||
pub enum OpenVrTask {
|
pub enum OpenVrTask {
|
||||||
ColorGain(ColorChannel, f32),
|
ColorGain(ColorChannel, f32),
|
||||||
@@ -87,6 +95,7 @@ pub enum OverlayTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum TaskType {
|
pub enum TaskType {
|
||||||
|
Input(InputTask),
|
||||||
Overlay(OverlayTask),
|
Overlay(OverlayTask),
|
||||||
Playspace(PlayspaceTask),
|
Playspace(PlayspaceTask),
|
||||||
#[cfg(feature = "openvr")]
|
#[cfg(feature = "openvr")]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
self,
|
self,
|
||||||
task::{OverlayTask, TaskType},
|
task::{InputTask, OverlayTask, TaskType},
|
||||||
},
|
},
|
||||||
ipc::signal::WayVRSignal,
|
ipc::signal::WayVRSignal,
|
||||||
overlays::{self},
|
overlays::{self},
|
||||||
@@ -160,6 +160,10 @@ where
|
|||||||
wayland_server.pending_haptics = Some(haptics);
|
wayland_server.pending_haptics = Some(haptics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
WayVRSignal::DeviceHaptics(device, haptics) => {
|
||||||
|
app.tasks
|
||||||
|
.enqueue(TaskType::Input(InputTask::Haptics { device, haptics }));
|
||||||
|
}
|
||||||
WayVRSignal::DropOverlay(overlay_id) => {
|
WayVRSignal::DropOverlay(overlay_id) => {
|
||||||
app.tasks
|
app.tasks
|
||||||
.enqueue(TaskType::Overlay(OverlayTask::Drop(OverlaySelector::Id(
|
.enqueue(TaskType::Overlay(OverlayTask::Drop(OverlaySelector::Id(
|
||||||
|
|||||||
@@ -507,6 +507,21 @@ impl Connection {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_wlx_device_haptics(
|
||||||
|
params: &mut TickParams,
|
||||||
|
device: usize,
|
||||||
|
haptics_params: packet_client::WlxHapticsParams,
|
||||||
|
) {
|
||||||
|
params.signals.send(WayVRSignal::DeviceHaptics(
|
||||||
|
device,
|
||||||
|
crate::backend::input::Haptics {
|
||||||
|
duration: haptics_params.duration,
|
||||||
|
frequency: haptics_params.frequency,
|
||||||
|
intensity: haptics_params.intensity,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_wlx_panel(
|
fn handle_wlx_panel(
|
||||||
params: &mut TickParams,
|
params: &mut TickParams,
|
||||||
custom_params: packet_client::WlxModifyPanelParams,
|
custom_params: packet_client::WlxModifyPanelParams,
|
||||||
@@ -606,6 +621,9 @@ impl Connection {
|
|||||||
#[cfg(feature = "wayvr")]
|
#[cfg(feature = "wayvr")]
|
||||||
Self::handle_wlx_haptics(params, haptics_params);
|
Self::handle_wlx_haptics(params, haptics_params);
|
||||||
}
|
}
|
||||||
|
PacketClient::WlxDeviceHaptics(device, haptics_params) => {
|
||||||
|
Self::handle_wlx_device_haptics(params, device, haptics_params);
|
||||||
|
}
|
||||||
PacketClient::WlxModifyPanel(custom_params) => {
|
PacketClient::WlxModifyPanel(custom_params) => {
|
||||||
Self::handle_wlx_panel(params, custom_params);
|
Self::handle_wlx_panel(params, custom_params);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ pub enum WayVRSignal {
|
|||||||
BroadcastStateChanged(wayvr_ipc::packet_server::WvrStateChanged),
|
BroadcastStateChanged(wayvr_ipc::packet_server::WvrStateChanged),
|
||||||
#[cfg(feature = "wayvr")]
|
#[cfg(feature = "wayvr")]
|
||||||
Haptics(crate::backend::input::Haptics),
|
Haptics(crate::backend::input::Haptics),
|
||||||
|
DeviceHaptics(usize, crate::backend::input::Haptics),
|
||||||
DropOverlay(crate::windowing::OverlayID),
|
DropOverlay(crate::windowing::OverlayID),
|
||||||
CustomTask(crate::backend::task::ModifyPanelTask),
|
CustomTask(crate::backend::task::ModifyPanelTask),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user