Focus split between applications

30 views
Skip to first unread message

zbearicus96

unread,
Oct 19, 2022, 4:21:23 PM10/19/22
to fltk.general
Hi all,

I'm new to fltk but have done a lot of reading of its docs and code in the area of focus and am confused by some behavior I'm seeing in a complicated open source program. I see the following things happen:

1. When the application starts, it appears that fltk walks the widget tree sending FL_FOCUS messages to each widget in definition order until someone takes it.

Question - is there a way to stop fltk from sending FL_FOCUS to all the widgets prior to me clicking in the application?

2. If I click on another application to set focus there, keyboard entry goes to the other application as expected.

3. I can then move the mouse over the fltk application for hours on end without any widget getting focus (good) and  Fl::focus() reports 0 in the log.

4. But if I roll the mousewheel with the mouse over an Fl_Value_Slider, two things happen:

   a. The slider value changes (OK, but wish it didn't)
   
   b. fltk seems to re-initiate its 'give the focus to some widget' process, and a widget that can accept text input gets focus (I can tell this from log messages).
   
5. The log messages show that the widget has focus, but no keyboard events are delivered to it and text I enter continues to appear on the other application that from a title bar perspective really does have focus.  The widget getting focus is an Fl_Float_Input.

6. To unscrew this situation (enable me to actually enter something into the Fl_Float_Input), I have to click in the Fl_Float_Input widget.  At that point the widget REALLY has focus from a keyboard event delivery perspective.


What I would like to have happen is this: if the fltk app does not have focus, no user action will cause a value to change.  If any of its widgets DO have focus, I'd like all the keyboard events to be delivered to that widget.

Can anyone shed some light on why fltk behaves this way and whether there is something I'm doing or not doing that is contributing to this?

Thanks
Dave

chris

unread,
Oct 28, 2022, 12:51:56 PM10/28/22
to fltkg...@googlegroups.com
Am 19.10.22 um 22:21 schrieb zbearicus96:
>
> 2. If I click on another application to set focus there, keyboard entry goes to the other application as expected.
>
> 3. I can then move the mouse over the fltk application for hours on end without any widget getting focus (good) and  Fl::focus() reports 0 in the log.
>
> 4. But if I roll the mousewheel with the mouse over an Fl_Value_Slider, two things happen:
>
>    a. The slider value changes (OK, but wish it didn't)

This behavior seems to be common in UI's and can be seen with other applications too e.g. you can scroll in a (not focused) terminal window with the mouse wheel.
I don't think there is an easy way to disable it generally in FLTK - except you can probably get rid of it in a derived custom widget that overrides the handle() method.

>
>    b. fltk seems to re-initiate its 'give the focus to some widget' process, and a widget that can accept text input gets focus (I can tell this from log messages).
>
> 5. The log messages show that the widget has focus, but no keyboard events are delivered to it and text I enter continues to appear on the other application that from a title bar perspective really does have focus.  The widget getting focus is an Fl_Float_Input.
>
> 6. To unscrew this situation (enable me to actually enter something into the Fl_Float_Input), I have to click in the Fl_Float_Input widget.  At that point the widget REALLY has focus from a keyboard event delivery perspective.
>
>

I think you may have found a "bug" here in FLTK: A text input widget displaying the text cursor even when it does not have the X11 input focus is IMHO a misleading signal to the user.

But: this "bug" is a very old one - it can be found even in FLTK 1.1.10.

I have experimented a little with it and observed how to reproduce it easily:

- Use any of the FLTK test program with an input widget e.g. the `editor` or `input` programs.
- When the input widget has the text focus raise another window on your desktop (e.g. a terminal) so the cursor goes away from the input field
- Move the mouse over the test program somewhere and just scroll the mouse wheel
- Leave the window with the mouse and then re-enter it: the input cursor appears! But the input widget does not receive keyboard events

I have also found, that commenting out this line:

https://github.com/fltk/fltk/blob/master/src/Fl.cxx#L1457

seems to fix it, but of course there may be and probably will be side effects. Experts anyone?

Bill Spitzak

unread,
Oct 28, 2022, 1:25:55 PM10/28/22
to fltkg...@googlegroups.com
I would agree that line looks like a mistake, I think it is assuming the window manager is point-to-type.

The if/else statements below are kind of redundant too as they all result in the same call, just changing what window (grab, modal, window) to send to. Probably could be much shorter.

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/6709cbea-5a5b-ec8b-7939-562215e07089%40gmx.net.

Albrecht Schlosser

unread,
Oct 28, 2022, 2:06:24 PM10/28/22
to fltkg...@googlegroups.com
On 10/28/22 18:51 chris wrote:
Am 19.10.22 um 22:21 schrieb zbearicus96:
    b. fltk seems to re-initiate its 'give the focus to some widget' process, and a widget that can accept text input gets focus (I can tell this from log messages).

5. The log messages show that the widget has focus, but no keyboard events are delivered to it and text I enter continues to appear on the other application that from a title bar perspective really does have focus.  The widget getting focus is an Fl_Float_Input.

6. To unscrew this situation (enable me to actually enter something into the Fl_Float_Input), I have to click in the Fl_Float_Input widget.  At that point the widget REALLY has focus from a keyboard event delivery perspective.



I think you may have found a "bug" here in FLTK: A text input widget displaying the text cursor even when it does not have the X11 input focus is IMHO a misleading signal to the user.

But: this "bug" is a very old one - it can be found even in FLTK 1.1.10.

I have experimented a little with it and observed how to reproduce it easily:

- Use any of the FLTK test program with an input widget e.g. the `editor` or `input` programs.
- When the input widget has the text focus raise another window on your desktop (e.g. a terminal) so the cursor goes away from the input field
- Move the mouse over the test program somewhere and just scroll the mouse wheel
- Leave the window with the mouse and then re-enter it: the input cursor appears! But the input widget does not receive keyboard events

I have also found, that commenting out this line:

https://github.com/fltk/fltk/blob/master/src/Fl.cxx#L1457

seems to fix it, but of course there may be and probably will be side effects. Experts anyone?

Well, I'm not the author of that old code but it looks as if this statement might have been copied from keyboard handling above. It makes sense that keyboard input should not happen w/o having the X focus which would explain the comment in that code:
https://github.com/fltk/fltk/blob/a918292547cfb154dec26eeabdf70b4ff026f6be/src/Fl.cxx#L1387

  fl_xfocus = window; // this should not happen! But maybe it does:


... and the fact that this is "corrected" where keyboard input is involved.

The case in line 1457 (identical statement) where mousewheel scrolling is handled is IMHO questionable and we should maybe not set fl_xfocus in that case as you, Chris, found out. Thanks, that's a great investigation.

Anyway, this needs either more investigation (in Git history ?) or someone else might know better what to do.


[Note: I just saw that Bill commented on this while I was writing. Thank you very much, Bill!]

zbearicus96

unread,
Nov 3, 2022, 9:07:51 AM11/3/22
to fltk.general
Thank you all for the response and diagnostic.  I will comment out the line in my local copy and try it out.

Thanks
Dave

wcout

unread,
Nov 4, 2022, 7:43:12 AM11/4/22
to fltkg...@googlegroups.com
Am 28.10.22 um 18:51 schrieb chris:
> Am 19.10.22 um 22:21 schrieb zbearicus96:
>>
>> 2. If I click on another application to set focus there, keyboard entry goes to the other application as expected.
>>
>> 3. I can then move the mouse over the fltk application for hours on end without any widget getting focus (good) and  Fl::focus() reports 0 in the log.
>>
>> 4. But if I roll the mousewheel with the mouse over an Fl_Value_Slider, two things happen:
>>
>>     a. The slider value changes (OK, but wish it didn't)
>
> This behavior seems to be common in UI's and can be seen with other applications too e.g. you can scroll in a (not focused) terminal window with the mouse wheel.
> I don't think there is an easy way to disable it generally in FLTK - except you can probably get rid of it in a derived custom widget that overrides the handle() method.
>

Here is an example (attached) that shows how mouse wheel events could be handled for the valuator type widgets depending on window focus and/or mouse over.
It's basically as simple as intercepting the FL_MOUSEWHEEL event and handling/ignoring it on the conditions "window has focus" and "widget below mouse".

I think this features would be nice to have in the base classes already, because I had to use templates in order not to type the same code over and over...
wheel_valuators.cxx

Albrecht Schlosser

unread,
Nov 5, 2022, 10:33:40 AM11/5/22
to fltkg...@googlegroups.com
On 11/4/22 12:42 wcout wrote:
> Am 28.10.22 um 18:51 schrieb chris:
>> This behavior seems to be common in UI's and can be seen with other
>> applications too e.g. you can scroll in a (not focused) terminal
>> window with the mouse wheel.
>> I don't think there is an easy way to disable it generally in FLTK -
>> except you can probably get rid of it in a derived custom widget that
>> overrides the handle() method.
>>
>
> Here is an example (attached) that shows how mouse wheel events could
> be handled for the valuator type widgets depending on window focus
> and/or mouse over.
> It's basically as simple as intercepting the FL_MOUSEWHEEL event and
> handling/ignoring it on the conditions "window has focus" and "widget
> below mouse".

Sorry, it took a while to come back to your source code and to read and
understand it. Thanks, I see what you're demonstrating (not tested though).

> I think this features would be nice to have in the base classes
> already, because I had to use templates in order not to type the same
> code over and over...

So, what are you proposing, actually? Should we add flags to some base
class (maybe even Fl_Widget) to be able to decide whether mousewheel
scrolling should be applied and under which condition (e.g. window-focus
or belowmouse) ? Or are you thinking of a global flag for all kinds of
widgets?

wcout

unread,
Nov 6, 2022, 10:33:54 AM11/6/22
to fltkg...@googlegroups.com
Am 05.11.22 um 15:33 schrieb Albrecht Schlosser:
>
>> I think this features would be nice to have in the base classes already, because I had to use templates in order not to type the same code over and over...
>
> So, what are you proposing, actually? Should we add flags to some base class (maybe even Fl_Widget) to be able to decide whether mousewheel scrolling should be applied and under which condition (e.g. window-focus or belowmouse) ? Or are you thinking of a global flag for all kinds of widgets?
>
I was actually thinking only about the unification of the valuator widgets (as there are Fl_Scrollbar, Fl_Slider, Fl_Value_Slider, Fl_Dial, Fl_Adjuster, Fl_Counter, Fl_Roller) in respect to mouse wheel handling. Looking at the (original) 'valuators' test program it can be observed that only the Fl_Scrollbar and the Fl_Roller widgets react to this event and of these only the vertical "flavours" do (not the horizontal).
Combined with the observations of the OP (when do they react?) it would be good also to put some variables (or methods) into the Valuator base class to control the whens and whereabouts through the application.
As you can see with my extended valuator demo (as proof) it feels nice and natural to have them all react consistently to mouse wheel events.
Reply all
Reply to author
Forward
0 new messages