jay icon indicating copy to clipboard operation
jay copied to clipboard

wayland: implement wl_touch

Open Sporif opened this issue 1 year ago • 6 comments

I'm testing this on a touchscreen laptop and trying to implement basic support:

  • [x] Send events to the active client at the correct position (tested by tapping, scrolling and zooming in Konsole and Firefox)
  • [ ] Hide the cursor on touch down
  • [x] Switch the active client on touch down
  • [ ] Switch client on titlebar touch down
  • [ ] Switch workspace on bar touch down
  • [ ] Resize clients with touch motion on the edges/corners

I haven't figured out how to complete the rest.

Closes #115

Sporif avatar Apr 21 '24 14:04 Sporif

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.)

mahkoh avatar Apr 21 '24 16:04 mahkoh

Alternatively, each touch id could have its own touch owner. This seems to be how it works on android.

mahkoh avatar Apr 21 '24 16:04 mahkoh

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?

Sporif avatar Apr 22 '24 00:04 Sporif

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?

mahkoh avatar Apr 22 '24 13:04 mahkoh

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.

Sporif avatar Apr 22 '24 21:04 Sporif

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.

mahkoh avatar Apr 23 '24 10:04 mahkoh

I'm currently working on adding tablet support. I'll continue the review once that is done.

mahkoh avatar Apr 29 '24 18:04 mahkoh

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.

mahkoh avatar May 02 '24 16:05 mahkoh

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?

Sporif avatar May 03 '24 12:05 Sporif

Sounds good.

mahkoh avatar May 03 '24 15:05 mahkoh

#190 has been merged.

mahkoh avatar May 04 '24 08:05 mahkoh

I've now implemented all the basic features. There's still some more future work but for now I think this is enough.

Sporif avatar May 05 '24 14:05 Sporif

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.

mahkoh avatar Jul 21 '24 00:07 mahkoh