[SOLVED]'Smart Launcher' and 'Next' peculiarity

[*]I am trying to write a function which would do the following:

  • If no instances of gedit or firefox or nautilus are running, launch one
  • If there is one, bring the window on top and give it focus
  • If there are two or more, circulate through them, rising them on top and giving them focus

What I have so far is:


This one is from manual:

DestroyFunc WinToTop
AddToFunc WinToTop

  • I Layer 0 ontop
  • I Raise

This is what I wrote:

DestroyFunc LaunchRaiseSwitch
AddToFunc LaunchRaiseSwitch

  • I None (gedit) Exec exec nautilus --no-desktop
  • I Next (gedit) WinOnTop

Key F A 4 Function LaunchRaiseSwitch[/code]

It would not launch gedit if one is running, which is good. But it would not circulate through gedit windows, it would only switch to next one or two and then stop, while “Fvwm stores windows in a ring internally.” (manuals) and ‘Focus’ instead ‘WinOnTop’ does what I want (but does not raise the window, just circulates)

Where did I go wrong?

DestroyFunc SomeFunc AddToFunc SomeFunc

+ I None (window1) Exec exec window1
+ I TestRc (NoMatch) RaiseAndFocus window1
+ I None (window2) Exec exec window2
+ I TestRc (NoMatch) RaiseAndFocus window2
+ I None (window3) Exec exec window3
+ I TestRc (NoMatch) RaiseAndFocus window3
DestroyFunc RaiseAndFocus
AddToFunc  RaiseAndFocus
+ I Next ($0, AcceptsFocus) RaiseLower
+ I Next ($0, AcceptsFocus) Focus

Eh? What madness is this?

– Thomas Adam

Yes, thank you, Thomas, I managed to make first two. Seems like I did not explain properly.

I would like to have Super+g to launch gedit if it is not running yet, raise it if it is running (and this actually works just fine) and make the same key switch between gedit window1, gedit window2, gedit window3, gedit window1 again and so on. The latter would not work. It would just run through gedit windows once and the stick to the last one. I would like it to switch to first from last. And if I write

[code]DestroyFunc LaunchRaiseSwitch
AddToFunc LaunchRaiseSwitch

  • I None (gedit) Exec exec gedit
  • I Next (gedit) RaiseAndFocus

Key F A 4 Function Focus[/code]

it gives focus to gedit window as I described.

 + I TestRc (Match) Wait gedit

– Thomas Adam

That would not switch them, would it?

The behaviour you want is completely odd.

In the case of doing this:

+ I Exec exec foo
+ I Next (foo) DoSomething

You have no guarantee that the next command is going to operate on the window you’re launching – if the “exec foo” line doesn’t complete in time before the Next line is run, then it could run on any window in the stack ring. Which is why the use of “Wait” is important here – so you ensure the next line always waits for the “foo” window you’re launching here to appear.

But what you want might be something different, in which case, you will need to be a lot more specific about just what it is you want – because the requirement of: “If there’s more than two windows raise and focus them” really amounts ot reordering the stack of windows to put the last window at the top – as you can’t focus more than one window at a time anyway.

So just what is it that you’re trying to do?

– Thomas Adam

Well I’ll try to explain one more time.

I hit Super+g, gedit starts.

I write some stuff, than I switch to firefox. Than I need gedit again. I hit Super+g once again and the existing gedit window raises.

Then I (no matter how) launch one more (ore two) gedits.

Now if I hit Super+g and active window is Firefox, gedit window is raised and gets focus. If active window is gedit one, gedit two is raised and gets focus, than gedit three, than gedit one again.

I can check if an application is launched and launch one if not with

+ I None (*gedit*) Exec exec gedit

That part seems to work fine.

What I am trying to with

+ I Next (*gedit*) WinToTop

is switchig between all open gedit windows, raising them one by one to top and giving them focus (not all at once).

[code]+ I Layer 0 ontop

  • I Raise[/code]

works fine - it raises the window and places it on it’s layer again.

+ I Next (*gedit*) Focus

also is nice - when I have several gedits running and repeatedly hit Super+g, the focus goes 12312312 etc.

But if I write

+ I Next (*gedit*) WinToTop

raising gedits goes like 123 or 23 and sticks with 3, and that’s what I would like to work around somehow.

It’s not like it’s a necessary option, but it would be nice. And it’s interesting how to repeatedly switch between windows on this or that condition.

I see – which goes well beyond any meaningful usecase.

At this point, I would suggest you forget your own implementation of this, and look at using FvwmWindowMenu to switch between applications.

– Thomas Adam

If I only wanted what doesn’t go ‘beyond any meaningful usecase’, I would use Metacity. ))

Thanks for the tip, it would be pretty close to what I wanted.

Still it’s strange why Next (foo) Focus and Next (foo) Raise work differently.

Focus uses the window ring – so the ordering is different to the window you might reach with “Next (foo) Raise”.

– Thomas Adam

It was very stupid of me not to try FvwmAuto 0 -mfocus - chances are it would do what I want.


– Thomas Adam

Focus would go through the ring and FvwmAuto would raise focused windows. Bingo.

Or why do I want fvwm to do strange things? It’s a sort of hobby - checking out how it would work and would it work at all. Why people bother implementing window snapshots instead of icons?

You misunderstand me. If you consider the id

Sorry, seems like I missed something. What’s with id?

As soon as I’m home I’ll post the exact function I’m thinking about.

This does exactly what I wanted:

What I wanted:

[code]DestroyFunc LaunchRaiseSwitch
AddToFunc LaunchRaiseSwitch

  • I None (gedit) Exec exec gedit
  • I Next (gedit) Focus

Key F A 4 Function LaunchRaiseSwitch

Module FvwmAuto 0 -mfocus “Silent Raise” “Silent Lower”

And one more to launch new instance of an application explicitly:

[code]DestroyFunc Launch
AddToFunc Launch

  • I Exec exec gedit --new-window

Key F A 4C Function Launch

Works just as planned. Now I’ll see if it worthed it. ))

Right, you failed to explain that for toffee. Generalise it, perhaps:

[code]DestroyFunc LaunchRaiseSwitch
AddToFunc LaunchRaiseSwitch

  • I None ($0) Exec exec $1
  • I Next ($0) Focus

You don’t need the word Function here.

Key F A 4 LaunchRaiseSwitch “gedit” gedit
Key G A 4 LaunchRaiseSwitch XTeddy xteddy

Of course, this so-called “special casing” of a new window blows. Why can’t you instead do this:

DestroyFunc LaunchRaiseSwitch
AddToFunc LaunchRaiseSwitch
+ I None ($0) Launch $1
+ I Next ($0) Focus

# You don't need the word Function here.
Key F A 4 LaunchRaiseSwitch "*gedit*" gedit
Key G A 4 LaunchRaiseSwitch XTeddy xteddy

DestroyFunc Launch
+ I Exec exec $0 

Oh, you can’t do that because it’s pointless.

– Thomas Adam

Luckily I’ve read a nice Python handbook couple of months ago so I know what generalisation is. Half a year ago I would go like ‘what?’, so thanks for this advice.

I usually generalise a working function, probably I should take as a rule write them generalised from the start.