First commit
This commit is contained in:
commit
401f005e42
|
@ -0,0 +1,5 @@
|
|||
proc
|
||||
cgroup
|
||||
xorg
|
||||
#wayland
|
||||
main
|
|
@ -0,0 +1,23 @@
|
|||
import os
|
||||
cg = "/sys/fs/cgroup"
|
||||
|
||||
def addControllers(cname,*names):
|
||||
controllers = open(cg+ "/" +cname+ "/cgroup.subtree_control").read().split(" ")
|
||||
for name in names:
|
||||
if not name in controllers: open("/sys/fs/cgroup/" +cname+ "/cgroup.subtree_control","a").write("+" +name+ "\n")
|
||||
|
||||
def create(name):
|
||||
if not os.path.isdir(cg+ "/" +name):
|
||||
os.makedirs(cg+ "/" +name)
|
||||
|
||||
def setProp(name,prop,value):
|
||||
open(cg+ "/" +name+ "/" +prop,"w").write(value)
|
||||
|
||||
def setGroup(pid,name):
|
||||
print("Setting cgroup of " +pid+ " to: '" +name+ "'")
|
||||
open(cg+ "/" +name+ "/cgroup.procs","w").write(pid)
|
||||
|
||||
def getProcs(name):
|
||||
return open(cg+ "/" +name+ "/cgroup.procs").read().split("\n")
|
||||
|
||||
_g.cgroup = globals()
|
|
@ -0,0 +1,89 @@
|
|||
handlerGroups = { # The first group that takes control of a process has priority
|
||||
"firefox": {
|
||||
"idents": ["binSimple:firefox","binSimple:firefox-esr"],
|
||||
"unhookUnmatchedChildren": True,
|
||||
"propsFocused": {
|
||||
"memory.high": "256M"
|
||||
},
|
||||
"propsUnfocused": {
|
||||
"memory.high": "256M",
|
||||
"cpu.weight": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import fnmatch
|
||||
|
||||
for group in handlerGroups:
|
||||
if not "propsFocused" in handlerGroups[group]: handlerGroups[group]["propsFocused"] = {}
|
||||
if not "propsUnfocused" in handlerGroups[group]: handlerGroups[group]["propsUnfocused"] = {}
|
||||
|
||||
requiredControllers = []
|
||||
for group in handlerGroups: # Figure out the required controllers
|
||||
for ptype in ["propsFocused","propsUnfocused"]:
|
||||
for controller in handlerGroups[group][ptype]:
|
||||
controller = controller.split(".",1)[0]
|
||||
if not controller in requiredControllers:
|
||||
requiredControllers.append(controller)
|
||||
_g.cgroup.create("window-cg")
|
||||
_g.cgroup.addControllers("window-cg",*requiredControllers)
|
||||
|
||||
# Create cgroups
|
||||
for group in handlerGroups:
|
||||
_g.cgroup.create("window-cg/" +group+ ".focused")
|
||||
_g.cgroup.addControllers("window-cg/" +group+ ".focused",*requiredControllers)
|
||||
_g.cgroup.create("window-cg/" +group+ ".unfocused")
|
||||
_g.cgroup.addControllers("window-cg/" +group+ ".unfocused",*requiredControllers)
|
||||
|
||||
def doesProcMatch(proc,group):
|
||||
for ident in group["idents"]:
|
||||
iSplit = ident.split(":",1)
|
||||
if fnmatch.fnmatch(proc[iSplit[0]],iSplit[1]):
|
||||
return True
|
||||
return False
|
||||
|
||||
def windowChanged(window):
|
||||
pid = _g.windowSystem.getWindowPID(window)
|
||||
procs = _g.proc.getList()
|
||||
focusedGroup = None
|
||||
|
||||
for group in handlerGroups:
|
||||
try:
|
||||
if doesProcMatch(procs[pid],handlerGroups[group]):
|
||||
focusedGroup = group
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
print("Focused group: " +str(focusedGroup))
|
||||
|
||||
for group in handlerGroups:
|
||||
unhook = handlerGroups[group].get("unhookUnmatchedChildren",True)
|
||||
if unhook:
|
||||
groupProcs = _g.cgroup.getProcs("window-cg/" + group + ".focused") + _g.cgroup.getProcs("window-cg/" + group + ".unfocused")
|
||||
|
||||
for proc in list(procs):
|
||||
match = False
|
||||
try:
|
||||
match = doesProcMatch(procs[proc],handlerGroups[group])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if unhook:
|
||||
try:
|
||||
if not match and proc in groupProcs:
|
||||
_g.cgroup.setGroup(proc,"")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
if not match: continue
|
||||
pproc = procs[proc]
|
||||
del procs[proc]
|
||||
|
||||
if focusedGroup == group:
|
||||
_g.cgroup.setGroup(pproc["pid"],"window-cg/" + group + ".focused")
|
||||
else:
|
||||
_g.cgroup.setGroup(pproc["pid"],"window-cg/" + group + ".unfocused")
|
||||
except Exception:
|
||||
pass
|
|
@ -0,0 +1,23 @@
|
|||
import os
|
||||
def getList():
|
||||
procs = {}
|
||||
for root,dirs,files in os.walk("/proc"):
|
||||
for file in dirs:
|
||||
try:
|
||||
pid = (root + "/" + file).replace("/proc/","",1)
|
||||
for char in pid:
|
||||
if not (char in "0123456789"):
|
||||
pid = None
|
||||
break
|
||||
if pid == None: continue
|
||||
info = {}
|
||||
info["pid"] = pid
|
||||
info["bin"] = os.path.realpath("/proc/" +pid+ "/exe")
|
||||
info["binSimple"] = info["bin"].rsplit(os.path.sep,1)[-1]
|
||||
procs[pid] = info
|
||||
except Exception:
|
||||
pass
|
||||
break
|
||||
return procs
|
||||
|
||||
_g.proc = globals()
|
|
@ -0,0 +1,28 @@
|
|||
import gi
|
||||
gi.require_version("Gtk","3.0")
|
||||
gi.require_version("Wnck","3.0")
|
||||
from gi.repository import Gtk, Wnck
|
||||
import traceback
|
||||
|
||||
def init():
|
||||
wnck_scr = Wnck.Screen.get_default()
|
||||
wnck_scr.force_update()
|
||||
wnck_scr.connect("active-window-changed",sWindowChanged)
|
||||
sWindowChanged(wnck_scr,None)
|
||||
Gtk.main()
|
||||
|
||||
def sWindowChanged(screen, previous_window):
|
||||
window = screen.get_active_window()
|
||||
for module in _g.modules:
|
||||
try:
|
||||
module["windowChanged"](window)
|
||||
except Exception:
|
||||
print(traceback.format_exc())
|
||||
|
||||
def getWindowPID(window):
|
||||
try:
|
||||
return str(window.get_pid())
|
||||
except:
|
||||
return "0"
|
||||
|
||||
_g.windowSystem = globals()
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import os
|
||||
p = os.path.join
|
||||
pUp = os.path.dirname
|
||||
s = False
|
||||
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
|
||||
s = os.path.realpath(sys.executable)
|
||||
else:
|
||||
s = os.path.realpath(__file__)
|
||||
sp = pUp(s)
|
||||
|
||||
import munch
|
||||
|
||||
_g = munch.Munch()
|
||||
_g.modules = []
|
||||
def loadModules():
|
||||
moduleID = 0
|
||||
moduleText = open(p(sp,"modules.txt")).read()
|
||||
moduleText = moduleText.replace("\r","")
|
||||
moduleText = moduleText.strip("\n")
|
||||
moduleText = moduleText.split("\n")
|
||||
for line in moduleText:
|
||||
line = line.split("#",1)[0]
|
||||
line = line.strip(" \t")
|
||||
if line == "": continue
|
||||
g = munch.Munch()
|
||||
g._g = _g
|
||||
_g.modules.append(g)
|
||||
code = compile(
|
||||
open(p(sp,"modules",line + ".py")).read(),
|
||||
p(sp,"modules",line + ".py"),
|
||||
"exec"
|
||||
)
|
||||
exec(code,_g.modules[moduleID])
|
||||
if not "windowChanged" in _g.modules[moduleID]:
|
||||
del _g.modules[moduleID]
|
||||
continue
|
||||
|
||||
moduleID += 1
|
||||
|
||||
def main():
|
||||
loadModules()
|
||||
_g.windowSystem.init()
|
||||
main()
|
Loading…
Reference in New Issue