mirror of https://github.com/wayvr-org/wayvr.git
alt-tabbing and stuff
This commit is contained in:
parent
4cd238e487
commit
7efcb3cc84
|
|
@ -7,7 +7,7 @@ use glam::{Affine3A, Vec2, Vec3A, Vec3Swizzles};
|
|||
|
||||
use idmap_derive::IntegerId;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use strum::AsRefStr;
|
||||
use strum::{AsRefStr, EnumIs};
|
||||
use wayvr_ipc::packet_client::{HandsfreeAction, HandsfreeParams};
|
||||
use wlx_common::common::LeftRight;
|
||||
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
||||
|
|
@ -58,13 +58,22 @@ pub enum TrackedDeviceRole {
|
|||
Tracker,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, EnumIs)]
|
||||
pub enum FocusPickState {
|
||||
None,
|
||||
/// aiming to pick the focus
|
||||
Aiming,
|
||||
/// picking the focus. this will be consumed on valid on_hover
|
||||
Picking,
|
||||
}
|
||||
|
||||
pub struct InputState {
|
||||
pub hmd: Affine3A,
|
||||
pub ipd: f32,
|
||||
pub pointers: [Pointer; 2],
|
||||
pub devices: Vec<TrackedDevice>,
|
||||
pub handsfree_state: PointerState,
|
||||
pub picking_focus: bool,
|
||||
pub picking_focus: FocusPickState,
|
||||
processes: Vec<Child>,
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +86,7 @@ impl InputState {
|
|||
devices: Vec::new(),
|
||||
processes: Vec::new(),
|
||||
handsfree_state: PointerState::default(),
|
||||
picking_focus: false,
|
||||
picking_focus: FocusPickState::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,6 +219,9 @@ fn debug_print_hand(hand: &Pointer) {
|
|||
if hand.now.grab != hand.before.grab {
|
||||
log::debug!("Hand {}: grab {}", hand.idx, hand.now.grab);
|
||||
}
|
||||
if hand.now.grab_float != hand.before.grab_float {
|
||||
log::debug!("Hand {}: grab {}", hand.idx, hand.now.grab);
|
||||
}
|
||||
if hand.now.alt_click != hand.before.alt_click {
|
||||
log::debug!("Hand {}: alt_click {}", hand.idx, hand.now.alt_click);
|
||||
}
|
||||
|
|
@ -316,6 +328,7 @@ pub struct PointerState {
|
|||
pub scroll_y: f32,
|
||||
pub click: bool,
|
||||
pub grab: bool,
|
||||
pub grab_float: bool,
|
||||
pub alt_click: bool,
|
||||
pub show_hide: bool,
|
||||
pub toggle_dashboard: bool,
|
||||
|
|
@ -411,6 +424,7 @@ fn populate_lines(
|
|||
|
||||
fn update_focus(app: &mut AppState, overlay_input_focus: Option<InputFocus>) {
|
||||
if let Some(f) = &overlay_input_focus
|
||||
&& app.input_state.picking_focus.is_none()
|
||||
&& app
|
||||
.hid_provider
|
||||
.set_input_focus(app.wvr_server.as_mut(), *f)
|
||||
|
|
@ -538,8 +552,11 @@ where
|
|||
|
||||
let hovered_state = hovered.config.active_state.as_mut().unwrap();
|
||||
|
||||
let grab_float = pointer.now.grab_float;
|
||||
let grab_start = pointer.now.grab && !pointer.before.grab;
|
||||
|
||||
// grab
|
||||
if pointer.now.grab && !pointer.before.grab && hovered_state.grabbable {
|
||||
if grab_start && hovered_state.grabbable {
|
||||
update_focus(app, hovered.config.input_focus);
|
||||
start_grab(
|
||||
idx,
|
||||
|
|
@ -549,6 +566,7 @@ where
|
|||
hovered_state,
|
||||
app,
|
||||
edit_mode,
|
||||
grab_float,
|
||||
);
|
||||
log::debug!("Hand {}: grabbed {}", hit.pointer, hovered.config.name);
|
||||
return (
|
||||
|
|
@ -762,15 +780,19 @@ fn start_grab(
|
|||
state: &mut OverlayWindowState,
|
||||
app: &mut AppState,
|
||||
edit_mode: bool,
|
||||
grab_float: bool,
|
||||
) {
|
||||
let pointer = &mut app.input_state.pointers[idx];
|
||||
|
||||
// Grab anchor if:
|
||||
// - grabbed overlay is Anchored
|
||||
// - not in editmode
|
||||
// - not using grab_float
|
||||
// - grabbing with one hand. (grabbing with the 2nd hand will grab the individual overlay instead)
|
||||
let grab_anchor =
|
||||
!edit_mode && !app.anchor_grabbed && matches!(state.positioning, Positioning::Anchored);
|
||||
let grab_anchor = !edit_mode
|
||||
&& !grab_float
|
||||
&& !app.anchor_grabbed
|
||||
&& matches!(state.positioning, Positioning::Anchored);
|
||||
|
||||
let relative_grab_transform = if grab_anchor {
|
||||
app.anchor
|
||||
|
|
|
|||
|
|
@ -219,6 +219,9 @@ pub fn openvr_run(args: &Args) -> Result<(), BackendError> {
|
|||
|
||||
while let Some(task) = due_tasks.pop_front() {
|
||||
match task {
|
||||
TaskType::Global(task) => {
|
||||
task(&mut app);
|
||||
}
|
||||
TaskType::Input(task) => {
|
||||
app.input_state.handle_task(task);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::{
|
|||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use glam::{Affine3A, Quat, Vec3, bool};
|
||||
use glam::{Affine3A, FloatExt, Quat, Vec3, bool};
|
||||
use libmonado::{self as mnd, DeviceLogic};
|
||||
use openxr::{self as xr, Quaternionf, Vector2f, Vector3f};
|
||||
use wlx_common::{
|
||||
|
|
@ -238,13 +238,18 @@ impl OpenXrInputSource {
|
|||
let mut any_tracked = false;
|
||||
let old_handsfree = app.session.config.handsfree_pointer;
|
||||
|
||||
if app.input_state.picking_focus {
|
||||
if !app.input_state.picking_focus.is_none() {
|
||||
app.session.config.handsfree_pointer = app.session.config.handsfree_alt_tab.into();
|
||||
|
||||
app.input_state.handsfree_state.scroll_x =
|
||||
app.input_state.handsfree_state.scroll_x.lerp(0.0, 0.7);
|
||||
app.input_state.handsfree_state.scroll_y =
|
||||
app.input_state.handsfree_state.scroll_y.lerp(0.0, 0.7);
|
||||
|
||||
let ptr1 = &mut app.input_state.pointers[1];
|
||||
ptr1.before = ptr1.now;
|
||||
ptr1.now = PointerState::default();
|
||||
ptr1.tracked = false
|
||||
ptr1.tracked = false;
|
||||
} else {
|
||||
for i in 0..2 {
|
||||
let pointer = &mut app.input_state.pointers[i];
|
||||
|
|
@ -399,6 +404,7 @@ impl OpenXrPointer {
|
|||
// input from wayvrctl
|
||||
pointer.now.click = handsfree_state.click;
|
||||
pointer.now.grab = handsfree_state.grab;
|
||||
pointer.now.grab_float = handsfree_state.grab_float;
|
||||
pointer.now.click_modifier_right = handsfree_state.click_modifier_right;
|
||||
pointer.now.click_modifier_middle = handsfree_state.click_modifier_middle;
|
||||
pointer.now.scroll_y = handsfree_state.scroll_y;
|
||||
|
|
|
|||
|
|
@ -473,6 +473,9 @@ pub fn openxr_run(args: &Args) -> Result<(), BackendError> {
|
|||
app.tasks.retrieve_due(&mut due_tasks);
|
||||
while let Some(task) = due_tasks.pop_front() {
|
||||
match task {
|
||||
TaskType::Global(task) => {
|
||||
task(&mut app);
|
||||
}
|
||||
TaskType::Input(task) => {
|
||||
app.input_state.handle_task(task);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,8 +128,11 @@ pub enum OverlayTask {
|
|||
Drop(OverlaySelector),
|
||||
}
|
||||
|
||||
pub type GlobalTask = dyn FnOnce(&mut AppState) + Send;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub enum TaskType {
|
||||
Global(Box<GlobalTask>),
|
||||
Input(InputTask),
|
||||
Overlay(OverlayTask),
|
||||
Playspace(PlayspaceTask),
|
||||
|
|
|
|||
|
|
@ -34,9 +34,8 @@ pub enum KeyCombo {
|
|||
Super2,
|
||||
Super3,
|
||||
Super4,
|
||||
SuperTab,
|
||||
AltF4,
|
||||
AltTab,
|
||||
AltShiftTab,
|
||||
/// Always consumed by InputCapture internally
|
||||
CtrlAltDel,
|
||||
}
|
||||
|
|
@ -61,7 +60,8 @@ pub enum CapturedEvent {
|
|||
horizontal_v120: i32,
|
||||
vertical_v120: i32,
|
||||
},
|
||||
UngrabbedAll,
|
||||
Grabbed,
|
||||
Ungrabbed,
|
||||
KeyCombo {
|
||||
combo: KeyCombo,
|
||||
pressed: bool,
|
||||
|
|
@ -326,6 +326,7 @@ fn worker_main(
|
|||
}
|
||||
|
||||
let mut grabbed = false;
|
||||
let mut pending_grab = false;
|
||||
let mut watchdog = Instant::now() + WATCHDOG_TIMEOUT;
|
||||
let mut emergency_ungrab = false;
|
||||
let mut pointer_accel = PointerAccelConfig::default();
|
||||
|
|
@ -336,6 +337,8 @@ fn worker_main(
|
|||
loop {
|
||||
match command_rx.try_recv() {
|
||||
Ok(Command::SetGrabbed(requested)) => {
|
||||
pending_grab = false;
|
||||
|
||||
let _ = if requested {
|
||||
match restricted_state.borrow_mut().set_grabbed(true) {
|
||||
Ok(()) => {
|
||||
|
|
@ -409,9 +412,10 @@ fn worker_main(
|
|||
&event_tx,
|
||||
);
|
||||
grabbed = false;
|
||||
pending_grab = false;
|
||||
emergency_ungrab = false;
|
||||
|
||||
if event_tx.send(CapturedEvent::UngrabbedAll).is_err() {
|
||||
if event_tx.send(CapturedEvent::Ungrabbed).is_err() {
|
||||
break 'worker;
|
||||
}
|
||||
continue;
|
||||
|
|
@ -459,6 +463,8 @@ fn worker_main(
|
|||
match process_libinput_event(
|
||||
event,
|
||||
grabbed,
|
||||
true,
|
||||
&mut pending_grab,
|
||||
&event_tx,
|
||||
&mut runtime_devices,
|
||||
&mut pointer_devices,
|
||||
|
|
@ -473,6 +479,27 @@ fn worker_main(
|
|||
}
|
||||
}
|
||||
|
||||
if !grabbed && pending_grab && all_keyboard_keys_released(&runtime_devices) {
|
||||
pending_grab = false;
|
||||
|
||||
match restricted_state.borrow_mut().set_grabbed(true) {
|
||||
Ok(()) => {
|
||||
grabbed = true;
|
||||
watchdog = Instant::now() + WATCHDOG_TIMEOUT;
|
||||
|
||||
// should not be needed but sanity
|
||||
clear_transient_state(&mut runtime_devices);
|
||||
|
||||
if event_tx.send(CapturedEvent::Grabbed).is_err() {
|
||||
break 'worker;
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
log::warn!("Could not grab input devices after Super+Tab: {error}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if emergency_ungrab {
|
||||
force_emergency_ungrab(
|
||||
&mut libinput,
|
||||
|
|
@ -485,7 +512,7 @@ fn worker_main(
|
|||
grabbed = false;
|
||||
emergency_ungrab = false;
|
||||
|
||||
if event_tx.send(CapturedEvent::UngrabbedAll).is_err() {
|
||||
if event_tx.send(CapturedEvent::Ungrabbed).is_err() {
|
||||
break 'worker;
|
||||
}
|
||||
}
|
||||
|
|
@ -494,7 +521,9 @@ fn worker_main(
|
|||
|
||||
fn process_libinput_event(
|
||||
event: Event,
|
||||
emit: bool,
|
||||
grabbed: bool,
|
||||
allow_deferred_grab: bool,
|
||||
pending_grab: &mut bool,
|
||||
event_tx: &Sender<CapturedEvent>,
|
||||
runtime_devices: &mut HashMap<LibinputDevice, RuntimeDeviceState>,
|
||||
pointer_devices: &mut HashSet<LibinputDevice>,
|
||||
|
|
@ -504,7 +533,7 @@ fn process_libinput_event(
|
|||
Event::Device(event) => {
|
||||
handle_device_event(event, runtime_devices, pointer_devices, pointer_accel);
|
||||
}
|
||||
Event::Keyboard(KeyboardEvent::Key(event)) if emit => {
|
||||
Event::Keyboard(KeyboardEvent::Key(event)) => {
|
||||
let code_u32 = event.key();
|
||||
let Ok(code) = u16::try_from(code_u32) else {
|
||||
log::warn!("Ignoring out-of-range Linux key code {code_u32}");
|
||||
|
|
@ -521,16 +550,26 @@ fn process_libinput_event(
|
|||
state.pressed_keys.remove(&code);
|
||||
}
|
||||
|
||||
if !grabbed {
|
||||
// while ungrabbed, SuperTab will arm an automatic grab
|
||||
if allow_deferred_grab
|
||||
&& key_combo_is_pressed(KeyCombo::SuperTab, &state.pressed_keys)
|
||||
{
|
||||
*pending_grab = true;
|
||||
}
|
||||
|
||||
return ProcessResult::Continue;
|
||||
}
|
||||
|
||||
if pressed && key_combo_is_pressed(KeyCombo::CtrlAltDel, &state.pressed_keys) {
|
||||
log::info!("Ctrl+Alt+Del pressed, ungrabbing all input devices");
|
||||
return ProcessResult::EmergencyUngrab;
|
||||
}
|
||||
|
||||
// emit press/release whenever a combo's complete state changes.
|
||||
// while grabbed, these combos get emitted as normal
|
||||
for combo in [
|
||||
KeyCombo::SuperTab,
|
||||
KeyCombo::AltF4,
|
||||
KeyCombo::AltShiftTab,
|
||||
KeyCombo::AltTab,
|
||||
KeyCombo::Super1,
|
||||
KeyCombo::Super2,
|
||||
KeyCombo::Super3,
|
||||
|
|
@ -564,7 +603,7 @@ fn process_libinput_event(
|
|||
return ProcessResult::ReceiverGone;
|
||||
}
|
||||
}
|
||||
Event::Pointer(PointerEvent::Motion(event)) if emit => {
|
||||
Event::Pointer(PointerEvent::Motion(event)) if grabbed => {
|
||||
let dx = event.dx();
|
||||
let dy = event.dy();
|
||||
let dx_raw = event.dx_unaccelerated();
|
||||
|
|
@ -582,7 +621,7 @@ fn process_libinput_event(
|
|||
return ProcessResult::ReceiverGone;
|
||||
}
|
||||
}
|
||||
Event::Pointer(PointerEvent::Button(event)) if emit => {
|
||||
Event::Pointer(PointerEvent::Button(event)) if grabbed => {
|
||||
let pressed = event.button_state() == ButtonState::Pressed;
|
||||
if event_tx
|
||||
.send(CapturedEvent::PointerButton {
|
||||
|
|
@ -594,7 +633,7 @@ fn process_libinput_event(
|
|||
return ProcessResult::ReceiverGone;
|
||||
}
|
||||
}
|
||||
Event::Pointer(PointerEvent::ScrollWheel(event)) if emit => {
|
||||
Event::Pointer(PointerEvent::ScrollWheel(event)) if grabbed => {
|
||||
let horizontal = if event.has_axis(Axis::Horizontal) {
|
||||
event.scroll_value_v120(Axis::Horizontal)
|
||||
} else {
|
||||
|
|
@ -680,10 +719,14 @@ fn drain_pending_libinput_events(
|
|||
event_tx: &Sender<CapturedEvent>,
|
||||
) {
|
||||
let _ = libinput.dispatch();
|
||||
|
||||
let mut ignored = false;
|
||||
for event in libinput {
|
||||
let _ = process_libinput_event(
|
||||
event,
|
||||
false,
|
||||
false,
|
||||
&mut ignored,
|
||||
event_tx,
|
||||
runtime_devices,
|
||||
pointer_devices,
|
||||
|
|
@ -836,14 +879,10 @@ fn key_combo_is_pressed(combo: KeyCombo, pressed: &HashSet<u16>) -> bool {
|
|||
let meta =
|
||||
pressed.contains(&KeyCode::KEY_LEFTMETA.0) || pressed.contains(&KeyCode::KEY_RIGHTMETA.0);
|
||||
|
||||
let shift =
|
||||
pressed.contains(&KeyCode::KEY_LEFTSHIFT.0) || pressed.contains(&KeyCode::KEY_RIGHTSHIFT.0);
|
||||
|
||||
match combo {
|
||||
KeyCombo::AltF4 => alt && pressed.contains(&KeyCode::KEY_F4.0),
|
||||
KeyCombo::AltShiftTab => alt && shift && pressed.contains(&KeyCode::KEY_TAB.0),
|
||||
KeyCombo::AltTab => alt && pressed.contains(&KeyCode::KEY_TAB.0),
|
||||
KeyCombo::CtrlAltDel => ctrl && alt && pressed.contains(&KeyCode::KEY_DELETE.0),
|
||||
KeyCombo::SuperTab => meta && pressed.contains(&KeyCode::KEY_TAB.0),
|
||||
KeyCombo::Super1 => meta && pressed.contains(&KeyCode::KEY_1.0),
|
||||
KeyCombo::Super2 => meta && pressed.contains(&KeyCode::KEY_2.0),
|
||||
KeyCombo::Super3 => meta && pressed.contains(&KeyCode::KEY_3.0),
|
||||
|
|
@ -861,3 +900,11 @@ fn with_device_context(action: &str, path: &Path, error: io::Error) -> io::Error
|
|||
format!("failed to {action} {}: {error}", path.display()),
|
||||
)
|
||||
}
|
||||
|
||||
fn all_keyboard_keys_released(
|
||||
runtime_devices: &HashMap<LibinputDevice, RuntimeDeviceState>,
|
||||
) -> bool {
|
||||
runtime_devices
|
||||
.values()
|
||||
.all(|state| state.pressed_keys.is_empty())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,12 +77,13 @@ use crate::{
|
|||
state::AppState,
|
||||
subsystem::{
|
||||
dbus::DbusConnector,
|
||||
hid::{MODS_TO_KEYS, WheelDelta},
|
||||
hid::{self, MODS_TO_KEYS, WheelDelta},
|
||||
input::{HidWrapper, InputFocus},
|
||||
},
|
||||
windowing::{OverlayID, OverlaySelector, backend::OverlayEventData},
|
||||
};
|
||||
|
||||
pub use hit_test::{WvrHitContext, WvrHitTarget, build_hit_context};
|
||||
pub use hit_test::{WvrHitTarget, build_hit_context};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WaylandEnv {
|
||||
|
|
@ -322,6 +323,7 @@ impl WvrServerState {
|
|||
input_state: &app.input_state,
|
||||
tasks: &mut tasks,
|
||||
signals: &app.wayvr_signals,
|
||||
hid_wrapper: &mut app.hid_provider,
|
||||
});
|
||||
|
||||
// Tick all child processes
|
||||
|
|
@ -637,7 +639,11 @@ impl WvrServerState {
|
|||
wvr_server.manager.cleanup_handles();
|
||||
}
|
||||
|
||||
wvr_server.process_input_capture(&mut app.input_state, &mut app.tasks);
|
||||
wvr_server.process_input_capture(
|
||||
&mut app.input_state,
|
||||
&mut app.tasks,
|
||||
&mut app.hid_provider,
|
||||
);
|
||||
|
||||
wvr_server.ticks += 1;
|
||||
|
||||
|
|
@ -752,10 +758,8 @@ impl WvrServerState {
|
|||
&mut self,
|
||||
input_state: &mut InputState,
|
||||
tasks: &mut TaskContainer,
|
||||
hid_wrapper: &mut HidWrapper,
|
||||
) {
|
||||
if !self.has_input_focus {
|
||||
return;
|
||||
}
|
||||
let Some(input_capture) = self.input_capture.as_mut() else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -766,13 +770,47 @@ impl WvrServerState {
|
|||
for ev in input_capture.drain_events() {
|
||||
match ev {
|
||||
input_capture::CapturedEvent::Key { code, pressed } => {
|
||||
self.manager.send_key((code as u32) + 8, pressed);
|
||||
let vk = (code as u32) + 8;
|
||||
if input_state.picking_focus.is_aiming() {
|
||||
if (hid::VirtualKey::Q as u32) == vk {
|
||||
input_state.handsfree_state.grab = pressed;
|
||||
input_state.handsfree_state.grab_float = pressed;
|
||||
}
|
||||
if (hid::VirtualKey::A as u32) == vk {
|
||||
input_state.handsfree_state.grab = pressed;
|
||||
}
|
||||
if (hid::VirtualKey::W as u32) == vk {
|
||||
input_state.handsfree_state.click = pressed;
|
||||
}
|
||||
if (hid::VirtualKey::E as u32) == vk && pressed {
|
||||
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleEditMode));
|
||||
}
|
||||
if (hid::VirtualKey::D as u32) == vk && pressed {
|
||||
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleDashboard));
|
||||
}
|
||||
} else {
|
||||
self.manager.send_key(vk, pressed);
|
||||
}
|
||||
}
|
||||
input_capture::CapturedEvent::PointerButton { button, pressed } => {
|
||||
let Some(mouse_index) = Self::button_to_mouse_index(button) else {
|
||||
continue;
|
||||
};
|
||||
self.manager.send_pointer_button(mouse_index, pressed);
|
||||
if input_state.picking_focus.is_aiming() {
|
||||
match mouse_index {
|
||||
MouseIndex::Left => input_state.handsfree_state.click = pressed,
|
||||
MouseIndex::Right => {
|
||||
input_state.handsfree_state.click = pressed;
|
||||
input_state.handsfree_state.click_modifier_right = pressed;
|
||||
}
|
||||
MouseIndex::Center if pressed => {
|
||||
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleEditMode));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
self.manager.send_pointer_button(mouse_index, pressed);
|
||||
}
|
||||
}
|
||||
input_capture::CapturedEvent::PointerMotion {
|
||||
dx,
|
||||
|
|
@ -794,9 +832,16 @@ impl WvrServerState {
|
|||
x: horizontal_v120 as f32,
|
||||
y: vertical_v120 as f32,
|
||||
};
|
||||
self.manager.send_pointer_axis_wheel_raw(delta);
|
||||
if input_state.picking_focus.is_aiming() {
|
||||
input_state.handsfree_state.scroll_y = (vertical_v120 as f32) * -0.12;
|
||||
} else {
|
||||
self.manager.send_pointer_axis_wheel_raw(delta);
|
||||
}
|
||||
}
|
||||
input_capture::CapturedEvent::UngrabbedAll => {
|
||||
input_capture::CapturedEvent::Grabbed => {
|
||||
hid_wrapper.set_input_focus(Some(self), InputFocus::WayVR);
|
||||
}
|
||||
input_capture::CapturedEvent::Ungrabbed => {
|
||||
self.manager.release_all_keys();
|
||||
self.has_input_focus = false;
|
||||
self.wm.keyboard_focus = None;
|
||||
|
|
@ -808,20 +853,33 @@ impl WvrServerState {
|
|||
self.close_window(window_handle);
|
||||
}
|
||||
}
|
||||
input_capture::KeyCombo::AltTab => input_state.picking_focus = pressed,
|
||||
input_capture::KeyCombo::AltShiftTab => {
|
||||
input_state.handsfree_state.grab = pressed
|
||||
input_capture::KeyCombo::SuperTab => {
|
||||
if pressed {
|
||||
input_state.picking_focus = super::input::FocusPickState::Aiming;
|
||||
} else {
|
||||
input_state.picking_focus = super::input::FocusPickState::Picking;
|
||||
|
||||
tasks.enqueue_at(
|
||||
TaskType::Global(Box::new(|app| {
|
||||
app.input_state.picking_focus =
|
||||
super::input::FocusPickState::None;
|
||||
|
||||
let _ = std::mem::take(&mut app.input_state.handsfree_state);
|
||||
})),
|
||||
Instant::now() + Duration::from_millis(33),
|
||||
);
|
||||
}
|
||||
}
|
||||
input_capture::KeyCombo::Super1 => {
|
||||
input_capture::KeyCombo::Super1 if pressed => {
|
||||
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(0)))
|
||||
}
|
||||
input_capture::KeyCombo::Super2 => {
|
||||
input_capture::KeyCombo::Super2 if pressed => {
|
||||
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(1)))
|
||||
}
|
||||
input_capture::KeyCombo::Super3 => {
|
||||
input_capture::KeyCombo::Super3 if pressed => {
|
||||
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(2)))
|
||||
}
|
||||
input_capture::KeyCombo::Super4 => {
|
||||
input_capture::KeyCombo::Super4 if pressed => {
|
||||
tasks.enqueue(TaskType::Overlay(OverlayTask::ToggleSet(3)))
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -881,6 +939,7 @@ impl WvrServerState {
|
|||
}
|
||||
}
|
||||
|
||||
/// Use HidWrapper::set_input_focus instead!!!
|
||||
pub fn set_input_focus(&mut self, has_focus: bool) {
|
||||
let Some(input_capture) = self.input_capture.as_mut() else {
|
||||
return;
|
||||
|
|
@ -982,7 +1041,7 @@ impl WvrServerState {
|
|||
target: PointerFocusTarget,
|
||||
global_pos: Vec2,
|
||||
hover_window: window::WindowHandle,
|
||||
force_focus: bool,
|
||||
picking_focus: bool,
|
||||
) {
|
||||
if self.mouse_freeze > Instant::now() {
|
||||
return;
|
||||
|
|
@ -990,7 +1049,7 @@ impl WvrServerState {
|
|||
|
||||
let global_pos = DVec2::from(global_pos);
|
||||
|
||||
let (focus, focus_keyboard) = self.get_mouse_focus(target, hover_window, force_focus);
|
||||
let (focus, focus_keyboard) = self.get_mouse_focus(target, hover_window, picking_focus);
|
||||
if focus_keyboard.is_some() {
|
||||
self.manager.seat_keyboard.set_focus(
|
||||
&mut self.manager.state,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::backend::wayvr::{self, WvrServerState};
|
||||
|
||||
use crate::subsystem::input::{HidWrapper, InputFocus};
|
||||
use crate::{
|
||||
backend::input::InputState,
|
||||
ipc::{event_queue::SyncEventQueue, signal::WayVRSignal},
|
||||
|
|
@ -86,6 +87,7 @@ pub struct TickParams<'a> {
|
|||
pub tasks: &'a mut Vec<wayvr::TickTask>,
|
||||
pub signals: &'a SyncEventQueue<WayVRSignal>,
|
||||
pub input_state: &'a InputState,
|
||||
pub hid_wrapper: &'a mut HidWrapper,
|
||||
}
|
||||
|
||||
pub fn gen_args_vec(input: &str) -> Vec<&str> {
|
||||
|
|
@ -335,7 +337,14 @@ impl Connection {
|
|||
}
|
||||
|
||||
fn handle_wvr_input_capture(params: &mut TickParams, grab: bool) {
|
||||
params.wvr_server.set_input_focus(grab);
|
||||
let val = if grab {
|
||||
InputFocus::WayVR
|
||||
} else {
|
||||
InputFocus::PhysicalScreen
|
||||
};
|
||||
params
|
||||
.hid_wrapper
|
||||
.set_input_focus(Some(params.wvr_server), val);
|
||||
}
|
||||
|
||||
fn handle_wlx_device_haptics(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use wlx_capture::{WlxCapture, frame::Transform};
|
|||
use crate::{
|
||||
backend::{
|
||||
XrBackend,
|
||||
input::{HoverResult, PointerHit, PointerMode},
|
||||
input::{self, HoverResult, PointerHit, PointerMode},
|
||||
},
|
||||
overlays::screen::capture::MyFirstDmaExporter,
|
||||
state::AppState,
|
||||
|
|
@ -302,7 +302,9 @@ impl OverlayBackend for ScreenBackend {
|
|||
#[cfg(debug_assertions)]
|
||||
log::trace!("Hover: {:?}", hit.uv);
|
||||
|
||||
if app.input_state.picking_focus {
|
||||
let pick_now = app.input_state.picking_focus.is_picking();
|
||||
if pick_now {
|
||||
app.input_state.picking_focus = input::FocusPickState::None;
|
||||
app.hid_provider
|
||||
.set_input_focus(app.wvr_server.as_mut(), InputFocus::PhysicalScreen);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -845,7 +845,9 @@ impl OverlayBackend for WvrWindowBackend {
|
|||
self.panel_hovered = false;
|
||||
}
|
||||
|
||||
if app.input_state.picking_focus {
|
||||
let pick_now = app.input_state.picking_focus.is_picking();
|
||||
if pick_now {
|
||||
app.input_state.picking_focus = input::FocusPickState::None;
|
||||
app.hid_provider
|
||||
.set_input_focus(app.wvr_server.as_mut(), InputFocus::WayVR);
|
||||
}
|
||||
|
|
@ -855,7 +857,7 @@ impl OverlayBackend for WvrWindowBackend {
|
|||
PointerFocusTarget::Surface { surface, origin },
|
||||
global_pos,
|
||||
self.window,
|
||||
app.input_state.picking_focus,
|
||||
pick_now,
|
||||
);
|
||||
|
||||
HoverResult::consume()
|
||||
|
|
@ -866,7 +868,9 @@ impl OverlayBackend for WvrWindowBackend {
|
|||
self.panel_hovered = false;
|
||||
}
|
||||
|
||||
if app.input_state.picking_focus {
|
||||
let pick_now = app.input_state.picking_focus.is_picking();
|
||||
if pick_now {
|
||||
app.input_state.picking_focus = input::FocusPickState::None;
|
||||
app.hid_provider
|
||||
.set_input_focus(app.wvr_server.as_mut(), InputFocus::WayVR);
|
||||
}
|
||||
|
|
@ -876,7 +880,7 @@ impl OverlayBackend for WvrWindowBackend {
|
|||
PointerFocusTarget::Toplevel,
|
||||
pos,
|
||||
self.window,
|
||||
app.input_state.picking_focus,
|
||||
pick_now,
|
||||
);
|
||||
|
||||
HoverResult::consume()
|
||||
|
|
|
|||
Loading…
Reference in New Issue