diff options
Diffstat (limited to 'awesome/lib/awful/mouse/init.lua')
-rw-r--r-- | awesome/lib/awful/mouse/init.lua | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/awesome/lib/awful/mouse/init.lua b/awesome/lib/awful/mouse/init.lua new file mode 100644 index 0000000..03f7e89 --- /dev/null +++ b/awesome/lib/awful/mouse/init.lua @@ -0,0 +1,437 @@ +--------------------------------------------------------------------------- +--- Mouse module for awful +-- +-- @author Julien Danjou <julien@danjou.info> +-- @copyright 2008 Julien Danjou +-- @module mouse +--------------------------------------------------------------------------- + +-- Grab environment we need +local layout = require("awful.layout") +local aplace = require("awful.placement") +local util = require("awful.util") +local type = type +local ipairs = ipairs +local capi = +{ + root = root, + mouse = mouse, + screen = screen, + client = client, + mousegrabber = mousegrabber, +} + +local mouse = { + resize = require("awful.mouse.resize"), + snap = require("awful.mouse.snap"), + drag_to_tag = require("awful.mouse.drag_to_tag") +} + +mouse.object = {} +mouse.client = {} +mouse.wibox = {} + +--- The default snap distance. +-- @tfield integer awful.mouse.snap.default_distance +-- @tparam[opt=8] integer default_distance +-- @see awful.mouse.snap + +--- Enable screen edges snapping. +-- @tfield[opt=true] boolean awful.mouse.snap.edge_enabled + +--- Enable client to client snapping. +-- @tfield[opt=true] boolean awful.mouse.snap.client_enabled + +--- Enable changing tag when a client is dragged to the edge of the screen. +-- @tfield[opt=false] integer awful.mouse.drag_to_tag.enabled + +--- The snap outline background color. +-- @beautiful beautiful.snap_bg +-- @tparam color|string|gradient|pattern color + +--- The snap outline width. +-- @beautiful beautiful.snap_border_width +-- @param integer + +--- The snap outline shape. +-- @beautiful beautiful.snap_shape +-- @tparam function shape A `gears.shape` compatible function + +--- Get the client object under the pointer. +-- @deprecated awful.mouse.client_under_pointer +-- @return The client object under the pointer, if one can be found. +-- @see current_client +function mouse.client_under_pointer() + util.deprecate("Use mouse.current_client instead of awful.mouse.client_under_pointer()") + + return mouse.object.get_current_client() +end + +--- Move a client. +-- @function awful.mouse.client.move +-- @param c The client to move, or the focused one if nil. +-- @param snap The pixel to snap clients. +-- @param finished_cb Deprecated, do not use +function mouse.client.move(c, snap, finished_cb) --luacheck: no unused args + if finished_cb then + util.deprecate("The mouse.client.move `finished_cb` argument is no longer".. + " used, please use awful.mouse.resize.add_leave_callback(f, 'mouse.move')") + end + + c = c or capi.client.focus + + if not c + or c.fullscreen + or c.type == "desktop" + or c.type == "splash" + or c.type == "dock" then + return + end + + -- Compute the offset + local coords = capi.mouse.coords() + local geo = aplace.centered(capi.mouse,{parent=c, pretend=true}) + + local offset = { + x = geo.x - coords.x, + y = geo.y - coords.y, + } + + mouse.resize(c, "mouse.move", { + placement = aplace.under_mouse, + offset = offset, + snap = snap + }) +end + +mouse.client.dragtotag = { } + +--- Move a client to a tag by dragging it onto the left / right side of the screen. +-- @deprecated awful.mouse.client.dragtotag.border +-- @param c The client to move +function mouse.client.dragtotag.border(c) + util.deprecate("Use awful.mouse.snap.drag_to_tag_enabled = true instead ".. + "of awful.mouse.client.dragtotag.border(c). It will now be enabled.") + + -- Enable drag to border + mouse.snap.drag_to_tag_enabled = true + + return mouse.client.move(c) +end + +--- Move the wibox under the cursor. +-- @function awful.mouse.wibox.move +--@tparam wibox w The wibox to move, or none to use that under the pointer +function mouse.wibox.move(w) + w = w or mouse.wibox_under_pointer() + if not w then return end + + if not w + or w.type == "desktop" + or w.type == "splash" + or w.type == "dock" then + return + end + + -- Compute the offset + local coords = capi.mouse.coords() + local geo = aplace.centered(capi.mouse,{parent=w, pretend=true}) + + local offset = { + x = geo.x - coords.x, + y = geo.y - coords.y, + } + + mouse.resize(w, "mouse.move", { + placement = aplace.under_mouse, + offset = offset + }) +end + +--- Get a client corner coordinates. +-- @deprecated awful.mouse.client.corner +-- @tparam[opt=client.focus] client c The client to get corner from, focused one by default. +-- @tparam string corner The corner to use: auto, top_left, top_right, bottom_left, +-- bottom_right, left, right, top bottom. Default is auto, and auto find the +-- nearest corner. +-- @treturn string The corner name +-- @treturn number x The horizontal position +-- @treturn number y The vertical position +function mouse.client.corner(c, corner) + util.deprecate( + "Use awful.placement.closest_corner(mouse) or awful.placement[corner](mouse)".. + " instead of awful.mouse.client.corner" + ) + + c = c or capi.client.focus + if not c then return end + + local ngeo = nil + + if (not corner) or corner == "auto" then + ngeo, corner = aplace.closest_corner(mouse, {parent = c}) + elseif corner and aplace[corner] then + ngeo = aplace[corner](mouse, {parent = c}) + end + + return corner, ngeo and ngeo.x or nil, ngeo and ngeo.y or nil +end + +--- Resize a client. +-- @function awful.mouse.client.resize +-- @param c The client to resize, or the focused one by default. +-- @tparam string corner The corner to grab on resize. Auto detected by default. +-- @tparam[opt={}] table args A set of `awful.placement` arguments +-- @treturn string The corner (or side) name +function mouse.client.resize(c, corner, args) + 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 + + -- Set some default arguments + local new_args = setmetatable( + { + include_sides = (not args) or args.include_sides ~= false + }, + { + __index = args or {} + } + ) + + -- Move the mouse to the corner + if corner and aplace[corner] then + aplace[corner](capi.mouse, {parent=c}) + else + local _ + _, corner = aplace.closest_corner(capi.mouse, { + parent = c, + include_sides = new_args.include_sides ~= false, + }) + end + + new_args.corner = corner + + mouse.resize(c, "mouse.resize", new_args) + + return corner +end + +--- Default handler for `request::geometry` signals with "mouse.resize" context. +-- @signalhandler awful.mouse.resize_handler +-- @tparam client c The client +-- @tparam string context The context +-- @tparam[opt={}] table hints The hints to pass to the handler +function mouse.resize_handler(c, context, hints) + if hints and context and context:find("mouse.*") then + -- This handler only handle the floating clients. If the client is tiled, + -- then it let the layouts handle it. + local t = c.screen.selected_tag + local lay = t and t.layout or nil + + if (lay and lay == layout.suit.floating) or c.floating then + c:geometry { + x = hints.x, + y = hints.y, + width = hints.width, + height = hints.height, + } + elseif lay and lay.resize_handler then + lay.resize_handler(c, context, hints) + end + end +end + +-- Older layouts implement their own mousegrabber. +-- @tparam client c The client +-- @tparam table args Additional arguments +-- @treturn boolean This return false when the resize need to be aborted +mouse.resize.add_enter_callback(function(c, args) --luacheck: no unused args + if c.floating then return end + + local l = c.screen.selected_tag and c.screen.selected_tag.layout or nil + if l == layout.suit.floating then return end + + if l ~= layout.suit.floating and l.mouse_resize_handler then + capi.mousegrabber.stop() + + local geo, corner = aplace.closest_corner(capi.mouse, {parent=c}) + + l.mouse_resize_handler(c, corner, geo.x, geo.y) + + return false + end +end, "mouse.resize") + +--- Get the client currently under the mouse cursor. +-- @property current_client +-- @tparam client|nil The client + +function mouse.object.get_current_client() + local obj = capi.mouse.object_under_pointer() + if type(obj) == "client" then + return obj + end +end + +--- Get the wibox currently under the mouse cursor. +-- @property current_wibox +-- @tparam wibox|nil The wibox + +function mouse.object.get_current_wibox() + local obj = capi.mouse.object_under_pointer() + if type(obj) == "drawin" and obj.get_wibox then + return obj:get_wibox() + end +end + +--- Get the widgets currently under the mouse cursor. +-- +-- @property current_widgets +-- @tparam nil|table list The widget list +-- @treturn table The list of widgets.The first element is the biggest +-- container while the last is the topmost widget. The table contains *x*, *y*, +-- *width*, *height* and *widget*. +-- @see wibox.find_widgets + +function mouse.object.get_current_widgets() + local w = mouse.object.get_current_wibox() + if w then + local geo, coords = w:geometry(), capi.mouse:coords() + + local list = w:find_widgets(coords.x - geo.x, coords.y - geo.y) + + local ret = {} + + for k, v in ipairs(list) do + ret[k] = v.widget + end + + return ret, list + end +end + +--- Get the topmost widget currently under the mouse cursor. +-- @property current_widget +-- @tparam widget|nil widget The widget +-- @treturn ?widget The widget +-- @see wibox.find_widgets +-- @see current_widget_geometry + +function mouse.object.get_current_widget() + local wdgs, geos = mouse.object.get_current_widgets() + + if wdgs then + return wdgs[#wdgs], geos[#geos] + end +end + +--- Get the current widget geometry. +-- @property current_widget_geometry +-- @tparam ?table The geometry. +-- @see current_widget + +function mouse.object.get_current_widget_geometry() + local _, ret = mouse.object.get_current_widget() + + return ret +end + +--- Get the current widget geometries. +-- @property current_widget_geometries +-- @tparam ?table A list of geometry tables. +-- @see current_widgets + +function mouse.object.get_current_widget_geometries() + local _, ret = mouse.object.get_current_widgets() + + return ret +end + +--- True if the left mouse button is pressed. +-- @property is_left_mouse_button_pressed +-- @param boolean + +--- True if the right mouse button is pressed. +-- @property is_right_mouse_button_pressed +-- @param boolean + +--- True if the middle mouse button is pressed. +-- @property is_middle_mouse_button_pressed +-- @param boolean + +for _, b in ipairs {"left", "right", "middle"} do + mouse.object["is_".. b .."_mouse_button_pressed"] = function() + return capi.mouse.coords().buttons[1] + end +end + +capi.client.connect_signal("request::geometry", mouse.resize_handler) + +-- Set the cursor at startup +capi.root.cursor("left_ptr") + +-- Implement the custom property handler +local props = {} + +capi.mouse.set_newindex_miss_handler(function(_,key,value) + if mouse.object["set_"..key] then + mouse.object["set_"..key](value) + elseif not mouse.object["get_"..key] then + props[key] = value + else + -- If there is a getter, but no setter, then the property is read-only + error("Cannot set '" .. tostring(key) .. " because it is read-only") + end +end) + +capi.mouse.set_index_miss_handler(function(_,key) + if mouse.object["get_"..key] then + return mouse.object["get_"..key]() + else + return props[key] + end +end) + +--- Get or set the mouse coords. +-- +-- +-- +--![Usage example](../images/AUTOGEN_awful_mouse_coords.svg) +-- +--**Usage example output**: +-- +-- 235 +-- +-- +-- @usage +-- -- Get the position +--print(mouse.coords().x) +-- -- Change the position +--mouse.coords { +-- x = 185, +-- y = 10 +--} +-- +-- @tparam[opt=nil] table coords_table None or a table with x and y keys as mouse +-- coordinates. +-- @tparam[opt=nil] integer coords_table.x The mouse horizontal position +-- @tparam[opt=nil] integer coords_table.y The mouse vertical position +-- @tparam[opt=false] boolean silent Disable mouse::enter or mouse::leave events that +-- could be triggered by the pointer when moving. +-- @treturn integer table.x The horizontal position +-- @treturn integer table.y The vertical position +-- @treturn table table.buttons Table containing the status of buttons, e.g. field [1] is true +-- when button 1 is pressed. +-- @function mouse.coords + + +return mouse + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 |