diff options
author | B Stack <bgstack15@gmail.com> | 2019-06-09 21:29:57 -0400 |
---|---|---|
committer | B Stack <bgstack15@gmail.com> | 2019-06-09 21:29:57 -0400 |
commit | 2068554259e00e2ce36a0aa9e621921725a44900 (patch) | |
tree | b63b968971ceccf6f1951475bce0256035c3006c | |
parent | initial commit (diff) | |
download | logout-manager-2068554259e00e2ce36a0aa9e621921725a44900.tar.gz logout-manager-2068554259e00e2ce36a0aa9e621921725a44900.tar.bz2 logout-manager-2068554259e00e2ce36a0aa9e621921725a44900.zip |
WIP: add major logic
* add get_scaled_icon function which merges two amazing Internet posts
* add support for custom icon theme, and specific filenames for icons
* add support for specific icon sizes
* add hibernate and lock screen
- add logic to detect if hibernate is supported
* move actions to own class
* move configuration options to own class
* add configuration file parsing
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | logout-manager.conf | 16 | ||||
-rwxr-xr-x | logout-manager.py | 315 |
3 files changed, 315 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4bc7e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.2019-* diff --git a/logout-manager.conf b/logout-manager.conf new file mode 100644 index 0000000..1a14909 --- /dev/null +++ b/logout-manager.conf @@ -0,0 +1,16 @@ +[logout-manager] +hibernate_command="printf 'disk' | sudo tee /sys/power/state" +lock_command="xscreensaver --locknow" +logout_command="logout from something" +reboot_command="sudo shutdown -r now" +shutdown_command="sudo shutdown -h now" + +[icons] +size = 24 +#theme = default +# use names as used by the icon theme, or give a full path here +hibernate = system-hibernate +lock = system-lock-screen +logout = system-log-out +reboot = system-reboot +shutdown = system-shutdown diff --git a/logout-manager.py b/logout-manager.py index 890f533..d1583e6 100755 --- a/logout-manager.py +++ b/logout-manager.py @@ -15,22 +15,52 @@ # accelerator keys https://askubuntu.com/questions/655452/python-gtk3-keyboard-accelerators # gtk3 widget signals https://developer.gnome.org/gtk3/unstable/GtkWidget.html#GtkWidget-button-press-event # /usr/share/wicd/gtk/gui.py netentry.py wicd.ui +# combined with next ref: scale down valid icon https://stackoverflow.com/questions/42800482/how-to-set-size-of-a-gtk-image-in-python +# https://stackoverflow.com/questions/6090241/how-can-i-get-the-full-file-path-of-an-icon-name +# use custom icon theme https://lazka.github.io/pgi-docs/Gtk-3.0/classes/IconTheme.html#Gtk.IconTheme.set_custom_theme # Improve: -# read commands to execute from an ini file # actually execute the commands +# only show debug info when DEBUG=1 or similar. +# support global conf file, and user conf file # far future: provide graphical way to change commands run # Documentation: -import gi, warnings +import gi, warnings, configparser gi.require_version("Gtk","3.0") from gi.repository import Gtk from gi.repository import Gdk from gi.repository.GdkPixbuf import Pixbuf +from pathlib import Path -logout_manager_version="2019-06-01a" +logout_manager_version="2019-06-09a" application_icon=("system-log-out") -# graphical classes +# graphical classes and functions +def get_scaled_icon(icon_name, size=24, fallback_icon_name = "", icon_theme = "default"): + # return a Gtk.Image.new_from_pixbuf + + # ripped from https://stackoverflow.com/questions/42800482/how-to-set-size-of-a-gtk-image-in-python and combined with https://stackoverflow.com/questions/6090241/how-can-i-get-the-full-file-path-of-an-icon-name + # further ref for lookup_icon function: https://lazka.github.io/pgi-docs/Gtk-3.0/flags.html#Gtk.IconLookupFlags + # if a file exists by the specific name, use it. + if Path(icon_name).is_file(): + iconfilename = icon_name + else: + if icon_theme != "default": + this_theme = Gtk.IconTheme.new() + this_theme.set_custom_theme(icon_theme) + else: + this_theme = Gtk.IconTheme.get_default() + try: + icon_info = this_theme.lookup_icon(icon_name, size, 0) + iconfilename = icon_info.get_filename() + except: + icon_info = this_theme.lookup_icon(fallback_icon_name, size, 0) + iconfilename = icon_info.get_filename() + #print(iconfilename) + return Gtk.Image.new_from_pixbuf(Pixbuf.new_from_file_at_scale( + filename=iconfilename, + width=size, height=size, preserve_aspect_ratio=True)) + class MainWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="Log out options") @@ -56,24 +86,46 @@ class MainWindow(Gtk.Window): self.grid = Gtk.Grid() self.add(self.grid) + self.button0 = Gtk.Button(label="Loc_k") + self.button0.connect("button-press-event", self.on_button0_press_event) + self.button0.connect("activate", self.on_button0_press_event) # activate covers ALT+L action and spacebar when selected + self.buttonicon0 = get_scaled_icon(config.get_lock_icon(), config.get_icon_size(),config.get_lock_fallback_icon(), config.get_icon_theme()) + self.button0.set_image(self.buttonicon0) + self.button0.set_tooltip_text("Hide session and require authentication to return to it") + self.button0.set_always_show_image(True) + self.button0.set_use_underline(True) + self.grid.add(self.button0) + self.button1 = Gtk.Button(label="_Logout") self.button1.connect("button-press-event", self.on_button1_press_event) self.button1.connect("activate", self.on_button1_press_event) # activate covers ALT+L action and spacebar when selected - self.buttonicon1 = Gtk.Image() - self.buttonicon1.set_from_icon_name("system-log-out",24) + self.buttonicon1 = get_scaled_icon(config.get_logout_icon(), config.get_icon_size(),config.get_logout_fallback_icon(), config.get_icon_theme()) self.button1.set_image(self.buttonicon1) self.button1.set_tooltip_text("Close the current user session") self.button1.set_always_show_image(True) self.button1.set_use_underline(True) self.grid.add(self.button1) - self.button2 = Gtk.Button(label="Shut_down") + self.buttonHibernate = Gtk.Button(label="_Hibernate") + self.buttonHibernate.connect("button-press-event", self.on_buttonHibernate_press_event) + self.buttonHibernate.connect("activate", self.on_buttonHibernate_press_event) # activate covers ALT+L action and spacebar when selected + #self.buttoniconHibernate = Gtk.Image() + #self.buttoniconHibernate.set_from_icon_name("system-hibernate",24) + self.buttoniconHibernate = get_scaled_icon(config.get_hibernate_icon(), config.get_icon_size(),config.get_hibernate_fallback_icon(), config.get_icon_theme()) + self.buttonHibernate.set_image(self.buttoniconHibernate) + self.buttonHibernate.set_tooltip_text("Save state to disk and power off") + self.buttonHibernate.set_always_show_image(True) + self.buttonHibernate.set_use_underline(True) + self.buttonHibernate.set_sensitive(True if config.get_can_hibernate() else False) + self.grid.add(self.buttonHibernate) + + self.button2 = Gtk.Button(label="_Shutdown") self.button2.connect("button-press-event", self.on_button2_press_event) self.button2.connect("activate", self.on_button2_accel) # unnecessary because the "activate" suffices above. #self.button2.connect("mnemonic-activate", self.on_button2_accel) self.buttonicon2 = Gtk.Image() - self.buttonicon2.set_from_icon_name("system-shutdown",24) + self.buttonicon2 = get_scaled_icon(config.get_shutdown_icon(), config.get_icon_size(), config.get_shutdown_fallback_icon(), config.get_icon_theme()) self.button2.set_image(self.buttonicon2) self.button2.set_tooltip_text("Power off the computer") self.button2.set_always_show_image(True) @@ -84,10 +136,7 @@ class MainWindow(Gtk.Window): self.button3.connect("button-press-event", self.on_button3_press_event) self.button3.connect("activate", self.on_button3_press_event) self.buttonicon3 = Gtk.Image() - # WORKS, when it was a box object self.box.pack_start(self.button3, True, True, 3) - # WORKS self.buttonicon3.set_from_file("/usr/share/icons/Adwaita/48x48/actions/system-log-out.png") - # WORKS self.buttonicon3.set_from_icon_name("system-log-out",24) - self.buttonicon3.set_from_icon_name("system-reboot",24) + self.buttonicon3 = get_scaled_icon(config.get_reboot_icon(), config.get_icon_size(), config.get_reboot_fallback_icon(), config.get_icon_theme()) self.button3.set_image(self.buttonicon3) self.button3.set_tooltip_text("Reboot the computer back to the login screen") self.button3.set_always_show_image(True) @@ -99,7 +148,15 @@ class MainWindow(Gtk.Window): self.button4.connect("activate", self.on_button4_press_event) self.button4.set_tooltip_text("Do nothing; just close this window") self.button4.set_use_underline(True) - self.grid.attach(self.button4,0,1,3,1) + self.grid.attach(self.button4,0,1,8,1) + + # hibernate button + def on_buttonHibernate_press_event(self, *args): + self.do_hibernate(self.buttonHibernate) + + # lock button + def on_button0_press_event(self, *args): + self.do_lock(self.button0) # logout button def on_button1_press_event(self, *args): @@ -134,19 +191,243 @@ class MainWindow(Gtk.Window): self.cancel(self.button4) def do_shutdown(self, *args): - print("please shut yourself down!") - print(dir(self.props)) + #print(dir(self.props)) + Actions.shutdown() + + def do_hibernate(self, widget): + Actions.hibernate() + + def do_lock(self, widget): + Actions.lock() def do_logout(self, widget): - print("please log out of current session!") + Actions.logout() def do_reboot(self, widget): - print("please reboot.") + Actions.reboot() def cancel(self, widget): print("Cancel any logout action.") Gtk.main_quit() +class Actions: + + @staticmethod + def hibernate(): + #print("need to run the /sys/power/state trick, if available") + print(config.get_hibernate_command()) + + @staticmethod + def lock(): + #print("please lock the screen.") + print(config.get_lock_command()) + + @staticmethod + def logout(): + #print("please log out of current session!") + print(config.get_logout_command()) + + @staticmethod + def reboot(): + #print("please reboot.") + print(config.get_reboot_command()) + + @staticmethod + def shutdown(): + #print("please shut yourself down!") + print(config.get_shutdown_command()) + +class Config: + def __init__(self): + # load defaults which can be overwritten + self.hibernate_command = "" + self.lock_command = "" + self.logout_command = "" + self.reboot_command = "" + self.shutdown_command = "" + self.hibernate_icon = "system-hibernate" + self.hibernate_fallback_icon = "system-hibernate" + self.lock_icon = "system-lock-screen" + self.lock_fallback_icon = "system-lock-screen" + self.logout_icon = "system-log-out" + self.logout_fallback_icon = "system-log-out" + self.reboot_icon = "system-reboot" + self.reboot_fallback_icon = "system-reboot" + self.shutdown_icon = "system-shutdown" + self.shutdown_fallback_icon = "system-shutdown" + self.icon_size = 24 + self.icon_theme = "default" + self.can_hibernate = False + + def set_hibernate_command(self,hibernate_command): + self.hibernate_command = hibernate_command + + def set_lock_command(self,lock_command): + self.lock_command = lock_command + + def set_logout_command(self,logout_command): + self.logout_command = logout_command + + def set_reboot_command(self,reboot_command): + self.reboot_command = reboot_command + + def set_shutdown_command(self,shutdown_command): + self.shutdown_command = shutdown_command + + def set_hibernate_icon(self,hibernate_icon): + self.hibernate_icon = hibernate_icon + + def set_lock_icon(self,lock_icon): + self.lock_icon = lock_icon + + def set_logout_icon(self,logout_icon): + self.logout_icon = logout_icon + + def set_reboot_icon(self,reboot_icon): + self.reboot_icon = reboot_icon + + def set_shutdown_icon(self,shutdown_icon): + self.shutdown_icon = shutdown_icon + + def set_icon_size(self,icon_size): + self.icon_size = int(icon_size) + + def set_icon_theme(self,icon_theme): + self.icon_theme = icon_theme + + def set_can_hibernate(self,can_hibernate): + print("Setting can_hibernate:",can_hibernate) + self.can_hibernate = bool(can_hibernate) + + def get_hibernate_command(self): + return self.hibernate_command + + def get_lock_command(self): + return self.lock_command + + def get_logout_command(self): + return self.logout_command + + def get_reboot_command(self): + return self.reboot_command + + def get_shutdown_command(self): + return self.shutdown_command + + def get_hibernate_icon(self): + return self.hibernate_icon + + def get_lock_icon(self): + return self.lock_icon + + def get_logout_icon(self): + return self.logout_icon + + def get_reboot_icon(self): + return self.reboot_icon + + def get_shutdown_icon(self): + return self.shutdown_icon + + def get_hibernate_fallback_icon(self): + return self.hibernate_fallback_icon + + def get_lock_fallback_icon(self): + return self.lock_fallback_icon + + def get_logout_fallback_icon(self): + return self.logout_fallback_icon + + def get_reboot_fallback_icon(self): + return self.reboot_fallback_icon + + def get_shutdown_fallback_icon(self): + return self.shutdown_fallback_icon + + def get_icon_size(self): + return self.icon_size + + def get_icon_theme(self): + return self.icon_theme + + def get_can_hibernate(self): + return self.can_hibernate + +# Read config +config_in = configparser.ConfigParser() +config_in.read('logout-manager.conf') +config = Config() +try: + ci = config_in['logout-manager'] +except: + # no definition + print("Using default commands") + +try: + ci_icons = config_in['icons'] +except: + # no definition + print("Using default icons") + +# load up our custom class, which stores the defaults in case we do not set them here +if 'hibernate_command' in ci: + config.set_hibernate_command(ci['hibernate_command']) +if 'lock_command' in ci: + config.set_lock_command(ci['lock_command']) +if 'logout_command' in ci: + config.set_logout_command(ci['logout_command']) +if 'reboot_command' in ci: + config.set_reboot_command(ci['reboot_command']) +if 'shutdown_command' in ci: + config.set_shutdown_command(ci['shutdown_command']) +if 'hibernate' in ci_icons: + config.set_hibernate_icon(ci_icons['hibernate']) +if 'lock' in ci_icons: + config.set_lock_icon(ci_icons['lock']) +if 'logout' in ci_icons: + config.set_logout_icon(ci_icons['logout']) +if 'reboot' in ci_icons: + config.set_reboot_icon(ci_icons['reboot']) +if 'shutdown' in ci_icons: + config.set_shutdown_icon(ci_icons['shutdown']) +if 'size' in ci_icons: + config.set_icon_size(ci_icons['size']) +if 'theme' in ci_icons: + config.set_icon_theme(ci_icons['theme']) +# store the info about if hibernate is an option +can_hibernate = False +try: + with open('/sys/power/state') as r: + line = r.read() + if 'disk' in line: can_hibernate = True +except: + pass +config.set_can_hibernate(can_hibernate) + +# DEBUG, raw from conf file and system status +print("Raw values:") +for item in config_in.sections(): + print("["+item+"]") + for key in config_in[item]: + print(key+" = "+config_in[item][key]) +print("Can hibernate:",can_hibernate) + +# DEBUG, stored values +print("Stored values:") +print(config.get_hibernate_command()) +print(config.get_lock_command()) +print(config.get_logout_command()) +print(config.get_reboot_command()) +print(config.get_shutdown_command()) +print(config.get_hibernate_icon()) +print(config.get_lock_icon()) +print(config.get_logout_icon()) +print(config.get_reboot_icon()) +print(config.get_shutdown_icon()) +print(config.get_icon_size()) +print(config.get_icon_theme()) +print("Can hibernate:",config.get_can_hibernate()) + # MAIN LOOP win = MainWindow() win.connect("destroy", Gtk.main_quit) |