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

Add inversion/eraser-end property for tablet pens #62212

Merged
merged 1 commit into from
Jul 4, 2022

Conversation

hansemro
Copy link
Contributor

@hansemro hansemro commented Jun 19, 2022

godotengine/godot-proposals#4702

Status: Ready for review

As stated in the proposal, this pull request introduces a new InputEventMouseMotion boolean property called pen_inverted which is true when the eraser-end of the pen is detected. This new property makes it possible to map different behavior to both ends of a tablet pen.

Currently, this PR supports Windows (wintab & winink), Linux, and macOS.

Simple demo project: https://github.com/hansemro/InvertedPenGodotTest/tree/godot4

@hansemro hansemro changed the title Add inversion/eraser-end detection for tablet pens Add inversion/eraser-end property for tablet pens Jun 19, 2022
@hansemro hansemro marked this pull request as ready for review June 19, 2022 11:37
@hansemro hansemro requested review from a team as code owners June 19, 2022 11:37
@hansemro hansemro marked this pull request as draft June 19, 2022 11:38
@hansemro

This comment was marked as resolved.

@mbrlabs
Copy link
Contributor

mbrlabs commented Jun 19, 2022

What's your OS and tablet model? It's possibly a driver/OS bug...on Linux at least the same kind of flakiness exists for pressure sensitivity (jump from 0.5 to 1.0 and back in 1 frame without any kind of pressure change). I had to filter these out in Lorien.

I can test it later on Windows and Manjaro with a Wacom Intuos Pro (and regular)

@fire
Copy link
Member

fire commented Jun 19, 2022

Approved continuous integration testing actions.

@hansemro

This comment was marked as outdated.

@fire
Copy link
Member

fire commented Jun 19, 2022

I will suggest that this be put into core, because this type of filtering is hard to design and it's a common usecase of pens.

@JFonS since you are making a pen app, thoughts?

@hansemro
Copy link
Contributor Author

hansemro commented Jun 20, 2022

Fixed the intermittent signal issues in x11 by removing a bad assignment that sets the property to false.

In Windows, only wintab had the intermittent issue and was fixed in 3.x by leveraging pressure & tilt update logic for wintab API.

Will update PR branch soon after testing.

Edit: Done

@hansemro
Copy link
Contributor Author

hansemro commented Jun 20, 2022

With fixes, we no longer require complicated state machine to filter bad pen_inverted signals in godot projects.

Lorien code from above is so much better now: https://github.com/hansemro/Lorien/blob/77ecb0524bbd3152b9e2fa282efba72d1f125063/lorien/InfiniteCanvas/InfiniteCanvas.gd#L57-L61

@hansemro
Copy link
Contributor Author

@mbrlabs
Copy link
Contributor

mbrlabs commented Jun 20, 2022

I tested the latest build on Windows 11 with a Wacom Intuos Pro - no problems, works great now! The Linux (Mono) editor CI build failed however...something related to the class reference

Edit: Built it myself on Manjaro Linux - works without problems. I also tried the CI build of the macOS editor on an M1 Mac Mini but it crashed with a NSInvalidArgumentException (not sure if related to this PR...maybe M1 chips are not supported in CI builds?)

@hansemro
Copy link
Contributor Author

@mbrlabs CI builds for just x86_64

% file godot.osx.opt.tools.64 
godot.osx.opt.tools.64: Mach-O 64-bit executable x86_64
% file godot.osx.opt.64
godot.osx.opt.64: Mach-O 64-bit executable x86_64

@hansemro
Copy link
Contributor Author

hansemro commented Jun 20, 2022

The Linux (Mono) editor CI build failed however...something related to the class reference

Not sure what to do to fix this. I don't want to make blind attempts to fix this.

@akien-mga
Copy link
Member

See https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html to make sure that what you probably added manually actually matches what the doc generator would have done. Here the problem is the alphabetical order not being respected.

@hansemro
Copy link
Contributor Author

hansemro commented Jun 20, 2022

Another macOS issue: once pen_inverted is set true, moving mouse (or any non-tablet interface) does not clear it when it should.

Debug print patch
diff --git a/platform/osx/godot_content_view.mm b/platform/osx/godot_content_view.mm
index 739f2d6a1b..f5ea5c455c 100644
--- a/platform/osx/godot_content_view.mm
+++ b/platform/osx/godot_content_view.mm
@@ -387,6 +387,7 @@ - (void)mouseMoved:(NSEvent *)event {
                last_pen_inverted = [event pointingDeviceType] == NSPointingDeviceTypeEraser;
        }
        mm->set_pen_inverted(last_pen_inverted);
+       print_line("subtype: " + rtos(subtype) + ", deviceType: " + rtos([event pointingDeviceType]) + ", pen_inverted: " + rtos(mm->get_pen_inverted()));
        mm->set_global_position(wd.mouse_pos);
        mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
        const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * ds->screen_get_max_scale();
Debug build console log
subtype: 2, deviceType: 1, pen_inverted: 0 <- proxmity event: pen-end of stylus (entering)
subtype: 1, deviceType: 0, pen_inverted: 0 <- moving pen and/or pressing down
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 1, deviceType: 0, pen_inverted: 0
...
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 2, deviceType: 1, pen_inverted: 0 <- proximity event: pen-end of stylus (exiting)
subtype: 2, deviceType: 3, pen_inverted: 1 <- proxmity event: eraser-end of stylus (entering)
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 2, deviceType: 3, pen_inverted: 1
subtype: 1, deviceType: 0, pen_inverted: 1 <- moving pen and/or pressing down (inversion retained)
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 1, deviceType: 0, pen_inverted: 1
...
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 2, deviceType: 3, pen_inverted: 1 <- proxmity event: eraser-end of stylus (exiting)
subtype: 0, deviceType: 0, pen_inverted: 1 <- moving mouse and/or pressing on mouse buttons
subtype: 0, deviceType: 0, pen_inverted: 1 <-   mouse incorrectly retains pen_inversion
subtype: 0, deviceType: 0, pen_inverted: 1
subtype: 0, deviceType: 0, pen_inverted: 1
subtype: 0, deviceType: 0, pen_inverted: 1
subtype: 0, deviceType: 0, pen_inverted: 1
...
subtype: 0, deviceType: 0, pen_inverted: 1
subtype: 0, deviceType: 0, pen_inverted: 1

One fix is to only retain pen_inversion on tablet subevents and default to false on other event subtypes.

Edit: Fixed by 367a653

Console log with fix
subtype: 2, deviceType: 1, pen_inverted: 0 <- proxmity event: pen-end of stylus (entering)
subtype: 1, deviceType: 0, pen_inverted: 0 <- moving pen and/or pressing down
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 1, deviceType: 0, pen_inverted: 0
subtype: 2, deviceType: 1, pen_inverted: 0 <- proximity event: pen-end of stylus (exiting)
subtype: 2, deviceType: 3, pen_inverted: 1 <- proxmity event: eraser-end of stylus (entering)
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 1, deviceType: 0, pen_inverted: 1
subtype: 2, deviceType: 3, pen_inverted: 1 <- proximity event: eraser-end of stylus (exiting)
subtype: 0, deviceType: 0, pen_inverted: 0 <- moving mouse and/or pressing on mouse buttons
subtype: 0, deviceType: 0, pen_inverted: 0 <-   mouse (and non-tablet events) reset pen_inverted
subtype: 0, deviceType: 0, pen_inverted: 0
subtype: 0, deviceType: 0, pen_inverted: 0
subtype: 0, deviceType: 0, pen_inverted: 0

@hansemro hansemro marked this pull request as ready for review June 22, 2022 20:39
@hansemro hansemro requested a review from a team as a code owner June 22, 2022 20:39
@hansemro
Copy link
Contributor Author

Let me know if want me to rebase or squash commits later.

Copy link
Member

@bruvzg bruvzg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least macOS and Windows changes seems fine, but I do not have any pan with the eraser to actually test it.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me overall. The changes should be squashed before merging, given the scope (+69, -10) I think a single commit is fine for all 3 platform implementations.

@hansemro
Copy link
Contributor Author

hansemro commented Jul 4, 2022

Squashed the commits.

@akien-mga akien-mga merged commit 344b427 into godotengine:master Jul 4, 2022
@akien-mga
Copy link
Member

Thanks! And congrats for your first merged Godot contribution 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants