From 49bb7e87b4e7e8346793e6781fd0386476ad53e5 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Fri, 14 Nov 2008 16:16:09 +0100 Subject: [PATCH] mouse: remove client_move, move it to awful Signed-off-by: Julien Danjou --- awesomerc.lua.in | 2 +- client.c | 14 ++- lib/awful/init.lua.in | 1 + lib/awful/mouse.lua.in | 138 ++++++++++++++++++++++ mouse.c | 258 ----------------------------------------- mouse.h | 1 - structs.h | 2 - 7 files changed, 152 insertions(+), 264 deletions(-) create mode 100644 lib/awful/mouse.lua.in diff --git a/awesomerc.lua.in b/awesomerc.lua.in index a40e72be..7167c980 100644 --- a/awesomerc.lua.in +++ b/awesomerc.lua.in @@ -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 diff --git a/client.c b/client.c index a507fc1d..bbbb9e58 100644 --- a/client.c +++ b/client.c @@ -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 }, diff --git a/lib/awful/init.lua.in b/lib/awful/init.lua.in index e052113b..12961fb4 100644 --- a/lib/awful/init.lua.in +++ b/lib/awful/init.lua.in @@ -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") diff --git a/lib/awful/mouse.lua.in b/lib/awful/mouse.lua.in new file mode 100644 index 00000000..94d97476 --- /dev/null +++ b/lib/awful/mouse.lua.in @@ -0,0 +1,138 @@ +--------------------------------------------------------------------------- +-- @author Julien Danjou <julien@danjou.info> +-- @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 diff --git a/mouse.c b/mouse.c index fdd2d48c..45e6a59c 100644 --- a/mouse.c +++ b/mouse.c @@ -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. diff --git a/mouse.h b/mouse.h index 63b37e01..a707422e 100644 --- a/mouse.h +++ b/mouse.h @@ -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 *); diff --git a/structs.h b/structs.h index f73a52b9..10164b18 100644 --- a/structs.h +++ b/structs.h @@ -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 */