require 'dbus' require 'singleton' module Compiz class Node include Enumerable def initialize(service, dbus_node) @service = service @node = dbus_node @node.introspect @subnodes = {} end def leaf? @node.has_iface?('org.freedesktop.compiz') && @node["org.freedesktop.compiz"].methods.key?('get') end def each @node.subnodes.each do |n| nnode = __subnode(n) yield nnode unless nnode.leaf? end end def __subnode(name) @subnodes[name] ||= Node.new(@service, @service.object("#{@node.path}/#{name}")) end def __get iface = @node["org.freedesktop.compiz"] iface.get end def __set(*args) iface = @node["org.freedesktop.compiz"] iface.set(*args) end def to_s if leaf? @node.__get.to_s else @node.subnodes.join(", ") end end def method_missing(sym, *args) if sym =~ /^.+=$/ && @node.subnodes.include?(sym.to_s.chop) nnode = __subnode(sym.to_s.chop) if nnode.leaf? nnode.__set(*args) else super end elsif @node.subnodes.include? sym.to_s nnode = __subnode(sym.to_s) if nnode && nnode.leaf? nnode.__get else nnode end else super end end end class Root < Node include Singleton def initialize session = DBus::SessionBus.instance @service = session.service("org.freedesktop.compiz") @node = @service.object("/org/freedesktop/compiz") @node.introspect @subnodes = {} end end end