mouse: remove client_move, move it to awful

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-11-14 16:16:09 +01:00
parent b465fd7d2b
commit 49bb7e87b4
7 changed files with 152 additions and 264 deletions

View File

@ -335,7 +335,7 @@ awful.hooks.manage.register(function (c)
-- Add mouse bindings
c:buttons({
button({ }, 1, function (c) client.focus = c; c:raise() end),
button({ modkey }, 1, function (c) c:mouse_move() end),
button({ modkey }, 1, awful.mouse.client.move),
button({ modkey }, 3, function (c) c:mouse_resize() end)
})
-- New client may not receive focus

View File

@ -572,7 +572,7 @@ client_resize(client_t *c, area_t geometry, bool hints)
area_t area;
layout_t *layout = layout_get_current(c->screen);
if(c->titlebar && !c->ismoving && c->titlebar->isvisible && !client_isfloating(c) && layout != layout_floating)
if(c->titlebar && c->titlebar->isvisible && !client_isfloating(c) && layout != layout_floating)
geometry = titlebar_geometry_remove(c->titlebar, c->border, geometry);
if(hints)
@ -612,7 +612,7 @@ client_resize(client_t *c, area_t geometry, bool hints)
/* save the floating geometry if the window is floating but not
* maximized */
if(c->ismoving || client_isfloating(c)
if(client_isfloating(c)
|| layout_get_current(new_screen) == layout_floating
|| layout_get_current(c->screen) == layout_floating)
if(!c->isfullscreen)
@ -1591,6 +1591,16 @@ luaA_client_module_newindex(lua_State *L)
return 0;
}
/** Move a client with mouse (DEPRECATED).
* \param L The Lua VM state.
*/
static int
luaA_client_mouse_move(lua_State *L)
{
luaA_deprecate(L, "awful.mouse.client.move()");
return 0;
}
const struct luaL_reg awesome_client_methods[] =
{
{ "get", luaA_client_get },

View File

@ -16,6 +16,7 @@ require("awful.titlebar")
require("awful.util")
require("awful.widget")
require("awful.menu")
require("awful.mouse")
--- AWesome Functions very UsefuL
module("awful")

138
lib/awful/mouse.lua.in Normal file
View File

@ -0,0 +1,138 @@
---------------------------------------------------------------------------
-- @author Julien Danjou &lt;julien@danjou.info&gt;
-- @copyright 2008 Julien Danjou
-- @release @AWESOME_VERSION@
---------------------------------------------------------------------------
-- Grab environment we need
local layout = require("awful.layout")
local hooks = require("awful.hooks")
local aclient = require("awful.client")
local math = math
local ipairs = ipairs
local capi =
{
mouse = mouse,
screen = screen,
client = client,
mousegrabber = mousegrabber,
}
--- Mouse module for awful
module("awful.mouse")
client = {}
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
elseif g.x + g.width < sg.x and g.x + g.width > sg.x - snap then
g.x = sg.x - g.width
end
if g.y < snap + sg.y + sg.height and g.y > sg.y + sg.height then
g.y = sg.y + sg.height
elseif g.y + g.height < sg.y and g.y + g.height > sg.y - snap then
g.y = sg.y - g.height
end
return g
end
local function snap_inside(g, sg, snap)
if math.abs(g.x) < snap + sg.x and g.x > sg.x then
g.x = sg.x
elseif math.abs((sg.x + sg.width) - (g.x + g.width)) < snap then
g.x = sg.x + sg.width - g.width
end
if math.abs(g.y) < snap + sg.y and g.y > sg.y then
g.y = sg.y
elseif math.abs((sg.y + sg.height) - (g.y + g.height)) < snap then
g.y = sg.y + sg.height - g.height
end
return g
end
--- Snap a client to the closest client or screen edge.
-- @param c The client to snap.
-- @param snap The pixel to snap clients.
-- @param x The client x coordinate.
-- @param y The client y coordinate.
function client.snap(c, snap, x, y)
local snap = snap or 8
local c = c or client.focus
local geom = c:fullgeometry()
geom.x = x or geom.x
geom.y = y or geom.y
geom = snap_inside(geom, capi.screen[c.screen].geometry, snap)
geom = snap_inside(geom, capi.screen[c.screen].workarea, snap)
for k, snapper in ipairs(aclient.visible(c.screen)) do
if snapper ~= c then
geom = snap_outside(geom, snapper:fullgeometry(), snap)
end
end
return geom
end
--- Move a client.
-- @param c The client to move, or the focused one if nil.
-- @param snap The pixel to snap clients.
function client.move(c, snap)
local c = c or capi.client.focus
if not c then return end
if c.fullscreen
or c.type == "desktop"
or c.type == "splash"
or c.type == "dock" then
return
end
c:raise()
local orig = c:fullgeometry()
local m_c = capi.mouse.coords()
local dist_x = m_c.x - orig.x
local dist_y = m_c.y - orig.y
local function ug(c, prop)
if prop == "geometry" then
local g = c:fullgeometry()
capi.mouse.coords({ x = g.x + dist_x, y = g.y + dist_y })
end
end
capi.mousegrabber.run(function (mouse)
hooks.property.unregister(ug)
for k, v in ipairs(mouse.buttons) do
if v then
local lay = layout.get(c.screen)
if lay == "floating" or c.floating then
local x = mouse.x - dist_x
local y = mouse.y - dist_y
c:fullgeometry(client.snap(c, snap, x, y))
if layout.get(c.screen) ~= "floating" and not c.floating then
hooks.property.register(ug)
end
elseif lay ~= "magnifier" then
c.screen = capi.mouse.screen
if layout.get(c.screen) ~= "floating" then
local c_u_m = capi.mouse.client_under_pointer()
if c_u_m and not c_u_m.floating then
if c_u_m ~= c then
c:swap(c_u_m)
end
end
else
hooks.property.register(ug)
end
end
return true
end
end
return false
end, "fleur")
end
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

258
mouse.c
View File

@ -79,100 +79,6 @@ button_delete(button_t **button)
p_delete(button);
}
/** Snap an area to the outside of an area.
* \param geometry geometry of the area to snap
* \param snap_geometry geometry of snapping area
* \param snap snap trigger in pixel
* \return snapped geometry
*/
static area_t
mouse_snapclienttogeometry_outside(area_t geometry, area_t snap_geometry, int snap)
{
if(geometry.x < snap + snap_geometry.x + snap_geometry.width
&& geometry.x > snap_geometry.x + snap_geometry.width)
geometry.x = snap_geometry.x + snap_geometry.width;
else if(geometry.x + geometry.width < snap_geometry.x
&& geometry.x + geometry.width > snap_geometry.x - snap)
geometry.x = snap_geometry.x - geometry.width;
if(geometry.y < snap + snap_geometry.y + snap_geometry.height
&& geometry.y > snap_geometry.y + snap_geometry.height)
geometry.y = snap_geometry.y + snap_geometry.height;
else if(geometry.y + geometry.height < snap_geometry.y
&& geometry.y + geometry.height > snap_geometry.y - snap)
geometry.y = snap_geometry.y - geometry.height;
return geometry;
}
/** Snap an area to the inside of an area.
* \param geometry geometry of the area to snap
* \param snap_geometry geometry of snapping area
* \param snap snap trigger in pixel
* \return snapped geometry
*/
static area_t
mouse_snapclienttogeometry_inside(area_t geometry, area_t snap_geometry, int snap)
{
if(abs(geometry.x) < snap + snap_geometry.x && geometry.x > snap_geometry.x)
geometry.x = snap_geometry.x;
else if(abs((snap_geometry.x + snap_geometry.width) - (geometry.x + geometry.width))
< snap)
geometry.x = snap_geometry.x + snap_geometry.width - geometry.width;
if(abs(geometry.y) < snap + snap_geometry.y && geometry.y > snap_geometry.y)
geometry.y = snap_geometry.y;
else if(abs((snap_geometry.y + snap_geometry.height) - (geometry.y + geometry.height))
< snap)
geometry.y = snap_geometry.y + snap_geometry.height - geometry.height;
return geometry;
}
/** Snap a client with a future geometry to the screen and other clients.
* \param c The client.
* \param geometry Geometry the client will get.
* \param snap The maximum distance in pixels to trigger a "snap".
* \return Geometry to set to the client.
*/
static area_t
mouse_snapclient(client_t *c, area_t geometry, int snap)
{
client_t *snapper;
area_t snapper_geometry;
area_t screen_geometry =
screen_area_get(c->screen,
&globalconf.screens[c->screen].wiboxes,
&globalconf.screens[c->screen].padding,
false);
area_t screen_geometry_barless =
screen_area_get(c->screen,
NULL,
&globalconf.screens[c->screen].padding,
false);
geometry = titlebar_geometry_add(c->titlebar, c->border, geometry);
geometry =
mouse_snapclienttogeometry_inside(geometry, screen_geometry, snap);
geometry =
mouse_snapclienttogeometry_inside(geometry, screen_geometry_barless, snap);
for(snapper = globalconf.clients; snapper; snapper = snapper->next)
if(snapper != c && client_isvisible(snapper, c->screen))
{
snapper_geometry = snapper->geometry;
snapper_geometry = titlebar_geometry_add(snapper->titlebar, snapper->border, snapper_geometry);
geometry =
mouse_snapclienttogeometry_outside(geometry,
snapper_geometry,
snap);
}
return titlebar_geometry_remove(c->titlebar, c->border, geometry);
}
/** Set coordinates to a corner of an area.
*
* \param a The area.
@ -439,142 +345,6 @@ mouse_track_mouse_drag(int *x, int *y)
}
}
/** Get the client that contains the pointer.
*
* \return The client that contains the pointer or NULL.
*/
static client_t *
mouse_get_client_under_pointer(int phys_screen)
{
xcb_window_t root;
xcb_query_pointer_cookie_t query_ptr_c;
xcb_query_pointer_reply_t *query_ptr_r;
client_t *c = NULL;
root = xutil_screen_get(globalconf.connection, phys_screen)->root;
query_ptr_c = xcb_query_pointer_unchecked(globalconf.connection, root);
query_ptr_r = xcb_query_pointer_reply(globalconf.connection, query_ptr_c, NULL);
if(query_ptr_r)
{
c = client_getbywin(query_ptr_r->child);
p_delete(&query_ptr_r);
}
return c;
}
/** Move the focused window with the mouse.
* \param c The client.
* \param snap The maximum distance in pixels to trigger a "snap".
* \param infobox Enable or disable the infobox.
*/
static void
mouse_client_move(client_t *c, int snap, bool infobox)
{
/* current mouse postion */
int mouse_x, mouse_y;
/* last mouse position */
int last_x = 0, last_y = 0;
/* current layout */
layout_t *layout;
/* the infobox */
simple_window_t sw;
/* the root window */
xcb_window_t root;
layout = layout_get_current(c->screen);
root = xutil_screen_get(globalconf.connection, c->phys_screen)->root;
/* get current pointer position */
mouse_query_pointer(root, &last_x, &last_y, NULL);
/* grab pointer */
if(c->isfullscreen
|| c->type == WINDOW_TYPE_DESKTOP
|| c->type == WINDOW_TYPE_SPLASH
|| c->type == WINDOW_TYPE_DOCK
|| !mouse_grab_pointer(root, xcursor_new(globalconf.connection, XC_fleur)))
return;
if(infobox && (client_isfloating(c) || layout == layout_floating))
mouse_infobox_new(&sw, c->phys_screen, c->border, c->geometry);
else
infobox = false;
/* for each motion event */
while(mouse_track_mouse_drag(&mouse_x, &mouse_y))
if(client_isfloating(c) || layout == layout_floating)
{
area_t geometry;
/* calc new geometry */
geometry = c->geometry;
geometry.x += (mouse_x - last_x);
geometry.y += (mouse_y - last_y);
/* snap and move */
geometry = mouse_snapclient(c, geometry, snap);
c->ismoving = true;
client_resize(c, geometry, false);
xcb_flush(globalconf.connection);
c->ismoving = false;
/* draw the infobox */
if(infobox)
mouse_infobox_draw(&sw, c->geometry, c->border);
/* refresh live */
wibox_refresh();
xcb_flush(globalconf.connection);
/* keep track */
last_x = mouse_x;
last_y = mouse_y;
}
else
{
int newscreen;
client_t *target;
/* client moved to another screen? */
newscreen = screen_getbycoord(c->screen, mouse_x, mouse_y);
if(newscreen != c->screen)
{
screen_client_moveto(c, newscreen, true, true);
globalconf.screens[c->screen].need_arrange = true;
globalconf.screens[newscreen].need_arrange = true;
layout_refresh();
wibox_refresh();
xcb_flush(globalconf.connection);
}
/* find client to swap with */
target = mouse_get_client_under_pointer(c->phys_screen);
/* swap position */
if(target && target != c && !target->isfloating)
{
client_list_swap(&globalconf.clients, c, target);
globalconf.screens[c->screen].need_arrange = true;
if(globalconf.hooks.clients != LUA_REFNIL)
luaA_dofunction(globalconf.L, globalconf.hooks.clients, 0, 0);
layout_refresh();
wibox_refresh();
xcb_flush(globalconf.connection);
}
}
/* ungrab pointer */
xcb_ungrab_pointer(globalconf.connection, XCB_CURRENT_TIME);
/* free the infobox */
if(infobox)
simplewindow_wipe(&sw);
}
/** Resize a floating client with the mouse.
* \param c The client to resize.
* \param corner The corner to resize with.
@ -1022,34 +792,6 @@ luaA_client_mouse_resize(lua_State *L)
return 0;
}
/** Move a client with mouse.
* \param L The Lua VM state.
*
* \luastack
* \lvalue A client.
* \lparam An optional table with keys: `snap' for pixel to snap (default to 8), and
* `infobox' to enable or disable the coordinates and dimensions box (default to
* enabled).
*/
int
luaA_client_mouse_move(lua_State *L)
{
client_t **c = luaA_checkudata(L, 1, "client");
int snap = 8;
bool infobox = true;
if(lua_gettop(L) == 2 && !lua_isnil(L, 2))
{
luaA_checktable(L, 2);
snap = luaA_getopt_number(L, 2, "snap", 8);
infobox = luaA_getopt_boolean(L, 2, "infobox", true);
}
mouse_client_move(*c, snap, infobox);
return 0;
}
/** Create a new mouse button bindings.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.

View File

@ -48,7 +48,6 @@ DO_RCNT(button_t, button, button_delete)
ARRAY_FUNCS(button_t *, button, button_unref)
int luaA_client_mouse_resize(lua_State *);
int luaA_client_mouse_move(lua_State *);
int luaA_button_userdata_new(lua_State *, button_t *);

View File

@ -167,8 +167,6 @@ struct client_t
bool isurgent;
/** true if the window is floating */
bool isfloating;
/** true if the client is moving */
bool ismoving;
/** True if the client is hidden */
bool ishidden;
/** True if the client is minimized */