Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pen events blocking improvements #672

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a3b9dfc
Block events from non-current-pen devices
cyclane May 13, 2023
a0d7aa1
cargo fmt
cyclane May 13, 2023
98e42c6
Zooming gesture with touch drawing
cyclane May 13, 2023
c403957
RnoteEngine.zooming does not need to be public
cyclane May 14, 2023
3ff0663
Ignore strokes <100ms after zooming gesture ended
cyclane May 14, 2023
908d4a3
Cleanup
cyclane May 14, 2023
63c2f5e
Fix pen progress check and only undo same device strokes on zoom
cyclane May 15, 2023
55c10c0
Remove touch-drawing condition from canvas_zoom_gesture_update
cyclane May 15, 2023
2367fee
Cleanup
cyclane May 15, 2023
38cf0a7
Fix hover writing writing after zoom gesture
cyclane May 15, 2023
c9b51ac
Move out of rnote-engine & use gdk::Device::name for comparisons
cyclane May 17, 2023
b4aa19a
Merge branch 'main' into pen-events-blocking-improvements
cyclane May 17, 2023
a51da7e
Remove pen_idle from RnoteEngine
cyclane May 18, 2023
3527490
Remove testing log::debug!
cyclane May 18, 2023
315e0e0
Custom input source detection
cyclane May 18, 2023
eb48894
Fix X11 zooming with touch-drawing and comment input_source_from_event
cyclane May 21, 2023
632f927
Cleanup
cyclane May 22, 2023
5e13634
Remove future history on touch-drawing zooming undo
cyclane May 22, 2023
97be4fd
Merge branch 'main' into pen-events-blocking-improvements
cyclane May 23, 2023
7f425f5
Remove touch-drawing zooming implementations
cyclane May 27, 2023
f6623d0
Review changes
cyclane May 27, 2023
396657b
Inhibit events rejected from device check
cyclane May 31, 2023
f0ae4c2
Merge remote-tracking branch 'upstream/main' into pen-events-blocking…
cyclane Jun 11, 2023
239261c
Merge remote-tracking branch 'upstream/main' into pen-events-blocking…
cyclane Nov 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 48 additions & 15 deletions crates/rnote-ui/src/canvas/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,19 @@ pub(crate) fn handle_pointer_controller_event(
let gdk_modifiers = event.modifier_state();
let _gdk_device = event.device().unwrap();
let backlog_policy = canvas.engine_ref().penholder.backlog_policy();
let is_stylus = event_is_stylus(event);
let input_source = input_source_from_event(event);
let is_stylus = input_source == Some(gdk::InputSource::Pen);

//std::thread::sleep(std::time::Duration::from_millis(100));
//super::input::debug_gdk_event(event);

if reject_pointer_input(event, touch_drawing) {
return (glib::Propagation::Proceed, pen_state);
if let Some(propagation) = reject_pointer_input(
event,
pen_state,
input_source == canvas.pen_input_source(),
touch_drawing,
) {
return (propagation, pen_state);
}

let mut handle_pen_event = false;
Expand Down Expand Up @@ -216,6 +222,7 @@ pub(crate) fn handle_pointer_controller_event(
}
}

canvas.set_pen_input_source(input_source);
canvas.emit_handle_widget_flags(widget_flags);
(propagation, pen_state)
}
Expand Down Expand Up @@ -293,31 +300,57 @@ fn debug_gdk_event(event: &gdk::Event) {
);
}

/// Returns true if input should be rejected
fn reject_pointer_input(event: &gdk::Event, touch_drawing: bool) -> bool {
/// Returns Option<inhibit> if pointer input should be rejected
fn reject_pointer_input(
event: &gdk::Event,
state: PenState,
input_source_matches: bool,
touch_drawing: bool,
) -> Option<glib::Propagation> {
// If pen is already down, reject events from other input sources
if matches!(state, PenState::Down) && !input_source_matches {
return Some(glib::Propagation::Stop);
}
if touch_drawing {
if event.device().unwrap().num_touches() > 1 {
return true;
return Some(glib::Propagation::Proceed);
}
} else {
let event_type = event.event_type();
if event.is_pointer_emulated()
|| event_type == gdk::EventType::TouchBegin
|| event_type == gdk::EventType::TouchUpdate
|| event_type == gdk::EventType::TouchEnd
|| event_type == gdk::EventType::TouchCancel
{
return true;
if event.is_pointer_emulated() || event_is_touchscreen(event) {
return Some(glib::Propagation::Proceed);
}
}
false
None
}

fn event_is_stylus(event: &gdk::Event) -> bool {
// As in gtk4 'gtkgesturestylus.c:106' we detect if the pointer is a stylus when it has a device tool
event.device_tool().is_some()
}

fn event_is_touchscreen(event: &gdk::Event) -> bool {
matches!(
event.event_type(),
gdk::EventType::TouchBegin
| gdk::EventType::TouchUpdate
| gdk::EventType::TouchEnd
| gdk::EventType::TouchCancel
)
}

// gdk::Device.source() returns InputSource::Mouse for pens and touchscreens,
// so use manual detection instead, with gdk::Device.source() as a fallback.
// (see https://gitlab.gnome.org/GNOME/gtk/issues/4374)
pub(crate) fn input_source_from_event(event: &gdk::Event) -> Option<gdk::InputSource> {
if event_is_stylus(event) {
Some(gdk::InputSource::Pen)
} else if event_is_touchscreen(event) {
Some(gdk::InputSource::Touchscreen)
} else {
event.device().and_then(|d| Some(d.source()))
}
}

fn retrieve_pointer_elements(
canvas: &RnCanvas,
now: Instant,
Expand Down
12 changes: 12 additions & 0 deletions crates/rnote-ui/src/canvas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ mod imp {
pub(crate) key_controller_im_context: IMMulticontext,
pub(crate) drop_target: DropTarget,
pub(crate) drawing_cursor_enabled: Cell<bool>,
pub(crate) pen_input_source: Cell<Option<gdk::InputSource>>,

pub(crate) engine: RefCell<Engine>,
pub(crate) engine_task_handler_handle: RefCell<Option<glib::JoinHandle<()>>>,
Expand Down Expand Up @@ -156,6 +157,7 @@ mod imp {
key_controller_im_context,
drop_target,
drawing_cursor_enabled: Cell::new(false),
pen_input_source: Cell::new(None),

engine: RefCell::new(engine),
engine_task_handler_handle: RefCell::new(None),
Expand Down Expand Up @@ -685,6 +687,16 @@ impl RnCanvas {
}
}

#[allow(unused)]
pub(crate) fn pen_input_source(&self) -> Option<gdk::InputSource> {
self.imp().pen_input_source.get()
}

#[allow(unused)]
pub(crate) fn set_pen_input_source(&self, pen_input_source: Option<gdk::InputSource>) {
self.imp().pen_input_source.set(pen_input_source);
}

#[allow(unused)]
pub(crate) fn show_drawing_cursor(&self) -> bool {
self.property::<bool>("show-drawing-cursor")
Expand Down