18

I want to open a programme in a floating window. I tried exec emacsclient -c ; floating enable, but that made the window that was active before float, not the new window.

5 Answers 5

20

This is how I did it for my Galculator application:

In my i3 config file ~/.config/i3/config I added the next line:

for_window [class="Galculator" instance="galculator"] floating enable

To find out what goes into class="..." and instance="..." for your application, type xprop in the terminal, press enter, then click on the window you want to float. This will display the window properties of your application. You will find the information at the bottom under WM_CLASS(STRING)="instance", "Class".

1
  • 4
    This is fine if we want all windows of that class to float. I usually find that I don't.
    – Raphael
    Commented Oct 9, 2018 at 17:17
7

The proper way to make the currently focused window float in i3 is to run

i3-msg floating enable

This is what your config line does.

The problem now is that i3-msg runs before the window is in focus (if it even grabs focus). Peter O. explains over here how to get a window in focus based on its PID. We can use this as such:

our_application &
pid="$!"

# Wait for the window to open and grab its window ID
winid=''
while : ; do
    winid="`wmctrl -lp | awk -vpid=$pid '$3==pid {print $1; exit}'`"
    [[ -z "${winid}" ]] || break
done

# Focus the window we found
wmctrl -ia "${winid}"

# Make it float
i3-msg floating enable > /dev/null;

# Move it to the center for good measure
i3-msg move position center > /dev/null;

# Wait for the application to quit
wait "${pid}";

Nota bene:

  • If the application does grab focus by itself, it may be sufficient to just wait for that to happen. See here for ways to determine the currently focused window.
  • I didn't work through it, but it should be possible to extend the script to return focus to where it was before we changed it.
  • wmctrl can not always figure out the PID for all windows; ImageMagick's display always has PID 0 in its listing, for example. See here for modified approach that uses the window title.
  • Wrapping the salient parts of above solution in a script, it should be possible to write something like

    exec our_command; grab_focus; floating enable
    

    in the i3 config.

5

I would like to sum up HubbleTs post with some other dirty workarounds added information:


TLDR: Append && i3-msg "[id=$(xdotool getactivewindow)] floating enable" to your shortcut definition (requires xdotool). E.g. bindsym $mod+button exec program && i3-msg "[id=$(xdotool getactivewindow)] floating enable"


You can set up rules for all windows that match a list of criteria that can be set up within your i3-config or equivalently send using i3-msg.

The syntax is for_window [ criteria ] command. You can read more about it here. If you want it to work only on a single window, you might ensure uniqueness of your criteria.

There is not just

class

Compares the window class (the second part of WM_CLASS). Use the special value focused to match all windows having the same window class as the currently focused window.

instance

Compares the window instance (the first part of WM_CLASS). Use the special value focused to match all windows having the same window instance as the currently focused window.

but way more, like title or id:

title

Compares the X11 window title (_NET_WM_NAME or WM_NAME as fallback). Use the special value __focused__ to match all windows having the same window title as the currently focused window.

id

Compares the X11 window ID, which you can get via xwininfo for example.

Assuming emacsclient to be a command line program, you could hence add

for_window [ title="uniquetitle" ] floating enable

to your i3 config and open your favorite terminal using

termite -e emacsclient -t uniquetitle

and it would directly open in floating mode.

If it is not a command line program and has no title options, you could play around with the other criteria or e.g. (using xdotool and i3-msg):

bindsym $mod+button exec program && xdotool getactivewindow set_window --name uniquetitle

or less dirty

bindsym $mod+t exec program && i3-msg "[id=$(xdotool getactivewindow)] floating enable"
1
  • 1
    This doesn't work, the "&&" waits for the first half (the exec) to complete before it runs the second half (the floating enable on the current window). What actually happens is that the new program window is opened, and once it's closed the window focus returns to is made floating. Adding --no-startup-id also doesn't solve that issue.
    – mtalexan
    Commented Feb 4, 2020 at 17:08
2

Was searching for a way to have a application always start in tiling but at the same time have a way to open it in floating (without changing all the other instances of this app beeing send to floating).

Combining Adaephon-R's suggestion from reddit and Suuuehgi's answer on this question the easiest (and most stable for me) solution I found is using the WM_CLASS(STRING) of the window-property and setting the instance field by passing the --class floating (or similar) parameter to the desired app.

in my .i3/config:

# start a terminal (alacritty)
bindsym $mod+Return exec --no-startup-id alacritty
# start a terminal in floating mode
bindsym $mod+Shift+Return exec --no-startup-id alacritty --class floating

# enable startup in float from exec by setting the x11 class to floating
# many apps support '--class floating' for setting the x11 class (the instance get renamed)
for_window [class="floating"] floating enabled move position center

As the result I can open my terminal-sessions with

  • $mod+Return while tiling
  • $mod+Shift+Return while floating
1
  • 1
    For xterm you need -class floating, like bindsym $mod+Shift+Return exec xterm -class floating Commented Oct 18, 2023 at 10:06
0

A small tweak to termnml's answer made it work for me. The full working result now reads:

bindsym $mod+Shift+Return exec --no-startup-id urxvt --class floating
for_window [class="floating"] floating enabled
1
  • Welcome to the site. If you want to comment on another answer, please don't post this as an answer - the answer section is only intended for definitive solutions to the original problem. Once you have enough reputation, you will be able to comment on other people's posts. In the meantime, consider submitting an edit suggestion if you think that you can improve the other answer.
    – AdminBee
    Commented Jan 3, 2023 at 14:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .