0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Linux Mintで画面の自動回転を行う。

Last updated at Posted at 2022-01-01

以前メルカリで1万円しないで購入したLenovo YOGA900がメモリ4GB固定でWindows厳しいのでLinux Mint(Cinamon)をインストールしスワップ12GB突っ込んだら意外と使い勝手のいいモバイルPCになりました。
とはいえせっかくヒンジが360度回転するのにモニタが自動で回転しないのがもったいないので色々試してみて上手くいった方法を備忘録として書き残しておきます。合わせてタッチパネルも回転時にずれないように調整する必要があるのでその辺りをまとめて対応しました。

PC情報

メーカー 機種名 CPU メモリ OS バージョン GUI
Lenovo YOGA 900 Core(TM) i5-6200U 4GB Linux Mint 20.2 Cinamon

参考にしたサイト

Ubuntu16.04LTSの画面を自動回転させる
Linuxで画面&タッチスクリーンを90度回転 (Debian10 KDE)

ちゃんと実装する人は上の記事は絶対読みましょう。

やること

  1. xinput listで回転させるモニター(タッチパネル)デバイス名を探す。
  2. monitor-sensorコマンドでモニターの傾きを検出
  3. モニターの傾きに合わせてxranderコマンドでモニターを回転
  4. 1で取得したタッチパネル情報から回転後の座標を調整
  5. 2-4を行うスクリプトをGUIの自動起動設定に追加

2-4はPythonで書きました。
といってもPythonで各コマンド叩かせるだけなんですがねw

作業の流れ

1. xinput listでタッチパネルのデバイス名を調べる

$ xinput list
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ Synaptics TM3066-002                    	id=10	[slave  pointer  (2)]
⎜   ↳ ELAN21EF:00 04F3:227C                   	id=11	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Video Bus                               	id=7	[slave  keyboard (3)]
    ↳ Power Button                            	id=8	[slave  keyboard (3)]
    ↳ Lenovo EasyCamera: Lenovo EasyC         	id=9	[slave  keyboard (3)]
    ↳ Ideapad extra buttons                   	id=12	[slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard            	id=13	[slave  keyboard (3)]

この中でELAN21EF:00 04F3:227Cが私の環境でのタッチパネルデバイス名です。
座標の調整にこのidが必要になるんですが、再起動だったりマウスも使ったりするとよく変わるので次のPythonのスクリプト内で拾います。

2. モニタの回転、タッチパネルの座標調整

以下のPythonスクリプトを用意します。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import subprocess
from subprocess import PIPE, STDOUT

# get input id
def get_input_id(monitor_name):
    cmd = "xinput list | grep '{}' | awk -F'[\t=]' '{{print $3}}'".format(monitor_name)
    proc = subprocess.Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT,text=True)
    outs,err = proc.communicate()
    id = outs.rstrip()
    return id

# check monitor-sensor and monitor rotate
def monitor_rotate(monitor_name):

    # check word of monitor-sensor
    check_word = "Accelerometer orientation changed:"
  
    # monitor_rotate
    cmd = "/usr/bin/monitor-sensor"
    proc = subprocess.Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT,text=True)
    
    while True:
        monitor_status = proc.stdout.readline()
        
        if "normal" in monitor_status:
            id = get_input_id(monitor_name)
            monitor_rotate_cmd = \
            "/usr/bin/xrandr -o normal " \
            "&& " \
            "xinput set-prop {} 'Coordinate Transformation Matrix' 1 0 0 0 1 0 0 0 1".format(id)
            subprocess.Popen(monitor_rotate_cmd, shell=True, stdout=PIPE, stderr=STDOUT,text=True)
        elif "right-up" in monitor_status:
            id = get_input_id(monitor_name)
            monitor_rotate_cmd = \
            "/usr/bin/xrandr -o right " \
            "&& " \
            "xinput set-prop {} 'Coordinate Transformation Matrix' 0 1 0 -1 0 1 0 0 1".format(id)
            subprocess.Popen(monitor_rotate_cmd, shell=True, stdout=PIPE, stderr=STDOUT,text=True)
        elif "bottom-up" in monitor_status:
            id = get_input_id(monitor_name)
            monitor_rotate_cmd = \
            "/usr/bin/xrandr -o inverted " \
            "&& " \
            "xinput set-prop {} 'Coordinate Transformation Matrix' -1 0 1 0 -1 1 0 0 1".format(id)
            subprocess.Popen(monitor_rotate_cmd, shell=True, stdout=PIPE, stderr=STDOUT,text=True)
            
if __name__ == '__main__':
    monitor_name = "<タッチパネルデバイス名>"
    monitor_rotate(monitor_name)

<タッチパネルデバイス名>の部分に先程のデバイス名を突っ込んで上げればOKです。
やってることは完全にLinuxのコマンドをPythonに叩かせているだけですえ(笑)シェルスクリプトでもいいんですがsubprocess.Popenで叩いたコマンドの標準出力結果って変数に格納して継続監視できるのでmonitor-sensorの傾き情報をログファイル等に用意すること無く傾きの検出することができるので必要なものはこのPythonスクリプト一つだけでOK!と少しは作業の楽が出来るかなと!

ちなみにモニターのleft-upの状態が無いのは、YOGA900の右側にいろいろ電源ボタンとかがあるので右側が下になると勝手に電源落としたりスリープになったりと誤作動をよく起こしたことがあり個人的な理由で抜きました。

ではこのスクリプトを適当な名前で保存して実行権限を付けます。

# 私は/opt配下にmonitor-rotate.pyで保存していますので作成して保存したスクリプト名に読み替えてください。
$ sudo chmod 755 /opt/monitor-rotate.py
または
$ sudo chmod +x /opt/monitor-rotate.py

3. Linux MintのGUI設定で自動起動させるようにする。

最後に"設定" > "自動開始させるアプリケーション"から先程作成したPythonスクリプトを選択します。
image.png
image.png

なんとなくで起動遅延時間を1秒入れています。

Linux Mintでの内容で書いてますが、デストリビューション側のGUIでアプリの自動起動機能があればいけるのではないかと思います。

所感

結局どうしてsystemctlでデーモン化して上手く動かなかったのか不明という残念な結果ですいません。トラブルシューティングを行う場合としては非常にまずいですね。
実際にサービスとしては起動してくれてmonitor-sensorも動いていることは確認できてたんですけど、自動回転せずorz
まぁサーバーではなく一般的なクライアントOSとしてのLinux利用なのでGUI側で実装できることはそれでOKとすべきかなとこんな形になりました。
試行錯誤しまくってたので最初Pythonで書いたら楽じゃないか!!って思って作り出してから2日もかかるというね。

そしてこれ書いている間になんか使ってた無線マウス行方不明orz

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?