sway
sway copied to clipboard
for_window criteria are not executed when a window's floating state changes
Running Sway and i3 with the following config:
exec alacritty
for_window [floating] border pixel 2
for_window [tiling] border normal 2
i3 will change the border when changing the windows floating state. Sway will not (but will if the window title changes).
$ swaymsg -t get_version | jq -r .human_readable
1.6-rc2-a9563a37 (Mar 24 2021, branch 'makepkg')
Related: PR #5323, possibly others. There is a comment on that PR which is incorrect, as i3 does execute for_window criteria on window state changes. Example from the i3 user docs:
# makes the window floating as soon as I change
# directory to ~/work
for_window [title="x200: ~/work"] floating enable
However, both i3 and Sway will only apply each criteria once per window (which makes something like my sample config not as useful in either i3 or Sway).
Basically, for_window criteria are kind of broken and unintuitive in i3 anyway (trigger on window mapping or state change, but only if that criteria hasn't yet been triggered for the given view).
Also ref i3/i3#4346
I understand some reasoning why criteria are only applied once: Suppose a title-based criteria is triggered (like the one in the i3 docs), and then a user manually re-tiles the window. If the title is re-set (to the same title), the window will not re-float because of the only-once rule.
Allowing the trigger to happen when the title changes would be very good, and would help with some softwares like slack that set a title and modify it a little later.
Slack will create a window with the title Slack and a little later will change that to another pattern.
For example for calls, slack will create a mini panel window; that window will contain the title Slack and after a very short time it will change to mini panel, but at that point it is to late to apply the criteria.
Allowing the trigger to happen when the title changes would be very good, and would help with some softwares like slack that set a title and modify it a little later.
It already does. That case should already work. This issue is that i3 also triggers on floating state, while Sway does not.
From my tests it doesn't work; maybe something specific with xwayland?
I guess the problem is the floating state; the mini panel is a floating window...
I have the same issue with chromium screen sharing. The title is changed after the fact, so I can't use for_window (that I can tell). It would be cool to do something like always_for_window instead!
I'm having a similar problem, also with Chrome (but, I suspect this is common to any application that has tabs internally and re-titles the window to match the tab title):
I want Chrome to have inhibit_idle when I'm using Google Meet, but not for any other tabs. If I do:
for_window [class="Google-chrome" title="^Meet - .* - Google Chrome"] inhibit_idle visible
for_window [class="Google-chrome" title="^(?!Meet)"] inhibit_idle none
My desired workflow is to join a meeting, move the tab to a new window (at which point I want inhibit_idle) then close the window (and nothing should have inhibit_idle anymore). It works correctly once, but, after that, the inhibit_idle gets "stuck" on the original chrome window, even if meet isn't there.
It'd be nice to have a way to design "reactive" settings like that, without having to spawn off another process to watch for changes.
It would be cool to do something like
always_for_windowinstead!
It'd be nice to have a way to design "reactive" settings like that, without having to spawn off another process to watch for changes.
I would love to see such an extension! However, this issue is about the existing i3 compatibility wrt floating state changes.
Looking forward to this being fixed. Currently I cannot set the border to be different for floating windows than for tiled windows (for windows that are initially tiled and that I change to floating).
I think I have a related issue. For many windows (browsers, terminals, etc.), I want them to tile by default, but I also float them pretty frequently, and would like to specify their floating size. Since criteria are only executed once,
for_window [app_id="firefox" floating] resize set 50 ppt 90 ppt
doesn't work, because the window was initially tiled. Similarly,
for_window [app_id="firefox"] floating enable, resize set 50 ppt 90 ppt
works once, but if I tile the window and then re-float it, my size settings are lost.
Absent some form of persistent criteria checking, is there some other way I can specify a "default-size-when-floating"?
Got a similar issue. I am using Ferdi and wanted to get its window floating everytime it appears. The first time the app is started, its window is made floating as intended by the criteria. However if I close the window and reopen it by clicking the traybar icon, the window does not float anymore, the criteria is not triggered anymore even if the class or instance of he window didn't change.
Anything new here?
Still not work for floating window when setting the opacity
for_window [ floating] opacity set 0.5
Allowing the trigger to happen when the title changes would be very good, and would help with some softwares like slack that set a title and modify it a little later.
This may also affect some browser extension windows. I'm not 100% sure, but could be related due to some rules applying on floating state change, sometimes... or else maybe this is another bug due to the additional redraw problems complicating it? I tested this with LastPass extension in Firefox (native sway windows) with the following setting checked: "Open extension pages (like this one) in new dialog". This setting causes most LastPass windows to open as full windows instead of browser tabs. The idea here was to set certain LastPass windows based on title to floating & specific sizes. However, the actual behavior of Sway seemed very buggy.
The for_window rules tested were:
for_window [app_id="firefox" title="Extension.*LastPass.*(?:Reprompt|YubiKey Multifactor Authentication).*"] floating enable
for_window [app_id="firefox" title="Extension.*LastPass.*Reprompt.*"] resize set width 460px height 460px
for_window [app_id="firefox" title="Extension.*LastPass.*YubiKey Multifactor Authentication.*"] resize set 800 300
for_window [app_id="firefox" title="Extension.*LastPass.*Edit secure note.*"] resize set 600 400
# The following rule could also be "floating enable",
# with similar yet slightly different buggy behavior
for_window [app_id="firefox" title="Extension.*LastPass.*Edit.*"] floating disable
The result is very buggy behavior, which could indicate some race condition with when title is set (or simply some coordinates or sizes are wrong on redraw?)
- Some windows float and resize as they are supposed to, but the resize & float seem delayed
- Some windows don't float or resize correctly, and the inner window content looks as if it's drawn incorrectly
- Only the very bottom left of the window contents are drawn
- Yet they're drawn inside a small square "viewport" that's packed into the upper top left of the Sway window (when
floating disableis used infor_windowrule) - See this screenshot for what this looks like:
- When this happens, toggling the window floating / non-floating forcibly using keybindings usually seems to force Sway to run the rules & the window redraws properly.
- Notice that in this case, Sway does seem to apply rules on floating state change! :shrug: :thinking:
- When
floating enableis used instead for the "title="Extension.*LastPass.*Edit.*"rule:- Similar to the above behavior, except the initial floating window is very small (seems to be only
95 x 95pixels) - After moving the mouse, then the
600 x 400pixel resize occurs - However, the parent Firefox window (the one which launched the LastPass "Edit" window) is now drawn incorrectly
- See these screenshots for this behavior:
- Similar to the above behavior, except the initial floating window is very small (seems to be only
Is this a pretty much dead project nowadays? I still have these issues.
Allowing the trigger to happen when the title changes would be very good, and would help with some softwares like slack that set a title and modify it a little later.
This may also affect some browser extension windows. I'm not 100% sure, but could be related due to some rules applying on floating state change, sometimes... or else maybe this is another bug due to the additional redraw problems complicating it? I tested this with LastPass extension in Firefox (native sway windows) with the following setting checked: "
Open extension pages (like this one) in new dialog". This setting causes most LastPass windows to open as full windows instead of browser tabs. The idea here was to set certain LastPass windows based on title to floating & specific sizes. However, the actual behavior of Sway seemed very buggy.The
for_windowrules tested were:for_window [app_id="firefox" title="Extension.*LastPass.*(?:Reprompt|YubiKey Multifactor Authentication).*"] floating enable for_window [app_id="firefox" title="Extension.*LastPass.*Reprompt.*"] resize set width 460px height 460px for_window [app_id="firefox" title="Extension.*LastPass.*YubiKey Multifactor Authentication.*"] resize set 800 300 for_window [app_id="firefox" title="Extension.*LastPass.*Edit secure note.*"] resize set 600 400 # The following rule could also be "floating enable", # with similar yet slightly different buggy behavior for_window [app_id="firefox" title="Extension.*LastPass.*Edit.*"] floating disableThe result is very buggy behavior, which could indicate some race condition with when
titleis set (or simply some coordinates or sizes are wrong on redraw?)* Some windows float and resize as they are supposed to, but the resize & float seem delayed * Some windows don't float or resize correctly, and the inner window content looks as if it's drawn incorrectly * Only the very bottom left of the window contents are drawn * Yet they're drawn inside a small square "viewport" that's packed into the upper top left of the Sway window (when `floating disable` is used in `for_window` rule) * See this screenshot for what this looks like:  * When this happens, toggling the window floating / non-floating forcibly using keybindings usually seems to force Sway to run the rules & the window redraws properly. * **Notice that in this case, Sway _does_ seem to apply rules on floating state change!** 🤷 🤔 * When `floating enable` is used instead for the "`title="Extension.*LastPass.*Edit.*"` rule: * Similar to the above behavior, except the initial floating window is very small (seems to be only `95 x 95` pixels) * After moving the mouse, then the `600 x 400` pixel resize occurs * However, the parent Firefox window (the one which launched the LastPass "Edit" window) is now drawn incorrectly * See these screenshots for this behavior:  
I can confirm this. I think it might be useful to create a new issue to gain some traction since the problem that you've described seems different from what is written by OP.
For what it's worth: I have updated to Manjaro "unstable", and have not seen my particular window resize drawing problem occurring now.
My system is now running the following package versions:
extra/sway:1:1.9-3extra/wlroots:0.17.3-1extra/wlr-protocols:r106.2b8d433-1
It looks like sway 1.9 release says that there have been changes to the rendering code, using the new wlroots rendering API. So, maybe this fixed something w.r.t. these window resize + redraw race conditions?
:crossed_fingers: I'm hoping that things actually stay more stable this way, and so far this has been the case! :sweat_smile: In case the issue re-occurs, I will probably file a separate bug report as suggested by @SoumyaRanjanPatnaik
After some recent updates, part of the problem described here has come back. New LastPass Firefox window stays in tiled mode, taking up half the screen until focus changes and then it snaps into focused mode with size as configured above. Sometimes the window auto-closes before I can re-enter the LastPass master password. At least the buggy window size issue appears resolved. In other words: The buggy window contents draw issue is fixed.
Now it's just that the window rules are not applying properly when it first appears. I suspect a race condition on the window title match causing the configured rules to not apply initially. Possibly due to the page load updating the title asynchronously, happening after the window match rules are applied. A new manual focus change event seems to trigger the rules after the title has been updated.
The affected system is currently running:
| Package name | Version | Arch Linux repo/package |
|---|---|---|
sway |
1:1.10.1-2 |
extra/sway |
wlroots |
0.18.2-1 |
extra/wlroots |
wayland-protocols |
1.41-1 |
extra/wayland-protocols |
Affected windows are all from Firefox, running natively under Wayland/Sway (not xwayland). Easy to reproduce with LastPass Firefox extension and configs above.
It would also be useful if we could configure the timeout that for_window keeps watching for changes.
I have reproduced what @trinitronx has reported ; and would like to include some observations:
-
When a criteria-matched extension window (i.e LastPass extension) is focused, the Firefox application becomes unfocused.
This is in contrast with a criteria-matched Picture-in-Picture window; which properly transforms and causes the Firefox application to become focused_inactive.
-
This criteria-matched extension window will not transform until the window-header is crossed.
When the header (i.e section that contains the window-title) is crossed by the cursor, the window properly transforms. Consequently, if there is no window-header (i.e
border none) it will not transform at all ! -
A criteria-matched window will silently fail when it contains a non-applicable transformation.
This was discovered when trying to use
border csdwith Firefox sub-windows. It may be relevant, as some internal transformation may initially fail (silently) ; and when attempting transformations again (i.e window-header is crossed) will not fail and allow the window to properly transform. -
A criteria-matched window properly transforms when the
app_idcriteria is used andtitlecriteria is unused.Contrary to my last three points, matching a window with only
app_idwill always properly transform the window without any intervention. This, however, is not a viable configuration - as carving out the difference between Firefox extensions and main windows leads to an unmaintainable heuristic.
I have not read the source in any capacity, but I am assuming this is caused by one of:
- A race-condition between criteria-parsing and window-focus-change
- GTK using an obscure/older Wayland API to open extension windows, which only parses the
app_idcriteria - GTK using an obscure/older Wayland API to open extension windows, which does not setup the environment properly - leading to an internal transformation initially failing (silently)
The affected system is currently running:
| Package name | Version | Arch Linux repo/package |
|---|---|---|
sway |
1:1.11 |
extra/sway |
wlroots |
0.19 |
extra/wlroots |
wayland-protocols |
1.45 |
extra/wayland-protocols |
Affected windows are all from Firefox, running natively under Wayland (no Xwayland).