From: Michael D. Lowis Date: Thu, 12 Mar 2020 16:54:36 +0000 (-0400) Subject: reworked monitor detection to use overlap algorithm and reworked focus handling to... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=4ae2dc7a45d920f1e12e025e40035d9a01217163;p=proto%2Fanvil.git reworked monitor detection to use overlap algorithm and reworked focus handling to fix some corner cases --- diff --git a/anvil.c b/anvil.c index 6442aa6..d700467 100644 --- 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 1097b42..342ad9c 100644 --- a/anvil.h +++ b/anvil.h @@ -5,6 +5,9 @@ #include #include +#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); diff --git a/client.c b/client.c index 557f2ea..e961417 100644 --- 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 0d47a7b..ed6cebd 100644 --- 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;