Wayland에서 터치 스크린을 보정하는 방법은 무엇입니까?

Wayland에서 터치 스크린을 보정하는 방법은 무엇입니까?

저는 Gnome과 Wayland를 실행하는 Fedora 35 노트북을 가지고 있습니다. 다중 모니터 설정에서도 작동하고 보정이 필요하지 않은 내장형 터치스크린이 있습니다.
두 개의 외부 모니터(일반 4k 모니터와 1080p USB-C 터치스크린)가 있습니다. 이 모니터를 연결할 때 이 설정에서는 필요하지 않기 때문에 내부 노트북 화면을 비활성화합니다. 그래서 나는 마침내 다음과 같은 결론에 이르렀습니다.

모니터 설정

정말 괜찮습니다. (오른쪽 화면은 외부 터치스크린이고, 왼쪽 화면은 외부 4k 모니터입니다.)

문제는 터치스크린이 실제로는 1920x1080일 때 5760x2160픽셀로 인식하여 터치 입력이 올바르지 않게 된다는 것입니다.

잘못된 터치 입력 2

이 문제를 해결하기 위해 다음 기사를 찾았습니다.아치 위키 - 교정_터치스크린 하지만 Wayland에는 존재하지 않는 것 같은 xinput에 의존합니다.

그러나 기사에서는 udev를 사용하여 터치 스크린을 지속적으로 보정하는 방법을 언급합니다. 이를 위해서는 기사에 설명된 대로 변환 행렬을 계산해야 합니다.

이제 가능한 한 정확하게 계산해 보세요.

c0 = touch_area_width / total_width
c2 = touch_area_height / total_height
c1 = touch_area_x_offset / total_width
c3 = touch_area_y_offset / total_height

매트릭스는

[ c0 0 c1 ] [ 0 c2 c3 ] [ 0 0 1 ]

이는 행별 배열로 표시됩니다.

c0 0 c1 0 c2 c3 0 0 1

나는 이것으로 끝났습니다 :

c0 = touch_area_width / total_width     | 1920/(3840+1920)=0.333333333
c2 = touch_area_height / total_height   | 1080/2160=0.5
c1 = touch_area_x_offset / total_width  | 3840/(3840+1920)=0.666666667
c3 = touch_area_y_offset / total_height | 0/2160=0

c0 0 c1 0 c2 c3 0 0 1                   | 0.333333333 0 0.666666667 0 0.5 0 0 0 1

그런 다음 이 기사에서는 간단한 변환 행렬을 사용하는 udev 규칙의 예를 보여줍니다.

/etc/udev/rules.d/99-acer-touch.rules

ENV{ID_VENDOR_ID}=="2149", ENV{ID_MODEL_ID}=="2703", ENV{WL_OUTPUT}="DVI1", ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0"

그래서 공급업체 ID와 모델 ID(제가 생각하는 제품 ID와 동일)는 물론 "WL_OUTPUT"(저는 모니터 커넥터라고 부름)도 알아야 할 것 같습니다.

공급업체 ID와 제품 ID를 얻는 방법은 다음 을 통해 lsusb간단합니다 .

$ lsusb
Bus 005 Device 007: ID 1d5c:7102 Fresco Logic Generic Billboard Device
Bus 005 Device 006: ID 222a:0001 ILI Technology Corp. Multi-Touch Screen
Bus 005 Device 005: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
# ... Those 5 devices show up when I connect the touch screen. I removed the rest from the list.

좋습니다. 이제 공급업체 ID(222a)와 제품 ID(0001)가 생겼습니다.

그런 다음 다음 명령 없이는 수행 방법을 알 수 없었기 때문에 dbus를 통해 모니터 커넥터의 이름을 찾기 위해 이 말도 안되는 Python 스크립트를 작성했습니다 xrandr --query.

#!/usr/bin/python3

# https://dbus.freedesktop.org/doc/dbus-python/tutorial.html
# https://github.com/GNOME/mutter/blob/b5f99bd12ebc483e682e39c8126a1b51772bc67d/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
# https://ask.fedoraproject.org/t/change-scaling-resolution-of-primary-monitor-from-bash-terminal/19892

import dbus
bus = dbus.SessionBus()

display_config_well_known_name = "org.gnome.Mutter.DisplayConfig"
display_config_object_path = "/org/gnome/Mutter/DisplayConfig"

display_config_proxy = bus.get_object(display_config_well_known_name, display_config_object_path)
display_config_interface = dbus.Interface(display_config_proxy, dbus_interface=display_config_well_known_name)

serial, physical_monitors, logical_monitors, properties = display_config_interface.GetCurrentState()

for x, y, scale, transform, primary, linked_monitors_info, props in logical_monitors:
    for linked_monitor_connector, linked_monitor_vendor, linked_monitor_product, linked_monitor_serial in linked_monitors_info:
        for monitor_info, monitor_modes, monitor_properties in physical_monitors:
            monitor_connector, monitor_vendor, monitor_product, monitor_serial = monitor_info
            if linked_monitor_connector == monitor_connector:
                print("Display: " + monitor_properties.get("display-name") + " - Connector: " + monitor_connector)

출력은 다음과 같습니다

Display: RTK 22" - Connector: DP-2
Display: LG Electronics 27" - Connector: DP-5

이제 커넥터가 DP-2라는 것을 알고 있습니다.

그런 다음 이 간단한 bash 스크립트를 만들고 실행했습니다 sudo.

#!/bin/bash
VENDOR_ID=222a
PRODUCT_ID=0001
MONITOR_CONNECTOR=DP-2
CALIBRATION_MATRIX="0.333333333 0 0.666666667 0 0.5 0 0 0 1"

UDEV_RULE="ENV{ID_VENDOR_ID}==\"${VENDOR_ID}\",ENV{ID_MODEL_ID}==\"${PRODUCT_ID}\",ENV{WL_OUTPUT}=\"${MONITOR_CONNECTOR}\",ENV{LIBINPUT_CALIBRATION_MATRIX}=\"${CALIBRATION_MATRIX}\""
UDEV_RULES_FILE="/etc/udev/rules.d/99-touchscreen-cal.rules"

echo "${UDEV_RULE}" > "${UDEV_RULES_FILE}"
udevadm control --reload-rules && udevadm trigger

오류가 발생하지 않습니다. 그런 다음 생성된 규칙 파일을 다시 확인했습니다.

$ cat /etc/udev/rules.d/99-touchscreen-cal.rules 
ENV{ID_VENDOR_ID}=="222a",ENV{ID_MODEL_ID}=="0001",ENV{WL_OUTPUT}="DP-2",ENV{LIBINPUT_CALIBRATION_MATRIX}="0.333333333 0 0.666666667 0 0.5 0 0 0 1"

그러면 모든 것이 제대로 작동할 것입니다. 그렇죠? 그러나 그것은 진실이 아니다. 터치스크린 입력은 여전히 ​​이전처럼 부정확합니다.

이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

편집하다:

내부 터치스크린을 비활성화하지 않으면 외부 터치스크린은 터치 입력을 모든 디스플레이에 분산시키는 대신 모든 터치 입력을 내부 터치스크린으로 보냅니다. (외부 1080p 터치스크린의 오른쪽 하단을 터치하면 노트북처럼 내장된 4k 터치스크린의 오른쪽 하단에 터치가 등록됩니다...) 모니터 3대
(왼쪽부터 오른쪽으로: 외부 4k 화면, 외부 1080p 터치스크린, 내장 4k 터치스크린)

편집 2:

~에 따르면이것기사에 따르면 다중 모니터 설정에서 터치스크린이 제대로 작동하도록 하는 유일한 방법은 X11을 사용하는 것입니다. 기사 에 따르면 libinput currently assumes the touchscreen(s) covers all available monitors.내부(USB가 아닌) 터치스크린이 다중 모니터 설정에서도 제대로 작동하기 때문에 잘못된 것으로 알고 있습니다.

관련 정보