wayland tablet support redux
- Date: Wed, 30 Mar 2016 16:46:43 +0200
- From: Carlos Garnacho <carlosg@xxxxxxxxx>
- Subject: wayland tablet support redux
Now that 3.22 is open, and that the v1 of the wayland tablet protocol
is formalized, I'll be attempting to merge wip/wayland-tablet again.
Some random concepts:
=What's new in the branch=
The main new API feature is GdkDeviceTool, it (almost, more on this
ahead) univocally represents physical tablet tool (usually a pen),
these structs contain a GdkDeviceToolType saying the kind of tool it
is (pen, eraser, airbrush,...) and their serial number if available.
The idea behind this struct is that interested apps can do per-tool
tracking/configuration/etc, using a same tool will always result in
the same GdkDeviceTool pointer reported in events, etc. And the serial
number can be used to compose GSettings paths and whatnot.
The branch also resuscitates proximity events, they are a thing again,
and I added some kind of support for these for X11/XI2.
There's though low-range tablets that don't report serials (and most
usually, you can't use further/different tools than the one coming
with the device), in wayland it's the compositor which takes care of
creating the separate tool interfaces for those, in x11 we create
extra GdkDeviceTools with serial=0, which are shared for all devices
for all devices with these characteristics.
=...but we had already an eraser device?=
Yes, and in the branch we still do, all events from the eraser tool
will be sent with a GDK_SOURCE_ERASER device, and all other tools will
be always sent with a GDK_SOURCE_PEN device. That's kind of
unfortunate and something that'd be great to switch on 4.0.
Another option could have been going the other way around, and adding
extra GdkInputSources and devices. I don't think that option scales as
=Relationship between tablets and tools=
The typical noncontroversial setups are those with one tablet+one
tool, or multiple tablets each with their own tool. Things complicate
soon though when you add multiple tools and multiple compatible
tablets, tools can then be used interchangeably across tablets.
This is one thing that IMO the wayland protocol got right, both
tablets and tools are announced by the seat, it is tools which do
"emit" the events, have axes, etc. And you can only relate a tool to a
tablet on proximity_in.
And this is something we kind of do too in gdk. In the end you
shouldn't expect that a given GdkDeviceTool will always be accompanied
with the same GdkDevice in events. The difference here is that in gdk
it is GdkDevices which have axes, "emit" events, etc. In order to keep
doing this, slave pen/eraser devices do change their axes in order to
resemble the tool in proximity_in, just like master devices currently
do in x11 on slave device switch. The end message is the same,
event->xxx.axes is only guaranteed to map correctly to the current
device axes at the time of dispatching the event.
This also affects the lifetime of objects, unplugging a tablet will
tear down the associated GdkDevices, but GdkDeviceTools may stay
=Tablets and pointer cursors=
One fundamental difference between X11 (with default XI2 behavior) and
wayland is that in the former all plugged in devices drive the Virtual
Core Pointer, whereas in wayland each tool in proximity (1 per tablet,
effectively) will get their own.
This leads to differences in how are those are tablets mapped to
GdkDevices, which I expect GdkSeat to help even out. in wayland we'll
create a separate "master pointer" device for each tablet, its cursor
can be set independently, etc. GTK+ has been prepared for the most
part to deal with multiple pointers since 3.0, and it finally pays off
:). The difference is that these several pointers come from the same
seat, so they should all be able to interact with popup menus, etc.
This is one place where GdkSeat grabs came to help, those will perform
the input redirection for all devices in the seat, with the practical
result that all of pointer/touch/tablets will be able to select
something in the popup, dismiss the menu, etc... just as it happens
when all slave devices drive the same master pointer.
There is however a potential porting effort here for some applications
or widgets outside gtk+. If you need to keep track of motion events,
query device positions, etc. You better track gdk_event_get_device()
too, any app that was cheaply ported to 3.x using
gdk_device_manager_get_client_pointer() thinking "the pointer" is
sufficient and single enough will potentially get things wrong, but
then again, it's been potentially broken since 3.0. This is something
that GtkGesture is already prepared for FWIW.
gtk-devel-list mailing list