Skip to content

Commit

Permalink
Added script to dynamically change window shortnames
Browse files Browse the repository at this point in the history
  • Loading branch information
justbuchanan committed Oct 16, 2016
1 parent 402da44 commit 59d70c9
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 6 deletions.
18 changes: 12 additions & 6 deletions i3-autoname-workspaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import signal
import sys

from util import *


# 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
Expand Down Expand Up @@ -61,6 +63,7 @@

i3 = i3ipc.Connection()


# Returns an array of the values for the given property from xprop. This
# requires xorg-xprop to be installed.
def xprop(win_id, property):
Expand All @@ -84,19 +87,22 @@ def icon_for_window(window):
# renames all workspaces based on the windows present
def rename():
for workspace in i3.get_tree().workspaces():
icons = [icon_for_window(w) for w in workspace.leaves()]
icon_str = ': ' + ' '.join(icons) if len(icons) else ''
new_name = str(workspace.num) + icon_str
name_parts = parse_workspace_name(workspace.name)
name_parts['icons'] = ' '.join([icon_for_window(w) for w in workspace.leaves()])
new_name = construct_workspace_name(name_parts)
i3.command('rename workspace "%s" to "%s"' % (workspace.name, new_name))

rename()

# exit gracefully when ctrl+c is pressed
def signal_handler(signal, frame):
# rename workspaces to just numbers on exit to indicate that this script is
# no longer running
# rename workspaces to just numbers and shortnames on exit to indicate that
# this script is no longer running
for workspace in i3.get_tree().workspaces():
i3.command('rename workspace "%s" to "%d"' % (workspace.name, workspace.num))
name_parts = parse_workspace_name(workspace.name)
name_parts['icons'] = None
new_name = construct_workspace_name(name_parts)
i3.command('rename workspace "%s" to "%s"' % (workspace.name, new_name))
i3.main_quit()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
Expand Down
52 changes: 52 additions & 0 deletions i3-rename-workspace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3

## This script is used to dynamically rename workspace names in i3.
# When run, it presents a text field popup using zenity, in which you can type a
# new name for the workspace. It is compatible with the i3-autoname-workspaces
# script and renames only the "shortname" of the workspace, keeping the number
# and window icons in place.
#
# Note that this script can be used without i3-autoname-workspaces.py
#
# Dependencies:
# * zenity - install with system package manager
# * i3ipc - install with pip

import i3ipc
import logging
import subprocess as proc
import re
import sys

from util import *


logging.basicConfig(level=logging.INFO)

i3 = i3ipc.Connection()
workspace = [w for w in i3.get_workspaces() if w.focused][0]
name_parts = parse_workspace_name(workspace.name)
logging.info("Current workspace shortname: '%s'" % name_parts['shortname'])

try:
# use zenity to show a text box asking the user for a new workspace name
prompt_title = "Rename Workspace:" if name_parts['shortname'] == None else "Rename Workspace '%s':" % name_parts['shortname']
response = proc.check_output(['zenity', '--entry', "--text=%s" % prompt_title])
new_shortname = response.decode('utf-8').strip()
logging.info("New name from user: '%s'" % new_shortname)

if ' ' in new_shortname:
msg = "No spaces allowed in workspace names"
logging.error(msg)
proc.check_call(['zenity', '--error', '--text=%s' % msg])
sys.exit(1)


name_parts['shortname'] = new_shortname
new_name = construct_workspace_name(name_parts)

# get the current workspace and rename it
workspace = [w for w in i3.get_workspaces() if w.focused][0]
res = i3.command('rename workspace "%s" to "%s"' % (workspace.name, new_name))
except proc.CalledProcessError as e:
logging.info("Cancelled by user, exiting...")
22 changes: 22 additions & 0 deletions util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import re

# Used so that we can keep the workspace's name when we add icons to it.
# Returns a dictionary with the following keys: 'num', 'shortname', and 'icons'
# Any field that's missing in @name will be None in the returned dict
def parse_workspace_name(name):
return re.match('(?P<num>\d+):?(?P<shortname>\w+)? ?(?P<icons>.+)?', name).groupdict()

# Given a dictionary with 'num', 'shortname', 'icons', return the formatted name
# by concatenating them together.
def construct_workspace_name(parts):
new_name = str(parts['num'])
if parts['shortname'] or parts['icons']:
new_name += ':'

if parts['shortname']:
new_name += parts['shortname']

if parts['icons']:
new_name += ' ' + parts['icons']

return new_name

0 comments on commit 59d70c9

Please sign in to comment.