1. Remember the Page/Desktop an Application was started on
This is a very common problem: You start an application, and as it is a bigger one, the window is not created instantly. By the time the window finally appears, you already switched to another page/desktop. Now the window is created on your current page/desktop, instead of the desktop it was started on.
As neither the X Window System nor the application itself knows which desktop it was started on, we have to find another way.
I wrote a small fvwm script to get the job done:
DestroyFunc StartOnCurrentDesk
AddToFunc StartOnCurrentDesk
+ I PipeRead `echo Style $1 SkipMapping, !FPGrabFocus, !FPFocusByProgram, StartsOnPage $[desk.n] $[page.nx] $[page.ny]`
+ I Exec exec $0
+ I Wait $1
+ I Style $1 !SkipMapping, FPGrabFocus, FPFocusByProgram, StartsAnyWhere
Now you can start apps with
StartOnCurrentDesk <command> <window name>
For example:
StartOnCurrentDesk firefox *Firefox*
You have to tell the script what the window of the app will be called, because neither fvwm nor X know this, and the app won’t tell us But you don’t have to specify the exact name, it supports wildcards.
You can use this in your menu definitions, shortcuts, starterbars,… …or even in your shell! This needs aliases, or it is not practicable. You don’t wanna type
FvwmCommand "StartOnCurrentDesk firefox *Firefox*"
in your terminal, so you alias it. In bash this is
alias <alias-name> 'FvwmCommand "StartOnCurrentDesk <command> <window name>"'
NOTE: This alias will not work if fvwm is not running!
2. Combine with RememberFocus
The thing is, if you changed the desk/page, and the app window starts on the page it should start on, you probably want it to get focused when you return to this desk/page.
I set “State 2” as a marker for windows that started on another page, the Function now looks like this:
DestroyFunc StartOnCurrentDesk
AddToFunc StartOnCurrentDesk
+ I All ($1) State 1 True
+ I PipeRead `echo Style $1 SkipMapping, !FPGrabFocus, !FPFocusByProgram, StartsOnPage $[desk.n] $[page.nx] $[page.ny]`
+ I Exec exec $0
+ I Wait $1
+ I All ($1, State 1 False) State 2 True
+ I Style $1 !SkipMapping, FPGrabFocus, FPFocusByProgram, StartsAnyWhere
Then you can combine this with the RememberFocus script. It just needs a little adjustment:
DestroyFunc CurrentPageFocusFunc
AddToFunc CurrentPageFocusFunc
+ I Next (CurrentPage, State 3) Focus
+ I Next (CurrentPage, State 2) Focus
+ I None (CurrentPage, Focused) Prev (CurrentPage, !Iconified, !Sticky) Focus
DestroyFunc CurrentDeskFocusFunc
AddToFunc CurrentDeskFocusFunc
+ I Current FlipFocus
DestroyFunc MarkWindowAsActiveFunc
AddToFunc MarkWindowAsActiveFunc
+ I Current (!Iconified) All (CurrentPage, !Focused) State 3 False
+ I Current (!Iconified) State 3 True
DestroyModuleConfig FvwmEvent: *
*FvwmEvent: Cmd Function
*FvwmEvent: new_page CurrentPageFocusFunc
*FvwmEvent: new_desk CurrentDeskFocusFunc
*FvwmEvent: destroy_window CurrentPageFocusFunc
*FvwmEvent: focus_change MarkWindowAsActiveFunc
Module FvwmEvent
I changed the “RememberFocus” State to 3, and added the “+ I Next (?CurrentPage, State 2) Focus” line.
So if you switch to another page, it focuses the last focused window on this page, and then tries to focus a window with state 2, i.e. a window created by my script.
3. BUGS
I am currently using taviso’s fvwm2rc (http://dev.gentoo.org/~taviso/fvwm2rc.html), with some little changes. I use his WheelScroll Function to switch pages. This Function is called by 2 different actions:
*Scrolling my mousewheel on the root window
*Scrolling my mousewheel anywhere while holding down CTRL
Both normally work as they should. But for some strange reason, when i use the second method (wheel+CTRL) while an application started by my script is running and still has no window, it just kicks me out of fvwm. After the window is there, both methods work fine again.
I heard this could be a bug in 2.5.12, but i did’t change the version to find out more yet.
And: This does not work with all windows. sancho, for example, makes me jump to the page it was started on after the window was created. But up to now this is the only app that refuses behaving normally
Have Fun!
Pixelbrei