187 lines
3.0 KiB
Ruby
Executable File
187 lines
3.0 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
|
|
$PROGRAM_NAME = "moltenbar"
|
|
|
|
# Base worker class
|
|
class Worker
|
|
def initialize(config, name, pipe)
|
|
@config = config
|
|
@name = name
|
|
@pipe_in = pipe
|
|
end
|
|
|
|
def run()
|
|
@wpid = fork do
|
|
$PROGRAM_NAME = "moltenbar: worker (#{@name})"
|
|
Signal.trap("INT") do; end
|
|
|
|
mainloop()
|
|
end
|
|
|
|
return @wpid
|
|
end
|
|
|
|
def mainloop()
|
|
loop do
|
|
self.write("I am a dummy")
|
|
sleep(1)
|
|
end
|
|
end
|
|
|
|
def get_pid()
|
|
return @wpid
|
|
end
|
|
|
|
def kill()
|
|
begin
|
|
if Process.getpgid(@wpid) == Process.getpgid($$)
|
|
puts "Killing pid: #{@wpid}"
|
|
Process.kill("HUP", @wpid)
|
|
end
|
|
rescue Errno::ESRCH => err
|
|
puts "#{err}: #{@wpid}"
|
|
end
|
|
end
|
|
|
|
def write(data)
|
|
@pipe_in.puts @name + "\0" + data
|
|
end
|
|
end
|
|
|
|
class DoSystem < Worker
|
|
def initialize(name, pipe)
|
|
@name = name
|
|
@pipe = pipe
|
|
end
|
|
|
|
def mainloop()
|
|
@pipe.each do |cmd|
|
|
system(cmd)
|
|
end
|
|
end
|
|
end
|
|
|
|
module Modules
|
|
@modules = {}
|
|
|
|
def self.add(name, class_name)
|
|
@modules[name] = class_name
|
|
end
|
|
|
|
def self.get
|
|
return @modules
|
|
end
|
|
end
|
|
|
|
class Template
|
|
def initialize(template)
|
|
@template = template
|
|
end
|
|
|
|
def render(config, data)
|
|
@config = config
|
|
@panel_data = data
|
|
|
|
return ERB.new(@template).result(binding())
|
|
end
|
|
end
|
|
|
|
# Kill the workers.
|
|
def cleanup(workers)
|
|
for w in workers do
|
|
w.kill
|
|
end
|
|
|
|
exit(0)
|
|
end
|
|
|
|
def get_x_dims
|
|
return `xrandr`.scan(/current (\d+) x (\d+)/).flatten
|
|
end
|
|
|
|
require 'erb'
|
|
require 'yaml'
|
|
require 'optparse'
|
|
|
|
workers = []
|
|
panel_data = {}
|
|
options = {}
|
|
|
|
OptionParser.new do |opts|
|
|
opts.banner = "Usage: moltenvar [-c]"
|
|
|
|
opts.on("-cCONFIG", "--config=CONFIG") do |v|
|
|
options[:config_file] = v
|
|
end
|
|
end.parse!
|
|
|
|
if ENV["XDG_CONFIG_HOME"] == nil
|
|
conf_dir = ENV["HOME"] + "/.config/moltenbar"
|
|
else
|
|
conf_dir = ENV["XDG_CONFIG_HOME"] + "/moltenbar"
|
|
end
|
|
|
|
options[:config_file] ||= conf_dir + "/rc.yaml"
|
|
|
|
config = YAML.load_file(options[:config_file])
|
|
|
|
config['mod_dir'] ||= conf_dir + "/mod"
|
|
|
|
for m in config['modules'] do
|
|
load("#{config['mod_dir']}/#{m}")
|
|
end
|
|
|
|
pipe_r, pipe_w = IO.pipe
|
|
|
|
Modules.get.each do |k, v|
|
|
m = Object.const_get(v).new(config, k, pipe_w)
|
|
workers << m
|
|
|
|
m.run
|
|
end
|
|
|
|
Signal.trap("INT") do cleanup(workers); end
|
|
Signal.trap("TERM") do cleanup(workers); end
|
|
|
|
if config['geometry'] == nil
|
|
config['gap'] ||= 0
|
|
config['height'] ||= 14
|
|
|
|
gap = config['gap'].to_i
|
|
|
|
if config['width'] == nil
|
|
y, x = get_x_dims()
|
|
config['width'] = y.to_i - (gap * 2)
|
|
end
|
|
|
|
config['geometry'] = "#{config['width']}x#{config['height']}+#{gap}+#{gap}"
|
|
end
|
|
|
|
lemonbar_cmd = [
|
|
"lemonbar",
|
|
"-g", config['geometry'],
|
|
"-f", config['fontspec'],
|
|
"-n", config['window_name'],
|
|
"-a", config['active_areas'],
|
|
"-F", config['colours']['fg'],
|
|
"-B", config['colours']['bg']
|
|
]
|
|
|
|
puts "Launching lemonbar as: " + lemonbar_cmd.join(" ")
|
|
|
|
IO.popen(lemonbar_cmd, "w+") do |pipe_lb|
|
|
pipe_lb.sync = true
|
|
|
|
sys = DoSystem.new("system", pipe_lb)
|
|
workers << sys
|
|
sys.run()
|
|
|
|
pipe_r.each do |line|
|
|
mod_name, data = line.chomp.split("\0")
|
|
panel_data[mod_name] = data
|
|
|
|
t = Template.new(config['format'])
|
|
pipe_lb.puts t.render(config, panel_data)
|
|
end
|
|
end
|