X11: Touchscreen orientation support: UI, monitor follow, basic autoassignment.
Features
UI:
New tab: Touchscreen
Only visible if device is a touchscreen.
Three dropdown menus within the tab:
-
Assigned Monitor:
List of connected monitors.
Determines which monitor this touchscreen will follow in orientation and position. -
Relative Rotation:
Same list of rotations as in monitor dialog - None, Left, Inverted, Right.
Monitor and touchscreen settings are combined, if a monitor is assigned.
E.g. Left-oriented monitor with Left-oriented touchscreen results in Inverted touchscreen per "global top" -
Relative Reflection:
Same list of reflections as in monitor dialog - None, Horizontal, Vertial, Both.
Monitor and touchscreen settings are combined, if a monitor is assigned.
If this results in reflecting twice on the same axis for the touchscreen, reflection is cancelled out.
Monitor follow:
Touchscreen automatically follows it's assigned monitor orientation.
This includes temporary changes during keep-or-revert dialog.
Basic autoassignment
First touchscreen is assigned to eDP-1.
Remaining touchscreens and outputs are naively paired up.
Implementation details
xfce-randr.c xfce-randr.h
New utility function: xfce_randr_get_connector_by_edid
meson.build
Added xrandr and libsettings-common to mouse dialog.
mouse-dialog main.c
There is one callback per dropdown menu that simply writes respective data to xfconf. Signals connected respectively.
Monitors dropdown is populated on init and any time a device is selected. Data is retrieved from xrandr state, as xfconf may not have yet saved monitor configuration.
mouse_settings_device_selection_changed extended to detect touchscreens, making touchscreen tab visible, and restore current settings from xfconf to UI.
Assigned monitor is stored as EDID hash in xfconf, one per touchscreen device.
Relative rotations and reflections are stored in identical format to the ones for outputs, also one of each per touchscreen device.
xfsettingsd pointers.c
To achieve autofollow pointers helper reacts to monitors-changed signal.
I've had to introduce a delay here, because those changes aren't always instant and display-related logic also has an (admittedly smaller) delay. I tried existing signals, custom signal, signalling through special xfconf property, but either it runs with stale data or I run into some kind of mess with nested dbus calls that cancel xfconf application, which I'm not entirely sure how to work around.
Pointers helper already monitors pointers channel. To respond to new UI, there's an extra case for Rotation or Reflection or AssignedMonitor, which runs orientation update function.
Autoassignment matches first touchscreen to eDP-1 - built-in monitor - and pairs up the rest.
I am unfortunately unable to take this part any further.
I have access to laptops with touchscreens, but I do not have access to a dedicated monitor with a touchscreen.
Still, this should at least cover the most common case automatically.
The orientation update function takes touchscreen settings, monitor settings, and display size and combines them into a coordinate transformation matrix that maps touchscreen input exactly onto the monitor's rectangle within the display.
It covers rotation, reflection, position, resolution, and scale changes in single- and multi-monitor setups - as long as source data is accurate.
Comment
This has a few rough edges.
Feedback would be appreciated.