mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
Fix gs_frame spawning on monitor other than the one the main window is on (#4029)
* Fix gs_frame spawning on a screen other than the one the RPCS3 window is on for multi-monitor setups * Cleaned up code & refactored it into a utility function for reuse * Qt: take gs_frame's framemargins into account by using showEvent
This commit is contained in:
parent
cd9bfba790
commit
f6b0b31e8b
10 changed files with 112 additions and 21 deletions
|
@ -938,6 +938,7 @@
|
|||
<ClCompile Include="rpcs3qt\game_list_grid.cpp" />
|
||||
<ClCompile Include="rpcs3qt\game_list_grid_delegate.cpp" />
|
||||
<ClCompile Include="rpcs3qt\progress_dialog.cpp" />
|
||||
<ClCompile Include="rpcs3qt\qt_utils.cpp" />
|
||||
<ClCompile Include="rpcs3qt\syntax_highlighter.cpp" />
|
||||
<ClCompile Include="rpcs3qt\save_data_info_dialog.cpp" />
|
||||
<ClCompile Include="rpcs3qt\save_manager_dialog.cpp" />
|
||||
|
@ -1432,6 +1433,7 @@
|
|||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
|
||||
</Command>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="rpcs3qt\qt_utils.h" />
|
||||
<ClInclude Include="rpcs3qt\save_data_dialog.h" />
|
||||
<CustomBuild Include="rpcs3qt\register_editor_dialog.h">
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
|
|
|
@ -99,6 +99,9 @@
|
|||
<Filter Include="Io\evdev">
|
||||
<UniqueIdentifier>{6992629a-48f1-43ec-8070-d1dba81bcbf9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Gui\utils">
|
||||
<UniqueIdentifier>{77ca7382-c296-43af-adb4-fb32f5ab4571}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="\rpcs3qt\*.cpp">
|
||||
|
@ -587,6 +590,9 @@
|
|||
<ClCompile Include="rpcs3qt\find_dialog.cpp">
|
||||
<Filter>Gui\misc dialogs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rpcs3qt\qt_utils.cpp">
|
||||
<Filter>Gui\utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_register_editor_dialog.cpp">
|
||||
<Filter>Generated Files\Release - LLVM</Filter>
|
||||
</ClCompile>
|
||||
|
@ -679,6 +685,9 @@
|
|||
<ClInclude Include="rpcs3qt\custom_table_widget_item.h">
|
||||
<Filter>Gui\game list</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rpcs3qt\qt_utils.h">
|
||||
<Filter>Gui\utils</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||
|
@ -808,4 +817,4 @@
|
|||
<ItemGroup>
|
||||
<ResourceCompile Include="rpcs3.rc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "rpcs3_app.h"
|
||||
|
||||
#include "rpcs3qt/qt_utils.h"
|
||||
|
||||
#include "rpcs3qt/welcome_dialog.h"
|
||||
|
||||
#include "Emu/System.h"
|
||||
|
@ -167,37 +169,40 @@ void rpcs3_app::InitializeCallbacks()
|
|||
}
|
||||
|
||||
bool disableMouse = guiSettings->GetValue(gui::gs_disableMouse).toBool();
|
||||
auto frame_geometry = gui::utils::create_centered_window_geometry(RPCS3MainWin->geometry(), w, h);
|
||||
|
||||
gs_frame* frame;
|
||||
|
||||
switch (video_renderer type = g_cfg.video.renderer)
|
||||
{
|
||||
case video_renderer::null:
|
||||
{
|
||||
gs_frame* ret = new gs_frame("Null", w, h, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
gameWindow = ret;
|
||||
return std::unique_ptr<gs_frame>(ret);
|
||||
frame = new gs_frame("Null", frame_geometry, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
break;
|
||||
}
|
||||
case video_renderer::opengl:
|
||||
{
|
||||
gl_gs_frame* ret = new gl_gs_frame(w, h, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
gameWindow = ret;
|
||||
return std::unique_ptr<gl_gs_frame>(ret);
|
||||
frame = new gl_gs_frame(frame_geometry, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
break;
|
||||
}
|
||||
case video_renderer::vulkan:
|
||||
{
|
||||
gs_frame* ret = new gs_frame("Vulkan", w, h, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
gameWindow = ret;
|
||||
return std::unique_ptr<gs_frame>(ret);
|
||||
frame = new gs_frame("Vulkan", frame_geometry, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
break;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12:
|
||||
{
|
||||
gs_frame* ret = new gs_frame("DirectX 12", w, h, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
gameWindow = ret;
|
||||
return std::unique_ptr<gs_frame>(ret);
|
||||
frame = new gs_frame("DirectX 12", frame_geometry, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
||||
default:
|
||||
fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
||||
}
|
||||
|
||||
gameWindow = frame;
|
||||
return std::unique_ptr<gs_frame>(frame);
|
||||
};
|
||||
|
||||
callbacks.get_gs_render = []() -> std::shared_ptr<GSRender>
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include <QOpenGLContext>
|
||||
#include <QWindow>
|
||||
|
||||
gl_gs_frame::gl_gs_frame(int w, int h, QIcon appIcon, bool disableMouse)
|
||||
: gs_frame("OpenGL", w, h, appIcon, disableMouse)
|
||||
gl_gs_frame::gl_gs_frame(const QRect& geometry, QIcon appIcon, bool disableMouse)
|
||||
: gs_frame("OpenGL", geometry, appIcon, disableMouse)
|
||||
{
|
||||
setSurfaceType(QSurface::OpenGLSurface);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ private:
|
|||
QSurfaceFormat m_format;
|
||||
|
||||
public:
|
||||
gl_gs_frame(int w, int h, QIcon appIcon, bool disableMouse);
|
||||
gl_gs_frame(const QRect& geometry, QIcon appIcon, bool disableMouse);
|
||||
|
||||
draw_context_t make_context() override;
|
||||
void set_current(draw_context_t context) override;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
constexpr auto qstr = QString::fromStdString;
|
||||
|
||||
gs_frame::gs_frame(const QString& title, int w, int h, QIcon appIcon, bool disableMouse)
|
||||
gs_frame::gs_frame(const QString& title, const QRect& geometry, QIcon appIcon, bool disableMouse)
|
||||
: QWindow(), m_windowTitle(title), m_disable_mouse(disableMouse)
|
||||
{
|
||||
//Get version by substringing VersionNumber-buildnumber-commithash to get just the part before the dash
|
||||
|
@ -55,8 +55,7 @@ gs_frame::gs_frame(const QString& title, int w, int h, QIcon appIcon, bool disab
|
|||
|
||||
m_show_fps = static_cast<bool>(g_cfg.misc.show_fps_in_title);
|
||||
|
||||
resize(w, h);
|
||||
|
||||
setGeometry(geometry);
|
||||
setTitle(m_windowTitle);
|
||||
setVisibility(Hidden);
|
||||
create();
|
||||
|
@ -70,6 +69,18 @@ void gs_frame::paintEvent(QPaintEvent *event)
|
|||
Q_UNUSED(event);
|
||||
}
|
||||
|
||||
void gs_frame::showEvent(QShowEvent *event)
|
||||
{
|
||||
// we have to calculate new window positions, since the frame is only known once the window was created
|
||||
// the left and right margins are too big on my setup for some reason yet unknown, so we'll have to ignore them
|
||||
int x = geometry().left(); //std::max(geometry().left(), frameMargins().left());
|
||||
int y = std::max(geometry().top(), frameMargins().top());
|
||||
|
||||
setPosition(x, y);
|
||||
|
||||
QWindow::showEvent(event);
|
||||
}
|
||||
|
||||
void gs_frame::keyPressEvent(QKeyEvent *keyEvent)
|
||||
{
|
||||
auto l_handleKeyEvent = [this ,keyEvent]()
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
class gs_frame : public QWindow, public GSFrameBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
u64 m_frames = 0;
|
||||
QString m_windowTitle;
|
||||
bool m_show_fps;
|
||||
|
@ -20,7 +21,7 @@ class gs_frame : public QWindow, public GSFrameBase
|
|||
bool m_minimized = false;
|
||||
|
||||
public:
|
||||
gs_frame(const QString& title, int w, int h, QIcon appIcon, bool disableMouse);
|
||||
gs_frame(const QString& title, const QRect& geometry, QIcon appIcon, bool disableMouse);
|
||||
|
||||
draw_context_t make_context() override;
|
||||
void set_current(draw_context_t context) override;
|
||||
|
@ -29,6 +30,7 @@ public:
|
|||
wm_event get_default_wm_event() const override;
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *event);
|
||||
virtual void showEvent(QShowEvent *event);
|
||||
|
||||
void keyPressEvent(QKeyEvent *keyEvent) override;
|
||||
void OnFullScreen();
|
||||
|
|
37
rpcs3/rpcs3qt/qt_utils.cpp
Normal file
37
rpcs3/rpcs3qt/qt_utils.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
#include "qt_utils.h"
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
|
||||
namespace gui
|
||||
{
|
||||
namespace utils
|
||||
{
|
||||
QRect create_centered_window_geometry(const QRect& origin, s32 width, s32 height)
|
||||
{
|
||||
// Get minimum virtual screen x & y for clamping the
|
||||
// window x & y later while taking the width and height
|
||||
// into account, so they don't go offscreen
|
||||
s32 min_screen_x = std::numeric_limits<s32>::max();
|
||||
s32 max_screen_x = std::numeric_limits<s32>::min();
|
||||
s32 min_screen_y = std::numeric_limits<s32>::max();
|
||||
s32 max_screen_y = std::numeric_limits<s32>::min();
|
||||
for (auto screen : QApplication::screens())
|
||||
{
|
||||
auto screen_geometry = screen->availableGeometry();
|
||||
min_screen_x = std::min(min_screen_x, screen_geometry.x());
|
||||
max_screen_x = std::max(max_screen_x, screen_geometry.x() + screen_geometry.width() - width);
|
||||
min_screen_y = std::min(min_screen_y, screen_geometry.y());
|
||||
max_screen_y = std::max(max_screen_y, screen_geometry.y() + screen_geometry.height() - height);
|
||||
}
|
||||
|
||||
s32 frame_x_raw = origin.left() + ((origin.width() - width) / 2);
|
||||
s32 frame_y_raw = origin.top() + ((origin.height() - height) / 2);
|
||||
|
||||
s32 frame_x = std::clamp(frame_x_raw, min_screen_x, max_screen_x);
|
||||
s32 frame_y = std::clamp(frame_y_raw, min_screen_y, max_screen_y);
|
||||
|
||||
return QRect(frame_x, frame_y, width, height);
|
||||
}
|
||||
} // utils
|
||||
} // gui
|
14
rpcs3/rpcs3qt/qt_utils.h
Normal file
14
rpcs3/rpcs3qt/qt_utils.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <QtCore>
|
||||
|
||||
namespace gui
|
||||
{
|
||||
namespace utils
|
||||
{
|
||||
// Creates a frame geometry rectangle with given width height that's centered inside the origin,
|
||||
// while still considering screen boundaries.
|
||||
QRect create_centered_window_geometry(const QRect& origin, s32 width, s32 height);
|
||||
} // utils
|
||||
} // gui
|
|
@ -42,5 +42,16 @@ namespace std { inline namespace literals { inline namespace chrono_literals {}}
|
|||
#include <array>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
// Remove once we move to C++17
|
||||
namespace std
|
||||
{
|
||||
template<typename T>
|
||||
constexpr const T clamp(const T value, const T min, const T max)
|
||||
{
|
||||
return value < min ? min : value > max ? max : value;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue