mirror of
https://github.com/vincentbernat/i3wm-configuration.git
synced 2025-06-21 17:39:00 +02:00
i3-companion: swallow quake console functionality
While payload could be structured, we keep a string as it is easier to express it in i3 configuration file.
This commit is contained in:
parent
2a85902609
commit
1caacfd679
3 changed files with 46 additions and 105 deletions
|
@ -12,6 +12,7 @@ import logging.handlers
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
from i3ipc import Connection, Event
|
from i3ipc import Connection, Event
|
||||||
|
|
||||||
|
@ -135,6 +136,47 @@ def new_workspace(i3, event):
|
||||||
current.command(f'move container to workspace number "{available}"')
|
current.command(f'move container to workspace number "{available}"')
|
||||||
|
|
||||||
|
|
||||||
|
def quake_console(i3, event):
|
||||||
|
"""Spawn a quake console or toggle an existing one."""
|
||||||
|
if type(event.payload) is not str or \
|
||||||
|
not event.payload.startswith("quake-console:"):
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
_, term_exec, term_name, height = event.payload.split(":")
|
||||||
|
height = float(height)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warn(f"unable to parse payload {event.payload}: {exc}")
|
||||||
|
return
|
||||||
|
|
||||||
|
term = i3.get_tree().find_instanced(term_name)
|
||||||
|
if not term:
|
||||||
|
i3.command(f'exec {term_exec} --name {term_name}')
|
||||||
|
tries = 5
|
||||||
|
while not term and tries:
|
||||||
|
term = i3.get_tree().find_instanced(term_name)
|
||||||
|
time.sleep(0.2)
|
||||||
|
tries -= 1
|
||||||
|
if not term:
|
||||||
|
raise RuntimeError("unable to spawn terminal")
|
||||||
|
term = term[0]
|
||||||
|
workspace = [ws for ws in i3.get_workspaces() if ws.focused][0]
|
||||||
|
ws_x = workspace.rect.x
|
||||||
|
ws_y = workspace.rect.y
|
||||||
|
ws_width = workspace.rect.width
|
||||||
|
ws_height = workspace.rect.height
|
||||||
|
width = ws_width
|
||||||
|
height = int(ws_height * height)
|
||||||
|
posx = ws_x
|
||||||
|
posy = ws_y
|
||||||
|
command = (f'[instance={term_name}] '
|
||||||
|
'border none,'
|
||||||
|
f'resize set {width} px {height} px,'
|
||||||
|
'scratchpad show,'
|
||||||
|
f'move absolute position {posx}px {posy}px')
|
||||||
|
logger.debug(f"QuakeConsole: {command}")
|
||||||
|
i3.command(command)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
options = parse_args()
|
options = parse_args()
|
||||||
setup_logging(options)
|
setup_logging(options)
|
||||||
|
@ -151,6 +193,9 @@ if __name__ == "__main__":
|
||||||
# Create a new workspace or move to a new workspace
|
# Create a new workspace or move to a new workspace
|
||||||
i3.on(Event.TICK, new_workspace)
|
i3.on(Event.TICK, new_workspace)
|
||||||
|
|
||||||
|
# Create/display a quake console
|
||||||
|
i3.on(Event.TICK, quake_console)
|
||||||
|
|
||||||
i3.main()
|
i3.main()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("%s", e)
|
logger.exception("%s", e)
|
||||||
|
|
104
bin/quake
104
bin/quake
|
@ -1,104 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
"""Personal i3 companion
|
|
||||||
|
|
||||||
This script will listen to i3 events and react accordingly.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import logging
|
|
||||||
import logging.handlers
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
from i3ipc import Connection
|
|
||||||
|
|
||||||
logger = logging.getLogger(os.path.splitext(os.path.basename(sys.argv[0]))[0])
|
|
||||||
|
|
||||||
|
|
||||||
class CustomFormatter(argparse.RawDescriptionHelpFormatter,
|
|
||||||
argparse.ArgumentDefaultsHelpFormatter):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def parse_args(args=sys.argv[1:]):
|
|
||||||
"""Parse arguments."""
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description=sys.modules[__name__].__doc__,
|
|
||||||
formatter_class=CustomFormatter)
|
|
||||||
|
|
||||||
g = parser.add_mutually_exclusive_group()
|
|
||||||
g.add_argument("--debug", "-d", action="store_true",
|
|
||||||
default=False,
|
|
||||||
help="enable debugging")
|
|
||||||
g.add_argument("--silent", "-s", action="store_true",
|
|
||||||
default=False,
|
|
||||||
help="don't log")
|
|
||||||
|
|
||||||
parser.add_argument("--height",
|
|
||||||
default=0.3,
|
|
||||||
help="height of terminal")
|
|
||||||
parser.add_argument("--name",
|
|
||||||
default="UniqueNameForConsole",
|
|
||||||
help="Unique name to identify terminal")
|
|
||||||
parser.add_argument("--term",
|
|
||||||
default="x-terminal-emulator",
|
|
||||||
help="Terminal emulator to run")
|
|
||||||
|
|
||||||
return parser.parse_args(args)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_logging(options):
|
|
||||||
"""Configure logging."""
|
|
||||||
root = logging.getLogger("")
|
|
||||||
root.setLevel(logging.WARNING)
|
|
||||||
logger.setLevel(options.debug and logging.DEBUG or logging.INFO)
|
|
||||||
if not options.silent:
|
|
||||||
ch = logging.StreamHandler()
|
|
||||||
ch.setFormatter(logging.Formatter(
|
|
||||||
"%(levelname)s[%(name)s] %(message)s"))
|
|
||||||
root.addHandler(ch)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
options = parse_args()
|
|
||||||
setup_logging(options)
|
|
||||||
|
|
||||||
try:
|
|
||||||
i3 = Connection()
|
|
||||||
term = i3.get_tree().find_instanced(options.name)
|
|
||||||
if not term:
|
|
||||||
i3.command(f'exec {options.term} --name {options.name}')
|
|
||||||
tries = 5
|
|
||||||
while not term and tries:
|
|
||||||
term = i3.get_tree().find_instanced(options.name)
|
|
||||||
time.sleep(0.2)
|
|
||||||
tries -= 1
|
|
||||||
if not term:
|
|
||||||
raise RuntimeError("unable to spawn terminal")
|
|
||||||
term = term[0]
|
|
||||||
workspace = [ws for ws in i3.get_workspaces() if ws.focused][0]
|
|
||||||
ws_x = workspace.rect.x
|
|
||||||
ws_y = workspace.rect.y
|
|
||||||
ws_width = workspace.rect.width
|
|
||||||
ws_height = workspace.rect.height
|
|
||||||
width = ws_width
|
|
||||||
height = int(ws_height * options.height)
|
|
||||||
posx = ws_x
|
|
||||||
posy = ws_y
|
|
||||||
command = (f'[instance={options.name}] '
|
|
||||||
'border none,'
|
|
||||||
f'resize set {width} px {height} px,'
|
|
||||||
'scratchpad show,'
|
|
||||||
f'move absolute position {posx}px {posy}px')
|
|
||||||
logger.debug(f"QuakeConsole: {command}")
|
|
||||||
i3.command(command)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception("%s", e)
|
|
||||||
sys.exit(1)
|
|
||||||
sys.exit(0)
|
|
2
config
2
config
|
@ -152,7 +152,7 @@ bindsym Print exec --no-startup-id "flameshot gui -r | xclip -selection clipboar
|
||||||
# Quake window
|
# Quake window
|
||||||
set $quake "QuakeConsoleNeedsUniqueName"
|
set $quake "QuakeConsoleNeedsUniqueName"
|
||||||
for_window [instance=$quake title=$term] move window to scratchpad
|
for_window [instance=$quake title=$term] move window to scratchpad
|
||||||
bindsym $mod+grave exec ~/.config/i3/bin/quake --name $quake --term $term
|
bindsym $mod+grave exec --no-startup-id i3-msg -t send_tick "quake-console:$term:$quake:0.3"
|
||||||
|
|
||||||
# Random rules
|
# Random rules
|
||||||
no_focus [class="zoom" window_type="dialog"]
|
no_focus [class="zoom" window_type="dialog"]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue