mouse: make button bindings objects

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-06-13 15:35:47 +02:00
parent 03516eee22
commit 1142c382f7
9 changed files with 145 additions and 114 deletions

View File

@ -72,19 +72,19 @@ end
-- {{{ Statusbar -- {{{ Statusbar
-- Create a taglist widget -- Create a taglist widget
mytaglist = widget.new({ type = "taglist", name = "mytaglist" }) mytaglist = widget.new({ type = "taglist", name = "mytaglist" })
mytaglist:mouse({}, 1, function (object, tag) awful.tag.viewonly(tag) end) mytaglist:mouse_add(mouse.new({}, 1, function (object, tag) awful.tag.viewonly(tag) end))
mytaglist:mouse({ modkey }, 1, function (object, tag) awful.client.movetotag(tag) end) mytaglist:mouse_add(mouse.new({ modkey }, 1, function (object, tag) awful.client.movetotag(tag) end))
mytaglist:mouse({}, 3, function (object, tag) tag:view(not tag:isselected()) end) mytaglist:mouse_add(mouse.new({}, 3, function (object, tag) tag:view(not tag:isselected()) end))
mytaglist:mouse({ modkey }, 3, function (object, tag) awful.client.toggletag(tag) end) mytaglist:mouse_add(mouse.new({ modkey }, 3, function (object, tag) awful.client.toggletag(tag) end))
mytaglist:mouse({ }, 4, awful.tag.viewnext) mytaglist:mouse_add(mouse.new({ }, 4, awful.tag.viewnext))
mytaglist:mouse({ }, 5, awful.tag.viewprev) mytaglist:mouse_add(mouse.new({ }, 5, awful.tag.viewprev))
mytaglist:set("text_focus", "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> ") mytaglist:set("text_focus", "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> ")
-- Create a tasklist widget -- Create a tasklist widget
mytasklist = widget.new({ type = "tasklist", name = "mytasklist" }) mytasklist = widget.new({ type = "tasklist", name = "mytasklist" })
mytasklist:mouse({ }, 1, function (object, c) c:focus_set(); c:raise() end) mytasklist:mouse_add(mouse.new({ }, 1, function (object, c) c:focus_set(); c:raise() end))
mytasklist:mouse({ }, 4, function () awful.client.focus(1) end) mytasklist:mouse_add(mouse.new({ }, 4, function () awful.client.focus(1) end))
mytasklist:mouse({ }, 5, function () awful.client.focus(-1) end) mytasklist:mouse_add(mouse.new({ }, 5, function () awful.client.focus(-1) end))
mytasklist:set("text_focus", "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> ") mytasklist:set("text_focus", "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> ")
-- Create a textbox widget -- Create a textbox widget
@ -102,10 +102,10 @@ myiconbox:set("image", "@iconsdir@/awesome16.png")
mylayoutbox = {} mylayoutbox = {}
for s = 1, screen.count() do for s = 1, screen.count() do
mylayoutbox[s] = widget.new({ type = "iconbox", name = "myiconbox", align = "right" }) mylayoutbox[s] = widget.new({ type = "iconbox", name = "myiconbox", align = "right" })
mylayoutbox[s]:mouse({ }, 1, function () awful.layout.inc(layouts, 1) end) mylayoutbox[s]:mouse_add(mouse.new({ }, 1, function () awful.layout.inc(layouts, 1) end))
mylayoutbox[s]:mouse({ }, 3, function () awful.layout.inc(layouts, -1) end) mylayoutbox[s]:mouse_add(mouse.new({ }, 3, function () awful.layout.inc(layouts, -1) end))
mylayoutbox[s]:mouse({ }, 4, function () awful.layout.inc(layouts, 1) end) mylayoutbox[s]:mouse_add(mouse.new({ }, 4, function () awful.layout.inc(layouts, 1) end))
mylayoutbox[s]:mouse({ }, 5, function () awful.layout.inc(layouts, -1) end) mylayoutbox[s]:mouse_add(mouse.new({ }, 5, function () awful.layout.inc(layouts, -1) end))
mylayoutbox[s]:set("image", "@iconsdir@/layouts/tilew.png") mylayoutbox[s]:set("image", "@iconsdir@/layouts/tilew.png")
end end
@ -125,12 +125,9 @@ end
-- }}} -- }}}
-- {{{ Mouse bindings -- {{{ Mouse bindings
awesome.mouse({ }, 3, function () awful.spawn(terminal) end) awesome.mouse_add(mouse.new({ }, 3, function () awful.spawn(terminal) end))
awesome.mouse({ }, 4, awful.tag.viewnext) awesome.mouse_add(mouse.new({ }, 4, awful.tag.viewnext))
awesome.mouse({ }, 5, awful.tag.viewprev) awesome.mouse_add(mouse.new({ }, 5, awful.tag.viewprev))
client.mouse({ }, 1, function (c) c:focus_set(); c:raise() end)
client.mouse({ modkey }, 1, function (c) c:mouse_move() end)
client.mouse({ modkey }, 3, function (c) c:mouse_resize() end)
-- }}} -- }}}
-- {{{ Key bindings -- {{{ Key bindings
@ -301,6 +298,10 @@ end
-- Hook function to execute when a new client appears. -- Hook function to execute when a new client appears.
function hook_manage(c) function hook_manage(c)
-- Add mouse bindings
c:mouse_add(mouse.new({ }, 1, function (c) c:focus_set(); c:raise() end))
c:mouse_add(mouse.new({ modkey }, 1, function (c) c:mouse_move() end))
c:mouse_add(mouse.new({ modkey }, 3, function (c) c:mouse_resize() end))
-- New client may not receive focus -- New client may not receive focus
-- if they're not focusable, so set border anyway. -- if they're not focusable, so set border anyway.
c:border_set({ width = border_width, color = border_normal }) c:border_set({ width = border_width, color = border_normal })

View File

@ -256,7 +256,7 @@ client_focus(client_t *c, int screen)
c->win, XCB_CURRENT_TIME); c->win, XCB_CURRENT_TIME);
/* since we're dropping EnterWindow events and sometimes the window /* since we're dropping EnterWindow events and sometimes the window
* will appear under the mouse, grabbuttons */ * will appear under the mouse, grabbuttons */
window_grabbuttons(c->win, c->phys_screen); window_grabbuttons(c->win, c->phys_screen, c->buttons);
phys_screen = c->phys_screen; phys_screen = c->phys_screen;
/* Some layouts use focused client differently, so call them back. */ /* Some layouts use focused client differently, so call them back. */
@ -855,37 +855,32 @@ luaA_client_get(lua_State *L)
/** Add mouse bindings over clients's window. /** Add mouse bindings over clients's window.
* \param L The Lua VM state. * \param L The Lua VM state.
* \luastack * \luastack
* \lparam A table with modifier keys. * \lvalue A client.
* \lparam A mouse button number * \lparam A button binding.
* \lparam A function to execute.
*/ */
static int static int
luaA_client_mouse(lua_State *L) luaA_client_mouse_add(lua_State *L)
{ {
size_t i, len; client_t **c = luaA_checkudata(L, 1, "client");
int b; button_t **b = luaA_checkudata(L, 2, "mouse");
button_t *button; button_list_push(&(*c)->buttons, *b);
button_ref(b);
/* arg 1 is modkey table */ return 0;
luaA_checktable(L, 1); }
/* arg 2 is mouse button */
b = luaL_checknumber(L, 2);
/* arg 3 is cmd to run */
luaA_checkfunction(L, 3);
button = p_new(button_t, 1);
button->button = xutil_button_fromint(b);
button->fct = luaL_ref(L, LUA_REGISTRYINDEX);
len = lua_objlen(L, 1);
for(i = 1; i <= len; i++)
{
lua_rawgeti(L, 1, i);
button->mod |= xutil_keymask_fromstr(luaL_checkstring(L, -1));
}
button_list_push(&globalconf.buttons.client, button);
/** Remove mouse bindings over clients's window.
* \param L The Lua VM state.
* \luastack
* \lvalue A client.
* \lparam A button binding.
*/
static int
luaA_client_mouse_remove(lua_State *L)
{
client_t **c = luaA_checkudata(L, 1, "client");
button_t **b = luaA_checkudata(L, 1, "mouse");
button_list_detach(&(*c)->buttons, *b);
button_unref(b);
return 0; return 0;
} }
@ -1440,7 +1435,6 @@ const struct luaL_reg awesome_client_methods[] =
{ "get", luaA_client_get }, { "get", luaA_client_get },
{ "focus_get", luaA_client_focus_get }, { "focus_get", luaA_client_focus_get },
{ "visible_get", luaA_client_visible_get }, { "visible_get", luaA_client_visible_get },
{ "mouse", luaA_client_mouse },
{ NULL, NULL } { NULL, NULL }
}; };
const struct luaL_reg awesome_client_meta[] = const struct luaL_reg awesome_client_meta[] =
@ -1472,6 +1466,8 @@ const struct luaL_reg awesome_client_meta[] =
{ "hide", luaA_client_hide }, { "hide", luaA_client_hide },
{ "unhide", luaA_client_unhide }, { "unhide", luaA_client_unhide },
{ "ishidden", luaA_client_ishidden }, { "ishidden", luaA_client_ishidden },
{ "mouse_add", luaA_client_mouse_add },
{ "mouse_remove", luaA_client_mouse_remove },
{ "__eq", luaA_client_eq }, { "__eq", luaA_client_eq },
{ "__tostring", luaA_client_tostring }, { "__tostring", luaA_client_tostring },
{ NULL, NULL } { NULL, NULL }

View File

@ -156,7 +156,7 @@ event_handle_buttonpress(void *data __attribute__ ((unused)),
if((c = client_getbywin(ev->event))) if((c = client_getbywin(ev->event)))
{ {
event_handle_mouse_button_press(c, ev->detail, ev->state, globalconf.buttons.client); event_handle_mouse_button_press(c, ev->detail, ev->state, c->buttons);
xcb_allow_events(globalconf.connection, XCB_ALLOW_REPLAY_POINTER, XCB_CURRENT_TIME); xcb_allow_events(globalconf.connection, XCB_ALLOW_REPLAY_POINTER, XCB_CURRENT_TIME);
} }
else else
@ -321,7 +321,7 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
if((c = client_getbytitlebarwin(ev->event)) if((c = client_getbytitlebarwin(ev->event))
|| (c = client_getbywin(ev->event))) || (c = client_getbywin(ev->event)))
{ {
window_grabbuttons(c->win, c->phys_screen); window_grabbuttons(c->win, c->phys_screen, c->buttons);
/* the idea behind saving pointer_x and pointer_y is Bob Marley powered /* the idea behind saving pointer_x and pointer_y is Bob Marley powered
* this will allow us top drop some EnterNotify events and thus not giving * this will allow us top drop some EnterNotify events and thus not giving
* focus to windows appering under the cursor without a cursor move */ * focus to windows appering under the cursor without a cursor move */

46
lua.c
View File

@ -44,8 +44,9 @@ extern awesome_t globalconf;
extern bool running; extern bool running;
extern const name_func_link_t FloatingPlacementList[]; extern const name_func_link_t FloatingPlacementList[];
extern const struct luaL_reg awesome_mouse_lib[];
extern const struct luaL_reg awesome_keygrabber_lib[]; extern const struct luaL_reg awesome_keygrabber_lib[];
extern const struct luaL_reg awesome_mouse_methods[];
extern const struct luaL_reg awesome_mouse_meta[];
extern const struct luaL_reg awesome_client_methods[]; extern const struct luaL_reg awesome_client_methods[];
extern const struct luaL_reg awesome_client_meta[]; extern const struct luaL_reg awesome_client_meta[];
extern const struct luaL_reg awesome_titlebar_methods[]; extern const struct luaL_reg awesome_titlebar_methods[];
@ -59,43 +60,22 @@ extern const struct luaL_reg awesome_statusbar_meta[];
extern const struct luaL_reg awesome_keybinding_methods[]; extern const struct luaL_reg awesome_keybinding_methods[];
extern const struct luaL_reg awesome_keybinding_meta[]; extern const struct luaL_reg awesome_keybinding_meta[];
/** Define a global mouse binding. This binding will be available when you'll /** Add a global mouse binding. This binding will be available when you'll
* click on root window. * click on root window.
* \param L The Lua VM state. * \param L The Lua VM state.
* *
* \luastack * \luastack
* \lparam A table with modifiers keys. * \lparam A mouse button binding.
* \lparam A mouse button number.
* \lparam A function to execute.
*/ */
static int static int
luaA_mouse(lua_State *L) luaA_mouse_add(lua_State *L)
{ {
size_t i, len; button_t **button = luaA_checkudata(L, 1, "mouse");
int b;
button_t *button;
/* arg 1 is modkey table */ button_list_push(&globalconf.buttons.root, *button);
luaA_checktable(L, 1); button_ref(button);
/* arg 2 is mouse button */
b = luaL_checknumber(L, 2);
/* arg 3 is cmd to run */
luaA_checkfunction(L, 3);
button = p_new(button_t, 1); window_root_grabbutton(*button);
button->button = xutil_button_fromint(b);
button->fct = luaL_ref(L, LUA_REGISTRYINDEX);
len = lua_objlen(L, 1);
for(i = 1; i <= len; i++)
{
lua_rawgeti(L, 1, i);
button->mod |= xutil_keymask_fromstr(luaL_checkstring(L, -1));
}
button_list_push(&globalconf.buttons.root, button);
window_root_grabbutton(button);
return 0; return 0;
} }
@ -486,7 +466,7 @@ luaA_init(void)
{ "restart", luaA_restart }, { "restart", luaA_restart },
{ "floating_placement_set", luaA_floating_placement_set }, { "floating_placement_set", luaA_floating_placement_set },
{ "padding_set", luaA_padding_set }, { "padding_set", luaA_padding_set },
{ "mouse", luaA_mouse }, { "mouse_add", luaA_mouse_add },
{ "resizehints_set", luaA_resizehints_set }, { "resizehints_set", luaA_resizehints_set },
{ "font_set", luaA_font_set }, { "font_set", luaA_font_set },
{ "colors_set", luaA_colors_set }, { "colors_set", luaA_colors_set },
@ -526,12 +506,12 @@ luaA_init(void)
/* Export hooks lib */ /* Export hooks lib */
luaL_register(L, "hooks", awesome_hooks_lib); luaL_register(L, "hooks", awesome_hooks_lib);
/* Export mouses lib */
luaL_register(L, "mouse", awesome_mouse_lib);
/* Export keygrabber lib */ /* Export keygrabber lib */
luaL_register(L, "keygrabber", awesome_keygrabber_lib); luaL_register(L, "keygrabber", awesome_keygrabber_lib);
/* Export mouse */
luaA_openlib(L, "mouse", awesome_mouse_methods, awesome_mouse_meta);
/* Export tag */ /* Export tag */
luaA_openlib(L, "tag", awesome_tag_methods, awesome_tag_meta); luaA_openlib(L, "tag", awesome_tag_methods, awesome_tag_meta);

53
mouse.c
View File

@ -828,11 +828,62 @@ luaA_mouse_screen_get(lua_State *L)
return 1; return 1;
} }
const struct luaL_reg awesome_mouse_lib[] = /** Create a new mouse userdata.
* \param t The mouse.
*/
static int
luaA_mouse_userdata_new(button_t *bt)
{ {
button_t **b = lua_newuserdata(globalconf.L, sizeof(button_t *));
*b = bt;
button_ref(b);
return luaA_settype(globalconf.L, "mouse");
}
/** Create a new mouse button bindings.
* \param L The Lua VM state.
* \luastack
* \lparam A table with modifiers keys.
* \lparam A mouse button number.
* \lparam A function to execute on click events.
* \lreturn A mouse button binding.
*/
static int
luaA_mouse_new(lua_State *L)
{
int i, len;
button_t *button;
luaA_checktable(L, 1);
/* arg 3 is mouse button */
i = luaL_checknumber(L, 2);
/* arg 4 is cmd to run */
luaA_checkfunction(L, 3);
button = p_new(button_t, 1);
button->button = xutil_button_fromint(i);
button->fct = luaL_ref(L, LUA_REGISTRYINDEX);
len = lua_objlen(L, 1);
for(i = 1; i <= len; i++)
{
lua_rawgeti(L, 1, i);
button->mod |= xutil_keymask_fromstr(luaL_checkstring(L, -1));
}
return luaA_mouse_userdata_new(button);
}
const struct luaL_reg awesome_mouse_methods[] =
{
{ "new", luaA_mouse_new },
{ "screen_get", luaA_mouse_screen_get }, { "screen_get", luaA_mouse_screen_get },
{ "coords_set", luaA_mouse_coords_set }, { "coords_set", luaA_mouse_coords_set },
{ NULL, NULL } { NULL, NULL }
}; };
const struct luaL_reg awesome_mouse_meta[] =
{
{ NULL, NULL }
};
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -80,6 +80,8 @@ typedef enum
/** Mouse buttons bindings */ /** Mouse buttons bindings */
struct button_t struct button_t
{ {
/** Ref count */
int refcount;
/** Key modifiers */ /** Key modifiers */
unsigned long mod; unsigned long mod;
/** Mouse button number */ /** Mouse button number */
@ -91,6 +93,7 @@ struct button_t
}; };
DO_SLIST(button_t, button, p_delete) DO_SLIST(button_t, button, p_delete)
DO_RCNT(button_t, button, p_delete)
/** Widget */ /** Widget */
struct widget_t struct widget_t
@ -291,6 +294,8 @@ struct client_t
char *icon_path; char *icon_path;
/** Titlebar */ /** Titlebar */
titlebar_t *titlebar; titlebar_t *titlebar;
/** Button bindings */
button_t *buttons;
/** Next and previous clients */ /** Next and previous clients */
client_t *prev, *next; client_t *prev, *next;
}; };
@ -381,7 +386,6 @@ struct awesome_t
struct struct
{ {
button_t *root; button_t *root;
button_t *client;
} buttons; } buttons;
/** Numlock mask */ /** Numlock mask */
unsigned int numlockmask; unsigned int numlockmask;

View File

@ -350,39 +350,37 @@ luaA_widget_new(lua_State *L)
* *
* \luastack * \luastack
* \lvalue A widget. * \lvalue A widget.
* \lparam A table containing modifiers keys. * \lvalue A mouse button bindings object.
* \lparam A button number.
* \lparam A function to execute. Some widgets may pass arguments to this
* function. * function.
*/ */
static int static int
luaA_widget_mouse(lua_State *L) luaA_widget_mouse_add(lua_State *L)
{ {
size_t i, len;
/* arg 1 is object */
widget_t **widget = luaA_checkudata(L, 1, "widget"); widget_t **widget = luaA_checkudata(L, 1, "widget");
int b; button_t **b = luaA_checkudata(L, 2, "mouse");
button_t *button;
/* arg 2 is modkey table */ button_list_push(&(*widget)->buttons, *b);
luaA_checktable(L, 2); button_ref(b);
/* arg 3 is mouse button */
b = luaL_checknumber(L, 3);
/* arg 4 is cmd to run */
luaA_checkfunction(L, 4);
button = p_new(button_t, 1); return 0;
button->button = xutil_button_fromint(b); }
button->fct = luaL_ref(L, LUA_REGISTRYINDEX);
len = lua_objlen(L, 2); /** Remove a mouse button bindings from a widget.
for(i = 1; i <= len; i++) * \param L The Lua VM state.
{ *
lua_rawgeti(L, 2, i); * \luastack
button->mod |= xutil_keymask_fromstr(luaL_checkstring(L, -1)); * \lvalue A widget.
} * \lvalue A mouse button bindings object.
* function.
*/
static int
luaA_widget_mouse_remove(lua_State *L)
{
widget_t **widget = luaA_checkudata(L, 1, "widget");
button_t **b = luaA_checkudata(L, 2, "mouse");
button_list_push(&(*widget)->buttons, button); button_list_detach(&(*widget)->buttons, *b);
button_unref(b);
return 0; return 0;
} }
@ -565,7 +563,8 @@ const struct luaL_reg awesome_widget_methods[] =
}; };
const struct luaL_reg awesome_widget_meta[] = const struct luaL_reg awesome_widget_meta[] =
{ {
{ "mouse", luaA_widget_mouse }, { "mouse_add", luaA_widget_mouse_add },
{ "mouse_remove", luaA_widget_mouse_remove },
{ "set", luaA_widget_set }, { "set", luaA_widget_set },
{ "name_set", luaA_widget_name_set }, { "name_set", luaA_widget_name_set },
{ "name_get", luaA_widget_name_get }, { "name_get", luaA_widget_name_get },

View File

@ -110,11 +110,11 @@ window_configure(xcb_window_t win, area_t geometry, int border)
* \param phys_screen Physical screen number. * \param phys_screen Physical screen number.
*/ */
void void
window_grabbuttons(xcb_window_t win, int phys_screen) window_grabbuttons(xcb_window_t win, int phys_screen, button_t *buttons)
{ {
button_t *b; button_t *b;
for(b = globalconf.buttons.client; b; b = b->next) for(b = buttons; b; b = b->next)
{ {
xcb_grab_button(globalconf.connection, false, win, BUTTONMASK, xcb_grab_button(globalconf.connection, false, win, BUTTONMASK,
XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE,

View File

@ -22,12 +22,12 @@
#ifndef AWESOME_WINDOW_H #ifndef AWESOME_WINDOW_H
#define AWESOME_WINDOW_H #define AWESOME_WINDOW_H
#include "common/draw.h" #include "structs.h"
void window_setstate(xcb_window_t, long); void window_setstate(xcb_window_t, long);
long window_getstate(xcb_window_t); long window_getstate(xcb_window_t);
void window_configure(xcb_window_t, area_t, int); void window_configure(xcb_window_t, area_t, int);
void window_grabbuttons(xcb_window_t, int); void window_grabbuttons(xcb_window_t, int, button_t *);
void window_root_grabbutton(button_t *); void window_root_grabbutton(button_t *);
void window_root_grabbuttons(void); void window_root_grabbuttons(void);
void window_root_grabkey(keybinding_t *); void window_root_grabkey(keybinding_t *);