2008-11-14 16:16:09 +01:00
|
|
|
---------------------------------------------------------------------------
|
2014-05-20 13:02:39 +02:00
|
|
|
--- Mouse module for awful
|
|
|
|
--
|
2008-11-14 16:16:09 +01:00
|
|
|
-- @author Julien Danjou <julien@danjou.info>
|
|
|
|
-- @copyright 2008 Julien Danjou
|
|
|
|
-- @release @AWESOME_VERSION@
|
2014-05-20 13:02:39 +02:00
|
|
|
-- @module awful.mouse
|
2008-11-14 16:16:09 +01:00
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- Grab environment we need
|
|
|
|
local layout = require("awful.layout")
|
2008-11-17 17:12:54 +01:00
|
|
|
local tag = require("awful.tag")
|
2016-04-21 07:51:34 +02:00
|
|
|
local aplace = require("awful.placement")
|
2009-05-05 17:32:53 +02:00
|
|
|
local awibox = require("awful.wibox")
|
2008-12-14 14:38:48 +01:00
|
|
|
local util = require("awful.util")
|
2008-12-03 23:03:44 +01:00
|
|
|
local type = type
|
2008-11-14 16:16:09 +01:00
|
|
|
local ipairs = ipairs
|
|
|
|
local capi =
|
|
|
|
{
|
2009-04-03 17:15:14 +02:00
|
|
|
root = root,
|
2008-11-14 16:16:09 +01:00
|
|
|
mouse = mouse,
|
|
|
|
screen = screen,
|
|
|
|
client = client,
|
|
|
|
mousegrabber = mousegrabber,
|
|
|
|
}
|
|
|
|
|
2016-04-21 10:03:20 +02:00
|
|
|
local mouse = {
|
2016-04-22 07:59:02 +02:00
|
|
|
resize = require("awful.mouse.resize"),
|
|
|
|
snap = require("awful.mouse.snap"),
|
2016-04-21 10:03:20 +02:00
|
|
|
}
|
2008-11-14 16:16:09 +01:00
|
|
|
|
2012-06-14 01:33:27 +02:00
|
|
|
mouse.client = {}
|
|
|
|
mouse.wibox = {}
|
2008-11-14 16:16:09 +01:00
|
|
|
|
2016-04-22 08:16:59 +02:00
|
|
|
--- The default snap distance.
|
|
|
|
-- @tfield integer awful.mouse.snap.default_distance
|
|
|
|
-- @tparam[opt=8] integer default_distance
|
|
|
|
-- @see awful.mouse.snap
|
|
|
|
|
2016-04-23 08:14:01 +02:00
|
|
|
--- 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 width.
|
|
|
|
-- @beautiful beautiful.snap_shape
|
|
|
|
-- @tparam function shape A `gears.shape` compatible function
|
|
|
|
|
2009-02-15 20:12:45 +01:00
|
|
|
--- Get the client object under the pointer.
|
|
|
|
-- @return The client object under the pointer, if one can be found.
|
2012-06-14 01:33:27 +02:00
|
|
|
function mouse.client_under_pointer()
|
2008-12-03 23:03:44 +01:00
|
|
|
local obj = capi.mouse.object_under_pointer()
|
|
|
|
if type(obj) == "client" then
|
|
|
|
return obj
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-03-17 22:18:48 +01:00
|
|
|
--- Get the drawin object under the pointer.
|
|
|
|
-- @return The drawin object under the pointer, if one can be found.
|
|
|
|
function mouse.drawin_under_pointer()
|
2008-12-03 23:03:44 +01:00
|
|
|
local obj = capi.mouse.object_under_pointer()
|
2013-03-17 22:18:48 +01:00
|
|
|
if type(obj) == "drawin" then
|
2008-12-03 23:03:44 +01:00
|
|
|
return obj
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2008-11-14 16:16:09 +01:00
|
|
|
--- Move a client.
|
|
|
|
-- @param c The client to move, or the focused one if nil.
|
|
|
|
-- @param snap The pixel to snap clients.
|
2016-04-22 06:50:28 +02:00
|
|
|
-- @param finished_cb Deprecated, do not use
|
|
|
|
function mouse.client.move(c, snap, finished_cb) --luacheck: no unused args
|
|
|
|
if finished_cb then
|
|
|
|
util.deprecated("The mouse.client.move `finished_cb` argument is no longer"..
|
|
|
|
" used, please use awful.mouse.resize.add_leave_callback(f, 'mouse.move')")
|
|
|
|
end
|
|
|
|
|
2016-02-07 15:24:08 +01:00
|
|
|
c = c or capi.client.focus
|
2008-11-14 16:16:09 +01:00
|
|
|
|
2009-02-07 15:40:50 +01:00
|
|
|
if not c
|
|
|
|
or c.fullscreen
|
2008-11-14 16:16:09 +01:00
|
|
|
or c.type == "desktop"
|
|
|
|
or c.type == "splash"
|
|
|
|
or c.type == "dock" then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2016-04-22 06:50:28 +02:00
|
|
|
-- Compute the offset
|
|
|
|
local coords = capi.mouse.coords()
|
|
|
|
local geo = aplace.centered(capi.mouse,{parent=c, pretend=true})
|
2008-11-14 16:16:09 +01:00
|
|
|
|
2016-04-22 06:50:28 +02:00
|
|
|
local offset = {
|
|
|
|
x = geo.x - coords.x,
|
|
|
|
y = geo.y - coords.y,
|
|
|
|
}
|
|
|
|
|
2016-04-22 09:04:28 +02:00
|
|
|
mouse.resize(c, "mouse.move", {
|
|
|
|
placement = aplace.under_mouse,
|
|
|
|
offset = offset,
|
|
|
|
snap = snap
|
|
|
|
})
|
2008-11-14 16:16:09 +01:00
|
|
|
end
|
|
|
|
|
2012-06-14 01:33:27 +02:00
|
|
|
mouse.client.dragtotag = { }
|
2008-12-14 14:38:48 +01:00
|
|
|
|
|
|
|
--- Move a client to a tag by dragging it onto the left / right side of the screen
|
|
|
|
-- @param c The client to move
|
2012-06-14 01:33:27 +02:00
|
|
|
function mouse.client.dragtotag.border(c)
|
|
|
|
capi.mousegrabber.run(function (_mouse)
|
2016-04-28 01:48:03 +02:00
|
|
|
if not c.valid then return false end
|
|
|
|
|
2008-12-14 14:38:48 +01:00
|
|
|
local button_down = false
|
2012-06-14 01:33:27 +02:00
|
|
|
for _, v in ipairs(_mouse.buttons) do
|
2008-12-14 14:38:48 +01:00
|
|
|
if v then button_down = true end
|
|
|
|
end
|
2009-08-18 15:45:17 +02:00
|
|
|
local wa = capi.screen[c.screen].workarea
|
2012-06-14 01:33:27 +02:00
|
|
|
if _mouse.x >= wa.x + wa.width then
|
2008-12-14 14:38:48 +01:00
|
|
|
capi.mouse.coords({ x = wa.x + wa.width - 1 })
|
2012-06-14 01:33:27 +02:00
|
|
|
elseif _mouse.x <= wa.x then
|
2008-12-14 14:38:48 +01:00
|
|
|
capi.mouse.coords({ x = wa.x + 1 })
|
|
|
|
end
|
|
|
|
if not button_down then
|
2016-04-05 09:02:00 +02:00
|
|
|
local tags = c.screen.tags
|
|
|
|
local t = c.screen.selected_tag
|
2008-12-14 14:38:48 +01:00
|
|
|
local idx
|
|
|
|
for i, v in ipairs(tags) do
|
|
|
|
if v == t then
|
|
|
|
idx = i
|
|
|
|
end
|
|
|
|
end
|
2012-06-14 01:33:27 +02:00
|
|
|
if _mouse.x > wa.x + wa.width - 10 then
|
2008-12-14 14:38:48 +01:00
|
|
|
local newtag = tags[util.cycle(#tags, idx + 1)]
|
2016-04-02 09:27:45 +02:00
|
|
|
c:move_to_tag(newtag)
|
2008-12-14 14:38:48 +01:00
|
|
|
tag.viewnext()
|
2012-06-14 01:33:27 +02:00
|
|
|
elseif _mouse.x < wa.x + 10 then
|
2008-12-14 14:38:48 +01:00
|
|
|
local newtag = tags[util.cycle(#tags, idx - 1)]
|
2016-04-02 09:27:45 +02:00
|
|
|
c:move_to_tag(newtag)
|
2008-12-14 14:38:48 +01:00
|
|
|
tag.viewprev()
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end, "fleur")
|
|
|
|
end
|
|
|
|
|
2008-12-10 19:57:58 +01:00
|
|
|
--- Move the wibox under the cursor
|
|
|
|
--@param w The wibox to move, or none to use that under the pointer
|
2012-06-14 01:33:27 +02:00
|
|
|
function mouse.wibox.move(w)
|
2016-02-07 15:24:08 +01:00
|
|
|
w = w or mouse.wibox_under_pointer()
|
2008-12-10 19:57:58 +01:00
|
|
|
if not w then return end
|
|
|
|
|
|
|
|
local offset = {
|
2009-08-17 16:56:03 +02:00
|
|
|
x = w.x - capi.mouse.coords().x,
|
|
|
|
y = w.y - capi.mouse.coords().y
|
2008-12-10 19:57:58 +01:00
|
|
|
}
|
|
|
|
|
2012-06-14 01:33:27 +02:00
|
|
|
capi.mousegrabber.run(function (_mouse)
|
2008-12-10 19:57:58 +01:00
|
|
|
local button_down = false
|
2009-06-05 19:51:33 +02:00
|
|
|
if awibox.get_position(w) == "floating" then
|
2009-08-17 16:56:03 +02:00
|
|
|
w.x = capi.mouse.coords().x + offset.x
|
|
|
|
w.y = capi.mouse.coords().y + offset.y
|
2008-12-10 19:57:58 +01:00
|
|
|
else
|
2009-08-18 15:45:17 +02:00
|
|
|
local wa = capi.screen[capi.mouse.screen].workarea
|
2008-12-10 19:57:58 +01:00
|
|
|
|
|
|
|
if capi.mouse.coords()["y"] > wa.y + wa.height - 10 then
|
2009-06-05 19:51:33 +02:00
|
|
|
awibox.set_position(w, "bottom", w.screen)
|
2008-12-10 19:57:58 +01:00
|
|
|
elseif capi.mouse.coords()["y"] < wa.y + 10 then
|
2009-06-05 19:51:33 +02:00
|
|
|
awibox.set_position(w, "top", w.screen)
|
2008-12-10 19:57:58 +01:00
|
|
|
elseif capi.mouse.coords()["x"] > wa.x + wa.width - 10 then
|
2009-06-05 19:51:33 +02:00
|
|
|
awibox.set_position(w, "right", w.screen)
|
2008-12-10 19:57:58 +01:00
|
|
|
elseif capi.mouse.coords()["x"] < wa.x + 10 then
|
2009-06-05 19:51:33 +02:00
|
|
|
awibox.set_position(w, "left", w.screen)
|
2008-12-10 19:57:58 +01:00
|
|
|
end
|
|
|
|
w.screen = capi.mouse.screen
|
|
|
|
end
|
2016-02-07 15:24:08 +01:00
|
|
|
for _, v in ipairs(_mouse.buttons) do
|
2008-12-10 19:57:58 +01:00
|
|
|
if v then button_down = true end
|
|
|
|
end
|
|
|
|
if not button_down then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end, "fleur")
|
|
|
|
end
|
|
|
|
|
2008-11-17 17:12:54 +01:00
|
|
|
--- Get a client corner coordinates.
|
2016-04-21 07:51:34 +02:00
|
|
|
-- @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
|
2012-06-14 01:33:27 +02:00
|
|
|
function mouse.client.corner(c, corner)
|
2016-04-21 07:51:34 +02:00
|
|
|
util.deprecated(
|
|
|
|
"Use awful.placement.closest_corner(mouse) or awful.placement[corner](mouse)"..
|
|
|
|
" instead of awful.mouse.client.corner"
|
|
|
|
)
|
|
|
|
|
2016-02-07 15:24:08 +01:00
|
|
|
c = c or capi.client.focus
|
2008-11-17 17:12:54 +01:00
|
|
|
if not c then return end
|
|
|
|
|
2016-04-21 07:51:34 +02:00
|
|
|
local ngeo = nil
|
2008-11-17 17:12:54 +01:00
|
|
|
|
2016-04-21 07:51:34 +02:00
|
|
|
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})
|
2008-11-17 17:12:54 +01:00
|
|
|
end
|
|
|
|
|
2016-04-21 07:51:34 +02:00
|
|
|
return corner, ngeo and ngeo.x or nil, ngeo and ngeo.y or nil
|
2008-11-17 17:12:54 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Resize a client.
|
|
|
|
-- @param c The client to resize, or the focused one by default.
|
2016-04-21 11:01:35 +02:00
|
|
|
-- @tparam string corner The corner to grab on resize. Auto detected by default.
|
|
|
|
-- @tparam[opt={}] table args A set of `awful.placement` arguments
|
|
|
|
function mouse.client.resize(c, corner, args)
|
2016-02-07 15:24:08 +01:00
|
|
|
c = c or capi.client.focus
|
2008-11-17 17:12:54 +01:00
|
|
|
|
|
|
|
if not c then return end
|
|
|
|
|
|
|
|
if c.fullscreen
|
|
|
|
or c.type == "desktop"
|
|
|
|
or c.type == "splash"
|
|
|
|
or c.type == "dock" then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2016-04-21 11:01:35 +02:00
|
|
|
-- Move the mouse to the corner
|
|
|
|
if corner and aplace[corner] then
|
|
|
|
aplace[corner](capi.mouse, {parent=c})
|
|
|
|
end
|
|
|
|
|
|
|
|
mouse.resize(c, "mouse.resize", args or {include_sides=true})
|
|
|
|
end
|
2008-11-17 17:12:54 +01:00
|
|
|
|
2016-04-21 11:01:35 +02:00
|
|
|
--- Default handler for `request::geometry` signals with `mouse.resize` context.
|
|
|
|
-- @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 lay = c.screen.selected_tag.layout
|
|
|
|
|
|
|
|
if lay == layout.suit.floating or c.floating then
|
2016-04-22 06:50:28 +02:00
|
|
|
local offset = hints and hints.offset or {}
|
|
|
|
|
|
|
|
if type(offset) == "number" then
|
|
|
|
offset = {
|
|
|
|
x = offset,
|
|
|
|
y = offset,
|
|
|
|
width = offset,
|
|
|
|
height = offset,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2016-04-21 11:01:35 +02:00
|
|
|
c:geometry {
|
2016-04-22 06:50:28 +02:00
|
|
|
x = hints.x + (offset.x or 0 ),
|
|
|
|
y = hints.y + (offset.y or 0 ),
|
|
|
|
width = hints.width + (offset.width or 0 ),
|
|
|
|
height = hints.height + (offset.height or 0 ),
|
2016-04-21 11:01:35 +02:00
|
|
|
}
|
|
|
|
elseif lay.resize_handler then
|
|
|
|
lay.resize_handler(c, context, hints)
|
|
|
|
end
|
2008-11-17 17:12:54 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-04-21 11:01:35 +02:00
|
|
|
capi.client.connect_signal("request::geometry", mouse.resize_handler)
|
|
|
|
|
2009-04-03 17:15:14 +02:00
|
|
|
-- Set the cursor at startup
|
|
|
|
capi.root.cursor("left_ptr")
|
|
|
|
|
2012-06-14 01:33:27 +02:00
|
|
|
return mouse
|
|
|
|
|
2011-09-11 16:50:01 +02:00
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|