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

SDL2 + Touch on linux doesn't work correctly #8150

Open
miffe opened this issue Nov 14, 2024 · 5 comments
Open

SDL2 + Touch on linux doesn't work correctly #8150

miffe opened this issue Nov 14, 2024 · 5 comments

Comments

@miffe
Copy link

miffe commented Nov 14, 2024

Version/Branch of Dear ImGui:

Version 1.91.5, Branch: master

Back-ends:

imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer2.cpp

Compiler, OS:

Arch Linux + gcc version 14.2.1 20240910 + SDL 2.30.9

Full config/build information:

Dear ImGui 1.91.5 (19150)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201703
define: __linux__
define: __GNUC__=14
--------------------------------
io.BackendPlatformName: imgui_impl_sdl2
io.BackendRendererName: imgui_impl_sdlrenderer2
io.ConfigFlags: 0x00000000
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x0000000E
 HasMouseCursors
 HasSetMousePos
 RendererHasVtxOffset
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

Hi,

My issue is that touch events stop working after the first tap on linux with the SDL2 backend. The attached testcode gives the following output and nothing more, even with multiple taps. Normal mouse buttons continue to work correctly.

Mouse down which=-1 button=1
Mouse down which=0 button=1
Mouse up which=0 button=1

Strange thing is when I comment out the call to ImGui_ImplSDL2_ProcessEvent, SDL reports the touch events correctly.

Also it works fine on Windows.

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

#include <SDL.h>
#include <imgui.h>
#include <imgui_impl_sdl2.h>
#include <imgui_impl_sdlrenderer2.h>
#include <stdio.h>

int main(int argc, char** argv) {
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        printf("SDL_Init Error: %s\n", SDL_GetError());
        return 1;
    }

    SDL_Window* window = NULL;
    SDL_Renderer* renderer = NULL;

    if ((window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE)) == NULL) {
        printf("SDL_CreateWindow Error: %s\n", SDL_GetError());
        return 1;
    }

    if ((renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)) == NULL) {
        printf("SDL_CreateRenderer Error: %s\n", SDL_GetError());
        return 1;
    }

    ImGui::CreateContext();
    ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
    ImGui_ImplSDLRenderer2_Init(renderer);

    while (true) {
        ImGui_ImplSDL2_NewFrame();
        ImGui_ImplSDLRenderer2_NewFrame();
        ImGui::NewFrame();

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_QUIT:
                goto out;
            case SDL_MOUSEBUTTONDOWN:
                printf("Mouse down which=%d button=%d\n", event.button.which, event.button.button);
                break;
            case SDL_MOUSEBUTTONUP:
                printf("Mouse up which=%d button=%d\n", event.button.which, event.button.button);
                break;
            }
            ImGui_ImplSDL2_ProcessEvent(&event);
        }

        ImGui::ShowDemoWindow();

        ImGui::Render();

        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), renderer);
        SDL_RenderPresent(renderer);
    }

out:

    ImGui_ImplSDLRenderer2_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}
@ocornut
Copy link
Owner

ocornut commented Nov 14, 2024

Strange thing is when I comment out the call to ImGui_ImplSDL2_ProcessEvent, SDL reports the touch events correctly.

This is very strange indeed, because if you look inside ImGui_ImplSDL2_ProcessEvent() it shouldn't be doing anything that seem like it would have a side-effect on SDL2 event processing.

I suppose you would need to investigate the code in ImGui_ImplSDL2_ProcessEvent(), e.g. comment out selected parts to try to understand how/why this is having a side-effect and we can work from there.

(Unrelated to your specific issue but: your event loop should be processed above the NewFrame calls, otherwise your events will be processed one frame late)

@miffe
Copy link
Author

miffe commented Nov 14, 2024

Commenting out the SDL_CaptureMouse call in ImGui_ImplSDL2_UpdateMouseData fixes the issue. But I'm unsure what side effects this will have.

@ocornut
Copy link
Owner

ocornut commented Nov 14, 2024

Thanks for investigating. I see that the event handler by writing to bd->MouseButtonsDown has an effect on ImGui_ImplSDL2_NewFrame(). Mouse capture allows accessing mouse coordinates when outside of the platform window boundaries.

Typically when you do a mouse-down and drag you want the app to receive mouse movement even outside the mouse boundaries.

I'm finding it odd that this break touch inputs. I would say it might be a bug in SDL2.
Do you think you can try compiling the SDL3 example with SDL3 latest and see if it also happens?

@miffe
Copy link
Author

miffe commented Nov 14, 2024

It works with SDL3, but give double mouse down/up events.

Ie:

Mouse down which=0 button=1
Mouse down which=-1 button=1
Mouse up which=0 button=1
Mouse up which=-1 button=1
Mouse down which=0 button=1
Mouse down which=-1 button=1
Mouse up which=0 button=1
Mouse up which=-1 button=1

Testcode:

#include <SDL3/SDL.h>
#include <imgui.h>
#include <imgui_impl_sdl3.h>
#include <imgui_impl_sdlrenderer3.h>
#include <stdio.h>

int main(int argc, char** argv) {
    if (!SDL_Init(SDL_INIT_VIDEO)) {
        printf("SDL_Init Error: %s\n", SDL_GetError());
        return 1;
    }

    SDL_Window* window = NULL;
    SDL_Renderer* renderer = NULL;

    if ((window = SDL_CreateWindow("SDL3 test", 1280, 720, SDL_WINDOW_RESIZABLE)) == NULL) {
        printf("SDL_CreateWindow Error: %s\n", SDL_GetError());
        return 1;
    }

    if ((renderer = SDL_CreateRenderer(window, NULL)) == NULL) {
        printf("SDL_CreateRenderer Error: %s\n", SDL_GetError());
        return 1;
    }

    ImGui::CreateContext();
    ImGui_ImplSDL3_InitForSDLRenderer(window, renderer);
    ImGui_ImplSDLRenderer3_Init(renderer);

    while (true) {
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_EVENT_QUIT:
                goto out;
            case SDL_EVENT_MOUSE_BUTTON_DOWN:
                printf("Mouse down which=%d button=%d\n", event.button.which, event.button.button);
                break;
            case SDL_EVENT_MOUSE_BUTTON_UP:
                printf("Mouse up which=%d button=%d\n", event.button.which, event.button.button);
                break;
            }
            ImGui_ImplSDL3_ProcessEvent(&event);
        }

        ImGui_ImplSDL3_NewFrame();
        ImGui_ImplSDLRenderer3_NewFrame();
        ImGui::NewFrame();

        ImGui::ShowDemoWindow();

        ImGui::Render();

        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), renderer);
        SDL_RenderPresent(renderer);

        ImGui::EndFrame();
    }

out:

    ImGui_ImplSDLRenderer3_Shutdown();
    ImGui_ImplSDL3_Shutdown();
    ImGui::DestroyContext();

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

@ocornut
Copy link
Owner

ocornut commented Nov 14, 2024

It works with SDL3, but give double mouse down/up events

This shouldn’t be a problem at least for the imgui backends.

So i guess this is a bug in SDL2, maybe fixed in latest SDL2 I don’t know. Feedback may be best addressed to SDL repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants