config: Add invert_scroll_direction and scroll_speed
This commit is contained in:
@@ -134,7 +134,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.push_event(
|
.push_event(
|
||||||
&wgui::event::Event::MouseWheel(MouseWheelEvent {
|
&wgui::event::Event::MouseWheel(MouseWheelEvent {
|
||||||
shift: Vec2::new(x, y),
|
delta: Vec2::new(x, y),
|
||||||
pos: mouse / scale,
|
pos: mouse / scale,
|
||||||
device: 0,
|
device: 0,
|
||||||
}),
|
}),
|
||||||
@@ -149,7 +149,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.push_event(
|
.push_event(
|
||||||
&wgui::event::Event::MouseWheel(MouseWheelEvent {
|
&wgui::event::Event::MouseWheel(MouseWheelEvent {
|
||||||
shift: Vec2::new(pos.x as f32 / 5.0, pos.y as f32 / 5.0),
|
delta: Vec2::new(pos.x as f32 / 5.0, pos.y as f32 / 5.0),
|
||||||
pos: mouse / scale,
|
pos: mouse / scale,
|
||||||
device: 0,
|
device: 0,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ pub struct MouseUpEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct MouseWheelEvent {
|
pub struct MouseWheelEvent {
|
||||||
pub pos: Vec2,
|
pub pos: Vec2, /* mouse position */
|
||||||
pub shift: Vec2,
|
pub delta: Vec2, /* wheel delta */
|
||||||
pub device: usize,
|
pub device: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ impl WidgetState {
|
|||||||
if info.handle_size.x < 1.0 && wheel.pos.x != 0.0 {
|
if info.handle_size.x < 1.0 && wheel.pos.x != 0.0 {
|
||||||
// Horizontal scrolling
|
// Horizontal scrolling
|
||||||
let mult = (1.0 / (l.content_box_width() - info.content_size.x)) * step_pixels;
|
let mult = (1.0 / (l.content_box_width() - info.content_size.x)) * step_pixels;
|
||||||
let new_scroll = (self.data.scrolling_target.x + wheel.shift.x * mult).clamp(0.0, 1.0);
|
let new_scroll = (self.data.scrolling_target.x + wheel.delta.x * mult).clamp(0.0, 1.0);
|
||||||
if self.data.scrolling_target.x != new_scroll {
|
if self.data.scrolling_target.x != new_scroll {
|
||||||
self.data.scrolling_target.x = new_scroll;
|
self.data.scrolling_target.x = new_scroll;
|
||||||
params.alterables.mark_tick(self.obj.get_id());
|
params.alterables.mark_tick(self.obj.get_id());
|
||||||
@@ -405,7 +405,7 @@ impl WidgetState {
|
|||||||
if info.handle_size.y < 1.0 && wheel.pos.y != 0.0 {
|
if info.handle_size.y < 1.0 && wheel.pos.y != 0.0 {
|
||||||
// Vertical scrolling
|
// Vertical scrolling
|
||||||
let mult = (1.0 / (l.content_box_height() - info.content_size.y)) * step_pixels;
|
let mult = (1.0 / (l.content_box_height() - info.content_size.y)) * step_pixels;
|
||||||
let new_scroll = (self.data.scrolling_target.y + wheel.shift.y * mult).clamp(0.0, 1.0);
|
let new_scroll = (self.data.scrolling_target.y + wheel.delta.y * mult).clamp(0.0, 1.0);
|
||||||
if self.data.scrolling_target.y != new_scroll {
|
if self.data.scrolling_target.y != new_scroll {
|
||||||
self.data.scrolling_target.y = new_scroll;
|
self.data.scrolling_target.y = new_scroll;
|
||||||
params.alterables.mark_tick(self.obj.get_id());
|
params.alterables.mark_tick(self.obj.get_id());
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ use std::{collections::VecDeque, time::Instant};
|
|||||||
|
|
||||||
use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles};
|
use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles};
|
||||||
|
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{SmallVec, smallvec};
|
||||||
|
|
||||||
use crate::overlays::anchor::ANCHOR_NAME;
|
use crate::overlays::anchor::ANCHOR_NAME;
|
||||||
use crate::state::{AppSession, AppState};
|
use crate::state::{AppSession, AppState};
|
||||||
|
use crate::subsystem::hid::WheelDelta;
|
||||||
use crate::subsystem::input::KeyboardFocus;
|
use crate::subsystem::input::KeyboardFocus;
|
||||||
use crate::windowing::manager::OverlayWindowManager;
|
use crate::windowing::manager::OverlayWindowManager;
|
||||||
use crate::windowing::window::{OverlayWindowData, OverlayWindowState, Positioning};
|
use crate::windowing::window::{OverlayWindowData, OverlayWindowState, Positioning};
|
||||||
@@ -450,37 +451,58 @@ fn handle_no_hit<O>(
|
|||||||
|
|
||||||
fn handle_scroll<O>(hit: &PointerHit, hovered: &mut OverlayWindowData<O>, app: &mut AppState) {
|
fn handle_scroll<O>(hit: &PointerHit, hovered: &mut OverlayWindowData<O>, app: &mut AppState) {
|
||||||
let pointer = &mut app.input_state.pointers[hit.pointer];
|
let pointer = &mut app.input_state.pointers[hit.pointer];
|
||||||
if pointer.now.scroll_x.abs() > 0.1 || pointer.now.scroll_y.abs() > 0.1 {
|
if pointer.now.scroll_x.abs() <= 0.1 && pointer.now.scroll_x.abs() <= 0.1 {
|
||||||
let scroll_x = pointer.now.scroll_x;
|
return;
|
||||||
let scroll_y = pointer.now.scroll_y;
|
}
|
||||||
if app.input_state.pointers[1 - hit.pointer]
|
|
||||||
.interaction
|
|
||||||
.grabbed
|
|
||||||
.is_some_and(|x| x.grabbed_id == hit.overlay)
|
|
||||||
{
|
|
||||||
let can_curve = hovered
|
|
||||||
.frame_meta()
|
|
||||||
.is_some_and(|e| e.extent[0] >= e.extent[1]);
|
|
||||||
|
|
||||||
// re-borrow
|
let config = &app.session.config;
|
||||||
let hovered_state = hovered.config.active_state.as_mut().unwrap();
|
|
||||||
if can_curve {
|
let scroll_x = pointer.now.scroll_x
|
||||||
let cur = hovered_state.curvature.unwrap_or(0.0);
|
* config.scroll_speed
|
||||||
let new = scroll_y.mul_add(-0.01, cur).min(0.5);
|
* if config.invert_scroll_direction_x {
|
||||||
if new <= f32::EPSILON {
|
-1.0
|
||||||
hovered_state.curvature = None;
|
} else {
|
||||||
} else {
|
1.0
|
||||||
hovered_state.curvature = Some(new);
|
};
|
||||||
}
|
let scroll_y = pointer.now.scroll_y
|
||||||
} else {
|
* config.scroll_speed
|
||||||
|
* if config.invert_scroll_direction_x {
|
||||||
|
-1.0
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
|
||||||
|
if app.input_state.pointers[1 - hit.pointer]
|
||||||
|
.interaction
|
||||||
|
.grabbed
|
||||||
|
.is_some_and(|x| x.grabbed_id == hit.overlay)
|
||||||
|
{
|
||||||
|
let can_curve = hovered
|
||||||
|
.frame_meta()
|
||||||
|
.is_some_and(|e| e.extent[0] >= e.extent[1]);
|
||||||
|
|
||||||
|
// re-borrow
|
||||||
|
let hovered_state = hovered.config.active_state.as_mut().unwrap();
|
||||||
|
if can_curve {
|
||||||
|
let cur = hovered_state.curvature.unwrap_or(0.0);
|
||||||
|
let new = scroll_y.mul_add(-0.01, cur).min(0.5);
|
||||||
|
if new <= f32::EPSILON {
|
||||||
hovered_state.curvature = None;
|
hovered_state.curvature = None;
|
||||||
|
} else {
|
||||||
|
hovered_state.curvature = Some(new);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hovered
|
hovered_state.curvature = None;
|
||||||
.config
|
|
||||||
.backend
|
|
||||||
.on_scroll(app, hit, scroll_y, scroll_x);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
hovered.config.backend.on_scroll(
|
||||||
|
app,
|
||||||
|
hit,
|
||||||
|
WheelDelta {
|
||||||
|
x: scroll_x,
|
||||||
|
y: scroll_y,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use ash::vk::SubmitInfo;
|
use ash::vk::SubmitInfo;
|
||||||
use glam::{Affine3A, Vec3, Vec3A, Vec4};
|
use glam::{Affine3A, Vec3, Vec3A, Vec4};
|
||||||
@@ -8,6 +8,7 @@ use idmap::IdMap;
|
|||||||
use ovr_overlay::overlay::OverlayManager;
|
use ovr_overlay::overlay::OverlayManager;
|
||||||
use ovr_overlay::sys::ETrackingUniverseOrigin;
|
use ovr_overlay::sys::ETrackingUniverseOrigin;
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
|
VulkanObject,
|
||||||
command_buffer::{
|
command_buffer::{
|
||||||
CommandBufferBeginInfo, CommandBufferLevel, CommandBufferUsage, RecordingCommandBuffer,
|
CommandBufferBeginInfo, CommandBufferLevel, CommandBufferUsage, RecordingCommandBuffer,
|
||||||
},
|
},
|
||||||
@@ -15,19 +16,19 @@ use vulkano::{
|
|||||||
image::view::ImageView,
|
image::view::ImageView,
|
||||||
image::{Image, ImageLayout},
|
image::{Image, ImageLayout},
|
||||||
sync::{
|
sync::{
|
||||||
fence::{Fence, FenceCreateInfo},
|
|
||||||
AccessFlags, DependencyInfo, ImageMemoryBarrier, PipelineStages,
|
AccessFlags, DependencyInfo, ImageMemoryBarrier, PipelineStages,
|
||||||
|
fence::{Fence, FenceCreateInfo},
|
||||||
},
|
},
|
||||||
VulkanObject,
|
|
||||||
};
|
};
|
||||||
use wgui::gfx::WGfx;
|
use wgui::gfx::WGfx;
|
||||||
|
|
||||||
use crate::backend::input::{HoverResult, PointerHit};
|
use crate::backend::input::{HoverResult, PointerHit};
|
||||||
use crate::graphics::CommandBuffers;
|
use crate::graphics::CommandBuffers;
|
||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
|
use crate::subsystem::hid::WheelDelta;
|
||||||
|
use crate::windowing::Z_ORDER_LINES;
|
||||||
use crate::windowing::backend::{FrameMeta, OverlayBackend, ShouldRender};
|
use crate::windowing::backend::{FrameMeta, OverlayBackend, ShouldRender};
|
||||||
use crate::windowing::window::{OverlayWindowConfig, OverlayWindowData};
|
use crate::windowing::window::{OverlayWindowConfig, OverlayWindowData};
|
||||||
use crate::windowing::Z_ORDER_LINES;
|
|
||||||
|
|
||||||
use super::overlay::OpenVrOverlayData;
|
use super::overlay::OpenVrOverlayData;
|
||||||
|
|
||||||
@@ -209,7 +210,7 @@ impl OverlayBackend for LineBackend {
|
|||||||
}
|
}
|
||||||
fn on_left(&mut self, _: &mut AppState, _: usize) {}
|
fn on_left(&mut self, _: &mut AppState, _: usize) {}
|
||||||
fn on_pointer(&mut self, _: &mut AppState, _: &PointerHit, _: bool) {}
|
fn on_pointer(&mut self, _: &mut AppState, _: &PointerHit, _: bool) {}
|
||||||
fn on_scroll(&mut self, _: &mut AppState, _: &PointerHit, _: f32, _: f32) {}
|
fn on_scroll(&mut self, _: &mut AppState, _: &PointerHit, _delta: WheelDelta) {}
|
||||||
fn get_interaction_transform(&mut self) -> Option<glam::Affine2> {
|
fn get_interaction_transform(&mut self) -> Option<glam::Affine2> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ use std::{cell::RefCell, rc::Rc, sync::Arc};
|
|||||||
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::{
|
backend::renderer::{
|
||||||
element::{
|
|
||||||
surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement},
|
|
||||||
Kind,
|
|
||||||
},
|
|
||||||
gles::{ffi, GlesRenderer, GlesTexture},
|
|
||||||
utils::draw_render_elements,
|
|
||||||
Bind, Color32F, Frame, Renderer,
|
Bind, Color32F, Frame, Renderer,
|
||||||
|
element::{
|
||||||
|
Kind,
|
||||||
|
surface::{WaylandSurfaceRenderElement, render_elements_from_surface_tree},
|
||||||
|
},
|
||||||
|
gles::{GlesRenderer, GlesTexture, ffi},
|
||||||
|
utils::draw_render_elements,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
utils::{Logical, Point, Rectangle, Size, Transform},
|
utils::{Logical, Point, Rectangle, Size, Transform},
|
||||||
@@ -16,11 +16,13 @@ use smithay::{
|
|||||||
};
|
};
|
||||||
use wayvr_ipc::packet_server;
|
use wayvr_ipc::packet_server;
|
||||||
|
|
||||||
use crate::{backend::wayvr::time::get_millis, gen_id, windowing::OverlayID};
|
use crate::{
|
||||||
|
backend::wayvr::time::get_millis, gen_id, subsystem::hid::WheelDelta, windowing::OverlayID,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
client::WayVRCompositor, comp::send_frames_surface_tree, egl_data, event_queue::SyncEventQueue,
|
BlitMethod, WayVRSignal, client::WayVRCompositor, comp::send_frames_surface_tree, egl_data,
|
||||||
process, smithay_wrapper, time, window, BlitMethod, WayVRSignal,
|
event_queue::SyncEventQueue, process, smithay_wrapper, time, window,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn generate_auth_key() -> String {
|
fn generate_auth_key() -> String {
|
||||||
@@ -527,7 +529,7 @@ impl Display {
|
|||||||
manager.seat_pointer.frame(&mut manager.state);
|
manager.seat_pointer.frame(&mut manager.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_mouse_scroll(manager: &mut WayVRCompositor, delta_y: f32, delta_x: f32) {
|
pub fn send_mouse_scroll(manager: &mut WayVRCompositor, delta: WheelDelta) {
|
||||||
manager.seat_pointer.axis(
|
manager.seat_pointer.axis(
|
||||||
&mut manager.state,
|
&mut manager.state,
|
||||||
input::pointer::AxisFrame {
|
input::pointer::AxisFrame {
|
||||||
@@ -537,8 +539,8 @@ impl Display {
|
|||||||
smithay::backend::input::AxisRelativeDirection::Identical,
|
smithay::backend::input::AxisRelativeDirection::Identical,
|
||||||
),
|
),
|
||||||
time: 0,
|
time: 0,
|
||||||
axis: (f64::from(delta_x), f64::from(-delta_y)),
|
axis: (f64::from(delta.x), f64::from(-delta.y)),
|
||||||
v120: Some((0, (delta_y * -120.0) as i32)),
|
v120: Some((0, (delta.y * -64.0) as i32)),
|
||||||
stop: (false, false),
|
stop: (false, false),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -42,7 +42,10 @@ use std::{
|
|||||||
use time::get_millis;
|
use time::get_millis;
|
||||||
use wayvr_ipc::{packet_client, packet_server};
|
use wayvr_ipc::{packet_client, packet_server};
|
||||||
|
|
||||||
use crate::{state::AppState, subsystem::hid::MODS_TO_KEYS};
|
use crate::{
|
||||||
|
state::AppState,
|
||||||
|
subsystem::hid::{MODS_TO_KEYS, WheelDelta},
|
||||||
|
};
|
||||||
|
|
||||||
const STR_INVALID_HANDLE_DISP: &str = "Invalid display handle";
|
const STR_INVALID_HANDLE_DISP: &str = "Invalid display handle";
|
||||||
|
|
||||||
@@ -507,8 +510,8 @@ impl WayVRState {
|
|||||||
Display::send_mouse_up(&mut self.manager, index);
|
Display::send_mouse_up(&mut self.manager, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_mouse_scroll(&mut self, delta_y: f32, delta_x: f32) {
|
pub fn send_mouse_scroll(&mut self, delta: WheelDelta) {
|
||||||
Display::send_mouse_scroll(&mut self.manager, delta_y, delta_x);
|
Display::send_mouse_scroll(&mut self.manager, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_key(&mut self, virtual_key: u32, down: bool) {
|
pub fn send_key(&mut self, virtual_key: u32, down: bool) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::state::LeftRight;
|
|||||||
use crate::windowing::set::SerializedWindowSet;
|
use crate::windowing::set::SerializedWindowSet;
|
||||||
use chrono::Offset;
|
use chrono::Offset;
|
||||||
use config::{Config, File};
|
use config::{Config, File};
|
||||||
use glam::{vec3, Affine3A, Quat, Vec3};
|
use glam::{Affine3A, Quat, Vec3, vec3};
|
||||||
use idmap::IdMap;
|
use idmap::IdMap;
|
||||||
use log::error;
|
use log::error;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -193,6 +193,15 @@ pub struct GeneralConfig {
|
|||||||
#[serde(default = "def_click_freeze_time_ms")]
|
#[serde(default = "def_click_freeze_time_ms")]
|
||||||
pub click_freeze_time_ms: u32,
|
pub click_freeze_time_ms: u32,
|
||||||
|
|
||||||
|
#[serde(default = "def_false")]
|
||||||
|
pub invert_scroll_direction_x: bool,
|
||||||
|
|
||||||
|
#[serde(default = "def_false")]
|
||||||
|
pub invert_scroll_direction_y: bool,
|
||||||
|
|
||||||
|
#[serde(default = "def_one")]
|
||||||
|
pub scroll_speed: f32,
|
||||||
|
|
||||||
#[serde(default = "def_mouse_move_interval_ms")]
|
#[serde(default = "def_mouse_move_interval_ms")]
|
||||||
pub mouse_move_interval_ms: u32,
|
pub mouse_move_interval_ms: u32,
|
||||||
|
|
||||||
@@ -343,6 +352,7 @@ impl GeneralConfig {
|
|||||||
fn post_load(&self) {
|
fn post_load(&self) {
|
||||||
Self::sanitize_range("keyboard_scale", self.keyboard_scale, 0.05, 5.0);
|
Self::sanitize_range("keyboard_scale", self.keyboard_scale, 0.05, 5.0);
|
||||||
Self::sanitize_range("desktop_view_scale", self.desktop_view_scale, 0.05, 5.0);
|
Self::sanitize_range("desktop_view_scale", self.desktop_view_scale, 0.05, 5.0);
|
||||||
|
Self::sanitize_range("scroll_speed", self.scroll_speed, 0.01, 10.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use button::setup_custom_button;
|
use button::setup_custom_button;
|
||||||
use glam::{vec2, Affine2, Vec2};
|
use glam::{Affine2, Vec2, vec2};
|
||||||
use label::setup_custom_label;
|
use label::setup_custom_label;
|
||||||
use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
@@ -15,14 +15,15 @@ use wgui::{
|
|||||||
layout::{Layout, LayoutParams, WidgetID},
|
layout::{Layout, LayoutParams, WidgetID},
|
||||||
parser::ParserState,
|
parser::ParserState,
|
||||||
renderer_vk::context::Context as WguiContext,
|
renderer_vk::context::Context as WguiContext,
|
||||||
widget::{label::WidgetLabel, rectangle::WidgetRectangle, EventResult},
|
widget::{EventResult, label::WidgetLabel, rectangle::WidgetRectangle},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{Haptics, HoverResult, PointerHit, PointerMode},
|
backend::input::{Haptics, HoverResult, PointerHit, PointerMode},
|
||||||
graphics::{CommandBuffers, ExtentExt},
|
graphics::{CommandBuffers, ExtentExt},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
windowing::backend::{ui_transform, FrameMeta, OverlayBackend, ShouldRender},
|
subsystem::hid::WheelDelta,
|
||||||
|
windowing::backend::{FrameMeta, OverlayBackend, ShouldRender, ui_transform},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{timer::GuiTimer, timestep::Timestep};
|
use super::{timer::GuiTimer, timestep::Timestep};
|
||||||
@@ -270,9 +271,9 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) {
|
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta) {
|
||||||
let e = WguiEvent::MouseWheel(MouseWheelEvent {
|
let e = WguiEvent::MouseWheel(MouseWheelEvent {
|
||||||
shift: vec2(delta_x, delta_y),
|
delta: vec2(delta.x, delta.y),
|
||||||
pos: hit.uv * self.layout.content_size,
|
pos: hit.uv * self.layout.content_size,
|
||||||
device: hit.pointer,
|
device: hit.pointer,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use crate::{
|
|||||||
graphics::CommandBuffers,
|
graphics::CommandBuffers,
|
||||||
gui::panel::GuiPanel,
|
gui::panel::GuiPanel,
|
||||||
state::AppState,
|
state::AppState,
|
||||||
subsystem::hid::{KeyModifier, VirtualKey, ALT, CTRL, META, SHIFT, SUPER},
|
subsystem::hid::{ALT, CTRL, KeyModifier, META, SHIFT, SUPER, VirtualKey, WheelDelta},
|
||||||
windowing::backend::{FrameMeta, OverlayBackend, ShouldRender},
|
windowing::backend::{FrameMeta, OverlayBackend, ShouldRender},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,8 +69,8 @@ impl OverlayBackend for KeyboardBackend {
|
|||||||
&wgui::event::Event::InternalStateChange(InternalStateChangeEvent { metadata: 0 }),
|
&wgui::event::Event::InternalStateChange(InternalStateChangeEvent { metadata: 0 }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) {
|
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta) {
|
||||||
self.panel.on_scroll(app, hit, delta_y, delta_x);
|
self.panel.on_scroll(app, hit, delta);
|
||||||
}
|
}
|
||||||
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
||||||
self.panel.on_left(app, pointer);
|
self.panel.on_left(app, pointer);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::{
|
|||||||
use futures::{Future, FutureExt};
|
use futures::{Future, FutureExt};
|
||||||
use glam::{Affine2, Affine3A, Vec3};
|
use glam::{Affine2, Affine3A, Vec3};
|
||||||
use vulkano::image::view::ImageView;
|
use vulkano::image::view::ImageView;
|
||||||
use wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture, PipewireSelectScreenResult};
|
use wlx_capture::pipewire::{PipewireCapture, PipewireSelectScreenResult, pipewire_select_screen};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
@@ -15,10 +15,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
graphics::CommandBuffers,
|
graphics::CommandBuffers,
|
||||||
state::{AppSession, AppState},
|
state::{AppSession, AppState},
|
||||||
|
subsystem::hid::WheelDelta,
|
||||||
windowing::{
|
windowing::{
|
||||||
backend::{ui_transform, FrameMeta, OverlayBackend, ShouldRender},
|
|
||||||
window::{OverlayWindowConfig, OverlayWindowState},
|
|
||||||
OverlaySelector,
|
OverlaySelector,
|
||||||
|
backend::{FrameMeta, OverlayBackend, ShouldRender, ui_transform},
|
||||||
|
window::{OverlayWindowConfig, OverlayWindowState},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -138,7 +139,7 @@ impl OverlayBackend for MirrorBackend {
|
|||||||
}
|
}
|
||||||
fn on_left(&mut self, _: &mut AppState, _: usize) {}
|
fn on_left(&mut self, _: &mut AppState, _: usize) {}
|
||||||
fn on_pointer(&mut self, _: &mut AppState, _: &PointerHit, _: bool) {}
|
fn on_pointer(&mut self, _: &mut AppState, _: &PointerHit, _: bool) {}
|
||||||
fn on_scroll(&mut self, _: &mut AppState, _: &PointerHit, _: f32, _: f32) {}
|
fn on_scroll(&mut self, _: &mut AppState, _: &PointerHit, _delta: WheelDelta) {}
|
||||||
fn get_interaction_transform(&mut self) -> Option<Affine2> {
|
fn get_interaction_transform(&mut self) -> Option<Affine2> {
|
||||||
self.interaction_transform
|
self.interaction_transform
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
use std::{
|
use std::{
|
||||||
sync::{atomic::AtomicU64, Arc, LazyLock},
|
sync::{Arc, LazyLock, atomic::AtomicU64},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
use glam::{vec2, Affine2, Vec2};
|
use glam::{Affine2, Vec2, vec2};
|
||||||
use vulkano::image::view::ImageView;
|
use vulkano::image::view::ImageView;
|
||||||
use wlx_capture::{frame::Transform, WlxCapture};
|
use wlx_capture::{WlxCapture, frame::Transform};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{HoverResult, PointerHit, PointerMode},
|
backend::input::{HoverResult, PointerHit, PointerMode},
|
||||||
graphics::{CommandBuffers, ExtentExt},
|
graphics::{CommandBuffers, ExtentExt},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
subsystem::hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
|
subsystem::hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, WheelDelta},
|
||||||
windowing::backend::{FrameMeta, OverlayBackend, ShouldRender},
|
windowing::backend::{FrameMeta, OverlayBackend, ShouldRender},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::capture::{receive_callback, ScreenPipeline, WlxCaptureIn, WlxCaptureOut};
|
use super::capture::{ScreenPipeline, WlxCaptureIn, WlxCaptureOut, receive_callback};
|
||||||
|
|
||||||
const CURSOR_SIZE: f32 = 16. / 1440.;
|
const CURSOR_SIZE: f32 = 16. / 1440.;
|
||||||
|
|
||||||
@@ -246,11 +246,11 @@ impl OverlayBackend for ScreenBackend {
|
|||||||
let pos = self.mouse_transform.transform_point2(hit.uv);
|
let pos = self.mouse_transform.transform_point2(hit.uv);
|
||||||
app.hid_provider.inner.mouse_move(pos);
|
app.hid_provider.inner.mouse_move(pos);
|
||||||
}
|
}
|
||||||
fn on_scroll(&mut self, app: &mut AppState, _hit: &PointerHit, delta_y: f32, delta_x: f32) {
|
|
||||||
app.hid_provider
|
fn on_scroll(&mut self, app: &mut AppState, _hit: &PointerHit, delta: WheelDelta) {
|
||||||
.inner
|
app.hid_provider.inner.wheel(delta);
|
||||||
.wheel((delta_y * 64.) as i32, (delta_x * 64.) as i32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_left(&mut self, _app: &mut AppState, _hand: usize) {}
|
fn on_left(&mut self, _app: &mut AppState, _hand: usize) {}
|
||||||
|
|
||||||
fn get_interaction_transform(&mut self) -> Option<Affine2> {
|
fn get_interaction_transform(&mut self) -> Option<Affine2> {
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
use glam::{vec3, Affine2, Affine3A, Quat, Vec3};
|
use glam::{Affine2, Affine3A, Quat, Vec3, vec3};
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::{BufferUsage, Subbuffer},
|
buffer::{BufferUsage, Subbuffer},
|
||||||
command_buffer::CommandBufferUsage,
|
command_buffer::CommandBufferUsage,
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, Image, ImageTiling, SubresourceLayout},
|
image::{Image, ImageTiling, SubresourceLayout, view::ImageView},
|
||||||
};
|
};
|
||||||
use wayvr_ipc::packet_server::{self, PacketServer, WvrStateChanged};
|
use wayvr_ipc::packet_server::{self, PacketServer, WvrStateChanged};
|
||||||
use wgui::gfx::{
|
use wgui::gfx::{
|
||||||
|
WGfx,
|
||||||
pass::WGfxPass,
|
pass::WGfxPass,
|
||||||
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
||||||
WGfx,
|
|
||||||
};
|
};
|
||||||
use wlx_capture::frame::{DmabufFrame, FourCC, FrameFormat, FramePlane};
|
use wlx_capture::frame::{DmabufFrame, FourCC, FrameFormat, FramePlane};
|
||||||
|
|
||||||
@@ -20,20 +20,19 @@ use crate::{
|
|||||||
input::{self, HoverResult},
|
input::{self, HoverResult},
|
||||||
task::TaskType,
|
task::TaskType,
|
||||||
wayvr::{
|
wayvr::{
|
||||||
self, display,
|
self, WayVR, WayVRAction, WayVRDisplayClickAction, display,
|
||||||
server_ipc::{gen_args_vec, gen_env_vec},
|
server_ipc::{gen_args_vec, gen_env_vec},
|
||||||
WayVR, WayVRAction, WayVRDisplayClickAction,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
config_wayvr,
|
config_wayvr,
|
||||||
graphics::{dmabuf::WGfxDmabuf, CommandBuffers, Vert2Uv},
|
graphics::{CommandBuffers, Vert2Uv, dmabuf::WGfxDmabuf},
|
||||||
state::{self, AppState},
|
state::{self, AppState},
|
||||||
subsystem::input::KeyboardFocus,
|
subsystem::{hid::WheelDelta, input::KeyboardFocus},
|
||||||
windowing::{
|
windowing::{
|
||||||
backend::{ui_transform, FrameMeta, OverlayBackend, ShouldRender},
|
OverlayID, OverlaySelector, Z_ORDER_DASHBOARD,
|
||||||
|
backend::{FrameMeta, OverlayBackend, ShouldRender, ui_transform},
|
||||||
manager::OverlayWindowManager,
|
manager::OverlayWindowManager,
|
||||||
window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState},
|
window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState},
|
||||||
OverlayID, OverlaySelector, Z_ORDER_DASHBOARD,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -770,15 +769,10 @@ impl OverlayBackend for WayVRBackend {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_app: &mut state::AppState,
|
_app: &mut state::AppState,
|
||||||
_hit: &input::PointerHit,
|
_hit: &input::PointerHit,
|
||||||
delta_y: f32,
|
delta: WheelDelta,
|
||||||
delta_x: f32,
|
|
||||||
) {
|
) {
|
||||||
let ctx = self.context.borrow();
|
let ctx = self.context.borrow();
|
||||||
ctx.wayvr
|
ctx.wayvr.borrow_mut().data.state.send_mouse_scroll(delta);
|
||||||
.borrow_mut()
|
|
||||||
.data
|
|
||||||
.state
|
|
||||||
.send_mouse_scroll(delta_y, delta_x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_interaction_transform(&mut self) -> Option<Affine2> {
|
fn get_interaction_transform(&mut self) -> Option<Affine2> {
|
||||||
|
|||||||
@@ -3,6 +3,17 @@
|
|||||||
# Default: 300
|
# Default: 300
|
||||||
click_freeze_time_ms: 300
|
click_freeze_time_ms: 300
|
||||||
|
|
||||||
|
# Make scroll events inverted in X/Y axis
|
||||||
|
# Default: false
|
||||||
|
invert_scroll_direction_x: false
|
||||||
|
invert_scroll_direction_y: false
|
||||||
|
|
||||||
|
# Change speed of scrolling
|
||||||
|
# Default: 1.0
|
||||||
|
# 0.5: half the speed
|
||||||
|
# 2.0: twice the speed
|
||||||
|
scroll_speed: 1.0
|
||||||
|
|
||||||
# Default: true
|
# Default: true
|
||||||
keyboard_sound_enabled: true
|
keyboard_sound_enabled: true
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use glam::{IVec2, Vec2};
|
use glam::Vec2;
|
||||||
use idmap::{idmap, IdMap};
|
use idmap::{IdMap, idmap};
|
||||||
use idmap_derive::IntegerId;
|
use idmap_derive::IntegerId;
|
||||||
use input_linux::{
|
use input_linux::{
|
||||||
AbsoluteAxis, AbsoluteInfo, AbsoluteInfoSetup, EventKind, InputId, Key, RelativeAxis,
|
AbsoluteAxis, AbsoluteInfo, AbsoluteInfoSetup, EventKind, InputId, Key, RelativeAxis,
|
||||||
@@ -40,10 +40,15 @@ pub(super) fn initialize() -> Box<dyn HidProvider> {
|
|||||||
Box::new(DummyProvider {})
|
Box::new(DummyProvider {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct WheelDelta {
|
||||||
|
pub x: f32,
|
||||||
|
pub y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait HidProvider: Sync + Send {
|
pub trait HidProvider: Sync + Send {
|
||||||
fn mouse_move(&mut self, pos: Vec2);
|
fn mouse_move(&mut self, pos: Vec2);
|
||||||
fn send_button(&mut self, button: u16, down: bool);
|
fn send_button(&mut self, button: u16, down: bool);
|
||||||
fn wheel(&mut self, delta_y: i32, delta_x: i32);
|
fn wheel(&mut self, delta: WheelDelta);
|
||||||
fn set_modifiers(&mut self, mods: u8);
|
fn set_modifiers(&mut self, mods: u8);
|
||||||
fn send_key(&self, key: VirtualKey, down: bool);
|
fn send_key(&self, key: VirtualKey, down: bool);
|
||||||
fn set_desktop_extent(&mut self, extent: Vec2);
|
fn set_desktop_extent(&mut self, extent: Vec2);
|
||||||
@@ -61,7 +66,7 @@ struct MouseAction {
|
|||||||
last_requested_pos: Option<Vec2>,
|
last_requested_pos: Option<Vec2>,
|
||||||
pos: Option<Vec2>,
|
pos: Option<Vec2>,
|
||||||
button: Option<MouseButtonAction>,
|
button: Option<MouseButtonAction>,
|
||||||
scroll: Option<IVec2>,
|
scroll: Option<WheelDelta>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UInputProvider {
|
pub struct UInputProvider {
|
||||||
@@ -195,7 +200,12 @@ impl UInputProvider {
|
|||||||
log::error!("{res}");
|
log::error!("{res}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn wheel_internal(&self, delta_y: i32, delta_x: i32) {
|
|
||||||
|
fn wheel_internal(&self, delta: WheelDelta) {
|
||||||
|
let multiplier = 64.0; /* cherry-picked value, overall scrolling speed can be altered via `scroll_speed` in the config */
|
||||||
|
let delta_x = (delta.x * multiplier) as i32;
|
||||||
|
let delta_y = (delta.y * multiplier) as i32;
|
||||||
|
|
||||||
let time = get_time();
|
let time = get_time();
|
||||||
let events = [
|
let events = [
|
||||||
new_event(time, EV_REL, RelativeAxis::WheelHiRes as _, delta_y),
|
new_event(time, EV_REL, RelativeAxis::WheelHiRes as _, delta_y),
|
||||||
@@ -257,14 +267,16 @@ impl HidProvider for UInputProvider {
|
|||||||
self.current_action.pos = self.current_action.last_requested_pos;
|
self.current_action.pos = self.current_action.last_requested_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn wheel(&mut self, delta_y: i32, delta_x: i32) {
|
|
||||||
|
fn wheel(&mut self, delta: WheelDelta) {
|
||||||
if self.current_action.scroll.is_none() {
|
if self.current_action.scroll.is_none() {
|
||||||
self.current_action.scroll = Some(IVec2::new(delta_x, delta_y));
|
self.current_action.scroll = Some(delta);
|
||||||
// Pass mouse motion events only if not scrolling
|
// Pass mouse motion events only if not scrolling
|
||||||
// (allows scrolling on all Chromium-based applications)
|
// (allows scrolling on all Chromium-based applications)
|
||||||
self.current_action.pos = None;
|
self.current_action.pos = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit(&mut self) {
|
fn commit(&mut self) {
|
||||||
if let Some(pos) = self.current_action.pos.take() {
|
if let Some(pos) = self.current_action.pos.take() {
|
||||||
self.mouse_move_internal(pos);
|
self.mouse_move_internal(pos);
|
||||||
@@ -273,7 +285,7 @@ impl HidProvider for UInputProvider {
|
|||||||
self.send_button_internal(button.button, button.down);
|
self.send_button_internal(button.button, button.down);
|
||||||
}
|
}
|
||||||
if let Some(scroll) = self.current_action.scroll.take() {
|
if let Some(scroll) = self.current_action.scroll.take() {
|
||||||
self.wheel_internal(scroll.y, scroll.x);
|
self.wheel_internal(scroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,7 +293,7 @@ impl HidProvider for UInputProvider {
|
|||||||
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(&mut self, _button: u16, _down: bool) {}
|
fn send_button(&mut self, _button: u16, _down: bool) {}
|
||||||
fn wheel(&mut self, _delta_y: i32, _delta_x: i32) {}
|
fn wheel(&mut self, _delta: WheelDelta) {}
|
||||||
fn set_modifiers(&mut self, _modifiers: u8) {}
|
fn set_modifiers(&mut self, _modifiers: u8) {}
|
||||||
fn send_key(&self, _key: VirtualKey, _down: bool) {}
|
fn send_key(&self, _key: VirtualKey, _down: bool) {}
|
||||||
fn set_desktop_extent(&mut self, _extent: Vec2) {}
|
fn set_desktop_extent(&mut self, _extent: Vec2) {}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use crate::{
|
|||||||
backend::input::{HoverResult, PointerHit},
|
backend::input::{HoverResult, PointerHit},
|
||||||
graphics::CommandBuffers,
|
graphics::CommandBuffers,
|
||||||
state::AppState,
|
state::AppState,
|
||||||
|
subsystem::hid::WheelDelta,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy)]
|
#[derive(Default, Clone, Copy)]
|
||||||
@@ -51,7 +52,7 @@ pub trait OverlayBackend {
|
|||||||
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult;
|
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult;
|
||||||
fn on_left(&mut self, app: &mut AppState, pointer: usize);
|
fn on_left(&mut self, app: &mut AppState, pointer: usize);
|
||||||
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool);
|
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool);
|
||||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32);
|
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta);
|
||||||
fn get_interaction_transform(&mut self) -> Option<Affine2>;
|
fn get_interaction_transform(&mut self) -> Option<Affine2>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user