2020-10-24 11:40:02 +02:00
|
|
|
local awful = require("awful")
|
|
|
|
local gears = require("gears")
|
|
|
|
local beautiful = require("beautiful")
|
|
|
|
|
2021-01-23 23:04:22 +01:00
|
|
|
local helpers = require(tostring(...):match(".*bling") .. ".helpers")
|
2020-11-02 08:37:39 +01:00
|
|
|
|
2020-10-24 11:40:02 +02:00
|
|
|
-- It might actually swallow too much, that's why there is a filter option by classname
|
2021-08-27 20:01:22 +02:00
|
|
|
-- without the don't-swallow-list it would also swallow for example
|
2020-10-24 11:40:02 +02:00
|
|
|
-- file pickers or new firefox windows spawned by an already existing one
|
|
|
|
|
|
|
|
local window_swallowing_activated = false
|
|
|
|
|
|
|
|
-- you might want to add or remove applications here
|
2022-01-04 11:14:12 +01:00
|
|
|
local parent_filter_list = beautiful.parent_filter_list
|
|
|
|
or beautiful.dont_swallow_classname_list
|
2021-08-27 20:01:22 +02:00
|
|
|
or { "firefox", "Gimp", "Google-chrome" }
|
2022-01-04 11:14:12 +01:00
|
|
|
local child_filter_list = beautiful.child_filter_list
|
|
|
|
or beautiful.dont_swallow_classname_list or { }
|
2021-08-19 12:16:21 +02:00
|
|
|
|
2022-01-04 11:14:12 +01:00
|
|
|
-- for boolean values the or chain way to set the values breaks with 2 vars
|
|
|
|
-- and always defaults to true so i had to do this to se the right value...
|
|
|
|
local swallowing_filter = true
|
|
|
|
local filter_vars = { beautiful.swallowing_filter, beautiful.dont_swallow_filter_activated }
|
|
|
|
for _, var in pairs(filter_vars) do
|
|
|
|
swallowing_filter = var
|
|
|
|
end
|
|
|
|
|
|
|
|
-- check if element exist in table
|
|
|
|
-- returns true if it is
|
|
|
|
local function is_in_table(element, table)
|
|
|
|
local res = false
|
|
|
|
for _, value in pairs(table) do
|
|
|
|
if element:match(value) then
|
|
|
|
res = true
|
|
|
|
break
|
2021-08-19 12:16:21 +02:00
|
|
|
end
|
|
|
|
end
|
2022-01-04 11:14:12 +01:00
|
|
|
return res
|
2021-08-19 12:16:21 +02:00
|
|
|
end
|
2020-10-24 11:40:02 +02:00
|
|
|
|
2022-01-04 11:14:12 +01:00
|
|
|
-- if the swallowing filter is active checks the child and parent classes
|
|
|
|
-- against their filters
|
|
|
|
local function check_swallow(parent, child)
|
|
|
|
local res = true
|
|
|
|
if swallowing_filter then
|
|
|
|
local prnt = not is_in_table(parent, parent_filter_list)
|
|
|
|
local chld = not is_in_table(child, child_filter_list)
|
|
|
|
res = ( prnt and chld )
|
|
|
|
end
|
|
|
|
return res
|
|
|
|
end
|
|
|
|
|
|
|
|
-- async function to get the parent's pid
|
|
|
|
-- recieves a child process pid and a callback function
|
|
|
|
-- parent_pid in format "init(1)---ancestorA(pidA)---ancestorB(pidB)...---process(pid)"
|
|
|
|
function get_parent_pid(child_ppid, callback)
|
|
|
|
local ppid_cmd = string.format("pstree -A -p -s %s", child_ppid)
|
|
|
|
awful.spawn.easy_async(ppid_cmd, function(stdout, stderr, reason, exit_code)
|
|
|
|
-- primitive error checking
|
|
|
|
if stderr and stderr ~= "" then
|
|
|
|
callback(stderr)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
local ppid = stdout
|
|
|
|
callback(nil, ppid)
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2020-10-24 11:40:02 +02:00
|
|
|
-- the function that will be connected to / disconnected from the spawn client signal
|
|
|
|
local function manage_clientspawn(c)
|
|
|
|
-- get the last focused window to check if it is a parent window
|
2021-08-27 20:01:22 +02:00
|
|
|
local parent_client = awful.client.focus.history.get(c.screen, 1)
|
|
|
|
if not parent_client then
|
|
|
|
return
|
2022-01-04 11:14:12 +01:00
|
|
|
elseif parent_client.type == "dialog" or parent_client.type == "splash" then
|
|
|
|
return
|
2021-08-27 20:01:22 +02:00
|
|
|
end
|
2021-08-19 12:16:21 +02:00
|
|
|
|
2022-01-04 11:14:12 +01:00
|
|
|
get_parent_pid(c.pid, function(err, ppid)
|
|
|
|
if err then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
parent_pid = ppid
|
2021-08-27 20:01:22 +02:00
|
|
|
if
|
2022-01-04 11:14:12 +01:00
|
|
|
-- will search for "(parent_client.pid)" inside the parent_pid string
|
|
|
|
( tostring(parent_pid):find("("..tostring(parent_client.pid)..")") )
|
|
|
|
and check_swallow(parent_client.class, c.class)
|
2021-08-27 20:01:22 +02:00
|
|
|
then
|
2020-10-24 11:40:02 +02:00
|
|
|
c:connect_signal("unmanage", function()
|
2022-01-04 11:14:12 +01:00
|
|
|
if parent_client then
|
|
|
|
helpers.client.turn_on(parent_client)
|
|
|
|
helpers.client.sync(parent_client, c)
|
|
|
|
end
|
2020-10-24 11:40:02 +02:00
|
|
|
end)
|
|
|
|
|
2021-03-15 13:50:25 +01:00
|
|
|
helpers.client.sync(c, parent_client)
|
2021-01-23 23:04:22 +01:00
|
|
|
helpers.client.turn_off(parent_client)
|
2020-10-24 11:40:02 +02:00
|
|
|
end
|
2022-01-04 11:14:12 +01:00
|
|
|
end)
|
2020-10-24 11:40:02 +02:00
|
|
|
end
|
|
|
|
|
2021-08-19 12:16:21 +02:00
|
|
|
-- without the following functions that module would be autoloaded by require("bling")
|
2020-10-24 11:40:02 +02:00
|
|
|
-- a toggle window swallowing hotkey is also possible that way
|
|
|
|
|
|
|
|
local function start()
|
|
|
|
client.connect_signal("manage", manage_clientspawn)
|
|
|
|
window_swallowing_activated = true
|
2021-08-27 20:01:22 +02:00
|
|
|
end
|
2020-10-24 11:40:02 +02:00
|
|
|
|
|
|
|
local function stop()
|
|
|
|
client.disconnect_signal("manage", manage_clientspawn)
|
|
|
|
window_swallowing_activated = false
|
2021-08-27 20:01:22 +02:00
|
|
|
end
|
2020-10-24 11:40:02 +02:00
|
|
|
|
|
|
|
local function toggle()
|
2021-08-19 12:16:21 +02:00
|
|
|
if window_swallowing_activated then
|
2020-10-24 11:40:02 +02:00
|
|
|
stop()
|
2021-08-19 12:16:21 +02:00
|
|
|
else
|
2020-10-24 11:40:02 +02:00
|
|
|
start()
|
2021-08-19 12:16:21 +02:00
|
|
|
end
|
|
|
|
end
|
2020-10-24 11:40:02 +02:00
|
|
|
|
|
|
|
return {
|
|
|
|
start = start,
|
|
|
|
stop = stop,
|
2021-08-27 20:01:22 +02:00
|
|
|
toggle = toggle,
|
2020-10-24 11:40:02 +02:00
|
|
|
}
|