def main(): parser = argparse.ArgumentParser() parser.add_argument("--debug", action="store_true", help="Print debug messages to stderr") parser.add_argument( "--version", "-v", action="version", version="%(prog)s {}, Python {}".format(__version__, sys.version), help="display version information", ) parser.add_argument( "--workspaces", "-w", help= "Restricts autotiling to certain workspaces. Example: autotiling --workspaces 8 9", nargs="*", type=str, default=[], ) args = parser.parse_args() if args.debug and args.workspaces: print("autotiling is only active on workspaces:", ','.join(args.workspaces)) handler = partial(switch_splitting, debug=args.debug, workspaces=args.workspaces) i3 = Connection() i3.on(Event.WINDOW_FOCUS, handler) i3.main()
class I3Thread(threading.Thread): def __init__(self, queue): self.queue = queue self.i3 = Connection() super().__init__() def i3_update(self): self.queue.put(self.i3.get_tree().descendants()) def on_new_window(self, _, event): # when bar window becomes visible if event.container.name == TITLE: # make it floating and sticky self.i3.command( f"[title=\"{TITLE}\"] floating enable, sticky enable") # send the containers structure to it self.i3_update() # disable this event handler self.i3.off(self.on_new_window) def run(self): # this event is used to set up the bar window self.i3.on(Event.WINDOW_NEW, self.on_new_window) def update_on(event): self.i3.on(event, (lambda _, __: self.i3_update())) update_on(Event.WORKSPACE) update_on(Event.WINDOW_NEW) update_on(Event.WINDOW_CLOSE) self.i3.main() def switch_to_workspace(self, workspace_index): self.i3.command(f"workspace {workspace_index}")
def __init__(self): self.floating_windows = [] self.fader_running = False self.fade_queue = [] self.fade_data = {} self.bottom_win = None self.old_win = None self.active_win = None ipc = Connection() ipc.on(Event.WINDOW_FOCUS, self.on_window_focus) ipc.on(Event.WINDOW_NEW, self.on_window_new) ipc.on(Event.WINDOW_FLOATING, self.on_window_floating) for win in ipc.get_tree(): if win.type == "floating_con": self.floating_windows.append(win.id) if win.focused: change_opacity(win, FLOAT_AC) self.active_win = win else: change_opacity(win, FLOAT_INAC) elif win.type == "con": if win.focused: self.active_win = win change_opacity(win, CON_AC) else: change_opacity(win, CON_INAC) ipc.main()
def start(self): from i3ipc import Connection i3 = Connection() self.update(i3) for event in ["window::move", "window::urgent"]: i3.on(event, self.update) i3.main()
def main(args): '''Connect to IPC, set transparencies, and set up listener''' ipc = Connection() set_opacities(ipc, args.focused, args.unfocused) ipc.on('window::focus', lambda ipc, _: set_opacities(ipc, args.focused, args.unfocused)) ipc.main()
def main(): i3 = Connection() rename_workspaces(i3, None) i3.on(Event.WINDOW_NEW, rename_workspaces) i3.on(Event.WINDOW_CLOSE, rename_workspaces) i3.on(Event.WINDOW_MOVE, rename_workspaces) i3.main()
def main(): parser = argparse.ArgumentParser() parser.add_argument('--debug', action='store_true', help='Print debug messages to stderr') args = parser.parse_args() handler = partial(switch_splitting, debug=args.debug) i3 = Connection() i3.on(Event.WINDOW_FOCUS, handler) i3.main()
def start(self): from i3ipc import Connection i3 = Connection() self.change_title(i3) for event in ["workspace::focus", "window::close"]: i3.on(event, self.clear_title) for event in ["window::title", "window::focus", "binding"]: i3.on(event, self.change_title) i3.main()
def main(): i3 = Connection() i3swallow = I3Swallow(i3, "st") i3.on(Event.WINDOW_NEW, i3swallow.on_new) i3.on(Event.WINDOW_FOCUS, i3swallow.on_focus) i3.on(Event.WINDOW_CLOSE, i3swallow.on_close) i3.on(Event.WINDOW_MOVE, i3swallow.on_move) i3.on(Event.BINDING, i3swallow.on_binding) i3.on(Event.TICK, i3swallow.on_tick) i3.main()
def main(): parser = argparse.ArgumentParser() parser.add_argument("--debug", action="store_true", help="Print debug messages to stderr") parser.add_argument( "--version", "-v", action="version", version="%(prog)s {}, Python {}".format(1, sys.version), help="display version information", ) args = parser.parse_args() handler = partial(switch_splitting, debug=args.debug) i3 = Connection() i3.on(Event.WINDOW_FOCUS, handler) i3.main()
def __init__(self): self.fader_running = False self.fade_queue = [] self.fade_data = {} self.current_win = None self.new_win = None ipc = Connection() ipc.on(Event.WINDOW_FOCUS, self.on_window_focus) ipc.on(Event.WINDOW_NEW, self.on_window_new) ipc.on(Event.WINDOW_FLOATING, self.on_window_floating) for win in ipc.get_tree(): if win.focused: change_opacity(win, AC_TRANS) self.current_win = win else: change_opacity(win, INAC_TRANS) ipc.main()
def start(self): ipc = Connection() ipc.on(Event.WINDOW_FOCUS, self.on_window_focus) ipc.on(Event.WINDOW_NEW, self.on_window_new) ipc.on(Event.WINDOW_FLOATING, self.on_window_floating) for win in ipc.get_tree(): if win.type == "floating_con": self.floating_windows.append(win.id) if win.focused: change_opacity(win, FLOAT_AC) self.active_win = win else: change_opacity(win, FLOAT_INAC) elif win.type == "con": if win.focused: self.active_win = win change_opacity(win, CON_AC) else: change_opacity(win, CON_INAC) ipc.main()
def main(): """ Main function - listen for window focus changes and call set_layout when focus changes """ opt_list, _ = getopt.getopt(sys.argv[1:], 'hp:') pid_file = None for opt in opt_list: if opt[0] == "-h": print_help() sys.exit() if opt[0] == "-p": pid_file = opt[1] if pid_file: with open(pid_file, 'w') as f: f.write(str(os.getpid())) i3 = Connection() i3.on(Event.WINDOW_FOCUS, set_layout) i3.main()
def main(): """If indicator script is not already running, subscribe to events""" # Get a lock on a temporary file to prevent multiple instances from # running, which would cause nasty race conditions lockfile = os.path.normpath(gettempdir() + "/i3_layout_indicator.lock") fp = open(lockfile, 'w') try: fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: print("i3 layout indicator is already running") print("To kill, run 'pkill -f \"python.*i3_layout_indicator.py\"'") sys.exit(1) # Bind events i3 = Connection() i3.on(Event.TICK, update_indicator) i3.on(Event.WINDOW_FOCUS, update_indicator) i3.on(Event.BINDING, update_indicator) # Update indicator once on startup update_indicator(i3, None) # Start listening for events i3.main()
import i3ipc.events as events import time, os, subprocess sway = Connection() def show_notification(text, timeout=1000): proc = subprocess.Popen(['notify-send', text, '-t', str(timeout)]) proc.wait(2) def on_ws_init(_, e: events.WorkspaceEvent): print('ws init', e.current.name) # Start VS Code on workspace 2 if e.current.name == '2' and os.system('pgrep code') != 0: show_notification('Launching VS Code...', 2000) sway.command('exec code') # Start Firefox on workspace 3 if e.current.name == '3' and os.system('pgrep firefox') != 0: show_notification('Launching Firefox...', 3000) sway.command('exec firefox') sway.on(Event.WORKSPACE_INIT, on_ws_init) sway.get_workspaces() sway.main()
import os titlehook = Connection() th = 'polybar-msg [-p pid] hook titlehook 1' wh = 'polybar-msg hook weatherhook 1' show = 'polybar-msg cmd show' hide = 'polybar-msg cmd hide' bh = 'polybar-msg hook backupd 1' ws = 'polybar-msg hook wshook 1' def windownotify(titlehook, event): # if event.container.fullscreen_mode == 0: # os.system(show) # #call('polybar-msg cmd show'.split(' ')) # else: # os.system(hide) # #call('polybar-msg cmd hide'.split(' ')) if event.change in "focus" "title": os.system(th) #call('polybar-msg hook titlehook 1'.split(' ')) titlehook.on('window', windownotify) titlehook.main()
from i3ipc import Connection from subprocess import call def window_notify(i3, event): if event.container.fullscreen_mode == 0: call ('polybar-msg cmd show'.split()) else: call ('polybar-msg cmd hide'.split()) if event.change in ["focus", "title"]: call("polybar-msg hook titlehook 1".split(" ")) def window_ws_notify(i3, event): if event.change in ["title", "focus"]: call('polybar-msg hook wshook 1'.split()) def ws_notify(i3, event): if event.change == "focus": if event.old.num != -1: call('polybar-msg hook wshook 1'.split()) if __name__ == "__main__": i3 = Connection() i3.on('window', window_ws_notify) i3.on('workspace', window_ws_notify) i3.main()
#!/usr/bin/env python3 from i3ipc import Event, Connection def set_urgency_hint(c, e): window = c.get_tree().find_by_id(e.container.id) if window.workspace().id != c.get_tree().find_focused().workspace().id: window.command("urgent enable") c = Connection() c.on(Event.WINDOW_TITLE, set_urgency_hint) c.on(Event.WINDOW_NEW, set_urgency_hint) c.main()
def main(): parser = argparse.ArgumentParser() parser.add_argument("-d", "--debug", action="store_true", help="print debug messages to stderr") parser.add_argument( "-v", "--version", action="version", version="%(prog)s {}, Python {}".format(__version__, sys.version), help="display version information", ) parser.add_argument( "-w", "--workspaces", help= "restricts autotiling to certain workspaces; example: autotiling --workspaces 8 9", nargs="*", type=str, default=[], ) """ Changing event subscription has already been the objective of several pull request. To avoid doing this again and again, let's allow to specify them in the `--events` argument. """ parser.add_argument( "-e", "--events", help= "list of events to trigger switching split orientation; default: WINDOW MODE", nargs="*", type=str, default=["WINDOW", "MODE"]) args = parser.parse_args() if args.debug and args.workspaces: print("autotiling is only active on workspaces:", ','.join(args.workspaces)) # For use w/ nwg-panel if args.workspaces: save_string(','.join(args.workspaces), os.path.join(temp_dir(), "autotiling")) if not args.events: print("No events specified", file=sys.stderr) sys.exit(1) handler = partial(switch_splitting, debug=args.debug, workspaces=args.workspaces) i3 = Connection() for e in args.events: try: i3.on(Event[e], handler) print("{} subscribed".format(Event[e])) except KeyError: print("'{}' is not a valid event".format(e), file=sys.stderr) i3.main()
def main(): i3 = Connection() i3.on(Event.WINDOW_FOCUS, float_status) i3.on(Event.WORKSPACE_MOVE, float_status) i3.main()
def main(): i3 = Connection() handler = I3UnityFix() i3.on(Event.WORKSPACE_FOCUS, handler.on_workspace_focus) i3.main()
def display_workspace(workspace): append = "" if last_urgent_workspace_name is not None: append = ' %{F#ad471c}(' + last_urgent_workspace_name + '*)%{F-}' print(" %s%s%s" % (workspace.name, " %{F#002b36}%{F-}" if workspace.focused else "", append), flush=True) def on_window_urgent(self, e): display_current_workspace() def on_workspace_urgent(self, e): display_current_workspace() i3.on(Event.WORKSPACE_FOCUS, on_workspace_focus) i3.on(Event.WORKSPACE_RENAME, on_workspace_focus) i3.on(Event.WINDOW_URGENT, on_window_urgent) i3.on(Event.WORKSPACE_URGENT, on_workspace_urgent) display_current_workspace() i3.main()
class Fader: ipc = None def __init__(self, active_opacity, inactive_opacity, floating_opacity, fade_time, frame_time): self.active_opacity = active_opacity self.inactive_opacity = inactive_opacity self.floating_opacity = floating_opacity self.fade_time = fade_time self.frame_time = frame_time self.fader_running = False self.fade_queue = [] self.fade_data = {} self.current_win = None self.new_win = None def start(self): if self.ipc is not None: raise Exception('Already started') self.ipc = Connection() self.ipc.on(Event.WINDOW_FOCUS, self.on_window_focus) self.ipc.on(Event.WINDOW_NEW, self.on_window_new) self.ipc.on(Event.WINDOW_FLOATING, self.on_window_floating) for win in self.ipc.get_tree(): if win.focused: change_opacity(win, self.active_opacity) self.current_win = win else: change_opacity(win, self.inactive_opacity) self.ipc.main() def stop(self): if self.ipc is None: raise Exception('Not started') self.ipc.off(self.on_window_focus) self.ipc.off(self.on_window_new) self.ipc.off(self.on_window_floating) for win in self.ipc.get_tree(): change_opacity(win, 1) self.ipc.main_quit() def enqueue_fade(self, win, start, target, duration): if win.id in self.fade_queue: f = self.fade_data[win.id] change = (self.frame_time / duration) * (target - f['opacity']) f['change'] = change f['target'] = target else: change_opacity(win, start) change = (self.frame_time / duration) * (target - start) fade_data = { 'opacity': start, 'change': change, 'target': target, 'win': win } self.fade_queue.append(win.id) self.fade_data[win.id] = fade_data def start_fader(self): if not self.fader_running: self.fader_running = True Thread(target=self.fader).start() def fader(self): while self.fade_queue: for win_id in self.fade_queue.copy(): f = self.fade_data[win_id] f['opacity'] += f['change'] finished = False if f['change'] > 0: if f['opacity'] >= f['target']: finished = True elif f['opacity'] <= f['target']: finished = True if finished: change_opacity(f['win'], f['target']) self.fade_queue.remove(win_id) del self.fade_data[win_id] else: change_opacity(f['win'], f['opacity']) sleep(self.frame_time) self.fader_running = False def on_window_new(self, ipc, event): if event.container.type == 'floating_con': change_opacity(event.container, self.floating_opacity) else: change_opacity(event.container, self.inactive_opacity) self.new_win = event.container.id def on_window_floating(self, ipc, event): if event.container.id == self.current_win.id: self.current_win = event.container def on_window_focus(self, ipc, event): if self.current_win.id == event.container.id: return if self.current_win.type == 'floating_con': trans = self.floating_opacity else: trans = self.inactive_opacity if event.container.id == self.new_win: change_opacity(self.current_win, trans) change_opacity(event.container, self.active_opacity) else: self.enqueue_fade(self.current_win, self.active_opacity, trans, self.fade_time) if event.container.type == 'floating_con': self.enqueue_fade(event.container, self.floating_opacity, self.active_opacity, self.fade_time) else: self.enqueue_fade(event.container, self.inactive_opacity, self.active_opacity, self.fade_time) self.start_fader() self.current_win = event.container self.new_win = None
class I3ipc(Ipc): """ i3ipc - an improved python library to control i3wm and sway """ _focused_workspace = None _focused_window = None def setup(self, parent): from threading import Thread self.parent.cache_timeout = self.parent.py3.CACHE_FOREVER self.window_properties = {} t = Thread(target=self.start) t.daemon = True t.start() # noinspection PyTypeChecker def start(self): from i3ipc import Connection, Event self.i3 = Connection() self._update(self.i3.get_tree().find_focused()) self.i3.on(Event.WORKSPACE_FOCUS, self._on_workplace_focus) self.i3.on(Event.WINDOW_CLOSE, self._on_window_close) self.i3.on(Event.WINDOW_TITLE, self._on_window_title) self.i3.on(Event.WINDOW_FOCUS, self._on_window_focus) self.i3.on(Event.BINDING, self._on_binding) self.i3.main() def _on_workplace_focus(self, i3, event): self._focused_workspace = event.current self._focused_window = None if event.current.nodes or event.current.floating_nodes: return self._update(event.current) def _on_window_close(self, i3, event): if event.container.window == self._focused_window: self._focused_window = None self._update(i3.get_tree().find_focused()) def _on_binding(self, i3, event): self._update(i3.get_tree().find_focused()) def _on_window_title(self, i3, event): if event.container.focused: self._update(event.container) def _on_window_focus(self, i3, event): self._focused_window = event.container.window self._update(event.container) def _update(self, event_element): if not event_element: return # hide title on containers with window title if self.parent.hide_title: show_name = True if event_element.border == "normal" or event_element.type == "workspace": show_name = False else: event_element_parent = event_element.parent or getattr( self.i3.get_tree().find_by_id(event_element.id), "parent", None) if (event_element_parent and event_element_parent.layout in ("stacked", "tabbed") and len(event_element_parent.nodes) > 1): show_name = False window_properties = { "title": event_element.name if show_name else None, "class": event_element.window_class, "instance": event_element.window_instance, } else: window_properties = { "title": event_element.name, "class": event_element.window_class, "instance": event_element.window_instance, } window_properties = self.compatibility(window_properties) if self.window_properties != window_properties: self.window_properties = window_properties self.parent.py3.update() def get_window_properties(self): return self.window_properties
def main(args): i3 = Connection() i3.on(Event.WINDOW_NEW, on_window_new) with Listener(on_click=on_click): i3.main()