状況に応じたメニューは常に機能していませんか?

状況に応じたメニューは常に機能していませんか?

私はアーチLinuxとデフォルトのcppカスタムウィンドウマネージャを使用しています。ところで、右クリックしてコンテキストメニューを開くたびに点滅して消えます。まったく使えません。また、どのアプリでもトップドロップダウンメニュー(ファイル、編集、情報など)を使用できません。コンテキストメニューを正しく使用するためにXlibに注意する必要がありますか?

これは私が使ったすべてのアプリの場合です。唯一の手がかりは、Braveが時々次のメッセージを表示することです。

XGetWindowAttributes failed for window [WINDOW_ID]

エラーを検索すると、一部のChrome関連の結果が表示されますが、通常Linuxでは何も表示されません。この問題を解決またはデバッグする方法についての手がかりを提供していただきありがとうございます!

次の簡単な例は、この問題を示しています。

int main()
{
    display = XOpenDisplay(nullptr);
    root = DefaultRootWindow(display);
    XSelectInput(display, root, SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask);
 
    XGrabServer(display);
    Window returned_root;
    Window returned_parent;
    Window* top_level_windows;
    unsigned int num_top_level_windows;
    XQueryTree(display, root, &returned_root, &returned_parent, &top_level_windows, &num_top_level_windows);
 
    for(unsigned int i = 0; i < num_top_level_windows; ++i)
    {
        Frame(top_level_windows[i], true);
    }
 
    XFree(top_level_windows);
    XUngrabServer(display);
 
    for(;;)
    {
        XEvent event;
        XNextEvent(display, &event);
 
        switch (event.type)
        {
        case MapRequest:
        {
            Frame(event.xmaprequest.window, false);
            XMapWindow(display, event.xmaprequest.window);
            break;
        }
        case ConfigureRequest:
            OnConfigureRequest(event.xconfigurerequest);
            break;
        case ButtonPress:
            XRaiseWindow(display, event.xbutton.window);
            break;
        }
    }
 
    return true;
}
 
void OnConfigureRequest(const XConfigureRequestEvent& event)
{
    XWindowChanges changes;
    changes.x = event.x;
    changes.y = event.y;
    changes.width = event.width;
    changes.height = event.height;
    changes.border_width = event.border_width;
    changes.sibling = event.above;
    changes.stack_mode = event.detail;
 
    if(frame_list.count(event.window))
    {
        const Window frame = event.window;
        XConfigureWindow(display, frame, event.value_mask, &changes);
    }
 
    //Grant request
    XConfigureWindow(display, event.window, event.value_mask, &changes);
}
 
void Frame(Window window, bool created_before_manager)
{
    //Retrieve attributes of window to frame
    XWindowAttributes attr = {0};
    XGetWindowAttributes(display, window, &attr);
 
    //If window was created before window manager started, we should frame it only if it is visible and does not set override_redirect
    if(created_before_manager && (attr.override_redirect || attr.map_state != IsViewable))
    {
        return;
    }
 
    //Create frame
    Window frame = XCreateSimpleWindow(display, root, attr.x, attr.y, attr.width, attr.height, 5, 0xff0000, 0xffffff);
    XReparentWindow(display, window, frame, 0, 0);
    XMapWindow(display, frame);
 
    XGrabButton(display, Button1Mask, Mod1Mask, window, None, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
}

問題は、次の非常に簡単な例でも見つかりました。

int main()
{
    Display* display = XOpenDisplay(nullptr);
    for(;;) {}
    return true;
}

私がビューにウィンドウマネージャに問題があると思うのは、この問題はウィンドウマネージャを実行した後にのみ発生するためです。

答え1

答えは以下から来ています。この質問のスタックオーバーフローバージョン:

クライアントウィンドウに入力があることを確認する必要があります。クリックした項目(フレーム、タイトルバー、またはクライアント)の入力を設定しました。通常の入力に関する限り正常に動作するためです。ただし、コンテキストメニューは、入力がクライアントウィンドウに直接設定されていることを確認した場合にのみ機能します。

関連情報