Smile Engineering Blog

ジェイエスピーからTipsや技術特集、プロジェクト物語を発信します

Wayland でのコマンドラインによる解像度変更

はじめに

Ubuntu 21.04 がリリースされました。この版からデフォルトのウィンドウプロトコル(ディスプレイサーバプロトコル、ウィンドウシステム)として、Xorg に変わり Wayland が採用されています。

今までは xrandr コマンドを用いたスクリプトで解像度を切り替えていたのですが、Wayland では同じ方法ではできなくなってしまいました。調査した結果、D-Bus 経由で代用できることが分かったので、備忘のため記します。

スクリプト

いきなり答えですが、これです。

解像度 "1920x1200@59.885101318359375" の例:

#!/bin/bash

display_name="Virtual-1"
resolution="1440x900@59.887947082519531"

function get_serial() {
  serial="$(gdbus call --session --dest org.gnome.Mutter.DisplayConfig \
  --object-path /org/gnome/Mutter/DisplayConfig \
  --method org.gnome.Mutter.DisplayConfig.GetResources | awk '{print $2}' | tr -d ',')"
  echo $serial
}

serial=$(get_serial)
gdbus call --session --dest org.gnome.Mutter.DisplayConfig \
  --object-path /org/gnome/Mutter/DisplayConfig \
  --method org.gnome.Mutter.DisplayConfig.ApplyMonitorsConfig \
  $serial 1 "[(0, 0, 1, 0, true, [('$display_name', '$resolution', [] )] )]" "[]"

get_serial 関数で現在の設定の識別子 $serial を取得し、この識別子を用いてモニタの設定を適用しています。

変数 $display_name、および $resolution ですが、事前に DisplayConfig オブジェクトに問い合わせて希望の値を調べておきます。

DisplayConfig オブジェクトへの問い合わせ:

gdbus call \
--session \
--dest=org.gnome.Mutter.DisplayConfig \
--object-path /org/gnome/Mutter/DisplayConfig \
--method org.gnome.Mutter.DisplayConfig.GetResources

問い合わせ結果例:

$ gdbus call \
--session \
--dest=org.gnome.Mutter.DisplayConfig \
--object-path /org/gnome/Mutter/DisplayConfig \
--method org.gnome.Mutter.DisplayConfig.GetResources
(uint32 3, \
  [(uint32 0, int64 38, 0, 0, 1920, 1200, 17, uint32 0, [uint32 0, 1, 2, 3, 4, 5, 6, 7], @a{sv} {}),
  (1, 43, 0, 0, 0, 0, -1, 0, [0, 1, 2, 3, 4, 5, 6, 7], {}),
  (2, 48, 0, 0, 0, 0, -1, 0, [0, 1, 2, 3, 4, 5, 6, 7], {}),
  (3, 53, 0, 0, 0, 0, -1, 0, [0, 1, 2, 3, 4, 5, 6, 7], {}),
  (4, 58, 0, 0, 0, 0, -1, 0, [0, 1, 2, 3, 4, 5, 6, 7], {}),
  (5, 63, 0, 0, 0, 0, -1, 0, [0, 1, 2, 3, 4, 5, 6, 7], {}),
  (6, 68, 0, 0, 0, 0, -1, 0, [0, 1, 2, 3, 4, 5, 6, 7], {}),
  (7, 73, 0, 0, 0, 0, -1, 0, [0, 1, 2, 3, 4, 5, 6, 7], {})],
  [(uint32 0, int64 4294967332, 0, [uint32 0], 'Virtual-1', [uint32 14, 6, 17, 0, 9, 12, 16, 18, 5, 8, 2, 10, 3, 13, 1, 15, 7, 11, 4], @au [], {'vendor': <'unknown'>, 'product': <'unknown'>, 'serial': <'unknown'>, 'width-mm': <0>, 'height-mm': <0>, 'display-name': <'Virtual-1'>, 'backlight': <-1>, 'min-backlight-step': <-1>, 'primary': <true>, 'presentation': <false>, 'connector-type': <'VIRTUAL'>, 'underscanning': <false>, 'supports-underscanning': <false>})], 
  [(uint32 0, int64 0, uint32 1856, uint32 1392, 59.995689392089844, uint32 6), 
  (1, 1, 1280, 768, 59.8707275390625, 6), 
  (2, 2, 1360, 768, 60.015655517578125, 5), 
  (3, 3, 1280, 960, 60.000499725341797, 5), 
  (4, 4, 640, 480, 59.940975189208984, 10), 
  (5, 5, 1440, 900, 59.887947082519531, 6), 
  (6, 6, 1920, 1440, 60.000499725341797, 6), 
  ..省略.. 
  (67, 67, 2304, 4096, 59.989521026611328, 9), 
  (68, 68, 2880, 5120, 59.987667083740234, 9)], 65535, 65535)

参考:

デスクトップのスクリプトをダブルクリックで実行する

デスクトップのスクリプトをダブルクリックで実行するには Files(nautilus)の Preferences で設定します。

f:id:jspnet:20210504223327p:plain

「Executable Text Files」の Run them もしくは Ask what to do を選択します。

これにより、解像度別のスクリプトをデスクトップに作成しておき、ダブルクリックで変更できるようになります。

おわりに

VMUbuntu Desktop を使用していて、かつマルチモニター環境の人向けのトピックでした。。が、わりと探している人も多かったのでヒントになれば。

D-Bus まわりについてはまだ勉強不足ですので、おかしなところがありましたらご指摘下さると嬉しいです。Python あたりで書くと楽そうなのでもうちょっと勉強してみます。