On Tue, May 04, 2010 at 07:24:20AM -0400, Shriver, Daniel wrote:
> I seem to be having a lot of difficulty understanding what you're telling
> me. If you want me to reply off list (so as not to bore everyone else)
> let me know.
If you would mind *not* cross-mixing threads, that'd be good.
>
> > > > Style window_at_bottom SloppyFocus, GrabFocus
> > > > Style window_at_top NeverFocus, PositionPlacement x y
> > >
> > > > You might have to sort the ordering out yourself as to when/where these
> > > > windows are mapped,
> > > > and in what order. I've given you an example of PositionPlacement, so
> > >
> > > I've tried what you gave above (except with no ", PositionPlacement x y"
> >
> > Right -- I thought you said this top window was alwas over the bottom window
> > which is to have the focus?
>
> That's correct. I just don't understand why there is "PositionPlacement"
> there. That should just put the widget at that spot right? Does it
> change focus behavior? I did add it back in (with "10 10" for the x y)
> but still notice the same behavior (the lower window doesn't regain
> keyboard focus until I slew out of the top window.
PositionPlacement only affects position, yes.
> > Style bottom_window InitialMapCommand Focus NoWarp, StartsOnPage x y, \
> > SkipMapping
> >
> > then you can always do something like this:
> >
> > DestroyModuleConfig FE-PW:*
> > *FE-PW: enter_window SomeFunc
> >
> > AddToFunc StartFunction I Module FvwmEvent FE-PW
> >
> > DestroyFunc SomeFunc
> > AddToFunc SomeFunc
> > + I PointerWindow (top_level_window_class_name) \
> > Next (my_bottom_win_name, AcceptsFocus, !Focused, CirculateHit) Focus
> > NoWarp
>
> I did change "bottom_window" to be the "class" of my bottom window
> likewise with "my_bottom_win_name", and made "top_level_window_class_name"
> to be the top window class name. Otherwise, I literally wrote in what you
> gave. Should I chage InitialMapCommand to be "FE-PW" or "SomeFunc"?
Neither. I'll start from the beginning, perhaps that will help you
understand this.
Style bottom_window InitialMapCommand Focus NoWarp
The "InitialMapCommand" is a style condition that runs anything FVWM-related
when the window with the name/class/resource (whichever is matched) of
"bottom_window" appears. As soon as it does, FVWM trundles off, and in this
case runs "Focus NoWarp" -- the effect here is to give focus to this window,
without moving the mouse pointer.
Style bottom_window StartsOnPage x y
... you should replace "x" and "y" with something more meaningful, *if* you
want/need this bottom_window to be on a particular page when it's mapped.
If it doesn't bother you, don't use it.
Style bottom_window SkipMapping
... this instructs FVWM *not* to switch to the page specified with
"StartsOnPage". You wouldn't want this with something like "Focus Nowarp",
I wouldn't have thought. So I put it in as an example for you only to
consider.
The thing to take away from this though -- is that the only style which will
need is the first one:
Style bottom_window InitialMapCommand Focus NoWarp
But note that if another window loads after that which steals focus, the
effect of the InitialMapCommand is going to be lost; it's a one-shot
approach only for the duration that some other client doesn't ask for focus
-- which is likely the effect you're seeing. Thankfully though I've written
up some notes about focus stealing here:
http://fvwmwiki.xteddy.org/Tips/FocusStealing/
>
> > But I am still not sure what effect it is you're after from that point on.
>
> I want everything typed by the keyboard to go to the "bottom widget" never
> the "top" one (even if the mouse is above the top one or is clicking on
> the top one). So far, I'm happy with the pointer behavior, but the best
> solution I have (the first one you gave) I still have to move the pointer
> so it is no longer above the top window before the bottom window regains
> keyboard focus.
Not with the FvwmEvent example I gave you.
DestroyModuleConfig FE-PW:*
*FE-PW: enter_window SomeFunc
These two lines simply instruct FVWM that there's a module alias called
"FE-PW"
AddToFunc StartFunction I Module FvwmEvent FE-PW
This one *tells* FVWM that the FE-PW alias belongs to an FvwmEvent instance.
DestroyFunc SomeFunc
AddToFunc SomeFunc
+ I PointerWindow (top_level_window_class_name) \
Next (my_bottom_win_name, AcceptsFocus, !Focused, CirculateHit) Focus
NoWarp
This is the function which does the hard-work for you. Whenever you move
the mouse out of/in to a window (don't get me to explain that here -- that's
a subtly with how reparented windows work) an EnterNotify event is
generated.
We can track this. But note that now, because your top_window has
NeverFocus set on it, we can't use any of the focus_window changes FvwmEvent
would normally use to track it, as those events never reach the window. So
we have to instead reference the window with PointerWindow -- which
guarantees to reference any window under the mouse pointer.
So, if when the pointer moves into the window called
top_level_window_class_name (in this case -- your "top_window"), then we
know we're meant to be sending events through to your bottom_window -- and
the only way we can do this is by giving focus to *that* window.
Note that there is a side-effect here, too. I know I mentioned it in a
previous email, but the bottom_window must also have:
Style bottom_window SloppyFocus
You *don't* want to be using MouseFocus, since if the pointer goes into the
root window, bottom_window would lose focus, which is what SloppyFocus
prevents in this case. Similarly of course (although out of scope for
this), if the pointer leaves top_window to $some_other_window, then unless
you want the same functionality as with top_window to send events elsewhere
-- then you're going to have to augment the PointerWindow condition.
> That's probably the only way for a window manager to give keyboard focus
> to a GUI that is obscured (have the window on top pass it to the window on
> bottom).
And note that we're not really "sending" events anywhere -- they're all
going to the application that has the focus, it's just that we're cheating
almost and doing this with a "proxy" window.
> >
> > DestroyModuleConfig FE-PW:*
> > *FE-PW: enter_window SomeFunc
> >
> > AddToFunc StartFunction I Module FvwmEvent FE-PW
> >
> > DestroyFunc SomeFunc
> > AddToFunc SomeFunc
> > + I PointerWindow (top_level_window_class_name) \
> > Next (my_bottom_win_name, AcceptsFocus, !Focused, CirculateHit) Focus
> > NoWarp
>
> I put this bottom part in literally (only changing
> "top_level_window_class_name" and "my_bottom_win_name"- to the respective
> class names). When I reloaded fvwm was not working properly (either some
> of the things I left out that I thought were optional weren't or I did
> substitutions wrong (like "InitialMapCommand").
Send me your config.
HTH,
-- Thomas Adam