We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 5505 - Changing active window during SDL_MOUSEBUTTONDOWN and getting back drops first SDL_MOUSEBUTTONDOWN event after return
Summary: Changing active window during SDL_MOUSEBUTTONDOWN and getting back drops firs...
Status: WAITING
Alias: None
Product: SDL
Classification: Unclassified
Component: events (show other bugs)
Version: 2.0.14
Hardware: x86_64 Linux
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-01-27 08:18 UTC by Jarosław Siebert
Modified: 2021-01-29 16:46 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jarosław Siebert 2021-01-27 08:18:00 UTC
Hello,
I port my application from SDL1 to SDL2.
During tests I noticed little bug in events susbsystem (or maybe my fault).
I use main loop in program with:
SDL_PollEvent(&event)
then I check which event I get:
SDL_MOUSEMOTION, SDL_MOUSEBUTTONUP, SDL_WINDOWEVENT, SDL_DISPLAYEVENT, SDL_KEYUP,
SDL_KEYDOWN, SDL_MOUSEBUTTONDOWN.
It works ok mostly. The only situation when I have got problem is:
1. When I do SDL_MOUSEBUTTONDOWN and keep it in that state.
2. During SDL_MOUSEBUTTONDOWN I change active window to another app (xterm) with ALT+TAB from my windowmanager (fluxbox)
3. I stop pressing mouse button on xterm window (not on sdl2 app)
4. I go back with ALT+TAB to sdl2 app with mouse pointer in diferent place and without pressing mouse button
5. When I press mouse button on my sdl2 app again (first time after window switch)
then I have no SDL_MOUSEBUTTONDOWN event. 
6. When I press mouse button again then I get SDL_MOUSEBUTTONDOWN event.
What I tried:
when I change active app from sdl2 app to xterm I get SDL_WINDOWEVENT, and I can use it to reinitialize events susbsystem.
I did it with:
SDL_PumpEvents();
SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT-1);
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_InitSubSystem(SDL_INIT_EVENTS);
It didn't help.
Can you fix it or let me know how to fix my app to don't loss first SDL_MOUSEBUTTONDOWN after window change?
Thanks for any help
Comment 1 Cameron Gutman 2021-01-27 16:35:32 UTC
Try setting SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH to 1.
Comment 2 Jarosław Siebert 2021-01-28 06:54:31 UTC
Hello,
thanks for tip.
I just tested it - and there is no change.
I am not sure how to use SDL_SetHintWithPriority() (where to place it in my code) so I tested with many places:
- before SDL_SetMainReady()
- after SDL_SetMainReady()
- before SDL_Init()
- after SDL_Init()
Tests didn't help.
WHat is proper place to use SDL_SetHintWithPriority()?

I dide more tests with SDL_SetHintWithPriority and SDL_HINT_GRAB_KEYBOARD hint:
SDL_SetHintWithPriority(SDL_HINT_GRAB_KEYBOARD, "1", SDL_HINT_OVERRIDE) in each test returned SDL_TRUE, but I always could use fluxbox shortcut to run another xterm app in the background.
I init SDL in fullscreen mode (SDL_WINDOW_FULLSCREEN_DESKTOP|SDL_WINDOW_BORDERLESS).
What exactly hints do? Should they work or it depends on which window manager we use?
Comment 3 Jarosław Siebert 2021-01-28 06:59:54 UTC
Regarding to hints, there is i another hint description:

"You need to set this hint before you call SDL_Init otherwise it will not take effect. "

So I will place them before SDL_Init().
As I wrote before - I did tests with hints before SDL_Init() and it didn't helped.
Comment 4 Jarosław Siebert 2021-01-28 08:13:05 UTC
I did some more tests with touchscreen.
1. I use touchscreen (no mouse) and touch screen (DOWN) and keep it touching.
2. With keyboard I change active window to xterm.
3. I keep pressing touch down but then I start moving it over the panel.
4. My app that is behind xterm keeps getting SDL_MOUSEMOTION
5. I stop pressing touchscreen.
6. I change active app to sdl2 app with ALT+TAB keys
7. I can receive SDL_MOUSEBUTTONDOWN with first touch or first mouse button action
So - it is working ok.
When I do the test again but using mouse (not touch screen) then the above scenario is diffrent in point 4. I don't get SDL_MOUSEMOTION events after changing
active window to xterm. And then I can't receive first SDL_MOUSEBUTTONDOWN event
with touch and with mouse button.
Comment 5 Cameron Gutman 2021-01-28 15:16:05 UTC
(In reply to Jarosław Siebert from comment #2)
> Hello,
> thanks for tip.
> I just tested it - and there is no change.
> I am not sure how to use SDL_SetHintWithPriority() (where to place it in my
> code) so I tested with many places:
> - before SDL_SetMainReady()
> - after SDL_SetMainReady()
> - before SDL_Init()
> - after SDL_Init()
> Tests didn't help.
> WHat is proper place to use SDL_SetHintWithPriority()?
> 

It depends on the hint. With SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, as long as you do it before the actual click, it should be fine.

> I dide more tests with SDL_SetHintWithPriority and SDL_HINT_GRAB_KEYBOARD
> hint:
> SDL_SetHintWithPriority(SDL_HINT_GRAB_KEYBOARD, "1", SDL_HINT_OVERRIDE) in
> each test returned SDL_TRUE, but I always could use fluxbox shortcut to run
> another xterm app in the background.

SDL_HINT_GRAB_KEYBOARD doesn't grab the keyboard on its own. It "specifies whether grabbing input grabs the keyboard". You still have to grab input with SDL_SetWindowGrab() for it to do anything. You also should be sure you really want to do this. Unless your application needs to grab shortcuts like Alt+Tab, you should really avoid it (and _definitely_ give users a clear option to opt-in to that behavior).

(In reply to Jarosław Siebert from comment #4)
> I did some more tests with touchscreen.
> 1. I use touchscreen (no mouse) and touch screen (DOWN) and keep it touching.
> 2. With keyboard I change active window to xterm.
> 3. I keep pressing touch down but then I start moving it over the panel.
> 4. My app that is behind xterm keeps getting SDL_MOUSEMOTION
> 5. I stop pressing touchscreen.
> 6. I change active app to sdl2 app with ALT+TAB keys
> 7. I can receive SDL_MOUSEBUTTONDOWN with first touch or first mouse button
> action
> So - it is working ok.

With SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH=1, or with no hints set?

> When I do the test again but using mouse (not touch screen) then the above
> scenario is diffrent in point 4. I don't get SDL_MOUSEMOTION events after
> changing
> active window to xterm. And then I can't receive first SDL_MOUSEBUTTONDOWN
> event
> with touch and with mouse button.

I think I'm starting to follow now. The specific issue you're seeing is that if the mouse button is down when focus is switched away from the SDL window and it is released while the SDL window does not have focus, then the state of the mouse button is not as you'd expect (up) when you  set focus back on the SDL window.

Can you please set SDL_HINT_EVENT_LOGGING=1 and check if you see SDL_MOUSEBUTTONUP event when focus leaves your SDL window?

Better yet, you could post the log here and annotate it a bit (write what action you did between each series of events).
Comment 6 Cameron Gutman 2021-01-29 03:15:56 UTC
OK, I played with this a bit. It looks like some differences in how different OSes/WMs handle focus tracking and probably some differences in SDL's behavior on different backends.

On X11 and Wayland, it works as you described. The SDL_MOUSEBUTTONUP is completely dropped if input focus leaves the window while the mouse button is down. As a result, the next SDL_MOUSEBUTTONDOWN is not sent because it is redundant from SDL's perspective (the button is already down).

On Windows, if input focus leaves the window with a mouse button down, we get a SDL_WINDOWEVENT_FOCUS_LOST then the SDL_MOUSEBUTTONUP is delayed until focus re-enters the window. Interesting, you _do_ get a SDL_WINDOWEVENT_LEAVE at the time you lift the mouse button. When input focus returns, you get a SDL_WINDOWEVENT_FOCUS_GAINED followed immediately by the delayed SDL_MOUSEBUTTONUP event.

On macOS, focus stays in the clicked window until the mouse button is released (even if the top-most window is switched with Cmd+Tab), then you will get SDL_MOUSEBUTTONUP and SDL_WINDOWEVENT_FOCUS_LOST after the mouse button is released. This is essentially functioning as you're expecting it to.
Comment 7 Jarosław Siebert 2021-01-29 16:46:28 UTC
Hello,
my log:

Here I click mouse button down
INFO: SDL EVENT: SDL_MOUSEBUTTONDOWN (timestamp=23442 windowid=2 which=0 button=1 state=pressed clicks=1 x=1370 y=775)

here I use key shortcut: ALT+TAB to switch active window

INFO: SDL EVENT: SDL_KEYDOWN (timestamp=24651 windowid=2 state=pressed repeat=false scancode=226 keycode=1073742050 mod=256)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=25206 windowid=2 state=pressed repeat=false scancode=43 keycode=9 mod=256)
INFO: SDL EVENT: SDL_KEYUP (timestamp=25206 windowid=2 state=released repeat=false scancode=43 keycode=9 mod=256)
INFO: SDL EVENT: SDL_KEYUP (timestamp=25206 windowid=2 state=released repeat=false scancode=226 keycode=1073742050 mod=0)

active window change to xterm

INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=25207 windowid=2 event=SDL_WINDOWEVENT_FOCUS_LOST data1=0 data2=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=25263 windowid=2 event=SDL_WINDOWEVENT_LEAVE data1=0 data2=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=32931 windowid=2 event=SDL_WINDOWEVENT_ENTER data1=0 data2=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=33132 windowid=2 event=SDL_WINDOWEVENT_LEAVE data1=0 data2=0)

changing active window with ALT+TAB few times:

INFO: SDL EVENT: SDL_KEYDOWN (timestamp=46557 windowid=2 state=pressed repeat=false scancode=43 keycode=9 mod=0)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=46557 windowid=2 state=pressed repeat=false scancode=226 keycode=1073742050 mod=256)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=46558 windowid=2 event=SDL_WINDOWEVENT_EXPOSED data1=0 data2=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=46558 windowid=2 event=SDL_WINDOWEVENT_ENTER data1=0 data2=0)
INFO: SDL EVENT: SDL_KEYUP (timestamp=46620 windowid=2 state=released repeat=false scancode=226 keycode=1073742050 mod=0)
INFO: SDL EVENT: SDL_KEYUP (timestamp=46670 windowid=2 state=released repeat=false scancode=43 keycode=9 mod=0)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=47070 windowid=2 state=pressed repeat=false scancode=226 keycode=1073742050 mod=256)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=47183 windowid=2 state=pressed repeat=false scancode=43 keycode=9 mod=256)
INFO: SDL EVENT: SDL_KEYUP (timestamp=47183 windowid=2 state=released repeat=false scancode=43 keycode=9 mod=256)
INFO: SDL EVENT: SDL_KEYUP (timestamp=47183 windowid=2 state=released repeat=false scancode=226 keycode=1073742050 mod=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=47183 windowid=2 event=SDL_WINDOWEVENT_FOCUS_LOST data1=0 data2=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=47183 windowid=2 event=SDL_WINDOWEVENT_LEAVE data1=0 data2=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=179650 windowid=2 event=SDL_WINDOWEVENT_FOCUS_GAINED data1=0 data2=0)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=179653 windowid=2 state=pressed repeat=false scancode=43 keycode=9 mod=0)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=179653 windowid=2 state=pressed repeat=false scancode=226 keycode=1073742050 mod=256)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=179658 windowid=2 event=SDL_WINDOWEVENT_EXPOSED data1=0 data2=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=179658 windowid=2 event=SDL_WINDOWEVENT_ENTER data1=0 data2=0)
INFO: SDL EVENT: SDL_KEYUP (timestamp=179715 windowid=2 state=released repeat=false scancode=226 keycode=1073742050 mod=0)
INFO: SDL EVENT: SDL_KEYUP (timestamp=179765 windowid=2 state=released repeat=false scancode=43 keycode=9 mod=0)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=180366 windowid=2 state=pressed repeat=false scancode=226 keycode=1073742050 mod=256)
INFO: SDL EVENT: SDL_KEYDOWN (timestamp=180423 windowid=2 state=pressed repeat=false scancode=43 keycode=9 mod=256)
INFO: SDL EVENT: SDL_KEYUP (timestamp=180423 windowid=2 state=released repeat=false scancode=43 keycode=9 mod=256)
INFO: SDL EVENT: SDL_KEYUP (timestamp=180423 windowid=2 state=released repeat=false scancode=226 keycode=1073742050 mod=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=180423 windowid=2 event=SDL_WINDOWEVENT_FOCUS_LOST data1=0 data2=0)
INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=180473 windowid=2 event=SDL_WINDOWEVENT_LEAVE data1=0 data2=0)

Click mouse button down and up:
INFO: SDL EVENT: SDL_MOUSEBUTTONUP (timestamp=237126 windowid=2 which=0 button=1 state=released clicks=1 x=1343 y=759)

As you described - there is no SDL_MOUSEBUTTONDOWN