aboutsummaryrefslogtreecommitdiff
path: root/logout-manager-tcl.py
diff options
context:
space:
mode:
Diffstat (limited to 'logout-manager-tcl.py')
-rwxr-xr-xlogout-manager-tcl.py116
1 files changed, 104 insertions, 12 deletions
diff --git a/logout-manager-tcl.py b/logout-manager-tcl.py
index c605dc0..b9d9997 100755
--- a/logout-manager-tcl.py
+++ b/logout-manager-tcl.py
@@ -1,5 +1,8 @@
#!/usr/bin/env python3
# Startdate: 2019-06-12 20:05
+# Dependencies:
+# python36-tkinter | python3-tk
+# python36-pillow-tk | python3-pil.imagetk
# WORKHERE:
# add icons
# add full headers
@@ -12,12 +15,18 @@
# alternate for passing params https://stackoverflow.com/questions/6920302/how-to-pass-arguments-to-a-button-command-in-tkinter
# https://stackoverflow.com/questions/18537918/set-window-icon#18538416
# the exact syntax <Alt-k> for master.bind https://stackoverflow.com/questions/16082243/how-to-bind-ctrl-in-python-tkinter
+# https://pillow.readthedocs.io/en/stable/reference/ImageTk.html
+# 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
-import os, sys
-sys.path.append("/home/bgirton/dev/logout-manager")
-import lmlib
+import os, sys, configparser, glob, re
from tkinter import *
from functools import partial
+from pathlib import Path
+from PIL import Image, ImageTk
+sys.path.append("/home/bgirton/dev/logout-manager")
+import lmlib
config = lmlib.Initialize_config()
actions = lmlib.Actions
@@ -25,13 +34,89 @@ actions = lmlib.Actions
# graphical classes and functions
print("Loading graphics...")
-def icon_bitmap(name = "", theme = "default", size = "48"):
- # WORKHERE: can build some tool that loops through the icon theme dirs
+def get_gtk3_default_theme():
+ # abstracted so it does not clutter get_scaled_icon
+ name = None
+ 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)
+ try:
+ if 'Settings' in gtk3_config:
+ name = gtk3_config['Settings']['gtk-icon-theme-name']
+ elif 'settings' in gtk3_config:
+ name = gtk3_config['settings']['gtk-icon-theme-name']
+ except:
+ # supposed failsafe
+ name = "hicolor"
+ return name
+
+def tryint(s):
+ try:
+ return int(s)
+ except:
+ return s
+
+def sort_sizes(x):
+ # I don't even know how this works. I mashed it together from so#46228101
+ # WORKS return [tryint(c) for c in re.split('([0-9]+)',x.split("/")[5])]
+ value = x.split("/")[5]
+ #return int(re.split("[^0-9]+",value)[0]) * 100 + int( re.split("[^0-9]+",value)[1] if len(value.split("@")) >= 2 else 0 )
+ return mynum(value, "all")
+
+def mynum(x, type = "all"):
+ # return the complicated numerical value for the weird size options
+ 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 )
+ else:
+ return int(re.split("[^0-9]+",x)[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])
+
+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
+
+ # first, find all files underneath /usr/share/icons/$THEME/$SIZE
+ print("Finding filename of icon.")
+ results = glob.glob("/usr/share/icons/"+theme+"/*/"+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)
+ # now find the first one that matches
+ filename = find_best_size_match(size,results)
+ return filename
+
+def get_scaled_icon(icon_name, size = 24, fallback_icon_name = "", icon_theme = "default"):
+ iconfilename = None
+
# if name is a specific filename, just use it.
- # if the only thing that is found during the looping is a svg, return None
- # if the valid file provided is svg, then try a few derivations to get a png, else return None
- imgicon = PhotoImage(file=os.path.join("/usr/share/icons/Adwaita/24x24/actions","system-log-out.png"))
- return imgicon
+ if Path(icon_name).is_file():
+ #print("This is a file:",icon_name)
+ iconfilename = icon_name
+ else:
+
+ if icon_theme == "default":
+ # retrieve default theme from config file
+ #print("Discovering default 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)
+
+ # So now that we think we have derived the correct filename...
+ try:
+ print("Trying icon file",iconfilename)
+ photo = Image.open(iconfilename)
+ except:
+ print("Error with icon file.")
+ 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)
+ return photo2
class App:
def __init__(self, master):
@@ -39,15 +124,22 @@ class App:
frame.grid(row=0)
self.buttonLock = Button(frame, text="Lock", underline=3, command=partial(actions.lock,config))
- #self.buttonLock.pack(side=LEFT)
self.buttonLock.grid(row=0,column=0)
# WORKS master.bind_all("<Alt-k>", something)
# PASSES 2 params when expecting 1 master.bind_all("<Alt-k>", self.buttonLock.invoke)
master.bind_all("<Alt-k>", partial(actions.lock,config))
- self.buttonLogout = Button(frame, text="Logout", underline=0, command=lambda: actions.logout(config))
- self.buttonLogout.grid(row=0,column=1)
+ # WORKS, for basic image loading.
+ #self.photoLogout = get_scaled_icon("/usr/share/icons/Adwaita/48x48/actions/system-log-out.png")
+ #self.buttonLogout = Button(frame, text="Logout", underline=0, command=lambda: actions.logout(config), image=self.photoLogout, compound=TOP)
+ #self.photoLogout1 = Image.open("/usr/share/icons/Adwaita/48x48/actions/system-log-out.png")
+ #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.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.buttonHibernate.grid(row=0,column=2)
bgstack15