Merge pull request #507 from psychon/closest_screen
Update the definition of "closest screen" to take into account that a screen is a rectangle and not just the top-left corner. Closes https://github.com/awesomeWM/awesome/pull/507.
This commit is contained in:
commit
872c321e81
|
@ -26,24 +26,42 @@ data.padding = {}
|
||||||
|
|
||||||
screen.mouse_per_screen = {}
|
screen.mouse_per_screen = {}
|
||||||
|
|
||||||
|
-- @param s Screen number
|
||||||
|
-- @param x X coordinate of point
|
||||||
|
-- @param y Y coordinate of point
|
||||||
|
-- @return The squared distance of the screen to the provided point
|
||||||
|
function screen.getdistance_sq(s, x, y)
|
||||||
|
local geom = capi.screen[s].geometry
|
||||||
|
local dist_x, dist_y = 0, 0
|
||||||
|
if x < geom.x then
|
||||||
|
dist_x = geom.x - x
|
||||||
|
elseif x >= geom.x + geom.width then
|
||||||
|
dist_x = x - geom.x - geom.width
|
||||||
|
end
|
||||||
|
if y < geom.y then
|
||||||
|
dist_y = geom.y - y
|
||||||
|
elseif y >= geom.y + geom.height then
|
||||||
|
dist_y = y - geom.y - geom.height
|
||||||
|
end
|
||||||
|
return dist_x * dist_x + dist_y * dist_y
|
||||||
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Return Xinerama screen number corresponding to the given (pixel) coordinates.
|
-- Return Xinerama screen number corresponding to the given (pixel) coordinates.
|
||||||
-- The number returned can be used as an index into the global
|
-- The number returned can be used as an index into the global
|
||||||
-- `screen` table/object.
|
-- `screen` table/object.
|
||||||
-- @param x The x coordinate
|
-- @param x The x coordinate
|
||||||
-- @param y The y coordinate
|
-- @param y The y coordinate
|
||||||
-- @param[opt] default The default return value. If unspecified, 1 is returned.
|
function screen.getbycoord(x, y)
|
||||||
function screen.getbycoord(x, y, default)
|
local s = 1
|
||||||
for i = 1, capi.screen:count() do
|
local dist = screen.getdistance_sq(s, x, y)
|
||||||
local geometry = capi.screen[i].geometry
|
for i = 2, capi.screen:count() do
|
||||||
if((x < 0 or (x >= geometry.x and x < geometry.x + geometry.width))
|
local d = screen.getdistance_sq(i, x, y)
|
||||||
and (y < 0 or (y >= geometry.y and y < geometry.y + geometry.height))) then
|
if d < dist then
|
||||||
return i
|
s, dist = i, d
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- No caller expects a nil result here, so just make something up
|
return s
|
||||||
if default == nil then return 1 end
|
|
||||||
return default
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Give the focus to a screen, and move pointer to last known position on this
|
--- Give the focus to a screen, and move pointer to last known position on this
|
||||||
|
|
|
@ -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
|
||||||
|
@ -298,15 +329,15 @@ screen_getbycoord(int x, int y)
|
||||||
return *s;
|
return *s;
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
Loading…
Reference in New Issue