First commit
This commit is contained in:
commit
66967c0fb2
|
@ -0,0 +1,9 @@
|
|||
#Tyranic - A simple rule engine
|
||||
|
||||
Shifty was great and served us well since the early days of the Awesome 3.* series, but just as
|
||||
many kid aged TV stars, it havn't grown that well. Many of it's, once unique, features are now
|
||||
supported by the default awful.tag engine, adding legacy complexity to the code base and affecting
|
||||
performance.
|
||||
|
||||
This is why Tyranic was created. It is a light rule engine offering pretty much the same rule system,
|
||||
but without all the dynamic tag code. Note that dynamic tagging is now supported directly by awesome.
|
|
@ -0,0 +1,182 @@
|
|||
local setmetatable = setmetatable
|
||||
local print , pairs = print , pairs
|
||||
local ipairs , type = ipairs , type
|
||||
local string = string
|
||||
local awful = require("awful")
|
||||
|
||||
local capi = {client = client , tag = tag ,
|
||||
screen = screen , mouse = mouse }
|
||||
|
||||
module("tyranic")
|
||||
|
||||
-------------------------------INIT------------------------------
|
||||
|
||||
for _,sig in ipairs({"property::exclusive","property::init","property::volatile","property::focus_on_new","property::instances","property::match","property::class"})do
|
||||
capi.tag.add_signal(sig)
|
||||
end
|
||||
|
||||
-------------------------------DATA------------------------------
|
||||
|
||||
local class_client,matches_client = {},{}
|
||||
|
||||
--------------------------TYRANIC LOGIC--------------------------
|
||||
|
||||
--Turn tags -> matches into matches -> tags
|
||||
local function fill_tyranic(tab_in,tab_out,value)
|
||||
if tab_in and tab_out then
|
||||
for i=1,#tab_in do
|
||||
local low = string.lower(tab_in[i])
|
||||
local tmp = tab_out[low] or {tags={},properties={}}
|
||||
value.instances = value.instances or {}
|
||||
tmp.tags[#tmp.tags+1] = value
|
||||
tab_out[low] = tmp
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Load tags, this cannot be undone
|
||||
local function load_tags(tyranic_tags)
|
||||
for k,v in ipairs(tyranic_tags) do
|
||||
if v.init ~= false then
|
||||
v.instances = {}
|
||||
local stype = type(v.screen)
|
||||
if stype == "table" then
|
||||
for k2,v2 in pairs(v.screen) do
|
||||
if v2 <= capi.screen.count() then
|
||||
v.screen = v2
|
||||
v.instances[v2] = awful.tag.add(v.name,v)
|
||||
end
|
||||
end
|
||||
elseif (v.screen or 1) <= capi.screen.count() then
|
||||
v.instances[v.screen or 1] = awful.tag.add(v.name,v)
|
||||
end
|
||||
elseif v.volatile == nil then
|
||||
v.volatile = true
|
||||
end
|
||||
fill_tyranic(v.class,class_client,v)
|
||||
fill_tyranic(v.match,matches_client,v)
|
||||
end
|
||||
end
|
||||
|
||||
--Load property
|
||||
local function load_property(name,property)
|
||||
for k2,v2 in pairs(property) do
|
||||
local key_type = type(k2)
|
||||
local low = string.lower(key_type == "number" and v2 or k2)
|
||||
class_client[low] = class_client[low] or {name=low,tags={},properties={}}
|
||||
class_client[low].properties[name] = key_type == "number" and true or v2
|
||||
end
|
||||
end
|
||||
|
||||
--Match client
|
||||
local function match_client(c, startup)
|
||||
if not c then return end
|
||||
local low = string.lower(c.class or "N/A")
|
||||
local rules = class_client[low]
|
||||
if rules then
|
||||
--Force floating state if necessary
|
||||
if rules.properties.floating ~= nil then
|
||||
awful.client.floating.set(c, rules.properties.floating)
|
||||
end
|
||||
--Set other properties
|
||||
for k,v in pairs(rules.properties) do
|
||||
c[k] = v
|
||||
end
|
||||
--Add to the current tag if the client is intrusive, ignore exclusive
|
||||
if rules.properties.intrusive == true then
|
||||
local tag = awful.tag.selected(c.screen)
|
||||
if tag then
|
||||
c:tags({tag})
|
||||
return
|
||||
end
|
||||
end
|
||||
--TODO pre_match
|
||||
--Add to matches
|
||||
local tags = {}
|
||||
for j=1,#(rules.tags or {}) do
|
||||
local tag_tmp = rules.tags[j]
|
||||
if not tag_tmp.instances[c.screen or 1] then
|
||||
local cache = tag_tmp.screen
|
||||
tag_tmp.screen = tag_tmp.force_screen == true and tag_tmp.screen or c.screen
|
||||
c.screen = tag_tmp.screen
|
||||
tag_tmp.instances[c.screen or 1] = awful.tag.add(tag_tmp.name,tag_tmp)
|
||||
tag_tmp.screen = cache
|
||||
end
|
||||
tags[#tags+1] = tag_tmp.instances[c.screen or 1]
|
||||
end
|
||||
if #tags > 0 then
|
||||
c:tags(tags)
|
||||
if awful.tag.getproperty(tags[1],"focus_on_new") ~= false then
|
||||
awful.tag.viewonly(tags[1])
|
||||
end
|
||||
return
|
||||
end
|
||||
--TODO post_match
|
||||
end
|
||||
--Add to the current tag if not exclusive
|
||||
--TODO
|
||||
--Last resort, create a new tag
|
||||
class_client[low] = class_client[low] or {tags={},properties={}}
|
||||
local tmp,tag = class_client[low],awful.tag.add(c.class,{name=c.class,volatile=true,screen=c.screen})
|
||||
tmp.tags[#tmp.tags+1] = {name=c.class,instances = {tag},volatile=true,screen=c.screen}
|
||||
c:tags({tag})
|
||||
if awful.tag.getproperty(tag,"focus_on_new") ~= false then
|
||||
awful.tag.viewonly(tag)
|
||||
end
|
||||
end
|
||||
|
||||
capi.client.connect_signal("manage", match_client)
|
||||
|
||||
capi.client.connect_signal("untagged", function (c, t)
|
||||
if awful.tag.getproperty(t,"volatile") == true and #t:clients() == 0 then
|
||||
local rules = class_client[string.lower(c.class or "N/A")]
|
||||
for j=1,#(rules and rules.tags or {}) do
|
||||
rules.tags[j].instances[c.screen] = rules.tags[j].instances[c.screen] ~= t and rules.tags[j].instances[c.screen] or nil
|
||||
end
|
||||
awful.tag.delete(t)
|
||||
end
|
||||
end)
|
||||
|
||||
-- awful.tag.withcurrent = function() end --Disable automatic tag insertion
|
||||
awful.tag.withcurrent = function(c, startup)
|
||||
local tags,old_tags = {},c:tags()
|
||||
--Safety to prevent
|
||||
for k, t in ipairs(old_tags) do
|
||||
if awful.tag.getscreen(t) == c.screen then
|
||||
tags[#tags+1] = t
|
||||
end
|
||||
end
|
||||
--Necessary when dragging clients
|
||||
if startup == nil and old_tags[1] and old_tags[1].screen ~= c.screen then --nil != false
|
||||
local sellist = awful.tag.selectedlist(c.screen)
|
||||
if #sellist > 0 then --Use already selected tag
|
||||
tags = sellist
|
||||
else --Select a tag
|
||||
match_client(c, startup)
|
||||
end
|
||||
end
|
||||
c:tags(tags)
|
||||
end
|
||||
|
||||
--------------------------OBJECT GEARS---------------------------
|
||||
local properties = {}
|
||||
setmetatable(properties, {__newindex = function(table,k,v) load_property(k,v) end})
|
||||
|
||||
local function getter (table, key)
|
||||
if key == "properties" then
|
||||
return properties
|
||||
end
|
||||
end
|
||||
local function setter (table, key,value)
|
||||
if key == "tags" then
|
||||
load_tags(value)
|
||||
elseif key == "properties" then
|
||||
properties = value
|
||||
setmetatable(properties, {__newindex = function(table,k,v) load_property(k,v) end})
|
||||
for k,v in pairs(tyranic_properties) do
|
||||
load_property(k,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(_M, { __call = function(_, ...) return end , __index = getter, __newindex = setter})
|
|
@ -0,0 +1,316 @@
|
|||
local awful = require("awful")
|
||||
|
||||
|
||||
-- }}}
|
||||
|
||||
local layouts =
|
||||
{
|
||||
awful.layout.suit.floating,
|
||||
awful.layout.suit.tile,
|
||||
awful.layout.suit.tile.left,
|
||||
awful.layout.suit.tile.bottom,
|
||||
awful.layout.suit.tile.top,
|
||||
awful.layout.suit.fair,
|
||||
awful.layout.suit.fair.horizontal,
|
||||
awful.layout.suit.spiral,
|
||||
awful.layout.suit.spiral.dwindle,
|
||||
awful.layout.suit.max,
|
||||
awful.layout.suit.max.fullscreen,
|
||||
awful.layout.suit.magnifier
|
||||
}
|
||||
|
||||
tags = {} --TODO remove
|
||||
|
||||
tyranic.tags = {
|
||||
{
|
||||
name = "Term",
|
||||
init = true ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("term.png") ,
|
||||
screen = {config.data().scr.pri, config.data().scr.sec} ,
|
||||
layout = awful.layout.suit.tile ,
|
||||
class = {
|
||||
"xterm" , "urxvt" , "aterm","URxvt","XTerm"
|
||||
},
|
||||
match = {
|
||||
"konsole"
|
||||
}
|
||||
} ,
|
||||
{
|
||||
name = "Internet",
|
||||
init = true ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("net.png") ,
|
||||
screen = config.data().scr.pri ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {
|
||||
"Opera" , "Firefox" , "Rekonq" , "Dillo" , "Arora",
|
||||
"Chromium" , "nightly" , "Nightly" , "minefield" , "Minefield" }
|
||||
} ,
|
||||
{
|
||||
name = "Files",
|
||||
init = true ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("folder.png") ,
|
||||
screen = config.data().scr.pri ,
|
||||
layout = awful.layout.suit.tile ,
|
||||
class = {
|
||||
"Thunar" , "Konqueror" , "Dolphin" , "ark" , "Nautilus", }
|
||||
} ,
|
||||
{
|
||||
name = "Develop",
|
||||
init = true ,
|
||||
exclusive = true ,
|
||||
-- screen = {config.data().scr.pri, config.data().scr.sec} ,
|
||||
icon = utils.tools.invertedIconPath("bug.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class ={
|
||||
"Kate" , "KDevelop" , "Codeblocks", "Code::Blocks" , "DDD", "kate4" }
|
||||
} ,
|
||||
{
|
||||
name = "Edit",
|
||||
init = true ,
|
||||
exclusive = true ,
|
||||
-- screen = {config.data().scr.pri, config.data().scr.sec} ,
|
||||
icon = utils.tools.invertedIconPath("editor.png") ,
|
||||
layout = awful.layout.suit.tile.bottom ,
|
||||
class = {
|
||||
"KWrite" , "GVim" , "Emacs" , "Code::Blocks" , "DDD" }
|
||||
} ,
|
||||
{
|
||||
name = "Media",
|
||||
init = true ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("media.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {
|
||||
"Xine" , "xine Panel" , "xine*" , "MPlayer" , "GMPlayer",
|
||||
"XMMS" }
|
||||
} ,
|
||||
{
|
||||
name = "Doc",
|
||||
-- init = true ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("info.png") ,
|
||||
-- screen = config.data().scr.music ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {
|
||||
"Assistant" , "Okular" , "Evince" , "EPDFviewer" , "xpdf",
|
||||
"Xpdf" , }
|
||||
} ,
|
||||
|
||||
|
||||
-----------------VOLATILE TAGS-----------------------
|
||||
{
|
||||
name = "Imaging",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("image.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"Inkscape" , "KolourPaint" , "Krita" , "Karbon" , "Karbon14"}
|
||||
} ,
|
||||
{
|
||||
name = "Picture",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("image.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"Digikam" , "F-Spot" , "GPicView" , "ShowPhoto" , "KPhotoAlbum"}
|
||||
} ,
|
||||
{
|
||||
name = "Video",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("video.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"KDenLive" , "Cinelerra" , "AVIDeMux" , "Kino"}
|
||||
} ,
|
||||
{
|
||||
name = "Movie",
|
||||
init = false ,
|
||||
position = 12 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("video.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"VLC"}
|
||||
} ,
|
||||
{
|
||||
name = "3D",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("3d.png") ,
|
||||
layout = awful.layout.suit.max.fullscreen ,
|
||||
class = {"Blender" , "Maya" , "K-3D" , "KPovModeler" , }
|
||||
} ,
|
||||
{
|
||||
name = "Music",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
screen = config.data().scr.music or config.data().scr.pri ,
|
||||
icon = utils.tools.invertedIconPath("media.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"Amarok" , "SongBird" , "last.fm" ,}
|
||||
} ,
|
||||
{
|
||||
name = "Down",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("download.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"Transmission" , "KGet"}
|
||||
} ,
|
||||
{
|
||||
name = "Office",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("office.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {
|
||||
"OOWriter" , "OOCalc" , "OOMath" , "OOImpress" , "OOBase" ,
|
||||
"SQLitebrowser" , "Silverun" , "Workbench" , "KWord" , "KSpread" ,
|
||||
"KPres","Basket", "openoffice.org" , "OpenOffice.*" , }
|
||||
} ,
|
||||
{
|
||||
name = "RSS",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("rss.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {}
|
||||
} ,
|
||||
{
|
||||
name = "Chat",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
screen = config.data().scr.sec or config.data().scr.sec ,
|
||||
icon = utils.tools.invertedIconPath("chat.png") ,
|
||||
layout = awful.layout.suit.tile ,
|
||||
class = {"Pidgin" , "Kopete" ,}
|
||||
} ,
|
||||
{
|
||||
name = "Burning",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
icon = utils.tools.invertedIconPath("burn.png") ,
|
||||
layout = awful.layout.suit.tile ,
|
||||
class = {"k3b"}
|
||||
} ,
|
||||
{
|
||||
name = "Mail",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
-- screen = config.data().scr.sec or config.data().scr.pri ,
|
||||
icon = utils.tools.invertedIconPath("mail2.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"Thunderbird" , "kmail" , "evolution" ,}
|
||||
} ,
|
||||
{
|
||||
name = "IRC",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = true ,
|
||||
screen = config.data().scr.irc or config.data().scr.pri ,
|
||||
init = true ,
|
||||
spawn = "konversation" ,
|
||||
icon = utils.tools.invertedIconPath("irc.png") ,
|
||||
force_screen= true ,
|
||||
layout = awful.layout.suit.fair ,
|
||||
class = {"Konversation" , "Botch" , "WeeChat" , "weechat" , "irssi"}
|
||||
} ,
|
||||
{
|
||||
name = "Test",
|
||||
init = false ,
|
||||
position = 99 ,
|
||||
exclusive = false ,
|
||||
screen = config.data().scr.sec or config.data().scr.pri ,
|
||||
leave_kills = true ,
|
||||
persist = true ,
|
||||
icon = utils.tools.invertedIconPath("tools.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {}
|
||||
} ,
|
||||
{
|
||||
name = "Config",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = false ,
|
||||
icon = utils.tools.invertedIconPath("tools.png") ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"Systemsettings", "Kcontrol" , "gconf-editor"}
|
||||
} ,
|
||||
{
|
||||
name = "Game",
|
||||
init = false ,
|
||||
screen = config.data().scr.pri ,
|
||||
position = 10 ,
|
||||
exclusive = false ,
|
||||
icon = utils.tools.invertedIconPath("game.png") ,
|
||||
force_screen= true ,
|
||||
layout = awful.layout.suit.max ,
|
||||
class = {"sauer_client" , "Cube 2$" , "Cube 2: Sauerbraten" ,}
|
||||
} ,
|
||||
{
|
||||
name = "Gimp",
|
||||
init = false ,
|
||||
position = 10 ,
|
||||
exclusive = false ,
|
||||
icon = utils.tools.invertedIconPath("image.png") ,
|
||||
layout = awful.layout.tile ,
|
||||
nmaster = 1 ,
|
||||
incncol = 10 ,
|
||||
ncol = 2 ,
|
||||
mwfact = 0.00 ,
|
||||
class = {}
|
||||
} ,
|
||||
{
|
||||
name = "Other",
|
||||
init = true ,
|
||||
position = 15 ,
|
||||
exclusive = false ,
|
||||
icon = utils.tools.invertedIconPath("term.png") ,
|
||||
max_clients = 5 ,
|
||||
screen = {3, 4, 5} ,
|
||||
layout = awful.layout.suit.tile ,
|
||||
class = {}
|
||||
} ,
|
||||
{
|
||||
name = "MediaCenter",
|
||||
init = true ,
|
||||
position = 15 ,
|
||||
exclusive = false ,
|
||||
icon = utils.tools.invertedIconPath("video.png") ,
|
||||
max_clients = 5 ,
|
||||
screen = config.data().scr.media or config.data().scr.pri ,
|
||||
init = "mythfrontend" ,
|
||||
layout = awful.layout.suit.tile ,
|
||||
class = {"mythfrontend" , "xbmc" ,}
|
||||
} ,
|
||||
}
|
||||
tyranic.properties.intrusive = {
|
||||
"ksnapshot" , "pinentry" , "gtksu" , "kcalc" , "xcalc" ,
|
||||
"feh" , "Gradient editor", "About KDE" , "Paste Special", "Background color",
|
||||
"kcolorchooser" , "plasmoidviewer" , "plasmaengineexplorer" , "Xephyr" , "kruler" ,
|
||||
}
|
||||
tyranic.properties.floating = {
|
||||
"MPlayer" , "pinentry" , "ksnapshot" , "pinentry" , "gtksu" ,
|
||||
"xine" , "feh" , "kmix" , "kcalc" , "xcalc" ,
|
||||
"yakuake" , "Select Color$" , "kruler" , "kcolorchooser", "Paste Special" ,
|
||||
"New Form" , "Insert Picture" , "kcharselect", "mythfrontend" , "plasmoidviewer"
|
||||
}
|
||||
|
||||
tyranic.properties.ontop = {
|
||||
"Xephyr" , "ksnapshot" , "kruler"
|
||||
}
|
||||
|
||||
tyranic.properties.size_hints_honor = { xterm = false, URxvt = false, aterm = false, sauer_client = false, mythfrontend = false}
|
Loading…
Reference in New Issue