source: trunk/debathena/debathena/kiosk/gdm-launch-kiosk @ 25554

Revision 25554, 5.4 KB checked in by jdreed, 12 years ago (diff)
Set a parent for the MessageDialog
  • Property svn:executable set to *
Line 
1#!/usr/bin/python -Wall
2
3import dbus
4import dbus.mainloop.glib
5import gtk
6import gtk.glade
7import gobject
8import time
9import os
10import sys
11import subprocess
12from optparse import OptionParser
13
14GLADE_FILE = "/usr/share/debathena-kiosk/gdm-launch-kiosk.glade"
15LAUNCH_COMMAND = "/usr/lib/debathena-kiosk/launch-kiosk"
16
17SM_DBUS_NAME = "org.gnome.SessionManager"
18SM_DBUS_PATH = "/org/gnome/SessionManager"
19SM_DBUS_INTERFACE = "org.gnome.SessionManager"
20SM_CLIENT_DBUS_INTERFACE = "org.gnome.SessionManager.ClientPrivate"
21APP_ID = "debathena-kiosk"
22
23class Kiosk:
24    def __init__(self):
25        self.sessionEnding = False
26        self.sessionBus = dbus.SessionBus()
27        try:
28            self.register_with_sm()
29            self.init_sm_client()
30        except:
31            print "Warning: Cannot register with session manager."
32
33        try:
34            self.xml = gtk.glade.XML(GLADE_FILE)
35        except:
36            print "Failed to create Glade XML object."
37            sys.exit(1)
38        self.kioskWindow = self.xml.get_widget('KioskWindow')
39        self.kioskDialog = self.xml.get_widget('KioskDialog')
40        self.xml.signal_autoconnect(self)
41        # Turn off all window decorations for the login screen.
42        self.kioskWindow.set_decorated(False)
43        # Because the resize anchor in Natty is obscenely large
44        self.kioskWindow.set_property('resizable', False)
45        self.kioskDialog.set_decorated(False)
46        # Position the window near the bottom of the screen, in the center.
47        self.kioskWindow.set_gravity(gtk.gdk.GRAVITY_SOUTH)
48        width, height = self.kioskWindow.get_size()
49        self.kioskWindow.move((gtk.gdk.screen_width() - width) / 2,
50                              gtk.gdk.screen_height() - height - 80)
51        self.kioskWindow.show_all()
52
53    def kioskButton_on_click(self, button):
54        if not self.sessionEnding:
55            if os.path.exists("/var/run/athena-nologin"):
56                errDlg = gtk.MessageDialog(self.kioskWindow,
57                                           gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
58                                           gtk.MESSAGE_ERROR,
59                                           gtk.BUTTONS_CLOSE,
60                                           "This machine is currently taking an update and the kiosk browser can't be launched.  Please try again later.")
61                errDlg.run()
62                errDlg.destroy()
63            else:
64                self.kioskDialog.run()
65
66    def kioskDialogResponseHandler(self, dialog, response_id):
67        if response_id == 1 and not self.sessionEnding:
68            self.launch()
69        self.kioskDialog.hide()
70
71    def launch(self):
72        pid = os.fork()
73        if pid == 0:
74            # Start a new session.
75            os.setsid();
76            # Fork another child to launch the command.
77            pid = os.fork()
78            if pid == 0:
79                # Here in the second child, exec the command.
80                try:
81                    os.execlp("sudo", "sudo", "-n", LAUNCH_COMMAND)
82                except OSError, e:
83                    print "error: Could not run %s as root: %s" % (LAUNCH_COMMAND, e.strerror)
84                    os._exit(255)
85            else:
86                # The first child exits immediately.
87                os._exit(0)
88        else:
89            # Here in the parent: wait for the first child to exit.
90            (pid, status) = os.waitpid(pid, 0)
91            if status != 0:
92                print "error launching command, status %d" % status
93
94    # Connect to the session manager, and register our client.
95    def register_with_sm(self):
96        proxy = self.sessionBus.get_object(SM_DBUS_NAME, SM_DBUS_PATH)
97        sm = dbus.Interface(proxy, SM_DBUS_INTERFACE)
98        autostart_id = os.getenv("DESKTOP_AUTOSTART_ID", default="")
99        self.smClientId = sm.RegisterClient(APP_ID, autostart_id)
100
101    # Set up to handle signals from the session manager.
102    def init_sm_client(self):
103        proxy = self.sessionBus.get_object(SM_DBUS_NAME, self.smClientId)
104        self.smClient = dbus.Interface(proxy, SM_CLIENT_DBUS_INTERFACE)
105        self.smClient.connect_to_signal("QueryEndSession",
106                                         self.sm_on_QueryEndSession)
107        self.smClient.connect_to_signal("EndSession", self.sm_on_EndSession)
108        self.smClient.connect_to_signal("CancelEndSession",
109                                         self.sm_on_CancelEndSession)
110        self.smClient.connect_to_signal("Stop", self.sm_on_Stop)
111
112    # Here on a QueryEndSession signal from the session manager.
113    def sm_on_QueryEndSession(self, flags):
114        self.sessionEnding = True
115        # Response args: is_ok, reason.
116        self.smClient.EndSessionResponse(True, "")
117
118    # Here on an EndSession signal from the session manager.
119    def sm_on_EndSession(self, flags):
120        self.sessionEnding = True
121        # Response args: is_ok, reason.
122        self.smClient.EndSessionResponse(True, "")
123
124    # Here on a CancelEndSession signal from the session manager.
125    def sm_on_CancelEndSession(self):
126        self.sessionEnding = False
127
128    # Here on a Stop signal from the session manager.
129    def sm_on_Stop(self):
130        gtk.main_quit()
131
132def main():
133    if not os.access(GLADE_FILE, os.R_OK):
134        print 'error: Unable to read glade file "' + GLADE_FILE + '"'
135        sys.exit(1)
136    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
137    Kiosk()
138    gtk.main()
139
140if __name__ == '__main__':
141    main()
Note: See TracBrowser for help on using the repository browser.