aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB Stack <bgstack15@gmail.com>2019-06-09 21:29:57 -0400
committerB Stack <bgstack15@gmail.com>2019-06-09 21:29:57 -0400
commit2068554259e00e2ce36a0aa9e621921725a44900 (patch)
treeb63b968971ceccf6f1951475bce0256035c3006c
parentinitial commit (diff)
downloadlogout-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--.gitignore1
-rw-r--r--logout-manager.conf16
-rwxr-xr-xlogout-manager.py315
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)
bgstack15