Revert focus to previous window

I’m working on a kiosk-like configuration: a computer for displaying slideshows and TV picture. It needs a keyboard-driven OSD-like menu for setting certain options.

Because the menu has been written in ruby/tk and the computer isn’t very fast, it has a considerable load time. I made the process work all the time and I use FVWM to show and hide its window. Works very nicely but I have one issue with focus.

The menu application has a list of settings and opens a dialog window for each. After closing the dialog the focus doesn’t come back to the parent window. I have to use mouse to set it (either enter window for SloppyFocus or click for ClickToFocus).

What could you recommend me to solve the problem? I also understand that I might need to unfocus the menu window in HideWindow function once focus works as I want it to.

Here’s my config:

Style "*" !Title, !Borders, NeverFocus
Style "*config_menu*" Borders, NeverFocus, CenterPlacement, StaysOnBottom

DestroyFunc ShowConfigMenu
AddToFunc ShowConfigMenu
 + I Key Escape A A -
 + I Style "*config_menu*" StaysOnTop, Focus
 + I All ("*config_menu*") Function ShowWindow
 + I UpdateStyles

DestroyFunc HideConfigMenu
AddToFunc HideConfigMenu
 + I All ("*config_menu*") Function HideWindow
 + I Style "*config_menu*" StaysOnBottom
 + I Key Escape A A ShowConfigMenu

DestroyFunc ShowWindow
AddToFunc ShowWindow
 + I WindowStyle SloppyFocus StaysOnTop
 + I Layer 0 6
 + I UpdateStyles
 + I Focus

DestroyFunc HideWindow
AddToFunc HideWindow
 + I DestroyWindowStyle
 + I Layer 0 2

Key Escape A A ShowConfigMenu

Module FvwmCommandS

As you can see I use various combinations of NeverFocus (mainly for mplayer and xpdf windows) and SloppyFocus (chosen randomly :slight_smile:).

I also am aware that these functions probably might be written in a much better way - feel free to suggest better solutions ;]

Assuming you want to check for that whenever these dialog windows are closed, you’d need to use FvwmEvent:

DestroyModuleConfig FE-AlwaysFocus:*
*FE-AlwaysFocus: destroy_window "PointerWindow (!Focused) Prev (AcceptsFocus) Focus"

AddToFunc StartFunction I FvwmEvent FE-AlwaysFocus

– Thomas Adam

Well, I guess that this is a valid way to achieve the result.

Based on your code I use the lines below and it works fine, including occasional third-level windows.

DestroyModuleConfig FE-AlwaysFocus:*
*FE-AlwaysFocus: destroy_window "None (Focused) Next (AcceptsFocus) Focus"

Thanks for help.

Marcin Simonides

It’s the only way to achieve the result.

But this is, of course, wrong. What you’re saying here, in using:

None (Focused) Next (AcceptsFocus) Focus

is: “If no window called Focused exists, to then focus the next window in the window ring”. Thus, if it happens to be the case that when you close one of your dialogue windows that the pointer happens to focus a window, it will then switch focus regardless.

I suggested PointerWindow for a reason. Use it.

And whilst you’re at it, you might want to see: linuxgazette.net/128/adam1.html

– Thomas Adam

According to FVWM manpage (I’m using version 2.5.* BTW, forgot to mention this important detail), section “Conditions”:

so, in this context, I understand the command as: “if there is no window with focus, focus the next window that accepts focus”… unless Focused in my command should somehow be escaped, quoted or otherwise distinguished from window names.

But doesn’t it check whether the window under mouse pointer has focus and then act accordingly?

Perhaps I didn’t clearly state it previously: the user is expected to interact only with the use of keyboard. The pointer sits in an arbitrary place on the screen (usually somewhere in a corner) and is hidden by unclutter.

So let’s assume that it’s in a corner and that’s over MPlayer’s full-screen window. MPlayer has style NeverFocus and the condition is always true. This means that “Next (AcceptFocus) Focus” is always being called.

No – that’s misleading. None is special in that it acts on window name, class or resource.

Right.

No – MPlayer has Style NeverFocus which means any attempt at sending events to it (by means of focus) will be ignored. Again though, unless you’ve redefined WindowListFunc, the mouse pointer is going to be warped to various windows all over the shot when you come to focus them by the keyboard – this is fine. If you expect to be closing windows just through they keyboard alone, that too is fine in which case you can redefine the FvwmEvent condition to perhaps use:

ThisWindow (!Focused, !HasPointer) Next (AcceptsFocus) Focus

But this will mislead you to give erroneous results. I don’t see anything wrong with the original proposal at all.

– Thomas Adam

Ok, it seems that all these conditions and commands are much more convoluted than one expects after skimming the manpage :slight_smile:
I’ve got everything working fine but below are a few more questions that answers to may help me understand what’s actually happening, please bear with me.

I can’t find it in any places in the docs, is it only implied by something? Or am I missing the obvious?

But it does mean that MPlayer’s windows never meet the Focused condition, right?

No, I have only disabled the Alt-Tab shortcut.

Ok, it works, I’m using it, though I’m not 100% sure I understand it (which I’m usually uncomfortable with :slight_smile: ). Maybe I will understand in time.

No – maybe my phrasing is – what you’re asking None to do when you say:

None (Focused)

Is to find a window called Focused – hence you could use ThisWindow (!Focused) instead, as I have suggested, although see PointerWindow – which operates in the content of the window under the pointer, or not at all if no window is under the pointer (this doesn’t include the root window.)

– Thomas Adam