mouse: add object_under_pointer
Signed-off-by: Gregor Best <farhaven@googlemail.com> Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
53d7062917
commit
0235d995c2
44
event.c
44
event.c
|
@ -89,50 +89,6 @@ event_handle_mouse_button(client_t *c,
|
|||
}
|
||||
}
|
||||
|
||||
/** Get a widget node from a wibox by coords.
|
||||
* \param Container position.
|
||||
* \param widgets The widget list.
|
||||
* \param width The container width.
|
||||
* \param height The container height.
|
||||
* \param x X coordinate of the widget.
|
||||
* \param y Y coordinate of the widget.
|
||||
* \return A widget.
|
||||
*/
|
||||
static widget_t *
|
||||
widget_getbycoords(position_t position, widget_node_array_t *widgets,
|
||||
int width, int height, int16_t *x, int16_t *y)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
/* Need to transform coordinates like it was top/bottom */
|
||||
switch(position)
|
||||
{
|
||||
case Right:
|
||||
tmp = *y;
|
||||
*y = width - *x;
|
||||
*x = tmp;
|
||||
break;
|
||||
case Left:
|
||||
tmp = *y;
|
||||
*y = *x;
|
||||
*x = height - tmp;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for(int i = 0; i < widgets->len; i++)
|
||||
{
|
||||
widget_node_t *w = &widgets->tab[i];
|
||||
if(w->widget->isvisible &&
|
||||
*x >= w->geometry.x && *x < w->geometry.x + w->geometry.width
|
||||
&& *y >= w->geometry.y && *y < w->geometry.y + w->geometry.height)
|
||||
return w->widget;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Handle an event with mouse grabber if needed
|
||||
* \param x The x coordinate.
|
||||
* \param y The y coordinate.
|
||||
|
|
|
@ -9,6 +9,7 @@ local layout = require("awful.layout")
|
|||
local tag = require("awful.tag")
|
||||
local hooks = require("awful.hooks")
|
||||
local aclient = require("awful.client")
|
||||
local type = type
|
||||
local math = math
|
||||
local ipairs = ipairs
|
||||
local capi =
|
||||
|
@ -24,6 +25,27 @@ module("awful.mouse")
|
|||
|
||||
client = {}
|
||||
|
||||
function client_under_pointer()
|
||||
local obj = capi.mouse.object_under_pointer()
|
||||
if type(obj) == "client" then
|
||||
return obj
|
||||
end
|
||||
end
|
||||
|
||||
function wibox_under_pointer()
|
||||
local obj = capi.mouse.object_under_pointer()
|
||||
if type(obj) == "wibox" then
|
||||
return obj
|
||||
end
|
||||
end
|
||||
|
||||
function widget_under_pointer()
|
||||
local obj, obj2 = capi.mouse.object_under_pointer()
|
||||
if type(obj2) == "widget" then
|
||||
return obj2
|
||||
end
|
||||
end
|
||||
|
||||
local function snap_outside(g, sg, snap)
|
||||
if g.x < snap + sg.x + sg.width and g.x > sg.x + sg.width then
|
||||
g.x = sg.x + sg.width
|
||||
|
@ -119,7 +141,7 @@ function client.move(c, snap)
|
|||
elseif lay ~= layout.suit.magnifier then
|
||||
c.screen = capi.mouse.screen
|
||||
if layout.get(c.screen) ~= layout.suit.floating then
|
||||
local c_u_m = capi.mouse.client_under_pointer()
|
||||
local c_u_m = client_under_pointer()
|
||||
if c_u_m and not aclient.floating.get(c_u_m) then
|
||||
if c_u_m ~= c then
|
||||
c:swap(c_u_m)
|
||||
|
|
71
mouse.c
71
mouse.c
|
@ -24,6 +24,7 @@
|
|||
#include "common/tokenize.h"
|
||||
#include "screen.h"
|
||||
#include "tag.h"
|
||||
#include "wibox.h"
|
||||
#include "common/xcursor.h"
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
@ -47,11 +48,12 @@ button_delete(button_t **button)
|
|||
* \param window The window to get position on.
|
||||
* \param x will be set to the Pointer-x-coordinate relative to window
|
||||
* \param y will be set to the Pointer-y-coordinate relative to window
|
||||
* \param child Will be set to the window under the pointer.
|
||||
* \param mask will be set to the current buttons state
|
||||
* \return true on success, false if an error occured
|
||||
**/
|
||||
bool
|
||||
mouse_query_pointer(xcb_window_t window, int *x, int *y, uint16_t *mask)
|
||||
mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask)
|
||||
{
|
||||
xcb_query_pointer_cookie_t query_ptr_c;
|
||||
xcb_query_pointer_reply_t *query_ptr_r;
|
||||
|
@ -66,6 +68,8 @@ mouse_query_pointer(xcb_window_t window, int *x, int *y, uint16_t *mask)
|
|||
*y = query_ptr_r->win_y;
|
||||
if (mask)
|
||||
*mask = query_ptr_r->mask;
|
||||
if(child)
|
||||
*child = query_ptr_r->child;
|
||||
|
||||
p_delete(&query_ptr_r);
|
||||
|
||||
|
@ -76,11 +80,12 @@ mouse_query_pointer(xcb_window_t window, int *x, int *y, uint16_t *mask)
|
|||
* \param screen This will be set to the screen number the mouse is on.
|
||||
* \param x This will be set to the Pointer-x-coordinate relative to window.
|
||||
* \param y This will be set to the Pointer-y-coordinate relative to window.
|
||||
* \param child This will be set to the window under the pointer.
|
||||
* \param mask This will be set to the current buttons state.
|
||||
* \return True on success, false if an error occured.
|
||||
*/
|
||||
static bool
|
||||
mouse_query_pointer_root(int *s, int *x, int *y, uint16_t *mask)
|
||||
mouse_query_pointer_root(int *s, int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask)
|
||||
{
|
||||
for(int screen = 0;
|
||||
screen < xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
|
||||
|
@ -88,7 +93,7 @@ mouse_query_pointer_root(int *s, int *x, int *y, uint16_t *mask)
|
|||
{
|
||||
xcb_window_t root = xutil_screen_get(globalconf.connection, screen)->root;
|
||||
|
||||
if(mouse_query_pointer(root, x, y, mask))
|
||||
if(mouse_query_pointer(root, x, y, child, mask))
|
||||
{
|
||||
*s = screen;
|
||||
return true;
|
||||
|
@ -324,13 +329,13 @@ luaA_mouse_index(lua_State *L)
|
|||
{
|
||||
size_t len;
|
||||
const char *attr = luaL_checklstring(L, 2, &len);
|
||||
int mouse_x, mouse_y, i;
|
||||
int screen;
|
||||
int16_t mouse_x, mouse_y;
|
||||
int screen, i;
|
||||
|
||||
switch(a_tokenize(attr, len))
|
||||
{
|
||||
case A_TK_SCREEN:
|
||||
if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, NULL))
|
||||
if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, NULL, NULL))
|
||||
return 0;
|
||||
|
||||
i = screen_getbycoord(screen, mouse_x, mouse_y);
|
||||
|
@ -421,7 +426,8 @@ static int
|
|||
luaA_mouse_coords(lua_State *L)
|
||||
{
|
||||
uint16_t mask;
|
||||
int screen, x, y, mouse_x, mouse_y;
|
||||
int screen, x, y;
|
||||
int16_t mouse_x, mouse_y;
|
||||
|
||||
if(lua_gettop(L) == 1)
|
||||
{
|
||||
|
@ -429,7 +435,7 @@ luaA_mouse_coords(lua_State *L)
|
|||
|
||||
luaA_checktable(L, 1);
|
||||
|
||||
if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, &mask))
|
||||
if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, NULL, &mask))
|
||||
return 0;
|
||||
|
||||
x = luaA_getopt_number(L, 1, "x", mouse_x);
|
||||
|
@ -440,7 +446,7 @@ luaA_mouse_coords(lua_State *L)
|
|||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, &mask))
|
||||
if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, NULL, &mask))
|
||||
return 0;
|
||||
|
||||
return luaA_mouse_pushstatus(L, mouse_x, mouse_y, mask);
|
||||
|
@ -453,30 +459,39 @@ luaA_mouse_coords(lua_State *L)
|
|||
* \lreturn A client or nil.
|
||||
*/
|
||||
static int
|
||||
luaA_mouse_client_under_pointer(lua_State *L)
|
||||
luaA_mouse_object_under_pointer(lua_State *L)
|
||||
{
|
||||
for(int screen = 0;
|
||||
screen < xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
|
||||
screen++)
|
||||
{
|
||||
xcb_window_t root = xutil_screen_get(globalconf.connection, screen)->root;
|
||||
xcb_query_pointer_reply_t *query_ptr_r;
|
||||
xcb_query_pointer_cookie_t query_ptr_c = xcb_query_pointer_unchecked(globalconf.connection, root);
|
||||
query_ptr_r = xcb_query_pointer_reply(globalconf.connection, query_ptr_c, NULL);
|
||||
int screen;
|
||||
int16_t mouse_x, mouse_y;
|
||||
xcb_window_t child;
|
||||
|
||||
if(query_ptr_r)
|
||||
if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, &child, NULL))
|
||||
return 0;
|
||||
|
||||
wibox_t *wibox;
|
||||
client_t *client;
|
||||
if((wibox = wibox_getbywin(child)))
|
||||
{
|
||||
client_t *c = client_getbywin(query_ptr_r->child);
|
||||
p_delete(&query_ptr_r);
|
||||
if(c)
|
||||
return luaA_client_userdata_new(L, c);
|
||||
else
|
||||
luaA_wibox_userdata_new(L, wibox);
|
||||
|
||||
int16_t x = mouse_x - wibox->sw.geometry.x;
|
||||
int16_t y = mouse_y - wibox->sw.geometry.y;
|
||||
|
||||
widget_t *widget = widget_getbycoords(wibox->position, &wibox->widgets,
|
||||
wibox->sw.geometry.width,
|
||||
wibox->sw.geometry.height,
|
||||
&x, &y);
|
||||
|
||||
if(widget)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
luaA_widget_userdata_new(L, widget);
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((client = client_getbywin(child)))
|
||||
return luaA_client_userdata_new(L, client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -485,7 +500,7 @@ const struct luaL_reg awesome_mouse_methods[] =
|
|||
{ "__index", luaA_mouse_index },
|
||||
{ "__newindex", luaA_mouse_newindex },
|
||||
{ "coords", luaA_mouse_coords },
|
||||
{ "client_under_pointer", luaA_mouse_client_under_pointer },
|
||||
{ "object_under_pointer", luaA_mouse_object_under_pointer },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
const struct luaL_reg awesome_mouse_meta[] =
|
||||
|
|
2
mouse.h
2
mouse.h
|
@ -41,7 +41,7 @@ struct button_t
|
|||
|
||||
void button_delete(button_t **);
|
||||
|
||||
bool mouse_query_pointer(xcb_window_t, int *, int *, uint16_t *);
|
||||
bool mouse_query_pointer(xcb_window_t, int16_t *, int16_t *, xcb_window_t *, uint16_t *);
|
||||
int luaA_mouse_pushstatus(lua_State *, int, int, uint16_t);
|
||||
|
||||
DO_RCNT(button_t, button, button_delete)
|
||||
|
|
|
@ -40,11 +40,11 @@ mousegrabber_grab(xcb_cursor_t cursor)
|
|||
screen < xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
|
||||
screen++)
|
||||
{
|
||||
int x, y;
|
||||
int16_t x, y;
|
||||
uint16_t mask;
|
||||
|
||||
root = xutil_screen_get(globalconf.connection, screen)->root;
|
||||
if(mouse_query_pointer(root, &x, &y, &mask))
|
||||
if(mouse_query_pointer(root, &x, &y, NULL, &mask))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
44
widget.c
44
widget.c
|
@ -69,6 +69,50 @@ widget_calculate_offset(int barwidth, int widgetwidth, int offset, int alignment
|
|||
return barwidth - offset - widgetwidth;
|
||||
}
|
||||
|
||||
|
||||
/** Get a widget node from a wibox by coords.
|
||||
* \param Container position.
|
||||
* \param widgets The widget list.
|
||||
* \param width The container width.
|
||||
* \param height The container height.
|
||||
* \param x X coordinate of the widget.
|
||||
* \param y Y coordinate of the widget.
|
||||
* \return A widget.
|
||||
*/
|
||||
widget_t *
|
||||
widget_getbycoords(position_t position, widget_node_array_t *widgets,
|
||||
int width, int height, int16_t *x, int16_t *y)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
/* Need to transform coordinates like it was top/bottom */
|
||||
switch(position)
|
||||
{
|
||||
case Right:
|
||||
tmp = *y;
|
||||
*y = width - *x;
|
||||
*x = tmp;
|
||||
break;
|
||||
case Left:
|
||||
tmp = *y;
|
||||
*y = *x;
|
||||
*x = height - tmp;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for(int i = 0; i < widgets->len; i++)
|
||||
{
|
||||
widget_node_t *w = &widgets->tab[i];
|
||||
if(w->widget->isvisible &&
|
||||
*x >= w->geometry.x && *x < w->geometry.x + w->geometry.width
|
||||
&& *y >= w->geometry.y && *y < w->geometry.y + w->geometry.height)
|
||||
return w->widget;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Convert a Lua table to a list of widget nodet.
|
||||
* \param L The Lua VM state.
|
||||
* \param widgets The linked list of widget node.
|
||||
|
|
1
widget.h
1
widget.h
|
@ -37,6 +37,7 @@ void widget_delete(widget_t **);
|
|||
DO_RCNT(widget_t, widget, widget_delete)
|
||||
|
||||
int widget_calculate_offset(int, int, int, int);
|
||||
widget_t *widget_getbycoords(position_t, widget_node_array_t *, int, int, int16_t *, int16_t *);
|
||||
void widget_render(widget_node_array_t *, draw_context_t *, xcb_gcontext_t, xcb_drawable_t, int, orientation_t, int, int, wibox_t *);
|
||||
|
||||
int luaA_widget_userdata_new(lua_State *, widget_t *);
|
||||
|
|
Loading…
Reference in New Issue