お知らせ

  • 利用規約を守って投稿してください。また、よくある質問および投稿の手引きも参照してください。
  • メッセージの投稿にはアカウントが必要です。未登録の方は、ユーザ登録ページからアカウントを作成することができます。

#1 2019-05-29 01:33:41

ShiroAmada
メンバ
登録日: 2019-05-06

GNOMEのD-Busイベントで、タブレットPCの画面自動回転及びタッチスクリーンを適切に処理する方法について

■ サマリ
D-Busイベントで、タブレットPCの画面自動回転及びタッチスクリーンを適切に処理する方法についてご教示いただけないでしょうか。

■ Ubuntuのバージョン
19.04-Desktop

コード:

$ uname -a && cat /etc/lsb-release
Linux U1904 5.1.0-050100-generic #201905052130 SMP Mon May 6 01:32:59 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=19.04
DISTRIB_CODENAME=disco
DISTRIB_DESCRIPTION="Ubuntu 19.04"

■ ハード(タブレットPC)
TOSHIBA dynabook Tab S68/N
https://dynabook.com/pc/catalog/tablet_ … 8/spec.htm

コード:

$ dmesg | grep 'TOSHIBA dynabook'
[    0.000000] DMI: TOSHIBA dynabook Tab S68/N/Type2 - Board Product Name, BIOS 1.40 04/15/2015

■ 質問内容
前述のハードウェアで、画面の自動回転とタッチスクリーンを適切に処理する方法がわからず悩んでおります。
・ デスクトップ環境にGNOMEを採用し、iio-sensor-proxyを導入することにより、画面の自動回転を適切に処理可能であること確認しました。
・ Xrog + GNOME の環境においてはタッチスクリーンの入力識別が適正でない問題を確認しました。
・ wayland + GNOME の環境においては、画面の自動回転及びタッチスクリーンの入力識別が適正であることを確認しました。
上記について、以前 https://forums.ubuntulinux.jp/viewtopic.php?id=20450 に記載しました。


しかしながら、私の環境においては wayland の動作が不安定で、画面ロックのからの回復等でフリーズする現象が発生しています。
Xorg で適切な処理を実現したく、ご意見・ご教示いただきたいと考えております。

画面の自動回転に利用しているプログラム

コード:

$ apt list --installed iio-sensor-proxy
Listing... Done
iio-sensor-proxy/disco,now 2.5-0ubuntu1 amd64 [installed,automatic]

上記のプログラムを読んだところ、g_dbus_connection_emit_signal というAPI(?)で画面の回転が発生したことを通知していると理解しました。
(D-Bus や GNOME の API 等に疎いため、誤った理解かもしれません)

iio-sensor-proxy.c

コード:

    g_dbus_connection_emit_signal (data->connection,
                       NULL,
                       (mask & PROP_ALL) ? SENSOR_PROXY_DBUS_PATH : SENSOR_PROXY_COMPASS_DBUS_PATH,
                       "org.freedesktop.DBus.Properties",
                       "PropertiesChanged",
                       props_changed, NULL);

上記の理解から、GNOMEが当該 D-Bus のメッセージを受けて、画面回転及びタッチスクリーンの入力マッピングを調整しているのではないかと推察しています。
以上で、私の理解を超えたので、GNOMEが具体的に上記メッセージをどのように処理しているのかについてご教示いただきたい次第です。

直接的なご回答でなくとも結構ですので、参考になりそうな情報等あればご教示いただけないでしょうか。

オフライン

 

#2 2019-05-31 20:18:45

taka.zoo.n
メンバ
登録日: 2013-05-30

Re: GNOMEのD-Busイベントで、タブレットPCの画面自動回転及びタッチスクリーンを適切に処理する方法について

はじめにお断りしておきますが、私は実機を持っていないどころか、タブレットPCを使ったことがありません。ubuntu の標準的な desktopも使っていません。dbus も glib ではなくlibdbus で使っています。ですが、レスがつかないようなので、あえてコメントさせていただきます。なので以下はとんでもなく的はずれなコメントになっている可能性が有ることをご理解願います。話が噛み合ってないと思われる点、よくわからない点があれば遠慮無くご指摘下さい。

dbus の signal は linux kernel の signal(送り手が signal の伝達先を決める)とは異なり、受け手が受け取りたい signal を指定します。(イメージ的には IP の broadcast や multicast に近いです)。なので送られた signal がどう処理されているかを突き止めるのは一般にはかなり厄介です。

signal を受け取るのが独立したプロセスなら Wayland と X.org でログインしてps ax の結果を比べるのでしょうけど、window manager に組み込まれているならこれではダメですよね。

もし、私だったら以下のような手順を踏むと思います。

まず、X.org でも本体の向きを変えた時に dbus に property changed signal が送られていることを確認する必要があります。X.org の desktop でログインして端末から

コード:

dbus-monitor --system >/tmp/foo

を実行して下さい。本体を適当に回転(少なくとも90度回転を4回)させてから Ctrl-c で dbus-monitor を終了させます。ファイル /tmp/foo を調べてセンサーの回転に関連する signal の object, interface, member, signalの値(member の後に書かれている array[ ... ] の中身)などの情報を収集します。dbus-monitor 実行中の system message bus を流れる全てのメッセージが記録されているのでちょっと大変かもしれませんが、どんなメッセージが飛んでいるのか分からないので最初は特定のメッセージに限定せず全部ファイルに残して調べたほうが結局は早道だと思います。

もし、signal が発生していないなら
   ps ax | grep iio-sensor-proxy

   systemctl status iio-sensor-proxy
で iio-sensor-proxy の状態をしらべます。

signal が発生しているとして、そもそもお使いの desktop で加速度センサーによる画面の自動回転はサポートされているのでしょうか?されている場合どの package が担当しているのでしょうか?私には皆目見当が付きません。が、適切なパッケージをインストールことになるのだと思います。

サポートされていなければ、自分で signal handler を書いても既存のパッケージとは干渉しないことを期待しつつ、signal handler を書くと思います。いきなり C で書くのは大変なので最初は shell 手続きで動作を検証します。骨格は

dbus-monitor(今度は必要とするsignalのみにfilterする)でセンサーの向きが変わったことを検知したら
dbus-query でセンサーの向きを取得して(注:センサーの向きは dbus-monitor の結果をきちんと解釈すれば取得できるはずですがそれは面倒なので改めて dbus-query を実行したほうが安易に取得できるはずです。)その向きに応じて xrandr と xinput を実行する

となります。(数十行程度???)漠然としすぎているかもしれませんが、上で調べた dbus-monitor の出力を教えていただければ、もう少し具体的に説明できると思います。性能上の問題がなければもうこれで良しとするでしょうし、重くて耐えられなくなったら(なってから) C で書き直すと思います。

また、どのような実装にせよ、ログインする度にいちいち端末を開いて自動回転のためのコマンドを実行するのは面倒なので、自動的に実行させるようにするわけですが、これはお使いのdesktop 環境に依存します。

オフライン

 

#3 2019-06-01 07:50:00

ShiroAmada
メンバ
登録日: 2019-05-06

Re: GNOMEのD-Busイベントで、タブレットPCの画面自動回転及びタッチスクリーンを適切に処理する方法について

taka.zoo.n さん
ありがとうございます。

taka.zoo.n さん による投稿:

dbus の signal は linux kernel の signal(送り手が signal の伝達先を決める)とは異なり、受け手が受け取りたい signal を指定します。(イメージ的には IP の broadcast や multicast に近いです)。

理解しました。体系だった知識が不足しているので、根本的な挙動についてのご助言を頂き嬉しいかぎりです。

ご助言頂いた手順に沿い、一旦全てのdbusメッセージを記録のうえ、「path=」でフィルターをかけてモニターした結果、以下の出力を得ることができました。

コード:

user@host:~$ sudo dbus-monitor --system path=/net/hadess/SensorProxy
signal time=1559338645.050678 sender=org.freedesktop.DBus -> destination=:1.296 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired
   string ":1.296"
signal time=1559338645.050748 sender=org.freedesktop.DBus -> destination=:1.296 serial=4 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameLost
   string ":1.296"
signal time=1559338645.783433 sender=:1.10 -> destination=(null destination) serial=253 path=/net/hadess/SensorProxy; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
   string "net.hadess.SensorProxy"
   array [
      dict entry(
         string "AccelerometerOrientation"
         variant             string "left-up"
      )
   ]
   array [
   ]
signal time=1559338647.188631 sender=:1.10 -> destination=(null destination) serial=254 path=/net/hadess/SensorProxy; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
   string "net.hadess.SensorProxy"
   array [
      dict entry(
         string "AccelerometerOrientation"
         variant             string "normal"
      )
   ]
   array [
   ]
signal time=1559338648.595074 sender=:1.10 -> destination=(null destination) serial=255 path=/net/hadess/SensorProxy; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
   string "net.hadess.SensorProxy"
   array [
      dict entry(
         string "AccelerometerOrientation"
         variant             string "right-up"
      )
   ]
   array [
   ]
signal time=1559338649.987029 sender=:1.10 -> destination=(null destination) serial=256 path=/net/hadess/SensorProxy; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
   string "net.hadess.SensorProxy"
   array [
      dict entry(
         string "AccelerometerOrientation"
         variant             string "bottom-up"
      )
   ]
   array [
   ]

taka.zoo.n さん による投稿:

signal が発生しているとして、そもそもお使いの desktop で加速度センサーによる画面の自動回転はサポートされているのでしょうか?

GNOMEデスクトップ環境において画面の自動回転がサポートされていると考えています。
iio-sensor-proxy の READMEの記述

With a GNOME 3.18 (or newer) based system, orientation changes will automatically be applied when rotating the panel, ambient light will be used to change the screen brightness, and Geoclue will be able to read the compass data to show the direction in Maps.

・ 実際の挙動
当方の環境では筐体の回転に伴い画面が自動回転します。
- GNOME + Wayland : 画面の自動回転 → ○、画面の自動回転にともなうタッチスクリーンのマッピング(回転) → ○
- GNOME + Xorg : 画面の自動回転 → ○、画面の自動回転にともなうタッチスクリーンのマッピング(回転) → ×
という状況です。

taka.zoo.n さん による投稿:

どの package が担当しているのでしょうか?私には皆目見当が付きません。が、適切なパッケージをインストールことになるのだと思います。

これについては、私も全くわかりません。
top -d1 しながら画面を回転させてみたところ、回転時にリソース消費(CPU,メモリ)が目立って変動するのは、gnome-shell, iio-sensor-proxy, Xwayland, gsd-color, dbus-daemon, systemd-journal, gsd-xsettings 等でした。
以上が頂いた助言への対応報告となり、以下、今後の対応の方向性の検討状況となります。
以下のご助言に沿って進める予定です。

taka.zoo.n さん による投稿:

dbus-monitor(今度は必要とするsignalのみにfilterする)でセンサーの向きが変わったことを検知したら
dbus-query でセンサーの向きを取得して(注:センサーの向きは dbus-monitor の結果をきちんと解釈すれば取得できるはずですがそれは面倒なので改めて dbus-query を実行したほうが安易に取得できるはずです。)その向きに応じて xrandr と xinput を実行する

となります。(数十行程度???)漠然としすぎているかもしれませんが、上で調べた dbus-monitor の出力を教えていただければ、もう少し具体的に説明できると思います。性能上の問題がなければもうこれで良しとするでしょうし、重くて耐えられなくなったら(なってから) C で書き直すと思います。

iio-sensor-proxy には monitor-sensor というツールが付属しており、これを使用すれば dbus-monitor の出力をフィルタする部分について省力化できそうです。(dbus-query については、当方の環境でコマンド・該当するパッケージを発見できず試行できていません)
ご助言いただいたシェルスクリプトによる対応については、類似の処理を実装されている方がいらっしゃいました。
https://github.com/jfwells/linux-asus-t … /rotate.sh
C言語については、以下を参考に当方の環境にポーティングできそうと考えています。
https://github.com/mrquincle/yoga-900-a … o-rotate.c

考えを整理しつつ投稿文を書きましたが、ここまでやるのであれば、ウインドウマネージャを変更しても良いなと思い始めました。
GNOMEを選択した理由が画面の自動回転対応であり、リソース消費(CPU,メモリ,バッテリー)については改善したいと考えていたためです。
そうなると、iio-sensor-proxy について、dbusシグナルを発信している箇所を、直接 XRRRotations, XInternAtom を呼ぶように変更した方が効率が良いような気もしています。
今後の対応については、改めて整理のうえ結果を投稿させて頂く予定です。
当方の理解不足・誤認等ありましたらご指摘頂けますと助かります。
マイナーな(恐らく機種依存の?)トピックにご助言頂きありがとうございます。

オフライン

 

#4 2019-06-01 10:20:45

taka.zoo.n
メンバ
登録日: 2013-05-30

Re: GNOMEのD-Busイベントで、タブレットPCの画面自動回転及びタッチスクリーンを適切に処理する方法について

すいません、dbus-query は誤りで正しくは dbus-send です。(パッケージ dbus に入っているので既にインストールされているはずです。)
不手際をお詫びします。

ShiroAmada による投稿:

iio-sensor-proxy には monitor-sensor というツールが付属しており、これを使用すれば dbus-monitor の出力をフィルタする部分について省力化できそうです。

これ、知りませんでした。monitor-sensor.c を眺めてみましたが、確かにこの方が簡単そうですね。

コード:

#!/bin/sh
monitor-sensor | while read w1 w2 w3 w4 w5 ; do
  if [ "$w1" = Accelerometer -a "$w2" = "orientation" -a "$w3" = "changed:" ]
  then
     $w4 に応じて xinput や xrandr を実行する
  fi
done

みたいな骨格でしょうか(私の環境では試しようがないので間違っているかもしれません。)

ShiroAmada による投稿:

ご助言いただいたシェルスクリプトによる対応については、類似の処理を実装されている方がいらっしゃいました。
https://github.com/jfwells/linux-asus-t … /rotate.sh

これだとセンサーの状態を3秒毎にポーリングしているので回転が反映されるのが最悪3秒後とかなり違和感を覚えるのではないかと想像します。
他方、dbus の signal 遅延は通常ミリ秒以下のオーダーですので、これが問題になるとは思えません。
問題はお使いのマシンで xrandr と xinput をロードする時間が ShiroAmada さんにとって受け入れられるかどうかですが、shell 手続きであれば作るのは大した手間ではないので取り敢えず実験してみてはいかがでしょうか、

iio-proxy-sensor の仕様がどの程度安定しているのか全く分かりませんが、GNOME で対応しているとなっているなら、抜本的な対策(というか sensor 回りの API の変更の影響を受けない対策)は然るべきパッケージをインストールすべきことのように思えます。(19.04 は LTS ではありませんし。)他方 Wayland では動いているのですから不足しているパッケージはないとも思えます。もしかして Wayland と X.org では別のパッケージの GNOME が使われることがありえるのでしょうか?どうにも分かりません。

オフライン

 

#5 2019-06-02 10:49:45

ShiroAmada
メンバ
登録日: 2019-05-06

Re: GNOMEのD-Busイベントで、タブレットPCの画面自動回転及びタッチスクリーンを適切に処理する方法について

ありがとうございます。
dbus-send ありました。
指定可能なプロパティや、送信可能なメソット及びそのリプライ等を調査するためのツールでしょうか。
かなりオプションが多いのでまだ使い方を調べきれておりません。

taka.zoo.n さん による投稿:

問題はお使いのマシンで xrandr と xinput をロードする時間が ShiroAmada さんにとって受け入れられるかどうかですが、shell 手続きであれば作るのは大した手間ではないので取り敢えず実験してみてはいかがでしょうか、

いただいたサンプルコードから以下のスクリプトを作成し、実行してみました。(画面回転は自動実行されているので、タッチスクリーンの位置調整のみスクリプトで実行しています)

コード:

#!/bin/sh
INPUT_DEVICE="Wacom HID 5011 Finger"
INPUT_PROPERTY="Coordinate Transformation Matrix"
monitor-sensor | while read w1 w2 w3 w4; do
  if [ "$w1" = "Accelerometer" -a "$w2" = "orientation" -a "$w3" = "changed:" ]
  then
    case "$w4" in
      "normal" ) xinput set-prop "$INPUT_DEVICE" "$INPUT_PROPERTY" 1 0 0 0 1 0 0 0 1;;
      "left-up" ) xinput set-prop "$INPUT_DEVICE" "$INPUT_PROPERTY" 0 -1 1 1 0 0 0 0 1;;
      "right-up" ) xinput set-prop "$INPUT_DEVICE" "$INPUT_PROPERTY" 0 1 0 -1 0 1 0 0 1;;
      "bottom-up" ) xinput set-prop "$INPUT_DEVICE" "$INPUT_PROPERTY" -1 0 1 0 -1 1 0 0 1;;
      * ) ;;
    esac
fi
done

タッチスクリーンの位置調整(回転)が適正化され、スクリプトによるタッチスクリーン調整のオーバーヘッドについては体感できない程度でした。
アナログな方法ですが、筐体を回転させ始めてから画面が再描画されるまでの時間をストップウォッチで計測してみました。
・ GNOME on Xorg(スクリプト無) : 4.2s ~ 4.5s
・ GNOME on Xorg(スクリプト有) : 4.1s ~ 4.6s
・ GNOME on Wayland: 1.1s ~ 1.5s
併せてリソースの消費状況についても確かめてみました。

GNOME on Xorg(スクリプト無)

コード:

user@host:~$ uptime && vmstat && free -h
 09:38:26 up 3 min,  2 users,  load average: 1.46, 0.95, 0.39
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 651808  53160 761624    0    0   901   177  293  538 14  6 79  1  0
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       486Mi       636Mi        47Mi       795Mi       1.2Gi
Swap:         2.4Gi          0B       2.4Gi

GNOME on Xorg(スクリプト有)

コード:

user@host:~$ uptime && vmstat && free -h
 09:45:45 up 3 min,  2 users,  load average: 1.02, 0.92, 0.43
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 650528  53296 762092    0    0   629   124  231  428 11  4 84  1  0
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       487Mi       635Mi        47Mi       796Mi       1.2Gi
Swap:         2.4Gi          0B       2.4Gi

GNOME on Wayland

コード:

user@host:~$ uptime && vmstat && free -h
 09:57:17 up 3 min,  2 users,  load average: 1.07, 0.80, 0.35
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 622564  53080 758520    0    0   886    36  284  534 14  5 80  1  0
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       517Mi       607Mi        47Mi       792Mi       1.2Gi
Swap:         2.4Gi          0B       2.4Gi

こちらもスクリプトの有無による有意な差は無いようです。

おかげさまで、Xorg利用時にタッチスクリーンのタッチ位置適正化が実現できました。ありがとうございます。
ただ、GNOMEにおいて画面の自動回転処理を実施しているプロセスの特定、及び Xorg と Wayland で挙動が異なる理由が未だ気になっており、継続して調査したいと思います。

オフライン

 

#6 2019-06-05 20:37:53

ShiroAmada
メンバ
登録日: 2019-05-06

Re: GNOMEのD-Busイベントで、タブレットPCの画面自動回転及びタッチスクリーンを適切に処理する方法について

追記します。
どうやら GNOME 3.32 のバグだったようです。
解決策としては、 3.32.2へのアップデート又は 3.30 へのダウングレードが考えられるようです。

https://gitlab.gnome.org/GNOME/mutter/issues/514
https://gitlab.gnome.org/GNOME/mutter/issues/581

Ubuntu 19.04 の GNOME のバージョンは 3.32.1 でした。

コード:

user@host:~$ gnome-shell --version && mutter --version
GNOME Shell 3.32.1
mutter 3.32.1
(略)

以下、先の投稿で頂いた taka.zoo.n さんの疑問にご回答できていなかった箇所について、調査結果をもとに私の理解を記載します。

taka.zoo.n さん による投稿:

iio-proxy-sensor の仕様がどの程度安定しているのか全く分かりませんが、GNOME で対応しているとなっているなら、抜本的な対策(というか sensor 回りの API の変更の影響を受けない対策)は然るべきパッケージをインストールすべきことのように思えます。(19.04 は LTS ではありませんし。)他方 Wayland では動いているのですから不足しているパッケージはないとも思えます。もしかして Wayland と X.org では別のパッケージの GNOME が使われることがありえるのでしょうか?どうにも分かりません。

・ iio-proxy-sensor の仕様がどの程度安定しているのか
iio-proxy-sensor の仕様の安定度=GNOMEプロジェクトの安定度と考えて良いかと思います。
GNOME のソースコードをざっと眺めてみました。
https://download.gnome.org/core/3.32/3.32.1/sources/
mutter というプログラム(GNOME のウインドウマネージャ?)の src/backends/meta-orientation-manager.c iio-sensor-proxy の D-Bussプロキシパスがハードコーディングされていました。

コード:

  g_dbus_proxy_new (connection,
                    G_DBUS_PROXY_FLAGS_NONE,
                    NULL,
                    "net.hadess.SensorProxy",
                    "/net/hadess/SensorProxy",
                    "net.hadess.SensorProxy",
                    self->cancellable,
                    iio_proxy_ready,
                    self);

恐らく、ハードウェア使用の変更又は追加 -> iio-sensor-proxy の仕様変更 <-> mutter の仕様変更という連携が取れていそうなイメージを持っています。

・ 然るべきパッケージ
調査の結果、gnome-shell, mutter が然るべきパッケージ(iio-sensor-proxy の出力を受けて画面回転を制御するプログラム)であると考えています。
今回のケースにおいては、mutter のバグであることに気づけなかったため、パッケージの不足(特定)も問題に関連していると考えていました。
もう少し早くバグの可能性を探るべきでした。

・ もしかして Wayland と X.org では別のパッケージの GNOME が使われることがありえるのでしょうか?
パッケージとしては同一のものが使用されており、ディスプレイサーバの違いにより mutter が処理を変えているようです。
src/backends/meta-*.c というプログラム群が、抽象化した処理(画面拡大・回転等)を実行し、
src/backends/native, src/backends/x11, src/wayland, src/x11 等のプログラム群がより低層の処理を実行しているように見えます。
(詳細にソースコードを見たわけではないので、間違っているかもしれません)

今回GNOMEのバグが原因ということで、対応としては GNOME の新バージョンが Ubuntu に降りてくるの待つことになると思います。
原因が判明しスッキリしました。また当面のワークアラウンドについてのご助言を頂き助かりました。ありがとうございました。

オフライン

 

Board footer

Powered by FluxBB