def rotate_workspaces_to_right_and_keep_ws_names(): # Get all visible workspace(s) - the workspace(s) currently visible on output(s) workspaces = i3.filter(i3.get_workspaces(), visible=True) # Get list containing num of the visible workspaces ws_names = [ ws['num'] for ws in workspaces ] # Get focused workspace id/name ws_focused = i3.filter(workspaces, focused=True)[0]['num'] # Get index of focused node in ws_names idx = ws_names.index(ws_focused) # Create a range that starts from the index of the focused node so the # focused output is the last to be rotated to the right. This results in # the focus to stay on the same output ws_range = [ index%len(ws_names) for index in range(idx-1,idx+len(ws_names)-1) ] # For each visible workspace for i in ws_range: # Set focus to workspace by id/name i3.workspace( str(ws_names[i]) ) # Move focused workspace to output on the right i3.command('move workspace to output right')
def i3rnwps(): rnwps = {} wps = i3.get_workspaces() for wp in wps: workspace = i3.filter(num=wp['num']) if not workspace: continue workspace = workspace[0] windows = i3.filter(workspace, nodes=[]) instances = {} # Adds windows and their ids to the rnwps dictionary if len(windows) == 1: win =windows[0] if win.has_key('window_properties'): rnwps[workspace['name']] = "%i: %s" % (workspace['num'], win['window_properties']['class']) elif len(windows) == 0: rnwps[workspace['name']] = "%i: Empty" % (workspace['num']) else: names={} for win in windows: if win.has_key('window_properties'): if not names.has_key(win['window_properties']['class']): names[win['window_properties']['class']]=1 else: names[win['window_properties']['class']]=names[win['window_properties']['class']]+1 str="%i: " %(workspace['num']) for name in names.keys(): str+="%ix%s " %(names[name], name) rnwps[workspace['name']] = str return rnwps
def i3clients(): """Populate a dictionary with window strings for rofi. Structure of the dictionary: key: Formatted string containing workspace name and window name. value: ID of the window to be able to focus it. Return: The generated dictionary. """ clients = {} tree = i3.get_tree() # Iterate over all workspaces for ws in i3.get_workspaces(): wsname = ws["name"] wsshow = re.sub(r'[0-9]+(:)', "", wsname) workspace = i3.filter(tree, name=wsname)[0] # We do not want to go to the focused window windows = [win for win in i3.filter(workspace, nodes=[]) if not win["focused"]] # Build the formatted string to pass to rofi and add it to the # dictionary for window in windows: wsname = re.sub("<.*?>", "", wsshow) win_str = "%-6s %-50s" % (wsname, window["name"]) clients[win_str] = window["id"] return clients
def get_workspace(number): """gets a workspace by number, as opposed to name""" config = get_config() if str(number) in config: space = config[str(number)] else: space = None existing = [wks for wks in i3.get_workspaces() if wks['num'] is int(number)] if len(existing): return existing[0]['name'] else: if space is None: default_rfile = HOME + '/.config/i3/lib/planets' if "random" in config: rfile = os.path.expanduser(config['random']['file']) else: rfile = default_rfile try: words = open(rfile) except: words = open(default_rfile) total_chars = words.seek(0, 2) position = random.randint(0, total_chars) words.seek(position) rname = words.readline() rname = words.readline().replace("\n", "") space = {"name": rname} wksname = str(number) + ": " + space['name'] return wksname
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) ]
def new_ws(cmd, args): """Create a new workspace by using the first free number > 0.""" nums = (w["num"] for w in i3.get_workspaces()) nums = filter(lambda n: n is not None and n >= 0, nums) try: exe = args[args.index("--exec")+1] except (IndexError, ValueError): exe = None i = -1 # fallback if `nums` happens to be empty for i,n in enumerate(sorted(nums)): if i != n: cmd(str(i)) break else: cmd(str(i+1)) if exe: # We use i3.exec_ here instead of sh.Command, as we do not want the # exe to be a child of this script's process # Also we get startup notification support for free :-) if sh.which(exe): # i3 exec always yields 'success' i3.exec_(exe) else: nag("Command '%s' not found!" % exe)
def change_workspace(num): """ Switches to workspace num like xmonad. Always sets focused output to workspace num. If the workspace is on another output, then the workspaces are "shifted" among the outputs. """ num = int(num) LOG.debug('Switching to workspace %d', num) focused_workspace = get_focused_workspace() LOG.debug('Focused workspace:\n' + pformat(focused_workspace)) # Check if already on workspace if int(focused_workspace['num']) == num: LOG.debug('Already on correct workspace') return # Get workspace we want to switch to want_workspace = get_workspace(num) if want_workspace is None: LOG.debug('Switching to workspace because it does not exist') switch_workspace(num) return LOG.debug('Want workspace:\n' + pformat(want_workspace)) # Save workspace originally showing on want_workspace's output other_output = [outp for outp in get_active_outputs() if outp['name'] == want_workspace['output']][0] LOG.debug('Other_output=%s', other_output) other_workspace = [wk for wk in i3.get_workspaces() if wk['name'] == other_output['current_workspace']][0] LOG.debug('Other workspace:\n' + pformat(other_workspace)) # Check if wanted workspace is on focused output if focused_workspace['output'] == want_workspace['output']: LOG.debug('Wanted workspace already on focused output, ' 'switching as normal') switch_workspace(num) return # Check if wanted workspace is on other output if not want_workspace['visible']: LOG.debug('Workspace to switch to is on other output, not showing') # Switch to workspace on other output switch_workspace(num) LOG.debug('Wanted workspace is on other output') # Wanted workspace is visible, so swap workspaces swap_visible_workspaces(want_workspace, focused_workspace) # Focus other_workspace switch_workspace(other_workspace['num']) # Focus on wanted workspace switch_workspace(want_workspace['num'])
def focus_next_on_any_output(): # Get all visible workspace(s) - the workspace(s) currently visible on output(s) workspaces = i3.filter(i3.get_workspaces(), visible=True) # Get list containing num of the visible workspaces workspaces_num = [ ws['num'] for ws in workspaces ] # Get visible nodes nodes = [ i3.filter(num=ws_num)[0]['nodes'] for ws_num in workspaces_num ] # Get focused node curr = i3.filter(nodes, focused=True)[0] # Get ids of all nodes ids = [win['id'] for win in i3.filter(nodes, nodes=[])] # Get index of next node next_idx = (ids.index(curr['id']) + 1) % len(ids) # Set id of next node next_id = ids[next_idx] # Focus next node i3.focus(con_id=next_id)
def workspaces(): lhalf = u'\u258c' # left half block rhalf = u'\u2590' # right half block bar = fg(ws_inactive) + rhalf work = i3.get_workspaces() for ws in work: f = ws_active_txt #foreground s = "|" if ws["output"] == "LVDS": if ws["urgent"]: b = ws_urgent s = fg(ws_urgent) + lhalf + fg() bar = bar[:-1] + fg(ws_urgent) + rhalf + fg() elif ws["focused"]: b = ws_active s = fg(ws_active) + lhalf + fg() bar = bar[:-1] + fg(ws_active) + rhalf + fg() else: f = ws_inactive_txt b = ws_inactive bar += bg(b) + fg(f) \ + link(ws["name"], "i3-msg -q workspace "+ws["name"]) \ + bg(ws_inactive) + fg(ws_sep_col) + s #replace last separator with halfblock if ws["focused"]: bar = bar[:-13] + bg() + fg(ws_active) + lhalf else: bar = bar[:-1] + fg(ws_inactive) + bg() + lhalf return bar + bg() + fg()
def find_active_workspace(): workspaces = i3.get_workspaces() for workspace in workspaces: if workspace['focused'] == True: return workspace else: return False
def create_next_workspace_on_output(): # Get all workspace(s) workspaces = i3.get_workspaces() # Current workspace current = [ws for ws in workspaces if ws['focused']][0] output = current['output'] # Get list containing num of the workspaces on current output ws_names = [ ws['num'] for ws in workspaces if ws['output'] == output ] # Set start and end 'num' for workspaces depending on setup of one or two # monitors if ( len(ws_names) == len(workspaces) ): # One monitor start = 1 end = 10 else: # Two monitors start = 1 if current['num'] < 6 else 6 end = start+5 # Create workspace on output with lowest available 'num' for k in range(start,end): if not k in ws_names: i3.command('workspace {}'.format(k)) break;
def first_free(): workspaces = i3.get_workspaces() workints = list() for w in workspaces: workints.append(w['num']) for i in range(1,11): if i not in workints: return i
def migrate(src, dst, exclude=[]): workspaces = i3.get_workspaces() for w in workspaces: if w['name'] in exclude: continue if w['output'] != dst['name']: i3.workspace(w['name']) i3.command('move', 'workspace to output right')
def rename(args): cur_ws = i3.filter(i3.get_workspaces(), focused = True)[0] input = sh.i3_input.bake(P = "Rename workspace: ") if "--keep-num" in args and cur_ws["num"]: input(F = ('rename workspace to "%d: %%s"' % cur_ws["num"])) else: input(F = 'rename workspace to "%s"')
def _get_focused_workspace(): """ Gets the currently focused i3 workspace. Returns: dict: i3 workspace object """ return filter(lambda w: w['focused'], i3.get_workspaces())[0]
def main(): workspaces = i3.get_workspaces() workints = list() for w in workspaces: workints.append(w['num']) for i in range(1, 11): if i not in workints: i3.workspace(str(i)) break
def cmd_move_group_output(output): ws = i3.get_workspaces() group, current_wnum = get_wgroup(ws) wids = wids_by_furthest(ws, group, current_wnum) print 'move_group_output', output, '->', wids i3_move_args = ['workspace', 'to', output] for wid in wids: i3.workspace(str(wid)) i3.move(*i3_move_args)
def workspaces(pl): '''Return workspace list Highlight groups used: ``workspace``, ``w_visible``, ``w_focused``, ``w_urgent`` ''' return [{ 'contents': w['name'], 'highlight_groups': calcgrp(w) } for w in i3.get_workspaces()]
def is_w_focused(o): wss = i3.get_workspaces() name = o[u'current_workspace'] current = None for w in wss: if w[u'name'] == o['current_workspace']: current = w break return current[u'focused']
def get_workspace(num): """Returns workspace with num or None of it does not exist""" want_workspace_cands = [wk for wk in i3.get_workspaces() if wk['num'] == num] assert len(want_workspace_cands) in [0, 1] if len(want_workspace_cands) == 0: return None else: return want_workspace_cands[0]
def workspaces(): ws = i3.get_workspaces() # get all active workspaces # WORKSPACES wsp = "" # workspace for w in ws: # for each workspace if w['focused'] == True: #check if it's focused and if so make it follow red color wsp += active(clickable(" "+w['name']+" ","i3-msg workspace" + w['name'])) else: wsp += clickable(" "+w['name']+" ","i3-msg workspace" + w['name']) return wsp
def i3clients(): """ Returns a dictionary with convoluted strings with window information as keys, and the i3 window id as values. Each window text is of format "[workspace] mark window title (instance number)." """ clients = {} lengths = {'workspace': 0, 'mark': 0} tree = i3.get_tree() for ws in i3.get_workspaces(): wsname = ws['name'] if len(wsname) > lengths['workspace']: lengths['workspace'] = len(wsname) workspace = i3.filter(tree, name=wsname) if not workspace: continue workspace = workspace[0] windows = i3.filter(workspace, nodes=[]) instances = {} # Adds windows and their ids to the clients dictionary for window in windows: windowdict = { 'con_id': window['id'], \ 'ws': wsname, \ 'name': window['name']} try: windowdict['mark'] = window['mark'] if len(window['mark']) > lengths['mark']: lengths['mark'] = len(window['mark']) except KeyError: windowdict['mark'] = "" if window['name'] in instances: instances[window['name']] += 1 else: instances[window['name']] = 1 windowdict['instance'] = instances[window['name']] # win_str = '[%s] %s' % (workspace['name'], window['name']) clients[window['id']] = windowdict # Now build the strings to pass to dmenu: newdict = {} clientlist = [] for con_id in clients.keys(): clientlist.append(con_id) for con_id in clientlist: wslen = lengths['workspace'] mlen = lengths['mark'] win_str = '[{k:<{v}}] {l:<{w}} {m} ({n})'.format(\ k=clients[con_id]['ws'], v=wslen, \ l=clients[con_id]['mark'], w=mlen, \ m=clients[con_id]['name'], \ n=clients[con_id]['instance']) clients[win_str] = clients[con_id] del clients[con_id] return clients
def print_workspaces(): workspaces = i3.get_workspaces() outputlist=[] for i in workspaces: if i['focused']==True: output = "<span>"+i['name']+"</span>" else: output = "<span foreground='#96b5b4'>"+i['name']+"</span>" outputlist.append(output) print(" ".join(outputlist))
def to_ws(cmd, prompt, args): """Use `dmenu` to switch or move to a workspace.""" ws = sorted(w["name"] for w in i3.get_workspaces()) try: sel = sh.dmenu(b = True, p = prompt, _in = "\n".join(ws)).strip() except sh.ErrorReturnCode: sel = None if sel: cmd(sel)
def focus_next(): num = i3.filter(i3.get_workspaces(), focused=True)[0]['num'] ws_nodes = i3.filter(num=num)[0]['nodes'] curr = i3.filter(ws_nodes, focused=True)[0] ids = [win['id'] for win in i3.filter(ws_nodes, nodes=[])] next_idx = (ids.index(curr['id']) + 1) % len(ids) next_id = ids[next_idx] i3.focus(con_id=next_id)
def get_workspaces(): '''Returns all workspace names. NOTE: This returns a map of name → name, which is rather redundant, but makes it possible to use the result without changing much in main(). ''' workspaces = i3.get_workspaces() for ws in workspaces: # create_lookup_table will set the value of all entries in the lookup table # to the window id. We act as if the workspace name is the window id. ws['window'] = ws['name'] return create_lookup_table(workspaces)
def undock(): workspaces = i3.get_workspaces() # check path if not os.path.exists(os.path.dirname(PATH)): os.mkdir(os.path.dirname(PATH)) # pickle workspaces with open(PATH, 'wb') as savefile: pickle.dump(workspaces, savefile) #move all workspaces to laptop for workspace in workspaces: i3.command('[workspace={}] move workspace to output {}'.format( workspace['name'], LAPTOP))
def main(): outputs = i3.get_outputs() workspaces = i3.get_workspaces() active_workspaces = [o['current_workspace'] for o in outputs if o['active'] is True] if len(active_workspaces) != 2: return focused_workspace = [w['num'] for w in workspaces if w['focused'] is True] active_workspaces.remove(str(focused_workspace[0])) i3.command('workspace', active_workspaces[0])
def run(num): # current workspace current = [ws for ws in i3.get_workspaces() if ws["focused"]][0] # switch to workspace named 'fibonacci' i3.workspace("fibonacci") i3.layout("default") fibonacci(num) time.sleep(3) # close all opened terminals for n in range(num): i3.kill() time.sleep(0.5) i3.workspace(current["name"])
def run(num): # current workspace current = [ws for ws in i3.get_workspaces() if ws['focused']][0] # switch to workspace named 'fibonacci' i3.workspace('fibonacci') i3.layout('default') fibonacci(num) time.sleep(3) # close all opened terminals for n in range(num): i3.kill() time.sleep(0.5) i3.workspace(current['name'])
def copied_alt_tab(): num = i3.filter(i3.get_workspaces(), focused=True)[0]['num'] all_nodes = flatten_lists(list(map(get_nodes, i3.filter()))) curr = i3.filter(all_nodes, focused=True)[0] print(get_id(curr)) ids = list(map(get_id, all_nodes)) + [get_id(curr)] print(ids) next_id = ids[(ids.index(curr['id']) + 2) % len(ids)] print(next_id) i3.focus(con_id=next_id)
def positionWindow(): i3.scratchpad("show", instance="metask") workspace = [ws for ws in i3.get_workspaces() if ws['focused']][0] screen_w =str(workspace['rect']['width']) screen_h =str(workspace['rect']['height']) targetheight = str(workspace['rect']['height']/3) current = i3.filter(nodes=[], focused=True) i3.command("move","absolute","position","0",str(barHeight)) i3.command("resize","shrink","width",screen_w); i3.command("resize","shrink","height",screen_h); i3.command("resize","grow","width",screen_w); i3.command("resize","grow","height",targetheight);
def get_workspaces(unused=None): """ Returns all workspace names. NOTE: This returns a map of name → name, which is rather redundant, but makes it possible to use the result without changing much in main(). NOTE: The argument is not used but needed for compatibilty with get_windows """ workspaces = i3.get_workspaces() for ws in workspaces: # create_lookup_table will set the value of all entries # in the lookup table to the window id. We act as if the # workspace name is the window id. ws["window"] = ws["name"] return create_lookup_table(workspaces)
def dest_wid(w): wmove, wnum_dest = parse_wmove(w) ws = i3.get_workspaces() group, wnum = get_wgroup(ws) if wmove == WDest.num: wid = wroundid(group, wnum_dest) elif wmove == WDest.up: LRU_WNUM_PER_GROUPS[group] = wnum group, wid = wclosest(ws, group + 1, wnum) elif wmove == WDest.down: LRU_WNUM_PER_GROUPS[group] = wnum group, wid = wclosest(ws, group - 1, wnum) else: raise NotImplementedError() LRU_WNUM_PER_GROUPS[group] = wid % 10 return wid
def styled_workspaces(): workspaces = i3.get_workspaces() all_ws = sorted([x['num'] for x in workspaces]) active_ws = [x['num'] for x in workspaces if x['focused'] is True][0] styled = str() for ws in all_ws: if ws == active_ws: styled += u'\u25cf' else: styled += u'\u25cb' if ws != all_ws[-1]: styled += ' ' return styled
def _calc_metadata(self) -> (DisplayMap, dict): self.displays = i3.get_outputs() # Widths * Lengths (seperated to retain composition for children) total_size = {} monitor_cnt = 0 for display in self.displays: if display["name"].startswith("xroot"): continue display_screen_location = Location( width=display["rect"]["width"], height=display["rect"]["height"]) total_size[monitor_cnt] = display_screen_location monitor_cnt += 1 self.all_outputs = i3.get_workspaces() active = [i for i in self.all_outputs if i["focused"]][0] self.active_output = active["output"] return total_size, active
def main(projectName): print(projectName) if (projectName is None) or (len(projectName) == 0): sys.exit(0) new_workspaces = [] for output in i3.filter(tree=i3.get_outputs(), active=True): current_workspace_name = output['current_workspace'] print(current_workspace_name) current_workspace = i3.filter(tree=i3.get_workspaces(), name=current_workspace_name) if not current_workspace[0]['focused']: print("Current workspace, {}, not focussed".format( current_workspace_name)) i3.workspace(current_workspace_name) i3.workspace(projectName + '-' + output['name']) subprocess.call(['startWorkOn', projectName])
def next_free_workspace_index(): """ Returns the integer index of the next free workspace index. """ # Get all of the workspces workspaces = i3.get_workspaces() ws_indices = sorted([ws['num'] for ws in workspaces]) # Workspaces are 1 indexed, use 0 so we can catch if workspace 1 is not used prev_ws = 0 # First check for gaps for ws in ws_indices: next_ws = prev_ws + 1 if ws != next_ws: return next_ws else: prev_ws += 1 # We didn't find any gaps return prev_ws + 1
def main(): outputs = i3.get_outputs() workspaces = i3.get_workspaces() # Only include outputs with active: True workspaces = [ o['current_workspace'] for o in outputs if o['active'] is True ] if len(workspaces) == 2: i3.command('workspace', workspaces[0]) i3.command('move', 'workspace to output down') # Hacky fix for race condition time.sleep(0.01) i3.command('workspace', workspaces[1]) i3.command('move', 'workspace to output up') elif len(outputs) < 2: print('Not enough outputs') else: print('Too many outputs')
def set_theme(self): self.background = self.theme['background'] self.foreground = self.theme['foreground'] for i in i3.get_workspaces(): if i['focused'] == True: workspace = i screen_width = workspace['rect']['width'] screen_height = workspace['rect']['height'] if screen_height > screen_width: self.horizontal = True font_size = int(screen_width / self.theme['horiz_font_percent']) else: self.horizontal = False font_size = int(screen_width / self.theme['vert_font_percent']) self.accent_width = font_size / 9 self.font = font.Font(family=self.theme['font_family'], size=font_size, weight=self.theme["font_weight"]) self.cmd_font = font.Font(family="Symbola", size=font_size) self.configure(background=self.background)
def i3clients(): """ Returns a dictionary of key-value pairs of a window text and window id. Each window text is of format "[workspace] window title (instance number)" """ clients = {} for space in i3.get_workspaces(): workspace = i3.filter(name=space['name']) if not workspace: continue workspace = workspace[0] windows = i3.filter(workspace, nodes=[]) instances = {} # Adds windows and their ids to the clients dictionary for window in windows: win_str = '[%s] %s' % (workspace['name'], window['name']) # Appends an instance number if other instances are present if win_str in instances: instances[win_str] += 1 win_str = '%s (%d)' % (win_str, instances[win_str]) else: instances[win_str] = 1 clients[win_str] = window['id'] return clients
dest='direction', action='store_const', help='swich to the provious workspace (by default it goes to next)', const="prev", default="next") parser.add_argument('--next', dest='direction', action='store_const', help='swich to the next workspace (default)', const="next", default="next") args = parser.parse_args() workspaces = [] for workspace in i3.get_workspaces(): if workspace['visible']: workspaces.append(workspace) workspaces.extend(workspaces) if args.direction == "prev": workspaces.reverse() switch_to = False for workspace in workspaces: if switch_to: i3.workspace(workspace['name']) break if workspace['focused']: switch_to = True
import i3 parser = argparse.ArgumentParser( description='switch to or move container to next or prev free workspace') parser.add_argument('action', nargs=1, choices=['switch', 'move']) parser.add_argument('direction', nargs=1, choices=['prev', 'next']) args = parser.parse_args() def focused(workspace): if workspace['focused']: return workspace workspaces = i3.get_workspaces() current_ws = filter(focused, workspaces)[0]['num'] ws_list = range(current_ws + 1, 11) + range(1, current_ws) if args.direction[0] == 'prev': ws_list.reverse() used_ws = [ws['num'] for ws in i3.get_workspaces()] try: ws = next(ws for ws in ws_list if ws not in used_ws) except StopIteration: sys.exit(3) if args.action[0] == 'switch':
#!/usr/bin/env python # cycle-workspace # Moves the currently active workspace to the next active display # Depends on i3-py (`pip install i3-py`) import i3 # figure out what is on, and what is currently on your screen. focused_workspace = list(filter(lambda s: s['focused'], i3.get_workspaces()))[0] outputs = list(filter(lambda s: s['active'], i3.get_outputs())) # find the index of the currently focused workspace currentIndex = 0 for i, output in enumerate(outputs): if output['name'] == focused_workspace['output']: currentIndex = i break # find the next workspace nextIndex = currentIndex + 1 if nextIndex >= len(outputs): nextIndex = 0 other_workspace = outputs[nextIndex] this_workspace = outputs[currentIndex] # send current to the no-active one i3.command('move', 'workspace to output ' + other_workspace['name']) # i3.command('move', 'workspace to output '+this_workspace['name'])
def main(): workspaces = i3.get_workspaces() for workspace in workspaces: print(workspace['name'])
def get_current_workspace(): '''Get the name of the currently active workspace.''' filtered = [ws for ws in i3.get_workspaces() if ws["focused"] is True] return filtered[0]['name'] if filtered else None
#!/usr/bin/python3 import i3 current_output_name = [ws for ws in i3.get_workspaces() if ws["focused"]][0]["output"] output_names = [ output["name"] for output in i3.get_outputs() if output["current_workspace"] != None ] index = output_names.index(current_output_name) next_output_index = (index + 1) % len(output_names) next_output_name = output_names[next_output_index] i3.move(f"workspace to {next_output_name}")
def get_workspace(): workspaces = i3.get_workspaces() for workspace in workspaces: if workspace['focused']: return workspace return None
def change_workspace(num): """ Switches to workspace num like xmonad. Always sets focused output to workspace num. If the workspace is on another output, then the workspaces are "shifted" among the outputs. """ num = int(num) LOG.debug('Switching to workspace %d', num) focused_workspace = get_focused_workspace() LOG.debug('Focused workspace:\n' + pformat(focused_workspace)) # Check if already on workspace if int(focused_workspace['num']) == num: LOG.debug('Already on correct workspace') return # Get workspace we want to switch to want_workspace = get_workspace(num) if want_workspace is None: LOG.debug('Switching to workspace because it does not exist') switch_workspace(num) return LOG.debug('Want workspace:\n' + pformat(want_workspace)) # Save workspace originally showing on want_workspace's output other_output = [ outp for outp in get_active_outputs() if outp['name'] == want_workspace['output'] ][0] LOG.debug('Other_output=%s', other_output) other_workspace = [ wk for wk in i3.get_workspaces() if wk['name'] == other_output['current_workspace'] ][0] LOG.debug('Other workspace:\n' + pformat(other_workspace)) # Check if wanted workspace is on focused output if focused_workspace['output'] == want_workspace['output']: LOG.debug('Wanted workspace already on focused output, ' 'switching as normal') switch_workspace(num) return # Check if wanted workspace is on other output if not want_workspace['visible']: LOG.debug('Workspace to switch to is on other output, not showing') # Switch to workspace on other output switch_workspace(num) LOG.debug('Wanted workspace is on other output') # Wanted workspace is visible, so swap workspaces swap_visible_workspaces(want_workspace, focused_workspace) # Focus other_workspace switch_workspace(other_workspace['num']) # Focus on wanted workspace switch_workspace(want_workspace['num'])
def get_current_workspace(): workspaces = i3.get_workspaces() for workspace in workspaces: if workspace['focused']: return workspace['num']
#!/usr/bin/python3 import i3 from subprocess import call for w in i3.get_workspaces(): if w['focused']: cur_wks = w['name'] for w in i3.get_workspaces(): i3.workspace(w['name']) i3.command('move', 'workspace to output right') i3.command('workspace', cur_wks) for w in i3.get_workspaces(): if w['focused']: cur_output = w['output'] break call("xrandr --output {} --primary".format(cur_output), shell=True)
import i3 # pip install i3-py num = i3.filter(i3.get_workspaces(), focused=True)[0]['num'] ws_nodes = i3.filter(num=num)[0]['nodes'] ws_nodes = ws_nodes + i3.filter(num=num)[0]['floating_nodes'] curr = i3.filter(ws_nodes, focused=True)[0] ids = [win['id'] for win in i3.filter(ws_nodes, nodes=[])] next_idx = (ids.index(curr['id']) - 1) % len(ids) next_id = ids[next_idx] i3.focus(con_id=next_id)
#!/usr/bin/python3 import i3 # retrieve only active outputs outputs = list(filter(lambda output: output['active'], i3.get_outputs())) current_ws = i3.filter(i3.get_workspaces(), focused=True)[0]['name'] for output in outputs: # set current workspace to the one active on that output i3.workspace(output['current_workspace']) # ..and move it to the output to the right. # outputs wrap, so the right of the right is left ;) i3.command('move', 'workspace to output right') i3.workspace(current_ws)
def fromFocus(): workspaces = i3.get_workspaces() for ws in workspaces: if ws["focused"] == True: return Workspace.fromI3Workspace(ws)
def current_workspace(): workspaces = i3.get_workspaces() for w in workspaces: if w['focused'] == True: return i3.filter(type='workspace', name=w['name'])[0]['num']
def get_focused_workspace(): """Get workspace that is currently focused""" actives = [wk for wk in i3.get_workspaces() if wk['focused']] assert len(actives) == 1 return actives[0]
def get_workspaces(): data = i3.get_workspaces() data = {int(item['name']): item for item in data if is_valid(item)} return data
#!/usr/bin/env python # https://gist.github.com/97-109-107/b70356670ae8309ffb4f import i3 outputs = i3.get_outputs() workspaces = i3.get_workspaces() # figure out what is on, and what is currently on your screen. workspace = list(filter(lambda s: s['focused']==True, workspaces)) output = list(filter(lambda s: s['active']==True, outputs)) # figure out the other workspace name other_workspace = list(filter(lambda s: s['name']!=workspace[0]['output'], output)) # send current to the no-active one i3.command('move', 'workspace to output '+other_workspace[0]['name'])