Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN behaves strangely #962

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 3 comments
Closed
Labels
abandoned Bug has been abandoned for various reasons

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: 2.0.0
Reported for operating system, platform: Windows 7, x86

Comments on the original bug report:

On 2013-07-13 03:39:55 +0000, Stephan T. Lavavej wrote:

Created attachment 1223
Self-contained test case.

I've upgraded from SDL 1.2.15 to 2.0 (built from June 21's sources from hg) and I believe I've discovered a bug. I've prepared a self-contained test case here, and I can even provide my entire build environment if necessary. I'm running MinGW (32-bit) on Win7 x64, with dual 2560x1600 monitors.

What I observe is that FlagsWindowed, FlagsFullscreen, and FlagsDesktop (defined below) work perfectly. The cursor isn't grabbed so it's free to leave the window and travel to the other monitor. Clicking inside the window triggers SDL_MOUSEBUTTONUP and stops the color-changing whose sole purpose is to indicate that a click has been registered. (SDL 1.2's behavior was different, in that fullscreen mode grabbed the cursor. SDL 2.0's not-grabbing by default is perfectly fine, as long as I can request grabbing - which is how I discovered this.)

I additionally observe that FlagsGrabbedWindowed and FlagsGrabbedFocusedWindowed work correctly. The cursor is grabbed so it can't leave the window, and clicking immediately triggers the event and stops the color-changing.

The bug is that FlagsGrabbedFullscreen, FlagsGrabbedDesktop, FlagsGrabbedFocusedFullscreen, and FlagsGrabbedFocusedDesktop behave strangely. The cursor is indeed grabbed so it can't travel to the other monitor, and the fullscreen window is rendered on top of everything else (including an AutoHide taskbar), but the window does not behave as if it is truly on top of everything else. In particular, if other windows are open behind it (e.g. Notepad, a Command Prompt, whatever) the cursor will change from an ordinary pointer to a double-headed resize arrow when it's hovering over the other windows' edges. This is not just a cosmetic cursor defect - clicking will send the click to whatever window happens to be underneath, minimizing the SDL program to the taskbar. After clicking on the SDL program in the taskbar to restore it, the color-changing is still running, indicating that it didn't receive the click. However, the restoring process "fixes" whatever was wrong with the window - the mouse is grabbed and clicking works normally.

I am not sure what SDL_WINDOW_INPUT_FOCUS and SDL_WINDOW_MOUSE_FOCUS are supposed to do, but their absence/presence doesn't seem to affect anything.

Here is my code (dramatically simplified from my actual game engine, with all error-checking and other libraries eliminated):

// g++ -Wall -Wextra -mthreads -mwindows meow.cpp -o meow.exe -lopengl32 -lSDL2 -limm32 -lole32 -loleaut32 -luuid -lversion -lwinmm -lmingw32 -lSDL2main

#include <GL/gl.h>
#include <SDL2/SDL.h>

const Uint32 FlagsWindowed = 0;
const Uint32 FlagsFullscreen = SDL_WINDOW_FULLSCREEN;
const Uint32 FlagsDesktop = SDL_WINDOW_FULLSCREEN_DESKTOP;
const Uint32 FlagsGrabbedWindowed = SDL_WINDOW_INPUT_GRABBED;
const Uint32 FlagsGrabbedFullscreen = SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN;
const Uint32 FlagsGrabbedDesktop = SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN_DESKTOP;
const Uint32 FlagsGrabbedFocusedWindowed = SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS;
const Uint32 FlagsGrabbedFocusedFullscreen = SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_FULLSCREEN;
const Uint32 FlagsGrabbedFocusedDesktop = SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_FULLSCREEN_DESKTOP;

int main(int, char * []) {
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

#ifndef MY_WIDTH
    #define MY_WIDTH 1920
#endif

#ifndef MY_HEIGHT
    #define MY_HEIGHT 1200
#endif

#ifndef MY_FLAGS
    #define MY_FLAGS FlagsWindowed
#endif

SDL_Window * window = SDL_CreateWindow("Meow", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, MY_WIDTH, MY_HEIGHT, SDL_WINDOW_OPENGL | MY_FLAGS);
SDL_GLContext context = SDL_GL_CreateContext(window);
bool changing = true;
const Uint64 freq = SDL_GetPerformanceFrequency();

for (bool keep_going = true; keep_going; ) {
    for (SDL_Event event; SDL_PollEvent(&event); ) {
        switch (event.type) {
            case SDL_KEYDOWN:
            case SDL_QUIT:
                keep_going = false;
                break;
            case SDL_MOUSEBUTTONUP:
                changing = !changing;
                break;
            default:
                break;
        }
    }

    if (changing) {
        const double d = (SDL_GetPerformanceCounter() % freq) * 1.0 / freq;
        glClearColor(d, d, d, 1.0);
    }

    glClear(GL_COLOR_BUFFER_BIT);
    SDL_GL_SwapWindow(window);
}

SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;

}

I have provided the Flags* constants and MY_* macros for convenience, so you can build the test case with varying command lines like:

g++ -Wall -Wextra -mthreads -mwindows meow.cpp -o meow.exe -lopengl32 -lSDL2 -limm32 -lole32 -loleaut32 -luuid -lversion -lwinmm -lmingw32 -lSDL2main -DMY_FLAGS=FlagsGrabbedDesktop

instead of repeatedly altering the file.

On 2013-07-13 06:16:54 +0000, Stephan T. Lavavej wrote:

I believe I've found a workaround - instead of passing SDL_WINDOW_INPUT_GRABBED to SDL_CreateWindow(), calling SDL_SetWindowGrab() immediately after SDL_CreateWindow() works.

On 2018-08-06 21:20:24 +0000, Ryan C. Gordon wrote:

Hello, and sorry if you're getting dozens of copies of this message by email.

We are closing out bugs that appear to be abandoned in some form. This can happen for lots of reasons: we couldn't reproduce it, conversation faded out, the bug was noted as fixed in a comment but we forgot to mark it resolved, the report is good but the fix is impractical, we fixed it a long time ago without realizing there was an associated report, etc.

Individually, any of these bugs might have a better resolution (such as WONTFIX or WORKSFORME or INVALID) but we've added a new resolution of ABANDONED to make this easily searchable and make it clear that it's not necessarily unreasonable to revive a given bug report.

So if this bug is still a going concern and you feel it should still be open: please feel free to reopen it! But unless you respond, we'd like to consider these bugs closed, as many of them are several years old and overwhelming our ability to prioritize recent issues.

(please note that hundred of bug reports were sorted through here, so we apologize for any human error. Just reopen the bug in that case!)

Thanks,
--ryan.

@glebm
Copy link
Contributor

glebm commented Apr 2, 2022

We've just encountered this issue in 2022 on macOS.

I believe I've found a workaround - instead of passing SDL_WINDOW_INPUT_GRABBED to SDL_CreateWindow(), calling SDL_SetWindowGrab() immediately after SDL_CreateWindow() works.

Will see if the workaround works

/cc @StephanTLavavej

@glebm
Copy link
Contributor

glebm commented Apr 2, 2022

The workaround does work

@pionere
Copy link
Contributor

pionere commented Apr 2, 2022

Maybe pWinData->hwnd should be passed to WinSetCapture in _mouseCheck ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
abandoned Bug has been abandoned for various reasons
Projects
None yet
Development

No branches or pull requests

3 participants