you should definitely submit a bug report with your code
On February 7, 2024 1:27:07 PM MST, ZenitDS <zeni...@proton.me> wrote: > >In my patch there were some issues with unhandled events. I upload >here a hopefully better patch. Not pretty but fixes the issues. > >New patch: > >Index: calmwm.h >=================================================================== >RCS file: /cvs/xenocara/app/cwm/calmwm.h,v >retrieving revision 1.379 >diff -u -p -r1.379 calmwm.h >--- calmwm.h 20 Jul 2023 14:39:34 -0000 1.379 >+++ calmwm.h 7 Feb 2024 20:25:12 -0000 >@@ -481,7 +481,7 @@ struct geom screen_area(struct screen_ > struct screen_ctx *screen_find(Window); > void screen_init(int); > void screen_prop_win_create(struct screen_ctx *, Window); >-void screen_prop_win_destroy(struct screen_ctx *); >+void screen_prop_win_destroy(struct screen_ctx *, int); > void screen_prop_win_draw(struct screen_ctx *, > const char *, ...) > __attribute__((__format__ (printf, 2, 3))) >@@ -558,6 +558,7 @@ void conf_screen(struct screen_ctx >*) > void conf_group(struct screen_ctx *); > > void xev_process(void); >+void xev_process_ev(XEvent *); > > int xu_get_prop(Window, Atom, Atom, long, unsigned char > **); > int xu_get_strprop(Window, Atom, char **); >Index: kbfunc.c >=================================================================== >RCS file: /cvs/xenocara/app/cwm/kbfunc.c,v >retrieving revision 1.174 >diff -u -p -r1.174 kbfunc.c >--- kbfunc.c 20 Jul 2023 14:39:34 -0000 1.174 >+++ kbfunc.c 7 Feb 2024 20:25:12 -0000 >@@ -169,8 +169,8 @@ kbfunc_client_move_mb(void *ctx, struct > > screen_prop_win_create(sc, cc->win); > screen_prop_win_draw(sc, "%+5d%+5d", cc->geom.x, cc->geom.y); >- while (move) { >- XMaskEvent(X_Dpy, MOUSEMASK, &ev); >+ while (move > 0) { >+ XMaskEvent(X_Dpy, MOUSEMASK | SubstructureNotifyMask, &ev); > switch (ev.type) { > case MotionNotify: > /* not more than 60 times / second */ >@@ -197,11 +197,28 @@ kbfunc_client_move_mb(void *ctx, struct > case ButtonRelease: > move = 0; > break; >+ /* check for destroy events, in case the client window >+ * gets destroyed, which forcefully closes the prop window. >+ */ >+ case DestroyNotify: >+ /* set move to -1 to specify abrupt exit */ >+ if (ev.xdestroywindow.window == cc->win) { >+ screen_prop_win_destroy(sc, 1); >+ move = -1; >+ } else if (ev.xdestroywindow.window == sc->prop.win) { >+ screen_prop_win_destroy(sc, 0); >+ move = -1; >+ } >+ xev_process_ev(&ev); >+ default: /* process event anyway */ >+ xev_process_ev(&ev); > } > } >- if (ltime) >- client_move(cc); >- screen_prop_win_destroy(sc); >+ if (move != -1) { >+ if (ltime) >+ client_move(cc); >+ screen_prop_win_destroy(sc, 1); >+ } > XUngrabPointer(X_Dpy, CurrentTime); > } > >@@ -258,7 +275,7 @@ kbfunc_client_resize_mb(void *ctx, struc > > screen_prop_win_create(sc, cc->win); > screen_prop_win_draw(sc, "%4d x %-4d", cc->dim.w, cc->dim.h); >- while (resize) { >+ while (resize > 0) { > XMaskEvent(X_Dpy, MOUSEMASK, &ev); > switch (ev.type) { > case MotionNotify: >@@ -277,11 +294,27 @@ kbfunc_client_resize_mb(void *ctx, struc > case ButtonRelease: > resize = 0; > break; >+ /* check for destroy events, in case the client window >+ * gets destroyed, which forcefully closes the prop window. >+ */ >+ case DestroyNotify: >+ if (ev.xdestroywindow.window == cc->win) { >+ screen_prop_win_destroy(sc, 1); >+ resize = -1; >+ } else if (ev.xdestroywindow.window == sc->prop.win) { >+ screen_prop_win_destroy(sc, 0); >+ resize = -1; >+ } >+ default: /* process event anyway */ >+ xev_process_ev(&ev); >+ break; > } > } >- if (ltime) >- client_resize(cc, 1); >- screen_prop_win_destroy(sc); >+ if (resize != -1) { >+ if (ltime) >+ client_resize(cc, 1); >+ screen_prop_win_destroy(sc, 1); >+ } > XUngrabPointer(X_Dpy, CurrentTime); > > /* Make sure the pointer stays within the window. */ >Index: screen.c >=================================================================== >RCS file: /cvs/xenocara/app/cwm/screen.c,v >retrieving revision 1.98 >diff -u -p -r1.98 screen.c >--- screen.c 27 Jan 2022 18:45:10 -0000 1.98 >+++ screen.c 7 Feb 2024 20:25:12 -0000 >@@ -278,10 +278,15 @@ screen_prop_win_create(struct screen_ctx > } > > void >-screen_prop_win_destroy(struct screen_ctx *sc) >+screen_prop_win_destroy(struct screen_ctx *sc, int destroy_window) > { > XftDrawDestroy(sc->prop.xftdraw); >- XDestroyWindow(X_Dpy, sc->prop.win); >+ /* >+ * In case the window was already destroyed >+ * (i.e. DestroyNotify event) >+ */ >+ if (destroy_window) >+ XDestroyWindow(X_Dpy, sc->prop.win); > } > > void >Index: xevents.c >=================================================================== >RCS file: /cvs/xenocara/app/cwm/xevents.c,v >retrieving revision 1.150 >diff -u -p -r1.150 xevents.c >--- xevents.c 24 Mar 2020 14:47:29 -0000 1.150 >+++ xevents.c 7 Feb 2024 20:25:12 -0000 >@@ -485,9 +485,15 @@ xev_process(void) > > while (XPending(X_Dpy)) { > XNextEvent(X_Dpy, &e); >- if ((e.type - Conf.xrandr_event_base) == RRScreenChangeNotify) >- xev_handle_randr(&e); >- else if ((e.type < LASTEvent) && (xev_handlers[e.type] != NULL)) >- (*xev_handlers[e.type])(&e); >+ xev_process_ev(&e); > } >+} >+ >+void >+xev_process_ev(XEvent *ev) >+{ >+ if ((ev->type - Conf.xrandr_event_base) == RRScreenChangeNotify) >+ xev_handle_randr(ev); >+ else if ((ev->type < LASTEvent) && (xev_handlers[ev->type] != NULL)) >+ (*xev_handlers[ev->type])(ev); > } > >On Tuesday, February 6th, 2024 at 10:14 PM, ZenitDS <zeni...@proton.me> wrote: > >> Hello, >> >> This is my first time posting here so please forgive me if >> something is not correct. >> >> When running cwm you can destroy the client window while >> you are moving or resizing it, leading to crash of the WM >> when the prop window is accessed (the one at the top-left that >> indicates the position/scale). >> >> I include a demonstration for the crash and also a patch that >> fixes it. Hopefully someone with more experience can implement >> a better fix. >> >> Also, should this go into the tech mailing list instead of misc? >> >> Demonstration code for the crash: >> >> #include <X11/Xlib.h> >> >> >> #include <err.h> >> >> #include <unistd.h> >> >> >> int >> main(void) >> { >> Display *dpy; >> Window win; >> int scr; >> XEvent ev; >> >> dpy = XOpenDisplay(NULL); >> if (!dpy) >> err(1, "XOpenDisplay"); >> >> scr = DefaultScreen(dpy); >> >> win = XCreateSimpleWindow(dpy, RootWindow(dpy, scr), 0, 0, 500, 500, 0, 0, >> WhitePixel(dpy, scr)); >> if (!win) >> err(1, "XCreateSimpleWindow"); >> >> XSelectInput(dpy, win, StructureNotifyMask | SubstructureNotifyMask | >> ExposureMask); >> XMapRaised(dpy, win); >> >> while (1) { >> XNextEvent(dpy, &ev); >> switch (ev.type) { >> case CreateNotify: >> goto end; >> case Expose: >> XClearWindow(dpy, win); >> break; >> default: >> break; >> } >> } >> end: >> XDestroyWindow(dpy, win); >> >> XCloseDisplay(dpy); >> >> return 0; >> } >> >> Here is the patch: >> >> Index: calmwm.h >> =================================================================== >> RCS file: /cvs/xenocara/app/cwm/calmwm.h,v >> retrieving revision 1.379 >> diff -u -p -r1.379 calmwm.h >> --- calmwm.h 20 Jul 2023 14:39:34 -0000 1.379 >> +++ calmwm.h 6 Feb 2024 20:20:22 -0000 >> @@ -481,7 +481,7 @@ struct geom screen_area(struct screen_ >> struct screen_ctx *screen_find(Window); >> void screen_init(int); >> void screen_prop_win_create(struct screen_ctx *, Window); >> -void screen_prop_win_destroy(struct screen_ctx *); >> +void screen_prop_win_destroy(struct screen_ctx *, int); >> void screen_prop_win_draw(struct screen_ctx *, >> const char *, ...) >> attribute((format (printf, 2, 3))) >> Index: kbfunc.c >> =================================================================== >> RCS file: /cvs/xenocara/app/cwm/kbfunc.c,v >> retrieving revision 1.174 >> diff -u -p -r1.174 kbfunc.c >> --- kbfunc.c 20 Jul 2023 14:39:34 -0000 1.174 >> +++ kbfunc.c 6 Feb 2024 20:20:22 -0000 >> @@ -169,9 +169,23 @@ kbfunc_client_move_mb(void *ctx, struct >> >> screen_prop_win_create(sc, cc->win); >> >> screen_prop_win_draw(sc, "%+5d%+5d", cc->geom.x, cc->geom.y); >> >> - while (move) { >> - XMaskEvent(X_Dpy, MOUSEMASK, &ev); >> + while (move > 0) { >> >> + XMaskEvent(X_Dpy, MOUSEMASK | SubstructureNotifyMask, &ev); >> switch (ev.type) { >> + /* check for destroy events, in case the client window >> + * gets destroyed, which forcefully closes the prop window. >> + / >> + case DestroyNotify: >> + / set move to -1 to specify abrupt exit */ >> + if (ev.xdestroywindow.window == cc->win) { >> >> + screen_prop_win_destroy(sc, 1); >> + client_remove(cc); >> + move = -1; >> + } else if (ev.xdestroywindow.window == sc->prop.win) { >> >> + screen_prop_win_destroy(sc, 0); >> + move = -1; >> + } >> + break; >> case MotionNotify: >> /* not more than 60 times / second */ >> if ((ev.xmotion.time - ltime) <= (1000 / 60)) >> @@ -199,9 +213,11 @@ kbfunc_client_move_mb(void *ctx, struct >> break; >> } >> } >> - if (ltime) >> - client_move(cc); >> - screen_prop_win_destroy(sc); >> + if (move != -1) { >> + if (ltime) >> + client_move(cc); >> + screen_prop_win_destroy(sc, 1); >> + } >> XUngrabPointer(X_Dpy, CurrentTime); >> } >> >> @@ -258,9 +274,22 @@ kbfunc_client_resize_mb(void *ctx, struc >> >> screen_prop_win_create(sc, cc->win); >> >> screen_prop_win_draw(sc, "%4d x %-4d", cc->dim.w, cc->dim.h); >> >> - while (resize) { >> + while (resize > 0) { >> >> XMaskEvent(X_Dpy, MOUSEMASK, &ev); >> switch (ev.type) { >> + /* check for destroy events, in case the client window >> + * gets destroyed, which forcefully closes the prop window. >> + */ >> + case DestroyNotify: >> + if (ev.xdestroywindow.window == cc->win) { >> >> + screen_prop_win_destroy(sc, 1); >> + client_remove(cc); >> + resize = -1; >> + } else if (ev.xdestroywindow.window == sc->prop.win) { >> >> + screen_prop_win_destroy(sc, 0); >> + resize = -1; >> + } >> + break; >> case MotionNotify: >> /* not more than 60 times / second */ >> if ((ev.xmotion.time - ltime) <= (1000 / 60)) >> @@ -279,9 +308,11 @@ kbfunc_client_resize_mb(void ctx, struc >> break; >> } >> } >> - if (ltime) >> - client_resize(cc, 1); >> - screen_prop_win_destroy(sc); >> + if (resize != -1) { >> + if (ltime) >> + client_resize(cc, 1); >> + screen_prop_win_destroy(sc, 1); >> + } >> XUngrabPointer(X_Dpy, CurrentTime); >> >> / Make sure the pointer stays within the window. */ >> Index: screen.c >> =================================================================== >> RCS file: /cvs/xenocara/app/cwm/screen.c,v >> retrieving revision 1.98 >> diff -u -p -r1.98 screen.c >> --- screen.c 27 Jan 2022 18:45:10 -0000 1.98 >> +++ screen.c 6 Feb 2024 20:20:22 -0000 >> @@ -278,10 +278,15 @@ screen_prop_win_create(struct screen_ctx >> } >> >> void >> -screen_prop_win_destroy(struct screen_ctx *sc) >> +screen_prop_win_destroy(struct screen_ctx *sc, int destroy_window) >> { >> XftDrawDestroy(sc->prop.xftdraw); >> >> - XDestroyWindow(X_Dpy, sc->prop.win); >> >> + /* >> + * In case the window was already destroyed >> + * (i.e. DestroyNotify event) >> + */ >> + if (destroy_window) >> + XDestroyWindow(X_Dpy, sc->prop.win); >> >> } >> >> void >