def compute_local_numbers(monitor_workspaces: List[i3ipc.Con],
                          all_workspaces: List[i3ipc.Con],
                          renumber_workspaces: bool) -> List[int]:
    monitor_workspace_ids = {ws.id for ws in monitor_workspaces}
    other_monitors_workspaces = [
        ws for ws in all_workspaces if ws.id not in monitor_workspace_ids
    ]
    used_local_numbers = get_used_local_numbers(other_monitors_workspaces)
    logger.debug('Local numbers used by group in other monitors: %s',
                 used_local_numbers)
    if renumber_workspaces:
        return get_lowest_free_local_numbers(len(monitor_workspaces),
                                             used_local_numbers)
    if used_local_numbers:
        last_used_local_number = max(used_local_numbers)
    else:
        last_used_local_number = 0
    local_numbers = []
    for workspace in monitor_workspaces:
        ws_metadata = parse_name(workspace.name)
        local_number = ws_metadata.local_number
        if local_number is None or (local_number in used_local_numbers):
            local_number = last_used_local_number + 1
            last_used_local_number += 1
        local_numbers.append(local_number)
    return local_numbers
Exemple #2
0
 def focus_workspace_number(self, group_context,
                            target_local_number: int) -> None:
     target_workspace_name, _ = self._get_workspace_by_local_number(
         group=self._get_group_from_context(group_context),
         local_number=target_local_number)
     logger.debug('Derived workspace name: "%s"', target_workspace_name)
     self.i3_proxy.focus_workspace(target_workspace_name)
Exemple #3
0
 def organize_workspace_groups(self,
                               workspace_groups: OrderedWorkspaceGroups,
                               monitor_name: Optional[str] = None) -> None:
     if monitor_name is None:
         monitor_name = self.i3_proxy.get_focused_monitor_name()
     monitor_index = self.i3_proxy.get_monitor_index(monitor_name)
     group_to_all_workspaces = ws_names.get_group_to_workspaces(
         self.get_tree().workspaces())
     for group_index, (group, workspaces) in enumerate(workspace_groups):
         logger.debug('Organizing workspace group: "%s" in monitor "%s"',
                      group, monitor_name)
         local_numbers = ws_names.compute_local_numbers(
             workspaces, group_to_all_workspaces.get(group, []),
             self.config['renumber_workspaces'])
         for workspace, local_number in zip(workspaces, local_numbers):
             ws_metadata = ws_names.parse_name(workspace.name)
             ws_metadata.group = group
             ws_metadata.local_number = local_number
             ws_metadata.global_number = ws_names.compute_global_number(
                 monitor_index, group_index, local_number)
             dynamic_name = ''
             # Add window icons if needed.
             if self.config['icons']['enable'] and (
                     self.config['icons']['enable_all_groups']
                     or group_index == 0):
                 dynamic_name = self.icons_resolver.get_workspace_icons(
                     workspace)
             ws_metadata.dynamic_name = dynamic_name
             new_name = ws_names.create_name(ws_metadata)
             self.i3_proxy.rename_workspace(workspace.name, new_name)
             workspace.name = new_name
def get_group_to_workspaces(workspaces: List[i3ipc.Con]) -> GroupToWorkspaces:
    group_to_workspaces = collections.OrderedDict()
    for workspace in workspaces:
        ws_metadata = parse_name(workspace.name)
        group = ws_metadata.group
        logger.debug('Workspace %s parsed as: %s', workspace.name, ws_metadata)
        if group not in group_to_workspaces:
            group_to_workspaces[group] = []
        group_to_workspaces[group].append(workspace)
    return group_to_workspaces
Exemple #5
0
 def switch_active_group(self, target_group: str,
                         focused_monitor_only: bool) -> None:
     focused_monitor_name = self.i3_proxy.get_focused_monitor_name()
     monitor_to_workspaces = self.i3_proxy.get_monitor_to_workspaces()
     for monitor, workspaces in monitor_to_workspaces.items():
         group_exists = (target_group
                         in ws_names.get_group_to_workspaces(workspaces))
         if monitor == focused_monitor_name:
             logger.debug('Switching active group in focused monitor "%s"',
                          monitor)
         elif not focused_monitor_only and group_exists:
             logger.debug(
                 'Non focused monitor %s has workspaces in the group "%s", '
                 'switching to it.', monitor, target_group)
         else:
             continue
         self.switch_monitor_active_group(monitor, target_group)
     # NOTE: We only switch focus to the new workspace after renaming all the
     # workspaces in all monitors and groups. Otherwise, if the previously
     # focused workspace was renamed, i3's `workspace back_and_forth` will
     # switch focus to a non-existant workspace name.
     focused_group = ws_names.get_group(
         self.get_tree().find_focused().workspace())
     # The target group is already focused, no need to do anything.
     if focused_group == target_group:
         return
     group_to_monitor_workspaces = ws_names.get_group_to_workspaces(
         monitor_to_workspaces[focused_monitor_name])
     if target_group in group_to_monitor_workspaces:
         workspace_name = group_to_monitor_workspaces[target_group][0].name
     # The focused monitor doesn't have any workspaces in the target group,
     # so create one.
     else:
         workspace_name = self._create_new_active_group_workspace_name(
             focused_monitor_name, target_group)
     self.i3_proxy.focus_workspace(workspace_name,
                                   auto_back_and_forth=False)