def set(ctx, window, name, value): """Name is the property atom name as a string. Value is the property value as a JSON value, parsed using InfiniteGlass.fromjson (so any __jsonclass__ values supported by it are supported). In particular, strings are interpreted as atom names, actual string values need to use the __jsonclass__ encoding. Usage examples: \b glass-action window set --window 1234567 IG_COORDS "[1.0, 1.0, 1.0, 1.0]" """ with InfiniteGlass.Display() as display: @glass_action.window_tools.str_to_win(display, window) def set(win): v = value try: v = json.loads(v) except: pass properties = json.loads( json.dumps({name: v}), object_hook=InfiniteGlass.fromjson(display)) for k, v in properties.items(): win[k] = v display.flush() sys.exit(0)
def session(ctx, key): dbpath = os.path.expanduser("~/.config/glass/ghosts.sqlite3") dbconn = sqlite3.connect(dbpath) cur = dbconn.cursor() cur.execute( 'select value from ghosts where key = ? and name = "SM_CLIENT_ID"', (key, )) client_id = json.loads( next(cur)[0], object_hook=InfiniteGlass.fromjson(None)).decode("utf-8") print(client_id)
def expression(ctx, value): with InfiniteGlass.Display() as display: try: value = json.loads(value, object_hook=InfiniteGlass.fromjson(display)) except: pass itemtype, items, fmt = InfiniteGlass.parse_value(display, value) print("%s(%s): %s" % (itemtype, fmt, items)) sys.exit(0)
def set(win): v = value try: v = json.loads(v) except: pass properties = json.loads( json.dumps({name: v}), object_hook=InfiniteGlass.fromjson(display)) for k, v in properties.items(): win[k] = v display.flush() sys.exit(0)
def restore_islands(self): self.restoring_islands = True cur = self.dbconn.cursor() cur.execute("select * from islands order by key") properties = {} currentkey = None for key, name, value in cur: if key != currentkey: if currentkey: island.Island(self, properties, key=currentkey) properties = {} currentkey = key properties[name] = json.loads(value, object_hook=InfiniteGlass.fromjson( self.display)) if currentkey: island.Island(self, properties, key=currentkey) self.restoring_islands = False
def restore_ghosts(self): self.restoring_ghosts = True cur = self.dbconn.cursor() cur.execute("select * from ghosts order by key") properties = {} currentkey = None for key, name, value in cur: if key != currentkey: if currentkey: glass_ghosts.ghost.Shadow(self, properties).activate() properties = {} currentkey = key properties[name] = json.loads(value, object_hook=InfiniteGlass.fromjson( self.display)) if currentkey: glass_ghosts.ghost.Shadow(self, properties).activate() self.restoring_ghosts = False
def __init__(self, display): self.display = display configpath = os.path.expanduser( os.environ.get("GLASS_GHOSTS_CONFIG", "~/.config/glass/ghosts.yml")) with open(configpath) as f: self.config = json.loads( json.dumps(yaml.load(f, Loader=yaml.SafeLoader)), object_hook=InfiniteGlass.fromjson(self.display)) self.changes = False self.windows = {} self.ghosts = {} self.clients = {} self.dbdirpath = os.path.expanduser("~/.config/glass") if not os.path.exists(self.dbdirpath): os.makedirs(self.dbdirpath) self.dbpath = os.path.join(self.dbdirpath, "ghosts.sqlite3") dbexists = os.path.exists(self.dbpath) self.dbconn = sqlite3.connect(self.dbpath) if not dbexists: self.dbconn.execute( "create table ghosts (key text, name text, value text, primary key (key, name))" ) self.dbconn.execute( "create table clients (key text, name text, value text, primary key (key, name))" ) # Order is important here... self.restore_clients() self.restore_config_ghosts() self.restore_ghosts() self.session = glass_ghosts.session.Server(self, display) self.rootwindow = glass_ghosts.rootwindow.RootWindow(self, display) self.components = glass_ghosts.components.Components(self, display) display.mainloop.add_interval(0.5)(self.save_ghosts) InfiniteGlass.DEBUG("init", "Ghosts handler started\n")
def restore_clients(self): self.restoring_clients = True cur = self.dbconn.cursor() cur.execute("select * from clients order by key") properties = {} currentkey = None for key, name, value in cur: if key != currentkey: if currentkey: client = glass_ghosts.client.Client( self, currentkey, properties) self.clients[client.client_id] = client properties = {} currentkey = key properties[name] = json.loads(value, object_hook=InfiniteGlass.fromjson( self.display)) if currentkey: client = glass_ghosts.client.Client(self, currentkey, properties) self.clients[client.client_id] = client self.restoring_clients = False
def __init__(self, display): self.display = display configpath = os.path.expanduser( os.environ.get("GLASS_ISLANDS_CONFIG", "~/.config/glass/islands.yml")) with open(configpath) as f: self.config = json.loads( json.dumps(yaml.load(f, Loader=yaml.SafeLoader)), object_hook=InfiniteGlass.fromjson(self.display)) self.changes = False self.islands = {} self.dbdirpath = os.path.expanduser("~/.config/glass") if not os.path.exists(self.dbdirpath): os.makedirs(self.dbdirpath) self.dbpath = os.path.join(self.dbdirpath, "islands.sqlite3") dbexists = os.path.exists(self.dbpath) self.dbconn = sqlite3.connect(self.dbpath) if not dbexists: self.dbconn.execute( "create table islands (key text, name text, value text, primary key (key, name))" ) self.restore_islands() display.mainloop.add_interval(0.5)(self.save_islands) @display.root.on(mask="StructureNotifyMask", client_type="IG_ISLAND_CREATE") def ClientMessage(win, event): print("message", "RECEIVED CREATE") sys.stderr.flush() self.create() InfiniteGlass.DEBUG("init", "Islands handler started\n")
def main(*arg, **kw): configpath = os.path.expanduser( os.environ.get("GLASS_WIDGET_CONFIG", "~/.config/glass/widgets.json")) with open(configpath) as f: config = yaml.load(f, Loader=yaml.SafeLoader) with InfiniteGlass.Display() as display: for widget_type, widgets in config.items(): for name, widget in widgets.items(): w = display.root.create_window() properties = { "WM_CLASS": "data://glass-widget", "WM_NAME": "data://" + name, "_NET_WM_WINDOW_TYPE": "_NET_WM_WINDOW_TYPE_DESKTOP" } if widget_type == "widgets": properties["IG_LAYER"] = "IG_LAYER_OVERLAY" elif widget_type == "window-decorations": properties["IG_LAYER"] = "IG_LAYER_NONE" properties["IG_ITEM_LAYER"] = "IG_LAYER_DESKTOP" properties["IG_SHADER"] = "IG_SHADER_DECORATION" display.root["IG_WINDOW_DECORATION_" + name.upper()] = ("IG_ITEM", w) elif widget_type == "island-decorations": properties["IG_LAYER"] = "IG_LAYER_NONE" properties["IG_ITEM_LAYER"] = "IG_LAYER_ISLAND" properties["IG_SHADER"] = "IG_SHADER_DECORATION" display.root["IG_ISLAND_DECORATION_" + name.upper()] = ("IG_ITEM", w) properties.update(widget["properties"]) properties = json.loads( json.dumps(properties), object_hook=InfiniteGlass.fromjson(display)) for key, value in properties.items(): w[key] = value w.widget = widget @w.on() def ButtonPress(win, event): parent = win.get("IG_PARENT_WINDOW", None) def n(w): return w and w.get("WM_NAME", str( w.__window__())) or "none" print("%s/%s.%s()" % (n(parent), n(win), win.widget["action"])) target = parent or win target["IG_INPUT_ACTION"] = json.dumps( win.widget["action"]).encode("utf-8") display.root.send(display.root, "IG_INPUT_ACTION", target, "IG_INPUT_ACTION", event_mask=Xlib.X.SubstructureNotifyMask | Xlib.X.SubstructureRedirectMask) display.flush() InfiniteGlass.DEBUG("init", "Widgets started\n")