ゆとりーなの日記

日記的な事を書いて行くと思はれる

gtkmmでイベント駆動じゃないループ?

 gtkmmのメッセージループは所謂イベント駆動で、Win32APIで言う所のGetMessageを使った感じのようなものになってしまいます。これでは大抵の場合でゲームに向かないので、gtkmmでPeekMessageのようなループはないものかと探してみても案外見つかりません。Xlibにはそんな感じのループが書ける函数があるのですが、全てXで書くとなると、gtkmmだと一瞬で出せるメッセージダイアログやら画像読み込みユーティリティを破棄することになるので惜しいです。
 で、gdkにX特有の機能を使いたいときはgdkx.hを使うといいよという話を聞いたので見てみたところ、なんとgtk::WindowからDisplay *やらを取れそうなマクロ群があるわけですよ。早速これらを使ってgtkmmとxlibを組み合わせた感じのコードを書いてみたわけです。

#include <gtkmm.h>
#include <gdkx.h>
#include <X11/Xlib.h>

int main() {
  Gtk::Main kit(nullptr, nullptr);
  Gtk::Window window;
  window.show();
  const auto display = GDK_WINDOW_XDISPLAY(Glib::unwrap(window.get_window()));
  Atom atom1 = XInternAtom(display, "WM_PROTOCOLS", False);
  Atom atom2 = XInternAtom(display, "WM_DELETE_WINDOW", FALSE);
  XSetWMProtocols(display, GDK_WINDOW_XWINDOW(Glib::unwrap(window.get_window())), &atom2, 1);
  bool run = true;
  while (run) {
    XEvent event;
    while (XPending(display)) {
      XNextEvent(display, &event);
      if (event.type == ClientMessage) {
        if (event.xclient.message_type == atom1 && event.xclient.data.l[0] == atom2) {
          run = false;
        }
      }
    }
  }
  return 0;
}

 取り敢えずこれで目的のことは達成出来ているように見えます。マクロでXのインターフェイスを取り出してあとはXのメッセージループをベタ書きしただけです。特にエラーメッセージも出ませんでしたし、ちゃんとウィンドウの×ボタンを押したら終了、最大/小化ボタンで最大/小化もしました。只、Display *を取る前にwindowをshowメソッドで可視化していないと落ちるようです。また、結構フィーリングで書いているところがあるので例によって本当にこれで大丈夫なのかどうかは怪しいってのは当然のようにあるわけですので悪しからず。