diff options
Diffstat (limited to 'sway-de/xdg-names/.local/bin/xdg-names.py')
-rwxr-xr-x | sway-de/xdg-names/.local/bin/xdg-names.py | 160 |
1 files changed, 0 insertions, 160 deletions
diff --git a/sway-de/xdg-names/.local/bin/xdg-names.py b/sway-de/xdg-names/.local/bin/xdg-names.py deleted file mode 100755 index b5c3e42..0000000 --- a/sway-de/xdg-names/.local/bin/xdg-names.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python3 - -""" -Rename i3 and Sway workspaces based on the focused app's XDG categories. - - Copyright (C) 2024 Matt Singleton - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -Adapted from this script: - https://github.com/nwg-piotr/swayinfo/blob/master/wsdnames.py - -Which was in turn based on this example: - https://github.com/altdesktop/i3ipc-python/blob/master/README.rst - -Dependencies: python-i3ipc>=2.0.1 (i3ipc-python), python-xlib - -Pay attention to the fact that your workspaces need to be numbered, not named, -for the script to work. - -Use: - bindsym $mod+1 workspace number 1 - -instead of: - bindsym $mod+1 workspace 1 - -in your ~/.config/sway/config or ~/.config/i3/config file. -""" - -import argparse -import configparser -import logging -import os -import os.path -import traceback - -from i3ipc import Connection, Event - - -def get_xdg_categories(app_id): - path = os.path.join("/usr/share/applications", f"{app_id}.desktop") - try: - config = configparser.ConfigParser() - config.read(path) - return config["Desktop Entry"]["Categories"].split(";") - except Exception: - return [] - - -def glyph(ws_num, app_id=None): - """ - Return a single glyph based on the app_id, if given, - then a default based on the workspace number, - and finally an empty glyph. - """ - global CONFIG_MTIME - latest_mtime = os.stat(CONFIG_PATH).st_mtime - if CONFIG_MTIME < latest_mtime: - CONFIG_MTIME = latest_mtime - CONFIG.read(CONFIG_PATH) - if app_id is not None: - if app_id in CONFIG["app"]: - return CONFIG["app"][app_id] - categories = get_xdg_categories(app_id) - for c in categories: - if c in CONFIG["xdg_additional"]: - return CONFIG["xdg_additional"][c] - for c in categories: - if c in CONFIG["xdg_main"]: - return CONFIG["xdg_main"][c] - logger.debug(f"no xdg icon found for: {app_id}") - ws_num = str(ws_num) - if ws_num in CONFIG["desktop"]: - return CONFIG["desktop"][ws_num] - return CONFIG["fallback"]["icon"] - - -def get_ws_name(ws_num, app_id=None): - ws_glyph = glyph(ws_num, app_id) - return f"{ws_num}:{ws_glyph}" - - -def assign_generic_name(i3, e): - """ - Name the workspace after the focused window name - """ - try: - if e.change == 'rename': - return - if e.change in ['new', 'move']: - # if a change results in a window spawning in an unfocused - # state (i.e. on another workspace), we need to look - # it up by id - con = i3.get_tree().find_by_id(e.container.id) - else: - con = i3.get_tree().find_focused() - if con.type == 'workspace': - # empty workspace - ws_num = con.workspace().num - name = get_ws_name(ws_num) - i3.command(f'rename workspace to "{name}"') - else: - old_name = con.workspace().name - # assume windows without an app_id are xwayland - if con.app_id is None: - app_id = con.window_class or "xwayland" - else: - app_id = con.app_id - name = get_ws_name(con.workspace().num, app_id) - i3.command(f'rename workspace "{old_name}" to "{name}"') - except Exception as e: - logger.debug("".join(traceback.format_exception(e))) - - -parser = argparse.ArgumentParser() -parser.add_argument("--debug", action="store_true") -args = parser.parse_args() - -log_format = "%(levelname)s %(name)s: %(message)s" -if args.debug is True: - logging.basicConfig(level=logging.DEBUG, format=log_format) -else: - logging.basicConfig(level=logging.INFO, format=log_format) -logger = logging.getLogger(__name__) - -CONFIG_MTIME = 0 -CONFIG_PATH = os.path.join( - os.environ.get( - "XDG_CONFIG_HOME", - os.path.join(os.environ["HOME"], ".config"), - ), - "xdg-names.ini", -) -CONFIG = configparser.ConfigParser() - -# Create the Connection object that can be used to send commands and -# subscribe to events. -i3 = Connection() - -# Subscribe to events -i3.on(Event.WORKSPACE_FOCUS, assign_generic_name) -i3.on(Event.WINDOW_FOCUS, assign_generic_name) -i3.on(Event.WINDOW_TITLE, assign_generic_name) -i3.on(Event.WINDOW_CLOSE, assign_generic_name) -i3.on(Event.WINDOW_NEW, assign_generic_name) -i3.on(Event.WINDOW_MOVE, assign_generic_name) -i3.on(Event.BINDING, assign_generic_name) - -i3.main() |