本サイトでは、アフィリエイト広告およびGoogleアドセンスを利用しています。

マウスによるウィンドウのリサイズや移動処理を実装 (wayland)

前回のモデル描画を実装してみたところで中身が入った感じなので、ウィンドウとしてリサイズができるように処理を追加していきたいと思います。
実はこのウィンドウサイズのリサイズの処理のためにも、 EGL を使った描画実装に変更したのです。

まずは動作状況をお見せします。以下のような感じで動作するようになりました。

wayland-resize-window

ウィンドウリサイズ実装のポイント

なかなかウィンドウのリサイズについて情報がなく、試行錯誤しました。自分なりにうまくいった方法をここでは説明します。
shell オブジェクトの shell_surface_handler_configure ハンドラ関数と、 wl_egl_window_resize 関数がウィンドウリサイズの本体になるようです。
これらが呼び出されるためには、 wl_shell_surface_resize 関数が呼びされることが必要になります。

wl_shell_surface_resize を呼び出す際に、マウスの位置がウィンドウリサイズのためのどの位置にあたるのかを 自分で判定して、 wl_shell_surface_resize を呼び出します。
その判定以外だったらウィンドウの移動という感じにするべく、以下のような実装としました。これをマウスボタンが押された判定を行う箇所で実装しています。

int resize_type = cursorHitTest();
if( resize_type != WL_SHELL_SURFACE_RESIZE_NONE ) {
  wl_shell_surface_resize( mShellSurface, mSeat, serial, resize_type );
} else {
  wl_shell_surface_move( mShellSurface, mSeat, serial );
}

ここで wl_shell_surface_resize 関数に自分で場所判定して resize_type として WL_SHELL_SURFACE_RESIZE_TOP などの値を渡すと、マウスカーソルの形状を変化させることができました。
この状態で shell_surface_handler_configure コールバックが呼び出されるのでウィンドウのサイズを変更します.

surface_handler_configure( uint32_t edges, int width, int height ) {
  wl_egl_window_resize( mEglWindow, width, height, 0, 0);

Wayland ではウィンドウの位置は指定できませんが、この関数の第4,5引数で移動量を指定することはできるようです。

その他

上記の説明した内容を組み込んでみたところ以下のようにうまく動作しています。

ウィンドウのタイトルや枠などはまだありませんが、マウス操作でウィンドウの位置を移動できたり、端でサイズ変更ができるようになりました。
当初よりはずいぶんと通常のアプリケーションに近づけたと思います。

ウィンドウの外側から領域内にカーソルが入るときのための処理も今回追加しました。この過程で従来はマウス位置が飛ぶようなことがあったのですが修正されたように思います。このときもどの領域なのか判定を行い、マウスカーソルのセットをしています。

今回の内容についても、GitHub のほうに反映させてあります。 ソースコードに興味のある方はそちらをご確認ください。

追記

Ubuntu 17.04 の環境で本ソースコードで試したところ、移動は出来てもウィンドウサイズのリサイズが効かない状態でした。
これについては時間みつけて調査&修正したいと思います。

プログラミング
すらりんをフォローする
すらりん日記

コメント

タイトルとURLをコピーしました