]> git.mdlowis.com Git - proto/anvil.git/commitdiff
reworked monitor detection to use overlap algorithm and reworked focus handling to...
authorMichael D. Lowis <mike.lowis@gentex.com>
Thu, 12 Mar 2020 16:54:36 +0000 (12:54 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Thu, 12 Mar 2020 16:54:36 +0000 (12:54 -0400)
anvil.c
anvil.h
client.c
mons.c

diff --git a/anvil.c b/anvil.c
index 6442aa631c82490bad76e8e76e26bed1538d3140..d7004678ffa2492475d25a485b557589c1118b81 100644 (file)
--- a/anvil.c
+++ b/anvil.c
@@ -158,7 +158,7 @@ static void xexpose(XEvent* e)
         Client* c = client_get(e->xexpose.window);
         if (c)
         {
-            client_draw(c, 0);
+            client_draw(c);
         }
     }
 }
diff --git a/anvil.h b/anvil.h
index 1097b420b208c0e2294498987b883e1d65927a2c..342ad9cee1ea4e35a38ae41aa2cb021e27e027a2 100644 (file)
--- a/anvil.h
+++ b/anvil.h
@@ -5,6 +5,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
+#define min(a,b) (a < b ? a : b)
+#define max(a,b) (a > b ? a : b)
+
 /*
 Management Notes:
     * N monitors
@@ -67,7 +70,7 @@ void mons_place(Client* c);
 extern Client* Focused;
 void client_initall(void);
 Client* client_add(Window win, XWindowAttributes* attr);
-void client_draw(Client* c, int active);
+void client_draw(Client* c);
 Client* client_get(Window w);
 void client_raise(Client* c);
 void client_lower(Client* c);
index 557f2eab25194e40069f20b48633b540622b3218..e961417433d8b163961dc21f734605599380ec43 100644 (file)
--- a/client.c
+++ b/client.c
@@ -61,18 +61,18 @@ Client* client_add(Window win, XWindowAttributes* attr)
     XAddToSaveSet(X.disp, c->win);
     XMapWindow(X.disp, c->frame);
     XMapWindow(X.disp, c->win);
-    client_draw(c, 0);
+    client_draw(c);
 
     /* Set focus and state? */
 
     return c;
 }
 
-void client_draw(Client* c, int active)
+void client_draw(Client* c)
 {
     if (c->frame)
     {
-        XSetWindowBackground(X.disp, c->frame, active ? X.black : X.gray);
+        XSetWindowBackground(X.disp, c->frame, (Focused == c) ? X.black : X.gray);
         XClearWindow(X.disp, c->frame);
 
     //    int quarter = (border + titleHeight()) / 4;
@@ -131,6 +131,7 @@ void client_resize(Client* c, int xdiff, int ydiff)
         c->w + 2*BORDER_WIDTH,
         c->h + 2*BORDER_WIDTH + TITLE_HEIGHT);
     XSync(X.disp, False);
+    mons_place(c);
 }
 
 void client_close(Client* c)
@@ -141,12 +142,13 @@ void client_close(Client* c)
 
 void client_focus(Client* c)
 {
-    if (Focused != NULL)
-    {
-        client_draw(Focused, 0);
-    }
+    Client* prev = Focused;
     Focused = c;
     XSetInputFocus(X.disp, c->win, RevertToPointerRoot, CurrentTime);
-    client_draw(Focused, 1);
+    client_draw(Focused);
+    if (prev)
+    {
+        client_draw(prev);
+    }
     XSync(X.disp, False);
 }
\ No newline at end of file
diff --git a/mons.c b/mons.c
index 0d47a7bbd3e14a4ca1b6a79788bdae4e475a0ad2..ed6cebd4d97f5703421c23d546bd22ff478a206c 100644 (file)
--- a/mons.c
+++ b/mons.c
@@ -31,7 +31,7 @@ void mons_addclient(Client* c)
     /* for now just add it to the first monitor in the list */
     c->next = Monitors->cspace->floating;
     Monitors->cspace->floating = c;
-    /* now find the best one based on distance to midpoint */
+    /* now find the best one */
     mons_place(c);
 }
 
@@ -81,28 +81,36 @@ int mons_find(Window win, Location* loc)
     return 0;
 }
 
+/* find the best monitor to own the window by calculating the overlap */
 void mons_place(Client* c)
 {
     Location loc;
+    int cleft = (c->x - BORDER_WIDTH);
+    int cright = (c->x + c->w + 2*BORDER_WIDTH);
+    int ctop = (c->y - BORDER_WIDTH);
+    int cbot = (c->y + c->h + 2*BORDER_WIDTH + TITLE_HEIGHT);
     if (mons_find(c->win, &loc))
     {
-        int mindist = 0;
+        int maxarea = 0;
         Monitor* closest = NULL;
-        /* find the closest monitor by calculating distance between midpoints */
-        int midx = (c->x - BORDER_WIDTH) + (c->w + 2*BORDER_WIDTH)/2;
-        int midy = (c->y - BORDER_WIDTH - TITLE_HEIGHT) + (c->h + 2*BORDER_WIDTH + TITLE_HEIGHT)/2;
         for (Monitor* mon = Monitors; mon; mon = mon->next)
         {
-            /* dist = sqrt((x2-x1)^2 + (y2-y1)^2) */
-            int dist = sqrt((midx - mon->midx)*(midx - mon->midx) + (midy - mon->midy)*(midy - mon->midy));
-            if (!closest || dist < mindist)
+            int left = max(cleft, mon->x);
+            int right = min(cright, mon->x + mon->w);
+            int top = max(ctop, mon->y);
+            int bot = min(cbot, mon->y + mon->h);
+            if (left < right && top < bot)
             {
-                closest = mon;
-                mindist = dist;
+                int area = (right - left) * (bot - top);
+                if (area > maxarea)
+                {
+                    maxarea = area;
+                    closest = mon;
+                }
             }
         }
         /* if we changed monitiors, make sure we update accordingly */
-        if (loc.monitor != closest)
+        if (closest && loc.monitor != closest)
         {
             loc.workspace->floating = delclient(loc.workspace->floating, c);
             c->next = closest->cspace->floating;