WindowShade in autohide - shaded window takes focus (fvwm3)

Hello,

many many years ago, following the example shown on

I have created a file called “functions” that is read with
“Read functions”
immediately after ModulePath and ImagePath in my .fvwm2rc

8< - - - - - - - - - - - - - - - - - - - - - - - - - -

AddToFunc autohide

  • I ThisWindow ($0) Deschedule $[w.id]
  • I ThisWindow ($0) ThisWindow (shaded) Raise
  • I ThisWindow ($0) ThisWindow (shaded) WindowShade off
  • I TestRc (!Match) All ($0, !shaded) autohide_hide $1 $2

AddToFunc autohide_hide

  • I Schedule $0 $[w.id] WindowShade $1
  • I Schedule $0 $[w.id] Deschedule $[w.id]

AddToFunc StartFunction

  • I Module FvwmAuto FvwmAutohide -menter enter_handler

DestroyFunc enter_handler
AddToFunc enter_handler

  • I autohide ASW 400 N

8< - - - - - - - - - - - - - - - - - - - - - - - - - -

In fvwm2 it does what it is supposed to do, and autoshaded window “ASW” (a urxvt terminal) shades and unshades automatically depending on where my mouse is.

In fvwm3 the autohiding/unhiding behavior is the same.
However, the focus misbehaves:
When I move the mouse out of the ASW window and quickly into an xterm, for example, four things happen:

  1. ASW loses focus (o.k.)
  2. xterm gets focus for a brief moment (o.k.)
  3. ASW shades (o.k.)
  4. ASW takes focus, and xterm loses focus. (bad)

When I move the mouse from ASW and leave it on the root window for a moment and then go to the xterm, the focus is on the xterm.
Likewise, when I move the mouse from ASW quickly to one xterm (just as described above) and then to the next xterm, this second xterm will get focus.
So the WindowShade function grabs the focus from wherever it is, and once I move the mouse into another window, that window will get focus as it should.

There is a RegisterUnfocus function and I tried to insert it like so:

  • I Schedule $0 $[w.id] RegisterUnfocus $1

But that doesn’t seem to work.
How does one do this?
Or is something broken in fvwm3?

fvwm3 was freshly built from source from git (version 21 October 2022).

Thanks,
Amir

Forget what I wrote about RegisterUnfocus, which is not a predefined function - I did not understand the docs.

I’ve tried to use
!FPGrabFocus
!FPFocusByProgram
!FPFocusByFunction
DestroyFunc EWMHActivateWindowFunc
DestroyFunc UrgencyFunc
None of them make any difference.

I haven’t looked at this closely, but two thoughts.

  1. Try fvwm3 1.0.4, 1.0.3, etc, see if you can identify when the behavior changed. You can use git bisect to track down the actual commit if you have the time.

  2. You shouldn’t need to use Deschedule in your autohide_hide function, as you aren’t defining a periodic event, so it will only run once (unsure if that is getting in the way with some race condition). You still might need it in autohide due to you could be moving back to the window before the scheduled event triggered. As such you might be able to just remove the authohide_hide function altogether.

  3. You shouldn’t need to nest ThisWindow like you do, ThisWindow ($0, shaded) ... should be enough.

Thanks for looking into this!

  1. The problem occured in fvwm3 version 1.0.5.
    I’ve tried 1.0.0, 1.0.2 and 1.0.4, and they are o.k., just as fvwm2 was.
    I can’t use 1.0.4, because that version would freeze occasionally when deiconfying windows, which is rather unnerving when it happens during a teams or zoom video call ;-)

  2. If I remove Deschedule, the window erratically deshades, so I left it in.

Maybe I misunderstood, but if I remove the
+I TestRc (!Match) All ($0, !shaded) autohide_hide $1 $2
line, the function is gone, and the window remains unshaded when out of focus.

  1. ThisWindow ($0, shaded) works fine, thank you!

Amir

If you can track down the version it was broken that would help, and then file an issue on github and hopefully it can be figured out what changed. But knowing that it broke sometime after 1.0.3 does narrow things down. Look into git bisect to help with this.

As for the deschedule point, I was talking about this function.

AddToFunc autohide_hide
+ I Schedule $0 $[w.id] WindowShade $1
+ I Schedule $0 $[w.id] Deschedule $[w.id]

That second line seems pointless, and most likely doesn’t do anything. Since the first schedule isn’t creating a periodic task it should only run once, so scheduling a deschedule to stop it after it runs once (which it will do anyways) isn’t doing anything, except maybe causing a race condition. Your other Deschedule in the main autohide function is needed to stop the scheduled WindowShade from happening if focus changes before the scheduled task runs (so I can see this stopping erratic window shading), but this one here shouldn’t be needed (and could maybe causing a race condition giving you issues to make it seem like it isn’t working).

I also notice you are missing DestroyFunc in your function defintions, not required but can avoid unexpected issues of declaring the same function twice and thus adding to the definition vs creating a new one.

Thanks for the confirnation.

Removing

+ I Schedule $0 $[w.id] Deschedule $[w.id]

causes the occasional erratic behavior.

Adding
DestroyFunc autohide
DestroyFunc autohide_hide
makes no difference.

I have found a “workaround” and something that may help in narrowing down the cause:
If I remove the line

+ I ThisWindow ($0) ThisWindow (shaded) **Raise**

then the behavior is as it used to be.
Except, of course, that the whole point of the function is to unshade and raise a shaded window placed at the edge of the screen above other windows.

But I think this is a good starting point for investigation: the culprit is not WindowShade, but something in Raise.

It broke down between 1.0.4. (o.k.) and 1.0.5 (broken), but I don’t think I will find the time to test individual commits.

If anyone wants to see the behavior, all that is required is this minimal
.fvwm2rc

DestroyFunc autohide
DestroyFunc autohide_hide

AddToFunc autohide
+ I ThisWindow ($0) Deschedule $[w.id]
+ I ThisWindow ($0, shaded) Raise
+ I ThisWindow ($0, shaded) WindowShade off
+ I TestRc (!Match) All ($0, !shaded) autohide_hide $1 $2

AddToFunc autohide_hide
+ I Schedule $0 $[w.id] WindowShade $1
+ I Schedule $0 $[w.id] Deschedule $[w.id]

AddToFunc StartFunction
+ I Module FvwmAuto FvwmAutohide -menter enter_handler

DestroyFunc enter_handler
AddToFunc enter_handler
+ I autohide xterm 100 N

Style "*" FocusFollowsMouse

AddToFunc InitFunction
+	"I"	exec 	xterm

This will just start an autohiding xterm.
You can start a few urxvt or similar programs from the xterm and play with it.

Amir

Correction: it is not the Raise function, but something about the state of the window.
If I remove the Raise line, the autohide function works, but if I raise the window “manually”, it appears broken again.
Likewise, if I remove Raise from the functions, but add “StaysOnTop” to the style associated with the window, the window will grab focus.
So a raised window will grab focus when autoshaded.
When I manually shade a window, it does not grab focus.

Amir