mirror of
https://github.com/vincentbernat/i3wm-configuration.git
synced 2025-07-13 19:54:21 +02:00
More configuration
Including a Quake console and autosplit in i3-companion.
This commit is contained in:
parent
43ab22dee5
commit
a77a5e27ce
4 changed files with 173 additions and 36 deletions
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
"""Personal i3 companion
|
"""Personal i3 companion
|
||||||
|
|
||||||
This script will listen to i3 events and react accordingly. Currently,
|
This script will listen to i3 events and react accordingly.
|
||||||
it will rename workspaces using icons according to their content.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -12,9 +11,10 @@ import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import i3ipc
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from i3ipc import Connection, Event
|
||||||
|
|
||||||
logger = logging.getLogger(os.path.splitext(os.path.basename(sys.argv[0]))[0])
|
logger = logging.getLogger(os.path.splitext(os.path.basename(sys.argv[0]))[0])
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,20 +55,28 @@ def setup_logging(options):
|
||||||
# See https://fontawesome.com/v5.15/icons
|
# See https://fontawesome.com/v5.15/icons
|
||||||
application_icons = {
|
application_icons = {
|
||||||
"chromium": "",
|
"chromium": "",
|
||||||
"emacs": "",
|
"emacs": "",
|
||||||
"firefox": "",
|
"firefox": "",
|
||||||
"gimp": "",
|
"gimp": "",
|
||||||
"google-chrome": "",
|
"google-chrome": "",
|
||||||
|
"snes9x-gtk": "",
|
||||||
"spotify": "",
|
"spotify": "",
|
||||||
|
"steam": "",
|
||||||
"vbeterm": "",
|
"vbeterm": "",
|
||||||
"NOMATCH": ""
|
"NOMATCH": ""
|
||||||
}
|
}
|
||||||
|
application_icons_alone = {
|
||||||
|
application_icons[k] for k in {
|
||||||
|
"vbeterm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def application_icon(window):
|
def application_icon(window):
|
||||||
"""Get application icon for a window."""
|
"""Get application icon for a window."""
|
||||||
for attr in ('name', 'window_title',
|
for attr in ('name',
|
||||||
'window_instance', 'window_class'):
|
'window_instance',
|
||||||
|
'window_class'):
|
||||||
name = getattr(window, attr, None)
|
name = getattr(window, attr, None)
|
||||||
if name is None:
|
if name is None:
|
||||||
continue
|
continue
|
||||||
|
@ -89,6 +97,8 @@ def workspace_rename(i3, event):
|
||||||
icon = application_icon(window)
|
icon = application_icon(window)
|
||||||
if icon is not None:
|
if icon is not None:
|
||||||
icons.add(icon)
|
icons.add(icon)
|
||||||
|
if any([i not in application_icons_alone for i in icons]):
|
||||||
|
icons -= application_icons_alone
|
||||||
new_name = f"{workspace.num}:{'|'.join(icons)}"
|
new_name = f"{workspace.num}:{'|'.join(icons)}"
|
||||||
if workspace.name != new_name:
|
if workspace.name != new_name:
|
||||||
logger.debug(f"rename workspace {workspace.num}")
|
logger.debug(f"rename workspace {workspace.num}")
|
||||||
|
@ -97,18 +107,38 @@ def workspace_rename(i3, event):
|
||||||
i3.command(';'.join(commands))
|
i3.command(';'.join(commands))
|
||||||
|
|
||||||
|
|
||||||
|
def autosplit(i3, event):
|
||||||
|
"""Split on shortest side."""
|
||||||
|
window = event.container
|
||||||
|
if not window.rect:
|
||||||
|
return
|
||||||
|
if window.layout in {'stacked', 'tabbed'}:
|
||||||
|
return
|
||||||
|
height = window.rect.height
|
||||||
|
width = window.rect.width
|
||||||
|
if height > width:
|
||||||
|
layout = 'vertical'
|
||||||
|
else:
|
||||||
|
layout = 'horizontal'
|
||||||
|
window.command(f"split {layout}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
options = parse_args()
|
options = parse_args()
|
||||||
setup_logging(options)
|
setup_logging(options)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
i3 = i3ipc.Connection()
|
i3 = Connection()
|
||||||
|
|
||||||
# Rename workspace depending on what is inside
|
# Rename workspace depending on what is inside
|
||||||
for event in ('window::move', 'window::new',
|
for event in {Event.WINDOW_MOVE,
|
||||||
'window::title', 'window::close'):
|
Event.WINDOW_NEW,
|
||||||
|
Event.WINDOW_CLOSE}:
|
||||||
i3.on(event, workspace_rename)
|
i3.on(event, workspace_rename)
|
||||||
|
|
||||||
|
# Autosplit
|
||||||
|
i3.on(Event.WINDOW_FOCUS, autosplit)
|
||||||
|
|
||||||
i3.main()
|
i3.main()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("%s", e)
|
logger.exception("%s", e)
|
||||||
|
|
104
bin/quake
Executable file
104
bin/quake
Executable file
|
@ -0,0 +1,104 @@
|
||||||
|
#!/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)
|
18
config
18
config
|
@ -67,18 +67,20 @@ bindsym $mod+Shift+$left move left
|
||||||
bindsym $mod+Shift+$down move down
|
bindsym $mod+Shift+$down move down
|
||||||
bindsym $mod+Shift+$up move up
|
bindsym $mod+Shift+$up move up
|
||||||
bindsym $mod+Shift+$right move right
|
bindsym $mod+Shift+$right move right
|
||||||
|
bindsym $mod+o move container to output right
|
||||||
|
|
||||||
# resize focused window
|
# resize focused window
|
||||||
bindsym $mod+Ctrl+$left resize shrink width 10 px or 10 ppt
|
bindsym $mod+Ctrl+$left resize shrink width 10 px or 2 ppt
|
||||||
bindsym $mod+Ctrl+$down resize grow height 10 px or 10 ppt
|
bindsym $mod+Ctrl+$down resize grow height 10 px or 2 ppt
|
||||||
bindsym $mod+Ctrl+$up resize shrink height 10 px or 10 ppt
|
bindsym $mod+Ctrl+$up resize shrink height 10 px or 2 ppt
|
||||||
bindsym $mod+Ctrl+$right resize grow width 10 px or 10 ppt
|
bindsym $mod+Ctrl+$right resize grow width 10 px or 2 ppt
|
||||||
|
|
||||||
# change split orientation
|
# change split orientation
|
||||||
bindsym $mod+v split toggle
|
bindsym $mod+v split toggle
|
||||||
|
|
||||||
# enter fullscreen mode for the focused container
|
# enter fullscreen mode for the focused container
|
||||||
bindsym $mod+f fullscreen toggle
|
bindsym $mod+f fullscreen toggle
|
||||||
|
bindsym $mod+Shift+f fullscreen toggle global
|
||||||
|
|
||||||
# change container layout (stacked, tabbed, toggle split)
|
# change container layout (stacked, tabbed, toggle split)
|
||||||
bindsym $mod+s layout stacking
|
bindsym $mod+s layout stacking
|
||||||
|
@ -131,14 +133,20 @@ bindsym $mod+Shift+7 move container to workspace number $ws7
|
||||||
bindsym $mod+Shift+8 move container to workspace number $ws8
|
bindsym $mod+Shift+8 move container to workspace number $ws8
|
||||||
bindsym $mod+Shift+9 move container to workspace number $ws9
|
bindsym $mod+Shift+9 move container to workspace number $ws9
|
||||||
bindsym $mod+Shift+0 move container to workspace number $ws10
|
bindsym $mod+Shift+0 move container to workspace number $ws10
|
||||||
|
bindsym $mod+Shift+o move workspace to output right
|
||||||
|
|
||||||
# reload/restart
|
# reload/restart
|
||||||
bindsym $mod+Shift+c reload
|
bindsym $mod+Shift+c reload
|
||||||
bindsym $mod+Shift+r restart
|
bindsym $mod+Shift+r restart
|
||||||
|
|
||||||
# Lock screen
|
# Lock screen and print screen
|
||||||
bindsym XF86ScreenSaver exec --no-startup-id xset s activate
|
bindsym XF86ScreenSaver exec --no-startup-id xset s activate
|
||||||
bindsym $mod+Delete exec --no-startup-id xset s activate
|
bindsym $mod+Delete exec --no-startup-id xset s activate
|
||||||
|
bindsym Print exec --no-startup-id "flameshot gui -r | xclip -selection clipboard -t image/png"
|
||||||
|
|
||||||
|
set $quake "QuakeConsoleNeedsUniqueName"
|
||||||
|
for_window [instance=$quake] move window to scratchpad
|
||||||
|
bindsym $mod+grave exec ~/.config/i3/bin/quake --name $quake --term $term
|
||||||
|
|
||||||
# start stuff
|
# start stuff
|
||||||
exec_always --no-startup-id systemctl --user start --no-block wallpaper.service
|
exec_always --no-startup-id systemctl --user start --no-block wallpaper.service
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[colors]
|
[colors]
|
||||||
background = #a0000000
|
background = #c0000000
|
||||||
foreground = #eaeaea
|
foreground = #eaeaea
|
||||||
highlight = #4c7899
|
highlight = #4c7899
|
||||||
|
|
||||||
|
@ -21,16 +21,16 @@ module-margin = 1
|
||||||
background = ${colors.background}
|
background = ${colors.background}
|
||||||
foreground = ${colors.foreground}
|
foreground = ${colors.foreground}
|
||||||
|
|
||||||
font-0 = Hack:style=Regular:size=10;2
|
font-0 = Iosevka:style=Regular:size=10;2
|
||||||
font-1 = Font Awesome 5 Pro:style=Solid:size=10;2
|
font-1 = Font Awesome 5 Pro:style=Solid:size=10;2
|
||||||
font-2 = Font Awesome 5 Brands:style=Regular:size=10;2
|
font-2 = Font Awesome 5 Brands:style=Regular:size=10;2
|
||||||
|
|
||||||
modules-left = i3
|
modules-left = i3
|
||||||
modules-right = date
|
modules-center = date
|
||||||
|
|
||||||
[bar/primary]
|
[bar/primary]
|
||||||
inherit = bar/secondary
|
inherit = bar/secondary
|
||||||
modules-center = cpu memory pulseaudio ethernet wlan battery
|
modules-right = cpu memory pulseaudio battery ethernet wlan
|
||||||
|
|
||||||
[module/i3]
|
[module/i3]
|
||||||
type = internal/i3
|
type = internal/i3
|
||||||
|
@ -89,32 +89,27 @@ type = internal/date
|
||||||
interval = 2
|
interval = 2
|
||||||
date = %a %d.%m
|
date = %a %d.%m
|
||||||
time = %H:%M
|
time = %H:%M
|
||||||
label = %date% %time%
|
label = %date% %time%
|
||||||
|
|
||||||
[module/battery]
|
[module/battery]
|
||||||
type = internal/battery
|
type = internal/battery
|
||||||
battery = BAT0
|
battery = BAT0
|
||||||
adapter = ADP1
|
adapter = ADP1
|
||||||
full-at = 99
|
|
||||||
interval = 5
|
interval = 5
|
||||||
format-charging = <animation-charging> <label-charging>
|
format-charging = <label-charging>
|
||||||
label-charging = %percentage: 2%%
|
label-charging = %percentage: 2%%
|
||||||
format-discharging = <animation-discharging> <label-discharging>
|
format-discharging = <ramp-capacity> <label-discharging>
|
||||||
label-discharging = %percentage: 2%%
|
label-discharging = %percentage: 2%%%{F-}
|
||||||
format-full = <label-full>
|
format-full = <label-full>
|
||||||
label-full =
|
label-full =
|
||||||
animation-charging-0 =
|
ramp-capacity-0 = %{F#ff0000}
|
||||||
animation-charging-1 =
|
ramp-capacity-1 =
|
||||||
animation-charging-2 =
|
ramp-capacity-2 =
|
||||||
animation-charging-3 =
|
ramp-capacity-3 =
|
||||||
animation-charging-4 =
|
ramp-capacity-4 =
|
||||||
animation-charging-framerate = 1000
|
ramp-capacity-5 =
|
||||||
animation-discharging-0 =
|
ramp-capacity-6 =
|
||||||
animation-discharging-1 =
|
ramp-capacity-7 =
|
||||||
animation-discharging-2 =
|
|
||||||
animation-discharging-3 =
|
|
||||||
animation-discharging-4 =
|
|
||||||
animation-discharging-framerate = 1000
|
|
||||||
|
|
||||||
[module/pulseaudio]
|
[module/pulseaudio]
|
||||||
type = internal/pulseaudio
|
type = internal/pulseaudio
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue