Menu windows are recalculated with -w
authorphillbush <phillbush@cock.li>
Tue, 19 May 2020 16:41:11 +0000 (13:41 -0300)
committerphillbush <phillbush@cock.li>
Tue, 19 May 2020 16:41:11 +0000 (13:41 -0300)
Every time a window is opened, its position is recalculated with
recalcmenu().

xmenu.c

diff --git a/xmenu.c b/xmenu.c
index 6b45d2f..05c26b9 100644 (file)
--- a/xmenu.c
+++ b/xmenu.c
@@ -83,6 +83,7 @@ static void getmenuitem(Window win, int y, struct Menu **menu_ret, struct Item *
 static void drawmenu(void);
 static void calcscreengeom(void);
 static void calcmenu(struct Menu *menu);
 static void drawmenu(void);
 static void calcscreengeom(void);
 static void calcmenu(struct Menu *menu);
+static void recalcmenu(struct Menu *menu);
 static void grabpointer(void);
 static void grabkeyboard(void);
 static void setcurrmenu(struct Menu *currmenu_new);
 static void grabpointer(void);
 static void grabkeyboard(void);
 static void setcurrmenu(struct Menu *currmenu_new);
@@ -99,6 +100,7 @@ static Visual *visual;
 static Window rootwin;
 static int screen;
 static struct DC dc;
 static Window rootwin;
 static int screen;
 static struct DC dc;
+static Atom wmdelete;
 
 /* menu variables */
 static struct Menu *rootmenu = NULL;
 
 /* menu variables */
 static struct Menu *rootmenu = NULL;
@@ -143,6 +145,7 @@ main(int argc, char *argv[])
        visual = DefaultVisual(dpy, screen);
        rootwin = RootWindow(dpy, screen);
        colormap = DefaultColormap(dpy, screen);
        visual = DefaultVisual(dpy, screen);
        rootwin = RootWindow(dpy, screen);
        colormap = DefaultColormap(dpy, screen);
+       wmdelete=XInternAtom(dpy, "WM_DELETE_WINDOW", True);
 
        /* setup */
        getresources();
 
        /* setup */
        getresources();
@@ -317,6 +320,8 @@ allocmenu(struct Menu *parent, struct Item *list, unsigned level)
                                  CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWEventMask,
                                  &swa);
 
                                  CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWEventMask,
                                  &swa);
 
+       XSetWMProtocols(dpy, menu->win, &wmdelete, 1);
+
        return menu;
 }
 
        return menu;
 }
 
@@ -467,18 +472,13 @@ calcmenu(struct Menu *menu)
 
                XStringListToTextProperty(menutitle, menutitlecount, &textprop);
        } else {                    /* else, calculate in respect to parent menu */
 
                XStringListToTextProperty(menutitle, menutitlecount, &textprop);
        } else {                    /* else, calculate in respect to parent menu */
-
-               /* search for the item in parent menu that generates this menu */
-               for (item = menu->parent->list; item->submenu != menu; item = item->next)
-                       ;
-
                if (screengeom.screenw - (menu->parent->x + menu->parent->w + geom.border) >= menu->w)
                        menu->x = menu->parent->x + menu->parent->w + geom.border;
                else if (menu->parent->x > menu->w + geom.border)
                        menu->x = menu->parent->x - menu->w - geom.border;
 
                if (screengeom.screenw - (menu->parent->x + menu->parent->w + geom.border) >= menu->w)
                        menu->x = menu->parent->x + menu->parent->w + geom.border;
                else if (menu->parent->x > menu->w + geom.border)
                        menu->x = menu->parent->x - menu->w - geom.border;
 
-               if (screengeom.screenh - (item->y + menu->parent->y) > menu->h)
-                       menu->y = item->y + menu->parent->y;
+               if (screengeom.screenh - (menu->caller->y + menu->parent->y) > menu->h)
+                       menu->y = menu->caller->y + menu->parent->y;
                else if (screengeom.screenh - menu->parent->y > menu->h)
                        menu->y = menu->parent->y;
                else if (screengeom.screenh > menu->h)
                else if (screengeom.screenh - menu->parent->y > menu->h)
                        menu->y = menu->parent->y;
                else if (screengeom.screenh > menu->h)
@@ -513,6 +513,32 @@ calcmenu(struct Menu *menu)
        }
 }
 
        }
 }
 
+/* recalculate menu position in respect to its parent */
+static void
+recalcmenu(struct Menu *menu)
+{
+       XWindowAttributes parentwin;
+
+       if (menu->parent == NULL)
+               return;
+
+       XGetWindowAttributes(dpy, menu->parent->win, &parentwin);
+
+       if (screengeom.screenw - (parentwin.x + menu->parent->w + geom.border) >= menu->w)
+               menu->x = parentwin.x + menu->parent->w + geom.border;
+       else if (parentwin.x > menu->w + geom.border)
+               menu->x = parentwin.x - menu->w - geom.border;
+
+       if (screengeom.screenh - (menu->caller->y + parentwin.y) > menu->h)
+               menu->y = menu->caller->y + parentwin.y;
+       else if (screengeom.screenh - parentwin.y > menu->h)
+               menu->y = parentwin.y;
+       else if (screengeom.screenh > menu->h)
+               menu->y = screengeom.screenh - menu->h;
+
+       XMoveWindow(dpy, menu->win, menu->x, menu->y);
+}
+
 /* try to grab pointer, we may have to wait for another process to ungrab */
 static void
 grabpointer(void)
 /* try to grab pointer, we may have to wait for another process to ungrab */
 static void
 grabpointer(void)
@@ -607,6 +633,7 @@ setcurrmenu(struct Menu *currmenu_new)
 
        /* unmap menus from currmenu (inclusive) until lcamenu (exclusive) */
        for (menu = currmenu; menu != lcamenu; menu = menu->parent) {
 
        /* unmap menus from currmenu (inclusive) until lcamenu (exclusive) */
        for (menu = currmenu; menu != lcamenu; menu = menu->parent) {
+               menu->selected = NULL;
                XUnmapWindow(dpy, menu->win);
        }
 
                XUnmapWindow(dpy, menu->win);
        }
 
@@ -615,6 +642,8 @@ setcurrmenu(struct Menu *currmenu_new)
        /* map menus from currmenu (inclusive) until lcamenu (exclusive) */
        item = NULL;
        for (menu = currmenu; menu != lcamenu; menu = menu->parent) {
        /* map menus from currmenu (inclusive) until lcamenu (exclusive) */
        item = NULL;
        for (menu = currmenu; menu != lcamenu; menu = menu->parent) {
+               if (override_redirect == False)
+                       recalcmenu(menu);
                XMapWindow(dpy, menu->win);
                if (item != NULL)
                        menu->selected = item;
                XMapWindow(dpy, menu->win);
                if (item != NULL)
                        menu->selected = item;
@@ -810,6 +839,8 @@ selectitem:
                        currmenu->selected = NULL;
                        drawmenu();
                        break;
                        currmenu->selected = NULL;
                        drawmenu();
                        break;
+               case ClientMessage:     /* user closed a window */
+                       return;
                }
        }
 }
                }
        }
 }