mirror of
https://github.com/vincentbernat/i3wm-configuration.git
synced 2025-06-22 18:03:28 +02:00
i3-companion: try to move windows in the same workspace as similar ones
This commit is contained in:
parent
4e21366d7a
commit
84a535bb85
1 changed files with 46 additions and 31 deletions
|
@ -347,52 +347,67 @@ async def worksplace_exclusive(i3, event):
|
||||||
with an exclusive app."""
|
with an exclusive app."""
|
||||||
w = event.container
|
w = event.container
|
||||||
|
|
||||||
def can_intrude(w):
|
def partof(w, apps):
|
||||||
"""Can this new window intrude any workspace?"""
|
"""Provided window is part of the provided apps."""
|
||||||
if w.floating in {"auto_on", "user_on"}:
|
names = {
|
||||||
return True
|
|
||||||
if w.ipc_data["window_type"] not in {"normal", "splash", "unknown"}:
|
|
||||||
return True
|
|
||||||
if w.sticky:
|
|
||||||
return True
|
|
||||||
ids = {
|
|
||||||
s is not None and s.lower() or None
|
s is not None and s.lower() or None
|
||||||
for s in {w.name, w.window_class, w.window_instance}
|
for s in {w.name, w.window_class, w.window_instance}
|
||||||
}
|
}
|
||||||
if ids.intersection(intrusive_apps):
|
return bool(names.intersection(apps))
|
||||||
return True
|
|
||||||
|
|
||||||
# Can the new window just intrude?
|
# Can the current window intrude the workspace?
|
||||||
if can_intrude(w):
|
if (
|
||||||
|
w.floating in {"auto_on", "user_on"}
|
||||||
|
or w.ipc_data["window_type"] not in {"normal", "splash", "unknown"}
|
||||||
|
or w.sticky
|
||||||
|
or partof(w, intrusive_apps)
|
||||||
|
):
|
||||||
logger.debug("window %s can intrude", w.name)
|
logger.debug("window %s can intrude", w.name)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the workspace. From an event, w.workspace() is None, so
|
|
||||||
# search it in the tree.
|
|
||||||
tree = await i3.get_tree()
|
tree = await i3.get_tree()
|
||||||
workspace = next(
|
|
||||||
(ow.workspace() for ow in tree.leaves() if w.id == ow.id), None
|
# Get the window workspace. From an event, w.workspace() is None,
|
||||||
|
# so search it in the tree.
|
||||||
|
current_workspace = next(
|
||||||
|
(ow.workspace().num for ow in tree.leaves() if w.id == ow.id), None
|
||||||
)
|
)
|
||||||
if not workspace:
|
if not current_workspace:
|
||||||
|
logger.info(f"cannot get workspace for {w.window_class}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Does the target workspace contains an exclusive app (not using
|
# Get the list of workspaces with an exclusive app, excluding the
|
||||||
# the same class).
|
# current window and windows of the same class.
|
||||||
ids = {
|
exclusive_workspaces = {
|
||||||
s is not None and s.lower() or None
|
ow.workspace().num
|
||||||
for ow in workspace.leaves()
|
for ow in tree.leaves()
|
||||||
for s in {ow.name, ow.window_class, ow.window_instance}
|
if w.id != ow.id
|
||||||
if w.id != ow.id and w.window_class != ow.window_class
|
and (w.window_class or object()) != ow.window_class
|
||||||
|
and partof(ow, exclusive_apps)
|
||||||
}
|
}
|
||||||
exclusives = ids.intersection(exclusive_apps)
|
|
||||||
if not exclusives:
|
# If current one is OK, don't move
|
||||||
logger.debug("no exclusive app, %s can go there", w.name)
|
if current_workspace not in exclusive_workspaces:
|
||||||
|
logger.debug("no exclusive app, %s can go there", w.window_class)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Create a new workspace and move the window here
|
# Are there other workspaces with the same app but no exclusive apps?
|
||||||
|
candidate_workspaces = {
|
||||||
|
ow.workspace().num
|
||||||
|
for ow in tree.leaves()
|
||||||
|
if w.id != ow.id and (w.window_class or object()) == ow.window_class
|
||||||
|
}
|
||||||
|
candidate_workspaces -= exclusive_workspaces
|
||||||
|
|
||||||
|
if candidate_workspaces:
|
||||||
|
# Use one of the candidates
|
||||||
|
num = next(iter(candidate_workspaces))
|
||||||
|
else:
|
||||||
|
# Create a new workspace
|
||||||
num = await _new_workspace(i3)
|
num = await _new_workspace(i3)
|
||||||
|
|
||||||
logger.info(f"move window {w.window_class} to workspace {num}")
|
logger.info(f"move window {w.window_class} to workspace {num}")
|
||||||
await w.command(f'move container to workspace number "{num}"')
|
await w.command(f'move container to workspace number "{num}", focus')
|
||||||
|
|
||||||
|
|
||||||
@on(CommandEvent("quake-console"))
|
@on(CommandEvent("quake-console"))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue