Waylandでタッチスクリーンを補正する方法は?

Waylandでタッチスクリーンを補正する方法は?

私はGnomeとWaylandを実行しているFedora 35ノートブックを持っています。マルチモニター設定でも機能し、キャリブレーションを必要としない内蔵タッチスクリーンがあります。
2つの外部モニター(通常の4kモニターと1080p USB-Cタッチスクリーン)があります。このモニターを接続するときは、この設定では不要なため、内部ノートパソコンの画面を無効にします。だから私はついに次の結論に達しました。

モニター設定

本当に大丈夫です。 (右画面は外部タッチスクリーン、左画面は外部4kモニターです。)

問題は、タッチスクリーンが実際には1920×1080のときに5760×2160ピクセルと認識し、タッチ入力が正しくなくなることです。

誤ったタッチ入力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ではなく)タッチスクリーンがマルチモニタ設定でも正常に動作するため、間違っていることがわかっています。

関連情報