dotfiles/config/i3/icons.py

131 lines
3.4 KiB
Python

#!/usr/bin/env python3
# Taken from https://gist.github.com/bgavran/462c9391a49a835546f9bf9c15ce56f9
# and slightly modified by me (https://github.com/SijmenSchoon).
#
# This script listens for i3 events and updates workspace names to show icons
# for running programs. It contains icons for a few programs, but more can
# easily be added by inserting them into WINDOW_ICONS below.
#
# Dependencies
# * xorg-xprop - install through system package manager
# * i3ipc - install with pip
import i3ipc
import subprocess as proc
import re
# Add icons here for common programs you use. The keys are the X window class
# (WM_CLASS) names and the icons can be any text you want to display. However
# most of these are character codes for font awesome:
# http://fortawesome.github.io/Font-Awesome/icons/
FA_CHROME = "\uf268"
FA_CODE = "\uf121"
FA_DOWNLOAD = "\uf019"
FA_FILE_PDF_O = "\uf1c1"
FA_FILE_TEXT_O = "\uf0f6"
FA_FILES_O = "\uf0c5"
FA_FIREFOX = "\uf269"
FA_PICTURE_O = "\uf03e"
FA_SPOTIFY = "\uf1bc"
FA_TERMINAL = "\uf120"
FA_TELEGRAM = "\uf3fe"
FA_CUBE = "\uf1b2"
FA_PAINT_BRUSH = "\uf1fc"
FA_BOOK = "\uf02d"
FA_FOLDER = "\uf07c"
FA_CALENDAR = "\uf133"
FA_BEZIER_CURVE = "\uf55b"
FA_VECTOR_SQUARE = "\uf5cb"
FA_VOLUME_UP = "\uf028"
WINDOW_ICONS = {
"Firefox": FA_FIREFOX,
"Gnome-terminal": FA_TERMINAL,
"chromium": FA_CHROME,
"code": FA_CODE,
"emacs": FA_CODE,
"evince": FA_FILE_PDF_O,
"feh": FA_PICTURE_O,
"gimp-2.10": FA_PAINT_BRUSH,
"gnome-calendar": FA_CALENDAR,
"google-chrome": FA_CHROME,
"inkscape": FA_PAINT_BRUSH,
"jetbrains-pycharm": FA_CODE,
"jetbrains-webstorm": FA_CODE,
"libreoffice": FA_FILE_TEXT_O,
"mupdf": FA_FILE_PDF_O,
"nautilus": FA_FOLDER,
"notion-nativefier-102b2f": FA_BOOK,
"pulseeffects": FA_VOLUME_UP,
"slic3r-prusa3d": FA_CUBE,
"spotify": FA_SPOTIFY,
"subl": FA_CODE,
"subl3": FA_CODE,
"telegram-desktop": FA_TELEGRAM,
"transmission-gtk": FA_DOWNLOAD,
"thunar": FA_FOLDER,
"urxvt": FA_TERMINAL,
}
i3 = i3ipc.Connection()
def xprop(win_id, property):
"""
Return an array of the values for the given property from xprop.
Requires xorg-xprop to be installed.
"""
try:
prop = proc.check_output(['xprop', '-id', str(win_id), property],
stderr=proc.DEVNULL)
prop = prop.decode('utf-8')
return re.findall('"([^"]+)"', prop)
except proc.CalledProcessError:
print(f"Unable to get property for window '{win_id}'")
return None
def icon_for_window(window):
classes = xprop(window.window, 'WM_CLASS')
if classes:
for cls in classes:
if cls in WINDOW_ICONS:
return WINDOW_ICONS[cls]
print('No icon available for window with classes: %s' % str(classes))
return '*'
def rename():
"""Rename all workspaces based on the present windows."""
for workspace in i3.get_tree().workspaces():
icons = " ".join(icon_for_window(w) for w in workspace.leaves())
new_name = f"{workspace.num}"
if icons:
new_name += f": {icons}"
i3.command(f'rename workspace "{workspace.name}" to "{new_name}"')
def on_change(i3, e):
"""Call rename() on relevant window events."""
print(f"{e.change}")
if e.change in ['new', 'close', 'move']:
rename()
def main():
rename()
i3.on('window', on_change)
i3.main()
if __name__ == "__main__":
main()