sway icon indicating copy to clipboard operation
sway copied to clipboard

for_window criteria are not executed when a window's floating state changes

Open xPMo opened this issue 4 years ago • 16 comments

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).

xPMo avatar Mar 24 '21 19:03 xPMo

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.

xPMo avatar Mar 24 '21 19:03 xPMo

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.

thuck avatar Mar 25 '21 14:03 thuck

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.

xPMo avatar Mar 25 '21 14:03 xPMo

From my tests it doesn't work; maybe something specific with xwayland?

thuck avatar Mar 25 '21 14:03 thuck

I guess the problem is the floating state; the mini panel is a floating window...

thuck avatar Mar 25 '21 14:03 thuck

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!

runbmp avatar Apr 13 '21 15:04 runbmp

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.

spiralman avatar Apr 14 '21 22:04 spiralman

It would be cool to do something like always_for_window instead!

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.

xPMo avatar Apr 15 '21 01:04 xPMo

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).

choucavalier avatar May 25 '21 13:05 choucavalier

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"?

tusktenon avatar Jul 24 '21 18:07 tusktenon

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.

aacebedo avatar Oct 24 '21 08:10 aacebedo

Anything new here? Still not work for floating window when setting the opacity for_window [ floating] opacity set 0.5

forestchen1224 avatar Oct 12 '23 01:10 forestchen1224

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 disable is used in for_window rule)
    • See this screenshot for what this looks like: swappy-20231112_131500
    • 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 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: swappy-20231112_133123 swappy-20231112_133331

trinitronx avatar Nov 12 '23 20:11 trinitronx

Is this a pretty much dead project nowadays? I still have these issues.

YardQuit avatar Dec 12 '23 09:12 YardQuit

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 disable` is used in `for_window` rule)
  * See this screenshot for what this looks like: ![swappy-20231112_131500](https://private-user-images.githubusercontent.com/122524/282323554-b95d9a19-b99c-41e8-abd1-e5d89a52511f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTc2ODM1NjIsIm5iZiI6MTcxNzY4MzI2MiwicGF0aCI6Ii8xMjI1MjQvMjgyMzIzNTU0LWI5NWQ5YTE5LWI5OWMtNDFlOC1hYmQxLWU1ZDg5YTUyNTExZi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNjA2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDYwNlQxNDE0MjJaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0wYjJmMjg2MWE2OTUzNGRiZjk0Y2ViYjljZGZjMzcwYzE0Y2Y0Njc4NzViOWE0YjYwMjAzYjJlYzM5ZTM5OWYyJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.Dcy8nAWTAuL9c5n9nVLV-1738NqrfmC3rMRPog6PRk0)
  * 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: ![swappy-20231112_133123](https://private-user-images.githubusercontent.com/122524/282324005-84d93ee0-33eb-441c-bee5-3faa6117c566.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTc2ODM1NjIsIm5iZiI6MTcxNzY4MzI2MiwicGF0aCI6Ii8xMjI1MjQvMjgyMzI0MDA1LTg0ZDkzZWUwLTMzZWItNDQxYy1iZWU1LTNmYWE2MTE3YzU2Ni5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNjA2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDYwNlQxNDE0MjJaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1mZmZiMzIwYjdiYWYyNWUyNDI0MTk3MmU3MzdmOWU4MzQxMzczOGVkMDE1YmVjNDczNTk5OGYxZWY1OTc1NTYwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.s-OXg8YyxQ6DEB6B9O_qeNG9BHbS4tg6C80Cvc2FhCs)
      ![swappy-20231112_133331](https://private-user-images.githubusercontent.com/122524/282324088-8753f522-242a-48a7-9d3d-a882ff04743f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTc2ODM1NjIsIm5iZiI6MTcxNzY4MzI2MiwicGF0aCI6Ii8xMjI1MjQvMjgyMzI0MDg4LTg3NTNmNTIyLTI0MmEtNDhhNy05ZDNkLWE4ODJmZjA0NzQzZi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNjA2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDYwNlQxNDE0MjJaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT01YzZkYTBiMGEzZGFhYzQzMGIxNmJjODNjYjdiNzkxYWJhODFlNTc1NDNkZWY4MzExNjNmZDA4YWZmOTgxZDFjJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.8Oo9lkIjj7N6G_wjwLwZxoKRRTyFx47mYzvWb75c_OE)

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.

SoumyaRanjanPatnaik avatar Jun 06 '24 14:06 SoumyaRanjanPatnaik

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-3
  • extra/wlroots: 0.17.3-1
  • extra/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

trinitronx avatar Jun 08 '24 16:06 trinitronx

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.

trinitronx avatar Feb 28 '25 07:02 trinitronx

It would also be useful if we could configure the timeout that for_window keeps watching for changes.

laktak avatar Feb 28 '25 10:02 laktak

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 csd with 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_id criteria is used and title criteria is unused.

    Contrary to my last three points, matching a window with only app_id will 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_id criteria
  • 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).

mervn avatar Aug 14 '25 05:08 mervn