Skip to content

Commit

Permalink
Backends: Win32, SDL: maintain MouseButtonsDown instead of using IsAn…
Browse files Browse the repository at this point in the history
…yMouseDown(). Internals: added GetInputSourceName().
  • Loading branch information
ocornut committed Jan 12, 2022
1 parent 457d4b7 commit 7f8a89c
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 11 deletions.
17 changes: 13 additions & 4 deletions backends/imgui_impl_sdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
Expand Down Expand Up @@ -74,6 +75,7 @@ struct ImGui_ImplSDL2_Data
{
SDL_Window* Window;
Uint64 Time;
int MouseButtonsDown;
bool MousePressed[3];
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
char* ClipboardTextData;
Expand Down Expand Up @@ -240,10 +242,17 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
return true;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
if (event->button.button == SDL_BUTTON_LEFT) { bd->MousePressed[0] = true; }
if (event->button.button == SDL_BUTTON_RIGHT) { bd->MousePressed[1] = true; }
if (event->button.button == SDL_BUTTON_MIDDLE) { bd->MousePressed[2] = true; }
int mouse_button = -1;
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; }
if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; }
if (mouse_button == -1)
break;
if (event->type == SDL_MOUSEBUTTONDOWN)
bd->MousePressed[mouse_button] = true;
bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
return true;
}
case SDL_TEXTINPUT:
Expand Down Expand Up @@ -409,7 +418,7 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
mouse_window = focused_window;

// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
SDL_CaptureMouse(ImGui::IsAnyMouseDown() ? SDL_TRUE : SDL_FALSE);
SDL_CaptureMouse(bd->MouseButtonsDown != 0 ? SDL_TRUE : SDL_FALSE);
#else
// SDL 2.0.3 and non-windowed systems: single-viewport only
SDL_Window* mouse_window = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) ? bd->Window : NULL;
Expand Down
8 changes: 6 additions & 2 deletions backends/imgui_impl_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
Expand Down Expand Up @@ -74,6 +75,7 @@ struct ImGui_ImplWin32_Data
HWND hWnd;
HWND MouseHwnd;
bool MouseTracked;
int MouseButtonsDown;
INT64 Time;
INT64 TicksPerSecond;
ImGuiMouseCursor LastMouseCursor;
Expand Down Expand Up @@ -531,9 +533,10 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL)
::SetCapture(hwnd);
io.MouseDown[button] = true;
bd->MouseButtonsDown |= 1 << button;
return 0;
}
case WM_LBUTTONUP:
Expand All @@ -547,7 +550,8 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
if (msg == WM_MBUTTONUP) { button = 2; }
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
io.MouseDown[button] = false;
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
bd->MouseButtonsDown &= ~(1 << button);
if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
::ReleaseCapture();
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Other Changes:
We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of every
other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625)
- Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts.
- Backends: Win32, SDL: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
- Backends: Allegro5, GLFW, GLUT, SDL, OSX, Win32, Android: Updated to use io.AddKeyEvent() with full key range. (#2625) [@thedmd]
- Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk]
It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers.
Expand Down
14 changes: 10 additions & 4 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7585,6 +7585,7 @@ bool ImGui::IsMousePosValid(const ImVec2* mouse_pos)
return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID;
}

// [WILL OBSOLETE] This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid.
bool ImGui::IsAnyMouseDown()
{
ImGuiContext& g = *GImGui;
Expand Down Expand Up @@ -7642,6 +7643,13 @@ void ImGui::CaptureMouseFromApp(bool capture)
g.WantCaptureMouseNextFrame = capture ? 1 : 0;
}

static const char* GetInputSourceName(ImGuiInputSource source)
{
const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Nav", "Clipboard" };
IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT && source >= 0 && source < ImGuiInputSource_COUNT);
return input_source_names[source];
}


//-----------------------------------------------------------------------------
// [SECTION] ERROR CHECKING
Expand Down Expand Up @@ -12107,8 +12115,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
// Misc Details
if (TreeNode("Internal state"))
{
const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Nav", "Clipboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT);

Text("WINDOWING");
Indent();
Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
Expand All @@ -12119,7 +12125,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)

Text("ITEMS");
Indent();
Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, input_source_names[g.ActiveIdSource]);
Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, GetInputSourceName(g.ActiveIdSource));
Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");

int active_id_using_key_input_count = 0;
Expand All @@ -12134,7 +12140,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Indent();
Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL");
Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer);
Text("NavInputSource: %s", input_source_names[g.NavInputSource]);
Text("NavInputSource: %s", GetInputSourceName(g.NavInputSource));
Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible);
Text("NavActivateId/DownId/PressedId/InputId: %08X/%08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId, g.NavActivateInputId);
Text("NavActivateFlags: %04X", g.NavActivateFlags);
Expand Down
2 changes: 1 addition & 1 deletion imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ namespace ImGui
IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0).
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
IMGUI_API bool IsAnyMouseDown(); // is any mouse button held?
IMGUI_API bool IsAnyMouseDown(); // [WILL OBSOLETE] is any mouse button held? This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid.
IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls
IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve mouse position at the time of opening popup we have BeginPopup() into (helper to avoid user backing that value themselves)
IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold)
Expand Down

0 comments on commit 7f8a89c

Please sign in to comment.