diff options
-rw-r--r-- | lmlib.py | 23 | ||||
-rwxr-xr-x | logout-manager-tcl.py | 73 |
2 files changed, 74 insertions, 22 deletions
@@ -9,12 +9,14 @@ # Usage: # In a logout-manager-gtk.py program # Reference: +# platform info https://stackoverflow.com/questions/110362/how-can-i-find-the-current-os-in-python/10091465#10091465 # Improve: +# detect if el7, use icon_category = "apps". This should be an internal variable (not listed in .conf) # Documentation: -import configparser +import configparser, platform -logout_manager_version="2019-06-12b" +logout_manager_version="2019-06-14a" class Actions: @@ -63,6 +65,7 @@ class Config: self.shutdown_fallback_icon = "system-shutdown" self.icon_size = 24 self.icon_theme = "default" + self.icon_category = "actions" self.can_hibernate = False self.application_icon=("system-log-out") @@ -102,6 +105,9 @@ class Config: def set_icon_theme(self,icon_theme): self.icon_theme = icon_theme + def set_icon_category(self,icon_category): + self.icon_category = icon_category + def set_can_hibernate(self,can_hibernate): print("Setting can_hibernate:",can_hibernate) self.can_hibernate = bool(can_hibernate) @@ -157,6 +163,9 @@ class Config: def get_icon_theme(self): return self.icon_theme + def get_icon_category(self): + return self.icon_category + def get_can_hibernate(self): return self.can_hibernate @@ -212,6 +221,15 @@ def Initialize_config(): pass config.set_can_hibernate(can_hibernate) + # set icon category + # written primarily for el7 which uses "app" for the system-reboot icons, etc. + a = platform.dist() + try: + if a[0] == "redhat" and int(a[1].split(".")[0]) <= 7: + config.set_icon_category("apps") + except: + pass + # DEBUG, raw from conf file and system status print("Raw values:") for item in config_in.sections(): @@ -234,6 +252,7 @@ def Initialize_config(): print(config.get_shutdown_icon()) print(config.get_icon_size()) print(config.get_icon_theme()) + print(config.get_icon_category()) print("Can hibernate:",config.get_can_hibernate()) return config diff --git a/logout-manager-tcl.py b/logout-manager-tcl.py index b9d9997..305c3a7 100755 --- a/logout-manager-tcl.py +++ b/logout-manager-tcl.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 +# File: logout-manager-tcl.py +# License: CC-BY-SA 4.0 +# Author: bgstack15 # Startdate: 2019-06-12 20:05 -# Dependencies: -# python36-tkinter | python3-tk -# python36-pillow-tk | python3-pil.imagetk -# WORKHERE: -# add icons -# add full headers - +# Title: Tcl/tk-based logout manager +# Purpose: A tcl/tk graphical program for selecting shutdown, logout, etc. +# History: +# Usage: # References: # http://effbot.org/tkinterbook/button.htm # http://effbot.org/tkinterbook/tkinter-application-windows.htm @@ -19,6 +19,12 @@ # gtk-3.0 default icon theme https://coderwall.com/p/no3qfa/setting-gtk2-and-gtk3-theme-via-config-file # homedir https://stackoverflow.com/questions/4028904/how-to-get-the-home-directory-in-python # natural sort https://stackoverflow.com/questions/46228101/sort-list-of-strings-by-two-substrings-using-lambda-function/46228199#46228199 +# Improve: +# add tooltips +# add svg support +# Dependencies: +# python36-tkinter | python3-tk +# python36-pillow-tk | python3-pil.imagetk import os, sys, configparser, glob, re from tkinter import * @@ -27,6 +33,11 @@ from pathlib import Path from PIL import Image, ImageTk sys.path.append("/home/bgirton/dev/logout-manager") import lmlib +#if TkVersion < 8.6: +# USE_PRIVATE_TCL_IMAGES = 1 +# print("Loading private PIL translation layter") +# def PhotoImage_from_png(file): +# return ImageTk.PhotoImage(file=file) config = lmlib.Initialize_config() actions = lmlib.Actions @@ -36,7 +47,7 @@ print("Loading graphics...") def get_gtk3_default_theme(): # abstracted so it does not clutter get_scaled_icon - name = None + name = "hicolor" gtk3_config_path = os.path.join(os.path.expanduser("~"),".config","gtk-3.0","settings.ini") gtk3_config = configparser.ConfigParser() gtk3_config.read(gtk3_config_path) @@ -65,23 +76,32 @@ def sort_sizes(x): def mynum(x, type = "all"): # return the complicated numerical value for the weird size options + f = re.split("[^0-9]+",x) if type == "all": - return int(re.split("[^0-9]+",x)[0]) * 100 + int( re.split("[^0-9]+",x)[1] if len(re.split("[^0-9]+",x)) >= 2 else 0 ) + return int(f[0]) * 100 + int( f[1] if len(f) >= 2 else 0 ) else: - return int(re.split("[^0-9]+",x)[0]) + return int(f[0]) def find_best_size_match(size, thelist): # return item from sorted thelist whose split("/")[5] is the first to meet or exceed the requested size - return next(( i for i in thelist if mynum(i.split("/")[5],"real") >= size ), thelist[-1]) + try: + default = thelist[-1] + except: + default = None + return next(( i for i in thelist if mynum(i.split("/")[5],"real") >= size ), default) def get_filename_of_icon(name, theme = "hicolor", size = 48, category = "actions"): # poor man's attempt at walking through fd.o icon theme filename = None # example: Adwaita system-log-out + if theme == "default" or theme is None: + theme = "hicolor" + # first, find all files underneath /usr/share/icons/$THEME/$SIZE - print("Finding filename of icon.") - results = glob.glob("/usr/share/icons/"+theme+"/*/"+category+"/"+name+".*") + print("Finding filename of icon, theme=",theme,"category=",category,"name=",name) + # WORKHERE: this glob affects if scalable/ dir is included. When support for svg is added (which is beyond PIL), need to add a conditional and use a second glob if USE_SVG=1. + results = glob.glob("/usr/share/icons/"+theme+"/*[0-9]*/"+category+"/"+name+".*") # the sort arranges it so a Numix/24 dir comes before a Numix/24@2x dir results = sorted(results, key=sort_sizes) #print(results) @@ -104,7 +124,7 @@ def get_scaled_icon(icon_name, size = 24, fallback_icon_name = "", icon_theme = icon_theme = get_gtk3_default_theme() # so now that icon_theme is defined, let us go find the icon that matches the requested name and size, in the actions category #print("Using icon theme",icon_theme) - iconfilename = get_filename_of_icon(name=icon_name, theme=icon_theme, size=size) + iconfilename = get_filename_of_icon(name=icon_name, theme=icon_theme, size=size, category=config.get_icon_category()) # So now that we think we have derived the correct filename... try: @@ -115,7 +135,10 @@ def get_scaled_icon(icon_name, size = 24, fallback_icon_name = "", icon_theme = return None # If I ever add HiDPI stuff, multiple size here by the factor. So, size * 1.25 photo.thumbnail(size=[size, size]) - photo2 = ImageTk.PhotoImage(photo) + try: + photo2 = ImageTk.PhotoImage(photo) + except Exception as e: + print("Error was ",e) return photo2 class App: @@ -136,20 +159,24 @@ class App: #self.photoLogout1.thumbnail(size=[24,24]) #self.photoLogout = ImageTk.PhotoImage(self.photoLogout1,size="24x24") #self.photoLogout = get_scaled_icon("/usr/share/icons/Adwaita/48x48/actions/system-log-out.png", 24) - self.photoLogout = get_scaled_icon("system-log-out", 24, icon_theme="default") + #self.photoLogout = get_scaled_icon("system-log-out", 24, icon_theme="default") + self.photoLogout = get_scaled_icon(config.get_logout_icon(), config.get_icon_size(), config.get_icon_theme()) self.buttonLogout = Button(frame, text="Logout", underline=0, command=lambda: actions.logout(config), image=self.photoLogout, compound=LEFT) master.bind_all("<Alt-l>", partial(actions.logout,config)) self.buttonLogout.grid(row=0,column=1) - self.buttonHibernate = Button(frame, text="Hibernate", underline=0, command=lambda: actions.hibernate(config)) + self.photoHibernate = get_scaled_icon(config.get_hibernate_icon(), config.get_icon_size(), config.get_icon_theme()) + self.buttonHibernate = Button(frame, text="Hibernate", underline=0, command=lambda: actions.hibernate(config), image=self.photoHibernate, compound=LEFT) self.buttonHibernate.grid(row=0,column=2) master.bind_all("<Alt-h>", partial(actions.hibernate,config)) - self.buttonShutdown = Button(frame, text="Shutdown", underline=0, command=lambda: actions.shutdown(config)) + self.photoShutdown = get_scaled_icon(config.get_shutdown_icon(), config.get_icon_size(), config.get_icon_theme()) + self.buttonShutdown = Button(frame, text="Shutdown", underline=0, command=lambda: actions.shutdown(config), image=self.photoShutdown, compound=LEFT) self.buttonShutdown.grid(row=0,column=3) master.bind_all("<Alt-s>", partial(actions.shutdown,config)) - self.buttonReboot = Button(frame, text="Reboot", underline=0, command=lambda: actions.reboot(config)) + self.photoReboot = get_scaled_icon(config.get_reboot_icon(), config.get_icon_size(), config.get_icon_theme()) + self.buttonReboot = Button(frame, text="Reboot", underline=0, command=lambda: actions.reboot(config), image=self.photoReboot, compound=LEFT) self.buttonReboot.grid(row=0,column=4) master.bind_all("<Alt-r>", partial(actions.reboot,config)) @@ -172,7 +199,13 @@ root = Tk() # MAIN LOOP root.title("Log out options") #root.iconbitmap(r'/usr/share/icons/Numix/48/actions/system-logout.svg') -imgicon = PhotoImage(file=os.path.join("/usr/share/icons/Adwaita/24x24/actions","system-log-out.png")) +imgicon = get_scaled_icon(config.get_logout_icon(),24) +#if USE_PRIVATE_TCL_IMAGES is None: +# #imgicon = PhotoImage(file=os.path.join("/usr/share/icons/Adwaita/24x24/actions","system-log-out.png")) +# imgicon = get_scaled_icon(config.get_logout_icon(),24) +#else: +# #imgicon = PhotoImage_from_png(file=os.path.join("/usr/share/icons/Adwaita/24x24/actions","system-log-out.png")) +# imgicon = get_scaled_icon(config.get_logout_icon(),24) root.tk.call('wm','iconphoto', root._w, imgicon) app = App(root) root.mainloop() |