Example #1
0
def get_i3_connection():
    '''Return a valid, cached i3 Connection instance
	'''
    global conn
    if not conn:
        import i3ipc
        conn = i3ipc.Connection()
    try:
        conn.get_tree()
    except BrokenPipeError:
        import i3ipc
        conn = i3ipc.Connection()
    return conn
Example #2
0
def main():
    generate_keys()

    i3 = i3ipc.Connection()
    i3.on("mode", i3_mode_change)

    last_time = 0
    focused_window = False
    logsocket = socket.socket(socket.AF_UNIX)
    logsocket.connect(sys.argv[1])
    logsocket.setblocking(0)
    loglines = follow(logsocket, i3)
    settings = get_settings()
    for line in loglines:
        if line == None or len(line) == 0:
            continue
        if debug:
            print line
        try:
            data = json.loads(line)
        except:
            continue
        if debug:
            print data
        if data['event_type'] == 'focus_change':
            settings['state']['window_name'] = data['window_name']

        if data['event_type'] == 'key':
            handle_modifiers(data, modifiers)
        if data['event_type'] == 'key':
            handle_event(data, settings,modifiers)
            continue 
def main(workspace_name, get_index, visibility='invisible', *drek):

    get_index = int(get_index)

    conn = i3ipc.Connection()

    workspace = workspace_by_name(conn, workspace_name)  # Find workspace.
    if workspace == None:
        print("Workspace not found")
        exit(1)

    windows =  workspace.leaves()  # Find windows in there.
    if visibility=='visible':
        windows = filter(window_is_visible, windows)
    elif visibility!='invisible':
        print("WARN: currently only support invisible and visible as selectors.")

    window = pick_from_list(list(windows), get_index)  # Pick correct window from there.

#    conn.command("workspace " + workspace_name)  # It already goes there.

    if window!=None:
        print("Focussing %d" % window.window)
        conn.command('[id="%d"] focus' % window.window)
    else:
        print("Did not find window(%d)"%get_index)
def on_window_focus(ipc, event):
    global prev_focused
    print("Got event")

    focused = event.container
    #if prev_focused and (True or prev_focused.app_id == 'termite'):
    #    prev_focused.command('opacity 0.8')

    if True or focused.app_id == 'termite':
        tree = ipc.get_tree()
        focused = tree.find_by_id(focused.id)
        if focused:
            curent_workspace = focused.workspace()
            #from ipdb import set_trace; set_trace()
            for node in curent_workspace.descendants():
                node.command('opacity 0.8')
            focused.command('opacity 1')

    print(f"last_focused: {prev_focused}, new: {focused}")
    if prev_focused and focused.id != prev_focused.id:
        current_layouts = {
            i.identifier: i.xkb_active_layout_index
            for i in ipc.get_inputs()
        }
        id_to_layouts[prev_focused.id] = current_layouts
        ipc = i3ipc.Connection()
        for l in current_layouts:
            try:
                ipc.command(
                    f'input {l} xkb_switch_layout {id_to_layouts[focused.id][l]}'
                )
            except KeyError:
                pass

    prev_focused = focused
Example #5
0
 def run(self, queue=None):
     polling_interval = self.__params['polling']
     self.__queue = queue
     try:
         sway_ipc = sway.Connection()
     except:
         logger.error('Cannot find sway socket, exiting.')
         raise
     while True:
         sway_outputs = sway_ipc.get_outputs()
         #pprint(sway_outputs)
         # for now only first display is handled
         if len(sway_outputs) > 0:
             if (self.h != sway_outputs[0].rect.height
                     or self.w != sway_outputs[0].rect.width):
                 self.w = sway_outputs[0].rect.width
                 self.h = sway_outputs[0].rect.height
                 logger.info("Resolution changed w: {} h: {}".format(
                     self.w, self.h))
                 # reporting only resolution of first display, in future we might need to compile "global" resolution based on position of displays and it sizes
                 if (self.__queue):
                     self.__queue.put({
                         field.EVENT: event.SCREEN_RESOLUTION,
                         field.WIDTH: self.w,
                         field.HEIGHT: self.h
                     })
         sleep(
             polling_interval
         )  # get screen resolution once per minute (do we actually need to get it repeatedly? We might need to report resolution changes to server.
Example #6
0
def i3ipc_thread(use_ws=False, use_title=False):
    try:
        i3 = i3ipc.Connection()
        # conf = i3.get_bar_config("status")

        if renderer is not None:
            # "outputs" is not returned by i3ipc
            # if "outputs" in conf.keys():
            #     renderer.set_outputs(conf["outputs"])
            if use_ws:
                renderer.update_workspace(i3.get_workspaces())
            if use_title:
                renderer.clear_title()
            renderer.update_outputs(i3.get_outputs())
            thread_render()

        if use_ws:
            i3.on("workspace", on_change_ws)
        if use_title:
            i3.on("window", on_change_title)
        i3.on("output", on_change_output)
        i3.main()

        thread_die("connection to i3 lost.")
    except Exception as e:
        thread_die(exception=e)
Example #7
0
    def i3(self):
        process = Popen(['i3', '-c', 'test/i3.config'])
        # wait for i3 to start up
        tries = 0

        while True:
            try:
                IpcTest.i3_conn = i3ipc.Connection()
                break
            except Exception:
                tries += 1

                if tries > 1000:
                    raise Exception('could not start i3')

                time.sleep(0.01)

        yield IpcTest.i3_conn

        try:
            tree = IpcTest.i3_conn.get_tree()
            for l in tree.leaves():
                l.command('kill')
            IpcTest.i3_conn.command('exit')
        except OSError:
            pass

        process.kill()
        IpcTest.i3_conn = None
Example #8
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-c",
                        "--compat",
                        action="store_true",
                        help="Output compatible with i3tree")
    parser.add_argument("-w",
                        "--workspace",
                        type=str,
                        nargs="*",
                        help="Workspace to display")
    parser.add_argument("-f",
                        "--focused",
                        action="store_true",
                        help="Display info for focused workspace")
    args = parser.parse_args()

    i3 = i3ipc.Connection()
    tree = i3.get_tree()

    if args.compat:
        i3tree_walk_tree(tree, 0)
    else:
        if args.focused:
            current_workspace = find_focused_workspace(i3).name
            args.workspace = [current_workspace] if not args.workspace else \
                args.workspace + [current_workspace]

        walk_tree(tree,
                  0,
                  filter_workspaces=args.workspace,
                  mute=args.workspace is not None)
def toggle_pin(
    target = argv[1],
    left_margin = int(argv[2]), # 10
    desired_width = int(argv[3]) # 450
):
    i3 = i3ipc.Connection()
    current_workspace = i3.get_tree().find_focused().workspace()

    windows = {
        "tabs_outliner" : pinnable_window(i3, "tabs_outliner"),
        "rover" : pinnable_window(i3, "rover")
    }

    other = {
        "tabs_outliner" : "rover",
        "rover" : "tabs_outliner"
    }

    other = windows[other[target]]
    target = windows[target]
    
    if other.is_running and (other.window.workspace().name == current_workspace.name):
        other.window.command("move scratchpad")

    if target.is_running and (target.window.workspace().name == current_workspace.name):
        target.window.command("move scratchpad")
        return

    if not target.is_running:
        target.start()

    pin(target, current_workspace, left_margin, desired_width)
Example #10
0
def main(stdscr):
    ipc = i3ipc.Connection()

    def on_event(ipc, e):
        txt = ''
        for ws in ipc.get_tree().workspaces():
            txt += container_to_text(ws, 0) + '\n'

        global last_txt
        if txt == last_txt:
            return

        stdscr.clear()
        for l in txt:
            try:
                stdscr.addstr(l)
            except Exception:
                break
        stdscr.refresh()
        last_txt = txt

    on_event(ipc, None)

    ipc.on('window', on_event)
    ipc.on('binding', on_event)
    ipc.on('workspace', on_event)

    ipc.main()
Example #11
0
    def __init__(self):

        self.conn = i3ipc.Connection()

        # Subscribe to Events
        self.conn.on('mode', self.on_mode)
        self.conn.on('workspace', self.on_workspace)
Example #12
0
def workspaces(pl, only_show=None, output=None, strip=0):
    '''Return list of used workspaces

	:param list only_show:
		Specifies which workspaces to show. Valid entries are ``"visible"``, 
		``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces 
		are shown.

	:param str output:
		If specified, only workspaces on this output are shown.

	:param int strip:
		Specifies how many characters from the front of each workspace name 
		should be stripped (e.g. to remove workspace numbers). Defaults to zero.

	Highlight groups used: ``workspace`` or ``w_visible``, ``workspace`` or ``w_focused``, ``workspace`` or ``w_urgent``.
	'''
    global conn
    if not conn:
        try:
            import i3ipc
        except ImportError:
            import i3 as conn
        else:
            conn = i3ipc.Connection()

    return [{
        'contents': w['name'][min(len(w['name']), strip):],
        'highlight_groups': calcgrp(w)
    } for w in conn.get_workspaces() if (not only_show or any(
        w[typ]
        for typ in only_show)) and (not output or w['output'] == output)]
Example #13
0
def focus_i3():
    if have_i3:
        regex = w.config_get_plugin("title.regex")

        i3conn = i3.Connection()
        weechat = i3conn.get_tree().find_named(regex)[0]
        weechat.command('focus')
Example #14
0
def update_state(i3, e):
    t = timer.start("update_state")
    global last_update

    if not global_updates_running:
        return False
    if time.time() - last_update < float(
            args.interval if args.interval else 1):
        return False
    last_update = time.time()

    root = i3.get_tree()
    deleted = []
    for num in global_knowledge.keys():
        if type(num) is int and num not in [w.num for w in root.workspaces()]:
            deleted += [num]
    for num in deleted:
        del (global_knowledge[num])

    current_workspace = root.find_focused().workspace()
    update_workspace(current_workspace)

    t.stop()

    screenshot = grab_screen()

    if current_workspace.num == i3ipc.Connection().get_tree().find_focused(
    ).workspace().num:
        global_knowledge[current_workspace.num]['screenshot'] = screenshot
Example #15
0
def main(rofi_args=sys.argv[1:]):
    command_line = "rofi -dmenu -i -markup-rows -p '> '"
    i3 = i3ipc.Connection()
    pink = "w{} d{:<4} |<span color='pink'> {}</span>"
    yellow = "w{} d{:<4} |<span color='yellow'> {}</span>"
    coll = collections.deque()
    t = i3.get_tree()
    f = t.find_focused()
    for w, n in zip(t.leaves(), range(len(t.leaves()))):
        if f.id == w.id:
            coll.appendleft(
                (w.id, yellow.format(n + 1,
                                     w.workspace().name, w.name)))
        elif w.workspace().id == f.workspace().id:
            coll.appendleft(
                (w.id, pink.format(n + 1,
                                   w.workspace().name, w.name)))
        else:
            coll.append(
                (w.id, "w{} d{:<4} | {}".format(n + 1,
                                                w.workspace().name, w.name)))

    rofi = Menu(split(command_line) + rofi_args)
    result = rofi(collections.OrderedDict((v, k) for k, v in coll))
    f = t.find_by_id(result.value)
    f.command('focus')
Example #16
0
    def __init__(self, engine, config):
        super(Module, self).__init__(
            engine,
            config
        )

        # parsing of parameters
        self._scroll = bumblebee.util.asbool(self.parameter("scroll", False))
        self._max = int(self.parameter("max", 64))
        self._placeholder = self.parameter("placeholder", "...")

        # set output of the module
        self.widgets(bumblebee.output.Widget(full_text=
            self._scrolling_focused_title if self._scroll else self._focused_title))

        # create a connection with i3ipc
        try:
            self._i3 = i3ipc.Connection()
            # event is called both on focus change and title change
            self._i3.on("window", lambda _p_i3, _p_e: self._pollTitle())
            # begin listening for events
            threading.Thread(target=self._i3.main).start()
        except:
            pass

        # initialize the first title
        self._pollTitle()
Example #17
0
def restore(workspace_name, saved_programs):
    """
    Restore the running programs from an i3 workspace.
    """
    # Remove already running programs from the list of program to restore.
    running_programs = get_programs(workspace_name, False)
    for program in running_programs:
        if program in saved_programs:
            saved_programs.remove(program)

    i3 = i3ipc.Connection()
    for entry in saved_programs:
        cmdline = entry['command']
        working_directory = entry['working_directory']

        # If the working directory does not exist, set working directory to
        # user's home directory.
        if not Path(working_directory).exists():
            working_directory = Path.home()

        # If cmdline is array, join it into one string for use with i3's exec
        # command.
        if isinstance(cmdline, list):
            # Quote each argument of the command in case some of them contain
            # spaces.
            cmdline = [f'\\"{arg}\\"' for arg in cmdline if arg != '']
            command = ' '.join(cmdline)
        else:
            command = cmdline

        # Execute command via i3 exec.
        i3.command(f'exec "cd \\"{working_directory}\\" && {command}"')
def main(args):
    conn = i3ipc.Connection()

    workspace = workspace_by_name(conn, args.workspace)  # Find workspace.
    if workspace == None:
        print("Workspace not found, making it.")
        conn.command("workspace " + args.workspace)

    else:
        windows = workspace.leaves()  # Find windows in there.
        if args.filter == 'visible':
            windows = filter(window_is_visible, windows)
        elif args.filter != 'none':
            print("WARN: currently only support `visible` as window filter.")

        window = pick_from_list(list(windows),
                                args.nth)  # Pick correct window from there.

        if window != None:
            print("Focussing %d" % window.window)
            conn.command('[id="%d"] focus' % window.window)
        else:
            print("Did not find window(%d) going to workspace anyway." %
                  args.nth)
            conn.command("workspace " + args.workspace)

    if args.mode != 'no':
        conn.command("mode " + args.mode)
Example #19
0
def update_state(i3, e):
    global last_update

    if not global_updates_running:
        return False
    if time.time() - last_update < 0.1:
        return False
    last_update = time.time()

    root = i3.get_tree()
    deleted = []
    for num in global_knowledge.keys():
        if type(num) is int and num not in [w.num for w in root.workspaces()]:
            deleted += [num]
    for num in deleted:
        del (global_knowledge[num])

    current_workspace = root.find_focused().workspace()
    update_workspace(current_workspace)

    screenshot = grab_screen()

    #time.sleep(0.5)

    if current_workspace.num == i3ipc.Connection().get_tree().find_focused(
    ).workspace().num:
        global_knowledge[current_workspace.num]['screenshot'] = screenshot
Example #20
0
def goto(char):
    i3 = i3ipc.Connection()
    workspaces = i3.get_workspaces()
    focused = i3.get_tree().find_focused()
    char_wp = []

    for wp in workspaces:
        if wp["name"].lower().startswith(char):
            char_wp.append(wp)

    if len(char_wp) == 0:
        i3.command("workspace {}".format(char))
    else:
        if not focused.workspace().name.startswith(char):
            i3.command("workspace {}".format(char_wp[0]["name"]))
        else:
            jump = False
            for wp in cycle(char_wp):
                if jump:
                    i3.command("workspace {}".format(wp["name"]))
                    exit(0)
                elif focused.workspace().name != wp["name"]:
                    continue
                else:
                    jump = True
Example #21
0
def main():
    connection = i3ipc.Connection()
    tree = connection.get_tree()
    args = parser()
    app, title, window_class = args.app, args.title, args.window_class

    if title:
        results = tree.find_named(title)
    elif window_class:
        results = tree.find_instanced(window_class)
    else:
        import sys
        sys.exit('Must either provide a -t/--tittle or a -c/--class')
    # if window is not found, open it
    if not results:
        cmd_open = f'i3-msg exec "{app}"'
        run(cmd_open)
        if title:
            while not title_exists(connection, title):
                time.sleep(0.01)
            window = title_exists(connection, title)
        elif window_class:
            while not class_exists(connection, window_class):
                time.sleep(0.01)
            window = class_exists(connection, window_class)
        window.command('move scratchpad, move position center')
    else:
        if title:
            command = f'i3-msg \\[title="{title}"\\] scratchpad show, move position center'
        elif window_class:
            command = f'i3-msg \\[instance="{window_class}"\\] scratchpad show, move position center'
        run(command)
Example #22
0
def restore_workspace(workspace, numeric, directory, profile, target):
    """
    Restore i3 workspace layout and programs.
    """
    i3 = i3ipc.Connection()

    if workspace is None:
        workspace = i3.get_tree().find_focused().workspace().name

    directory = util.resolve_directory(directory, profile)

    if numeric and not workspace.isdigit():
        util.eprint('Invalid workspace number.')
        sys.exit(1)

    # Get layout name from file.
    workspace_layout = layout.read(workspace, directory, profile)
    if 'name' in workspace_layout and profile is None:
        workspace_name = workspace_layout['name']
    else:
        workspace_name = workspace

    # Switch to the workspace which we are loading.
    i3.command(f'workspace --no-auto-back-and-forth "{workspace_name}"')

    if target != 'programs_only':
        # Load workspace layout.
        layout.restore(workspace_name, workspace_layout)

    if target != 'layout_only':
        # Restore programs.
        saved_programs = programs.read(workspace, directory, profile)
        programs.restore(workspace_name, saved_programs)
Example #23
0
def main():
    i3 = i3ipc.Connection()
    p = 0
    moddown = False

    for event in dev.read_loop():
        if event.type == ecodes.EV_KEY:
            # left alt
            if event.code == 56:
                if event.value == 1:
                    workspaces = i3.get_workspaces()
                    p = startoverlay(workspaces)
                    moddown = True
                elif event.value == 0 and p != 0:
                    p.kill()
                    p = 0
                    moddown = False
            # other than left alt (-> restart subprocess)
            else:
                if event.value == 1:
                    if moddown:
                        p.kill()
                        # restart only if changing workspaces
                        time.sleep(0.1)
                        workspaces = i3.get_workspaces()
                        p = startoverlay(workspaces)
Example #24
0
def main():
    args = build_parser().parse_args()
    i3 = i3ipc.Connection()

    event_filter = true_filter

    if args.run is not None:
        event_filter = combine_filters(event_filter,
                                       change_filter('run', not args.run))

    if args.focus is not None:
        event_filter = combine_filters(event_filter,
                                       change_filter('focus', not args.focus))

    if args.quiet:
        formatter = quiet_formatter
    else:
        formatter = json.dumps

    handler = Handler(formatter, event_filter)

    WORKSPACE = "workspace"

    types = set(("ipc_shutdown", WORKSPACE, "output", "mode", "window",
                 "barconfig_update", "binding"))

    if args.workspace == True:
        types = set((WORKSPACE, ))
    elif args.workspace == False:
        types.remove(WORKSPACE)

    for name in types:
        i3.on(name, handler.handle)

    i3.main()
Example #25
0
def main():
    parser = argparse.ArgumentParser(__doc__)
    parser.add_argument("-config-path",
                        help="Path to file that maps applications to icons in json format. Defaults to ~/.i3/app-icons.json or ~/.config/i3/app-icons.json or hard-coded list if they are not available.",
                        required=False)
    parser.add_argument("-d", "--delimiter", help="The delimiter used to separate multiple window names in the same workspace.",
                        required=False,
                        default="|")
    parser.add_argument("-u", "--uniq", help="Remove duplicate icons in case the same application ",
                        action="store_true",
                        required=False,
                        default=False)
    args = parser.parse_args()

    app_icons = _get_app_icons(args.config_path)

    # check for missing icons
    for app, icon_name in app_icons.items():
        if not icon_name in icons:
            print("Specified icon '{}' for app '{}' does not exist!".format(icon_name, app))
    # build i3-connection
    i3 = i3ipc.Connection()

    rename = build_rename(i3, app_icons, args.delimiter, args.uniq)
    for case in ['window::move', 'window::new', 'window::title', 'window::close']:
        i3.on(case, rename)
    i3.main()
Example #26
0
    def __init__(
        self,
        command,
        wm_class=None,
        wm_instance=None,
        wm_title=None,
        workspace=None,
        target_workspace=None,
        scratch=False,
        con_mark=None,
        ignore_case=False,
        event_time_limit=2,
        cycle=False,
        leave_fullscreen=False,
    ):
        self.command = command
        self.wm_class = wm_class
        self.wm_instance = wm_instance
        self.wm_title = wm_title
        self.workspace = workspace
        self.target_workspace = target_workspace or workspace
        self.scratch = scratch
        self.con_mark = con_mark
        self.ignore_case = ignore_case
        self.event_time_limit = event_time_limit
        self.cycle = cycle
        self.leave_fullscreen = leave_fullscreen

        self.regex_flags = [re.IGNORECASE] if self.ignore_case else []

        self._check_args()

        self.i3 = i3ipc.Connection()
        self.tree = self.i3.get_tree()
        self.current_ws = self.get_current_workspace()
Example #27
0
def move_container_to(id):
    print("move focused containter to workspace {}".format(id))
    i3 = i3ipc.Connection()
    i3.command("move container to workspace {}".format(id))
    if conf.getboolean('main', 'follow-container-on-move'):
        state['last_ws_id'] = state['current_ws_id']
        display_workspace(id)
Example #28
0
 def generated_daemon():
     workspace_policy = create_workspace_policy(disabled_during_pomodoro)
     i3 = i3ipc.Connection()
     i3_state = {"focused_workspace_name": get_focused_workspace(i3).name}
     i3.on('workspace::focus',
           handle_workspace_focus(i3, i3_state, workspace_policy, nagbar))
     i3.main()
Example #29
0
def i3_tracker_backend():
    i3 = i3ipc.Connection()

    i3.on('workspace::focus', on_workspace_focus)
    i3.on("window::focus", on_window_focus)
    i3.on("window::title", on_window_title)

    i3.main()
Example #30
0
def main(args):
    i3 = i3ipc.Connection()
    focused = i3.get_tree().find_focused()
    if focused.sticky and focused.floating.endswith('on'):
        focused.command('border normal, floating disable')
    else:
        focused.command('floating enable, sticky enable, border none')
    return 0