サイズ: 1271
コメント:
|
サイズ: 7443
コメント:
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 1: | 行 1: |
サイズヒントについて | = サイズヒントについて = |
行 5: | 行 5: |
WMがサイズヒントを無視した場合考えられる弊害: | == WMがサイズヒントを無視した場合考えられる弊害 == |
行 12: | 行 12: |
サイズヒントに関連する資料: | == サイズヒントに関連する資料 == |
行 23: | 行 23: |
(後で追記する) | == WM_NORMAL_HINTS == ウィンドウのサイズヒントはWM_NORMAL_HINTSプロパティによって表される。その型はWM_SIZE_HINTSで、そのメンバは以下の通り: ||フィールド||型||対応するフラグ||意味||備考|| ||min_width||INT32||PMinSize||最小幅||存在しなければbase_width|| ||min_height||INT32||PMinSize||最小高さ||存在しなければbase_height|| ||max_width||INT32||PMaxSize||最大幅|||| ||max_height||INT32||PMaxSize||最大高さ|||| ||width_inc||INT32||PResizeInc||幅の増分|||| ||height_inc||INT32||PResizeInc||高さの増分|||| ||min_aspect||(INT32,INT32)||PAspect||最小アスペクト比||(1つめの値/2つめの値)で表される|| ||max_aspect||(INT32,INT32)||PAspect||最大アスペクト比||同上|| ||base_width||INT32||PBaseSize||基底幅||存在しなければmin_width|| ||base_height||INT32||PBaseSize||基底高さ||存在しなければmin_height|| ||win_gravity||INT32||PWinGravity||ウィンドウグラビティ||存在しなければNorthWest|| さらに、対応するメンバが存在しないフラグが存在する: ||フラグ||意味|| ||USPosition||ウィンドウの座標がユーザによって指定された|| ||USSize||上のサイズ版|| ||PPosition||ウィンドウの座標が(ユーザの操作なしに)プログラムによって指定された|| ||PSize||上のサイズ版|| * 座標とサイズはウィンドウ自体のもの * 昔はサイズヒントにメンバがあったが、今はウィンドウ自体の値を使うことになっている 各フィールドについて * サイズを指定するフィールドにはウィンドウ枠の分は含まれない * min_width=max_widthかつmin_height=max_heightの場合、ウィンドウが固定サイズであることを示す(EWMH Implementation NoteのFixed size Windowsの項) * base_widthとbase_height、width_incとheight_incの組み合わせでウィンドウのリサイズ単位を示す * width = base_width + (i * width_inc) * height = base_height + (i * height_inc) * i,jは非負整数。要するに、「baseを最小としてinc単位でリサイズする」 * 典型的な例は端末エミュレータ(文字単位でのリサイズを可能にする) * WMがユーザにウィンドウサイズを示す際は、実際の幅と高さではなくiとjを使う方が良い * アスペクト比のチェックを行う際、base_widthおよびbase_heightが設定されていればウィンドウサイズから引く * 設定されていなければ何も引かない(min_widthおよびmin_heightを代わりに使うことはしない) == gravity == WMのフレームウィンドウに対してクライアントウィンドウを配置する基準点を示す。ICCCMとEWMHの記述をまとめると'''たぶん'''以下のような感じ: 基準点(refx, refy)の計算に用いる表(EWMH Implementation Noteより) * クライアントウィンドウの要求する座標: (x,y) * クライアントウィンドウの要求するサイズ: (w,h) * クライアントウィンドウの要求する枠幅: bw ||gravity||rexf||refy||(refx,refy)に置かれる点||備考|| ||Static||x||y||クライアントウィンドウの左上角||クライアントウィンドウは不動|| ||NorthWest||x-bw||y-bw||フレームウィンドウの左上角||デフォルト|| ||North||x+(w/2)||y-bw||フレームウィンドウの上辺の中心|||| ||NorthEast||x+w+bw||y-bw||フレームウィンドウの右上角|||| ||East||x+w+bw||y+(h/2)||フレームウィンドウの右辺の中心|||| ||SouthEast||x+w+bw||y+h+bw||フレームウィンドウの右下角|||| ||South||x+(w/2)||y+h+bw||フレームウィンドウの底辺の中心|||| ||SouthWest||x-bw||y+h+bw||フレームウィンドウの左下角|||| ||West||x-bw||y+(h/2)||フレームウィンドウの左辺の中心|||| ||Center||x+(w/2)||y+(h/2)||フレームウィンドウの中心|||| * gravityを考慮して位置調整を行わなければならないタイミング * reparentするとき/reparentを解除するとき(MapRequest/UnmapNotifyを処理するとき) * ConfigureRequestを処理するとき * 要するに、クライアントが特定の座標を要求してきたとき * WMはウィンドウを移動(リサイズを含まない)したときクライアントに対して人工のConfigureNotifyイベントを送信する<<FootNote(WMがクライアントウィンドウをreparentした場合、フレームウィンドウを移動することでその子であるクライアントウィンドウも移動する。reparentによってクライアントウィンドウの座標はフレームウィンドウ内での座標となるので、これがフレームウィンドウの移動によって変化することはない=ConfigureNotifyは送られない。よって、クライアントにウィンドウの移動を通知するためにWMがConfigureNotifyを作って送る必要がある。また、リサイズの場合はフレームとともにクライアントのウィンドウもリサイズされるので真のConfigureNotifyが届く。そのためWMがConfigureNotifyを送信する必要はない)>>が、このときのクライアントウィンドウの座標はルートウィンドウに対するクライアントウィンドウの左上角の座標である(gravityは関係ない) * gravityは任意のタイミングで自由に変わりうる。それによってウィンドウが移動することはない(単に基準点が変わるだけ) * クライアントウィンドウが新たな座標を要求してきたら、WMは新たな基準点に従う * クライアントウィンドウがリサイズのみを要求した場合、ウィンドウの基準点が動かない<<FootNote(ルートウィンドウの座標系に対して)>>ようにしなければならない * 例えばgravityがSouthEastでサイズだけが大きくなった場合、リサイズしつつウィンドウ座標を左上に動かすことで基準点は不動に保たれる |
サイズヒントについて
Xにおいてウィンドウの配置は全てWMが取り仕切ることになっているが、クライアント側から配置方法について注文したい場合がある(例:固定サイズウィンドウ)。このようなときにサイズヒントが用いられる。
WMがサイズヒントを無視した場合考えられる弊害
- 固定サイズのはずのウィンドウがリサイズできてしまう
- UI崩壊
- アスペクト比がクライアントの意図しない値になる
- 動画再生用のウィンドウとかだと困る
- ウィンドウ位置が少しおかしくなる
サイズヒントに関連する資料
- ICCCM 4.1.2.3
- サイズヒントの実体であるWM_NORMAL_HINTSの説明
- EWMH Implementation NotesのWindow Geometryの項
- ICCCMがあまりにも分かりにくいので補足がなされた
- Xlib - C Language Interface 3.2.3 Gravity Attributes
- gravityの意味
EWMH Other Propertiesの_NET_WM_FULL_PLACEMENT
- WMがクライアントによる座標指定を制限することをクライアントに対して示す
- WMが十分な配置能力を備えていることを明示する効果がある
WM_NORMAL_HINTS
ウィンドウのサイズヒントはWM_NORMAL_HINTSプロパティによって表される。その型はWM_SIZE_HINTSで、そのメンバは以下の通り:
フィールド |
型 |
対応するフラグ |
意味 |
備考 |
min_width |
INT32 |
PMinSize |
最小幅 |
存在しなければbase_width |
min_height |
INT32 |
PMinSize |
最小高さ |
存在しなければbase_height |
max_width |
INT32 |
PMaxSize |
最大幅 |
|
max_height |
INT32 |
PMaxSize |
最大高さ |
|
width_inc |
INT32 |
PResizeInc |
幅の増分 |
|
height_inc |
INT32 |
PResizeInc |
高さの増分 |
|
min_aspect |
(INT32,INT32) |
PAspect |
最小アスペクト比 |
(1つめの値/2つめの値)で表される |
max_aspect |
(INT32,INT32) |
PAspect |
最大アスペクト比 |
同上 |
base_width |
INT32 |
PBaseSize |
基底幅 |
存在しなければmin_width |
base_height |
INT32 |
PBaseSize |
基底高さ |
存在しなければmin_height |
win_gravity |
INT32 |
PWinGravity |
ウィンドウグラビティ |
存在しなければNorthWest |
さらに、対応するメンバが存在しないフラグが存在する:
フラグ |
意味 |
USPosition |
ウィンドウの座標がユーザによって指定された |
USSize |
上のサイズ版 |
PPosition |
ウィンドウの座標が(ユーザの操作なしに)プログラムによって指定された |
PSize |
上のサイズ版 |
- 座標とサイズはウィンドウ自体のもの
- 昔はサイズヒントにメンバがあったが、今はウィンドウ自体の値を使うことになっている
各フィールドについて
- サイズを指定するフィールドにはウィンドウ枠の分は含まれない
- min_width=max_widthかつmin_height=max_heightの場合、ウィンドウが固定サイズであることを示す(EWMH Implementation NoteのFixed size Windowsの項)
- base_widthとbase_height、width_incとheight_incの組み合わせでウィンドウのリサイズ単位を示す
- width = base_width + (i * width_inc)
- height = base_height + (i * height_inc)
- i,jは非負整数。要するに、「baseを最小としてinc単位でリサイズする」
- 典型的な例は端末エミュレータ(文字単位でのリサイズを可能にする)
- WMがユーザにウィンドウサイズを示す際は、実際の幅と高さではなくiとjを使う方が良い
- アスペクト比のチェックを行う際、base_widthおよびbase_heightが設定されていればウィンドウサイズから引く
- 設定されていなければ何も引かない(min_widthおよびmin_heightを代わりに使うことはしない)
gravity
WMのフレームウィンドウに対してクライアントウィンドウを配置する基準点を示す。ICCCMとEWMHの記述をまとめるとたぶん以下のような感じ:
基準点(refx, refy)の計算に用いる表(EWMH Implementation Noteより)
- クライアントウィンドウの要求する座標: (x,y)
- クライアントウィンドウの要求するサイズ: (w,h)
- クライアントウィンドウの要求する枠幅: bw
gravity |
rexf |
refy |
(refx,refy)に置かれる点 |
備考 |
Static |
x |
y |
クライアントウィンドウの左上角 |
クライアントウィンドウは不動 |
x-bw |
y-bw |
フレームウィンドウの左上角 |
デフォルト |
|
North |
x+(w/2) |
y-bw |
フレームウィンドウの上辺の中心 |
|
x+w+bw |
y-bw |
フレームウィンドウの右上角 |
||
East |
x+w+bw |
y+(h/2) |
フレームウィンドウの右辺の中心 |
|
x+w+bw |
y+h+bw |
フレームウィンドウの右下角 |
||
South |
x+(w/2) |
y+h+bw |
フレームウィンドウの底辺の中心 |
|
x-bw |
y+h+bw |
フレームウィンドウの左下角 |
||
West |
x-bw |
y+(h/2) |
フレームウィンドウの左辺の中心 |
|
Center |
x+(w/2) |
y+(h/2) |
フレームウィンドウの中心 |
- gravityを考慮して位置調整を行わなければならないタイミング
reparentするとき/reparentを解除するとき(MapRequest/UnmapNotifyを処理するとき)
ConfigureRequestを処理するとき
- 要するに、クライアントが特定の座標を要求してきたとき
WMはウィンドウを移動(リサイズを含まない)したときクライアントに対して人工のConfigureNotifyイベントを送信する1が、このときのクライアントウィンドウの座標はルートウィンドウに対するクライアントウィンドウの左上角の座標である(gravityは関係ない)
- gravityは任意のタイミングで自由に変わりうる。それによってウィンドウが移動することはない(単に基準点が変わるだけ)
- クライアントウィンドウが新たな座標を要求してきたら、WMは新たな基準点に従う
クライアントウィンドウがリサイズのみを要求した場合、ウィンドウの基準点が動かない2ようにしなければならない
例えばgravityがSouthEastでサイズだけが大きくなった場合、リサイズしつつウィンドウ座標を左上に動かすことで基準点は不動に保たれる
WMがクライアントウィンドウをreparentした場合、フレームウィンドウを移動することでその子であるクライアントウィンドウも移動する。reparentによってクライアントウィンドウの座標はフレームウィンドウ内での座標となるので、これがフレームウィンドウの移動によって変化することはない=ConfigureNotifyは送られない。よって、クライアントにウィンドウの移動を通知するためにWMがConfigureNotifyを作って送る必要がある。また、リサイズの場合はフレームとともにクライアントのウィンドウもリサイズされるので真のConfigureNotifyが届く。そのためWMがConfigureNotifyを送信する必要はない (1)
ルートウィンドウの座標系に対して (2)