fix: mouse click when pointing at 2 screens
This commit is contained in:
@@ -296,6 +296,8 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.hid_provider.commit();
|
||||||
|
|
||||||
lines.update(universe.clone(), &mut overlay_mgr, &mut state)?;
|
lines.update(universe.clone(), &mut overlay_mgr, &mut state)?;
|
||||||
|
|
||||||
for o in overlays.iter_mut() {
|
for o in overlays.iter_mut() {
|
||||||
@@ -324,8 +326,6 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
// chaperone
|
// chaperone
|
||||||
|
|
||||||
// close font handles?
|
// close font handles?
|
||||||
|
|
||||||
state.hid_provider.on_new_frame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log::warn!("OpenVR shutdown");
|
log::warn!("OpenVR shutdown");
|
||||||
|
|||||||
@@ -256,6 +256,8 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app_state.hid_provider.commit();
|
||||||
|
|
||||||
let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic
|
let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic
|
||||||
let watch_transform = watch.state.transform;
|
let watch_transform = watch.state.transform;
|
||||||
if !watch.state.want_visible {
|
if !watch.state.want_visible {
|
||||||
@@ -376,8 +378,6 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
|
|
||||||
delete_queue.retain(|(_, frame)| *frame > cur_frame);
|
delete_queue.retain(|(_, frame)| *frame > cur_frame);
|
||||||
|
|
||||||
app_state.hid_provider.on_new_frame();
|
|
||||||
|
|
||||||
let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic
|
let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic
|
||||||
watch.state.transform = watch_transform;
|
watch.state.transform = watch_transform;
|
||||||
}
|
}
|
||||||
|
|||||||
90
src/hid.rs
90
src/hid.rs
@@ -37,21 +37,34 @@ pub fn initialize() -> Box<dyn HidProvider> {
|
|||||||
|
|
||||||
pub trait HidProvider {
|
pub trait HidProvider {
|
||||||
fn mouse_move(&mut self, pos: Vec2);
|
fn mouse_move(&mut self, pos: Vec2);
|
||||||
fn send_button(&self, button: u16, down: bool);
|
fn send_button(&mut self, button: u16, down: bool);
|
||||||
fn wheel(&self, delta: i32);
|
fn wheel(&mut self, delta: i32);
|
||||||
fn set_modifiers(&mut self, mods: u8);
|
fn set_modifiers(&mut self, mods: u8);
|
||||||
fn send_key(&self, key: u16, down: bool);
|
fn send_key(&self, key: u16, down: bool);
|
||||||
fn set_desktop_extent(&mut self, extent: Vec2);
|
fn set_desktop_extent(&mut self, extent: Vec2);
|
||||||
fn set_desktop_origin(&mut self, origin: Vec2);
|
fn set_desktop_origin(&mut self, origin: Vec2);
|
||||||
fn on_new_frame(&mut self);
|
fn commit(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MouseButtonAction {
|
||||||
|
button: u16,
|
||||||
|
down: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct MouseAction {
|
||||||
|
last_requested_pos: Option<Vec2>,
|
||||||
|
pos: Option<Vec2>,
|
||||||
|
button: Option<MouseButtonAction>,
|
||||||
|
scroll: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UInputProvider {
|
pub struct UInputProvider {
|
||||||
handle: UInputHandle<File>,
|
handle: UInputHandle<File>,
|
||||||
desktop_extent: Vec2,
|
desktop_extent: Vec2,
|
||||||
desktop_origin: Vec2,
|
desktop_origin: Vec2,
|
||||||
mouse_moved: bool,
|
|
||||||
cur_modifiers: u8,
|
cur_modifiers: u8,
|
||||||
|
current_action: MouseAction,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DummyProvider;
|
pub struct DummyProvider;
|
||||||
@@ -145,22 +158,25 @@ impl UInputProvider {
|
|||||||
handle,
|
handle,
|
||||||
desktop_extent: Vec2::ZERO,
|
desktop_extent: Vec2::ZERO,
|
||||||
desktop_origin: Vec2::ZERO,
|
desktop_origin: Vec2::ZERO,
|
||||||
mouse_moved: false,
|
current_action: Default::default(),
|
||||||
cur_modifiers: 0,
|
cur_modifiers: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl HidProvider for UInputProvider {
|
fn send_button_internal(&self, button: u16, down: bool) {
|
||||||
fn mouse_move(&mut self, pos: Vec2) {
|
let time = get_time();
|
||||||
if self.mouse_moved {
|
let events = [
|
||||||
return;
|
new_event(time, EV_KEY, button, down as _),
|
||||||
|
new_event(time, EV_SYN, 0, 0),
|
||||||
|
];
|
||||||
|
if let Err(res) = self.handle.write(&events) {
|
||||||
|
log::error!("send_button: {}", res.to_string());
|
||||||
}
|
}
|
||||||
self.mouse_moved = true;
|
}
|
||||||
|
fn mouse_move_internal(&mut self, pos: Vec2) {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
log::trace!("Mouse move: {:?}", pos);
|
log::trace!("Mouse move: {:?}", pos);
|
||||||
|
|
||||||
@@ -176,17 +192,7 @@ impl HidProvider for UInputProvider {
|
|||||||
log::error!("{}", res.to_string());
|
log::error!("{}", res.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn send_button(&self, button: u16, down: bool) {
|
fn wheel_internal(&self, delta: i32) {
|
||||||
let time = get_time();
|
|
||||||
let events = [
|
|
||||||
new_event(time, EV_KEY, button, down as _),
|
|
||||||
new_event(time, EV_SYN, 0, 0),
|
|
||||||
];
|
|
||||||
if let Err(res) = self.handle.write(&events) {
|
|
||||||
log::error!("send_button: {}", res.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn wheel(&self, delta: i32) {
|
|
||||||
let time = get_time();
|
let time = get_time();
|
||||||
let events = [
|
let events = [
|
||||||
new_event(time, EV_REL, RelativeAxis::Wheel as _, delta),
|
new_event(time, EV_REL, RelativeAxis::Wheel as _, delta),
|
||||||
@@ -196,6 +202,9 @@ impl HidProvider for UInputProvider {
|
|||||||
log::error!("wheel: {}", res.to_string());
|
log::error!("wheel: {}", res.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HidProvider for UInputProvider {
|
||||||
fn set_modifiers(&mut self, modifiers: u8) {
|
fn set_modifiers(&mut self, modifiers: u8) {
|
||||||
let changed = self.cur_modifiers ^ modifiers;
|
let changed = self.cur_modifiers ^ modifiers;
|
||||||
for i in 0..7 {
|
for i in 0..7 {
|
||||||
@@ -224,20 +233,45 @@ impl HidProvider for UInputProvider {
|
|||||||
fn set_desktop_origin(&mut self, origin: Vec2) {
|
fn set_desktop_origin(&mut self, origin: Vec2) {
|
||||||
self.desktop_origin = origin;
|
self.desktop_origin = origin;
|
||||||
}
|
}
|
||||||
fn on_new_frame(&mut self) {
|
fn mouse_move(&mut self, pos: Vec2) {
|
||||||
self.mouse_moved = false;
|
if self.current_action.pos.is_none() {
|
||||||
|
self.current_action.pos = Some(pos);
|
||||||
|
}
|
||||||
|
self.current_action.last_requested_pos = Some(pos);
|
||||||
|
}
|
||||||
|
fn send_button(&mut self, button: u16, down: bool) {
|
||||||
|
if self.current_action.button.is_none() {
|
||||||
|
self.current_action.button = Some(MouseButtonAction { button, down });
|
||||||
|
self.current_action.pos = self.current_action.last_requested_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn wheel(&mut self, delta: i32) {
|
||||||
|
if self.current_action.scroll.is_none() {
|
||||||
|
self.current_action.scroll = Some(delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn commit(&mut self) {
|
||||||
|
if let Some(pos) = self.current_action.pos.take() {
|
||||||
|
self.mouse_move_internal(pos);
|
||||||
|
}
|
||||||
|
if let Some(button) = self.current_action.button.take() {
|
||||||
|
self.send_button_internal(button.button, button.down);
|
||||||
|
}
|
||||||
|
if let Some(scroll) = self.current_action.scroll.take() {
|
||||||
|
self.wheel_internal(scroll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HidProvider for DummyProvider {
|
impl HidProvider for DummyProvider {
|
||||||
fn mouse_move(&mut self, _pos: Vec2) {}
|
fn mouse_move(&mut self, _pos: Vec2) {}
|
||||||
fn send_button(&self, _button: u16, _down: bool) {}
|
fn send_button(&mut self, _button: u16, _down: bool) {}
|
||||||
fn wheel(&self, _delta: i32) {}
|
fn wheel(&mut self, _delta: i32) {}
|
||||||
fn set_modifiers(&mut self, _modifiers: u8) {}
|
fn set_modifiers(&mut self, _modifiers: u8) {}
|
||||||
fn send_key(&self, _key: u16, _down: bool) {}
|
fn send_key(&self, _key: u16, _down: bool) {}
|
||||||
fn set_desktop_extent(&mut self, _extent: Vec2) {}
|
fn set_desktop_extent(&mut self, _extent: Vec2) {}
|
||||||
fn set_desktop_origin(&mut self, _origin: Vec2) {}
|
fn set_desktop_origin(&mut self, _origin: Vec2) {}
|
||||||
fn on_new_frame(&mut self) {}
|
fn commit(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use core::slice;
|
use core::slice;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
f32::consts::PI,
|
f32::consts::PI,
|
||||||
ops::Add,
|
ops::Add,
|
||||||
ptr,
|
ptr,
|
||||||
sync::Arc,
|
sync::{atomic::AtomicU64, Arc},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
@@ -62,9 +63,22 @@ const CURSOR_SIZE: f32 = 16. / 1440.;
|
|||||||
|
|
||||||
static DRM_FORMATS: once_cell::sync::OnceCell<Vec<DrmFormat>> = once_cell::sync::OnceCell::new();
|
static DRM_FORMATS: once_cell::sync::OnceCell<Vec<DrmFormat>> = once_cell::sync::OnceCell::new();
|
||||||
|
|
||||||
|
static START: Lazy<Instant> = Lazy::new(Instant::now);
|
||||||
|
static NEXT_MOVE: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
|
fn can_move() -> bool {
|
||||||
|
START.elapsed().as_millis() as u64 > NEXT_MOVE.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_next_move(millis_from_now: u64) {
|
||||||
|
NEXT_MOVE.store(
|
||||||
|
START.elapsed().as_millis() as u64 + millis_from_now,
|
||||||
|
std::sync::atomic::Ordering::Relaxed,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ScreenInteractionHandler {
|
pub struct ScreenInteractionHandler {
|
||||||
next_scroll: Instant,
|
next_scroll: Instant,
|
||||||
next_move: Instant,
|
|
||||||
mouse_transform: Affine2,
|
mouse_transform: Affine2,
|
||||||
}
|
}
|
||||||
impl ScreenInteractionHandler {
|
impl ScreenInteractionHandler {
|
||||||
@@ -90,7 +104,6 @@ impl ScreenInteractionHandler {
|
|||||||
|
|
||||||
ScreenInteractionHandler {
|
ScreenInteractionHandler {
|
||||||
next_scroll: Instant::now(),
|
next_scroll: Instant::now(),
|
||||||
next_move: Instant::now(),
|
|
||||||
mouse_transform: transform,
|
mouse_transform: transform,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +113,7 @@ impl InteractionHandler for ScreenInteractionHandler {
|
|||||||
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option<Haptics> {
|
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option<Haptics> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
log::trace!("Hover: {:?}", hit.uv);
|
log::trace!("Hover: {:?}", hit.uv);
|
||||||
if self.next_move < Instant::now()
|
if can_move()
|
||||||
&& (!app.session.config.focus_follows_mouse_mode
|
&& (!app.session.config.focus_follows_mouse_mode
|
||||||
|| app.input_state.pointers[hit.pointer].now.move_mouse)
|
|| app.input_state.pointers[hit.pointer].now.move_mouse)
|
||||||
{
|
{
|
||||||
@@ -117,8 +130,7 @@ impl InteractionHandler for ScreenInteractionHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if pressed {
|
if pressed {
|
||||||
self.next_move = Instant::now()
|
set_next_move(app.session.config.click_freeze_time_ms as u64);
|
||||||
+ Duration::from_millis(app.session.config.click_freeze_time_ms as u64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.hid_provider.send_button(btn, pressed);
|
app.hid_provider.send_button(btn, pressed);
|
||||||
@@ -568,7 +580,7 @@ pub fn create_screen_renderer_wl(
|
|||||||
capture = Some(renderer);
|
capture = Some(renderer);
|
||||||
|
|
||||||
if let Some(token) = restore_token {
|
if let Some(token) = restore_token {
|
||||||
if pw_token_store.arc_ins(display_name.into(), token.clone()) {
|
if pw_token_store.arc_set(display_name.into(), token.clone()) {
|
||||||
log::info!("Adding Pipewire token {}", token);
|
log::info!("Adding Pipewire token {}", token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user