summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2022-07-26 12:52:33 +0200
committerGitHub <noreply@github.com>2022-07-26 12:52:33 +0200
commit9d15a1c5a1e6183a0e98165ac093e74ca8e4894e (patch)
treebb9806ee563adf38a74e55506f1e387e0bd08b72 /Source/Core/InputCommon/ControllerInterface
parentc7752f80e4803362c58c03e0510680e95f4061c6 (diff)
parentd14bd10cd74ecfb9777e19dde842fe64d7681605 (diff)
Merge pull request #10858 from AdmiralCurtiss/mouse-center-hotkey
Add hotkey for centering mouse in render window.
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp10
-rw-r--r--Source/Core/InputCommon/ControllerInterface/ControllerInterface.h6
-rw-r--r--Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp29
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm38
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp48
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h2
6 files changed, 102 insertions, 31 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp
index 1c4dc71da8..442e5502fa 100644
--- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp
@@ -421,6 +421,16 @@ Common::Vec2 ControllerInterface::GetWindowInputScale() const
return {1 / ar, 1.f};
}
+void ControllerInterface::SetMouseCenteringRequested(bool center)
+{
+ m_requested_mouse_centering = center;
+}
+
+bool ControllerInterface::IsMouseCenteringRequested() const
+{
+ return m_requested_mouse_centering.load();
+}
+
// Register a callback to be called when a device is added or removed (as from the input backends'
// hotplug thread), or when devices are refreshed
// Returns a handle for later removing the callback.
diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
index 2f43cacc42..3a0276de41 100644
--- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
+++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
@@ -106,6 +106,11 @@ public:
// Inputs based on window coordinates should be multiplied by this.
Common::Vec2 GetWindowInputScale() const;
+ // Request that the mouse cursor should be centered in the render window at the next opportunity.
+ void SetMouseCenteringRequested(bool center);
+
+ bool IsMouseCenteringRequested() const;
+
HotplugCallbackHandle RegisterDevicesChangedCallback(std::function<void(void)> callback);
void UnregisterDevicesChangedCallback(const HotplugCallbackHandle& handle);
void InvokeDevicesChangedCallbacks() const;
@@ -127,6 +132,7 @@ private:
std::atomic<int> m_populating_devices_counter;
WindowSystemInfo m_wsi;
std::atomic<float> m_aspect_ratio_adjustment = 1;
+ std::atomic<bool> m_requested_mouse_centering = false;
};
namespace ciface
diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp
index 3fe850715c..551afde423 100644
--- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp
@@ -6,7 +6,9 @@
#include <algorithm>
#include "Common/Logging/Log.h"
+
#include "Core/Core.h"
+#include "Core/Host.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "InputCommon/ControllerInterface/DInput/DInput.h"
@@ -168,13 +170,6 @@ KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device,
void KeyboardMouse::UpdateCursorInput()
{
- POINT point = {};
- GetCursorPos(&point);
-
- // Get the cursor position relative to the upper left corner of the current window
- // (separate or render to main)
- ScreenToClient(s_hwnd, &point);
-
// Get the size of the current window (in my case Rect.top and Rect.left was zero).
RECT rect;
GetClientRect(s_hwnd, &rect);
@@ -183,6 +178,26 @@ void KeyboardMouse::UpdateCursorInput()
const auto win_width = std::max(rect.right - rect.left, 1l);
const auto win_height = std::max(rect.bottom - rect.top, 1l);
+ POINT point = {};
+ if (g_controller_interface.IsMouseCenteringRequested() && Host_RendererHasFocus())
+ {
+ point.x = win_width / 2;
+ point.y = win_height / 2;
+
+ POINT screen_point = point;
+ ClientToScreen(s_hwnd, &screen_point);
+ SetCursorPos(screen_point.x, screen_point.y);
+ g_controller_interface.SetMouseCenteringRequested(false);
+ }
+ else
+ {
+ GetCursorPos(&point);
+
+ // Get the cursor position relative to the upper left corner of the current window
+ // (separate or render to main)
+ ScreenToClient(s_hwnd, &point);
+ }
+
const auto window_scale = g_controller_interface.GetWindowInputScale();
// Convert the cursor position to a range from -1 to 1.
diff --git a/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm b/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm
index 6b1790149b..b8ae0219be 100644
--- a/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm
+++ b/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm
@@ -8,6 +8,8 @@
#include <Carbon/Carbon.h>
#include <Cocoa/Cocoa.h>
+#include "Core/Host.h"
+
#include "InputCommon/ControllerInterface/ControllerInterface.h"
namespace ciface::Quartz
@@ -192,16 +194,36 @@ void KeyboardAndMouse::UpdateInput()
CFRelease(windowDescriptions);
CFRelease(windowArray);
- CGEventRef event = CGEventCreate(nil);
- CGPoint loc = CGEventGetLocation(event);
- CFRelease(event);
+ const double window_width = std::max(bounds.size.width, 1.0);
+ const double window_height = std::max(bounds.size.height, 1.0);
+
+ if (g_controller_interface.IsMouseCenteringRequested() && Host_RendererHasFocus())
+ {
+ m_cursor.x = 0;
+ m_cursor.y = 0;
- const auto window_scale = g_controller_interface.GetWindowInputScale();
+ const CGPoint window_center_global_coordinates =
+ CGPointMake(bounds.origin.x + window_width / 2.0, bounds.origin.y + window_height / 2.0);
+ CGWarpMouseCursorPosition(window_center_global_coordinates);
+ // Without this line there is a short but obvious delay after centering the cursor before it can
+ // be moved again
+ CGAssociateMouseAndMouseCursorPosition(true);
- loc.x -= bounds.origin.x;
- loc.y -= bounds.origin.y;
- m_cursor.x = (loc.x / std::max(bounds.size.width, 1.0) * 2 - 1.0) * window_scale.x;
- m_cursor.y = (loc.y / std::max(bounds.size.height, 1.0) * 2 - 1.0) * window_scale.y;
+ g_controller_interface.SetMouseCenteringRequested(false);
+ }
+ else
+ {
+ CGEventRef event = CGEventCreate(nil);
+ CGPoint loc = CGEventGetLocation(event);
+ CFRelease(event);
+
+ const auto window_scale = g_controller_interface.GetWindowInputScale();
+
+ loc.x -= bounds.origin.x;
+ loc.y -= bounds.origin.y;
+ m_cursor.x = (loc.x / window_width * 2 - 1.0) * window_scale.x;
+ m_cursor.y = (loc.y / window_height * 2 - 1.0) * window_scale.y;
+ }
}
std::string KeyboardAndMouse::GetName() const
diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp
index 1f8e107987..0c5f5ffb01 100644
--- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp
@@ -15,6 +15,8 @@
#include "Common/StringUtil.h"
+#include "Core/Host.h"
+
// This is an input plugin using the XInput 2.0 extension to the X11 protocol,
// loosely based on the old XLib plugin. (Has nothing to do with the XInput
// API on Windows.)
@@ -209,30 +211,44 @@ KeyboardMouse::~KeyboardMouse()
}
// Update the mouse cursor controls
-void KeyboardMouse::UpdateCursor()
+void KeyboardMouse::UpdateCursor(bool should_center_mouse)
{
double root_x, root_y, win_x, win_y;
Window root, child;
- // unused-- we're not interested in button presses here, as those are
- // updated using events
- XIButtonState button_state;
- XIModifierState mods;
- XIGroupState group;
+ XWindowAttributes win_attribs;
+ XGetWindowAttributes(m_display, m_window, &win_attribs);
+ const auto win_width = std::max(win_attribs.width, 1);
+ const auto win_height = std::max(win_attribs.height, 1);
- XIQueryPointer(m_display, pointer_deviceid, m_window, &root, &child, &root_x, &root_y, &win_x,
- &win_y, &button_state, &mods, &group);
+ if (should_center_mouse)
+ {
+ win_x = win_width / 2;
+ win_y = win_height / 2;
- free(button_state.mask);
+ XIWarpPointer(m_display, pointer_deviceid, None, m_window, 0.0, 0.0, 0, 0, win_x, win_y);
- XWindowAttributes win_attribs;
- XGetWindowAttributes(m_display, m_window, &win_attribs);
+ g_controller_interface.SetMouseCenteringRequested(false);
+ }
+ else
+ {
+ // unused-- we're not interested in button presses here, as those are
+ // updated using events
+ XIButtonState button_state;
+ XIModifierState mods;
+ XIGroupState group;
+
+ XIQueryPointer(m_display, pointer_deviceid, m_window, &root, &child, &root_x, &root_y, &win_x,
+ &win_y, &button_state, &mods, &group);
+
+ free(button_state.mask);
+ }
const auto window_scale = g_controller_interface.GetWindowInputScale();
// the mouse position as a range from -1 to 1
- m_state.cursor.x = (win_x / std::max(win_attribs.width, 1) * 2 - 1) * window_scale.x;
- m_state.cursor.y = (win_y / std::max(win_attribs.height, 1) * 2 - 1) * window_scale.y;
+ m_state.cursor.x = (win_x / win_width * 2 - 1) * window_scale.x;
+ m_state.cursor.y = (win_y / win_height * 2 - 1) * window_scale.y;
}
void KeyboardMouse::UpdateInput()
@@ -318,8 +334,10 @@ void KeyboardMouse::UpdateInput()
m_state.axis.y /= MOUSE_AXIS_SMOOTHING + 1.0f;
// Get the absolute position of the mouse pointer
- if (mouse_moved)
- UpdateCursor();
+ const bool should_center_mouse =
+ g_controller_interface.IsMouseCenteringRequested() && Host_RendererHasFocus();
+ if (mouse_moved || should_center_mouse)
+ UpdateCursor(should_center_mouse);
// KeyRelease and FocusOut events are sometimes not received.
// Cycling Alt-Tab and landing on the same window results in a stuck "Alt" key.
diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h
index 482bc37830..b07f6325c7 100644
--- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h
+++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h
@@ -108,7 +108,7 @@ private:
private:
void SelectEventsForDevice(XIEventMask* mask, int deviceid);
- void UpdateCursor();
+ void UpdateCursor(bool should_center_mouse);
public:
void UpdateInput() override;