aboutsummaryrefslogtreecommitdiff
path: root/src/usr/bin
diff options
context:
space:
mode:
authorB Stack <bgstack15@gmail.com>2020-03-20 15:27:14 -0400
committerB Stack <bgstack15@gmail.com>2020-04-02 09:06:38 -0400
commit9938ce0de63ae8ea780daed3d6551832cb48c96b (patch)
tree93d9c57b0ad16fad30d3421ef4ce96b3ef46097c /src/usr/bin
parentadd alternative trayicon shell script (diff)
downloadlogout-manager-9938ce0de63ae8ea780daed3d6551832cb48c96b.tar.gz
logout-manager-9938ce0de63ae8ea780daed3d6551832cb48c96b.tar.bz2
logout-manager-9938ce0de63ae8ea780daed3d6551832cb48c96b.zip
add lm trayicon, and fix #1
Add program, its menu entry, and xdg autostart entry (disabled) Fix #1: cli executes valid command but still shows help message
Diffstat (limited to 'src/usr/bin')
-rwxr-xr-xsrc/usr/bin/logout-manager-cli.py1
-rwxr-xr-xsrc/usr/bin/logout-manager-trayicon163
2 files changed, 164 insertions, 0 deletions
diff --git a/src/usr/bin/logout-manager-cli.py b/src/usr/bin/logout-manager-cli.py
index 64ea133..8fd78b4 100755
--- a/src/usr/bin/logout-manager-cli.py
+++ b/src/usr/bin/logout-manager-cli.py
@@ -60,6 +60,7 @@ if config.can_hibernate:
if args.action in allowed_actions:
func = getattr(globals()['actions'],args.action)
func(config)
+ sys.exit(0)
elif args.action:
eprint("Unable to take action: %s" % str(args.action))
sys.exit(1)
diff --git a/src/usr/bin/logout-manager-trayicon b/src/usr/bin/logout-manager-trayicon
new file mode 100755
index 0000000..b6471f9
--- /dev/null
+++ b/src/usr/bin/logout-manager-trayicon
@@ -0,0 +1,163 @@
+#!/usr/bin/env python3
+# File: logout-manager-trayicon
+# License: CC-BY-SA 4.0
+# Author: bgstack15
+# Reference:
+# icon work https://stackoverflow.com/questions/45162862/how-do-i-set-an-icon-for-the-whole-application-using-pygobject
+# button right click must be from "button-press-event" and import Gdk https://python-gtk-3-tutorial.readthedocs.io/en/latest/menus.html
+# useful reference https://lazka.github.io/pgi-docs/Gtk-3.0/classes/Button.html#Gtk.Button
+# systray info https://github.com/PiSupply/PiJuice/blob/master/Software/Source/src/pijuice_tray.py
+# logout-manager-gtk.py
+# how to determine double click https://stackoverflow.com/questions/60009648/is-there-a-better-way-to-handle-double-click-in-pygobject
+# interactive python3 shell and help(Gdk.EventType)
+# https://developer.gnome.org/gtk3/unstable/GtkWidget.html#GtkWidget-button-press-event
+# find running processes https://thispointer.com/python-get-list-of-all-running-processes-and-sort-by-highest-memory-usage/
+# send signals https://stackoverflow.com/questions/15080500/how-can-i-send-a-signal-from-a-python-program
+# https://docs.python.org/3.8/library/signal.html#module-signal
+# Dependencies:
+# dep-pip: psutil
+# dep-devuan: python3-psutil
+
+import gi, os, platform, re, sys, psutil, signal
+gi.require_version("Gtk","3.0")
+from gi.repository import Gtk
+from gi.repository import Gdk
+from dotenv import load_dotenv
+
+# all this to load the libpath
+try:
+ defaultdir="/etc/sysconfig"
+ thisplatform = platform.platform().lower()
+ if 'debian' in thisplatform or 'devuan' in thisplatform:
+ defaultdir="/etc/default"
+ # load_dotenv keeps existing environment variables as higher precedent
+ load_dotenv(os.path.join(defaultdir,"logout-manager"))
+except:
+ pass
+if 'LOGOUT_MANAGER_LIBPATH' in os.environ:
+ for i in os.environ['LOGOUT_MANAGER_LIBPATH'].split(":"):
+ sys.path.append(i)
+import lmlib
+
+def is_dryrun():
+ result = False
+ try:
+ if "DRYRUN" in os.environ and os.environ["DRYRUN"] != "": result = True
+ except:
+ pass
+ return result
+
+def run_or_kill_logout_manager():
+ #print("Run or kill logout manager!")
+ _lm_is_running = False
+ lmregex = re.compile("logout-manager.*--from-trayicon")
+ lmprintregex = re.compile("logout-manager")
+ thisproc = None
+ for proc in psutil.process_iter():
+ try:
+ cmdline = " ".join(proc.cmdline())
+ #if lmprintregex.search(cmdline) != None: print("Checking \"" + cmdline + "\"")
+ if lmregex.search(cmdline) != None:
+ _lm_is_running = True
+ thisproc = proc
+ break
+ except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
+ pass
+
+ if _lm_is_running:
+ #print("Stopping the following process.")
+ #print(thisproc)
+ os.kill(thisproc.pid,signal.SIGHUP)
+ else:
+ # start new instance
+ #print("Please start a new instance")
+
+ # this actually returns the new pid, and we could choose to signal only this pid.
+ # but we will not at this point.
+ newpid = os.spawnvp(os.P_NOWAIT,"logout-manager",["logout-manager","--from-trayicon"])
+ print("spawned",newpid)
+
+class MainIcon(Gtk.StatusIcon):
+ def __init__(self,config,actions):
+ Gtk.StatusIcon.__init__(self)
+ self.config = config
+ self.actions = actions
+ self.set_from_icon_name(self.config.get_logout_icon())
+ loggedin_str = "Logged in as " + str(os.environ["USER"])
+ tooltiptext = loggedin_str
+ if is_dryrun():
+ tooltiptext = "DRYRUN MODE: " + tooltiptext
+ self.set_tooltip_text(tooltiptext)
+
+ self.traymenu = Gtk.Menu()
+ self.add_action_to_menu("Loc_k",self.config.get_lock_icon(),self.on_lock_menuitem)
+ self.add_action_to_menu("_Logout",self.config.get_logout_icon(),self.on_logout_menuitem)
+ self.add_action_to_menu("_Hibernate",self.config.get_hibernate_icon(),self.on_hibernate_menuitem)
+ self.add_action_to_menu("_Shutdown",self.config.get_shutdown_icon(),self.on_shutdown_menuitem)
+ self.add_action_to_menu("_Reboot",self.config.get_reboot_icon(),self.on_reboot_menuitem)
+
+ # separator
+ i = Gtk.SeparatorMenuItem.new()
+ i.show()
+ self.traymenu.append(i)
+
+ # logged in as
+ i = Gtk.MenuItem.new_with_label(tooltiptext)
+ i.set_sensitive(False)
+ i.show()
+ self.traymenu.append(i)
+
+ # hide tray icon
+ i = Gtk.MenuItem.new_with_mnemonic("Hide _tray icon")
+ i.show()
+ i.connect("activate", self.exit)
+ self.traymenu.append(i)
+
+ self.connect("button-press-event", self.on_button_press_event)
+ self.connect("popup-menu", self.show_menu)
+
+ def on_button_press_event(self, b_unknown, event: Gdk.EventButton):
+ if Gdk.EventType._2BUTTON_PRESS == event.type:
+ run_or_kill_logout_manager()
+
+ def exit(self, widget):
+ quit()
+
+ def show_menu(self, widget, event_button, event_time):
+ self.traymenu.popup(None, None,
+ self.position_menu,
+ self,
+ event_button,
+ Gtk.get_current_event_time())
+
+ def on_lock_menuitem(self, widget):
+ self.actions.lock(self.config)
+
+ def on_logout_menuitem(self, widget):
+ self.actions.logout(self.config)
+
+ def on_hibernate_menuitem(self, widget):
+ self.actions.hibernate(self.config)
+
+ def on_shutdown_menuitem(self, widget):
+ self.actions.shutdown(self.config)
+
+ def on_reboot_menuitem(self, widget):
+ self.actions.reboot(self.config)
+
+ def add_action_to_menu(self,label_str,icon_str,function_func):
+ i = Gtk.ImageMenuItem.new_with_mnemonic(label_str)
+ j = Gtk.Image.new_from_icon_name(icon_str,32)
+ j.show()
+ i.set_image(j)
+ i.set_always_show_image(True)
+ i.show()
+ i.connect("activate", function_func)
+ self.traymenu.append(i)
+
+# load configs
+config = lmlib.Initialize_config(os.environ['LOGOUT_MANAGER_CONF'])
+actions = lmlib.Actions
+
+icon = MainIcon(config,actions)
+Gtk.main()
bgstack15