feat(input): add tablet and touch support for release/1.4 - #692
Conversation
|
This is one that's going to be hard for me to test since I don't have a tablet. Did this end up having any overlap with PR #612? Or are they completely separate? |
|
Yes, that is a little bit uncomfortable, indeed. Maybe Wacom should sponsor you with a tablet :-) Concerning #612 I discussed this there, too. To me it feels that this PR also adds infrastructure on top of which touch support can be implemented. See also the last comment by @zharsing. I may actually give touch support a try, too. Have some Thinkpad Yoga with Debian nearby. |
b9ff331 to
1d25c78
Compare
|
@JimmyCozza I did an attempt to streamline the touch discussion in #707. |
|
And mouse tap-to-click added. I think this is a reasonable feature set for now. Let's leave it there. Next steps:
|
01620e0 to
586461d
Compare
|
Fixed a few smaller bugs and inconsistencies in behavior. |
03cce34 to
c6447c6
Compare
Looks up a Monitor by its wlr_output connector name (e.g. "DP-8"). Used by the tablet map_to_output resolution added in a following commit.
DRM connector names (DP-8, DP-9, ...) are assigned by enumeration order
and can shift across replug/redock even for the same physical monitor,
which breaks anything matching an output by connector name. Fall back to
the make/model/serial identifier - the same "make model serial" ("Unknown"
for missing fields) convention used by sway and wlr-randr - which stays
stable regardless of which port the monitor ends up on.
some_monitor_by_name() has a single caller today (tablet map_to_output
resolution), so this is low-risk; sets up list-valued map_to_output
(fallback preference list) as a following commit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Implements the tablet-v2 Wayland protocol for drawing tablets (e.g. Wacom), in the two stages proposed in trip-zip#663: - Stage 1 (MVP): a pen in proximity moves the pointer; a tip emulates a left click. Works for any client via wl_pointer emulation. - Stage 2 (full): wlr_tablet_v2_tablet_{tool,pad}_notify_*() forward pressure, distance, tilt, rotation, slider, and wheel to tablet-aware clients (tested against Krita, Xournal++, Okular). motionnotify() suppresses the wl_pointer emulation for surfaces that accept tablet-v2, so clients don't see both protocols firing for the same motion. Tip events route through buttonpress() rather than calling wlr_seat_pointer_notify_button() directly: buttonpress() is also where Lua button-binding dispatch happens (click-to-focus/raise), so tapping an unfocused window with the stylus focuses/raises it the same way a mouse click does. The tool already drives a real, hovering cursor via tablet_apply_motion() -> motionnotify(), so tip down/up map straight onto buttonpress() press/release - no atomic press+release synthesis needed the way touch requires. wlr_tablet_tool_axis_event only reports the axes that actually changed (updated_axes is a bitmask), not a full x/y or tilt_x/tilt_y pair every time - a tool dragged along a single axis near the tablet's edge is a normal, frequent case. Each tool's last known position is cached (find_or_create_tracked_tablet_tool(), split out of get_or_create_tablet_v2_tool() so it also works without tablet_v2_mgr) and used to fill in whichever axis wasn't part of a given event. Tablet pad support (buttons, ring, strip) sends proper enter/leave focus based on cursor position, since pad events carry no surface of their own. Pad-to-tablet pairing is done authoritatively via libinput device groups at device-creation time (mirrors sway), which is backend-independent and correctly handles multiple simultaneous tablets; the wlr_tablet_pad attach_tablet event is also wired up for the nested-Wayland-backend testing path, where libinput groups aren't available. Config surface, via awful.input.rules (inspired by man sway-input): - tool_mode = "absolute" | "relative" per tool type (tablet-tool-pen, -eraser, ...; tablet-tool wildcard). Mouse/lens tools are always relative, matching sway's hardcoded behavior - they have no fixed position on the tablet surface. - map_to_output: output name, "make model serial" identifier (stable across DRM connector renumbering, e.g. DP-8 -> DP-9 on replug), or an ordered list of candidates tried in turn (useful for docked laptops with different monitors per location). "*" or no match falls back to the full output layout. - map_to_region / map_from_region: explicit absolute-layout or tablet-space rectangles; map_to_region takes precedence over map_to_output when both are set, mirroring sway's mutually- exclusive output/region mapping. Not yet verified on real hardware: pad ring/strip and pen tilt/rotation (available test hardware doesn't have them). No live reconfiguration: changing map_to_output/map_to_region/ tool_mode requires editing rc.lua and reloading, or `somewm-client eval`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Forwards touch down/motion/up/cancel/frame events to clients via the
core wl_touch protocol, reusing the tablet-v2 output-mapping mechanism
(generalized tablet_map_coords() into input_map_coords()) instead of
duplicating it, and adds a single-enabled-output auto-default so an
unconfigured device maps onto the one screen present instead of
spanning the whole layout. rule = { type = "touch" } in
awful.input.rules works via the existing generic rule matcher, no Lua
changes required. No compositor-side pointer/click emulation is
included; that's deliberately out of scope for this first pass.
wlr_seat_touch_notify_motion() takes no surface argument - it always
delivers to the client of the touch point's original down surface, so
touchnotifymotion() stays pinned to that surface and projects the
current layout coordinates onto its own origin, rather than
re-resolving whatever surface is currently under the finger (which
would compute coordinates relative to the wrong surface once the
finger drags across a window boundary, and drop the event outright
once it drags off any surface at all). Same approach motionnotify()
uses to keep a held mouse button pinned to its focused surface while
the cursor roams elsewhere.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Raw wl_touch forwarding leaves clients that never bind wl_touch (wibar, GTK3/Qt-widgets apps) with no way to be clicked by touch. Gate emulation per-client on whether it bound wl_touch (wlr_seat_client->touches, same idiom pointerfocus() uses for ->pointers) so touch-aware clients keep receiving only real touch. XWayland is excluded the same way: it always binds wl_touch once the seat advertises it, deferring to its own built-in emulation. touchnotifydown() fires one atomic press+release, routed through buttonpress() rather than wlr_seat_pointer_notify_button() directly - buttonpress() is where Lua button-binding dispatch (and therefore click-to-focus/raise) happens, which a raw notify_button() call would skip. Raw touch forwarding is now also skipped for clients with no touch binding, avoiding a wlroots "could not create touch point" error on every such tap. Touch-aware clients (Krita, GIMP, ...) still deserve focus/raise on a tap, the same as a mouse click gets it, without a synthetic wl_pointer click on top of their real touch input (that would be double input). touchnotifydown() runs the same rc.lua button-binding dispatch (luaA_client_button_check()) for them too, just without the final wl_pointer delivery - unless some other surface already has an active touch point, since that means concurrent touch use across different windows (e.g. touch-drawing on an unfocused canvas on one screen while touch-scrolling a document on another) that a stolen focus would disrupt. Concurrent touches on the same surface (a two-finger gesture) don't count as "elsewhere". New awful.input.rules property: emulate_pointer (touch rule type), defaults on. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1d25c78 to
6ce4a6e
Compare
|
@shuber2 I don't want to stall this too long. I'm tempted to merge this and watch for bug reports after the fact just because I really do not have a way to test this out myself. Have you been running this yourself lately? Have you noticed any bugs or concerns with it? What I can say definitively, is that it is at least inert when I run this branch as my daily driver, so my vote is merge and monitor. |
Description
It adds tablet support as described in feature issue #663 and touch support as described in feature issue #707.
The following developments could naturally follow up on this PR:
Test Plan
Only little test code coverage. Mainly manual tests.
Checklist
lua/awful/,lua/gears/,lua/wibox/,lua/naughty/) are not modified — if a bug surfaces in Lua, the fix belongs in Cmake test-unit && make test-integration)