diff --git a/.bzrignore b/.bzrignore index ee3a330..3de9285 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1,3 +1,4 @@ +MANIFEST dist build *.new diff --git a/MANIFEST b/MANIFEST deleted file mode 100644 index 56b8f53..0000000 --- a/MANIFEST +++ /dev/null @@ -1,33 +0,0 @@ -LICENSE -README -oblogout -openbox-logout.conf -setup.py -openboxlogout/__init__.py -openboxlogout/openboxlogout.py -openboxlogout/locale/en/LC_MESSAGES/openboxlogout.mo -openboxlogout/locale/en_GB/LC_MESSAGES/openboxlogout.mo -openboxlogout/pofiles/openboxlogout_en.po -openboxlogout/pofiles/openboxlogout_en_GB.po -openboxlogout/themes/default/cancel.png -openboxlogout/themes/default/logout.png -openboxlogout/themes/default/restart.png -openboxlogout/themes/default/shutdown.png -openboxlogout/themes/foom/cancel.png -openboxlogout/themes/foom/hibernate.png -openboxlogout/themes/foom/lock.png -openboxlogout/themes/foom/logout.png -openboxlogout/themes/foom/oblog_icons.7z -openboxlogout/themes/foom/restart.png -openboxlogout/themes/foom/shutdown.png -openboxlogout/themes/foom/suspend.png -openboxlogout/themes/foom/switch.png -openboxlogout/themes/oxygen/cancel.png -openboxlogout/themes/oxygen/hibernate.png -openboxlogout/themes/oxygen/lock.png -openboxlogout/themes/oxygen/logout.png -openboxlogout/themes/oxygen/restart.png -openboxlogout/themes/oxygen/safesuspend.png -openboxlogout/themes/oxygen/shutdown.png -openboxlogout/themes/oxygen/suspend.png -openboxlogout/themes/oxygen/switch.png diff --git a/data/oblogout b/data/oblogout index 3e826fc..dce2ead 100755 --- a/data/oblogout +++ b/data/oblogout @@ -28,7 +28,7 @@ import sys import getopt import logging import logging.handlers -from oblogout import oblogout +from oblogout import OpenboxLogout class Usage(Exception): def __init__(self, msg): @@ -89,7 +89,7 @@ def main(argv = None): logger.setLevel(logging.INFO) # Start the application - app = oblogout.OpenboxLogout(config, local_mode) + app = OpenboxLogout(config, local_mode) app.run_logout() return 0 diff --git a/oblogout/__init__.py b/oblogout/__init__.py index e69de29..a831766 100644 --- a/oblogout/__init__.py +++ b/oblogout/__init__.py @@ -0,0 +1,404 @@ +#!/usr/bin/env python + +# Crunchbang Openbox Logout +# - GTK/Cairo based logout box styled for Crunchbang +# +# Andrew Williams +# +# Originally based on code by: +# adcomp +# iggykoopa +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +import os +import sys +import ConfigParser +import StringIO +import logging +import gettext +import string + +import pygtk +pygtk.require('2.0') + +try: + import gtk +except: + print "pyGTK missing, install python-gtk2" + sys.exit() + +try: + import cairo +except: + print "Cairo modules missing, install python-cairo" + +try: + from PIL import Image, ImageFilter +except: + print "PIL missing, install python-imaging" + sys.exit() + +class OpenboxLogout(): + + cmd_shutdown = "shutdown -h now" + cmd_restart = "reboot" + cmd_suspend = "pmi action suspend" + cmd_hibernate = "pmi action hibernate" + cmd_safesuspend = "" + cmd_lock = "gnome-screensaver-command -l" + cmd_switchuser = "gdm-control --switch-user" + cmd_logout = "openbox --exit" + + def __init__(self, config=None, local=None): + + if local: + self.local_mode = True + else: + self.local_mode = False + + # Start logger and gettext/i18n + self.logger = logging.getLogger(self.__class__.__name__) + + if self.local_mode: + gettext.install('oblogout', 'mo', unicode=1) + else: + gettext.install('oblogout', '%s/share/locale' % sys.prefix, unicode=1) + + # Load configuration file + self.load_config(config) + + # Start the window + self.__init_window() + + def __init_window(self): + # Start pyGTK setup + self.window = gtk.Window() + self.window.set_title(_("Openbox Logout")) + + self.window.connect("destroy", self.quit) + self.window.connect("key-press-event", self.on_keypress) + self.window.connect("window-state-event", self.on_window_state_change) + + if not self.window.is_composited(): + self.logger.debug("No compositing, enabling rendered effects") + # Window isn't composited, enable rendered effects + self.rendered_effects = True + else: + # Link in Cairo rendering events + self.window.connect('expose-event', self.on_expose) + self.window.connect('screen-changed', self.on_screen_changed) + self.on_screen_changed(self.window) + self.rendered_effects = False + + self.window.set_size_request(620,200) + self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("black")) + + self.window.set_decorated(False) + self.window.set_position(gtk.WIN_POS_CENTER) + + # Create the main panel box + self.mainpanel = gtk.HBox() + + # Create the button box + self.buttonpanel = gtk.HButtonBox() + self.buttonpanel.set_spacing(10) + + # Pack in the button box into the panel box, with two padder boxes + self.mainpanel.pack_start(gtk.VBox()) + self.mainpanel.pack_start(self.buttonpanel, False, False) + self.mainpanel.pack_start(gtk.VBox()) + + # Add the main panel to the window + self.window.add(self.mainpanel) + + for button in self.button_list: + self.__add_button(button, self.buttonpanel) + + if self.rendered_effects == True: + self.logger.debug("Stepping though render path") + w = gtk.gdk.get_default_root_window() + sz = w.get_size() + pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1]) + pb = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1]) + + self.logger.debug("Rendering Fade") + # Convert Pixbuf to PIL Image + wh = (pb.get_width(),pb.get_height()) + pilimg = Image.fromstring("RGB", wh, pb.get_pixels()) + + pilimg = pilimg.point(lambda p: (p * self.opacity) / 255 ) + + # "Convert" the PIL to Pixbuf via PixbufLoader + buf = StringIO.StringIO() + pilimg.save(buf, "ppm") + del pilimg + loader = gtk.gdk.PixbufLoader("pnm") + loader.write(buf.getvalue()) + pixbuf = loader.get_pixbuf() + + # Cleanup IO + buf.close() + loader.close() + + pixmap, mask = pixbuf.render_pixmap_and_mask() + # width, height = pixmap.get_size() + else: + pixmap = None + + self.window.set_app_paintable(True) + self.window.resize(gtk.gdk.screen_width(), gtk.gdk.screen_height()) + self.window.realize() + + if pixmap: + self.window.window.set_back_pixmap(pixmap, False) + self.window.move(0,0) + + + def load_config(self, config): + """ Load the configuration file and parse entries, when encountering a issue + change safe defaults """ + + self.parser = ConfigParser.SafeConfigParser() + self.parser.read(config) + + # Set some safe defaults + self.opacity = 50 + self.button_theme = "default" + self.bgcolor = gtk.gdk.color_parse("black") + blist = "" + + if self.parser.has_section("settings"): + + if self.parser.has_option("settings","usehal"): + self.usehal = self.parser.getboolean("settings","usehal") + else: + self.usehal = True + + if self.usehal: + from dbushandler import DbusController + self.dbus = DbusController() + + # Check the looks section and load the config as required + if self.parser.has_section("looks"): + + if self.parser.has_option("looks", "opacity"): + self.opacity = self.parser.getint("looks", "opacity") + + if self.parser.has_option("looks","buttontheme"): + self.button_theme = self.parser.get("looks", "buttontheme") + + if self.parser.has_option("looks", "bgcolor"): + try: + self.bgcolor = gtk.gdk.color_parse(self.parser.get("looks", "bgcolor")) + except: + self.logger.warning(_("Color %s is not a valid color, defaulting to black") % self.parser.get("looks", "bgcolor")) + self.bgcolor = gtk.gdk.color_parse("black") + + if self.parser.has_option("looks", "opacity"): + blist = self.parser.get("looks", "buttons") + + if self.parser.has_section("shortcuts"): + self.shortcut_keys = self.parser.items("shortcuts") + self.logger.debug("Shortcut Options: %s" % self.shortcut_keys) + + + if self.local_mode: + self.theme_prefix = "./data/themes" + else: + self.theme_prefix = "%s/share/themes" % sys.prefix + + self.img_path = "%s/%s/oblogout" % (self.theme_prefix, self.button_theme) + + if os.path.exists("%s/.themes/%s/oblogout" % (os.environ['HOME'], self.button_theme)): + # Found a valid theme folder in the userdir, use that + self.img_path = "%s/.themes/%s/oblogout" % (os.environ['HOME'], self.button_theme) + self.logger.info("Using user theme at %s" % self.img_path) + else: + if not os.path.exists("%s/%s/oblogout" % (self.theme_prefix, self.button_theme)): + self.logger.warning("Button theme %s not found, reverting to default" % self.button_theme) + self.button_theme = 'foom' + + + # Load and parse button list + validbuttons = ['cancel', 'logout', 'restart', 'shutdown', 'suspend', 'hibernate', 'safesuspend', 'lock', 'switch'] + buttonname = [_('cancel'), _('logout'), _('restart'), _('shutdown'), _('suspend'), _('hibernate'), _('safesuspend'), _('lock'), _('switch')] + + if not blist: + list = validbuttons + elif blist == "default": + list = validbuttons + else: + list = map(lambda button: string.strip(button), blist.split(",")) + + # Validate the button list + for button in list: + if not button in validbuttons: + self.logger.warning(_("Button %s is not a valid button name, removing") % button) + list.remove(button) + else: + if self.usehal: + if not self.dbus.check_ability(button): + self.logger.warning(_("Can't %s, disabling button" % button)) + list.remove(button) + + if len(list) == 0: + self.logger.warning(_("No valid buttons found, resetting to defaults")) + self.button_list = validbuttons + else: + self.logger.debug("Validated Button List: %s" % list) + self.button_list = list + + + def on_expose(self, widget, event): + + cr = widget.window.cairo_create() + + if self.supports_alpha == True: + cr.set_source_rgba(1.0, 1.0, 1.0, 0.0) # Transparent + else: + cr.set_source_rgb(1.0, 1.0, 1.0) # Opaque white + + # Draw the background + cr.set_operator(cairo.OPERATOR_SOURCE) + cr.paint() + + (width, height) = widget.get_size() + cr.set_source_rgba(self.bgcolor.red, self.bgcolor.green, self.bgcolor.blue, float(self.opacity)/100) + + cr.rectangle(0, 0, width, height) + cr.fill() + cr.stroke() + return False + + def on_screen_changed(self, widget, old_screen=None): + + # To check if the display supports alpha channels, get the colormap + screen = widget.get_screen() + colormap = screen.get_rgba_colormap() + if colormap == None: + self.logger.debug("Screen does not support alpha channels!") + colormap = screen.get_rgb_colormap() + self.supports_alpha = False + else: + self.logger.debug("Screen supports alpha channels!") + self.supports_alpha = True + + # Now we have a colormap appropriate for the screen, use it + widget.set_colormap(colormap) + + def on_window_state_change(self, widget, event, *args): + if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN: + self.window_in_fullscreen = True + else: + self.window_in_fullscreen = False + + def __add_button(self, name, widget): + """ Add a button to the panel """ + + box = gtk.VBox() + + image = gtk.Image() + if os.path.exists("%s/%s.svg" % (self.img_path, name)): + image.set_from_file("%s/%s.svg" % (self.img_path, name)) + else: + image.set_from_file("%s/%s.png" % (self.img_path, name)) + image.show() + + button = gtk.Button() + button.set_relief(gtk.RELIEF_NONE) + button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("black")) + button.set_focus_on_click(False) + button.set_border_width(0) + button.set_property('can-focus', False) + button.add(image) + button.show() + box.pack_start(button, False, False) + button.connect("clicked", self.click_button, name) + + label = gtk.Label(_(name)) + label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("white")) + box.pack_end(label, False, False) + + widget.pack_start(box, False, False) + + def click_button(self, widget, data=None): + if (data == 'logout'): + self.exec_cmd(self.cmd_logout) + + elif (data == 'restart'): + if self.usehal: + self.dbus.restart() + else: + self.exec_cmd(self.cmd_restart) + + elif (data == 'shutdown'): + if self.usehal: + self.dbus.shutdown() + else: + self.exec_cmd(self.cmd_shutdown) + + elif (data == 'suspend'): + self.window.hide() + self.exec_cmd(self.cmd_lock) + if self.usehal: + self.dbus.suspend() + + else: + self.exec_cmd(self.cmd_suspend) + + elif (data == 'hibernate'): + self.window.hide() + self.exec_cmd(self.cmd_lock) + if self.usehal: + self.dbus.hibernate() + else: + self.__exec_cmd(self.cmd_hibernate) + + elif (data == 'safesuspend'): + self.window.hide() + + if self.usehal: + self.dbus.safesuspend() + else: + self.exec_cmd(self.cmd_safesuspend) + + elif (data == 'lock'): + self.__exec_cmd(self.cmd_lock) + + elif (data == 'switch'): + self.__exec_cmd(self.cmd_switchuser) + + self.quit() + + def on_keypress(self, widget=None, event=None, data=None): + self.logger.debug("Keypress: %s/%s" % (event.keyval, gtk.gdk.keyval_name(event.keyval))) + for key in self.shortcut_keys: + if event.keyval == gtk.gdk.keyval_to_lower(gtk.gdk.keyval_from_name(key[1])): + self.logger.debug("Matched %s" % key[0]) + self.click_button(widget, key[0]) + + def __exec_cmd(self, cmdline): + self.logger.debug("Executing command: %s", cmdline) + os.system(cmdline) + + def quit(self, widget=None, data=None): + gtk.main_quit() + + def run_logout(self): + self.window.show_all() + gtk.main() + diff --git a/oblogout/oblogout.py b/oblogout/oblogout.py deleted file mode 100644 index a831766..0000000 --- a/oblogout/oblogout.py +++ /dev/null @@ -1,404 +0,0 @@ -#!/usr/bin/env python - -# Crunchbang Openbox Logout -# - GTK/Cairo based logout box styled for Crunchbang -# -# Andrew Williams -# -# Originally based on code by: -# adcomp -# iggykoopa -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -import os -import sys -import ConfigParser -import StringIO -import logging -import gettext -import string - -import pygtk -pygtk.require('2.0') - -try: - import gtk -except: - print "pyGTK missing, install python-gtk2" - sys.exit() - -try: - import cairo -except: - print "Cairo modules missing, install python-cairo" - -try: - from PIL import Image, ImageFilter -except: - print "PIL missing, install python-imaging" - sys.exit() - -class OpenboxLogout(): - - cmd_shutdown = "shutdown -h now" - cmd_restart = "reboot" - cmd_suspend = "pmi action suspend" - cmd_hibernate = "pmi action hibernate" - cmd_safesuspend = "" - cmd_lock = "gnome-screensaver-command -l" - cmd_switchuser = "gdm-control --switch-user" - cmd_logout = "openbox --exit" - - def __init__(self, config=None, local=None): - - if local: - self.local_mode = True - else: - self.local_mode = False - - # Start logger and gettext/i18n - self.logger = logging.getLogger(self.__class__.__name__) - - if self.local_mode: - gettext.install('oblogout', 'mo', unicode=1) - else: - gettext.install('oblogout', '%s/share/locale' % sys.prefix, unicode=1) - - # Load configuration file - self.load_config(config) - - # Start the window - self.__init_window() - - def __init_window(self): - # Start pyGTK setup - self.window = gtk.Window() - self.window.set_title(_("Openbox Logout")) - - self.window.connect("destroy", self.quit) - self.window.connect("key-press-event", self.on_keypress) - self.window.connect("window-state-event", self.on_window_state_change) - - if not self.window.is_composited(): - self.logger.debug("No compositing, enabling rendered effects") - # Window isn't composited, enable rendered effects - self.rendered_effects = True - else: - # Link in Cairo rendering events - self.window.connect('expose-event', self.on_expose) - self.window.connect('screen-changed', self.on_screen_changed) - self.on_screen_changed(self.window) - self.rendered_effects = False - - self.window.set_size_request(620,200) - self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("black")) - - self.window.set_decorated(False) - self.window.set_position(gtk.WIN_POS_CENTER) - - # Create the main panel box - self.mainpanel = gtk.HBox() - - # Create the button box - self.buttonpanel = gtk.HButtonBox() - self.buttonpanel.set_spacing(10) - - # Pack in the button box into the panel box, with two padder boxes - self.mainpanel.pack_start(gtk.VBox()) - self.mainpanel.pack_start(self.buttonpanel, False, False) - self.mainpanel.pack_start(gtk.VBox()) - - # Add the main panel to the window - self.window.add(self.mainpanel) - - for button in self.button_list: - self.__add_button(button, self.buttonpanel) - - if self.rendered_effects == True: - self.logger.debug("Stepping though render path") - w = gtk.gdk.get_default_root_window() - sz = w.get_size() - pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1]) - pb = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1]) - - self.logger.debug("Rendering Fade") - # Convert Pixbuf to PIL Image - wh = (pb.get_width(),pb.get_height()) - pilimg = Image.fromstring("RGB", wh, pb.get_pixels()) - - pilimg = pilimg.point(lambda p: (p * self.opacity) / 255 ) - - # "Convert" the PIL to Pixbuf via PixbufLoader - buf = StringIO.StringIO() - pilimg.save(buf, "ppm") - del pilimg - loader = gtk.gdk.PixbufLoader("pnm") - loader.write(buf.getvalue()) - pixbuf = loader.get_pixbuf() - - # Cleanup IO - buf.close() - loader.close() - - pixmap, mask = pixbuf.render_pixmap_and_mask() - # width, height = pixmap.get_size() - else: - pixmap = None - - self.window.set_app_paintable(True) - self.window.resize(gtk.gdk.screen_width(), gtk.gdk.screen_height()) - self.window.realize() - - if pixmap: - self.window.window.set_back_pixmap(pixmap, False) - self.window.move(0,0) - - - def load_config(self, config): - """ Load the configuration file and parse entries, when encountering a issue - change safe defaults """ - - self.parser = ConfigParser.SafeConfigParser() - self.parser.read(config) - - # Set some safe defaults - self.opacity = 50 - self.button_theme = "default" - self.bgcolor = gtk.gdk.color_parse("black") - blist = "" - - if self.parser.has_section("settings"): - - if self.parser.has_option("settings","usehal"): - self.usehal = self.parser.getboolean("settings","usehal") - else: - self.usehal = True - - if self.usehal: - from dbushandler import DbusController - self.dbus = DbusController() - - # Check the looks section and load the config as required - if self.parser.has_section("looks"): - - if self.parser.has_option("looks", "opacity"): - self.opacity = self.parser.getint("looks", "opacity") - - if self.parser.has_option("looks","buttontheme"): - self.button_theme = self.parser.get("looks", "buttontheme") - - if self.parser.has_option("looks", "bgcolor"): - try: - self.bgcolor = gtk.gdk.color_parse(self.parser.get("looks", "bgcolor")) - except: - self.logger.warning(_("Color %s is not a valid color, defaulting to black") % self.parser.get("looks", "bgcolor")) - self.bgcolor = gtk.gdk.color_parse("black") - - if self.parser.has_option("looks", "opacity"): - blist = self.parser.get("looks", "buttons") - - if self.parser.has_section("shortcuts"): - self.shortcut_keys = self.parser.items("shortcuts") - self.logger.debug("Shortcut Options: %s" % self.shortcut_keys) - - - if self.local_mode: - self.theme_prefix = "./data/themes" - else: - self.theme_prefix = "%s/share/themes" % sys.prefix - - self.img_path = "%s/%s/oblogout" % (self.theme_prefix, self.button_theme) - - if os.path.exists("%s/.themes/%s/oblogout" % (os.environ['HOME'], self.button_theme)): - # Found a valid theme folder in the userdir, use that - self.img_path = "%s/.themes/%s/oblogout" % (os.environ['HOME'], self.button_theme) - self.logger.info("Using user theme at %s" % self.img_path) - else: - if not os.path.exists("%s/%s/oblogout" % (self.theme_prefix, self.button_theme)): - self.logger.warning("Button theme %s not found, reverting to default" % self.button_theme) - self.button_theme = 'foom' - - - # Load and parse button list - validbuttons = ['cancel', 'logout', 'restart', 'shutdown', 'suspend', 'hibernate', 'safesuspend', 'lock', 'switch'] - buttonname = [_('cancel'), _('logout'), _('restart'), _('shutdown'), _('suspend'), _('hibernate'), _('safesuspend'), _('lock'), _('switch')] - - if not blist: - list = validbuttons - elif blist == "default": - list = validbuttons - else: - list = map(lambda button: string.strip(button), blist.split(",")) - - # Validate the button list - for button in list: - if not button in validbuttons: - self.logger.warning(_("Button %s is not a valid button name, removing") % button) - list.remove(button) - else: - if self.usehal: - if not self.dbus.check_ability(button): - self.logger.warning(_("Can't %s, disabling button" % button)) - list.remove(button) - - if len(list) == 0: - self.logger.warning(_("No valid buttons found, resetting to defaults")) - self.button_list = validbuttons - else: - self.logger.debug("Validated Button List: %s" % list) - self.button_list = list - - - def on_expose(self, widget, event): - - cr = widget.window.cairo_create() - - if self.supports_alpha == True: - cr.set_source_rgba(1.0, 1.0, 1.0, 0.0) # Transparent - else: - cr.set_source_rgb(1.0, 1.0, 1.0) # Opaque white - - # Draw the background - cr.set_operator(cairo.OPERATOR_SOURCE) - cr.paint() - - (width, height) = widget.get_size() - cr.set_source_rgba(self.bgcolor.red, self.bgcolor.green, self.bgcolor.blue, float(self.opacity)/100) - - cr.rectangle(0, 0, width, height) - cr.fill() - cr.stroke() - return False - - def on_screen_changed(self, widget, old_screen=None): - - # To check if the display supports alpha channels, get the colormap - screen = widget.get_screen() - colormap = screen.get_rgba_colormap() - if colormap == None: - self.logger.debug("Screen does not support alpha channels!") - colormap = screen.get_rgb_colormap() - self.supports_alpha = False - else: - self.logger.debug("Screen supports alpha channels!") - self.supports_alpha = True - - # Now we have a colormap appropriate for the screen, use it - widget.set_colormap(colormap) - - def on_window_state_change(self, widget, event, *args): - if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN: - self.window_in_fullscreen = True - else: - self.window_in_fullscreen = False - - def __add_button(self, name, widget): - """ Add a button to the panel """ - - box = gtk.VBox() - - image = gtk.Image() - if os.path.exists("%s/%s.svg" % (self.img_path, name)): - image.set_from_file("%s/%s.svg" % (self.img_path, name)) - else: - image.set_from_file("%s/%s.png" % (self.img_path, name)) - image.show() - - button = gtk.Button() - button.set_relief(gtk.RELIEF_NONE) - button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("black")) - button.set_focus_on_click(False) - button.set_border_width(0) - button.set_property('can-focus', False) - button.add(image) - button.show() - box.pack_start(button, False, False) - button.connect("clicked", self.click_button, name) - - label = gtk.Label(_(name)) - label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("white")) - box.pack_end(label, False, False) - - widget.pack_start(box, False, False) - - def click_button(self, widget, data=None): - if (data == 'logout'): - self.exec_cmd(self.cmd_logout) - - elif (data == 'restart'): - if self.usehal: - self.dbus.restart() - else: - self.exec_cmd(self.cmd_restart) - - elif (data == 'shutdown'): - if self.usehal: - self.dbus.shutdown() - else: - self.exec_cmd(self.cmd_shutdown) - - elif (data == 'suspend'): - self.window.hide() - self.exec_cmd(self.cmd_lock) - if self.usehal: - self.dbus.suspend() - - else: - self.exec_cmd(self.cmd_suspend) - - elif (data == 'hibernate'): - self.window.hide() - self.exec_cmd(self.cmd_lock) - if self.usehal: - self.dbus.hibernate() - else: - self.__exec_cmd(self.cmd_hibernate) - - elif (data == 'safesuspend'): - self.window.hide() - - if self.usehal: - self.dbus.safesuspend() - else: - self.exec_cmd(self.cmd_safesuspend) - - elif (data == 'lock'): - self.__exec_cmd(self.cmd_lock) - - elif (data == 'switch'): - self.__exec_cmd(self.cmd_switchuser) - - self.quit() - - def on_keypress(self, widget=None, event=None, data=None): - self.logger.debug("Keypress: %s/%s" % (event.keyval, gtk.gdk.keyval_name(event.keyval))) - for key in self.shortcut_keys: - if event.keyval == gtk.gdk.keyval_to_lower(gtk.gdk.keyval_from_name(key[1])): - self.logger.debug("Matched %s" % key[0]) - self.click_button(widget, key[0]) - - def __exec_cmd(self, cmdline): - self.logger.debug("Executing command: %s", cmdline) - os.system(cmdline) - - def quit(self, widget=None, data=None): - gtk.main_quit() - - def run_logout(self): - self.window.show_all() - gtk.main() -