Remember the Desktop/Page an Application was started on

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 :frowning: 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 :slight_smile:

Have Fun!
Pixelbrei

very nice post!
No late firefox or openoffice starting in front of chat programs anymore!

Nice function! However I noticed it doesn’t behave as expected with programs that use a splashscreen. For K3b, I find it pretty useless, so I just disabled it, but OpenOffice doesn’t have a ‘disable splash screen’ option, as far as I know. Here is, for example, my OOWriter entry:

+ "OpenOffice Writer"%icons/globes/edit.png% StartOnCurrentDesk xoowriter *OpenOffice*

The splash screen starts on the intended page, but the program itself does not.

So remove the splashscreen. Edit /etc/openoffice/sofficerc, and set:

logo=0

You can also just do:

$ openoffice -minimize

Or, if you’re using vanilla OO.o from openoffice.org:

$ soffice -minimize

HTH,

– Thomas Adam

I removed the splash screen, and I still had the same problem. Also “openoffice -minimize” didn’t do anything special.

Hi Pixelbrei,

as I red your post I thought: Yeah, I want it ! So I implemented your code and have tested it, but unfortunatelly it won’t work as it should :frowning:

I have tested both versions with some apps with the following result:
switching to another desk while program is starting -
a. with the pager -> I cannot switch until program has finished startup.
b. with my switch keys -> I can switch to another desk but then nothing has the focus - it looks like a screenshot. I can’t do anything on the current desk :cry: I must switch back via switch key to the started program. Then all works normally again - switch via pager, clicking on apps, hover over my icons, etc.

Do you know where’s my problem?

I hope you could help cause this behaviour is so useful, I wouldn’t miss… Thanks in advance.

Greetings,

TF

I also had this problem before, but solved it with a script called here, which allows me to start an application like “here firefox” from the command line (could be done via a menu as well, of course).

I used a directory ~/.here.d to specify application defaults, i.e., I would have a ~/.here.d/firefox file which contains the window-name excepted by Firefox. The script looks up this file and temporarily sets a Style to match that of the app on the current desk.

It was described on a thread on this forum:

http://fvwm.lair.be/viewtopic.php?t=560

// Simon

Hi SimonKagstrom,

sorry for long delay, but I’ve worked every evening on this problem and found no time to reply :blush: :blush:

Your script works great on the command line, but in between menus FVWM reports an error/problem with $* in your script :angry:

But I’ve found a fix for your problem to reset the old “StartsOnDesk” style - write on the end of your scriptFvwmCommand "DestroyStyle $STYLE_NAME"On my system it works -> if you start a program without “here” on another desk it pops up on this not on the last :wink:

Ok, back to my problem(s) - I’ve tested several versions of Pixelbreis StartOnCurrentDesk function. There’re two problems:

  1. the ‘Wait’ command - it doesn’t work if you switch desktops via pager. Also you must switch with a key to the desk to bring the window in focus to eliminate the wait ban.
  2. If I comment out the wait line the app appears on the current desk every time. I think this problem depends on when the style will applied to the app from FVWM. With+ I Exec exec $0 the app will start in the background. Therefore the next function command will execute immediately, but the app isn’t started yet. So the style will reset and the app appears on the current desk :cry:
    With + I Exec $0 the same behaviour occurs whether I red in the manpages that this stays until the command exits :confused:

At the moment I reflect how I implement a wait state until the app is started. Also how I can eliminate the window name in Pixelbreis command. Your idea with the .here.d directory for special cases could be useful. Let’s see 8)

Ok, I will post all as soon as I can

Best Regards,

TF

Ah, I’ve never tried it from the menus. $* should just execute everything that was passed to the script. I’ll look at it during the weekend, but echo $* should at least give some debugging hints.

Yep, I’ve later added that to my own here-script, but I didn’t update the forum post.

It can be useful sometimes. I actually only use it for one case now, but I think I’ll add other cases as they appear. The case I use it is that I have a svnxxdiff command which opens xxdiff with a directory view of the differences between current and last subversion revision. In this case the window name is xxdiff, so I’ve added a ~/.here.d/xxdiff to handle that.

As to your original question, I’m afraid I don’t quite understand how it works.

// Simon

Hi,

now I’ve fixed the $* problem :slight_smile:
Here’s my modified ‘here’ script#!/bin/bash if [ -f ~/.fvwm/temp/.here.d/$1 ]; then STYLE_NAME=`cat ~/.fvwm/temp/.here.d/$1` else STYLE_NAME=$1 fi FvwmCommand "Style $STYLE_NAME StartsOnPage \$[desk.n],SkipMapping" $* & FvwmCommand "Style $STYLE_NAME" sleep 10 FvwmCommand "DestroyStyle $STYLE_NAME"

To start an app via menu changeExec exec footoExec exec here foo

I’m working on the problem to generate a file with the correct window name if it is differently to the app name, but I don’t know how I can get the window name of the started app :frowning:

I tried it with this (implemented after sleep 10)FvwmCommand "ThisWindow ($STYLE_NAME) PipeRead `echo \$[w.resource] > ~/.fvwm/temp/.here.d/$STYLE_NAME`"but it doesn’t work :cry: :cry:

Have anyone an idea how I get the resource name of the started app?

Thanks in advanced,

TF

(I’m not sure I understand the problem completely).

What I do is to use the ~/.here.d. For example, the xpdf application uses the window name “Xpdf”, so I therefore (since today actually!) have a file ~/.here.d/xpdf which contains

Xpdf

(that’s all!). So when I run here xpdf blaha.pdf, the script looks in .here.d and finds xpdf and then applies the “Xpdf” name to the Style option.

Sorry if I understood your problem!

// Simon[/code]

Hi SimonKagstrom,

sorry for my bad explanation :blush:

Ok, at the moment you create a file manually if the window name (respectively resource name) is differnt to the app name. I want create this file automatically. Then after the second start of the app the style is initialized correctly and the function works properly again.

For this I need $[w.resource] to get this resource name. But at the moment it looks like that $[w.resource] is empty … Unfortunatelly I don’t know how I can get the resource name associated to the app which was started before …

I hope now it’s clear what I want, sorry.

Best Regards

TF