diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index c64eb1e22e..b5a4b13ce0 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -456,10 +456,14 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi return; } + // The frontend will likely have initialized the controller interface, as it needs + // it to provide the configuration dialogs. In this case, instead of re-initializing + // entirely, we switch the window used for inputs to the render window. This way, the + // cursor position is relative to the render window, instead of the main window. bool init_controllers = false; if (!g_controller_interface.IsInit()) { - g_controller_interface.Initialize(wsi.render_surface); + g_controller_interface.Initialize(wsi); Pad::Initialize(); Keyboard::Initialize(); init_controllers = true; @@ -467,6 +471,7 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi else { // Update references in case controllers were refreshed + g_controller_interface.ChangeWindow(wsi.render_surface); Pad::LoadConfig(); Keyboard::LoadConfig(); } diff --git a/Source/Core/DolphinQt/Host.cpp b/Source/Core/DolphinQt/Host.cpp index daaaee14b0..c4d3711eda 100644 --- a/Source/Core/DolphinQt/Host.cpp +++ b/Source/Core/DolphinQt/Host.cpp @@ -19,6 +19,8 @@ #include "DolphinQt/QtUtils/QueueOnObject.h" #include "DolphinQt/Settings.h" +#include "InputCommon/ControllerInterface/ControllerInterface.h" + #include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoConfig.h" @@ -32,8 +34,16 @@ Host* Host::GetInstance() void Host::SetRenderHandle(void* handle) { + if (m_render_handle == handle) + return; + + m_render_handle = handle; if (g_renderer) + { g_renderer->ChangeSurface(handle); + if (g_controller_interface.IsInit()) + g_controller_interface.ChangeWindow(handle); + } } bool Host::GetRenderFocus() diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index ec15365e55..e2b9e15791 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -169,6 +169,7 @@ MainWindow::MainWindow(std::unique_ptr boot_parameters) : QMainW setWindowIcon(Resources::GetAppIcon()); setUnifiedTitleAndToolBarOnMac(true); setAcceptDrops(true); + setAttribute(Qt::WA_NativeWindow); InitControllers(); @@ -237,7 +238,7 @@ void MainWindow::InitControllers() if (g_controller_interface.IsInit()) return; - g_controller_interface.Initialize(reinterpret_cast(winId())); + g_controller_interface.Initialize(GetWindowSystemInfo(windowHandle())); Pad::Initialize(); Keyboard::Initialize(); Wiimote::Initialize(Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES); @@ -874,7 +875,8 @@ void MainWindow::SetFullScreenResolution(bool fullscreen) // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. ChangeDisplaySettings(&screen_settings, CDS_FULLSCREEN); #elif defined(HAVE_XRANDR) && HAVE_XRANDR - m_xrr_config->ToggleDisplayMode(fullscreen); + if (m_xrr_config) + m_xrr_config->ToggleDisplayMode(fullscreen); #endif } @@ -938,6 +940,11 @@ void MainWindow::HideRenderWidget(bool reinit) if (m_render_widget->isFullScreen()) SetFullScreenResolution(focus); }); + + // The controller interface will still be registered to the old render widget, if the core + // has booted. Therefore, we should re-bind it to the main window for now. When the core + // is next started, it will be swapped back to the new render widget. + g_controller_interface.ChangeWindow(GetWindowSystemInfo(windowHandle()).render_surface); } } @@ -1003,14 +1010,18 @@ void MainWindow::ShowGraphicsWindow() if (!m_graphics_window) { #if defined(HAVE_XRANDR) && HAVE_XRANDR - m_xrr_config = std::make_unique( - static_cast(QGuiApplication::platformNativeInterface()->nativeResourceForWindow( - "display", windowHandle())), - winId()); + if (GetWindowSystemType() == WindowSystemType::X11) + { + m_xrr_config = std::make_unique( + static_cast(QGuiApplication::platformNativeInterface()->nativeResourceForWindow( + "display", windowHandle())), + winId()); + } m_graphics_window = new GraphicsWindow(m_xrr_config.get(), this); #else m_graphics_window = new GraphicsWindow(nullptr, this); #endif + InstallHotkeyFilter(m_graphics_window); } m_graphics_window->show(); @@ -1273,7 +1284,8 @@ void MainWindow::NetPlayQuit() void MainWindow::EnableScreenSaver(bool enable) { #if defined(HAVE_XRANDR) && HAVE_XRANDR - UICommon::EnableScreenSaver(winId(), enable); + if (GetWindowSystemType() == WindowSystemType::X11) + UICommon::EnableScreenSaver(winId(), enable); #else UICommon::EnableScreenSaver(enable); #endif diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index eaec778b5d..937e3beb7c 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -173,7 +173,7 @@ private: MenuBar* m_menu_bar; SearchBar* m_search_bar; GameList* m_game_list; - RenderWidget* m_render_widget; + RenderWidget* m_render_widget = nullptr; bool m_rendering_to_main; bool m_stop_requested = false; bool m_exit_requested = false; diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index 0e6857c137..9f6e7c5179 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -41,12 +41,12 @@ ControllerInterface g_controller_interface; // // Detect devices and inputs outputs / will make refresh function later // -void ControllerInterface::Initialize(void* const hwnd) +void ControllerInterface::Initialize(const WindowSystemInfo& wsi) { if (m_is_init) return; - m_hwnd = hwnd; + m_wsi = wsi; m_is_populating_devices = true; #ifdef CIFACE_USE_DINPUT @@ -59,7 +59,8 @@ void ControllerInterface::Initialize(void* const hwnd) // nothing needed #endif #ifdef CIFACE_USE_OSX - ciface::OSX::Init(hwnd); + if (m_wsi.type == WindowSystemType::MacOS) + ciface::OSX::Init(wsi.render_surface); // nothing needed for Quartz #endif #ifdef CIFACE_USE_SDL @@ -79,6 +80,15 @@ void ControllerInterface::Initialize(void* const hwnd) RefreshDevices(); } +void ControllerInterface::ChangeWindow(void* hwnd) +{ + if (!m_is_init) + return; + + m_wsi.render_surface = hwnd; + RefreshDevices(); +} + void ControllerInterface::RefreshDevices() { if (!m_is_init) @@ -92,17 +102,22 @@ void ControllerInterface::RefreshDevices() m_is_populating_devices = true; #ifdef CIFACE_USE_DINPUT - ciface::DInput::PopulateDevices(reinterpret_cast(m_hwnd)); + if (m_wsi.type == WindowSystemType::Windows) + ciface::DInput::PopulateDevices(reinterpret_cast(m_wsi.render_surface)); #endif #ifdef CIFACE_USE_XINPUT ciface::XInput::PopulateDevices(); #endif #ifdef CIFACE_USE_XLIB - ciface::XInput2::PopulateDevices(m_hwnd); + if (m_wsi.type == WindowSystemType::X11) + ciface::XInput2::PopulateDevices(m_wsi.render_surface); #endif #ifdef CIFACE_USE_OSX - ciface::OSX::PopulateDevices(m_hwnd); - ciface::Quartz::PopulateDevices(m_hwnd); + if (m_wsi.type == WindowSystemType::MacOS) + { + ciface::OSX::PopulateDevices(m_wsi.render_surface); + ciface::Quartz::PopulateDevices(m_wsi.render_surface); + } #endif #ifdef CIFACE_USE_SDL ciface::SDL::PopulateDevices(); diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h index c576b20fb3..d5567222a4 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h @@ -10,6 +10,7 @@ #include #include +#include "Common/WindowSystemInfo.h" #include "InputCommon/ControllerInterface/Device.h" // enable disable sources @@ -39,8 +40,9 @@ class ControllerInterface : public ciface::Core::DeviceContainer { public: - ControllerInterface() : m_is_init(false), m_hwnd(nullptr) {} - void Initialize(void* const hwnd); + ControllerInterface() : m_is_init(false) {} + void Initialize(const WindowSystemInfo& wsi); + void ChangeWindow(void* hwnd); void RefreshDevices(); void Shutdown(); void AddDevice(std::shared_ptr device); @@ -56,7 +58,7 @@ private: mutable std::mutex m_callbacks_mutex; bool m_is_init; std::atomic m_is_populating_devices{false}; - void* m_hwnd; + WindowSystemInfo m_wsi; }; extern ControllerInterface g_controller_interface;