diff -r 4ce8df2311f0 -r 6ca1ef6c8107 ui/motif/window.c --- a/ui/motif/window.c Sun Nov 23 10:39:51 2025 +0100 +++ b/ui/motif/window.c Sun Nov 23 10:49:24 2025 +0100 @@ -87,6 +87,13 @@ ui_get_window_default_width(&window_width, &window_height); } + UiMotifAppWindow *appwindow = cxZalloc(a, sizeof(UiMotifAppWindow)); + // Because we store appwindow as userdata in the widget, we use this + // magic field to check, if the pointer is actually the correct type. + // This is a dubious technique, but this is only the last defense + // mechanism against someone using the API wrong. + appwindow->magic = UI_MOTIF_APP_WINDOW; + Arg args[16]; int n = 0; XtSetArg(args[n], XmNtitle, title); n++; @@ -94,6 +101,7 @@ XtSetArg(args[n], XmNminHeight, 50); n++; XtSetArg(args[n], XmNwidth, window_width); n++; XtSetArg(args[n], XmNheight, window_height); n++; + XtSetArg(args[n], XmNuserData, appwindow); n++; Widget toplevel = XtAppCreateShell( ui_appname(), @@ -123,7 +131,7 @@ // menu if(!simple) { - ui_create_menubar(obj, window); + appwindow->menubar = ui_create_menubar(obj, window); } // content frame @@ -166,7 +174,17 @@ } void ui_window_menubar_set_visible(UiObject *obj, UiBool visible) { - + UiMotifAppWindow *window = NULL; + XtVaGetValues(obj->widget, XmNuserData, &window, NULL); + if(window) { + if(window->magic != UI_MOTIF_APP_WINDOW) { + fprintf(stderr, "Error: obj is not an app window\n"); + return; + } + if(window->menubar) { + ui_set_visible(window->menubar, visible); + } + } } static void filedialog_event(UiEventData *event, int result, UiFileList flist) {