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
-- Create a taglist widget
mytaglist = widget.new({ type = "taglist", name = "mytaglist" })
mytaglist:mouse({}, 1, function (object, tag) awful.tag.viewonly(tag) end)
mytaglist:mouse({ modkey }, 1, function (object, tag) awful.client.movetotag(tag) end)
mytaglist:mouse({}, 3, function (object, tag) tag:view(not tag:isselected()) end)
mytaglist:mouse({ modkey }, 3, function (object, tag) awful.client.toggletag(tag) end)
mytaglist:mouse({ }, 4, awful.tag.viewnext)
mytaglist:mouse({ }, 5, awful.tag.viewprev)
mytaglist:mouse_add(mouse.new({}, 1, function (object, tag) awful.tag.viewonly(tag) end))
mytaglist:mouse_add(mouse.new({ modkey }, 1, function (object, tag) awful.client.movetotag(tag) end))
mytaglist:mouse_add(mouse.new({}, 3, function (object, tag) tag:view(not tag:isselected()) end))
mytaglist:mouse_add(mouse.new({ modkey }, 3, function (object, tag) awful.client.toggletag(tag) end))
mytaglist:mouse_add(mouse.new({ }, 4, awful.tag.viewnext))
mytaglist:mouse_add(mouse.new({ }, 5, awful.tag.viewprev))
mytaglist:set("text_focus", "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> ")
-- Create a tasklist widget
mytasklist = widget.new({ type = "tasklist", name = "mytasklist" })
mytasklist:mouse({ }, 1, function (object, c) c:focus_set(); c:raise() end)
mytasklist:mouse({ }, 4, function () awful.client.focus(1) end)
mytasklist:mouse({ }, 5, function () awful.client.focus(-1) end)
mytasklist:mouse_add(mouse.new({ }, 1, function (object, c) c:focus_set(); c:raise() end))
mytasklist:mouse_add(mouse.new({ }, 4, 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> ")
-- Create a textbox widget
@ -102,10 +102,10 @@ myiconbox:set("image", "@iconsdir@/awesome16.png")
mylayoutbox = {}
for s = 1, screen.count() do
mylayoutbox[s] = widget.new({ type = "iconbox", name = "myiconbox", align = "right" })
mylayoutbox[s]:mouse({ }, 1, function () awful.layout.inc(layouts, 1) end)
mylayoutbox[s]:mouse({ }, 3, function () awful.layout.inc(layouts, -1) end)
mylayoutbox[s]:mouse({ }, 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({ }, 1, function () awful.layout.inc(layouts, 1) end))
mylayoutbox[s]:mouse_add(mouse.new({ }, 3, function () awful.layout.inc(layouts, -1) end))
mylayoutbox[s]:mouse_add(mouse.new({ }, 4, 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")
end
@ -125,12 +125,9 @@ end
-- }}}
-- {{{ Mouse bindings
awesome.mouse({ }, 3, function () awful.spawn(terminal) end)
awesome.mouse({ }, 4, awful.tag.viewnext)
awesome.mouse({ }, 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)
awesome.mouse_add(mouse.new({ }, 3, function () awful.spawn(terminal) end))
awesome.mouse_add(mouse.new({ }, 4, awful.tag.viewnext))
awesome.mouse_add(mouse.new({ }, 5, awful.tag.viewprev))
-- }}}
-- {{{ Key bindings
@ -301,6 +298,10 @@ end
-- Hook function to execute when a new client appears.
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
-- if they're not focusable, so set border anyway.
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);
/* since we're dropping EnterWindow events and sometimes the window
* 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;
/* 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.
* \param L The Lua VM state.
* \luastack
* \lparam A table with modifier keys.
* \lparam A mouse button number
* \lparam A function to execute.
* \lvalue A client.
* \lparam A button binding.
*/
static int
luaA_client_mouse(lua_State *L)
luaA_client_mouse_add(lua_State *L)
{
size_t i, len;
int b;
button_t *button;
/* arg 1 is modkey table */
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));
client_t **c = luaA_checkudata(L, 1, "client");
button_t **b = luaA_checkudata(L, 2, "mouse");
button_list_push(&(*c)->buttons, *b);
button_ref(b);
return 0;
}
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;
}
@ -1440,7 +1435,6 @@ const struct luaL_reg awesome_client_methods[] =
{ "get", luaA_client_get },
{ "focus_get", luaA_client_focus_get },
{ "visible_get", luaA_client_visible_get },
{ "mouse", luaA_client_mouse },
{ NULL, NULL }
};
const struct luaL_reg awesome_client_meta[] =
@ -1472,6 +1466,8 @@ const struct luaL_reg awesome_client_meta[] =
{ "hide", luaA_client_hide },
{ "unhide", luaA_client_unhide },
{ "ishidden", luaA_client_ishidden },
{ "mouse_add", luaA_client_mouse_add },
{ "mouse_remove", luaA_client_mouse_remove },
{ "__eq", luaA_client_eq },
{ "__tostring", luaA_client_tostring },
{ NULL, NULL }

View File

@ -156,7 +156,7 @@ event_handle_buttonpress(void *data __attribute__ ((unused)),
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);
}
else
@ -321,7 +321,7 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
if((c = client_getbytitlebarwin(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
* this will allow us top drop some EnterNotify events and thus not giving
* 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 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_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_meta[];
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_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.
* \param L The Lua VM state.
*
* \luastack
* \lparam A table with modifiers keys.
* \lparam A mouse button number.
* \lparam A function to execute.
* \lparam A mouse button binding.
*/
static int
luaA_mouse(lua_State *L)
luaA_mouse_add(lua_State *L)
{
size_t i, len;
int b;
button_t *button;
button_t **button = luaA_checkudata(L, 1, "mouse");
/* arg 1 is modkey table */
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_list_push(&globalconf.buttons.root, *button);
button_ref(button);
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.root, button);
window_root_grabbutton(button);
window_root_grabbutton(*button);
return 0;
}
@ -486,7 +466,7 @@ luaA_init(void)
{ "restart", luaA_restart },
{ "floating_placement_set", luaA_floating_placement_set },
{ "padding_set", luaA_padding_set },
{ "mouse", luaA_mouse },
{ "mouse_add", luaA_mouse_add },
{ "resizehints_set", luaA_resizehints_set },
{ "font_set", luaA_font_set },
{ "colors_set", luaA_colors_set },
@ -526,12 +506,12 @@ luaA_init(void)
/* Export hooks lib */
luaL_register(L, "hooks", awesome_hooks_lib);
/* Export mouses lib */
luaL_register(L, "mouse", awesome_mouse_lib);
/* Export keygrabber lib */
luaL_register(L, "keygrabber", awesome_keygrabber_lib);
/* Export mouse */
luaA_openlib(L, "mouse", awesome_mouse_methods, awesome_mouse_meta);
/* Export tag */
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;
}
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 },
{ "coords_set", luaA_mouse_coords_set },
{ 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

View File

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

View File

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

View File

@ -22,12 +22,12 @@
#ifndef AWESOME_WINDOW_H
#define AWESOME_WINDOW_H
#include "common/draw.h"
#include "structs.h"
void window_setstate(xcb_window_t, long);
long window_getstate(xcb_window_t);
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_grabbuttons(void);
void window_root_grabkey(keybinding_t *);