zaphod: restore support

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-08-14 22:16:13 +02:00
parent b48bf31afd
commit df79115dd1
4 changed files with 132 additions and 35 deletions

View File

@ -82,7 +82,8 @@ keybinding_cmp(const keybinding_t *k1, const keybinding_t *k2)
static void static void
window_root_grabkey(keybinding_t *k) window_root_grabkey(keybinding_t *k)
{ {
int phys_screen = globalconf.default_screen; int phys_screen = 0;
int nscreen = xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
xcb_screen_t *s; xcb_screen_t *s;
xcb_keycode_t kc; xcb_keycode_t kc;
@ -102,8 +103,7 @@ window_root_grabkey(keybinding_t *k)
k->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK, kc, XCB_GRAB_MODE_ASYNC, k->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK, kc, XCB_GRAB_MODE_ASYNC,
XCB_GRAB_MODE_ASYNC); XCB_GRAB_MODE_ASYNC);
phys_screen++; phys_screen++;
} while(!globalconf.screens_info->xinerama_is_active } while(phys_screen < nscreen);
&& phys_screen < globalconf.screens_info->nscreen);
} }
/** Ungrab key on the root windows. /** Ungrab key on the root windows.
@ -112,7 +112,8 @@ window_root_grabkey(keybinding_t *k)
static void static void
window_root_ungrabkey(keybinding_t *k) window_root_ungrabkey(keybinding_t *k)
{ {
int phys_screen = globalconf.default_screen; int phys_screen = 0;
int nscreen = xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
xcb_screen_t *s; xcb_screen_t *s;
xcb_keycode_t kc; xcb_keycode_t kc;
@ -130,8 +131,7 @@ window_root_ungrabkey(keybinding_t *k)
xcb_ungrab_key(globalconf.connection, kc, s->root, xcb_ungrab_key(globalconf.connection, kc, s->root,
k->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK); k->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK);
phys_screen++; phys_screen++;
} while(!globalconf.screens_info->xinerama_is_active } while(phys_screen < nscreen);
&& phys_screen < globalconf.screens_info->nscreen);
} }
static void static void

View File

@ -18,6 +18,7 @@ local table = table
local otable = otable local otable = otable
local capi = local capi =
{ {
awesome = awesome,
screen = screen, screen = screen,
client = client, client = client,
mouse = mouse, mouse = mouse,
@ -321,7 +322,7 @@ function screen.focus(i)
local c = client.focus.history.get(s, 0) local c = client.focus.history.get(s, 0)
if c then capi.client.focus = c end if c then capi.client.focus = c end
-- Move the mouse on the screen -- Move the mouse on the screen
capi.mouse.coords = capi.screen[s].coords capi.mouse.screen = s
end end
--- Compare 2 tables of tags. --- Compare 2 tables of tags.
@ -772,10 +773,10 @@ end
--- Spawn a program. --- Spawn a program.
-- @param cmd The command. -- @param cmd The command.
-- @return The os.execute() return value. -- @return The awesome.spawn return value.
function spawn(cmd) function spawn(cmd)
if cmd and cmd ~= "" then if cmd and cmd ~= "" then
return os.execute(cmd .. "&") return capi.awesome.spawn(cmd .. "&", capi.mouse.screen)
end end
end end

61
lua.c
View File

@ -24,6 +24,8 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ev.h> #include <ev.h>
@ -454,6 +456,64 @@ luaA_otable_newindex(lua_State *L)
} }
lua_rawset(L, 1); lua_rawset(L, 1);
return 0;
}
/** Spawn a program.
* This function is multi-head (Zaphod) aware and will set display to
* the right screen according to mouse position.
* \param L The Lua VM state.
* \return The number of elements pushed on stack
* \luastack
* \lparam The command to launch.
* \lparam The optional screen number to spawn the command on.
*/
static int
luaA_spawn(lua_State *L)
{
static const char *shell = NULL;
char display[128], *tmp, newdisplay[128];
const char *cmd;
int screen = 0;
if(!shell && !(shell = getenv("SHELL")))
shell = "/bin/sh";
if(lua_gettop(L) == 2)
{
screen = luaL_checknumber(L, 2) - 1;
luaA_checkscreen(screen);
}
cmd = luaL_checkstring(L, 1);
if(!globalconf.screens_info->xinerama_is_active
&& (tmp = getenv("DISPLAY")))
{
a_strcpy(display, sizeof(display) - 1, tmp);
if((tmp = strrchr(display, '.')))
*tmp = '\0';
snprintf(newdisplay, sizeof(newdisplay) - 1, "%s.%d", display, screen);
setenv("DISPLAY", newdisplay, 1);
}
/* The double-fork construct avoids zombie processes and keeps the code
* clean from stupid signal handlers. */
if(fork() == 0)
{
if(fork() == 0)
{
if(globalconf.connection)
xcb_disconnect(globalconf.connection);
setsid();
execl(shell, shell, "-c", cmd, NULL);
warn("execl '%s -c %s' failed: %s\n", shell, cmd, strerror(errno));
}
exit(EXIT_SUCCESS);
}
wait(0);
return 0; return 0;
} }
@ -479,6 +539,7 @@ luaA_init(void)
{ {
{ "quit", luaA_quit }, { "quit", luaA_quit },
{ "exec", luaA_exec }, { "exec", luaA_exec },
{ "spawn", luaA_spawn },
{ "restart", luaA_restart }, { "restart", luaA_restart },
{ "mouse_add", luaA_mouse_add }, { "mouse_add", luaA_mouse_add },
{ "font_set", luaA_font_set }, { "font_set", luaA_font_set },

87
mouse.c
View File

@ -300,8 +300,8 @@ mouse_infobox_new(int phys_screen, int border, area_t geometry,
return sw; return sw;
} }
/** Get the Pointer position /** Get the pointer position.
* \param window * \param window The window to get position on.
* \param x will be set to the Pointer-x-coordinate relative to window * \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 y will be set to the Pointer-y-coordinate relative to window
* \param mask will be set to the current buttons state * \param mask will be set to the current buttons state
@ -316,7 +316,7 @@ mouse_query_pointer(xcb_window_t window, int *x, int *y, uint16_t *mask)
query_ptr_c = xcb_query_pointer_unchecked(globalconf.connection, window); query_ptr_c = xcb_query_pointer_unchecked(globalconf.connection, window);
query_ptr_r = xcb_query_pointer_reply(globalconf.connection, query_ptr_c, NULL); query_ptr_r = xcb_query_pointer_reply(globalconf.connection, query_ptr_c, NULL);
if(!query_ptr_r) if(!query_ptr_r || !query_ptr_r->same_screen)
return false; return false;
*x = query_ptr_r->win_x; *x = query_ptr_r->win_x;
@ -329,6 +329,31 @@ mouse_query_pointer(xcb_window_t window, int *x, int *y, uint16_t *mask)
return true; return true;
} }
/** Get the pointer position on the screen.
* \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 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)
{
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;
if(mouse_query_pointer(root, x, y, mask))
{
*s = screen;
return true;
}
}
return false;
}
/** Grab the Pointer. /** Grab the Pointer.
* \param window The window grabbed. * \param window The window grabbed.
* \param cursor The cursor to display (see struct.h CurNormal, CurResize, etc). * \param cursor The cursor to display (see struct.h CurNormal, CurResize, etc).
@ -364,10 +389,10 @@ mouse_ungrab_pointer(void)
xcb_ungrab_pointer(globalconf.connection, XCB_CURRENT_TIME); xcb_ungrab_pointer(globalconf.connection, XCB_CURRENT_TIME);
} }
/** Set the Pointer position /** Set the pointer position.
* \param window the destination window * \param window The destination window.
* \param x x-coordinate inside window * \param x X-coordinate inside window.
* \param y y-coordinate inside window * \param y Y-coordinate inside window.
*/ */
static inline void static inline void
mouse_warp_pointer(xcb_window_t window, int x, int y) mouse_warp_pointer(xcb_window_t window, int x, int y)
@ -421,19 +446,19 @@ mouse_track_mouse_drag(int *x, int *y)
} }
} }
/** Get the client that contains the Pointer. /** Get the client that contains the pointer.
* *
* \return The client that contains the Pointer or NULL. * \return The client that contains the pointer or NULL.
*/ */
static client_t * static client_t *
mouse_get_client_under_pointer(void) mouse_get_client_under_pointer(int phys_screen)
{ {
xcb_window_t root; xcb_window_t root;
xcb_query_pointer_cookie_t query_ptr_c; xcb_query_pointer_cookie_t query_ptr_c;
xcb_query_pointer_reply_t *query_ptr_r; xcb_query_pointer_reply_t *query_ptr_r;
client_t *c = NULL; client_t *c = NULL;
root = xutil_screen_get(globalconf.connection, globalconf.default_screen)->root; root = xutil_screen_get(globalconf.connection, phys_screen)->root;
query_ptr_c = xcb_query_pointer_unchecked(globalconf.connection, root); query_ptr_c = xcb_query_pointer_unchecked(globalconf.connection, root);
query_ptr_r = xcb_query_pointer_reply(globalconf.connection, query_ptr_c, NULL); query_ptr_r = xcb_query_pointer_reply(globalconf.connection, query_ptr_c, NULL);
@ -525,7 +550,7 @@ mouse_client_move(client_t *c, int snap, bool infobox)
} }
/* find client to swap with */ /* find client to swap with */
target = mouse_get_client_under_pointer(); target = mouse_get_client_under_pointer(c->phys_screen);
/* swap position */ /* swap position */
if(target && target != c && !target->isfloating) if(target && target != c && !target->isfloating)
@ -832,8 +857,10 @@ mouse_client_resize_magnified(client_t *c, bool infobox)
maxdist = round(sqrt((area.width*area.width) + (area.height*area.height)) / 2.); maxdist = round(sqrt((area.width*area.width) + (area.height*area.height)) / 2.);
/* get current mouse position */ root = xutil_screen_get(globalconf.connection, c->phys_screen)->root;
mouse_query_pointer(root, &mouse_x, &mouse_y, NULL);
if(!mouse_query_pointer(root, &mouse_x, &mouse_y, NULL))
return;
/* select corner */ /* select corner */
corner = mouse_snap_to_corner(c->geometry, &mouse_x, &mouse_y, corner); corner = mouse_snap_to_corner(c->geometry, &mouse_x, &mouse_y, corner);
@ -1070,14 +1097,12 @@ luaA_mouse_index(lua_State *L)
const char *attr = luaL_checklstring(L, 2, &len); const char *attr = luaL_checklstring(L, 2, &len);
int mouse_x, mouse_y, i = 0; int mouse_x, mouse_y, i = 0;
uint16_t mask; uint16_t mask;
xcb_window_t root; int screen;
switch(a_tokenize(attr, len)) switch(a_tokenize(attr, len))
{ {
case A_TK_COORDS: case A_TK_COORDS:
root = xutil_screen_get(globalconf.connection, globalconf.default_screen)->root; if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, &mask))
if(!mouse_query_pointer(root, &mouse_x, &mouse_y, &mask))
return 0; return 0;
lua_newtable(L); lua_newtable(L);
@ -1114,14 +1139,10 @@ luaA_mouse_index(lua_State *L)
lua_setfield(L, -2, "buttons"); lua_setfield(L, -2, "buttons");
break; break;
case A_TK_SCREEN: case A_TK_SCREEN:
root = xutil_screen_get(globalconf.connection, globalconf.default_screen)->root; if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, NULL))
if(!mouse_query_pointer(root, &mouse_x, &mouse_y, NULL))
return 0; return 0;
i = screen_get_bycoord(globalconf.screens_info, i = screen_get_bycoord(globalconf.screens_info, screen, mouse_x, mouse_y);
globalconf.default_screen,
mouse_x, mouse_y);
lua_pushnumber(L, i + 1); lua_pushnumber(L, i + 1);
break; break;
@ -1144,19 +1165,33 @@ luaA_mouse_newindex(lua_State *L)
int mouse_x, mouse_y, x, y = 0; int mouse_x, mouse_y, x, y = 0;
uint16_t mask; uint16_t mask;
xcb_window_t root; xcb_window_t root;
int screen, phys_screen;
switch(a_tokenize(attr, len)) switch(a_tokenize(attr, len))
{ {
case A_TK_COORDS: case A_TK_COORDS:
luaA_checktable(L, 3); luaA_checktable(L, 3);
root = xutil_screen_get(globalconf.connection, globalconf.default_screen)->root; if(!mouse_query_pointer_root(&screen, &mouse_x, &mouse_y, &mask))
if(!mouse_query_pointer(root, &mouse_x, &mouse_y, &mask))
return 0; return 0;
x = luaA_getopt_number(L, 3, "x", mouse_x); x = luaA_getopt_number(L, 3, "x", mouse_x);
y = luaA_getopt_number(L, 3, "y", mouse_y); y = luaA_getopt_number(L, 3, "y", mouse_y);
root = xutil_screen_get(globalconf.connection, screen)->root;
mouse_warp_pointer(root, x, y);
break;
case A_TK_SCREEN:
screen = luaL_checknumber(L, 3) - 1;
luaA_checkscreen(screen);
/* we need the physical one to get the root window */
phys_screen = screen_virttophys(screen);
root = xutil_screen_get(globalconf.connection, phys_screen)->root;
x = globalconf.screens_info->geometry[screen].x;
y = globalconf.screens_info->geometry[screen].y;
mouse_warp_pointer(root, x, y); mouse_warp_pointer(root, x, y);
break; break;
default: default: