From b1c0faab896040ec411f0c38a85df1d0ab061f4e Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Thu, 12 Mar 2020 09:56:15 -0400 Subject: [PATCH] added logic to find closest monitor and associate the window with that monitor --- anvil.h | 3 ++- build.sh | 2 +- client.c | 1 + mons.c | 39 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/anvil.h b/anvil.h index ed23540..1097b42 100644 --- a/anvil.h +++ b/anvil.h @@ -38,7 +38,7 @@ typedef struct Workspace { typedef struct Monitor { struct Monitor* next; - int x, y, w, h; + int x, y, w, h, midx, midy; Workspace* wspaces; Workspace* cspace; } Monitor; @@ -61,6 +61,7 @@ void mons_init(void); void mons_addclient(Client* c); void mons_delclient(Client* c); int mons_find(Window win, Location* loc); +void mons_place(Client* c); /* client.c */ extern Client* Focused; diff --git a/build.sh b/build.sh index 6b0dfdc..2b940aa 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ #!/bin/sh -cc -g -Wall -Wextra -Werror -o anvil *.c -lX11 -lXinerama +cc -g -Wall -Wextra -Werror -o anvil *.c -lX11 -lXinerama -lm ctags * grep -n 'TODO' *.c | sed -e 's/: \+/: /' -e 's/\/\* *//g' -e 's/ *\*\/$//' -e 's/TODO: *//' \ No newline at end of file diff --git a/client.c b/client.c index 26c3d9e..557f2ea 100644 --- a/client.c +++ b/client.c @@ -117,6 +117,7 @@ void client_move(Client* c, int xdiff, int ydiff) c->x - BORDER_WIDTH, c->y - TITLE_HEIGHT - BORDER_WIDTH); XSync(X.disp, False); + mons_place(c); } void client_resize(Client* c, int xdiff, int ydiff) diff --git a/mons.c b/mons.c index 8a909b3..0d47a7b 100644 --- a/mons.c +++ b/mons.c @@ -1,4 +1,5 @@ #include "anvil.h" +#include Monitor* Monitors = NULL; @@ -16,6 +17,8 @@ void mons_init(void) m->y = mons[i].y_org; m->w = mons[i].width; m->h = mons[i].height; + m->midx = m->x + m->w/2; + m->midy = m->y + m->h/2; m->next = Monitors; Monitors = m; } @@ -28,7 +31,8 @@ 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; - /* TODO: use size and position to pick the "right" monitor */ + /* now find the best one based on distance to midpoint */ + mons_place(c); } Client* delclient(Client* list, Client* dead) @@ -58,10 +62,9 @@ void mons_delclient(Client* c) int mons_find(Window win, Location* loc) { - Monitor* mons = Monitors; for (Monitor* mon = Monitors; mon; mon = mon->next) { - for (Workspace* wspace = mons->wspaces; wspace; wspace = wspace->next) + for (Workspace* wspace = mon->wspaces; wspace; wspace = wspace->next) { for (Client* client = wspace->floating; client; client = client->next) { @@ -77,3 +80,33 @@ int mons_find(Window win, Location* loc) } return 0; } + +void mons_place(Client* c) +{ + Location loc; + if (mons_find(c->win, &loc)) + { + int mindist = 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) + { + closest = mon; + mindist = dist; + } + } + /* if we changed monitiors, make sure we update accordingly */ + if (loc.monitor != closest) + { + loc.workspace->floating = delclient(loc.workspace->floating, c); + c->next = closest->cspace->floating; + closest->cspace->floating = c; + } + } +} \ No newline at end of file -- 2.52.0