Beispiel #1
0
def main():
    args = parse_args()

    inc = -1 if args.reverse else 1

    i3 = Connection()

    if args.current:

        focused = i3.get_tree().find_focused()

        containers = focused.workspace().descendants()

        for c in containers[:]:
            if c.name is None:
                containers.remove(c)

            index = (containers.index(focused) + inc) % len(containers)

        containers[index].command('focus')

    else:
        all_containers = i3.get_tree().leaves()

        is_focused = [c.focused for c in all_containers]

        index = (is_focused.index(True) + inc) % len(all_containers)

        all_containers[index].command('focus')
Beispiel #2
0
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}")
Beispiel #3
0
    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()
Beispiel #4
0
def main():
    parse_options()
    cnx = Connection()
    focused = cnx.get_tree().find_focused()
    wsp = focused.workspace()
    if not wsp or wsp.name == "__i3_scratch":
        return
    switch_col(wsp, focused)
Beispiel #5
0
    def run(self):
        # Establish socket connection
        conn = Connection()

        # Get window tree and name of focused window
        tree = conn.get_tree()
        win_name = tree.find_focused().name

        self.output = {"full_text": win_name, "color": self.color, "urgent": False}
def main():
    name = "1:1:AT_Translated_Set_2_keyboard"
    sway = Connection()
    focused = sway.get_tree().find_focused()
    if (focused.window_class == 'Emacs'):
        system(
            'emacsclient -e "(with-current-buffer (window-buffer) (toggle-input-method))"'
        )
    else:
        sway.command(f"input {name} xkb_switch_layout next")
Beispiel #7
0
def undo_window_renaming(ipc: i3ipc.Connection) -> None:
    """reset workspace names to original name"""

    for workspace in ipc.get_tree().workspaces():
        name_parts = parse_workspace_name(workspace.name)
        name_parts["icons"] = None
        new_name = construct_workspace_name(name_parts)
        ipc.command('rename workspace "%s" to "%s"' %
                    (workspace.name, new_name))
    ipc.main_quit()
    sys.exit(0)
class i3focus:
    def __init__(self):
        self.i3 = Connection() # Create the Connection object that can be used to send commands and subscribe
        self.updateWinState()

    def updateWinState(self):
        self.winstate = self.i3.get_tree().find_focused().workspace().find_focused().workspace().name

    # Define a funtion to switch workspaces when eye position changes
    def on_eye_change(self, ws):
        if ws == 0:
            self.i3.command('focus output left')
        else:
            self.i3.command('focus output right')
        self.updateWinState()
Beispiel #9
0
def get_current_workspace(
        conn: i3ipc.Connection) -> Tuple[i3ipc.WorkspaceReply, object]:
    """ Get the focused workspace.

        Returns
        -------
        A tuple in form (workspace, con), with the focused workspace and
        the container object for the focused workspace, respectively.
    """
    ws = [w for w in conn.get_workspaces() if w['focused']][0]
    tree = conn.get_tree()
    ws_tree = [c for c in tree.descendents()
               if c.type == 'workspace' and c.name == ws['name']][0]

    return ws, ws_tree
Beispiel #10
0
def rename_workspaces(ipc: i3ipc.Connection, duplicates: bool) -> None:
    """scans for windows in all workspaces as renames the workspaces"""

    for workspace in ipc.get_tree().workspaces():
        name_parts = parse_workspace_name(workspace.name)
        icon_tuple = ()
        for wksp in workspace:
            if wksp.app_id is not None or wksp.window_class is not None:
                icon = icon_for_window(wksp)
                if not duplicates and icon in icon_tuple:
                    continue
                icon_tuple += (icon, )
        name_parts["icons"] = "  ".join(icon_tuple)
        new_name = construct_workspace_name(name_parts)
        ipc.command('rename workspace "%s" to "%s"' %
                    (workspace.name, new_name))
Beispiel #11
0
def on_window_focus(ipc: i3ipc.Connection, e):
    c: i3ipc.con.Con
    for c in ipc.get_tree():
        # only consider windows
        if c.type != 'con':
            continue
        opaque = c.focused
        opaque |= 'YouTube' in (c.name or '')
        opaque |= 'Netflix' in (c.name or '')
        opaque |= 'Zoom' in (c.name or '')
        opaque |= 'Jitsi' in (c.name or '')
        opaque |= 'vlc' == c.window_class
        if opaque:
            c.command('opacity 1')
        else:
            c.command('opacity 0.9')
Beispiel #12
0
def render_apps(i3: i3ipc.Connection, ws: Optional[int]):
    tree = i3.get_tree()
    wss = i3.get_workspaces()
    visible_ws = [ws.name for ws in wss if ws.visible]

    apps = tree.leaves()
    apps = [app for app in apps if app.workspace().name in visible_ws]
    if ws is not None:
        apps = [
            app for app in apps if (int(app.workspace().name) - 1) % 3 == ws
        ]
    apps.sort(key=lambda app: app.workspace().name)

    out = '%{O12}'.join(format_entry(app) for app in apps)

    print(out, flush=True)
Beispiel #13
0
    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()
Beispiel #14
0
def get_track_name_from_i3():
    """
    get title of Spotify window in i3WM
    """
    i3 = Connection()
    trees = i3.get_tree()  # retrieves all open windows in i3
    playing_track_name = None
    for tree in trees:
        if tree.name == '3:Music':  # static value in my own computer
            """ 
            Above condition is static because I open my Spotify
            in workspace 3 which has a label `:Music`
            """
            playing_track_name = tree.nodes[0].window_title

    playing_track_name = playing_track_name.split('-')
    if len(playing_track_name) > 1:
        playing_track_name = playing_track_name[1].strip()
        return playing_track_name
    else:
        return playing_track_name[0].strip()
Beispiel #15
0
def focus(i3: i3ipc.Connection, dir: Direction):
    tree = i3.get_tree()
    active_window = tree.find_focused()

    x, y = active_window.rect.x, active_window.rect.y
    width, height = active_window.rect.width, active_window.rect.height
    if dir == Direction.LEFT:
        x = x - 1
    elif dir == Direction.RIGHT:
        x = x + width + 1
    elif dir == Direction.UP:
        y = y - 1
    elif dir == Direction.DOWN:
        y = y + height + 1
    else:
        raise ValueError('{} is not a valid direction', dir)

    correct_window = find_eligible_node_at(x, y, tree)

    if correct_window is not None:
        correct_window.command('focus')
Beispiel #16
0
    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()
Beispiel #17
0
def swap_workspaces():
    """Swap two workspaces"""
    direction = sys.argv[1] if len(sys.argv) > 1 else False
    if not direction in ['left', 'right']:
        return False

    _i3 = Connection()

    # Get workspace objects
    focused = _i3.get_tree().find_focused().workspace()
    outputs = [output for output in _i3.get_outputs() if output.active]
    workspaces = [o.current_workspace for o in outputs][::-1]

    focused_idx = workspaces.index(focused.name)
    direction_num = {'left': -1, 'right': 1}[direction]
    direction_opp = {'left': 'right', 'right': 'left'}[direction]
    swap_idx = (focused_idx + direction_num) % len(workspaces)

    _i3.command('workspace ' + workspaces[focused_idx])
    _i3.command('move ' + 'workspace to output ' + direction)
    _i3.command('workspace ' + workspaces[swap_idx])
    _i3.command('move ' + 'workspace to output ' + direction_opp)
    return True
from i3ipc import Connection

i3 = Connection()

workspace_no = i3.get_tree().find_focused().workspace().num
new_workspace_no = 1 if (workspace_no + 1) > 10 else (workspace_no + 1)

command = f'move container to workspace number {new_workspace_no}'
print(command)
i3.command(command)

command = f'workspace number "{new_workspace_no}"'
print(command)
i3.command(command)
Beispiel #19
0
		return data



	if opts['only_child'] and len(con.nodes) == 1:
		return parse_tree(con.nodes[0])


	# implicit container
	if len(con.nodes) >= 1:

		children = [parse_tree(i) for i in con.nodes]
		data = str()

		if con.focused:
			data += foc_pre
		data += layouts[con.layout]
		if con.focused:
			data += foc_pst

		data += '['
		data += ' '.join(children)
		data += ']'
		return data



workspace = i3.get_tree().find_focused().workspace()
data = parse_tree(workspace)
print(data, flush = True)
Beispiel #20
0
#!/usr/bin/env python
from i3ipc import Connection

conn = Connection()
terms = conn.get_tree().find_instanced('gnome-terminal-server')
for term in terms:
    if term.parent.scratchpad_state != 'none':
        conn.command('scratchpad show')
        exit(0)

conn.command('exec --no-startup-id "gnome-terminal --window --title terminal-dropdown"')
Beispiel #21
0
#!/usr/bin/env python3

from i3ipc import Connection

i3 = Connection()

scratch = i3.get_tree().scratchpad().leaves()

# If there is something in the scratchpad
# Lists are true if not empty
if scratch:
    #switch to workspace 42 and making the windows stack
    i3.command("workspace 42")
    i3.command("layout stacking")

    #remove each window from scratchpad and defloat it
    for window in scratch:
        window.command("scratchpad show")
        window.command("floating toggle")
else:
    #make list of used workspaces
    workspaces = i3.get_workspaces()
    wsinuse = []

    for i in workspaces:
        wsinuse.append(i.num)

    #if workspace 42 is already in use, switch to it
    if 42 in wsinuse:
        i3.command("workspace 42")
Beispiel #22
0
#!/usr/bin/env python

from i3ipc import Connection
import re

conn = Connection()
htops = conn.get_tree().find_titled("htop-floating")

killed = False
for e in htops:
    print(e.window_title, e.floating)

    if re.findall("on", e.floating) and re.findall("htop-floating",
                                                   e.window_title):
        e.command('kill')
        killed = True

if not killed:
    conn.command(
        'exec "gnome-terminal --window --title htop-floating -- htop"')
from i3ipc import Connection, Con

if __name__ == "__main__":

    i3 = Connection()

    def _is_scratchpad(con: Con) -> bool:
        return con.window and con.parent.type != 'dockarea' and con.workspace(
        ).name == '__i3_scratch'

    for con in i3.get_tree():

        if _is_scratchpad(con):
            con.command("fullscreen")
            break

    i3.command("scratchpad show")
Beispiel #24
0
#!/usr/bin/env python

from i3ipc import Connection
import re

conn = Connection()
es = conn.get_tree().find_classed("Evolution")

killed = False
for e in es:
    if re.findall("on", e.floating) and re.findall("(K|C)alend(e|a)r – Evolution", e.window_title):
        e.command('kill')
        killed = True

if not killed:
    conn.command('exec "evolution -c calendar"')
Beispiel #25
0

def wifi_rfkill():
    """
    get wifi state from rfkill
    """
    output = subprocess.check_output(['rfkill', 'list', 'wifi'])
    r = re.findall("blocked: yes", output.decode('utf-8'))
    if len(r) == 0:
        # wifi not blocked
        return True
    else:
        return False


conn = Connection()
nets = conn.get_tree().find_instanced("gnome-control-center")

killed = False
for e in nets:
    if re.findall("on", e.floating):
        e.command('kill')
        killed = True
if not killed:
    if wifi_nm():
        # show wifi settings
        conn.command('exec "gnome-control-center wifi')
    else:
        # show network settings
        conn.command('exec "gnome-control-center network')
Beispiel #26
0
#
# This effect is similar to dwm's window swallowing patch: https://www.youtube.com/watch?v=92uo5OBOKfY
#
# To be super minimal, configure i3 to use a 0px font size to hide the tab title bars. With the
# unfortunate caveat that this will cause i3 error messages to become unreadable.

from i3ipc import Connection
import subprocess
import sys

if len(sys.argv) < 2:
    print("Usage: %s <command...>" % sys.argv[0])
    sys.exit(1)

i3 = Connection()
orig = i3.get_tree().find_focused()

# If the layout was already tabbed or stacked, don't do anything
layout = orig.parent.layout
if layout == "splith":
    orig.command("split v")
    orig.command("layout tabbed")
elif layout == "splitv":
    orig.command("split h")
    orig.command("layout tabbed")

try:
    # Run the given command
    code = subprocess.run(sys.argv[1:]).returncode

finally:
#!/usr/bin/env python3

from i3ipc import Connection
import sys

REVERSE = {'right': 'left', 'left': 'right', 'down': 'up', 'up': 'down'}

if __name__ == "__main__":
    direction = sys.argv[1]
    i3 = Connection()
    last_focused = i3.get_tree().find_focused()
    if not last_focused.fullscreen_mode:
        last_focused.command('focus ' + direction)
        sys.exit()

    last_focused.command('fullscreen')
    last_focused.command('focus ' + direction)
    cur_focused = i3.get_tree().find_focused()
    if last_focused.workspace().id == cur_focused.workspace().id:
        cur_focused.command('fullscreen')
    else:
        last_focused.command('focus; fullscreen')
    sys.exit()
Beispiel #28
0
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
Beispiel #29
0
#!/usr/bin/env python3
from i3ipc import Connection
import sys

i3 = Connection()
tree = i3.get_tree()
focused = tree.find_focused()
workspace = focused.workspace()
if focused.name == workspace.name:
    sys.exit(0)
else:
    sys.exit(1)

Beispiel #30
0
#!/usr/bin/env python3
from i3ipc import Connection

# Lil util to flatten 2d list
flatten = lambda t: [item for sublist in t for item in sublist]

i3 = Connection()

visible_workspaces = list(filter(lambda ws: ws.visible, i3.get_workspaces()))
focused_workspace = list(filter(lambda ws: ws.focused, visible_workspaces))[0]
named_workspace = i3.get_tree().find_named(focused_workspace.name)
workspace_index = list(map(lambda ws: ws.name,
                           named_workspace)).index(focused_workspace.name)

floating_windows = list(
    filter(lambda window: window.floating == 'user_on',
           named_workspace[workspace_index].leaves()))
floating_index = list(map(lambda win: win.focused,
                          floating_windows)).index(True)

next_win = floating_windows[(floating_index + 1) % len(floating_windows)]
next_win.command('focus')
Beispiel #31
0
#!/usr/bin/env python3
#
# Promotes the focused window by swapping it with the largest window.

from i3ipc import Connection, Event


def find_biggest_window(container):
    max_leaf = None
    max_area = 0
    for leaf in container.leaves():
        rect = leaf.rect
        area = rect.width * rect.height
        if not leaf.focused and area > max_area:
            max_area = area
            max_leaf = leaf
    return max_leaf


i3 = Connection()

for reply in i3.get_workspaces():
    if reply.focused:
        workspace = i3.get_tree().find_by_id(reply.ipc_data["id"])
        master = find_biggest_window(workspace)
        i3.command("swap container with con_id %s" % master.id)
Beispiel #32
0
def get_focused_window_name():
    connection = Connection()
    root = connection.get_tree()
    focus_con = root.find_focused()

    return focus_con.name, focus_con, root, connection