i3-companion: blacken the code

This commit is contained in:
Vincent Bernat 2021-07-11 12:23:00 +02:00
parent 0984436348
commit 0e88b0f545

View file

@ -24,13 +24,16 @@ logger = logging.getLogger("i3-companion")
def on(*events): def on(*events):
"""Tag events that should be provided to the function.""" """Tag events that should be provided to the function."""
def decorator(fn): def decorator(fn):
@functools.wraps(fn) @functools.wraps(fn)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
return fn(*args, **kwargs) return fn(*args, **kwargs)
on.functions = getattr(on, "functions", {}) on.functions = getattr(on, "functions", {})
on.functions[fn] = events on.functions[fn] = events
return wrapper return wrapper
return decorator return decorator
@ -46,7 +49,8 @@ async def notify(i3, **kwargs):
summary="", summary="",
actions=[], actions=[],
hints={}, hints={},
expire_timeout=5000) expire_timeout=5000,
)
parameters.update(kwargs) parameters.update(kwargs)
return await interface.Notify(**parameters) return await interface.Notify(**parameters)
@ -70,14 +74,10 @@ application_icons = {
"steam": "", "steam": "",
"vbeterm": "", "vbeterm": "",
"zathura": "", "zathura": "",
"zoom": "" "zoom": "",
} }
application_icons_nomatch = "" application_icons_nomatch = ""
application_icons_alone = { application_icons_alone = {application_icons[k] for k in {"vbeterm"}}
application_icons[k] for k in {
"vbeterm"
}
}
@on(Event.WINDOW_MOVE, Event.WINDOW_NEW, Event.WINDOW_CLOSE) @on(Event.WINDOW_MOVE, Event.WINDOW_NEW, Event.WINDOW_CLOSE)
@ -89,8 +89,7 @@ async def workspace_rename(i3, event):
def application_icon(window): def application_icon(window):
"""Get application icon for a window.""" """Get application icon for a window."""
for attr in ('window_instance', for attr in ("window_instance", "window_class"):
'window_class'):
name = getattr(window, attr, None) name = getattr(window, attr, None)
if name is None: if name is None:
continue continue
@ -113,7 +112,7 @@ async def workspace_rename(i3, event):
logger.debug(f"rename workspace {workspace.num}") logger.debug(f"rename workspace {workspace.num}")
command = f'rename workspace "{workspace.name}" to "{new_name}"' command = f'rename workspace "{workspace.name}" to "{new_name}"'
commands.append(command) commands.append(command)
await i3.command(';'.join(commands)) await i3.command(";".join(commands))
async def _new_workspace(i3): async def _new_workspace(i3):
@ -121,7 +120,7 @@ async def _new_workspace(i3):
workspace_nums = {w.num for w in workspaces} workspace_nums = {w.num for w in workspaces}
max_num = max(workspace_nums) max_num = max(workspace_nums)
available = (set(range(1, max_num + 2)) - workspace_nums).pop() available = (set(range(1, max_num + 2)) - workspace_nums).pop()
logger.info(f'create new workspace number {available}') logger.info(f"create new workspace number {available}")
await i3.command(f'workspace number "{available}"') await i3.command(f'workspace number "{available}"')
return available return available
@ -140,17 +139,11 @@ async def new_workspace(i3, event):
# Move the window to this workspace # Move the window to this workspace
if event == "move-to-new-workspace": if event == "move-to-new-workspace":
await current.command(f'move container to workspace ' await current.command(f"move container to workspace " f'number "{num}"')
f'number "{num}"')
exclusive_apps = { exclusive_apps = {"emacs", "firefox"}
"emacs", intrusive_apps = {"vbeterm"}
"firefox"
}
intrusive_apps = {
"vbeterm"
}
@on(Event.WINDOW_NEW) @on(Event.WINDOW_NEW)
@ -163,12 +156,14 @@ async def worksplace_exclusive(i3, event):
"""Can this new window intrude any workspace?""" """Can this new window intrude any workspace?"""
if w.floating in {"auto_on", "user_on"}: if w.floating in {"auto_on", "user_on"}:
return True return True
if w.ipc_data['window_type'] not in {"normal", "splash", "unknown"}: if w.ipc_data["window_type"] not in {"normal", "splash", "unknown"}:
return True return True
if w.sticky: if w.sticky:
return True return True
ids = {s is not None and s.lower() or None ids = {
for s in {w.name, w.window_class, w.window_instance}} s is not None and s.lower() or None
for s in {w.name, w.window_class, w.window_instance}
}
if ids.intersection(intrusive_apps): if ids.intersection(intrusive_apps):
return True return True
@ -182,10 +177,12 @@ async def worksplace_exclusive(i3, event):
workspace = tree.find_focused().workspace() workspace = tree.find_focused().workspace()
if not workspace: if not workspace:
return return
ids = {s is not None and s.lower() or None ids = {
s is not None and s.lower() or None
for ow in workspace.leaves() for ow in workspace.leaves()
for s in {ow.name, ow.window_class, ow.window_instance} for s in {ow.name, ow.window_class, ow.window_instance}
if w.id != ow.id} if w.id != ow.id
}
exclusives = ids.intersection(exclusive_apps) exclusives = ids.intersection(exclusive_apps)
if not exclusives: if not exclusives:
logger.debug("no exclusive app, {w.name} can go there") logger.debug("no exclusive app, {w.name} can go there")
@ -193,7 +190,7 @@ async def worksplace_exclusive(i3, event):
# Create a new workspace and move the window here # Create a new workspace and move the window here
num = await _new_workspace(i3) num = await _new_workspace(i3)
logger.info(f'move window {w.name} to workspace {num}') logger.info(f"move window {w.name} to workspace {num}")
await w.command(f'move container to workspace number "{num}"') await w.command(f'move container to workspace number "{num}"')
@ -210,7 +207,7 @@ async def quake_console(i3, event):
tree = await i3.get_tree() tree = await i3.get_tree()
term = tree.find_instanced(term_name) term = tree.find_instanced(term_name)
if not term: if not term:
await i3.command(f'exec exec {term_exec} --name {term_name}') await i3.command(f"exec exec {term_exec} --name {term_name}")
tries = 5 tries = 5
while not term and tries: while not term and tries:
tree = await i3.get_tree() tree = await i3.get_tree()
@ -230,11 +227,13 @@ async def quake_console(i3, event):
height = int(ws_height * height) height = int(ws_height * height)
posx = ws_x posx = ws_x
posy = ws_y posy = ws_y
command = (f'[instance={term_name}] ' command = (
'border none,' f"[instance={term_name}] "
f'resize set {width} px {height} px,' "border none,"
'scratchpad show,' f"resize set {width} px {height} px,"
f'move absolute position {posx}px {posy}px') "scratchpad show,"
f"move absolute position {posx}px {posy}px"
)
logger.debug(f"QuakeConsole: {command}") logger.debug(f"QuakeConsole: {command}")
await i3.command(command) await i3.command(command)
@ -256,23 +255,29 @@ async def container_info(i3, event):
"class": w.window_class, "class": w.window_class,
"instance": w.window_instance, "instance": w.window_instance,
"role": w.window_role, "role": w.window_role,
"type": w.ipc_data['window_type'], "type": w.ipc_data["window_type"],
"sticky": w.sticky, "sticky": w.sticky,
"floating": w.floating, "floating": w.floating,
"geometry": f"{r.width}×{r.height}+{r.x}+{r.y}", "geometry": f"{r.width}×{r.height}+{r.x}+{r.y}",
"layout": w.layout, "layout": w.layout,
"parcent": w.percent, "parcent": w.percent,
"marks": ", ".join(w.marks) or "(none)" "marks": ", ".join(w.marks) or "(none)",
} }
body = "\n".join((f"<tt>{k:10}</tt> {html.escape(str(v))}" body = "\n".join(
(
f"<tt>{k:10}</tt> {html.escape(str(v))}"
for k, v in info.items() for k, v in info.items()
if v is not None)) if v is not None
result = await notify(i3, )
)
result = await notify(
i3,
app_icon="system-search", app_icon="system-search",
expire_timeout=10000, expire_timeout=10000,
summary=summary, summary=summary,
body=body, body=body,
replaces_id=getattr(container_info, "last_id", 0)) replaces_id=getattr(container_info, "last_id", 0),
)
container_info.last_id = result[0] container_info.last_id = result[0]
@ -286,8 +291,7 @@ async def workspace_info(i3, event):
workspace = focused[0] workspace = focused[0]
summary = f"Workspace {workspace.num} on {workspace.output}" summary = f"Workspace {workspace.num} on {workspace.output}"
tree = await i3.get_tree() tree = await i3.get_tree()
workspace = [w for w in tree.workspaces() workspace = [w for w in tree.workspaces() if w.num == workspace.num]
if w.num == workspace.num]
def format(container): def format(container):
if container.focused: if container.focused:
@ -295,22 +299,22 @@ async def workspace_info(i3, event):
elif not container.window: elif not container.window:
style = 'foreground="#6c98ee"' style = 'foreground="#6c98ee"'
else: else:
style = '' style = ""
if container.window: if container.window:
content = (f"{(container.window_class or '???').lower()}: " content = (
f"{(container.window_title or '???')}") f"{(container.window_class or '???').lower()}: "
elif container.type == 'workspace' and not container.nodes: f"{(container.window_title or '???')}"
)
elif container.type == "workspace" and not container.nodes:
# Empty workspaces use workspace_layout, but when default, # Empty workspaces use workspace_layout, but when default,
# this is layout... # this is layout...
layout = container.ipc_data['workspace_layout'] layout = container.ipc_data["workspace_layout"]
if layout == "default": if layout == "default":
layout = container.layout layout = container.layout
content = f"({layout})" content = f"({layout})"
else: else:
content = f"({container.layout})" content = f"({container.layout})"
root = (f"<span {style}>" root = f"<span {style}>{content.lower()}</span>"
f"{content.lower()}"
"</span>")
children = [] children = []
for child in container.nodes: for child in container.nodes:
if child == container.nodes[-1]: if child == container.nodes[-1]:
@ -325,12 +329,14 @@ async def workspace_info(i3, event):
return "\n".join(children) return "\n".join(children)
body = format(workspace[0]).lstrip("\n") body = format(workspace[0]).lstrip("\n")
result = await notify(i3, result = await notify(
i3,
app_icon="system-search", app_icon="system-search",
expire_timeout=20000, expire_timeout=20000,
summary=summary, summary=summary,
body=body, body=body,
replaces_id=getattr(workspace_info, "last_id", 0)) replaces_id=getattr(workspace_info, "last_id", 0),
)
workspace_info.last_id = result[0] workspace_info.last_id = result[0]
@ -357,8 +363,7 @@ async def output_update(i3, event):
logger.warning(f"{cmd} exited with {proc.returncode}") logger.warning(f"{cmd} exited with {proc.returncode}")
logger.debug("schedule XRandR change") logger.debug("schedule XRandR change")
output_update.running = asyncio.get_event_loop().call_later( output_update.running = asyncio.get_event_loop().call_later(2, output_update_now)
2, output_update_now)
async def main(options): async def main(options):
@ -381,7 +386,7 @@ async def main(options):
cmd = event.binding.command cmd = event.binding.command
if not cmd.startswith("nop "): if not cmd.startswith("nop "):
return return
cmd = cmd[4:].strip('"\'') cmd = cmd[4:].strip("\"'")
if not cmd: if not cmd:
return return
kind = cmd.split(":")[0] kind = cmd.split(":")[0]
@ -389,6 +394,7 @@ async def main(options):
for e in events: for e in events:
if e == kind: if e == kind:
await fn(i3, cmd) await fn(i3, cmd)
i3.on(Event.BINDING, binding_event) i3.on(Event.BINDING, binding_event)
await i3.main() await i3.main()
@ -400,9 +406,9 @@ if __name__ == "__main__":
for fn, events in on.functions.items(): for fn, events in on.functions.items():
description += f" {fn.__doc__}" description += f" {fn.__doc__}"
parser = argparse.ArgumentParser(description=description) parser = argparse.ArgumentParser(description=description)
parser.add_argument("--debug", "-d", action="store_true", parser.add_argument(
default=False, "--debug", "-d", action="store_true", default=False, help="enable debugging"
help="enable debugging") )
options = parser.parse_args() options = parser.parse_args()
# Logging # Logging