Qt: Fix handling of mouse double-click events

- Fixes double-click events with mouse binds getting dropped.
- Fixes early release event when toggling fullscreen.
This commit is contained in:
Stenzek
2025-12-25 19:55:47 +10:00
parent 182075675d
commit e2aa1ae24c
4 changed files with 46 additions and 6 deletions

View File

@@ -327,13 +327,11 @@ bool DisplayWidget::event(QEvent* event)
case QEvent::MouseButtonDblClick:
{
// since we don't get press and release events for double-click, we need to send both the down and up
// otherwise the second click in a double click won't be registered by the input system
// we don't get press events for double-click, the dblclick event is substituted instead
if (!m_relative_mouse_enabled || !InputManager::IsUsingRawInput())
{
const u32 button_index = CountTrailingZeros(static_cast<u32>(static_cast<const QMouseEvent*>(event)->button()));
emit windowMouseButtonEvent(static_cast<int>(button_index), true);
emit windowMouseButtonEvent(static_cast<int>(button_index), false);
}
// don't toggle fullscreen when we're bound.. that wouldn't end well.
@@ -344,6 +342,12 @@ bool DisplayWidget::event(QEvent* event)
Core::GetBoolSettingValue("Main", "DoubleClickTogglesFullscreen", true))
{
g_core_thread->toggleFullscreen();
// when swapping fullscreen, the window is going to get recreated, and we won't get the release event.
// therefore we need to trigger it here instead, otherwise it gets lost and imgui is confused.
// skip this if we're not running on wankland or using render-to-main, since the window is preserved.
if (QtHost::IsDisplayWidgetContainerNeeded() || g_main_window->canRenderToMainWindow())
Host::RunOnCoreThread(&ImGuiManager::ClearMouseButtonState);
}
return true;

View File

@@ -119,6 +119,9 @@ public:
/// Updates debug menu visibility (hides if disabled).
void updateDebugMenuVisibility();
/// Returns true if rendering to the main window should be allowed.
bool canRenderToMainWindow() const;
void refreshGameList(bool invalidate_cache);
void cancelGameListRefresh();
QIcon getIconForGame(const QString& path);
@@ -183,9 +186,6 @@ private:
void saveDisplayWindowGeometryToConfig();
void restoreDisplayWindowGeometryFromConfig();
/// Returns true if rendering to the main window should be allowed.
bool canRenderToMainWindow() const;
/// Returns true if the separate-window display widget should use the main window coordinates.
bool useMainWindowGeometryForDisplayWindow() const;

View File

@@ -1415,6 +1415,39 @@ bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, float value
return s_state.imgui_wants_keyboard.load(std::memory_order_acquire);
}
void ImGuiManager::ClearMouseButtonState()
{
if (!s_state.imgui_context)
return;
GPUThread::RunOnThread([]() {
if (!s_state.imgui_context)
return;
ImGuiIO& io = s_state.imgui_context->IO;
for (int i = 0; i < ImGuiMouseButton_COUNT; i++)
{
bool current_state = io.MouseDown[i];
for (int n = s_state.imgui_context->InputEventsQueue.Size - 1; n >= 0; n--)
{
const ImGuiInputEvent& event = s_state.imgui_context->InputEventsQueue[n];
if (event.Type == ImGuiInputEventType_MouseButton && event.MouseButton.Button == i)
{
current_state = event.MouseButton.Down;
break;
}
}
// not down?
if (!current_state)
continue;
// Queue a button up event.
s_state.imgui_context->IO.AddMouseButtonEvent(i, false);
}
});
}
const char* ImGuiManager::GetClipboardTextImpl(ImGuiContext* ctx)
{
const std::string text = Host::GetClipboardText();

View File

@@ -174,6 +174,9 @@ bool ProcessHostKeyEvent(InputBindingKey key, float value);
/// Called on the CPU thread when any input event fires. Allows imgui to take over controller navigation.
bool ProcessGenericInputEvent(GenericInputBinding key, float value);
/// Resets the state of ImGui mouse buttons, call after the window is changed and events get lost.
void ClearMouseButtonState();
/// Sets an image and scale for a software cursor. Software cursors can be used for things like crosshairs.
void SetSoftwareCursor(u32 index, std::string image_path, float image_scale, u32 multiply_color = 0xFFFFFF);
bool HasSoftwareCursor(u32 index);