Skip to content

Instantly share code, notes, and snippets.

@3v1n0
Last active June 20, 2018 16:31
Show Gist options
  • Save 3v1n0/58c13a8bac4008a82cd66084fc71c95a to your computer and use it in GitHub Desktop.
Save 3v1n0/58c13a8bac4008a82cd66084fc71c95a to your computer and use it in GitHub Desktop.
Parse GTK Menu Model
#!/usr/bin/python
from __future__ import print_function
import re
import signal
import subprocess
import sys
from gi.repository import Gio, Gtk, GLib
xwininfo = subprocess.check_output(["xwininfo"]).decode('utf-8')
xid = int(re.search('Window id: (0x[0-9A-Fa-f]+) ', xwininfo).group(1), 16)
def get_x_property(xid, prop):
value = subprocess.check_output("xprop {} -id {}".format(prop, xid).split()).decode('utf-8')
return re.search(' = "([^\"]+)', value).group(1)
# Workaround Ctrl+C not working with gio-gtk3
signal.signal(signal.SIGINT, signal.SIG_DFL)
bus = Gio.bus_get_sync(Gio.BusType.SESSION)
menus = Gio.DBusMenuModel.get(bus, get_x_property(xid, "_GTK_UNIQUE_BUS_NAME"),
get_x_property(xid, "_GTK_MENUBAR_OBJECT_PATH"))
menus_ref = [menus]
def iterate_menus(menus, level=0):
global menus_ref
print(level*"\t","callback,",menus," menusize: ",menus.get_n_items())
for i in range(menus.get_n_items()):
miter = menus.iterate_item_attributes(i)
while miter.next():
print(level*"\t","attr:",miter.get_name()," = ",miter.get_value())
miter = menus.iterate_item_links(i)
while miter.next():
menu = miter.get_value()
print(level*"\t","link:",miter.get_name()," = ",menu)
menus_ref.append(menu)
menu.connect("items-changed", on_items_changed, level+1)
menu.get_n_items()
def on_items_changed(menus, position, removed, added, level=0):
iterate_menus(menus, level)
menus.connect("items-changed", on_items_changed)
menus.get_n_items()
GLib.MainLoop.new(None, False).run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment