diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index 202482e..1b479e6 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -77,6 +77,7 @@ MWDECL void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap); MWDECL void MwLLForceRender(MwLL handle); MWDECL void MwLLSetCursor(MwLL handle, MwCursor* image, MwCursor* mask); +MWDECL void MwLLDetach(MwLL handle, MwPoint* point); #ifdef __cplusplus } diff --git a/src/backend/gdi.c b/src/backend/gdi.c index a7ee6ee..b58e2c6 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -369,3 +369,23 @@ void MwLLSetCursor(MwLL handle, MwCursor* image, MwCursor* mask) { free(dimage); free(dmask); } + +void MwLLDetach(MwLL handle, MwPoint* point) { + RECT rc, rc2; + LONG_PTR style = GetWindowLongPtr(handle->hWnd, GWL_STYLE); + + style |= WS_OVERLAPPEDWINDOW; + + GetWindowRect(GetParent(handle->hWnd), &rc); + + GetClientRect(handle->hWnd, &rc2); + + SetParent(handle->hWnd, NULL); + + rc.left += point->x; + rc.top += point->y; + + SetWindowPos(handle->hWnd, HWND_TOPMOST, rc.left, rc.top, rc2.right == 0 ? 1 : rc2.right, rc2.bottom == 0 ? 1 : rc2.bottom, SWP_NOREDRAW); + + SetWindowLongPtr(handle->hWnd, GWL_STYLE, style); +} diff --git a/src/backend/x11.c b/src/backend/x11.c index 1007e75..f40db22 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -374,3 +374,20 @@ void MwLLSetCursor(MwLL handle, MwCursor* image, MwCursor* mask) { XcursorImageDestroy(img); } + +void MwLLDetach(MwLL handle, MwPoint* point) { + int x = 0, y = 0; + Window child, root, parent; + Window* children; + unsigned int nchild; + + XQueryTree(handle->display, handle->window, &root, &parent, &children, &nchild); + if(children != NULL) XFree(children); + + XTranslateCoordinates(handle->display, parent, RootWindow(handle->display, DefaultScreen(handle->display)), 0, 0, &x, &y, &child); + + XReparentWindow(handle->display, handle->window, RootWindow(handle->display, DefaultScreen(handle->display)), x + point->x, y + point->y); + + XMapWindow(handle->display, handle->window); + XSetInputFocus(handle->display, handle->window, RevertToNone, CurrentTime); +} diff --git a/src/widget/submenu.c b/src/widget/submenu.c index 823be17..01f7543 100644 --- a/src/widget/submenu.c +++ b/src/widget/submenu.c @@ -5,6 +5,7 @@ static int create(MwWidget handle) { #ifdef _WIN32 + ShowWindow(handle->lowlevel->hWnd, SW_HIDE); #else XUnmapWindow(handle->lowlevel->display, handle->lowlevel->window); #endif @@ -163,50 +164,28 @@ MwClass MwSubMenuClass = &MwSubMenuClassRec; void MwSubMenuAppear(MwWidget handle, MwMenu menu, MwPoint* point) { int i, w = 0, h = 0; -#ifdef _WIN32 - RECT rc; - LONG_PTR ex = GetWindowLongPtr(handle->lowlevel->hWnd, GWL_EXSTYLE); -#else +#ifndef _WIN32 + XSetWindowAttributes xswa; Atom wndtype = XInternAtom(handle->lowlevel->display, "_NET_WM_WINDOW_TYPE", False); Atom wndmenu = XInternAtom(handle->lowlevel->display, "_NET_WM_WINDOW_TYPE_MENU", False); - int x = 0, y = 0; - Window child; - XSetWindowAttributes xswa; + + xswa.override_redirect = True; + + XChangeWindowAttributes(handle->lowlevel->display, handle->lowlevel->window, CWOverrideRedirect, &xswa); + XChangeProperty(handle->lowlevel->display, handle->lowlevel->window, wndtype, 4, 32, PropModeReplace, (unsigned char*)&wndmenu, 1); #endif handle->internal = menu; + MwLLDetach(handle->lowlevel, point); #ifdef _WIN32 - ex |= WS_EX_TOOLWINDOW; - SetWindowLongPtr(handle->lowlevel->hWnd, GWL_STYLE, (LONG_PTR)0); - SetWindowLongPtr(handle->lowlevel->hWnd, GWL_EXSTYLE, ex); - - GetWindowRect(handle->parent->lowlevel->hWnd, &rc); - - SetParent(handle->lowlevel->hWnd, NULL); - - rc.left += point->x; - rc.top += point->y; - - SetWindowPos(handle->lowlevel->hWnd, HWND_TOPMOST, rc.left, rc.top, 1, 1, SWP_NOREDRAW); + SetWindowLongPtr(handle->lowlevel->hWnd, GWL_EXSTYLE, (LONG_PTR)WS_EX_TOOLWINDOW); ShowWindow(handle->lowlevel->hWnd, SW_NORMAL); SetFocus(handle->lowlevel->hWnd); #else - - xswa.override_redirect = True; - - XTranslateCoordinates(handle->parent->lowlevel->display, handle->parent->lowlevel->window, RootWindow(handle->parent->lowlevel->display, DefaultScreen(handle->parent->lowlevel->display)), 0, 0, &x, &y, &child); - - XReparentWindow(handle->lowlevel->display, handle->lowlevel->window, RootWindow(handle->lowlevel->display, DefaultScreen(handle->lowlevel->display)), x + point->x, y + point->y); - - XChangeWindowAttributes(handle->lowlevel->display, handle->lowlevel->window, CWOverrideRedirect, &xswa); - XChangeProperty(handle->lowlevel->display, handle->lowlevel->window, wndtype, 4, 32, PropModeReplace, (unsigned char*)&wndmenu, 1); - - XMapWindow(handle->lowlevel->display, handle->lowlevel->window); - XSetInputFocus(handle->lowlevel->display, handle->lowlevel->window, RevertToNone, CurrentTime); #endif for(i = 0; i < arrlen(menu->sub); i++) {