サイズ: 4284
コメント:
|
← 2013-03-06 02:14:34時点のリビジョン3 ⇥
サイズ: 6923
コメント: 読みなおした
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 15: | 行 15: |
* 2013/02/01追記: reparentを行う場合はこれを正しく設定しないとxkillにWMを殺される悲劇が発生する。reparentによってWMの作成したフレームウィンドウがトップレベルウィンドウとなるが、reparent対象のウィンドウにWM_STATEを設定しないとフレームウィンドウを対象にKillClientリクエストが発行されてWMが死ぬ | |
行 17: | 行 18: |
* ウィンドウが表示されていれば`NormalState` * (twmのタイトルバー左のボタンを押したときみたいに)アイコン化されていれば`IconicState` * ウィンドウ本体もアイコンも不可視であれば`WithdrawnState` |
* クライアントのトップレベルウィンドウが表示されていれば`NormalState` * トップレベルウィンドウがアイコン化されていれば`IconicState` * 想定しているのはトップレベルウィンドウの代わりにアイコンウィンドウが表示されている状況らしい<<FootNote(twmのタイトルバー左にあるボタンを押した時のアレ)>>が、これが実際の所どういう意味であるかはWMによる。単に「最小化」として扱っているWMもある<<FootNote(というかその方が多い気がする)>> * 非表示だがウィンドウが存在していることは分かるような状態<<FootNote(twmのアイコンウィンドウとか、よくあるAlt-Tabリストのような手段で)>>、と捉えるのが良さそう? * トップレベルウィンドウが非表示で、`IconicState`でもない場合は`WithdrawnState` * クライアントが、必要なくなったウィンドウを後で使うために破棄せず非表示で残しておくような場合を想定しているらしい * 非表示かつウィンドウの存在がユーザからは分からない状態、と捉えるのが良さそう? 作成されたばかりのトップレベルウィンドウは`WithdrawnState`にある。クライアントがトップレベルウィンドウを表示すると、WMはウィンドウの状態を`Normal`か`Iconic`のどちらかに設定する。その後、クライアントは自由に状態を変更できる。また、`WithdrawnState`への移行は'''クライアントのみ'''が行なって良いことになっている。 さらに、ICCCMでは`NormalState`にあるクライアントが`IconicState`への移行をWMに要求するためのプロトコルが定められていて<<FootNote(逆を行いたい時は単にウィンドウを表示(map)すれば良い。ただし、表示の逆(unmap)を行うと`WithdrawnState`への移行となる)>>、要求を行うクライアントはルートウィンドウに対してタイプ`WM_CHANGE_STATE`の`ClientMessage`イベントを送りつけることになっている。WMはこれを受け取って移行処理を行う。 |
行 22: | 行 30: |
* `_NET_WM_STATE`の各状態は`NormalState`や`IconicState`に付随するもの(substate)として扱う | |
行 42: | 行 51: |
`InputHint`がそもそも設定されていない場合は「受動的に得る」タイプとみなす。 |
|
行 44: | 行 55: |
* See also: [[clear/wm_devel/2013-02-10]] |
最低限のWM-クライアント間通信
クライアント間通信についてはICCCMやEWMHで規定されているが、全て実装していると日が暮れるどころか年が明けても全然終わらない(そもそもWMの備える機能によっては実装する意味がないものもある)。
しかし、ICCCMで規定されているものには「最低限これはないと不味い」というものがあるので記録しておく。
WM_DELETE_WINDOW
WMからウィンドウを閉じること(タイトルバーとボタンを備えたWMなら、「閉じる」ボタンが押された場合)を考える。単純な方法としてXKillClientが存在するが、これは問答無用で対象のウィンドウを持っているクライアントを殺してしまうため以下の問題がある。
- クライアントの終了処理が行われない(即死する)
- クライアントが複数のトップレベルウィンドウを持っており、そのうちの1つを閉じる場合でもクライアント自体を殺してしまう
WM_DELETE_WINDOW(正確にはこれを含むClientMessageイベント)をクライアントに送ることで、クライアントに終了を要求することができる。ただし全てのクライアントがこれを扱えるとは限らないので、対象ウィンドウのWM_PROTOCOLSプロパティを確認する必要がある。WM_DELETE_WINDOWを受け付けないクライアントに対しては単にXKillClientを実行してよい。
WM_STATE
ウィンドウの状態を表すプロパティ。各トップレベルウィンドウに対してWMが設定する。ユーザにウィンドウをクリックすることでウィンドウを指定させるプログラム(例えばxpropとかxkill)はこのプロパティを使ってウィンドウを検索するらしい。このプロパティを設定しないとxkillが-fを付けないと動かないことを確認したので、多分設定しておいた方が良い。
2013/02/01追記: reparentを行う場合はこれを正しく設定しないとxkillにWMを殺される悲劇が発生する。reparentによってWMの作成したフレームウィンドウがトップレベルウィンドウとなるが、reparent対象のウィンドウにWM_STATEを設定しないとフレームウィンドウを対象にKillClientリクエストが発行されてWMが死ぬ
値としては、
クライアントのトップレベルウィンドウが表示されていればNormalState
トップレベルウィンドウがアイコン化されていればIconicState
トップレベルウィンドウが非表示で、IconicStateでもない場合はWithdrawnState
- クライアントが、必要なくなったウィンドウを後で使うために破棄せず非表示で残しておくような場合を想定しているらしい
- 非表示かつウィンドウの存在がユーザからは分からない状態、と捉えるのが良さそう?
作成されたばかりのトップレベルウィンドウはWithdrawnStateにある。クライアントがトップレベルウィンドウを表示すると、WMはウィンドウの状態をNormalかIconicのどちらかに設定する。その後、クライアントは自由に状態を変更できる。また、WithdrawnStateへの移行はクライアントのみが行なって良いことになっている。
さらに、ICCCMではNormalStateにあるクライアントがIconicStateへの移行をWMに要求するためのプロトコルが定められていて4、要求を行うクライアントはルートウィンドウに対してタイプWM_CHANGE_STATEのClientMessageイベントを送りつけることになっている。WMはこれを受け取って移行処理を行う。
EWMHでは_NET_WM_STATEが定義されていて、最大化や最小化、フルスクリーン(最大化とは意味が違う)などの状態が表せるようになっている。
_NET_WM_STATEの各状態はNormalStateやIconicStateに付随するもの(substate)として扱う
WM_HINTS
アプリケーションがWMのために設定するプロパティ。いくつかの値が含まれる。
最低でもInputHintは見るべき。この値はウィンドウが入力フォーカスをどう扱うか(受動的に得る、能動的に得る、そもそも必要としない)を示していて、Falseになっているウィンドウは入力フォーカスを得ることを意図していない。代表例はxloadとかxclockのような、そもそも入力を受ける余地がないものだが、より深刻な例としてはJEDのVineに入っているWnnの変換候補ウィンドウがこれに当てはまり、eclipse + Wnn有効の状況で変換候補ウィンドウにフォーカスを持っていかれてまともに入力できなくなる現象を確認した。
取得自体は簡単なので、余裕があれば他にStateHintとかWindowGroupHint、UrgencyHintあたりを見ると良さそう。
InputHintがそもそも設定されていない場合は「受動的に得る」タイプとみなす。
WM_NORMAL_HINTS
各ウィンドウのサイズに関する指示を示すプロパティ。クライアントが設定する。このプロパティにはクライアント側が希望するウィンドウの最小サイズ、最大サイズ、アスペクト比の範囲などの情報が含まれる。無視することもできるが「最小サイズ = 最大サイズ」となっているウィンドウは固定サイズで表示されることを期待しているので、最低限これだけは見ておいた方が良い。
See also: clear/wm_devel/2013-02-10