From f6e181bc9456ee666cb8e135254bb7dc7180525d Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sun, 9 Nov 2025 11:31:02 +0000 Subject: [PATCH] fix the window placement bug git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@652 b9cfdab3-6d41-4d17-bbe4-086880011989 --- src/backend/x11.c | 79 +++++++++++++++++++++++++---------------- src/dialog/messagebox.c | 8 +++-- src/widget/submenu.c | 4 +-- 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/backend/x11.c b/src/backend/x11.c index b957b6c..a84d8d6 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -40,9 +40,20 @@ static void destroy_pixmap(MwLL handle) { XFreePixmap(handle->display, handle->pixmap); } -static void wait_map(MwLL handle) { - XEvent* queue = NULL; - XEvent ev; +static void wait_map(MwLL handle, int move_back, int nomap) { + XEvent* queue = NULL; + XEvent ev; + int x, y; + unsigned int w, h; + + MwLLGetXYWH(handle, &x, &y, &w, &h); + + if(move_back) MwLLSetXY(handle, x, y); + + if(!nomap) XMapWindow(handle->display, handle->window); + + XSync(handle->display, False); + while(1) { XNextEvent(handle->display, &ev); if(ev.type == MapNotify && ev.xmap.window == handle->window) { @@ -164,11 +175,6 @@ MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) { XSetGraphicsExposures(r->display, r->gc, False); XSelectInput(r->display, r->window, mask); - XMapWindow(r->display, r->window); - - XFlush(r->display); - XSync(r->display, False); - wait_map(r); if(x != MwDEFAULT || y != MwDEFAULT) { MwLLGetXYWH(r, &px, &py, &width, &height); @@ -177,8 +183,11 @@ MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) { if(y == MwDEFAULT) y = py; MwLLSetXY(r, x, y); + XSync(r->display, False); } + wait_map(r, 0, 0); + return r; } @@ -193,7 +202,8 @@ void MwLLDestroy(MwLL handle) { XUnmapWindow(handle->display, handle->window); XDestroyWindow(handle->display, handle->window); - XFlush(handle->display); + XSync(handle->display, False); + free(handle); } @@ -266,7 +276,19 @@ void MwLLGetXYWH(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) } void MwLLSetXY(MwLL handle, int x, int y) { + XSizeHints sh; + long r; + + XGetWMNormalHints(handle->display, handle->window, &sh, &r); + + sh.flags |= PPosition; + sh.x = x; + sh.y = y; + XMoveWindow(handle->display, handle->window, x, y); + XSetWMNormalHints(handle->display, handle->window, &sh); + + XSync(handle->display, False); } void MwLLSetWH(MwLL handle, int w, int h) { @@ -274,6 +296,11 @@ void MwLLSetWH(MwLL handle, int w, int h) { if(h < 1) h = 1; XResizeWindow(handle->display, handle->window, w, h); + + handle->width = w; + handle->height = h; + + XSync(handle->display, False); } void MwLLFreeColor(MwLLColor color) { @@ -336,9 +363,8 @@ void MwLLNextEvent(MwLL handle) { MwLLDispatch(handle, up, &p); } else if(ev.type == ConfigureNotify) { - MwLLDispatch(handle, resize, NULL); - if(handle->width != (unsigned int)ev.xconfigure.width || handle->height != (unsigned int)ev.xconfigure.height) { + MwLLDispatch(handle, resize, NULL); destroy_pixmap(handle); create_pixmap(handle); render = 1; @@ -738,16 +764,16 @@ void MwLLDetach(MwLL handle, MwPoint* point) { XTranslateCoordinates(handle->display, parent, RootWindow(handle->display, DefaultScreen(handle->display)), 0, 0, &x, &y, &child); + XUnmapWindow(handle->display, handle->window); + XReparentWindow(handle->display, handle->window, RootWindow(handle->display, DefaultScreen(handle->display)), x + point->x, y + point->y); - XFlush(handle->display); - XSync(handle->display, False); + wait_map(handle, 0, 0); } void MwLLShow(MwLL handle, int show) { if(show) { - XMapWindow(handle->display, handle->window); - wait_map(handle); + wait_map(handle, 0, 0); XSetInputFocus(handle->display, handle->window, RevertToNone, CurrentTime); } else { @@ -766,18 +792,17 @@ void MwLLMakePopup(MwLL handle, MwLL parent) { XChangeProperty(handle->display, handle->window, wndstate, XA_ATOM, 32, PropModeReplace, (unsigned char*)&wndmodal, 1); XUnmapWindow(handle->display, handle->window); - XMapWindow(handle->display, handle->window); - XFlush(handle->display); - XSync(handle->display, False); - - wait_map(handle); + wait_map(handle, 1, 0); } void MwLLSetSizeHints(MwLL handle, int minx, int miny, int maxx, int maxy) { XSizeHints* hints = XAllocSizeHints(); + long ret; - hints->flags = PMinSize | PMaxSize; + XGetWMSizeHints(handle->display, handle->window, hints, &ret, XA_WM_NORMAL_HINTS); + + hints->flags |= PMinSize | PMaxSize; hints->min_width = minx; hints->min_height = miny; hints->max_width = maxx; @@ -786,12 +811,8 @@ void MwLLSetSizeHints(MwLL handle, int minx, int miny, int maxx, int maxy) { XFree(hints); XUnmapWindow(handle->display, handle->window); - XMapWindow(handle->display, handle->window); - XFlush(handle->display); - XSync(handle->display, False); - - wait_map(handle); + wait_map(handle, 1, 0); } void MwLLMakeBorderless(MwLL handle, int toggle) { @@ -803,12 +824,8 @@ void MwLLMakeBorderless(MwLL handle, int toggle) { XChangeProperty(handle->display, handle->window, atom, atom, 32, PropModeReplace, (unsigned char*)&hints, 5); XUnmapWindow(handle->display, handle->window); - XMapWindow(handle->display, handle->window); - XFlush(handle->display); - XSync(handle->display, False); - - wait_map(handle); + wait_map(handle, 1, 0); } void MwLLFocus(MwLL handle) { diff --git a/src/dialog/messagebox.c b/src/dialog/messagebox.c index 2bce84a..aaa9f70 100644 --- a/src/dialog/messagebox.c +++ b/src/dialog/messagebox.c @@ -35,10 +35,12 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi int ww = MwGetInteger(handle, MwNwidth); int wh = MwGetInteger(handle, MwNheight); - p.x = 0; - p.y = 0; + w = 512; + h = 32 * 4; - window = MwVaCreateWidget(MwWindowClass, "messagebox", handle, ww, wh, (w = 512), (h = 32 * 4), + p.x = (ww - w) / 2; + p.y = (wh - h) / 2; + window = MwVaCreateWidget(MwWindowClass, "messagebox", handle, p.x, p.y, w, h, MwNtitle, title, NULL); diff --git a/src/widget/submenu.c b/src/widget/submenu.c index 305fad3..7b9a75b 100644 --- a/src/widget/submenu.c +++ b/src/widget/submenu.c @@ -160,8 +160,6 @@ static void mwSubMenuAppearImpl(MwWidget handle, MwMenu menu, MwPoint* point) { handle->internal = menu; - MwLLDetach(handle->lowlevel, point); - #ifdef USE_GDI SetWindowLongPtr(handle->lowlevel->hWnd, GWL_STYLE, (LPARAM)0); SetWindowLongPtr(handle->lowlevel->hWnd, GWL_EXSTYLE, (LPARAM)WS_EX_TOOLWINDOW); @@ -169,6 +167,8 @@ static void mwSubMenuAppearImpl(MwWidget handle, MwMenu menu, MwPoint* point) { MwLLShow(handle->lowlevel, 1); + MwLLDetach(handle->lowlevel, point); + for(i = 0; i < arrlen(menu->sub); i++) { int tw = MwTextWidth(handle, menu->sub[i]->name); h += MwTextHeight(handle, menu->sub[i]->name) + 3;