From 973e260d2935646bf378880f194fd2e5df3e20a5 Mon Sep 17 00:00:00 2001 From: Willie Walker Date: Thu, 28 Jan 2010 18:19:34 -0500 Subject: [PATCH] Partial fix for bfo#26039 - a11y bus does not participate in session management. This converts the at-spi-dbus-bus file into a Python script that connects to the session management API. It works OK except that: 1) The subprocess is not killed when I log out. I'm using the 'terminate' method to kill it and wonder if I should use 'kill' instead. 2) Launching the bus via the *.desktop file seems to still cause some sort of hang when an assistive technology then uses pyatspi. The test command I type is: python -c "import pyatspi; print(map(lambda x: x.name, filter(lambda x: x, pyatspi.Registry.getDesktop(0))))" --- bus/Makefile.am | 2 +- bus/at-spi-dbus-bus.desktop.in | 4 +- bus/at-spi-dbus-bus.in | 92 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 89 insertions(+), 9 deletions(-) diff --git a/bus/Makefile.am b/bus/Makefile.am index 9f0b5d4..885d447 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -14,7 +14,7 @@ EXTRA_DIST= \ at-spi-dbus-bus.desktop.in %.desktop: %.desktop.in Makefile.am - sed -e "s,\@bindir\@,$(EXPANDED_BINDIR)," < $< > $@ + sed -e "s,\@bindir\@,$(EXPANDED_BINDIR),g" < $< > $@ CLEANFILES= \ at-spi-dbus-bus.desktop diff --git a/bus/at-spi-dbus-bus.desktop.in b/bus/at-spi-dbus-bus.desktop.in index fadf900..a4e1ac0 100644 --- a/bus/at-spi-dbus-bus.desktop.in +++ b/bus/at-spi-dbus-bus.desktop.in @@ -1,9 +1,9 @@ [Desktop Entry] Type=Application Name=AT SPI D-Bus Bus -Exec=@bindir@/at-spi-dbus-bus +Exec=@bindir@/dbus-launch --exit-with-session @bindir@/at-spi-dbus-bus OnlyShowIn=GNOME; NoDisplay=true AutostartCondition=GNOME /desktop/gnome/interface/accessibility X-GNOME-AutoRestart=true -#X-GNOME-Autostart-Phase=Initialization +X-GNOME-Autostart-Phase=Initialization diff --git a/bus/at-spi-dbus-bus.in b/bus/at-spi-dbus-bus.in index 2c4f180..6a53af4 100644 --- a/bus/at-spi-dbus-bus.in +++ b/bus/at-spi-dbus-bus.in @@ -1,8 +1,88 @@ -#!/bin/sh +#!/usr/bin/env python -prefix=@prefix@ -sysconfdir=@sysconfdir@ -daemondir=@DBUS_DAEMONDIR@ +import os +import subprocess -address=`${daemondir}/dbus-daemon --config-file=${sysconfdir}/at-spi2/accessibility.conf --print-address` -xprop -root -f AT_SPI_BUS 8s -set AT_SPI_BUS ${address} +SM_DBUS_NAME = "org.gnome.SessionManager" +SM_DBUS_PATH = "/org/gnome/SessionManager" +SM_DBUS_INTERFACE = "org.gnome.SessionManager" +SM_CLIENT_DBUS_INTERFACE = "org.gnome.SessionManager.ClientPrivate" + +COMMAND = [ + os.path.join("@DBUS_DAEMONDIR@", "dbus-daemon"), + "--nofork", + "--print-address", + "--config-file=" \ + + os.path.join("@sysconfdir@", "at-spi2", "accessibility.conf") +] + +def set_at_spi_bus_property(address, remove=False): + if remove: + command = ["xprop", "-root", "-remove", "AT_SPI_BUS"] + else: + command = ["xprop", + "-root", "-f", "AT_SPI_BUS", "8s", "-set", + "AT_SPI_BUS", address] + subprocess.call(command) + +def start_accessibility_bus(): + accessibility_bus_process = subprocess.Popen(COMMAND, + bufsize=0, + stdout=subprocess.PIPE) + address = accessibility_bus_process.stdout.readline().strip() + return (accessibility_bus_process, address) + +def stop_handler(*args, **kwargs): + loop.quit() + +def query_end_session_handler(*args, **kwargs): + client.EndSessionResponse(True, "OK with me") + +def end_session_handler(*args, **kwargs): + client.EndSessionResponse(True, "OK with me") + loop.quit() + +def setup_session_management(): + global client + import dbus + from dbus.mainloop.glib import DBusGMainLoop + DBusGMainLoop(set_as_default=True) + + import os + desktop_autostart_id = os.getenv("DESKTOP_AUTOSTART_ID") + if not desktop_autostart_id: + print "DESKTOP_AUTOSTART_ID is not defined." + print "Not participating in session management." + return + + session_bus = dbus.SessionBus() + session_manager_proxy = session_bus.get_object(SM_DBUS_NAME, + SM_DBUS_PATH) + session_manager = dbus.Interface(session_manager_proxy, + dbus_interface=SM_DBUS_INTERFACE) + + client_id = session_manager.RegisterClient("at-spi-dbus-bus", + desktop_autostart_id) + client_proxy = session_bus.get_object(SM_DBUS_NAME, + client_id) + client = dbus.Interface(client_proxy, + dbus_interface=SM_CLIENT_DBUS_INTERFACE) + + client.connect_to_signal("Stop", stop_handler) + client.connect_to_signal("QueryEndSession", query_end_session_handler) + client.connect_to_signal("EndSession", end_session_handler) + +(process, address) = start_accessibility_bus() +set_at_spi_bus_property(address) + +try: + setup_session_management() +except: + print "Not participating in session management." + +import gobject +loop = gobject.MainLoop() +loop.run() + +set_at_spi_bus_property(None, remove=True) +process.terminate() -- 1.5.6.5