From 0235d995c2c5c624f87d5dd42e976320fc1a1b8c Mon Sep 17 00:00:00 2001 From: Gregor Best Date: Wed, 3 Dec 2008 23:03:44 +0100 Subject: [PATCH] mouse: add object_under_pointer Signed-off-by: Gregor Best Signed-off-by: Julien Danjou --- event.c | 44 ------------------------- lib/awful/mouse.lua.in | 24 +++++++++++++- mouse.c | 73 +++++++++++++++++++++++++----------------- mouse.h | 2 +- mousegrabber.c | 4 +-- widget.c | 44 +++++++++++++++++++++++++ widget.h | 1 + 7 files changed, 115 insertions(+), 77 deletions(-) diff --git a/event.c b/event.c index bdab60d91..4f69c8077 100644 --- a/event.c +++ b/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. diff --git a/lib/awful/mouse.lua.in b/lib/awful/mouse.lua.in index 217f90831..d8404101c 100644 --- a/lib/awful/mouse.lua.in +++ b/lib/awful/mouse.lua.in @@ -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) diff --git a/mouse.c b/mouse.c index 9afb027e9..636577947 100644 --- a/mouse.c +++ b/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))) + { + 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) { - client_t *c = client_getbywin(query_ptr_r->child); - p_delete(&query_ptr_r); - if(c) - return luaA_client_userdata_new(L, c); - else - { - lua_pushnil(L); - return 1; - } + 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[] = diff --git a/mouse.h b/mouse.h index 285e7d1ac..639c2dd0e 100644 --- a/mouse.h +++ b/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) diff --git a/mousegrabber.c b/mousegrabber.c index f392662f7..2ebf8716e 100644 --- a/mousegrabber.c +++ b/mousegrabber.c @@ -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; } diff --git a/widget.c b/widget.c index 4fa677fc1..a2d7534a8 100644 --- a/widget.c +++ b/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. diff --git a/widget.h b/widget.h index 58c423bb0..768d75afb 100644 --- a/widget.h +++ b/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 *);