進捗
- 移動とリサイズができるようになった
- リサイズは4方向に行える
- ただし、サイズヒントのことを何も考えていない
- サイズ0までウィンドウを小さくできる(そしてクラッシュする)
ButtonReleaseのタイミングでリサイズを行うのでぎこちない
MotionNotifyの度にリサイズするのが一般的だが、圧縮していない状態でそうすると重すぎる
- evilwmみたいに枠だけドラッグする方法の実装を検討
- マウス周りの実装が終わったら、次はキーバインド
- どうやって適切なハンドラにディスパッチするかが問題
- 基本的には関数ポインタ祭
- XCBだと色々と面倒
Keycode <-> Keysymの変換もXKBを使わないといけなさそうな感じ
XKeysymToString/XStringToKeysymがXCBには移植されていないらしい
- 文字列をキーシンボルに変換できない = 設定ファイル等でキーバインドを書いても変換できない
- 対策1: これのためだけにXlibを使う(XCBからfdを取ってくればXlibも使える)
- 対策2: 自前で適当にやる(全部は面倒なのでサブセットになる)
- 対策3: あきらめる(キーバインドはソースにベタ書き)
- 最初はベタ書きが楽、ただし後で置き換えられるように作る
- どうやって適切なハンドラにディスパッチするかが問題
枠だけドラッグ
ウィンドウを移動、あるいはリサイズする時に、毎回ウィンドウそのものを移動/リサイズしていると毎回ウィンドウの再描画が必要になって重い。確定するまでウィンドウ枠だけ描画すると大分マシになる。twmとかevilwmはこれを実装している。
実現方法
- 準備: 描画用のグラフィクスコンテキストを以下のように作成する
- functionにinvertを指定。これで2回同じものを描画すると消えるようになる
subwindow modeにIncludeInferiorsを指定。トップレベルウィンドウの上に描画可能になる
- ドラッグ開始時: サーバとマウスポインタをグラブする
- サーバをグラブすると、自分以外のクライアントからのリクエストと切断要求が処理されなくなる
- 他のウィンドウが何かすると色々と崩壊するのでこうする
- ドラッグ中: マウスポインタの移動に合わせて、ルートウィンドウ上に枠を描画する
- まず、以前に描いた枠をもう一度描画して消す
- 新しい枠を描画する
- ドラッグ終了: 枠を消してサーバのグラブを解除する。ウィンドウを実際に移動あるいはリサイズする
この方法でいいはず…なのだが、XCBで書いてみたところ、サーバをグラブしたことによって自分に対してもMotionNotifyが届かなくなってしまった(グラブを解除した途端にどさっとまとめてやって来る)。これでは全く意味がない。どうしてこうなった……
ついでに、この方法の根本的な問題: サーバのグラブが不可避
- サーバのグラブについては「絶対に必要でない限りやるな」とマニュアルには書いてある
- もし解除を忘れると非常に残念なことになる
- 他のクライアントのリクエスト処理が全く行われなくなる
- 動画再生とかも止まってしまう