From 4cfdddbeaa19e0d625c9a46282d12823ceac3217 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Fri, 14 Nov 2025 10:37:16 +0000 Subject: [PATCH] fixed on kde at least git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@701 b9cfdab3-6d41-4d17-bbe4-086880011989 --- src/backend/x11.c | 70 ++++++++++++++++++++++++++++++++--------- src/dialog/messagebox.c | 4 ++- src/widget/submenu.c | 2 +- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/backend/x11.c b/src/backend/x11.c index b152d66..fdf3931 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -40,6 +40,39 @@ static void destroy_pixmap(MwLL handle) { XFreePixmap(handle->x11.display, handle->x11.pixmap); } +static void sync_move(MwLL handle, int x, int y) { + XEvent* queue = NULL; + XEvent ev; + unsigned long n = MwTimeGetTick() + 100; + int t = 0; + XWindowAttributes xwa; + + XGetWindowAttributes(handle->x11.display, handle->x11.window, &xwa); + + XSync(handle->x11.display, False); + + while(!xwa.override_redirect && n > MwTimeGetTick()) { + XSync(handle->x11.display, False); + if(!XPending(handle->x11.display)) continue; + XNextEvent(handle->x11.display, &ev); + if(t == 0 && ev.type == ReparentNotify && ev.xreparent.window == handle->x11.window && ev.xreparent.window != RootWindow(handle->x11.display, DefaultScreen(handle->x11.display))) { + t = 1; + }else if(t == 1 && ev.type == ConfigureNotify && ev.xconfigure.window == handle->x11.window){ + break; + } else { + arrput(queue, ev); + } + } + + while(arrlen(queue) > 0) { + XPutBackEvent(handle->x11.display, &queue[0]); + arrdel(queue, 0); + } + arrfree(queue); + + MwLLSetXY(handle, x, y); +} + static void wait_map(MwLL handle, int move_back, int nomap) { XEvent* queue = NULL; XEvent ev; @@ -49,10 +82,12 @@ static void wait_map(MwLL handle, int move_back, int nomap) { MwLLGetXYWH(handle, &x, &y, &w, &h); - if(move_back) MwLLSetXY(handle, x, y); - XGetWindowAttributes(handle->x11.display, handle->x11.window, &xwa); if(xwa.map_state != IsViewable) { + if(move_back) MwLLSetXY(handle, x, y); + + XSync(handle->x11.display, False); + if(!nomap) XMapWindow(handle->x11.display, handle->x11.window); XSync(handle->x11.display, False); @@ -214,12 +249,17 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { if(x != MwDEFAULT || y != MwDEFAULT) { unsigned int dummy; + MwLLGetXYWH(r, &px, &py, &dummy, &dummy); if(x == MwDEFAULT) x = px; if(y == MwDEFAULT) y = py; - MwLLSetXY(r, x, y); + if(parent == NULL){ + sync_move(r, x, y); + }else{ + MwLLSetXY(r, x, y); + } } return r; @@ -317,7 +357,7 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) { sh.flags = 0; XGetWMNormalHints(handle->x11.display, handle->x11.window, &sh, &r); - sh.flags |= PPosition; + sh.flags |= USPosition; sh.x = x; sh.y = y; @@ -833,11 +873,11 @@ static void MwLLDetachImpl(MwLL handle, MwPoint* point) { XGetWindowAttributes(handle->x11.display, handle->x11.window, &xwa); - if(xwa.map_state == IsViewable) wait_unmap(handle); - XReparentWindow(handle->x11.display, handle->x11.window, RootWindow(handle->x11.display, DefaultScreen(handle->x11.display)), x + point->x, y + point->y); - - if(xwa.map_state == IsViewable) wait_map(handle, 0, 0); + + if(xwa.map_state == IsViewable){ + sync_move(handle, x + point->x, y + point->y); + } } static void MwLLShowImpl(MwLL handle, int show) { @@ -859,15 +899,14 @@ static void MwLLMakePopupImpl(MwLL handle, MwLL parent) { XSetTransientForHint(handle->x11.display, handle->x11.window, parent->x11.window); XChangeProperty(handle->x11.display, handle->x11.window, wndtype, XA_ATOM, 32, PropModeReplace, (unsigned char*)&wnddlg, 1); XChangeProperty(handle->x11.display, handle->x11.window, wndstate, XA_ATOM, 32, PropModeReplace, (unsigned char*)&wndmodal, 1); - - XUnmapWindow(handle->x11.display, handle->x11.window); - - wait_map(handle, 1, 0); } static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) { XSizeHints* hints = XAllocSizeHints(); long ret; + XWindowAttributes xwa; + + XGetWindowAttributes(handle->x11.display, handle->x11.window, &xwa); XGetWMSizeHints(handle->x11.display, handle->x11.window, hints, &ret, XA_WM_NORMAL_HINTS); @@ -879,9 +918,10 @@ static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int XSetWMSizeHints(handle->x11.display, handle->x11.window, hints, XA_WM_NORMAL_HINTS); XFree(hints); - XUnmapWindow(handle->x11.display, handle->x11.window); - - wait_map(handle, 1, 0); + if(xwa.map_state == IsViewable){ + wait_unmap(handle); + wait_map(handle, 1, 0); + } } static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { diff --git a/src/dialog/messagebox.c b/src/dialog/messagebox.c index ee9a197..de012cf 100644 --- a/src/dialog/messagebox.c +++ b/src/dialog/messagebox.c @@ -99,9 +99,11 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi MwNalignment, MwALIGNMENT_BEGINNING, NULL); - MwLLDetach(window->lowlevel, &p); + MwLLShow(window->lowlevel, 0); MwLLSetSizeHints(window->lowlevel, w, h, w, h); MwLLMakePopup(window->lowlevel, handle->lowlevel); + MwLLDetach(window->lowlevel, &p); + MwLLShow(window->lowlevel, 1); MwAddUserHandler(window, MwNcloseHandler, messagebox_close, NULL); diff --git a/src/widget/submenu.c b/src/widget/submenu.c index bd116db..56bbf34 100644 --- a/src/widget/submenu.c +++ b/src/widget/submenu.c @@ -165,8 +165,8 @@ static void mwSubMenuAppearImpl(MwWidget handle, MwMenu menu, MwPoint* point) { handle->internal = menu; - MwLLDetach(handle->lowlevel, point); MwLLMakeToolWindow(handle->lowlevel); + MwLLDetach(handle->lowlevel, point); MwLLShow(handle->lowlevel, 1); for(i = 0; i < arrlen(menu->sub); i++) {