Source code for i3pystatus.window_title

# -*- coding: utf-8 -*-
from i3pystatus import Module
from threading import Thread
import i3ipc


[docs]class WindowTitle(Module): """ Display the current window title with async update. Uses asynchronous update via i3 IPC events. Provides instant title update only when it required. fork from window_tile_async of py3status by Anon1234 https://github.com/Anon1234 Requires the PyPI package `i3ipc`. .. rubric:: Available formaters * `{title}` — title of current focused window * `{class_name}` - name of application class @author jok @license BSD """ settings = ( ("format", "format string."), ("always_show", "do not hide the title when it can be already visible"), ("empty_title", "string that will be shown instead of the title when the title is hidden"), ("max_width", "maximum width of title"), ("color", "text color"), ) format = "{title}" always_show = False empty_title = "" max_width = 79 color = "#FFFFFF" def init(self): self.title = self.empty_title self.output = { "full_text": self.title, "color": self.color, } # we are listening to i3 events in a separate thread t = Thread(target=self._loop) t.daemon = True t.start() def get_title(self, conn): tree = conn.get_tree() w = tree.find_focused() p = w.parent # don't show window title when the window already has means # to display it if (not self.always_show and (w.border == "normal" or w.type == "workspace" or (p.layout in ("stacked", "tabbed") and len(p.nodes) > 1))): return self.empty_title else: title = w.name class_name = w.window_class if title is None: title = self.empty_title if len(title) > self.max_width: title = title[:self.max_width - 1] + "…" return self.format.format(title=title, class_name=class_name) def update_title(self, conn, e): # catch only focused window title updates title_changed = hasattr(e, "container") and e.container.focused # check if we need to update title due to changes # in the workspace layout layout_changed = ( hasattr(e, "binding") and (e.binding.command.startswith("layout") or e.binding.command.startswith("move container") or e.binding.command.startswith("border")) ) if title_changed or layout_changed: self.title = self.get_title(conn) self.update_display() def clear_title(self, *args): self.title = self.empty_title self.update_display() def update_display(self): self.output = { "full_text": self.title, "color": self.color, } def _loop(self): conn = i3ipc.Connection() self.title = self.get_title(conn) # set title on startup self.update_display() # The order of following callbacks is important! # clears the title on empty ws conn.on('workspace::focus', self.clear_title) # clears the title when the last window on ws was closed conn.on("window::close", self.clear_title) # listens for events which can trigger the title update conn.on("window::title", self.update_title) conn.on("window::focus", self.update_title) conn.main() # run the event loop