Skip to content

Commit

Permalink
#228: refactor gtk menus / actions code into utility functions
Browse files Browse the repository at this point in the history
git-svn-id: https://xpra.org/svn/Xpra/trunk@10680 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Sep 25, 2015
1 parent 35b2f8f commit f54837f
Show file tree
Hide file tree
Showing 3 changed files with 378 additions and 302 deletions.
213 changes: 89 additions & 124 deletions src/tests/xpra/x11/get_gtk_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,141 +5,106 @@
# later version. See the file COPYING for details.

import sys
from xpra.x11.gtk2.gdk_display_source import display #@UnresolvedImport
from xpra.x11.gtk_x11.prop import prop_get
from xpra.util import AdHocStruct
from xpra.dbus.helper import DBusHelper
from xpra.log import Logger
log = Logger("dbus")

#beware: this import has side-effects:
import dbus.glib
assert dbus.glib

from xpra.dbus.common import loop_init
def get_menuaction_props(w):
from xpra.x11.gtk_x11.prop import prop_get
def pget(key, etype):
return prop_get(w, key, etype, ignore_errors=True, raise_xerrors=True)
props = {}
for k,x11name in {
"application-id" : "_GTK_APPLICATION_ID", #ie: org.gnome.baobab
"bus-name" : "_GTK_UNIQUE_BUS_NAME", #ie: :1.745
"application-path" : "_GTK_APPLICATION_OBJECT_PATH", #ie: /org/gnome/baobab
"app-menu-path" : "_GTK_APP_MENU_OBJECT_PATH", #ie: /org/gnome/baobab/menus/appmenu
"window-path" : "_GTK_WINDOW_OBJECT_PATH", #ie: /org/gnome/baobab/window/1
}.items():
v = pget(x11name, "utf8")
if v:
props[k] = v
return props


def main(args):
wid = sys.argv[1]
w = AdHocStruct()
if wid.startswith("0x"):
w.xid = int(wid[2:], 16)
else:
w.xid = int(wid)
def pget(key, etype, ignore_errors=True):
return prop_get(w, key, etype, ignore_errors=False, raise_xerrors=False)
#ie: /org/gnome/baobab/menus/appmenu
menu_path = pget("_GTK_APP_MENU_OBJECT_PATH", "utf8")
#ie: /org/gnome/baobab/window/1
window_path = pget("_GTK_WINDOW_OBJECT_PATH", "utf8")
#ie: /org/gnome/baobab
app_path = pget("_GTK_APPLICATION_OBJECT_PATH", "utf8")
#ie: :1.745
bus_name = pget("_GTK_UNIQUE_BUS_NAME", "utf8")
#ie: org.gnome.baobab
app_id = pget("_GTK_APPLICATION_ID", "utf8")
props = {
"app-menu-path" : menu_path,
"window-path" : window_path,
"application-path" : app_path,
"bus-name" : bus_name,
"application-id" : app_id,
}
print("gtk menu properties for window %s on display %s: %s" % (wid, display.get_name(), props))
def query_menuactions(app_id, bus_name,
app_path, app_actions_cb, app_actions_err,
window_path, window_actions_cb, window_actions_err,
menu_path, menu_cb, menu_err):
if not (menu_path and window_path and app_path and bus_name and app_id):
print("some properties are missing - cannot continue")
log.error("Error: some properties are missing - cannot continue")
return
from xpra.dbus.gtk_menuactions import query_actions, query_menu
aa = query_actions(bus_name, app_path, app_actions_cb, app_actions_err)
wa = query_actions(bus_name, window_path, window_actions_cb, window_actions_err)
am = query_menu(bus_name, menu_path, menu_cb, menu_err)
return (aa, wa, am)

loop_init()
import gobject
loop = gobject.MainLoop()
dbus_helper = DBusHelper()
def n(*args):
return dbus_helper.dbus_to_native(*args)
def ni(*args):
return int(n(*args))

bus = dbus_helper.get_session_bus()
window = bus.get_object(bus_name, window_path)
print("window=%s" % window)

#actions:
interface = "org.gtk.Actions"
iface = dbus.Interface(window, interface)
print("iface(%s)=%s" % (interface, iface))
def actions_changed(*args):
print("actions_changed%s" % str(args))
iface.connect_to_signal("Changed", actions_changed)

def list_cb(*args):
values = dbus_helper.dbus_to_native(args[0])
print("list_cb: values=%s" % str(values))
def list_err(*args):
print("list_err%s" % str(args))
dbus_helper.call_function(bus_name, window_path, interface, "List", [], list_cb, list_err)
dbus_helper.call_function(bus_name, app_path, interface, "List", [], list_cb, list_err)
def dump_menuactions(display, xid):
from xpra.util import AdHocStruct
w = AdHocStruct()
w.xid = xid
try:
props = get_menuaction_props(w)
except Exception as e:
log.error("Error: failed to get menus / actions for window %s:", w)
log.error(" %s", e)
return None

def describe_actions_cb(*args):
print("describe_actions_cb:")
values = dbus_helper.dbus_to_native(args[0])
#print("describe_cb: values=%s" % str(values))
actions = {}
for k,v in values.items():
#enabled, parameter type, state
mdef = [bool(n(v[0])), n(v[1]), [n(x) for x in v[2]]]
#print(" %s=%s" % (k, mdef))
actions[k] = mdef
print("actions=%s" % actions)
def describe_actions_err(*args):
print("describe_actions_err%s" % str(args))
dbus_helper.call_function(bus_name, window_path, interface, "DescribeAll", [], describe_actions_cb, describe_actions_err)
dbus_helper.call_function(bus_name, app_path, interface, "DescribeAll", [], describe_actions_cb, describe_actions_err)
log("gtk menu properties for window %#x on display %s: %s", xid, display.get_name(), props)
app_id = props.get("application-id")
bus_name = props.get("bus-name")
app_path = props.get("application-path")
menu_path = props.get("app-menu-path")
window_path = props.get("window-path")
if not (app_id and bus_name and app_path and menu_path and window_path):
log.error("Error: some properties are missing - cannot continue")
return

#app menu:
interface = "org.gtk.Menus"
iface = dbus.Interface(window, interface)
print("iface(%s)=%s" % (interface, iface))
def menus_changed(*args):
print("menus_changed%s" % str(args))
iface.connect_to_signal("Changed", menus_changed)
return query_menuactions(app_id, bus_name,
app_path, None, None,
window_path, None, None,
menu_path, None, None)

def menus_start_cb(*args):
#print("menus_start_cb args=%s" % str(args))
#print("menus_start_cb args[0]=%s" % str(args[0]))
values = n(args[0])
#print("menus_start_cb values=%s" % str(values))
menus = {}
for sgroup, menuno, items in values:
print(" %s: %s - %s" % (sgroup, menuno, n(items)))
dmenus = []
for d in items:
menu = {}
section = d.get(":section")
submenu = d.get(":submenu")
if section:
#subscription, menu
menu[":section"] = ni(section[0]), ni(section[1])
elif section or submenu:
#subscription, menu
menu[":submenu"] = ni(section[0]), ni(section[1])
else:
#action?
for k in ("action", "label"):
if k in d:
menu[k] = n(d[k])
if menu:
target = d.get("target")
if target:
menu["target"] = [n(target[x]) for x in range(len(target))]
#print("target=%s (len=%s)" % (target, len(target)))
if menu:
dmenus.append(menu)
menus.setdefault(ni(sgroup), {})[ni(menuno)] = dmenus
print("menus=%s" % menus)
#values = dbus_helper.dbus_to_native(args[0])
def menus_start_err(*args):
print("menus_start_err%s" % str(args))
dbus_helper.call_function(bus_name, menu_path, interface, "Start", [[0]], menus_start_cb, menus_start_err)

loop.run()
def main(args):
from xpra.platform import init, clean
from xpra.log import enable_color
try:
init("GTK-Menu Info")
enable_color()
if "-q" in sys.argv:
sys.argv.remove("-q")
elif "--quiet" in sys.argv:
sys.argv.remove("--quiet")
else:
log.enable_debug()
from xpra.dbus.gtk_menuactions import log as gtkmalog
gtkmalog.enable_debug()
try:
from xpra.x11.gtk2.gdk_display_source import display #@UnresolvedImport
wid = sys.argv[1]
if wid.startswith("0x"):
xid = int(wid[2:], 16)
else:
xid = int(wid)
except Exception as e:
log.error("Error: invalid window id: %s", e)
log.error("usage:")
log.error(" %s WINDOWID", sys.argv[0])
else:
#beware: this import has side-effects:
import dbus.glib
assert dbus.glib
from xpra.dbus.common import loop_init
loop_init()
import gobject
loop = gobject.MainLoop()
v = dump_menuactions(display, xid)
loop.run()
del v
finally:
clean()


if __name__ == '__main__':
Expand Down
Loading

0 comments on commit f54837f

Please sign in to comment.