Closed Sporif closed 2 months ago
Thanks for working on this.
I'm not familiar with how other compositors implement touch input, but here are some thoughts regarding how I would imagine it:
There are two touch owners:
struct DefaultTouchOwner;
struct GrabTouchOwner {
node: Rc<dyn Node>,
down_ids: AHashSet<i32>,
}
The DefaultTouchOwner ignores all events except down
. Once it gets a down
event, it finds the node under the touch position and replaces itself by GrabTouchOwner.
The down_ids field contains all ids that are currently down. When this set becomes empty, the GrabTouchOwner replaces itself by the DefaultTouchOwner.
When the GrabTouchOwner receives a down
event, that event is always sent to the node
, regardless of where on the screen it occurs. This means that you can press with one hand on an application and then with another hand anywhere else on the screen and the second event is sent to the node that was hit by the first press.
The first down event should also switch the keyboard focus to that node if it is an application window. (Using the same logic used by mouse button presses.)
Alternatively, each touch id could have its own touch owner. This seems to be how it works on android.
I've implemented your first suggestion, what do you think?
Also, I was trying to hide the cursor with seat.set_app_cursor(None)
, but then it doesn't show up again until it enters another surface. What's the best way of implementing that feature?
I've implemented your first suggestion, what do you think?
LGTM. Have you checked how other compositors handle multi-touch?
Also, I was trying to hide the cursor with seat.set_app_cursor(None), but then it doesn't show up again until it enters another surface. What's the best way of implementing that feature?
Why do you want to hide the cursor?
LGTM. Have you checked how other compositors handle multi-touch?
I haven't looked at the code but KWin seems to do it the way you suggested. Sway only sends touch down events that fall within the boundaries of the initial surface after the first touch down, but it always sends motion events.
Why do you want to hide the cursor?
KWin, Sway and Windows all hide the cursor on touch. I find it can be distracting when you're not using it.
KWin, Sway and Windows all hide the cursor on touch. I find it can be distracting when you're not using it.
Maybe it's best to simply not render the cursor in that case. See GfxFramebuffer::create_render_pass
.
Edit: But this is not going to work for hardware cursors. Maybe functions disable_cursor
/enable_cursor
on WlSeatGlobal
that are called when the first touch down/the last touch up occurs and that does the necessary work while preserving the cursor that should be shown otherwise.
I'm currently working on adding tablet support. I'll continue the review once that is done.
The tablet PR #190 has significant overlap with this MR:
The tablet PR #190 has significant overlap with this MR:
- It adds a mechanism to map input devices to outputs.
- It adds a CursorUserGroup type with a deactivate function that hides the cursor.
- It adds the necessary code for tablets to interact with compositor GUI elements.
So should I wait for you to merge that PR and then rework this one?
Sounds good.
I've now implemented all the basic features. There's still some more future work but for now I think this is enough.
I've opened #230 to fix the remaining issues with this PR.
One thing I've removed is integration with the compositor UI. There were some serious issues with multi-touch and I'm only testing this with a graphics tablet hacked to work as a touch screen, so I don't have the fine control to properly design this. This can get added back in the future.
I'm testing this on a touchscreen laptop and trying to implement basic support:
Future work:
Closes #115