widget: add support for mouse enter and leave events

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-08-25 14:34:56 +02:00
parent b92833274a
commit e871bbfa18
6 changed files with 130 additions and 1 deletions

View File

@ -61,7 +61,7 @@ simplewindow_new(xcb_connection_t *conn, int phys_screen, int x, int y,
| XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW
| XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_STRUCTURE_NOTIFY
| XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE
| XCB_EVENT_MASK_EXPOSURE; | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE;
sw->window = xcb_generate_id(conn); sw->window = xcb_generate_id(conn);
xcb_create_window(conn, s->root_depth, sw->window, s->root, x, y, w, h, xcb_create_window(conn, s->root_depth, sw->window, s->root, x, y, w, h,

View File

@ -35,6 +35,8 @@ layout
left left
line line
machine machine
mouse_enter
mouse_leave
mwfact mwfact
ncol ncol
nmaster nmaster

104
event.c
View File

@ -37,6 +37,7 @@
#include "keygrabber.h" #include "keygrabber.h"
#include "lua.h" #include "lua.h"
#include "systray.h" #include "systray.h"
#include "statusbar.h"
#include "layouts/floating.h" #include "layouts/floating.h"
#include "common/atoms.h" #include "common/atoms.h"
@ -329,6 +330,107 @@ event_handle_destroynotify(void *data __attribute__ ((unused)),
return 0; return 0;
} }
/** Handle a motion notify over widgets.
* \param object The object.
* \param type The object type.
* \param mouse_over The pointer to the registered mouse over widget.
* \param w The new widget the mouse is over.
*/
static void
event_handle_widget_motionnotify(void *object,
awesome_type_t type,
widget_node_t **mouse_over,
widget_node_t *w)
{
if(w != *mouse_over)
{
if(*mouse_over)
{
/* call mouse leave function on old widget */
luaA_pushpointer(globalconf.L, object, type);
luaA_dofunction(globalconf.L, (*mouse_over)->widget->mouse_leave, 1, 0);
}
if(w)
{
/* call mouse enter function on new widget and register it */
*mouse_over = w;
luaA_pushpointer(globalconf.L, object, type);
luaA_dofunction(globalconf.L, w->widget->mouse_enter, 1, 0);
}
}
}
/** The motion notify event handler.
* \param data currently unused.
* \param connection The connection to the X server.
* \param ev The event.
*/
static int
event_handle_motionnotify(void *data __attribute__ ((unused)),
xcb_connection_t *connection,
xcb_motion_notify_event_t *ev)
{
statusbar_t *statusbar = statusbar_getbywin(ev->event);
client_t *c;
widget_node_t *w;
if(statusbar)
{
w = widget_getbycoords(statusbar->position, statusbar->widgets,
statusbar->width, statusbar->height,
ev->event_x, ev->event_y);
event_handle_widget_motionnotify(statusbar,
AWESOME_TYPE_STATUSBAR,
&statusbar->mouse_over, w);
}
else if((c = client_getbytitlebarwin(ev->event)))
{
w = widget_getbycoords(c->titlebar->position, c->titlebar->widgets,
c->titlebar->width, c->titlebar->height,
ev->event_x, ev->event_y);
event_handle_widget_motionnotify(c->titlebar,
AWESOME_TYPE_TITLEBAR,
&c->titlebar->mouse_over, w);
}
return 0;
}
/** The leave notify event handler.
* \param data currently unused.
* \param connection The connection to the X server.
* \param ev The event.
*/
static int
event_handle_leavenotify(void *data __attribute__ ((unused)),
xcb_connection_t *connection,
xcb_leave_notify_event_t *ev)
{
statusbar_t *statusbar = statusbar_getbywin(ev->event);
client_t *c;
if(statusbar)
{
if(statusbar->mouse_over)
{
/* call mouse leave function on widget the mouse was over */
luaA_statusbar_userdata_new(globalconf.L, statusbar);
luaA_dofunction(globalconf.L, statusbar->mouse_over->widget->mouse_leave, 1, 0);
}
}
else if((c = client_getbytitlebarwin(ev->event)))
{
if(c->titlebar->mouse_over)
{
/* call mouse leave function on widget the mouse was over */
luaA_titlebar_userdata_new(globalconf.L, c->titlebar);
luaA_dofunction(globalconf.L, c->titlebar->mouse_over->widget->mouse_leave, 1, 0);
}
}
return 0;
}
/** The enter notify event handler. /** The enter notify event handler.
* \param data currently unused. * \param data currently unused.
* \param connection The connection to the X server. * \param connection The connection to the X server.
@ -705,6 +807,8 @@ void a_xcb_set_event_handlers(void)
xcb_event_set_configure_notify_handler(&globalconf.evenths, event_handle_configurenotify, NULL); xcb_event_set_configure_notify_handler(&globalconf.evenths, event_handle_configurenotify, NULL);
xcb_event_set_destroy_notify_handler(&globalconf.evenths, event_handle_destroynotify, NULL); xcb_event_set_destroy_notify_handler(&globalconf.evenths, event_handle_destroynotify, NULL);
xcb_event_set_enter_notify_handler(&globalconf.evenths, event_handle_enternotify, NULL); xcb_event_set_enter_notify_handler(&globalconf.evenths, event_handle_enternotify, NULL);
xcb_event_set_leave_notify_handler(&globalconf.evenths, event_handle_leavenotify, NULL);
xcb_event_set_motion_notify_handler(&globalconf.evenths, event_handle_motionnotify, NULL);
xcb_event_set_expose_handler(&globalconf.evenths, event_handle_expose, NULL); xcb_event_set_expose_handler(&globalconf.evenths, event_handle_expose, NULL);
xcb_event_set_key_press_handler(&globalconf.evenths, event_handle_keypress, NULL); xcb_event_set_key_press_handler(&globalconf.evenths, event_handle_keypress, NULL);
xcb_event_set_map_request_handler(&globalconf.evenths, event_handle_maprequest, NULL); xcb_event_set_map_request_handler(&globalconf.evenths, event_handle_maprequest, NULL);

View File

@ -606,6 +606,7 @@ luaA_statusbar_widgets(lua_State *L)
{ {
luaA_widget_set(L, 2, *statusbar, &(*statusbar)->widgets); luaA_widget_set(L, 2, *statusbar, &(*statusbar)->widgets);
(*statusbar)->need_update = true; (*statusbar)->need_update = true;
(*statusbar)->mouse_over = NULL;
return 1; return 1;
} }
return luaA_widget_get(L, (*statusbar)->widgets); return luaA_widget_get(L, (*statusbar)->widgets);

View File

@ -108,6 +108,8 @@ struct widget_t
int (*newindex)(lua_State *, awesome_token_t); int (*newindex)(lua_State *, awesome_token_t);
/** Button event handler */ /** Button event handler */
void (*button)(widget_node_t *, xcb_button_press_event_t *, int, void *, awesome_type_t); void (*button)(widget_node_t *, xcb_button_press_event_t *, int, void *, awesome_type_t);
/** Mouse over event handler */
luaA_ref mouse_enter, mouse_leave;
/** Alignement */ /** Alignement */
alignment_t align; alignment_t align;
/** Misc private data */ /** Misc private data */
@ -168,6 +170,8 @@ struct titlebar_t
alignment_t align; alignment_t align;
/** Widgets */ /** Widgets */
widget_node_t *widgets; widget_node_t *widgets;
/** Widget the mouse is over */
widget_node_t *mouse_over;
/** Width and height */ /** Width and height */
int width, height; int width, height;
/** Titlebar window */ /** Titlebar window */
@ -233,6 +237,8 @@ struct statusbar_t
{ {
xcolor_t fg, bg; xcolor_t fg, bg;
} colors; } colors;
/** Widget the mouse is over */
widget_node_t *mouse_over;
/** Next and previous statusbars */ /** Next and previous statusbars */
statusbar_t *prev, *next; statusbar_t *prev, *next;
}; };

View File

@ -292,6 +292,8 @@ luaA_widget_new(lua_State *L)
/* Set visible by default. */ /* Set visible by default. */
w->isvisible = true; w->isvisible = true;
w->mouse_enter = w->mouse_leave = LUA_REFNIL;
w->name = a_strdup(buf); w->name = a_strdup(buf);
return luaA_widget_userdata_new(L, w); return luaA_widget_userdata_new(L, w);
@ -337,6 +339,8 @@ luaA_widget_tostring(lua_State *L)
* \luastack * \luastack
* \lfield visible The widget visibility. * \lfield visible The widget visibility.
* \lfield name The widget name. * \lfield name The widget name.
* \lfield mouse_enter A function to execute when the mouse enter the widget.
* \lfield mouse_leave A function to execute when the mouse leave the widget.
*/ */
static int static int
luaA_widget_index(lua_State *L) luaA_widget_index(lua_State *L)
@ -357,6 +361,12 @@ luaA_widget_index(lua_State *L)
case A_TK_NAME: case A_TK_NAME:
lua_pushstring(L, (*widget)->name); lua_pushstring(L, (*widget)->name);
return 1; return 1;
case A_TK_MOUSE_ENTER:
lua_rawgeti(L, LUA_REGISTRYINDEX, (*widget)->mouse_enter);
return 1;
case A_TK_MOUSE_LEAVE:
lua_rawgeti(L, LUA_REGISTRYINDEX, (*widget)->mouse_leave);
return 1;
default: default:
break; break;
} }
@ -381,6 +391,12 @@ luaA_widget_newindex(lua_State *L)
case A_TK_VISIBLE: case A_TK_VISIBLE:
(*widget)->isvisible = luaA_checkboolean(L, 3); (*widget)->isvisible = luaA_checkboolean(L, 3);
break; break;
case A_TK_MOUSE_ENTER:
luaA_registerfct(L, 3, &(*widget)->mouse_enter);
break;
case A_TK_MOUSE_LEAVE:
luaA_registerfct(L, 3, &(*widget)->mouse_leave);
break;
default: default:
return (*widget)->newindex ? (*widget)->newindex(L, token) : 0; return (*widget)->newindex ? (*widget)->newindex(L, token) : 0;
} }