2009-10-05 17:13:29 +02:00
|
|
|
---------------------------------------------------------------------------
|
2014-05-20 13:02:39 +02:00
|
|
|
--- Implements EWMH requests handling.
|
|
|
|
--
|
2009-10-05 17:13:29 +02:00
|
|
|
-- @author Julien Danjou <julien@danjou.info>
|
|
|
|
-- @copyright 2009 Julien Danjou
|
|
|
|
-- @release @AWESOME_VERSION@
|
2014-05-20 13:02:39 +02:00
|
|
|
-- @module awful.ewmh
|
2009-10-05 17:13:29 +02:00
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
local setmetatable = setmetatable
|
|
|
|
local client = client
|
|
|
|
local screen = screen
|
|
|
|
local ipairs = ipairs
|
|
|
|
local math = math
|
2014-03-24 00:18:35 +01:00
|
|
|
local atag = require("awful.tag")
|
2014-04-16 06:32:44 +02:00
|
|
|
local aclient = require("awful.client")
|
2009-10-05 17:13:29 +02:00
|
|
|
|
2014-03-06 17:47:55 +01:00
|
|
|
local ewmh = {}
|
2009-10-05 17:13:29 +02:00
|
|
|
|
|
|
|
local data = setmetatable({}, { __mode = 'k' })
|
|
|
|
|
|
|
|
local function store_geometry(window, reqtype)
|
|
|
|
if not data[window] then data[window] = {} end
|
|
|
|
if not data[window][reqtype] then data[window][reqtype] = {} end
|
|
|
|
data[window][reqtype] = window:geometry()
|
|
|
|
data[window][reqtype].screen = window.screen
|
|
|
|
end
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Maximize a window horizontally.
|
2014-05-20 13:02:39 +02:00
|
|
|
--
|
2009-10-05 17:13:29 +02:00
|
|
|
-- @param window The window.
|
|
|
|
-- @param set Set or unset the maximized values.
|
|
|
|
local function maximized_horizontal(window, set)
|
|
|
|
if set then
|
2012-03-01 04:46:48 +01:00
|
|
|
store_geometry(window, "maximized_horizontal")
|
2009-10-05 17:13:29 +02:00
|
|
|
local g = screen[window.screen].workarea
|
2012-03-02 00:06:39 +01:00
|
|
|
local bw = window.border_width or 0
|
|
|
|
window:geometry { width = g.width - 2*bw, x = g.x }
|
2012-03-01 04:46:48 +01:00
|
|
|
elseif data[window] and data[window].maximized_horizontal
|
|
|
|
and data[window].maximized_horizontal.x
|
|
|
|
and data[window].maximized_horizontal.width then
|
|
|
|
local g = data[window].maximized_horizontal
|
|
|
|
window:geometry { width = g.width, x = g.x }
|
2009-10-05 17:13:29 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Maximize a window vertically.
|
2014-05-20 13:02:39 +02:00
|
|
|
--
|
2009-10-05 17:13:29 +02:00
|
|
|
-- @param window The window.
|
|
|
|
-- @param set Set or unset the maximized values.
|
|
|
|
local function maximized_vertical(window, set)
|
|
|
|
if set then
|
2012-03-01 04:46:48 +01:00
|
|
|
store_geometry(window, "maximized_vertical")
|
2009-10-05 17:13:29 +02:00
|
|
|
local g = screen[window.screen].workarea
|
2012-03-02 00:06:39 +01:00
|
|
|
local bw = window.border_width or 0
|
|
|
|
window:geometry { height = g.height - 2*bw, y = g.y }
|
2012-03-01 04:46:48 +01:00
|
|
|
elseif data[window] and data[window].maximized_vertical
|
|
|
|
and data[window].maximized_vertical.y
|
|
|
|
and data[window].maximized_vertical.height then
|
|
|
|
local g = data[window].maximized_vertical
|
|
|
|
window:geometry { height = g.height, y = g.y }
|
2009-10-05 17:13:29 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Fullscreen a window.
|
2014-05-20 13:02:39 +02:00
|
|
|
--
|
2009-10-05 17:13:29 +02:00
|
|
|
-- @param window The window.
|
|
|
|
-- @param set Set or unset the fullscreen values.
|
|
|
|
local function fullscreen(window, set)
|
|
|
|
if set then
|
|
|
|
store_geometry(window, "fullscreen")
|
|
|
|
data[window].fullscreen.border_width = window.border_width
|
|
|
|
window.border_width = 0
|
2016-02-15 21:15:41 +01:00
|
|
|
window:geometry(screen[window.screen].geometry)
|
2009-10-05 17:13:29 +02:00
|
|
|
elseif data[window] and data[window].fullscreen then
|
|
|
|
window.border_width = data[window].fullscreen.border_width
|
2016-02-15 21:15:41 +01:00
|
|
|
window:geometry(data[window].fullscreen)
|
2009-10-05 17:13:29 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function screen_change(window)
|
|
|
|
if data[window] then
|
2012-03-02 14:39:28 +01:00
|
|
|
for _, reqtype in ipairs({ "maximized_vertical", "maximized_horizontal", "fullscreen" }) do
|
2009-10-05 17:13:29 +02:00
|
|
|
if data[window][reqtype] then
|
|
|
|
if data[window][reqtype].width then
|
|
|
|
data[window][reqtype].width = math.min(data[window][reqtype].width,
|
|
|
|
screen[window.screen].workarea.width)
|
2012-03-02 14:39:28 +01:00
|
|
|
if reqtype == "maximized_horizontal" then
|
|
|
|
local bw = window.border_width or 0
|
|
|
|
data[window][reqtype].width = data[window][reqtype].width - 2*bw
|
|
|
|
end
|
2009-10-05 17:13:29 +02:00
|
|
|
end
|
|
|
|
if data[window][reqtype].height then
|
|
|
|
data[window][reqtype].height = math.min(data[window][reqtype].height,
|
|
|
|
screen[window.screen].workarea.height)
|
2012-03-02 14:39:28 +01:00
|
|
|
if reqtype == "maximized_vertical" then
|
|
|
|
local bw = window.border_width or 0
|
|
|
|
data[window][reqtype].height = data[window][reqtype].height - 2*bw
|
|
|
|
end
|
2009-10-05 17:13:29 +02:00
|
|
|
end
|
|
|
|
if data[window][reqtype].screen then
|
|
|
|
local from = screen[data[window][reqtype].screen].workarea
|
|
|
|
local to = screen[window.screen].workarea
|
|
|
|
local new_x, new_y
|
|
|
|
if data[window][reqtype].x then
|
|
|
|
new_x = to.x + data[window][reqtype].x - from.x
|
|
|
|
if new_x > to.x + to.width then new_x = to.x end
|
2015-03-21 05:46:56 +01:00
|
|
|
-- Move window if it overlaps the new area to the right.
|
|
|
|
if new_x + data[window][reqtype].width > to.x + to.width then
|
|
|
|
new_x = to.x + to.width - data[window][reqtype].width
|
|
|
|
end
|
|
|
|
if new_x < to.x then new_x = to.x end
|
2009-10-05 17:13:29 +02:00
|
|
|
data[window][reqtype].x = new_x
|
|
|
|
end
|
|
|
|
if data[window][reqtype].y then
|
|
|
|
new_y = to.y + data[window][reqtype].y - from.y
|
|
|
|
if new_y > to.y + to.width then new_y = to.y end
|
2015-03-21 05:46:56 +01:00
|
|
|
-- Move window if it overlaps the new area to the bottom.
|
|
|
|
if new_y + data[window][reqtype].height > to.y + to.height then
|
|
|
|
new_y = to.y + to.height - data[window][reqtype].height
|
|
|
|
end
|
|
|
|
if new_y < to.y then new_y = to.y end
|
2009-10-05 17:13:29 +02:00
|
|
|
data[window][reqtype].y = new_y
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Update a client's settings when its geometry changes, skipping signals
|
2015-01-31 11:58:49 +01:00
|
|
|
-- resulting from calls within.
|
|
|
|
local geometry_change_lock = false
|
|
|
|
local function geometry_change(window)
|
|
|
|
if geometry_change_lock then return end
|
|
|
|
geometry_change_lock = true
|
|
|
|
|
2012-05-16 23:03:32 +02:00
|
|
|
-- Fix up the geometry in case this window needs to cover the whole screen.
|
|
|
|
local bw = window.border_width or 0
|
|
|
|
local g = screen[window.screen].workarea
|
|
|
|
if window.maximized_vertical then
|
|
|
|
window:geometry { height = g.height - 2*bw, y = g.y }
|
|
|
|
end
|
|
|
|
if window.maximized_horizontal then
|
2014-03-06 17:58:03 +01:00
|
|
|
window:geometry { width = g.width - 2*bw, x = g.x }
|
2012-05-16 23:03:32 +02:00
|
|
|
end
|
|
|
|
if window.fullscreen then
|
|
|
|
window.border_width = 0
|
|
|
|
window:geometry(screen[window.screen].geometry)
|
|
|
|
end
|
2015-01-31 11:58:49 +01:00
|
|
|
|
|
|
|
geometry_change_lock = false
|
2012-05-16 23:03:32 +02:00
|
|
|
end
|
|
|
|
|
2015-10-13 12:00:33 +02:00
|
|
|
--- Activate a window.
|
|
|
|
--
|
|
|
|
-- This sets the focus only if the client is visible.
|
2014-05-20 13:02:39 +02:00
|
|
|
--
|
2015-07-29 04:12:49 +02:00
|
|
|
-- It is the default signal handler for `request::activate` on a `client`.
|
|
|
|
--
|
2014-05-20 13:02:39 +02:00
|
|
|
-- @client c A client to use
|
2015-05-13 13:36:28 +02:00
|
|
|
-- @tparam string context The context where this signal was used.
|
2015-09-10 20:45:29 +02:00
|
|
|
-- @tparam[opt] table hints A table with additional hints:
|
|
|
|
-- @tparam[opt=false] boolean hints.raise should the client be raised?
|
2016-02-07 15:02:25 +01:00
|
|
|
function ewmh.activate(c, context, hints) -- luacheck: no unused args
|
2015-09-25 00:18:33 +02:00
|
|
|
if c:isvisible() then
|
|
|
|
client.focus = c
|
|
|
|
end
|
2015-09-10 20:45:29 +02:00
|
|
|
if hints and hints.raise then
|
2015-09-09 22:26:39 +02:00
|
|
|
c:raise()
|
|
|
|
if not awesome.startup and not c:isvisible() then
|
2015-05-13 22:11:07 +02:00
|
|
|
c.urgent = true
|
|
|
|
end
|
|
|
|
end
|
2015-05-13 13:36:28 +02:00
|
|
|
end
|
|
|
|
|
2014-05-20 13:02:39 +02:00
|
|
|
--- Tag a window with its requested tag
|
2015-02-20 15:21:51 +01:00
|
|
|
--
|
2014-05-20 13:02:39 +02:00
|
|
|
-- @client c A client to tag
|
|
|
|
-- @tag[opt] t A tag to use. If omitted, then the client is made sticky.
|
2014-03-17 16:15:20 +01:00
|
|
|
function ewmh.tag(c, t)
|
|
|
|
if not t then
|
|
|
|
c.sticky = true
|
|
|
|
else
|
2014-03-24 00:18:35 +01:00
|
|
|
c.screen = atag.getscreen(t)
|
2014-03-17 16:15:20 +01:00
|
|
|
c:tags({ t })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-04-16 06:32:44 +02:00
|
|
|
function ewmh.urgent(c, urgent)
|
|
|
|
if c ~= client.focus and not aclient.property.get(c,"ignore_urgent") then
|
|
|
|
c.urgent = urgent
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-03-06 17:47:55 +01:00
|
|
|
client.connect_signal("request::activate", ewmh.activate)
|
2014-03-17 16:15:20 +01:00
|
|
|
client.connect_signal("request::tag", ewmh.tag)
|
2014-04-16 06:32:44 +02:00
|
|
|
client.connect_signal("request::urgent", ewmh.urgent)
|
2010-08-26 18:42:38 +02:00
|
|
|
client.connect_signal("request::maximized_horizontal", maximized_horizontal)
|
|
|
|
client.connect_signal("request::maximized_vertical", maximized_vertical)
|
|
|
|
client.connect_signal("request::fullscreen", fullscreen)
|
|
|
|
client.connect_signal("property::screen", screen_change)
|
2015-01-31 11:58:49 +01:00
|
|
|
client.connect_signal("property::border_width", geometry_change)
|
|
|
|
client.connect_signal("property::geometry", geometry_change)
|
2016-02-21 16:44:40 +01:00
|
|
|
screen.connect_signal("property::workarea", function(s)
|
|
|
|
for _, c in pairs(client.get(s)) do
|
|
|
|
geometry_change(c)
|
|
|
|
end
|
|
|
|
end)
|
2009-10-05 17:13:29 +02:00
|
|
|
|
2014-03-06 17:47:55 +01:00
|
|
|
return ewmh
|
|
|
|
|
2011-09-11 16:50:01 +02:00
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|