Comply with the new official client creation sequence
Tyrannical now use awful.rules for more callbacks. It can be better integrated, but that's enough for this commit. This commit also drop the legacy and request sub-module, as the legacy was dead code anyway amd requests are now mandatory.
This commit is contained in:
parent
b4df05fa1d
commit
a0fa9a4e35
|
@ -1,61 +0,0 @@
|
||||||
-- This file is used to store former Tyrannical features now part
|
|
||||||
-- of upstream. They are kept to support the older versions
|
|
||||||
local capi = {client = client , tag = tag , awesome = awesome,
|
|
||||||
screen = screen , mouse = mouse }
|
|
||||||
local awful = require("awful")
|
|
||||||
|
|
||||||
-- Check is Awesome is 3.5.3+
|
|
||||||
if capi.awesome.startup == nil then
|
|
||||||
-- Monkey patch a bug fixed in 3.5.3
|
|
||||||
awful.tag.setscreen = function(tag,screen)
|
|
||||||
if not tag or type(tag) ~= "tag" then return end
|
|
||||||
awful.tag._setscreen(tag,screen)
|
|
||||||
for k,c in ipairs(tag:clients()) do
|
|
||||||
c.screen = screen or 1 --Move all clients
|
|
||||||
c:tags({tag}) --Prevent some very strange side effects, does create some issue with multitag clients
|
|
||||||
end
|
|
||||||
awful.tag.history.restore(tag.screen,1)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Restore the old behavior in newer Awesome
|
|
||||||
require("tyrannical.extra.request")
|
|
||||||
end
|
|
||||||
|
|
||||||
awful.tag.swap = function(tag1,tag2)
|
|
||||||
local idx1,idx2,scr2 = awful.tag.getidx(tag1),awful.tag.getidx(tag2),awful.tag.getscreen(tag2)
|
|
||||||
awful.tag.setscreen(tag2,awful.tag.getscreen(tag1))
|
|
||||||
awful.tag.move(idx1,tag2)
|
|
||||||
awful.tag.setscreen(tag1,scr2)
|
|
||||||
awful.tag.move(idx2,tag1)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if adding support for sn-based spawn is necessary
|
|
||||||
if not awful.spawn then
|
|
||||||
awful.spawn = {snid_buffer={}}
|
|
||||||
function awful.util.spawn(cmd,sn_rules,callback)
|
|
||||||
if cmd and cmd ~= "" then
|
|
||||||
local enable_sn = (sn_rules ~= false or callback) and true or true
|
|
||||||
if not sn_rules and callback then
|
|
||||||
sn_rules = {callback=callback}
|
|
||||||
elseif callback then
|
|
||||||
sn_rules.callback = callback
|
|
||||||
end
|
|
||||||
local pid,snid = capi.awesome.spawn(cmd, enable_sn)
|
|
||||||
-- The snid will be nil in case of failure
|
|
||||||
if snid and type(sn_rules) == "table" then
|
|
||||||
awful.spawn.snid_buffer[snid] = sn_rules
|
|
||||||
end
|
|
||||||
return pid,snid
|
|
||||||
end
|
|
||||||
-- For consistency
|
|
||||||
return "Error: No command to execute"
|
|
||||||
end
|
|
||||||
local function on_canceled(sn)
|
|
||||||
awful.spawn.snid_buffer[sn] = nil
|
|
||||||
end
|
|
||||||
capi.awesome.connect_signal("spawn::canceled" , on_canceled )
|
|
||||||
capi.awesome.connect_signal("spawn::timeout" , on_canceled )
|
|
||||||
else
|
|
||||||
-- Then if it's there, disable the part we don't want
|
|
||||||
capi.client.disconnect_signal("manage",awful.spawn.on_snid_callback)
|
|
||||||
end
|
|
|
@ -1,40 +0,0 @@
|
||||||
local capi = {client=client,awesome=awesome}
|
|
||||||
local ewmh = require("awful.ewmh")
|
|
||||||
local tyrannical = nil
|
|
||||||
|
|
||||||
-- Use Tyrannical policies instead of the default ones
|
|
||||||
capi.client.disconnect_signal("request::activate",ewmh.activate)
|
|
||||||
capi.client.connect_signal("request::activate",function(c,reason)
|
|
||||||
if not tyrannical then
|
|
||||||
tyrannical = require("tyrannical")
|
|
||||||
end
|
|
||||||
-- Always grant those request as it probably mean that it is a modal dialog
|
|
||||||
if c.transient_for and capi.client.focus == c.transient_for then
|
|
||||||
capi.client.focus = c
|
|
||||||
c:raise()
|
|
||||||
-- If it is not modal, then use the normal code path
|
|
||||||
elseif reason == "rule" or reason == "ewmh" then
|
|
||||||
tyrannical.focus_client(c)
|
|
||||||
-- Tyrannical doesn't have enough information, grant the request
|
|
||||||
else
|
|
||||||
capi.client.focus = c
|
|
||||||
c:raise()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
capi.client.disconnect_signal("request::tag", ewmh.tag)
|
|
||||||
capi.client.connect_signal("request::tag", function(c)
|
|
||||||
-- if capi.awesome.startup then
|
|
||||||
-- --TODO create a tag on that screen
|
|
||||||
-- else
|
|
||||||
-- --TODO block invalid requests, let Tyrannical do its job
|
|
||||||
-- local tags = c:tags()
|
|
||||||
-- if #tags == 0 then
|
|
||||||
-- --TODO cannot happen
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
--lib/awful/tag.lua.in:capi.tag.connect_signal("request::select", tag.viewonly)
|
|
155
init.lua
155
init.lua
|
@ -1,9 +1,8 @@
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
local print , pairs = print , pairs
|
local print , pairs = print , pairs
|
||||||
local ipairs , type = ipairs , type
|
local ipairs , type = ipairs , type
|
||||||
local string , unpack= string , unpack
|
local string , unpack= string , unpack or table.unpack
|
||||||
local awful = require("awful")
|
local awful = require("awful")
|
||||||
require("tyrannical.extra.legacy")
|
|
||||||
|
|
||||||
local capi,sn_callback = {client = client, tag = tag, awesome = awesome,
|
local capi,sn_callback = {client = client, tag = tag, awesome = awesome,
|
||||||
screen = screen, mouse = mouse},awful.spawn and awful.spawn.snid_buffer or {}
|
screen = screen, mouse = mouse},awful.spawn and awful.spawn.snid_buffer or {}
|
||||||
|
@ -81,13 +80,15 @@ local function load_property(name,property)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--Check all focus policies then change focus (Awesome 3.5.3+)
|
|
||||||
function module.focus_client(c,properties)
|
function module.focus_client(c,properties)
|
||||||
local properties = properties or (c_rules.instance[string.lower(c.instance or "N/A")] or {}).properties or (c_rules.class[string.lower(get_class(c))] or {}).properties or {}
|
|
||||||
if (((not c.transient_for) or (c.transient_for==capi.client.focus) or (not settings.block_children_focus_stealing)) and (not properties.no_autofocus)) then
|
if (((not c.transient_for) or (c.transient_for==capi.client.focus) or (not settings.block_children_focus_stealing)) and (not c.no_autofocus)) then
|
||||||
if not awful.util.table.hasitem(c:tags(), (c.screen or capi.screen[1]).selected_tag) and (not prop(c:tags()[1],"no_focus_stealing_in")) then
|
local tags = c:tags()
|
||||||
|
|
||||||
|
if #tags > 0 and not c:isvisible() and not tags[1].no_focus_stealing_in then
|
||||||
c:tags()[1]:view_only()
|
c:tags()[1]:view_only()
|
||||||
end
|
end
|
||||||
|
|
||||||
capi.client.focus = c
|
capi.client.focus = c
|
||||||
c:raise()
|
c:raise()
|
||||||
return true
|
return true
|
||||||
|
@ -95,34 +96,32 @@ function module.focus_client(c,properties)
|
||||||
end
|
end
|
||||||
|
|
||||||
--Apply all properties
|
--Apply all properties
|
||||||
local function apply_properties(c,override,normal)
|
local function apply_properties(c, props, callbacks)
|
||||||
if not override and not normal then return nil,{} end
|
|
||||||
local props,ret = awful.util.table.join(settings.client,normal or {},override,
|
local force_intrusive = settings.force_odd_as_intrusive
|
||||||
override.callback and override.callback(c) or (normal and normal.callback and normal.callback(c)) or {}),nil
|
and c.type ~= "normal"
|
||||||
--Set all 'c.something' properties, --TODO maybe eventually move to awful.rules.execute
|
|
||||||
for k,_ in pairs(props) do
|
local is_intrusive = force_intrusive
|
||||||
c[k] = props[k]
|
or type(props.intrusive) == "function" and props.intrusive(c)
|
||||||
end
|
or props.intrusive
|
||||||
--Center client
|
|
||||||
if props.centered == true then
|
--Check if the client should be added to an existing tag (or tags)
|
||||||
awful.placement.centered(c, nil)
|
if (not props.new_tag) and is_intrusive then
|
||||||
|
local tag = c.screen.selected_tag
|
||||||
|
or c.screen.tags[1]:view_only()
|
||||||
|
or c.screen.selected_tag
|
||||||
|
|
||||||
|
if tag then --Can be false if there is no tags
|
||||||
|
props.tag, props.tags = tag, nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
awful.rules.execute(c, props, callbacks)
|
||||||
|
|
||||||
--Set slave or master
|
--Set slave or master
|
||||||
if props.slave == true or props.master == true then
|
if props.slave == true or props.master == true then
|
||||||
awful.client["set"..(props.slave and "slave" or "master")](c, true)
|
awful.client["set"..(props.slave and "slave" or "master")](c, true)
|
||||||
end
|
end
|
||||||
--Check if the client should be added to an existing tag (or tags)
|
|
||||||
if props.new_tag then
|
|
||||||
ret = c:tags({awful.tag.add(type(props.new_tag)=="table" and props.new_tag.name or c.class,type(props.new_tag)=="table" and props.new_tag or {screen=c.screen or 1})})
|
|
||||||
elseif props.tag then
|
|
||||||
ret = c:tags(type(props.tag) == "function" and props.tag(c) or (type(props.tag) == "table" and props.tag or { props.tag }))
|
|
||||||
elseif props.intrusive == true or (settings.force_odd_as_intrusive and c.type ~= "normal") then
|
|
||||||
local tag = c.screen.selected_tag or c.screen.tags[1]:view_only() or c.screen.selected_tag
|
|
||||||
if tag then --Can be false if there is no tags
|
|
||||||
ret = c:tags({tag})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return ret,props
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function select_screen(tag)
|
local function select_screen(tag)
|
||||||
|
@ -152,16 +151,17 @@ local function select_screen(tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
--Match client
|
--Match client
|
||||||
local function match_client(c, startup)
|
local function match_client(c, forced_tags, hints)
|
||||||
if not c then return end
|
if (not c) or #c:tags() > 0 then return end
|
||||||
local startup = startup == nil and capi.awesome.startup or startup
|
|
||||||
local props = c.startup_id and sn_callback[tostring(c.startup_id)] or {}
|
local props = c.startup_id and sn_callback[tostring(c.startup_id)] or {}
|
||||||
|
|
||||||
local low_i = string.lower(c.instance or "N/A")
|
local low_i = string.lower(c.instance or "N/A")
|
||||||
local low_c = string.lower(get_class(c))
|
local low_c = string.lower(get_class(c))
|
||||||
local tags = props.tags or {props.tag}
|
local tags = props.tags or {props.tag}
|
||||||
|
|
||||||
local rules = c_rules.instance[low_i] or c_rules.class[low_c]
|
local rules = c_rules.instance[low_i] or c_rules.class[low_c]
|
||||||
local forced_tags,props = apply_properties(c,props,rules and rules.properties)
|
|
||||||
if #tags == 0 and c.transient_for and (capi.mouse.screen or (rules and rules.properties.intrusive_popup)) then
|
if #tags == 0 and c.transient_for and (capi.mouse.screen or (rules and rules.properties.intrusive_popup)) then
|
||||||
c.sticky = c.transient_for.sticky or false
|
c.sticky = c.transient_for.sticky or false
|
||||||
c:tags(awful.util.table.join(c.transient_for:tags(),(rules and rules.properties.intrusive_popup) and c.screen.selected_tags))
|
c:tags(awful.util.table.join(c.transient_for:tags(),(rules and rules.properties.intrusive_popup) and c.screen.selected_tags))
|
||||||
|
@ -222,6 +222,7 @@ local function match_client(c, startup)
|
||||||
return module.focus_client(c,props)
|
return module.focus_client(c,props)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
capi.client.disconnect_signal("request::tag", awful.ewmh.tag)
|
||||||
capi.client.connect_signal("request::tag", match_client)
|
capi.client.connect_signal("request::tag", match_client)
|
||||||
|
|
||||||
capi.client.connect_signal("untagged", function (c, t)
|
capi.client.connect_signal("untagged", function (c, t)
|
||||||
|
@ -235,23 +236,7 @@ capi.client.connect_signal("untagged", function (c, t)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
awful.tag.withcurrent,awful.tag._add = function(c, startup)
|
awful.tag._add = awful.tag.add
|
||||||
local tags,old_tags = {},c:tags()
|
|
||||||
--Safety to prevent
|
|
||||||
for k, t in ipairs(old_tags) do
|
|
||||||
tags[#tags+1] = (t.screen == c.screen) and t or nil
|
|
||||||
end
|
|
||||||
--Necessary when dragging clients
|
|
||||||
if startup == nil and old_tags[1] and old_tags[1].screen ~= c.screen then --nil != false
|
|
||||||
local sellist = c.screen.selected_tags
|
|
||||||
if #sellist > 0 then --Use already selected tag
|
|
||||||
tags = sellist
|
|
||||||
else --Select a tag
|
|
||||||
match_client(c, startup)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
c:tags(tags)
|
|
||||||
end,awful.tag.add
|
|
||||||
|
|
||||||
awful.tag.add = function(tag,props,override)
|
awful.tag.add = function(tag,props,override)
|
||||||
props.screen,props.instances = props.screen or capi.mouse.screen,props.instances or setmetatable({}, { __mode = 'v' })
|
props.screen,props.instances = props.screen or capi.mouse.screen,props.instances or setmetatable({}, { __mode = 'v' })
|
||||||
|
@ -265,11 +250,9 @@ awful.tag.add = function(tag,props,override)
|
||||||
end
|
end
|
||||||
|
|
||||||
capi.tag.connect_signal("property::fallback",function(t)
|
capi.tag.connect_signal("property::fallback",function(t)
|
||||||
fallbacks[awful.util.table.hasitem(fallbacks, t) or (#fallbacks+1)] = prop(t,"fallback") and t or nil
|
fallbacks[awful.util.table.hasitem(fallbacks, t) or (#fallbacks+1)] = t.fallback and t or nil
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local is_init = setmetatable({}, { __mode = 'k' })
|
|
||||||
|
|
||||||
local function contain_screen(tab, s)
|
local function contain_screen(tab, s)
|
||||||
for _, v in ipairs(tab) do
|
for _, v in ipairs(tab) do
|
||||||
if type(v) ~= "number" or v <= capi.screen.count() then
|
if type(v) ~= "number" or v <= capi.screen.count() then
|
||||||
|
@ -284,9 +267,7 @@ local function contain_screen(tab, s)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add init tags to newly connected screens
|
-- Add init tags to newly connected screens
|
||||||
awful.screen.connect_for_each_screen(function(s) --TODO remove the load code and use this
|
awful.screen.connect_for_each_screen(function(s)
|
||||||
if is_init[s] then return end
|
|
||||||
|
|
||||||
for _, def in pairs(tags_hash) do
|
for _, def in pairs(tags_hash) do
|
||||||
if def.init then
|
if def.init then
|
||||||
if def.screen and (type(def.screen) == "table" and contain_screen(def.screen, s))
|
if def.screen and (type(def.screen) == "table" and contain_screen(def.screen, s))
|
||||||
|
@ -345,6 +326,68 @@ capi.tag.connect_signal("request::screen", function(t)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
capi.client.disconnect_signal("manage", awful.rules.apply)
|
||||||
|
capi.client.disconnect_signal("spawn::completed_with_payload", awful.rules.completed_with_payload_callback)
|
||||||
|
capi.client.disconnect_signal("manage",awful.spawn.on_snid_callback)
|
||||||
|
|
||||||
|
--- Replace the default handler to take into account Tyrannical properties
|
||||||
|
function awful.rules.apply(c)
|
||||||
|
local low_i = string.lower(c.instance or "N/A")
|
||||||
|
local low_c = string.lower(get_class(c))
|
||||||
|
|
||||||
|
local callbacks, props = {}, {}
|
||||||
|
|
||||||
|
local props_src = (c_rules.instance[low_i]
|
||||||
|
or c_rules.class[low_c] or {}).properties
|
||||||
|
or {}
|
||||||
|
|
||||||
|
-- Add Tyrannical properties
|
||||||
|
awful.util.table.crush(props,props_src)
|
||||||
|
|
||||||
|
-- Add the rules properties
|
||||||
|
for _, entry in ipairs(awful.rules.matching_rules(c, awful.rules.rules)) do
|
||||||
|
awful.util.table.crush(props,entry.properties or {})
|
||||||
|
|
||||||
|
if entry.callback then
|
||||||
|
table.insert(callbacks, entry.callback)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add startup_id overridden properties
|
||||||
|
if c.startup_id and awful.spawn.snid_buffer[c.startup_id] then
|
||||||
|
local snprops, sncb = unpack(awful.spawn.snid_buffer[c.startup_id])
|
||||||
|
|
||||||
|
-- The SNID tag(s) always have precedence over the rules one(s)
|
||||||
|
if snprops.tag or snprops.tags or snprops.new_tag then
|
||||||
|
props.tag, props.tags, props.new_tag, props.intrusive = nil, nil, nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
awful.util.table.crush(props,snprops)
|
||||||
|
awful.util.table.merge(callbacks, sncb)
|
||||||
|
end
|
||||||
|
|
||||||
|
apply_properties(c,props, callbacks)
|
||||||
|
end
|
||||||
|
|
||||||
|
capi.client.connect_signal("manage", awful.rules.apply)
|
||||||
|
|
||||||
|
capi.client.disconnect_signal("request::activate",awful.ewmh.activate)
|
||||||
|
capi.client.connect_signal("request::activate",function(c,reason)
|
||||||
|
-- Always grant those request as it probably mean that it is a modal dialog
|
||||||
|
if c.transient_for and capi.client.focus == c.transient_for then
|
||||||
|
capi.client.focus = c
|
||||||
|
c:raise()
|
||||||
|
-- If it is not modal, then use the normal code path
|
||||||
|
elseif reason == "rule" or reason == "rules" or reason == "ewmh" then
|
||||||
|
module.focus_client(c)
|
||||||
|
-- Tyrannical doesn't have enough information, grant the request
|
||||||
|
else
|
||||||
|
capi.client.focus = c
|
||||||
|
c:raise()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
--------------------------OBJECT GEARS---------------------------
|
--------------------------OBJECT GEARS---------------------------
|
||||||
local getter = {properties = setmetatable({}, {__newindex = function(table,k,v) load_property(k,v) end}),
|
local getter = {properties = setmetatable({}, {__newindex = function(table,k,v) load_property(k,v) end}),
|
||||||
settings = settings, tags_by_name = tags_hash, sn_callback = sn_callback}
|
settings = settings, tags_by_name = tags_hash, sn_callback = sn_callback}
|
||||||
|
|
12
shortcut.lua
12
shortcut.lua
|
@ -12,9 +12,9 @@ local glib = require( "lgi" ).GLib
|
||||||
|
|
||||||
local function get_current_screen()
|
local function get_current_screen()
|
||||||
if capi.client.focus and capi.client.focus.screen == capi.mouse.screen then
|
if capi.client.focus and capi.client.focus.screen == capi.mouse.screen then
|
||||||
return capi.mouse.screen
|
return capi.mouse.screen
|
||||||
elseif (not aw_tag.selected(capi.mouse.screen)) or (#aw_tag.selected(capi.mouse.screen):clients() == 0) or (not capi.client.focus) then
|
elseif (capi.mouse.screen.selected_tag and #capi.mouse.screen.selected_tag:clients() == 0) or (not capi.client.focus) then
|
||||||
return capi.mouse.screen
|
return capi.mouse.screen
|
||||||
end
|
end
|
||||||
return capi.client.focus.screen
|
return capi.client.focus.screen
|
||||||
end
|
end
|
||||||
|
@ -70,11 +70,11 @@ local function rename_tag()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function term_in_current_tag()
|
local function term_in_current_tag()
|
||||||
aw_spawn(terminal,{intrusive=true,slave=true})
|
aw_spawn(terminal,{intrusive=true,slave=true,screen=get_current_screen()})
|
||||||
end
|
end
|
||||||
|
|
||||||
local function new_tag_with_term()
|
local function new_tag_with_term()
|
||||||
aw_spawn(terminal,{new_tag={volatile = true}})
|
aw_spawn(terminal,{new_tag={volatile = true,screen=get_current_screen()}})
|
||||||
end
|
end
|
||||||
|
|
||||||
local function fork_tag()
|
local function fork_tag()
|
||||||
|
@ -84,7 +84,7 @@ local function fork_tag()
|
||||||
local clients = t:clients()
|
local clients = t:clients()
|
||||||
local t2 = aw_tag.add(t.name,aw_tag.getdata(t))
|
local t2 = aw_tag.add(t.name,aw_tag.getdata(t))
|
||||||
t2:clients(clients)
|
t2:clients(clients)
|
||||||
aw_tag.viewonly(t2)
|
t2:view_only()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function aero_tag()
|
local function aero_tag()
|
||||||
|
|
Loading…
Reference in New Issue