2

押されたキーを取得してキーボード入力をブロックするコードを書いています。例: Super_L または Super_R キーが押された場合、それらがアプリケーション メニューを開けないようにします。コードはプログラムが開いている間は機能しますが、プログラムが閉じられるとキーがシステムに送信されます。例: ユーザーが Super_L キーを押しても、プログラムの実行中には何も起こりませんが、プログラムを閉じると、Ubuntu アプリケーション メニューが自動的に開きます。この問題を解決するにはどうすればよいですか?

void hook()
{
    Display *dpy = XOpenDisplay(0);
    XEvent ev;

    if(!dpy)
    {
        qDebug() << "Error";
        return;
    }

    XGrabKeyboard(dpy, DefaultRootWindow(dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime);

    forever
    {
        XNextEvent(dpy, &ev);
        switch (ev.type)
        {
        case KeyPress:
            qDebug() << "KeyPress" << XKeysymToString(XKeycodeToKeysym(dpy, ev.xkey.keycode, 0));
            break;
        case KeyRelease:
            qDebug() << "KeyRelease" << XKeysymToString(XKeycodeToKeysym(dpy, ev.xkey.keycode, 0));
            break;
        }
    }
}
4

2 に答える 2

1

からman XGetKeyboard:

アクティブなキーボード グラブのイベント ウィンドウが表示できなくなると、X サーバーは UngrabKeyboard 要求を自動的に実行します。

それは設計によるものです。そうしないと、機能していないアプリケーションによってキーボードが無期限にグラブされたままになる可能性があり、ユーザーはそれを認識しません。確かに、ウィンドウはまだ表示可能です (ルート ウィンドウです) が、ディスプレイ接続は閉じられているため、理論的根拠は同じです。

アプリケーションを閉じた後もグラブを維持する必要がある場合は、実際に終了せずにバックグラウンドにとどまる必要があります。

于 2013-02-03T18:53:44.513 に答える
1

マニュアルを引用:

クライアントへの X サーバーの接続が明示的な呼び出しXCloseDisplay()またはプロセスの終了によって閉じられると、X サーバーは次の自動操作を実行します。

  • クライアントが所有するすべてのセレクションを否認します ( を参照 XSetSelectionOwner())。
  • クライアントがアクティブにポインタまたはキーボードをつかんだ場合、 XUngrabPointer()andを実行します。XUngrabKeyboard()
  • XUngrabServer()クライアントがサーバーを取得した場合に実行します。
  • クライアントによって作成されたすべてのパッシブ グラブを解放します。

グラブはクライアントによって要求され、クライアントに付与されます。グラブの間、関連するすべてのイベントがグラブしているクライアントに配信されます。クライアントなし、グラブなし。

ここで何を修正すべきかわかりません。機能の一部を機能させたい場合は、それを実装するアプリケーションが実行されていることを確認してください。

于 2013-02-03T19:30:41.400 に答える