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
>

Reply via email to