mahkoh / jay

A Wayland Compositor
GNU General Public License v3.0
230 stars 10 forks source link

wayland: implement wl_touch #177

Closed Sporif closed 2 months ago

Sporif commented 5 months ago

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

Future work:

Closes #115

mahkoh commented 5 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.)

mahkoh commented 5 months ago

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

Sporif commented 5 months ago

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?

mahkoh commented 5 months ago

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?

Sporif commented 5 months ago

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.

mahkoh commented 5 months ago

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 commented 5 months ago

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

mahkoh commented 5 months ago

The tablet PR #190 has significant overlap with this MR:

Sporif commented 5 months ago

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?

mahkoh commented 5 months ago

Sounds good.

mahkoh commented 5 months ago

190 has been merged.

Sporif commented 5 months ago

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

mahkoh commented 2 months ago

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.