= サイズヒントについて = 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||クライアントウィンドウの左上角||クライアントウィンドウは不動|| ||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を正しく処理するただひとつの方法 * クライアントによる移動要求 * クライアントの要求座標をもとに新しい基準点を計算 * 基準点に従って配置 * クライアントによるリサイズ要求(移動を含まない) * 現在の座標とサイズを元に基準点を計算 * 基準点に従って新しいサイズで配置