#!/bin/env python import os, subprocess, sys import shlex import xml.dom.minidom as dom def get_waybox_pid(name='waybox'): lines = subprocess.Popen(['pgrep', '-x', name], stdout=subprocess.PIPE).stdout.read().splitlines() if lines: return int(lines[0]) else: return 0 def get_menu_items(menu, indent, expand): menu_id = menu.getAttribute('id') nonselectable = str(bool(menu_id == '')).lower() print("%s%s ⇢\0info\x1f{\"menu\": \"%s\"}\x1fnonselectable\x1f%s" % (indent, menu.getAttribute('label').replace('_', '') or menu_id, menu_id, nonselectable)) indent = indent + " " children = menu.childNodes for i in range(0, children.length): if expand: if children[i].nodeType == dom.Node.ELEMENT_NODE and children[i].tagName == 'item': action = children[i].getElementsByTagName('action')[0].getAttribute('name') cmd = "" icon = children[i].getAttribute('icon') label = children[i].getAttribute('label').replace('_', '') if action == 'Execute': cmd = children[i].getElementsByTagName('execute')[0].firstChild.nodeValue elif action == 'Exit': cmd = "kill -s SIGTERM %d" % get_waybox_pid() elif action == 'Reconfigure': cmd = "kill -s SIGUSR2 %d" % get_waybox_pid() print("%s\0info\x1f{\"exec\": \"%s\"}\x1ficon\x1f%s\x1fdisplay\x1f%s %s" % (cmd, cmd.replace('"', '\\"'), icon, indent, label)) elif children[i].nodeType == dom.Node.ELEMENT_NODE and children[i].tagName == 'menu': if children[i].getAttribute('execute') == "": get_menu_items(children[i], indent, os.getenv('ROFI_RETV') is None) else: try: import xml.parsers.expat lines = subprocess.Popen(shlex.split(children[i].getAttribute('execute')), stdout=subprocess.PIPE).stdout.read() pipe = dom.parseString(lines) pipes = pipe.getElementsByTagName('menu') for j in range(0, pipes.length): get_menu_items(pipes[j], indent, True) # If a script doesn't function correctly anymore, don't stop rendering the menu except xml.parsers.expat.ExpatError: pass menu_xml = os.getenv("WB_MENU_XML") or "menu.xml" document = dom.parse(menu_xml) print("\0message\x1f%s" % os.path.abspath(menu_xml)) if not (info := os.getenv('ROFI_INFO')) is None: import json obj = json.JSONDecoder().decode(s=info) if 'exec' in info: subprocess.Popen(shlex.split(obj['exec']), stdout=subprocess.PIPE) sys.exit(0) elif 'menu' in obj: # Eh document.getElementById() seems not to work menus = document.getElementsByTagName('menu') for i in range(0, menus.length): if menus[i].getAttribute('id') == obj['menu']: menu = menus[i] if not menu is None: get_menu_items(menu, "", True) print("---\0nonselectable\x1ftrue") break root_menu = document.getElementsByTagName('menu')[0] get_menu_items(root_menu, "", True)