]> git.mdlowis.com Git - proto/anvil.git/commitdiff
added layer logic to mons.c to ensure floating windows always appear above tiled
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 17 Mar 2020 03:25:49 +0000 (23:25 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 17 Mar 2020 03:25:49 +0000 (23:25 -0400)
anvil.c
anvil.h
client.c
mons.c

diff --git a/anvil.c b/anvil.c
index 3f9ebdee1ab14816253f617e594ee06f52bb3da7..ce8a47f0b425a0e8c0b80326fe59d00d4262f623 100644 (file)
--- a/anvil.c
+++ b/anvil.c
@@ -29,28 +29,36 @@ static void warp_mouse(Client* c)
 static void xbtnpress(XEvent* e)
 {
     XButtonEvent* ev = &(e->xbutton);
-    Client* c = client_get(e->xbutton.window);
     X.start_x = ev->x_root;
     X.start_y = ev->y_root;
+    Location loc;
+    Client* c = client_get(e->xbutton.window, &loc);
     if (c && (ev->window == c->frame))
     {
-//        client_btnclick(c, ev->button, ev->x, ev->y);
-        if (ev->button == Button1)
+        if (loc.column)
         {
-           client_raise(c);
-            if (ev->y > (TITLE_HEIGHT + BORDER_WIDTH))
-            {
-                X.mode = M_RESIZE;
-                warp_mouse(c);
-            }
-        }
-        else if (ev->button == Button2)
-        {
-            client_close(c);
+            puts("tiled mouse click");
         }
-        else if (ev->button == Button3)
+        else
         {
-            client_lower(c);
+//            client_btnclick(c, ev->button, ev->x, ev->y);
+            if (ev->button == Button1)
+            {
+                mons_raise(loc.monitor, c);
+                if (ev->y > (TITLE_HEIGHT + BORDER_WIDTH))
+                {
+                    X.mode = M_RESIZE;
+                    warp_mouse(c);
+                }
+            }
+            else if (ev->button == Button2)
+            {
+                client_close(c);
+            }
+            else if (ev->button == Button3)
+            {
+                mons_lower(loc.monitor, c);
+            }
         }
     }
 }
@@ -66,19 +74,27 @@ static void xbtnmotion(XEvent* e)
     /* make sure we get just the latest event */
     XMotionEvent *ev = &e->xmotion;
     while (XCheckTypedWindowEvent(X.disp, ev->window, ev->type, e));
-    Client* c = client_get(ev->window);
+    Location loc;
+    Client* c = client_get(ev->window, &loc);
     if (c && (ev->window == c->frame))
     {
-//        client_btnmove(c, ev->button, ev->x, ev->y);
-        if (PRESSED(ev->state, Button1))
+        if (loc.column)
         {
-            if (X.mode != M_RESIZE)
-            {
-                client_move(c, ev->x_root - X.start_x, ev->y_root - X.start_y);
-            }
-            else
+            puts("tiled mouse drag");
+        }
+        else
+        {
+//            client_btnmove(c, ev->button, ev->x, ev->y);
+            if (PRESSED(ev->state, Button1))
             {
-                client_resize(c, ev->x_root - X.start_x, ev->y_root - X.start_y);
+                if (X.mode != M_RESIZE)
+                {
+                    client_move(c, ev->x_root - X.start_x, ev->y_root - X.start_y);
+                }
+                else
+                {
+                    client_resize(c, ev->x_root - X.start_x, ev->y_root - X.start_y);
+                }
             }
         }
     }
@@ -98,7 +114,7 @@ static void xconfigrequest(XEvent* e)
     wc.sibling = ev->above;
     wc.stack_mode = ev->detail;
     XConfigureWindow(X.disp, ev->window, ev->value_mask, &wc);
-    Client* c = client_get(ev->window);
+    Client* c = client_get(ev->window, NULL);
     if (c && c->win == ev->window)
     {
         c->w = wc.width;
@@ -115,7 +131,7 @@ static void xmaprequest(XEvent* e)
 {
     XMapRequestEvent* ev = &(e->xmaprequest);
     XWindowAttributes attr;
-    if (!client_get(ev->window))
+    if (!client_get(ev->window, NULL))
     {
         if (XGetWindowAttributes(X.disp, ev->window, &attr) && !attr.override_redirect)
         {
@@ -127,7 +143,7 @@ static void xmaprequest(XEvent* e)
 static void xunmapnotify(XEvent* e)
 {
     XUnmapEvent* ev = &(e->xunmap);
-    Client* c = client_get(ev->window);
+    Client* c = client_get(ev->window, NULL);
     if (c && c->win == ev->window)
     {
         XUnmapWindow(X.disp, c->frame);
@@ -137,7 +153,7 @@ static void xunmapnotify(XEvent* e)
 static void xdestroynotify(XEvent* e)
 {
     XDestroyWindowEvent* ev = &(e->xdestroywindow);
-    Client* c = client_get(ev->window);
+    Client* c = client_get(ev->window, NULL);
     if (c)
     {
         if (Focused == c)
@@ -156,7 +172,7 @@ static void xclientmsg(XEvent* e)
 static void xpropnotify(XEvent* e)
 {
     XPropertyEvent* ev = &(e->xproperty);
-    Client* c = client_get(ev->window);
+    Client* c = client_get(ev->window, NULL);
     if (c)
     {
         client_readprops(c);
@@ -167,7 +183,7 @@ static void xpropnotify(XEvent* e)
 static void xenternotify(XEvent* e)
 {
     XCrossingEvent* ev = &(e->xcrossing);
-    Client* c = client_get(ev->window);
+    Client* c = client_get(ev->window, NULL);
     if (c)
     {
         client_focus(c);
@@ -178,7 +194,7 @@ static void xexpose(XEvent* e)
 {
     if (e->xexpose.count == 0)
     {
-        Client* c = client_get(e->xexpose.window);
+        Client* c = client_get(e->xexpose.window, NULL);
         if (c)
         {
             client_draw(c);
diff --git a/anvil.h b/anvil.h
index cb787d0bd66838940a9f48be6347f470954de6e6..b465e1cf51f6d0f8db4fa9086d80e166507b3f0d 100644 (file)
--- a/anvil.h
+++ b/anvil.h
@@ -57,9 +57,9 @@ typedef struct Client {
 } Client;
 
 enum {
+    TILE_MONOCLE,
     TILE_STACKED,
-    TILE_EXPAND,
-    TILE_MONOCOLE
+    TILE_EXPAND
 } TileMode;
 
 typedef struct Column {
@@ -114,21 +114,22 @@ void keys_run(XKeyEvent* ev);
 /* mons.c */
 extern Monitor* Monitors;
 void mons_init(void);
+void mons_layer(Monitor* mon);
 void mons_addclient(Client* c);
 void mons_delclient(Client* c);
 int mons_find(Window win, Location* loc);
 void mons_place(Client* c);
 void mons_wspace(int i);
 void mons_towspace(Client* c, int i);
+void mons_raise(Monitor* mon, Client* c);
+void mons_lower(Monitor* mon, Client* c);
 
 /* client.c */
 extern Client* Focused;
 void client_initall(void);
 Client* client_add(Window win, XWindowAttributes* attr);
 void client_draw(Client* c);
-Client* client_get(Window w);
-void client_raise(Client* c);
-void client_lower(Client* c);
+Client* client_get(Window w, Location* loc);
 void client_move(Client* c, int xdiff, int ydiff);
 void client_resize(Client* c, int xdiff, int ydiff);
 void client_close(Client* c);
index f518b380e6260f116f0a1df4f421fc82f7e674d1..701981506c74dc293f9fbf32182f2e2aa2546af0 100644 (file)
--- a/client.c
+++ b/client.c
@@ -28,7 +28,6 @@ Client* client_add(Window win, XWindowAttributes* attr)
     c->y = attr->y;
     c->w = attr->width;
     c->h = attr->height;
-    mons_addclient(c);
     client_readprops(c);
 
     /* Reparent the window if applicable */
@@ -51,6 +50,7 @@ Client* client_add(Window win, XWindowAttributes* attr)
 
     /* Map the window and draw the frame */
     XAddToSaveSet(X.disp, c->win);
+    mons_addclient(c);
     client_show(c, 1);
     client_draw(c);
 
@@ -74,13 +74,14 @@ void client_draw(Client* c)
     }
 }
 
-Client* client_get(Window w)
+Client* client_get(Window w, Location* loc)
 {
+    Location local_loc;
     Client* c = NULL;
-    Location loc = {0};
-    if (mons_find(w, &loc))
+    loc = (loc ? loc : &local_loc);
+    if (mons_find(w, loc))
     {
-        c = loc.client;
+        c = loc->client;
     }
     return c;
 }
diff --git a/mons.c b/mons.c
index 6a3c21309aef81a34020a0821b925f20685dd008..b842801fef5a21cf2d70be565a9ba4eee8d33061 100644 (file)
--- a/mons.c
+++ b/mons.c
@@ -29,7 +29,7 @@ void mons_init(void)
         for (int i = 0; i < 10; i++)
         {
             Column* col = ecalloc(1, sizeof(Column));
-            col->mode = TILE_STACKED,
+            col->mode = TILE_MONOCLE,
             col->width = m->w;
             Workspace* wspace = ecalloc(1, sizeof(Workspace));
             wspace->columns = col;
@@ -41,6 +41,58 @@ void mons_init(void)
     xfree(mons);
 }
 
+static void coldims(Monitor* mon, Column* col, int *x, int *y, int *w, int *h)
+{
+    *x = mon->x, *y = mon->y, *w = col->width, *h = mon->h;
+    for (Column* c = mon->cspace->columns; c != col; *x += c->width, c = c->next);
+    *x += BORDER_WIDTH;
+    *y += BORDER_WIDTH + TITLE_HEIGHT;
+    *w -= 2*BORDER_WIDTH;
+    *h -= 2*BORDER_WIDTH + TITLE_HEIGHT;
+}
+
+void mons_layer(Monitor* mon)
+{
+    /* lower all of the floating windows first */
+    for (Client* client = mon->cspace->floating; client; client = client->next)
+    {
+        XLowerWindow(X.disp, client->win);
+        XLowerWindow(X.disp, client->frame);
+    }
+    /* now lower all of the tiled windows */
+    for (Column* col = mon->cspace->columns; col; col = col->next)
+    {
+        for (Client* client = col->clients; client; client = client->next)
+        {
+            XLowerWindow(X.disp, client->win);
+            XLowerWindow(X.disp, client->frame);
+        }
+    }
+}
+
+static void tile_monocle(Monitor* mon, Column* col, Client* c)
+{
+    coldims(mon, col, &(c->x), &(c->y), &(c->w), &(c->h));
+    client_move(c, 0, 0);
+    client_resize(c, 0, 0);
+    c->next = col->clients;
+    col->clients = c;
+}
+
+static void tile_expand(Monitor* mon, Column* col, Client* client)
+{
+    (void)mon, (void)col;
+    client->next = col->clients;
+    col->clients = client;
+}
+
+static void tile_stacked(Monitor* mon, Column* col, Client* client)
+{
+    (void)mon, (void)col;
+    client->next = col->clients;
+    col->clients = client;
+}
+
 /* adds a new client to the most appropriate monitor */
 void mons_addclient(Client* c)
 {
@@ -48,7 +100,6 @@ void mons_addclient(Client* c)
     int ptrx = 0, ptry = 0, winx = 0, winy = 0, mask = 0;
     XQueryPointer(X.disp, X.root, &root, &child, &ptrx, &ptry, &winx, &winy, (unsigned int*)&mask);
     Monitor* mon = pickmon(ptrx, ptry);
-    printf("add win to %p\n", mon);
     if (X.mode == M_INIT)
     {
         c->next = mon->cspace->floating;
@@ -57,34 +108,30 @@ void mons_addclient(Client* c)
         int ch = c->h + 2*BORDER_WIDTH + TITLE_HEIGHT;
         c->x = mon->midx - cw/2;
         c->y = mon->midy - ch/2;
+        client_move(c, 0, 0);
+        client_resize(c, 0, 0);
     }
     else
     {
         Column* col = pickcol(mon->cspace->columns, ptrx - mon->x);
-        /*
-        Client* c = find_max(col->clients);
-        if (c)
+        if (col->mode == TILE_MONOCLE)
         {
-            c->next = col->clients;
-            col->clients = c;
+            tile_monocle(mon, col, c);
         }
-        else
+        else if (col->mode == TILE_EXPAND)
         {
-            shrink the window;
-            fill the gap with the new window;
+            tile_expand(mon, col, c);
+        }
+        else if (col->mode == TILE_STACKED)
+        {
+            tile_stacked(mon, col, c);
         }
-        */
-
-        c->next = col->clients;
-        col->clients = c;
-        /* TODO: tile the window approriately */
     }
-    assert(c != c->next);
+    mons_layer(mon);
 }
 
 void mons_delclient(Client* c)
 {
-    assert(c != c->next);
     Location loc = {0};
     if (mons_find(c->win, &loc))
     {
@@ -203,6 +250,31 @@ void mons_towspace(Client* c, int wsid)
     }
 }
 
+void mons_raise(Monitor* mon, Client* c)
+{
+    mon->cspace->floating = delclient(mon->cspace->floating, c);
+    c->next = mon->cspace->floating;
+    mon->cspace->floating = c;
+    mons_layer(mon);
+}
+
+void mons_lower(Monitor* mon, Client* c)
+{
+    mon->cspace->floating = delclient(mon->cspace->floating, c);
+    c->next = NULL;
+    if (mon->cspace->floating)
+    {
+        Client* curr = mon->cspace->floating;
+        for (; curr && curr->next; curr = curr->next);
+        curr->next = c;
+    }
+    else
+    {
+        mon->cspace->floating = c;
+    }
+    mons_layer(mon);
+}
+
 static Monitor* pickmon(int ptrx, int ptry)
 {
     Monitor* mon = Monitors;
@@ -225,22 +297,18 @@ static Column* pickcol(Column* cols, int relx)
     /* otherwise, return the current column */
     if (!col)
     {
-        puts("searching for active col");
+//        puts("searching for active col");
         int left = 0, right = 0;
         for (col = cols; col; col = col->next)
         {
             left = right, right += col->width;
-            printf("%d <= %d < %d\n", left, relx, right);
+//            printf("%d <= %d < %d\n", left, relx, right);
             if (left <= relx && relx < right)
             {
                 break; /* we found the column holding the mouse */
             }
         }
     }
-    else
-    {
-        puts("empty col");
-    }
     assert(col);
     return col;
 }