It works well for GoToPage because of the universal variable $0 $1 GotoPage $0 $1, but not for WindowId. It gives a wrong ID number by adding the page numbers (11 digits instead of 9 digits).
Example window focus on Page 1 0 Wrong output: WindowId 100x6002575 Focus
I tested on FvwmConsole, this works: WindowId 0x6002575 Focus
Limited SOLUTION with separate variables for Page and ID:
+ I Current InfoStoreAdd lastFocusPage $[page.nx] $[page.ny]
+ I Current InfoStoreAdd FocusID $[w.id]
+ I GotoPage $0 $1
+ I WindowId $[infostore.FocusID] Focus
Best SOLUTION would be with universal variables $0 $1 $2 but something is missing with $2.
+ I Current InfoStoreAdd lastFocusPage $[page.nx] $[page.ny] $[w.id]
+ I GotoPage $0 $1
+ I WindowId $2 Focus
From the looks of it you are separating lastFocusPage, $[page.nx] and $[page.ny] with a space. These are not supposed to be separated, and will not work as I intended if they are separated. My solution stores the window ID in different variables depending on the page you are on.
With your bottom solution, you would have to pass the ID of the window to be focus and this would just be unnessecarily complicated.
$0 is the first parameter passed, $1 is the second and $2 is the third and so on
Your wrong window ID comes from the page numbers being handled as input to InfoStoreAdd. What you want is for the page numbers to be expanded as part of the variable name instead. This is why there shouldn’t be spaces inbetween lastPageFocus, $[page.nx] and $[page.ny]. Spaces might work if you use quotes, but I haven’t tested this
I don’t think variable names can have spaces, and you can only store a single value in an infostore variable, that is why creating a variable for each page/desk works.
I’ve seen this problem solved before, I don’t know if it was in the forms or not, but someone already setup functions using infostore to give the last active window focus when switching between pages.
You would need to make one for every direction.
Here is an example:
EdgeLeaveCommand North SwitchPage 0p -1p
EdgeLeaveCommand South SwitchPage 0p 1p
EdgeLeaveCommand West SwitchPage -1p 0p
EdgeLeaveCommand East SwitchPage 1p 0p
EdgeLeaveCommand takes the direction you leave, and the function to call. This function is then activated once the time specified by EdgeMoveDelay has gone by.
My code will have the same problem as this. If there isn’t any window in the page, the old window will retain its focus. If you want to remove the focus from the old window no matter if there is a window in the page you are going to, you could use a function for this.
I recently made a function to remove window focus from a window, then call another function and it is as follows:
DestroyFunc RemoveFocusAndCall
AddToFunc RemoveFocusAndCall
+ I Current InfoStoreAdd lastFocus $[w.id]
+ I Style $[infostore.lastFocus] NeverFocus
+ I $0 $[1-]
+ I Style $[infostore.lastFocus] ClickToFocus
It stores the window ID in a temporary called lastFocus. It then sets the style of this window to NeverFocus, which removes its focus. The next line, + I $0 $[1-], takes the first user input which is supposed to be a function, and calls it with the rest of the parameters starting from $1.
An example usage would be as follows:
RemoveFocusAndCall SwitchPage 0p -1p
or with EdgeLeaveCommand:
EdgeLeaveCommand North RemoveFocusAndCall SwitchPage 0p -1p
I think these should work together, but there is no guarantee as I haven’t used these in junction myself. From looks of it these shouldn’t be incompatible, but if you get problems try this instead:
DestroyFunc RemoveFocusAndCall
AddToFunc RemoveFocusAndCall
+ I Current InfoStoreAdd lastFocus $[w.id]
+ I Style $[infostore.lastFocus] NeverFocus
+ I Style $[infostore.lastFocus] ClickToFocus
+ I $0 $[1-]
These removes focus, then reverts the ClickToFocus style before calling the function
You would have to save that in an InfoStore variable since the new_page and new_desk events will only send the desk you moved to. Either that or store info about which window was last focused using State, and in this case you don’t really need to know what the previous page is. Next (CurrentPage, State X) will find the window you want to focus.
This State function works fine for my Xfce friends. I like it. It does the focus on any number of pages. Also, not a problem if it turns the previous window unfocused from an empty page because nobody goes to empty pages without doing anything there.
Has a slightly unstable focus when going drastically from one end of a Desk to another. Not a problem, just a sign of moving between Desks.
The function is simple and easy to understand. I copied it here below, add it at the beginning of your config.
Remember focused window in current page:
SetEnv FocusPage 0
DestroyFunc SavePageFocus
AddToFunc SavePageFocus
+ I All (CurrentPage) State $[FocusPage] False
+ I Current State $[FocusPage] True
Restore previously focused window in current page:
DestroyFunc RestorePageFocus
AddToFunc RestorePageFocus
+ I Current (CurrentPage) Break 1
+ I Next (CurrentPage, State $[FocusPage]) Focus
+ I None (CurrentPage, Focused) Prev (CurrentPage) Focus
DestroyModuleConfig FvwmEvent-FDpg:*
*FvwmEvent-FDpg: Cmd
*FvwmEvent-FDpg: new_page RestorePageFocus
*FvwmEvent-FDpg: new_desk RestorePageFocus
*FvwmEvent-FDpg: focus_change SavePageFocus
Module FvwmEvent FvwmEvent-FDpg
It keeps focus on the adjacent page of the next desk but no further distance e.g. from Desk 1 Page 1 0 to Desk 2 Page 0 0. Would be good also to fix this. Desker script in Fvwm Kise has 4 Desks, two pages each. Gets annoying with a focused email window on Desk 1 and going to search for data on an unfocused Desk 3.
It should be possible to include CurrentDesk and CurrentPageAnyDesk.
Don’t use CurrentPageAnyDesk, that is not what you want, add the new_desk event to FvwmEvent and run the exact same function.
Also, the FvwmEvent config is incorrect in the shared code, you need to use *FvwmEvent-Focus for all the configuration options (you were missing the -Focus). And then you launch it with Module FvwmEvent FvwmEvent-Focus.
Thank you @somiaj, the focus works perfectly on all pages and desks.
Note: Doesn’t work if FvwmEvent-Focus is on all configuration options. This I also understood with @thomasadam suggestion: FvwmEvent-Focus: Cmd. -Focus is just any name to differentiate from other FvwmEvent. Only for Cmd.
so that multiple FvwmEvent’s can then be defined for other Events. It might be the case that a user has other events scheduled which would get overriden with the binding to just “FvwmEvent”, as you have it in your example.
Not to confuse -Focus as a command, I edited it to *FvwmEvent-FDpg: Cmd and added option *FvwmEvent: new_desk RestorePageFocus.
My shared code that was posted, I have corrected and tested it. Works well.
That is not how module alias work. Thomas’ suggestion was to use a module alias. In this case you need to configure the alias with *AliasName: ConfigOption, and then launch the module with Module FvwmEvent AliasName. For an example see the default-config and how it uses the EventNewDesk alias for FvwmEvent.
Note this isn’t special to FvwmEvent either. The default-config also uses the alias RightPanel for the FvwmButtons module. All of the options to configure it use *RightPanel for the alias configuration. Because you are setting configurations for the main FvwmEvent module, you won’t achieve the effect Thomas was talking about because you are writing the configuration for just FvwmEvent.
The way you would use an alias in your case is as follows:
I’m unsure why your test are failing, but I think you are just getting lucky that your code works since you are setting configuration for the main FvwmEvent and not just the alias. And the only thing you are setting for the alias is Cmd which is the default anyways.