screen_getbycoord: Change definition of 'closest screen'

Instead of comparing only the top-left corner of the screen to the provided
coordinate, this now compares the screen in a more intuitive way, e.g.
coordinates inside of the screen have a distance of zero.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2015-10-10 20:10:23 +02:00
parent b34a653448
commit d4168f3c36
1 changed files with 38 additions and 7 deletions

View File

@ -35,7 +35,6 @@
#include "objects/client.h" #include "objects/client.h"
#include "objects/drawin.h" #include "objects/drawin.h"
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
@ -285,6 +284,38 @@ screen_scan(void)
screen_scan_x11(); screen_scan_x11();
} }
/** Return the squared distance of the given screen to the coordinates.
* \param screen The screen
* \param x X coordinate
* \param y Y coordinate
* \return Squared distance of the point to the screen.
*/
static unsigned int
screen_get_distance_squared(screen_t *s, int x, int y)
{
int sx = s->geometry.x, sy = s->geometry.y;
int sheight = s->geometry.height, swidth = s->geometry.width;
unsigned int dist_x, dist_y;
/* Calculate distance in X coordinate */
if (x < sx)
dist_x = sx - x;
else if (x < sx + swidth)
dist_x = 0;
else
dist_x = x - sx - swidth;
/* Calculate distance in Y coordinate */
if (y < sy)
dist_y = sy - y;
else if (y < sy + sheight)
dist_y = 0;
else
dist_y = y - sy - sheight;
return dist_x * dist_x + dist_y * dist_y;
}
/** Return the first screen number where the coordinates belong to. /** Return the first screen number where the coordinates belong to.
* \param x X coordinate * \param x X coordinate
* \param y Y coordinate * \param y Y coordinate
@ -299,14 +330,14 @@ screen_getbycoord(int x, int y)
/* No screen found, find nearest screen. */ /* No screen found, find nearest screen. */
screen_t *nearest_screen = globalconf.screens.tab[0]; screen_t *nearest_screen = globalconf.screens.tab[0];
int nearest_dist = INT_MAX; unsigned int nearest_dist = UINT_MAX;
foreach(s, globalconf.screens) foreach(s, globalconf.screens)
{ {
int dist = sqrt(pow((*s)->geometry.x - x, 2) + pow((*s)->geometry.y - y, 2)); unsigned int dist_sq = screen_get_distance_squared(*s, x, y);
if( dist < nearest_dist ) if(dist_sq < nearest_dist)
{ {
nearest_dist = dist; nearest_dist = dist_sq;
nearest_screen = (*s); nearest_screen = *s;
} }
} }
return nearest_screen; return nearest_screen;