New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add split events to RPC API #3542

memeplex opened this Issue Dec 4, 2018 · 3 comments


None yet
3 participants

memeplex commented Dec 4, 2018

I'm submitting a…

[ ] Bug
[x] Feature Request
[ ] Documentation Request
[ ] Other (Please describe in detail)

Current Behavior

There is no way to catch a split event using the IPC API. A compelling use case is to be able to implement rules for non-leaf containers, short of having builtin support for them, as was discussed in #3343.

Desired Behavior

To avoid adding a new type of event, I suggest to simply report a split change for window event. This event already includes the window's container. I'm not 100% sure it covers all cases though.


  • i3 version 4.16 (2018-11-04)

Output of i3 --moreversion 2>&-:

Binary i3 version:  4.16 (2018-11-04) © 2009 Michael Stapelberg and contributors
Running i3 version: 4.16 (2018-11-04) (pid 10832) abort…)
Loaded i3 config: /home/carlos/.config/i3/config (Last modified: Tue 04 Dec 2018 03:02:49 PM -03, 430 seconds ago)

The i3 binary you just called: /usr/bin/i3
The i3 binary you are running: i3
# General settings
set $mod Mod4
floating_modifier $mod
font pango:DejaVu Sans Bold 10
title_align center
default_border normal 1
hide_edge_borders both
workspace_auto_back_and_forth yes
set $nexec exec --no-startup-id

# Theme
set $bg #13191c
set $border #101619
set $fg #83898c
set $fg_high #cfd7d3
set $fg_urg #cc6666
#                       Border  Background Text     Indicator Child border
client.focused          $border $bg        $fg_high $fg       $border
client.focused_inactive $border $bg        $fg      $fg       $border
client.unfocused        $border $bg        $fg      $fg       $border
client.urgent           $border $bg        $fg_urg  $fg       $border
client.placeholder      $border $bg        $fg      $fg       $border
client.background       $border

# App shortcuts
bindsym $mod+l $nexec emacsclient -c
bindsym $mod+Control+l exec xfce4-terminal
bindsym $mod+Shift+l exec firefox
bindsym $mod+Mod1+l exec spotify
bindsym $mod+grave $nexec rofi -no-fixed-num-lines -location 7 -show window -yoffset -25
bindsym $mod+Return $nexec "rofi -location 7 -combi-modi drun,run -show combi -yoffset -25"
bindsym $mod+Control+Return $nexec music toggle
bindsym $mod+Shift+Return $nexec music mute
bindsym $mod+Mod1+Return $nexec dual
bindsym $mod+Shift+Control+Return $nexec passmenu
bindsym $mod+Left $nexec music prev
bindsym $mod+Right $nexec music next
bindsym $mod+Down $nexec music down
bindsym $mod+Up $nexec music up
bindsym $mod+Shift+Down $nexec xbacklight -dec 2
bindsym $mod+Shift+Up $nexec xbacklight -inc 2
bindsym $mod+s $nexec search $(xclip -o)
bindsym $mod+Control+s $nexec search -r
bindsym $mod+o $nexec shot %c
bindsym $mod+Control+o $nexec shot %d
bindsym $mod+Shift+o $nexec shot %c 5
bindsym $mod+Mod1+o $nexec shot %d 5

# Change focus
bindsym $mod+b focus left
bindsym $mod+n focus down
bindsym $mod+Shift+Control+n focus child
bindsym $mod+p focus up
bindsym $mod+Shift+Control+p focus parent
bindsym $mod+f focus right
bindsym $mod+Tab focus right

# Change layout
bindsym $mod+w layout splith
bindsym $mod+Control+w layout splitv
bindsym $mod+a layout tabbed
bindsym $mod+Control+a layout stacking
bindsym $mod+d split h
bindsym $mod+Control+d split v
bindsym $mod+m fullscreen toggle
bindsym $mod+Control+m border toggle
bindsym $mod+space focus mode_toggle
bindsym $mod+Control+space floating toggle

# Move window
bindsym $mod+Control+b move left
bindsym $mod+Control+n move down
bindsym $mod+Control+p move up
bindsym $mod+Control+f move right
bindsym $mod+Control+1 move container to workspace 1
bindsym $mod+Control+2 move container to workspace 2
bindsym $mod+Control+3 move container to workspace 3
bindsym $mod+Control+4 move container to workspace 4
bindsym $mod+Control+5 move container to workspace 5
bindsym $mod+Control+6 move container to workspace 6
bindsym $mod+Control+7 move container to workspace 7
bindsym $mod+Control+8 move container to workspace 8
bindsym $mod+Control+9 move container to workspace 9
bindsym $mod+Control+0 move container to workspace 10

# Resize window
bindsym $mod+Control+Left resize shrink width 10 px or 5 ppt
bindsym $mod+Control+Up resize grow height 10 px or 5 ppt
bindsym $mod+Control+Down resize shrink height 10 px or 5 ppt
bindsym $mod+Control+Right resize grow width 10 px or 5 ppt

# Switch to workspace
bindsym $mod+1 workspace 1
bindsym $mod+2 workspace 2
bindsym $mod+3 workspace 3
bindsym $mod+4 workspace 4
bindsym $mod+5 workspace 5
bindsym $mod+6 workspace 6
bindsym $mod+7 workspace 7
bindsym $mod+8 workspace 8
bindsym $mod+9 workspace 9
bindsym $mod+0 workspace 10
bindsym $mod+Escape workspace next_on_output

# Move workspace
bindsym $mod+Shift+1 rename workspace to 1
bindsym $mod+Shift+2 rename workspace to 2
bindsym $mod+Shift+3 rename workspace to 3
bindsym $mod+Shift+4 rename workspace to 4
bindsym $mod+Shift+5 rename workspace to 5
bindsym $mod+Shift+6 rename workspace to 6
bindsym $mod+Shift+7 rename workspace to 7
bindsym $mod+Shift+8 rename workspace to 8
bindsym $mod+Shift+9 rename workspace to 9
bindsym $mod+Shift+0 rename workspace to 10
bindsym $mod+Mod1+p move workspace to output up
bindsym $mod+Mod1+n move workspace to output down
bindsym $mod+Mod1+f move workspace to output right
bindsym $mod+Mod1+b move workspace to output left

# Marks
bindsym $mod+Control+F1 mark --toggle 1
bindsym $mod+F1 [con_mark=1] focus
bindsym $mod+Control+F2 mark --toggle 2
bindsym $mod+F2 [con_mark=2] focus
bindsym $mod+Control+x mark --toggle x
bindsym $mod+Shift+x move window to mark x, unmark x
bindsym $mod+x swap container with mark x, unmark x

# Scratchpad
bindsym $mod+z scratchpad show
bindsym $mod+Control+z floating enable, move scratchpad
bindsym $mod+Shift+z scratchpad show, scratchpad show
bindsym $mod+e [title="^Scratch - Emacs"] scratchpad show
bindsym $mod+Control+e [title="^Scratch - Terminal$"] scratchpad show
bindsym $mod+Shift+e [title="(Gmail|Slack|WhatsApp|Reddit)"] focus
bindsym $mod+Mod1+e [class="^Spotify$"] scratchpad show
bindsym $mod+Shift+Control+e $nexec emacsclient -F '((title . "Scratch - Emacs"))' -a '' -c
bindsym $mod+Shift+Control+Mod1+e exec xfce4-terminal --title 'Scratch - Terminal'

# Control
bindsym $mod+r exec i3-input
bindsym $mod+Control+r reload
bindsym $mod+Shift+r restart
bindsym $mod+Shift+Control+Mod1+r exit
bindsym $mod+slash --release $nexec slock
bindsym $mod+Control+slash exec systemctl suspend-then-hibernate
bindsym $mod+Shift+slash exec systemctl hibernate
bindsym $mod+Shift+Control+Mod1+slash exec systemctl poweroff
bindsym $mod+Control+q kill

# Rules
for_window [class="^Pavucontrol$"] floating enable
for_window [class="^qpaeq$"] floating enable
for_window [class="^Gpick$"] floating enable
for_window [class="^Connman-gtk$"] floating enable
for_window [class="^Xmag$"] floating enable
for_window [class="^Spotify$"] floating enable, resize set 1000 700, move position center, move scratchpad, scratchpad show
for_window [title="^Htop$"] floating enable
for_window [title="^Scratch - Terminal$"] floating enable, move scratchpad
for_window [title="^Scratch - Emacs$"] floating enable, move scratchpad

# Startup
$nexec bar start
$nexec i3hacks
$nexec emacsclient -F '((title . "Scratch - Emacs"))' -a '' -c
$nexec xfce4-terminal --title 'Scratch - Terminal'
~:: uname -a
Linux archlinux 4.19.4-arch1-1-ARCH #1 SMP PREEMPT Fri Nov 23 09:06:58 UTC 2018 x86_64 GNU/Linux
~:: compton --version

@i3bot i3bot added the enhancement label Dec 4, 2018


This comment has been minimized.


Airblader commented Dec 4, 2018

Thanks for opening this issue. In general I'm not against adding events provided they're useful. A major restriction in how i3 deals with this at the moment is that events are just notifications rather than hooks, ie, you'd get the event but the split would happen nonetheless. I just want to confirm that this is what you'd expect to happen and that your usecase would still work?


This comment has been minimized.

memeplex commented Dec 4, 2018

Yes, the use case came about in a discussion we had in the referenced ticket above. The motivating issue was that title_format was not being applied to non-leaf containers (btw, I raised again this issue in the context of title_align not being applied to non-leaf containers, see comment #3540 (comment)). Then the issue was discussed in the more general setting of rules not being applied at all to non-leaf containers. Thus one proposal was, short of extending rule matching to non-leaf containers, to at least let IPC clients know about structural changes so as they could apply whatever rule they see fit. So, to sum up, the idea is not to prevent the split, but to act on the created non-leaf container.


This comment has been minimized.

memeplex commented Dec 4, 2018

As an example, this is how I'm implementing a " %title" title format because of the lack of events reporting tree structural changes:


import i3ipc

title_format = ' %title'

def format_title(i3, ev):
    is_win = isinstance(ev, i3ipc.WindowEvent)
    if is_win and ev.change == 'new':
        i3.command(f'title_format " {title_format}"')
    elif is_win or ev.payload == 'format_title':
        for n in i3.get_tree():
            if n.type == 'con' and n.nodes:
                n.command(f'title_format " {title_format}"')

i3 = i3ipc.Connection()
for ev in 'window::new', 'window::move', 'tick':
    i3.on(ev, format_title)

Then in my i3 configuration:

set $tick exec --no-startup-id i3-msg -t send_tick
bindsym $mod+d split h, $tick format_title
bindsym $mod+Control+d split v, $tick format_title

It's quite a hack but it covers all cases (I hope).

Notice that I'm catching move events since they potentially create splits, and notifying about explicit split actions via tick events. Besides the convolved nature of the solution there are a couple of additional undesirable aspects:

  1. Having to call an external command like i3-msg is not the most efficient of the solutions.

  2. Nor having to visit the entire tree in order to reformat every non-leaf container, just in case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment