0

compiz ウィンドウマネージャー用のプラグインを開発しています。変換されたウィンドウ テクスチャを描画し、そのウィンドウにイベントを送信したいと考えています。変換されたウィンドウがレンダラーの場合、ポインターを取得してすべての xevents を制御します。ポインターを取得する compiz 関数の主要部分は次のようになります。

 status = XGrabPointer (privateScreen.dpy, privateScreen.eventManager.getGrabWindow(), true,
                        POINTER_GRAB_MASK,
                        GrabModeAsync, GrabModeAsync,
                        privateScreen.rootWindow(), cursor,
                        CurrentTime);

ポインターがグラブされると、ボタンを押す座標を再計算し、 XSendEventを使用して宛先ウィンドウにイベントを送信します。これは、Google Chrome ウィンドウまたは次のような単純な xwindow アプリケーションでは問題なく動作します。残念ながら、OpenGL レンダリングを実行するウィンドウでは正しく動作しません。SDL と GLFW をテストしました。このようなウィンドウはクリック イベントを受け取りますが、パラメーター (xbutton.x_root、xbutton.y_root、xbutton.x、xbutton.y) は XSendEvent で指定したものとは異なります。イベントを送信するたびに、これらのパラメーターには、xgrabpointer が呼び出される前のマウス位置と思われる同じ値が含まれます。ポインターがグラブされていない場合、(XSendEvent からの) イベントは正しく受信されます。xsendevent、xgrabpointer、および OpenGL レンダリングを実行するウィンドウの間には、特定の関係が必要です。さらに、クライアント (ウィンドウ) の実装が異なる場合があります。これは、コードがその特定のウィンドウでのみ機能しないか、何か間違っている可能性があります。

編集1

次の例を考えてみましょう: フルスクリーン ウィンドウがあり、プラグインを使用して変換されたウィンドウ テクスチャ (たとえば、スケール変換 (0.5、0.5、1.0)) を描画できますが、X11 にはまだフルスクリーン ウィンドウが表示されるため、変換されたテクスチャ イベントの外側の領域はウィンドウに移動します。プラグインでポインターを取得すると、すべてのイベントの受信者は私だけになり、ウィンドウの変換に基づいて座標を再計算し、ウィンドウに送信できます。

Edit2 Freeglut を使用すると、ポインターがグラブされると、すべてのイベントが目的のウィンドウに正しく送信されます。ライブラリの実装にはいくつかの違いが必要です。

4

2 に答える 2

1

OpenGL は入力イベントには関係なく、X11 やポインター イベントが何であるかさえ知らずに描画するだけです。

これは、SDL と GLFW の両方がウィンドウのセットアップで行う必要があります。

しかし、なぜポインタをつかんでいるのだろうか?Compiz およびその他の合成 WM が構築される基盤である X Composite 拡張機能には、ポインター入力変換用の専用 API が既にあります。 .txt RedirectCoordinateTransformCoordinate. ポインターをつかむのをいじる代わりに、これらの関数を使用する必要があります。ポインターをつかむことは、本当に、本当に悪い考えです。

さて、私がリンクした (そして私のコンピューターにある) X 複合拡張機能のコピーは、まだ RedirectCoordinate が含まれている初期のドラフトのようです。座標のリダイレクトが削除された新しいバージョン (残念ながら、頭に同じ日付が含まれています – WTF?) があります。

于 2014-12-19T09:04:05.167 に答える
0

SDL は、MouseMotion イベントを処理するときにマウスの位置を更新します。ButtonPress イベントに格納されている座標は使用しません。ウィンドウ マネージャーがポインターを取得し、ButtonPress イベントを SDL ウィンドウに送信すると、レシーバー内のマウスの位置が更新されません。解決策の例を次に示します (次のコードは、SDL_x11events.c の ButtonPress ラベルの後のセクションに追加する必要があります。

if(xevent.xany.send_event)
{
     SDL_Mouse *mouse = SDL_GetMouse();
     mouse->x = xevent.xbutton.x;
     mouse->y = xevent.xbutton.y;
}
于 2015-01-13T07:18:36.043 に答える