|
25 | 25 | // (minor and older changes stripped away, please see git history for details)
|
26 | 26 | // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
27 | 27 | // 2025-04-09: [Docking] Revert update monitors and work areas information every frame. Only do it on Windows. (#8415, #8558)
|
| 28 | +// 2025-04-09: Don't attempt to call SDL_CaptureMouse() on drivers where we don't call SDL_GetGlobalMouseState(). (#8561) |
28 | 29 | // 2025-03-30: Update for SDL3 api changes: Revert SDL_GetClipboardText() memory ownership change. (#8530, #7801)
|
29 | 30 | // 2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
|
30 | 31 | // 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
@@ -120,6 +121,7 @@ struct ImGui_ImplSDL3_Data
|
120 | 121 | SDL_Cursor* MouseLastCursor;
|
121 | 122 | int MousePendingLeaveFrame;
|
122 | 123 | bool MouseCanUseGlobalState;
|
| 124 | + bool MouseCanUseCapture; |
123 | 125 | bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
124 | 126 |
|
125 | 127 | // Gamepad handling
|
@@ -505,39 +507,40 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
505 | 507 | IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
506 | 508 | IM_UNUSED(sdl_gl_context); // Unused in this branch
|
507 | 509 |
|
508 |
| - // Check and store if we are on a SDL backend that supports global mouse position |
509 |
| - // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) |
510 |
| - bool mouse_can_use_global_state = false; |
511 |
| -#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE |
512 |
| - const char* sdl_backend = SDL_GetCurrentVideoDriver(); |
513 |
| - const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" }; |
514 |
| - for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++) |
515 |
| - if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0) |
516 |
| - mouse_can_use_global_state = true; |
517 |
| -#endif |
518 |
| - |
519 | 510 | // Setup backend capabilities flags
|
520 | 511 | ImGui_ImplSDL3_Data* bd = IM_NEW(ImGui_ImplSDL3_Data)();
|
521 | 512 | io.BackendPlatformUserData = (void*)bd;
|
522 | 513 | io.BackendPlatformName = "imgui_impl_sdl3";
|
523 | 514 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
524 | 515 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
525 |
| - if (mouse_can_use_global_state) |
526 |
| - io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) |
| 516 | + // (ImGuiBackendFlags_PlatformHasViewports may be set just below) |
527 | 517 |
|
528 | 518 | bd->Window = window;
|
529 | 519 | bd->WindowID = SDL_GetWindowID(window);
|
530 | 520 | bd->Renderer = renderer;
|
531 | 521 |
|
532 | 522 | // SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
|
533 | 523 | // We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
|
534 |
| - bd->MouseCanUseGlobalState = mouse_can_use_global_state; |
535 | 524 | #ifndef __APPLE__
|
536 | 525 | bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
537 | 526 | #else
|
538 | 527 | bd->MouseCanReportHoveredViewport = false;
|
539 | 528 | #endif
|
540 | 529 |
|
| 530 | + // Check and store if we are on a SDL backend that supports SDL_GetGlobalMouseState() and SDL_CaptureMouse() |
| 531 | + // ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list) |
| 532 | + bd->MouseCanUseGlobalState = false; |
| 533 | + bd->MouseCanUseCapture = false; |
| 534 | +#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE |
| 535 | + const char* sdl_backend = SDL_GetCurrentVideoDriver(); |
| 536 | + const char* capture_and_global_state_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" }; |
| 537 | + for (const char* item : capture_and_global_state_whitelist) |
| 538 | + if (strncmp(sdl_backend, item, strlen(item)) == 0) |
| 539 | + bd->MouseCanUseGlobalState = bd->MouseCanUseCapture = true; |
| 540 | +#endif |
| 541 | + if (bd->MouseCanUseGlobalState) |
| 542 | + io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) |
| 543 | + |
541 | 544 | ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
542 | 545 | platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
543 | 546 | platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
@@ -664,12 +667,15 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
664 | 667 | // We forward mouse input when hovered or captured (via SDL_EVENT_MOUSE_MOTION) or when focused (below)
|
665 | 668 | #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
666 | 669 | // - SDL_CaptureMouse() let the OS know e.g. that our drags can extend outside of parent boundaries (we want updated position) and shouldn't trigger other operations outside.
|
667 |
| - // - Debuggers under Linux tends to leave captured mouse on break, which may be very inconvenient, so to migitate the issue we wait until mouse has moved to begin capture. |
668 |
| - bool want_capture = false; |
669 |
| - for (int button_n = 0; button_n < ImGuiMouseButton_COUNT && !want_capture; button_n++) |
670 |
| - if (ImGui::IsMouseDragging(button_n, 1.0f)) |
671 |
| - want_capture = true; |
672 |
| - SDL_CaptureMouse(want_capture); |
| 670 | + // - Debuggers under Linux tends to leave captured mouse on break, which may be very inconvenient, so to mitigate the issue we wait until mouse has moved to begin capture. |
| 671 | + if (bd->MouseCanUseCapture) |
| 672 | + { |
| 673 | + bool want_capture = false; |
| 674 | + for (int button_n = 0; button_n < ImGuiMouseButton_COUNT && !want_capture; button_n++) |
| 675 | + if (ImGui::IsMouseDragging(button_n, 1.0f)) |
| 676 | + want_capture = true; |
| 677 | + SDL_CaptureMouse(want_capture); |
| 678 | + } |
673 | 679 |
|
674 | 680 | SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
675 | 681 | const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui_ImplSDL3_GetViewportForWindowID(SDL_GetWindowID(focused_window)) != NULL));
|
|
0 commit comments