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() outputs = i3.get_outputs() workspaces = i3.get_workspaces() focused_workspace = i3.get_tree().find_focused().workspace().name print('List of all workspaces:') for workspace in workspaces: print( f"Name {workspace.name} | Num {workspace.num} | Visible: {workspace.visible} | Focused: {workspace.focused} | Output: {workspace.output}" ) print('Get active workspaces') active_workspaces = [ workspace.name for workspace in filter(lambda w: w.visible and not w.focused, workspaces) ] print('Move workspaces to first another output:') for workspace in workspaces: for output in filter(lambda o: o.active, outputs): if output.name != workspace.output: command = f'[workspace="{workspace.name}"] move workspace to output {output.name}' print(command) i3.command(command) print('Focus on workspace (active workspaces):') for ws in active_workspaces: command = f'workspace "{ws}"'
class WorkSpacer: def __init__(self, args): self.i3 = None self.args = args self.workspaces_on_outputs = {} self.workspaces = None self.outputs = None self.config = None self.mouse = pynput.mouse.Controller() self.mouse_position = None self.current_output_name = None def _connect(self): self.print_if_debug('All available outputs on device') self.print_if_debug(names_for_outputs) try: self.i3 = Connection() self.config = self.i3.get_config().__dict__['config'] config_outputs = {} for matchNo, match in enumerate( re.finditer(r'set (\$[a-zA-Z0-9]+) (' + names_for_outputs + ')', self.config, re.MULTILINE), start=1 ): config_outputs[match.group(1)] = match.group(2) self.print_if_debug('All outputs listed in the config, matched on available configs') self.print_if_debug(config_outputs) config_workspace_names = {} for matchNum, match in enumerate( re.finditer(r'set (\$.*) (\d.*)', self.config, re.MULTILINE) ): config_workspace_names[match.group(1)] = match.group(2) self.print_if_debug('All config_workspaces_names') self.print_if_debug(config_workspace_names) for matchNum, match in enumerate( re.finditer(r'workspace (\$.*) output (\$.*)', self.config, re.MULTILINE) ): if not config_outputs.keys().__contains__(match.group(2)): continue # Not an active display, skip it if not self.workspaces_on_outputs.keys().__contains__(config_outputs[match.group(2)]): self.workspaces_on_outputs[config_outputs[match.group(2)]] = [] self.workspaces_on_outputs[config_outputs[match.group(2)]].append( config_workspace_names[match.group(1)]) self.print_if_debug("All workspaces with outputs") self.print_if_debug(self.workspaces_on_outputs) except Exception as exc: if self.args.debug: raise exc sys.exit(1) self.workspaces = [workspaces for workspaces in self.i3.get_workspaces()] outputs = self.i3.get_outputs() self.outputs = [output for output in outputs if output.__dict__["active"] is True] def run(self): self._connect() self.mouse_position = self.mouse.position self.current_output_name = self._get_workspace_from_courser_position() if self.args.shift: self.i3.command( f'move container to workspace {self.workspaces_on_outputs[self.current_output_name][self.args.index - 1]}') if not self.args.keep_with_it: return self.i3.command(f'workspace {self.workspaces_on_outputs[self.current_output_name][self.args.index - 1]}') def _get_workspace_from_courser_position(self): for output in self.outputs: width = output.__dict__["rect"].__dict__["width"] height = output.__dict__["rect"].__dict__["height"] x_offset = output.__dict__["rect"].__dict__["x"] y_offset = output.__dict__["rect"].__dict__["y"] if x_offset == 0 and y_offset == 0: if x_offset <= self.mouse_position[0] <= x_offset + width and y_offset <= \ self.mouse_position[1] <= y_offset + height: return output.__dict__["name"] elif x_offset == 0: if x_offset <= self.mouse_position[0] <= x_offset + width and y_offset < \ self.mouse_position[1] <= y_offset + height: return output.__dict__["name"] elif y_offset == 0: if x_offset < self.mouse_position[0] <= x_offset + width and y_offset <= \ self.mouse_position[1] <= y_offset + height: return output.__dict__["name"] else: if x_offset < self.mouse_position[0] <= x_offset + width and y_offset < \ self.mouse_position[1] <= y_offset + height: return output.__dict__["name"] def _get_workspaces_for_output(self, output): return [workspace for workspace in self.workspaces if workspace.__dict__['output'] == output] def print_if_debug(self, to_print): if self.args.debug: pprint.pprint(to_print)