Merge pull request #547 from mahkoh/jorth/pointer-absolute
metal: handle absolute motion events
This commit is contained in:
commit
c61a04c3d3
10 changed files with 97 additions and 18 deletions
|
|
@ -348,6 +348,11 @@ pub enum InputEvent {
|
||||||
dx_unaccelerated: Fixed,
|
dx_unaccelerated: Fixed,
|
||||||
dy_unaccelerated: Fixed,
|
dy_unaccelerated: Fixed,
|
||||||
},
|
},
|
||||||
|
MotionAbsolute {
|
||||||
|
time_usec: u64,
|
||||||
|
x_normed: f32,
|
||||||
|
y_normed: f32,
|
||||||
|
},
|
||||||
Button {
|
Button {
|
||||||
time_usec: u64,
|
time_usec: u64,
|
||||||
button: u32,
|
button: u32,
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ impl MetalBackend {
|
||||||
c::LIBINPUT_EVENT_DEVICE_REMOVED => self.handle_li_device_removed(event),
|
c::LIBINPUT_EVENT_DEVICE_REMOVED => self.handle_li_device_removed(event),
|
||||||
c::LIBINPUT_EVENT_KEYBOARD_KEY => self.handle_keyboard_key(event),
|
c::LIBINPUT_EVENT_KEYBOARD_KEY => self.handle_keyboard_key(event),
|
||||||
c::LIBINPUT_EVENT_POINTER_MOTION => self.handle_pointer_motion(event),
|
c::LIBINPUT_EVENT_POINTER_MOTION => self.handle_pointer_motion(event),
|
||||||
|
c::LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE => self.handle_pointer_motion_absolute(event),
|
||||||
c::LIBINPUT_EVENT_POINTER_BUTTON => self.handle_pointer_button(event),
|
c::LIBINPUT_EVENT_POINTER_BUTTON => self.handle_pointer_button(event),
|
||||||
c::LIBINPUT_EVENT_POINTER_SCROLL_WHEEL => {
|
c::LIBINPUT_EVENT_POINTER_SCROLL_WHEEL => {
|
||||||
self.handle_pointer_axis(event, AxisSource::Wheel)
|
self.handle_pointer_axis(event, AxisSource::Wheel)
|
||||||
|
|
@ -248,6 +249,15 @@ impl MetalBackend {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_pointer_motion_absolute(self: &Rc<Self>, event: LibInputEvent) {
|
||||||
|
let (event, dev) = unpack!(self, event, pointer_event);
|
||||||
|
dev.event(InputEvent::MotionAbsolute {
|
||||||
|
time_usec: event.time_usec(),
|
||||||
|
x_normed: event.x_transformed(1) as f32,
|
||||||
|
y_normed: event.y_transformed(1) as f32,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_gesture_swipe_begin(self: &Rc<Self>, event: LibInputEvent) {
|
fn handle_gesture_swipe_begin(self: &Rc<Self>, event: LibInputEvent) {
|
||||||
let (event, dev) = unpack!(self, event, gesture_event);
|
let (event, dev) = unpack!(self, event, gesture_event);
|
||||||
dev.event(InputEvent::SwipeBegin {
|
dev.event(InputEvent::SwipeBegin {
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,7 @@ fn start_compositor2(
|
||||||
enable_primary_selection: Cell::new(true),
|
enable_primary_selection: Cell::new(true),
|
||||||
xdg_surface_configure_events: Default::default(),
|
xdg_surface_configure_events: Default::default(),
|
||||||
workspace_display_order: Cell::new(WorkspaceDisplayOrder::Manual),
|
workspace_display_order: Cell::new(WorkspaceDisplayOrder::Manual),
|
||||||
|
outputs_without_hc: Default::default(),
|
||||||
});
|
});
|
||||||
state.tracker.register(ClientId::from_raw(0));
|
state.tracker.register(ClientId::from_raw(0));
|
||||||
create_dummy_output(&state);
|
create_dummy_output(&state);
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ impl CursorUserGroup {
|
||||||
let x_int = x.round_down();
|
let x_int = x.round_down();
|
||||||
let y_int = y.round_down();
|
let y_int = y.round_down();
|
||||||
let extents = cursor.extents_at_scale(Scale::default());
|
let extents = cursor.extents_at_scale(Scale::default());
|
||||||
self.state.damage2(true, extents.move_(x_int, y_int));
|
self.damage(extents.move_(x_int, y_int));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,6 +248,10 @@ impl CursorUserGroup {
|
||||||
};
|
};
|
||||||
active.present_hardware_cursor(output, hc);
|
active.present_hardware_cursor(output, hc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn damage(&self, rect: Rect) {
|
||||||
|
self.state.damage2(true, self.hardware_cursor.get(), rect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CursorUser {
|
impl CursorUser {
|
||||||
|
|
@ -416,10 +420,8 @@ impl CursorUser {
|
||||||
let old_x_int = old_x.round_down();
|
let old_x_int = old_x.round_down();
|
||||||
let old_y_int = old_y.round_down();
|
let old_y_int = old_y.round_down();
|
||||||
let extents = cursor.extents_at_scale(Scale::default());
|
let extents = cursor.extents_at_scale(Scale::default());
|
||||||
self.group
|
self.group.damage(extents.move_(old_x_int, old_y_int));
|
||||||
.state
|
self.group.damage(extents.move_(x_int, y_int));
|
||||||
.damage2(true, extents.move_(old_x_int, old_y_int));
|
|
||||||
self.group.state.damage2(true, extents.move_(x_int, y_int));
|
|
||||||
}
|
}
|
||||||
self.pos.set((x, y));
|
self.pos.set((x, y));
|
||||||
self.update_hardware_cursor_(false);
|
self.update_hardware_cursor_(false);
|
||||||
|
|
@ -435,7 +437,8 @@ impl CursorUser {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn software_cursor(&self) -> bool {
|
pub fn software_cursor(&self) -> bool {
|
||||||
self.is_active() && !self.group.hardware_cursor.get()
|
self.is_active()
|
||||||
|
&& (!self.group.hardware_cursor.get() || self.group.state.outputs_without_hc.get() > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_hardware_cursor_(&self, render: bool) {
|
fn update_hardware_cursor_(&self, render: bool) {
|
||||||
|
|
|
||||||
|
|
@ -310,6 +310,7 @@ impl WlSeatGlobal {
|
||||||
InputEvent::Key { time_usec, .. }
|
InputEvent::Key { time_usec, .. }
|
||||||
| InputEvent::ConnectorPosition { time_usec, .. }
|
| InputEvent::ConnectorPosition { time_usec, .. }
|
||||||
| InputEvent::Motion { time_usec, .. }
|
| InputEvent::Motion { time_usec, .. }
|
||||||
|
| InputEvent::MotionAbsolute { time_usec, .. }
|
||||||
| InputEvent::Button { time_usec, .. }
|
| InputEvent::Button { time_usec, .. }
|
||||||
| InputEvent::AxisFrame { time_usec, .. }
|
| InputEvent::AxisFrame { time_usec, .. }
|
||||||
| InputEvent::SwipeBegin { time_usec, .. }
|
| InputEvent::SwipeBegin { time_usec, .. }
|
||||||
|
|
@ -350,6 +351,7 @@ impl WlSeatGlobal {
|
||||||
match event {
|
match event {
|
||||||
InputEvent::ConnectorPosition { .. }
|
InputEvent::ConnectorPosition { .. }
|
||||||
| InputEvent::Motion { .. }
|
| InputEvent::Motion { .. }
|
||||||
|
| InputEvent::MotionAbsolute { .. }
|
||||||
| InputEvent::Button { .. }
|
| InputEvent::Button { .. }
|
||||||
| InputEvent::AxisFrame { .. }
|
| InputEvent::AxisFrame { .. }
|
||||||
| InputEvent::SwipeBegin { .. }
|
| InputEvent::SwipeBegin { .. }
|
||||||
|
|
@ -406,6 +408,13 @@ impl WlSeatGlobal {
|
||||||
dy_unaccelerated,
|
dy_unaccelerated,
|
||||||
time_usec,
|
time_usec,
|
||||||
} => self.motion_event(time_usec, dx, dy, dx_unaccelerated, dy_unaccelerated),
|
} => self.motion_event(time_usec, dx, dy, dx_unaccelerated, dy_unaccelerated),
|
||||||
|
InputEvent::MotionAbsolute {
|
||||||
|
time_usec,
|
||||||
|
x_normed,
|
||||||
|
y_normed,
|
||||||
|
} => {
|
||||||
|
self.motion_absolute_event(time_usec, dev.get_rect(&self.state), x_normed, y_normed)
|
||||||
|
}
|
||||||
InputEvent::Button {
|
InputEvent::Button {
|
||||||
time_usec,
|
time_usec,
|
||||||
button,
|
button,
|
||||||
|
|
@ -651,6 +660,18 @@ impl WlSeatGlobal {
|
||||||
self.cursor_moved(time_usec, false);
|
self.cursor_moved(time_usec, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn motion_absolute_event(
|
||||||
|
self: &Rc<Self>,
|
||||||
|
time_usec: u64,
|
||||||
|
rect: Rect,
|
||||||
|
x_normed: f32,
|
||||||
|
y_normed: f32,
|
||||||
|
) {
|
||||||
|
let x = Fixed::from_f32(rect.x1() as f32 + x_normed * rect.width() as f32);
|
||||||
|
let y = Fixed::from_f32(rect.y1() as f32 + y_normed * rect.height() as f32);
|
||||||
|
self.motion_event_abs(time_usec, x, y, false);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn button_event(self: &Rc<Self>, time_usec: u64, button: u32, state: KeyState) {
|
pub fn button_event(self: &Rc<Self>, time_usec: u64, button: u32, state: KeyState) {
|
||||||
self.for_each_ei_seat(|ei_seat| {
|
self.for_each_ei_seat(|ei_seat| {
|
||||||
ei_seat.handle_button(time_usec, button, state);
|
ei_seat.handle_button(time_usec, button, state);
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,16 @@ use {
|
||||||
libinput_event_get_touch_event, libinput_event_get_type, libinput_event_keyboard,
|
libinput_event_get_touch_event, libinput_event_get_type, libinput_event_keyboard,
|
||||||
libinput_event_keyboard_get_key, libinput_event_keyboard_get_key_state,
|
libinput_event_keyboard_get_key, libinput_event_keyboard_get_key_state,
|
||||||
libinput_event_keyboard_get_time_usec, libinput_event_pointer,
|
libinput_event_keyboard_get_time_usec, libinput_event_pointer,
|
||||||
libinput_event_pointer_get_button, libinput_event_pointer_get_button_state,
|
libinput_event_pointer_get_absolute_x_transformed,
|
||||||
libinput_event_pointer_get_dx, libinput_event_pointer_get_dx_unaccelerated,
|
libinput_event_pointer_get_absolute_y_transformed, libinput_event_pointer_get_button,
|
||||||
libinput_event_pointer_get_dy, libinput_event_pointer_get_dy_unaccelerated,
|
libinput_event_pointer_get_button_state, libinput_event_pointer_get_dx,
|
||||||
libinput_event_pointer_get_scroll_value, libinput_event_pointer_get_scroll_value_v120,
|
libinput_event_pointer_get_dx_unaccelerated, libinput_event_pointer_get_dy,
|
||||||
libinput_event_pointer_get_time_usec, libinput_event_pointer_has_axis,
|
libinput_event_pointer_get_dy_unaccelerated, libinput_event_pointer_get_scroll_value,
|
||||||
libinput_event_switch, libinput_event_switch_get_switch,
|
libinput_event_pointer_get_scroll_value_v120, libinput_event_pointer_get_time_usec,
|
||||||
libinput_event_switch_get_switch_state, libinput_event_switch_get_time_usec,
|
libinput_event_pointer_has_axis, libinput_event_switch,
|
||||||
libinput_event_tablet_pad, libinput_event_tablet_pad_get_button_number,
|
libinput_event_switch_get_switch, libinput_event_switch_get_switch_state,
|
||||||
|
libinput_event_switch_get_time_usec, libinput_event_tablet_pad,
|
||||||
|
libinput_event_tablet_pad_get_button_number,
|
||||||
libinput_event_tablet_pad_get_button_state,
|
libinput_event_tablet_pad_get_button_state,
|
||||||
libinput_event_tablet_pad_get_dial_delta_v120,
|
libinput_event_tablet_pad_get_dial_delta_v120,
|
||||||
libinput_event_tablet_pad_get_dial_number, libinput_event_tablet_pad_get_mode,
|
libinput_event_tablet_pad_get_dial_number, libinput_event_tablet_pad_get_mode,
|
||||||
|
|
@ -186,6 +188,14 @@ impl<'a> LibInputEventKeyboard<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LibInputEventPointer<'a> {
|
impl<'a> LibInputEventPointer<'a> {
|
||||||
|
pub fn x_transformed(&self, width: u32) -> f64 {
|
||||||
|
unsafe { libinput_event_pointer_get_absolute_x_transformed(self.event, width) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn y_transformed(&self, height: u32) -> f64 {
|
||||||
|
unsafe { libinput_event_pointer_get_absolute_y_transformed(self.event, height) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dx(&self) -> f64 {
|
pub fn dx(&self) -> f64 {
|
||||||
unsafe { libinput_event_pointer_get_dx(self.event) }
|
unsafe { libinput_event_pointer_get_dx(self.event) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,14 @@ unsafe extern "C" {
|
||||||
pub fn libinput_event_pointer_get_dy(event: *mut libinput_event_pointer) -> f64;
|
pub fn libinput_event_pointer_get_dy(event: *mut libinput_event_pointer) -> f64;
|
||||||
pub fn libinput_event_pointer_get_dx_unaccelerated(event: *mut libinput_event_pointer) -> f64;
|
pub fn libinput_event_pointer_get_dx_unaccelerated(event: *mut libinput_event_pointer) -> f64;
|
||||||
pub fn libinput_event_pointer_get_dy_unaccelerated(event: *mut libinput_event_pointer) -> f64;
|
pub fn libinput_event_pointer_get_dy_unaccelerated(event: *mut libinput_event_pointer) -> f64;
|
||||||
|
pub fn libinput_event_pointer_get_absolute_x_transformed(
|
||||||
|
event: *mut libinput_event_pointer,
|
||||||
|
width: u32,
|
||||||
|
) -> f64;
|
||||||
|
pub fn libinput_event_pointer_get_absolute_y_transformed(
|
||||||
|
event: *mut libinput_event_pointer,
|
||||||
|
height: u32,
|
||||||
|
) -> f64;
|
||||||
pub fn libinput_event_pointer_get_button(event: *mut libinput_event_pointer) -> u32;
|
pub fn libinput_event_pointer_get_button(event: *mut libinput_event_pointer) -> u32;
|
||||||
pub fn libinput_event_pointer_get_button_state(
|
pub fn libinput_event_pointer_get_button_state(
|
||||||
event: *mut libinput_event_pointer,
|
event: *mut libinput_event_pointer,
|
||||||
|
|
|
||||||
10
src/state.rs
10
src/state.rs
|
|
@ -277,6 +277,7 @@ pub struct State {
|
||||||
pub enable_primary_selection: Cell<bool>,
|
pub enable_primary_selection: Cell<bool>,
|
||||||
pub xdg_surface_configure_events: AsyncQueue<XdgSurfaceConfigureEvent>,
|
pub xdg_surface_configure_events: AsyncQueue<XdgSurfaceConfigureEvent>,
|
||||||
pub workspace_display_order: Cell<WorkspaceDisplayOrder>,
|
pub workspace_display_order: Cell<WorkspaceDisplayOrder>,
|
||||||
|
pub outputs_without_hc: NumCell<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Drop for State {
|
// impl Drop for State {
|
||||||
|
|
@ -648,7 +649,7 @@ impl State {
|
||||||
fn visit_output(&mut self, node: &Rc<OutputNode>) {
|
fn visit_output(&mut self, node: &Rc<OutputNode>) {
|
||||||
node.render_data.borrow_mut().titles.clear();
|
node.render_data.borrow_mut().titles.clear();
|
||||||
node.render_data.borrow_mut().status.take();
|
node.render_data.borrow_mut().status.take();
|
||||||
node.hardware_cursor.set(None);
|
node.set_hardware_cursor(None);
|
||||||
node.node_visit_children(self);
|
node.node_visit_children(self);
|
||||||
}
|
}
|
||||||
fn visit_float(&mut self, node: &Rc<FloatNode>) {
|
fn visit_float(&mut self, node: &Rc<FloatNode>) {
|
||||||
|
|
@ -968,16 +969,19 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn damage(&self, rect: Rect) {
|
pub fn damage(&self, rect: Rect) {
|
||||||
self.damage2(false, rect);
|
self.damage2(false, false, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn damage2(&self, cursor: bool, rect: Rect) {
|
pub fn damage2(&self, cursor: bool, skip_hc: bool, rect: Rect) {
|
||||||
if rect.is_empty() {
|
if rect.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.damage_visualizer.add(rect);
|
self.damage_visualizer.add(rect);
|
||||||
for output in self.root.outputs.lock().values() {
|
for output in self.root.outputs.lock().values() {
|
||||||
if output.global.pos.get().intersects(&rect) {
|
if output.global.pos.get().intersects(&rect) {
|
||||||
|
if skip_hc && output.hardware_cursor.is_some() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
output.global.add_damage_area(&rect);
|
output.global.add_damage_area(&rect);
|
||||||
if cursor && output.schedule.defer_cursor_updates() {
|
if cursor && output.schedule.defer_cursor_updates() {
|
||||||
output.schedule.software_cursor_changed();
|
output.schedule.software_cursor_changed();
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,7 @@ impl ConnectorHandler {
|
||||||
self.state.outputs.set(self.id, output_data.clone());
|
self.state.outputs.set(self.id, output_data.clone());
|
||||||
on.schedule_update_render_data();
|
on.schedule_update_render_data();
|
||||||
self.state.root.outputs.set(self.id, on.clone());
|
self.state.root.outputs.set(self.id, on.clone());
|
||||||
|
self.state.outputs_without_hc.fetch_add(1);
|
||||||
self.state.output_extents_changed();
|
self.state.output_extents_changed();
|
||||||
global.opt.node.set(Some(on.clone()));
|
global.opt.node.set(Some(on.clone()));
|
||||||
global.opt.global.set(Some(global.clone()));
|
global.opt.global.set(Some(global.clone()));
|
||||||
|
|
@ -330,7 +331,7 @@ impl ConnectorHandler {
|
||||||
ConnectorEvent::Disconnected => break 'outer,
|
ConnectorEvent::Disconnected => break 'outer,
|
||||||
ConnectorEvent::HardwareCursor(hc) => {
|
ConnectorEvent::HardwareCursor(hc) => {
|
||||||
on.schedule.set_hardware_cursor(&hc);
|
on.schedule.set_hardware_cursor(&hc);
|
||||||
on.hardware_cursor.set(hc);
|
on.set_hardware_cursor(hc);
|
||||||
self.state.refresh_hardware_cursors();
|
self.state.refresh_hardware_cursors();
|
||||||
}
|
}
|
||||||
ConnectorEvent::FormatsChanged(formats) => {
|
ConnectorEvent::FormatsChanged(formats) => {
|
||||||
|
|
@ -363,6 +364,9 @@ impl ConnectorHandler {
|
||||||
sc.stop();
|
sc.stop();
|
||||||
}
|
}
|
||||||
global.destroyed.set(true);
|
global.destroyed.set(true);
|
||||||
|
if on.hardware_cursor.is_none() {
|
||||||
|
self.state.outputs_without_hc.fetch_sub(1);
|
||||||
|
}
|
||||||
self.state.root.outputs.remove(&self.id);
|
self.state.root.outputs.remove(&self.id);
|
||||||
self.state.output_extents_changed();
|
self.state.output_extents_changed();
|
||||||
self.state.outputs.remove(&self.id);
|
self.state.outputs.remove(&self.id);
|
||||||
|
|
|
||||||
|
|
@ -1433,6 +1433,19 @@ impl OutputNode {
|
||||||
.handle_tearing_mode_change(mode.to_config());
|
.handle_tearing_mode_change(mode.to_config());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_hardware_cursor(&self, hc: Option<Rc<dyn HardwareCursor>>) {
|
||||||
|
let is_none = hc.is_none();
|
||||||
|
let old = self.hardware_cursor.set(hc);
|
||||||
|
let was_none = old.is_none();
|
||||||
|
if was_none != is_none {
|
||||||
|
if is_none {
|
||||||
|
self.state.outputs_without_hc.fetch_add(1);
|
||||||
|
} else {
|
||||||
|
self.state.outputs_without_hc.fetch_sub(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OutputTitle {
|
pub struct OutputTitle {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue