From 40aabee23a1aa9530df517af4c96b11881ec4546 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 29 Sep 2025 07:05:09 +0000 Subject: [PATCH] quit properly git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@60 b9cfdab3-6d41-4d17-bbe4-086880011989 --- include/Mw/LowLevel.h | 1 + include/Mw/TypeDefs.h | 1 + include/Mw/X11.h | 1 + src/core.c | 10 +++++++++- src/gdi.c | 5 +++++ src/x11.c | 14 ++++++++++---- 6 files changed, 27 insertions(+), 5 deletions(-) diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index 3e83595..eed72a0 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -31,6 +31,7 @@ struct _MwLLHandler { void (*up)(MwLL handle); void (*down)(MwLL handle); void (*resize)(MwLL handle); + void (*close)(MwLL handle); }; #ifdef __cplusplus diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index 0e50ea3..a851901 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -61,6 +61,7 @@ struct _MwWidget { MwClass widget_class; int pressed; + int close; MwIntegerKeyValue* integer; MwTextKeyValue* text; diff --git a/include/Mw/X11.h b/include/Mw/X11.h index 8aeb2a2..3282b5d 100644 --- a/include/Mw/X11.h +++ b/include/Mw/X11.h @@ -19,6 +19,7 @@ struct _MwLL { GC gc; Colormap colormap; void* user; + Atom wm_delete; MwLLHandler handler; }; diff --git a/src/core.c b/src/core.c index ff24157..7f79905 100644 --- a/src/core.c +++ b/src/core.c @@ -26,6 +26,12 @@ static void llresizehandler(MwLL handle) { MwDispatchUserHandler(h, MwNresizeHandler, NULL); } +static void llclosehandler(MwLL handle) { + MwWidget h = (MwWidget)handle->user; + + h->close = 1; +} + MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height) { MwWidget h = malloc(sizeof(*h)); @@ -37,12 +43,14 @@ MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, h->lowlevel = MwLLCreate(parent == NULL ? NULL : parent->lowlevel, x, y, width, height); h->widget_class = widget_class; h->pressed = 0; + h->close = 0; h->lowlevel->user = h; h->lowlevel->handler->draw = lldrawhandler; h->lowlevel->handler->up = lluphandler; h->lowlevel->handler->down = lldownhandler; h->lowlevel->handler->resize = llresizehandler; + h->lowlevel->handler->close = llclosehandler; if(parent != NULL) arrput(parent->children, h); @@ -133,7 +141,7 @@ int MwPending(MwWidget handle) { } void MwLoop(MwWidget handle) { - while(1) { + while(!handle->close) { MwStep(handle); MwDispatchUserHandler(handle, MwNtickHandler, NULL); diff --git a/src/gdi.c b/src/gdi.c index 9fce4d2..8fe46e1 100644 --- a/src/gdi.c +++ b/src/gdi.c @@ -47,6 +47,11 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { } else if(msg == WM_ERASEBKGND) { } else if(msg == WM_NCHITTEST) { return HTCLIENT; + } else if(msg == WM_DESTROY) { + MwLLDispatch(u->ll, close); + PostQuitMessage(0); + } else if(msg == WM_CLOSE) { + DestroyWindow(hWnd); } else { return (u->old == NULL) ? DefWindowProc(hWnd, msg, wp, lp) : CallWindowProc(u->old, hWnd, msg, wp, lp); } diff --git a/src/x11.c b/src/x11.c index fafbb58..b520ff8 100644 --- a/src/x11.c +++ b/src/x11.c @@ -18,8 +18,10 @@ MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) { r->display = parent->display; p = parent->window; } - r->window = XCreateSimpleWindow(r->display, p, x, y, width, height, 0, 0, WhitePixel(r->display, XDefaultScreen(r->display))); - r->colormap = DefaultColormap(r->display, XDefaultScreen(r->display)); + r->window = XCreateSimpleWindow(r->display, p, x, y, width, height, 0, 0, WhitePixel(r->display, XDefaultScreen(r->display))); + r->colormap = DefaultColormap(r->display, XDefaultScreen(r->display)); + r->wm_delete = XInternAtom(r->display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(r->display, r->window, &r->wm_delete, 1); r->gc = XCreateGC(r->display, r->window, 0, 0); @@ -96,7 +98,7 @@ void MwLLFreeColor(MwLLColor color) { int MwLLPending(MwLL handle) { XEvent ev; - if(XCheckWindowEvent(handle->display, handle->window, mask, &ev)) { + if(XCheckTypedWindowEvent(handle->display, handle->window, ClientMessage, &ev) || XCheckWindowEvent(handle->display, handle->window, mask, &ev)) { XPutBackEvent(handle->display, &ev); return 1; } @@ -105,7 +107,7 @@ int MwLLPending(MwLL handle) { void MwLLNextEvent(MwLL handle) { XEvent ev; - while(XCheckWindowEvent(handle->display, handle->window, mask, &ev)) { + while(XCheckTypedWindowEvent(handle->display, handle->window, ClientMessage, &ev) || XCheckWindowEvent(handle->display, handle->window, mask, &ev)) { if(ev.type == Expose) { MwLLDispatch(handle, draw); } else if(ev.type == ButtonPress) { @@ -120,6 +122,10 @@ void MwLLNextEvent(MwLL handle) { } } else if(ev.type == ConfigureNotify) { MwLLDispatch(handle, resize); + } else if(ev.type == ClientMessage) { + if(ev.xclient.data.l[0] == (long)handle->wm_delete) { + MwLLDispatch(handle, close); + } } } }