[Ubuntu]devilspie2でウインドウサイズと位置を調整

# 背景

Webアプリケーション開発では以下のようなGUIアプリケーションを常時起動しています。これらアプリケーション(ウインドウ)の同時一覧性を高めるためにモニタ上に適切なサイズで配置することは作業効率向上のために欠かせません。

- IDE(統合開発環境)
- ブラウザ
- ターミナル
- テキストエディタ・・・メモやTODO、IDE上では不向きなコードの編集・整形に利用
- データベースクライアント

私の場合は40インチ4Kモニタに以下のように配置しています。

![](https://i.gyazo.com/243794f6de36d95634e142c00e790caf.png)


# 課題

私が開発に使用している端末のOSは`Ubuntu18.04`です。

![](https://i.gyazo.com/1bc3669a6e24363fc681adcab93679f2.png)


Ubuntu18.04ではこれらのアプリケーション(ウインドウ)のサイズは記憶されますが、表示位置は記憶されません。毎回、微妙な位置に表示されてしまいます。毎回ウインドウを最適な位置に移動させるのは時間の無駄なので`devilspie2`を使って指定します。

- [devilspie2/README](https://github.com/gusnan/devilspie2/blob/master/README)
- [Devilspie2 for Automatic Placement of Windows on a Linux Desktop](https://www.justingedge.com/linux/devilspie2-automatic-window-placement/)

# 手順

- `devilspie2`のインストール
- 表示位置(x,y)とサイズ(width,height)の取得
- 設定ファイルの作成と配置
- 実行

## devilspie2のインストール

```
$ sudo apt install devilspie2

$ devilspie2 --help
用法:
  devilspie2 [OPTION…] - ウィンドウにルールを適用

ヘルプのオプション:
  -h, --help              ヘルプのオプションを表示する

アプリケーションのオプション:
  -d, --debug             標準出力にデバッグ情報を書き出す
  -e, --emulate           ルールを適用せず, エミュレーションのみ行う
  -f, --folder=FOLDER     スクリプト収容先フォルダ
  -v, --version           Devilspie2のバージョン情報を表示して終了
```

インストールが完了すると、自動的に`~/.config/devilspie2`ディレクトリが作成されます。
このディレクトリは、devilspie2コマンドを実行した時に自動的に参照されるディレクトリで、この下に配置したスクリプトが実行されます。(`-f`オプションで任意の場所を指定できます)

## 表示位置(x,y)とサイズ(width,height)の取得

以下のスクリプトファイルを作成して`~/.config/devilspie2/`ディレクトリの下に配置します。

```lua:~/.config/devilspie2/get_name_and_xywh.lua
debug_print( "get_window_name:                      " .. get_window_name())
debug_print( "get_application_name:                 " .. get_application_name())
debug_print( "get_class_instance_name:              " .. get_class_instance_name())
window_x, window_y, window_w, window_h = xywh()
debug_print( "xywh:                                 " .. window_x .. "," .. window_y .."+" .. window_w .. "+" .. window_h )
debug_print( "\n" )
```

### コマンドの実行

まず、ウインドウサイズ・位置を設定したいアプリケーションを起動して、サイズと位置を調整します。
この後、コマンドを実行すると各ウインドウに対して上記のスクリプトが適用されます。

```
$ devilspie2 --debug
```
※`--debug`オプションは必須です。これがないと`debug_print`関数が有効にならず出力結果が得られません。

### 出力例

起動しているGUIアプリケーションのウインドウ情報が得られました。以下は`ターミナル`、`Visual Studio Code`、`Google Chrome`の出力例です。

```
get_window_name:                      devel@ubuntu: ~/.config/devilspie2
get_application_name:                 端末
get_class_instance_name:              gnome-terminal-server
xywh:                                 139,30+1158+1362

get_window_name:                      xxxxxxx - Visual Studio Code
get_application_name:                 xxxxxxx - Visual Studio Code
get_class_instance_name:              code
xywh:                                 1007,30+1342+1452


get_window_name:                      xxxxxx - Google Chrome
get_application_name:                 xxxxxx - Google Chrome
get_class_instance_name:              google-chrome
xywh:                                 1831,30+1866+1576

・・・省略・・・
```

## 設定ファイルの作成と配置

上述した情報を使ってスクリプトを作成します。
以下では2つの方法でアプリケーションを特定しています。

* `get_class_instance_name()`を利用。完全一致
* `get_window_name()をパターンマッチ`・・・複数の同一アプリが異なるウインドウで開いている場合。たとえばVSCODEのワークスペース

表示位置とサイズの指定には[`set_window_geometry2 (xpos, ypos, xsize, ysize)`](https://github.com/gusnan/devilspie2/blob/master/README#L251)を利用します。

```lua:~/.config/devilspie2/adjust_window_xywh.lua

if (get_class_instance_name()=="Scala IDE") then
  set_window_geometry2 (335, 628, 3113, 1404)
end

-- ウインドウ名に"create_env"を含む
if (string.find(get_window_name(), "create_env") ~= nil) then
  set_window_geometry2 (3849, 50, 2531, 1297)
end

if (get_class_instance_name()=="code") then
  set_window_geometry2 (1007, 33, 1342, 1422)
end

if (get_class_instance_name()=="google-chrome") then
  set_window_geometry2 (1831, 32, 1866, 1546)
end

if (get_class_instance_name()=="gnome-terminal-server") then
  set_window_geometry2 (59, 40, 1238, 662)
end

if (get_class_instance_name()=="DBeaver") then
  set_window_geometry2 (82, 786, 2721, 1240)
end

```
上記以外にも情報取得関数(例.`get_workspace_count()`や`get_screen_geometry()`)が用意されているので、その結果を使って処理を分岐したり、設定値を変更させることも可能です。


## 実行

各アプリケーションを起動します。`devilspie2`コマンドを実行するとウインドウのサイズ・位置が設定されます。

```
$ devilspie2 
```