7

ウィンドウまたはフルスクリーンのウィンドウに描画するアプリケーションを作成したいのですが、マウスをつかんで、Alt + TabなどのWMキーボードショートカット傍受することはありません。また、ユーザーが出入りするたびに通知を受ける必要があります。集中。

Google Chrome、Firefox、gnome-terminalなどの一般的なアプリケーションは、これを問題なく処理できます(F11でフルスクリーンになりますが、Alt + Tabは引き続き使用できます)が、マウスをつかむことはありません。

SDLは、このユースケースの扱いが悪いことで有名です。SDL_WM_GrabInputはマウスを取得しますが、WMショートカットもインターセプトします。SDL_FULLSCREENは、それ自体で何らかの自動グラブを備えているようです(理由は聞かないでください)。

解決策は自分でAlt+Tabのコードを書くことかもしれませんが、これはうまくいきません(そして、別のワークスペースに変更するなど、他のWMショートカットには役立ちません)。

もう1つの解決策は、SDL_WM_GrabInputを呼び出さずに、グラブを偽造することです。マウスポインターを(SDL_ShowCursorを使用して)非表示にし、ユーザーが移動するたびに中央に戻します。これは醜いですが、実際には機能します。もちろん、SDL_FULLSCREENは自動的に取得されるため、SDL_FULLSCREENは除きます(正常な実装とは異なります)。フルスクリーン対応のSDLソリューションはこれですが、それでも私が望んでいることではありません。グラブを有効または無効にするためのハックは必要ありません。マウスをグラブしたいのですが、キーボードをグラブしたくありません。

だから私はSDLに夢中になっていて、代替案を見たいと思っています。SDLを使いたいのですが、必須ではありません。

この質問は、SDLが実際に行うことはXGrabKeyboardを使用することであることを指摘しているようです。マニュアルページを読んでも、キーボードをつかまなくてもマウスをつかむことができるかどうかはすぐにはわかりません(私はXlibを自分で使用したことはありません)。

GTK(つまり、Alt + Tabに対応した、gnome-terminalの種類)を使用して「偽のフルスクリーン」を作成する方法を知っています。これを行うことと、マウスを非表示にして中央に戻すこと(「偽のグラブ」)を組み合わせることでうまくいくと思いますが、これはダクトテープが多すぎるように感じます。もっと簡単な方法があるはずです。(また、依存関係としてGTKを追加したくありませんが、生のXlib呼び出しを行うことが良い考えかどうかもわかりません)。

これに対する良い解決策は何ですか?

Linux / X11ソリューションが必要ですが、クロスプラットフォームであると便利です。これはWindowsでスムーズに解決できることを知っているので、これを正確に実行するライブラリがあるかもしれません。(また、私はOpenGLでレンダリングしますが、これは関係ありません)

PS:おそらく私はこの問題についてよく理解しておらず、正しい質問をしていないので、私が検討していないアプローチを自由に指摘してください。

4

1 に答える 1

5

私は最近、Linux でのゲームに Gtk と GtkGLExt を使用しています (例: 私の Ludum Dare エントリ)。ここ ( gtk.c Gist ) は私のコードで、FreeBSD ライセンスの下でリリースしています。ウィンドウの状態の変更をデバッグするためにコメントアウトしたコードを見ることができます。これは、私がLudum Dareのようなものに使用するはるかに大きなフレームワークの一部であることを言及する必要があります。あなたが言及したのと同じ理由で、SDLよりも正確にそれを好みます。結果として得られるアプリケーションは、プラットフォーム (Linux、OS X、Windows)。言うまでもなく、この道を行くのは大変な作業です。

ただし、生の X11 プログラミングは本当に厄介です。Gtk コードを X11 コードに変換するには、しっかりとしたプログラミングとドキュメントの読み取りに 2 週間かかると見積もっています。それは私にとって価値がないだけですが、あなたは別の方法で決定するかもしれません. (とにかく誰もがインストールした依存関係を排除するだけで何時間もかかります!) Gtk の依存関係は実際にはそれほどとんでもないものではありません.とにかく、おそらく既にメモリに読み込まれています.2.x の ABI は非常に安定しているため、バイナリ互換性が損なわれることはありません. .

ゲーム用の X11 プログラミングの大きな問題は、イベント処理が完全に混乱していることです。イベントを簡単にポーリングすることはできません。Xlib インターフェイスはブロックしているため、関数呼び出しの難解なシーケンスを使用してデータを読み取り、保留中のイベントがあることを確認し、存在する場合にのみキューからイベントを読み取る必要があります (そうしないと、イベントが表示されるまでアプリケーションがブロックされます)。xcb ライブラリは Xlib の代替であり、Xlib は全体的に優れており、ノンブロッキング インターフェイスをサポートしていますが、OpenGL ではうまく機能しません。したがって、2 つを混在させることも、Gtk を使用することもできます。

フルスクリーン用の Gtk コードのスニペットを示します。

static void toggle_fullscreen()
{
    if (sg_gtk_status & SG_STATUS_VISIBLE) {
        if (sg_gtk_status & SG_STATUS_FULLSCREEN)
            gtk_window_unfullscreen(sg_window);
        else
            gtk_window_fullscreen(sg_window);
    }
}

X11 インターフェースでこれがどれだけの作業になるか想像してみてください: 画面のサイズを計算し (複数あるかもしれません!)、ウィンドウのサイズを変更し、他のすべての上に表示されるように順序を変更し、装飾を変更し、ユーザーが仮想デスクトップを切り替えたときにインテリジェントに応答します。何とか!(実際、これは私のコードが OS X でどのように機能するかを説明していますが、API の方がはるかに優れています。)

それ以上に、X11 を使用している場合は、期待どおりにユーザーに反応する方法を学ばなければなりません。X11は1980年代のものです。比較すると、Gtk は、Gtk の UI デザイナーからの適切なデフォルトの範囲をアプリケーションに提供します。UIデザインが仕事です。覚えておいてください: X11 と Gtk をうまく混在させることができます。

要約: X11 プログラミングは、時間に余裕のあるプログラマ向けです。

注: GtkGLExt は迷惑なリンカ フラグを追加します-Wl,--export-dynamicpkg-config私のビルド スクリプトは、の出力からフラグを削除します。

X11 の経験: X11ですべてを機能させるために約 1 週間を費やしたと思いますが、その過程で多くの行き詰まりをたどることになりました。私の失敗から学びましょう。

于 2013-02-13T04:57:14.990 に答える