Login
Immutable PageDiscussionInfoAttachments
clear/wm_devel/2012-12-11

MMA

最低限のWM-クライアント間通信

クライアント間通信についてはICCCMやEWMHで規定されているが、全て実装していると日が暮れるどころか年が明けても全然終わらない(そもそもWMの備える機能によっては実装する意味がないものもある)。

しかし、ICCCMで規定されているものには「最低限これはないと不味い」というものがあるので記録しておく。

WM_DELETE_WINDOW

WMからウィンドウを閉じること(タイトルバーとボタンを備えたWMなら、「閉じる」ボタンが押された場合)を考える。単純な方法としてXKillClientが存在するが、これは問答無用で対象のウィンドウを持っているクライアントを殺してしまうため以下の問題がある。

  1. クライアントの終了処理が行われない(即死する)
  2. クライアントが複数のトップレベルウィンドウを持っており、そのうちの1つを閉じる場合でもクライアント自体を殺してしまう

WM_DELETE_WINDOW(正確にはこれを含むClientMessageイベント)をクライアントに送ることで、クライアントに終了を要求することができる。ただし全てのクライアントがこれを扱えるとは限らないので、対象ウィンドウのWM_PROTOCOLSプロパティを確認する必要がある。WM_DELETE_WINDOWを受け付けないクライアントに対しては単にXKillClientを実行してよい。

WM_STATE

ウィンドウの状態を表すプロパティ。各トップレベルウィンドウに対してWMが設定する。ユーザにウィンドウをクリックすることでウィンドウを指定させるプログラム(例えばxpropとかxkill)はこのプロパティを使ってウィンドウを検索するらしい。このプロパティを設定しないとxkill-fを付けないと動かないことを確認したので、多分設定しておいた方が良い。

値としては、

作成されたばかりのトップレベルウィンドウはWithdrawnStateにある。クライアントがトップレベルウィンドウを表示すると、WMはウィンドウの状態をNormalIconicのどちらかに設定する。その後、クライアントは自由に状態を変更できる。また、WithdrawnStateへの移行はクライアントのみが行なって良いことになっている。

さらに、ICCCMではNormalStateにあるクライアントがIconicStateへの移行をWMに要求するためのプロトコルが定められていて4、要求を行うクライアントはルートウィンドウに対してタイプWM_CHANGE_STATEClientMessageイベントを送りつけることになっている。WMはこれを受け取って移行処理を行う。

EWMHでは_NET_WM_STATEが定義されていて、最大化や最小化、フルスクリーン(最大化とは意味が違う)などの状態が表せるようになっている。

WM_HINTS

アプリケーションがWMのために設定するプロパティ。いくつかの値が含まれる。

最低でもInputHintは見るべき。この値はウィンドウが入力フォーカスをどう扱うか(受動的に得る、能動的に得る、そもそも必要としない)を示していて、Falseになっているウィンドウは入力フォーカスを得ることを意図していない。代表例はxloadとかxclockのような、そもそも入力を受ける余地がないものだが、より深刻な例としてはJEDのVineに入っているWnnの変換候補ウィンドウがこれに当てはまり、eclipse + Wnn有効の状況で変換候補ウィンドウにフォーカスを持っていかれてまともに入力できなくなる現象を確認した。

取得自体は簡単なので、余裕があれば他にStateHintとかWindowGroupHintUrgencyHintあたりを見ると良さそう。

   1 Display *dpy;
   2 Window w;
   3 XWMHints *wm;
   4 
   5 wm = XGetWMHints(dpy, w);
   6 if (wm) {
   7     /* wm->flagsを見て設定されている値を処理する */
   8     /* ... */
   9     XFree(wm);
  10 }

InputHintがそもそも設定されていない場合は「受動的に得る」タイプとみなす。

WM_NORMAL_HINTS

各ウィンドウのサイズに関する指示を示すプロパティ。クライアントが設定する。このプロパティにはクライアント側が希望するウィンドウの最小サイズ、最大サイズ、アスペクト比の範囲などの情報が含まれる。無視することもできるが「最小サイズ = 最大サイズ」となっているウィンドウは固定サイズで表示されることを期待しているので、最低限これだけは見ておいた方が良い。

  1. twmのタイトルバー左にあるボタンを押した時のアレ (1)

  2. というかその方が多い気がする (2)

  3. twmのアイコンウィンドウとか、よくあるAlt-Tabリストのような手段で (3)

  4. 逆を行いたい時は単にウィンドウを表示(map)すれば良い。ただし、表示の逆(unmap)を行うとWithdrawnStateへの移行となる (4)

clear/wm_devel/2012-12-11 (last edited 2013-03-06 02:14:34 by clear)