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

Reply via email to