diff --git a/src/tests/xpra/x11/get_gtk_menu.py b/src/tests/xpra/x11/get_gtk_menu.py new file mode 100755 index 0000000000..553b36aed5 --- /dev/null +++ b/src/tests/xpra/x11/get_gtk_menu.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# This file is part of Xpra. +# Copyright (C) 2015 Antoine Martin +# Xpra is released under the terms of the GNU GPL v2, or, at your option, any +# 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 + +#beware: this import has side-effects: +import dbus.glib +assert dbus.glib + +from xpra.dbus.common import loop_init + + +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)) + + loop_init() + import gobject + loop = gobject.MainLoop() + dbus_helper = DBusHelper() + def n(*args): + return dbus_helper.dbus_to_native(*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", args, list_cb, list_err) + + def describe_cb(*args): + print("describe_cb:") + #print("describe_cb%s" % str(args)) + values = dbus_helper.dbus_to_native(args[0]) + #print("describe_cb: values=%s" % str(values)) + 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)) + def describe_err(*args): + print("describe_err%s" % str(args)) + dbus_helper.call_function(bus_name, window_path, interface, "DescribeAll", [], describe_cb, describe_err) + + #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) + + def start_cb(*args): + print("start_cb args=%s" % str(args)) + print("start_cb args[0]=%s" % str(args[0])) + #print("start_cb args[0][0]=%s" % str(args[0][0])) + values = n(args[0]) + print("start_cb values=%s" % str(values)) + for sgroup, menuno, items in values: + print(" %s: %s - %s" % (sgroup, menuno, n(items))) + #values = dbus_helper.dbus_to_native(args[0]) + def start_err(*args): + print("describe_cb%s" % str(args)) + dbus_helper.call_function(bus_name, menu_path, interface, "Start", [[0]], start_cb, start_err) + + loop.run() + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/src/xpra/dbus/common.py b/src/xpra/dbus/common.py index 0fbbc6608e..771c10813d 100644 --- a/src/xpra/dbus/common.py +++ b/src/xpra/dbus/common.py @@ -3,14 +3,13 @@ # Xpra is released under the terms of the GNU GPL v2, or, at your option, any # later version. See the file COPYING for details. -_loop_init_done = False +_loop = None def loop_init(): - global _loop_init_done - if _loop_init_done: - return - from dbus.mainloop.glib import DBusGMainLoop - DBusGMainLoop(set_as_default=True) - _loop_init_done = True + global _loop + if not _loop: + from dbus.mainloop.glib import DBusGMainLoop + _loop = DBusGMainLoop(set_as_default=True) + return _loop _session_bus = None def init_session_bus(): diff --git a/src/xpra/dbus/helper.py b/src/xpra/dbus/helper.py index c7ca140cb9..7108f83b28 100644 --- a/src/xpra/dbus/helper.py +++ b/src/xpra/dbus/helper.py @@ -15,6 +15,9 @@ def __init__(self): from xpra.dbus.common import init_session_bus self.bus = init_session_bus() + def get_session_bus(self): + return self.bus + def call_function(self, bus_name, path, interface, function, args, ok_cb, err_cb): try: #remote_object = self.bus.get_object("com.example.SampleService","/SomeObject")