Qt: Add 'Disable Window Rounded Corners' option

This commit is contained in:
Stenzek 2025-01-05 16:39:57 +10:00
parent 9f41ef9eac
commit 1765590a6f
No known key found for this signature in database
6 changed files with 81 additions and 12 deletions

View File

@ -238,6 +238,9 @@ void AdvancedSettingsWidget::addTweakOptions()
static_cast<u32>(SaveStateCompressionMode::Count), static_cast<u32>(SaveStateCompressionMode::Count),
Settings::DEFAULT_SAVE_STATE_COMPRESSION_MODE); Settings::DEFAULT_SAVE_STATE_COMPRESSION_MODE);
addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Disable Window Rounded Corners"), "Main",
"DisableWindowRoundedCorners", false);
if (m_dialog->isPerGameSettings()) if (m_dialog->isPerGameSettings())
{ {
addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Display Active Start Offset"), "Display", addIntRangeTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Display Active Start Offset"), "Display",
@ -295,10 +298,11 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
int i = 0; int i = 0;
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply Game Settings setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply Game Settings
setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply compatibility settings setBooleanTweakOption(m_ui.tweakOptionTable, i++, true); // Apply Compatibility settings
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Load Devices From Save States setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Load Devices From Save States
setChoiceTweakOption(m_ui.tweakOptionTable, i++, setChoiceTweakOption(m_ui.tweakOptionTable, i++,
Settings::DEFAULT_SAVE_STATE_COMPRESSION_MODE); // Save State Compression Settings::DEFAULT_SAVE_STATE_COMPRESSION_MODE); // Save State Compression
setBooleanTweakOption(m_ui.tweakOptionTable, i++, false); // Disable Window Rounded Corners
setIntRangeTweakOption(m_ui.tweakOptionTable, i++, setIntRangeTweakOption(m_ui.tweakOptionTable, i++,
static_cast<int>(Settings::DEFAULT_DMA_MAX_SLICE_TICKS)); // DMA max slice ticks static_cast<int>(Settings::DEFAULT_DMA_MAX_SLICE_TICKS)); // DMA max slice ticks
setIntRangeTweakOption(m_ui.tweakOptionTable, i++, setIntRangeTweakOption(m_ui.tweakOptionTable, i++,
@ -331,6 +335,7 @@ void AdvancedSettingsWidget::onResetToDefaultClicked()
sif->DeleteValue("Main", "ApplyCompatibilitySettings"); sif->DeleteValue("Main", "ApplyCompatibilitySettings");
sif->DeleteValue("Main", "LoadDevicesFromSaveStates"); sif->DeleteValue("Main", "LoadDevicesFromSaveStates");
sif->DeleteValue("Main", "CompressSaveStates"); sif->DeleteValue("Main", "CompressSaveStates");
sif->DeleteValue("Main", "DisableWindowRoundedCorners");
sif->DeleteValue("Display", "ActiveStartOffset"); sif->DeleteValue("Display", "ActiveStartOffset");
sif->DeleteValue("Display", "ActiveEndOffset"); sif->DeleteValue("Display", "ActiveEndOffset");
sif->DeleteValue("Display", "LineStartOffset"); sif->DeleteValue("Display", "LineStartOffset");

View File

@ -32,6 +32,7 @@
#include "util/cd_image.h" #include "util/cd_image.h"
#include "util/gpu_device.h" #include "util/gpu_device.h"
#include "util/platform_misc.h"
#include "common/assert.h" #include "common/assert.h"
#include "common/error.h" #include "common/error.h"
@ -83,6 +84,7 @@ static bool s_use_central_widget = false;
#endif #endif
// UI thread VM validity. // UI thread VM validity.
static bool s_disable_window_rounded_corners = false;
static bool s_system_valid = false; static bool s_system_valid = false;
static bool s_system_paused = false; static bool s_system_paused = false;
static bool s_fullscreen_ui_started = false; static bool s_fullscreen_ui_started = false;
@ -353,6 +355,9 @@ void MainWindow::createDisplayWidget(bool fullscreen, bool render_to_main, bool
else else
restoreDisplayWindowGeometryFromConfig(); restoreDisplayWindowGeometryFromConfig();
container->showNormal(); container->showNormal();
if (s_disable_window_rounded_corners)
PlatformMisc::SetWindowRoundedCornerState(reinterpret_cast<void*>(container->winId()), false);
} }
else if (s_use_central_widget) else if (s_use_central_widget)
{ {
@ -1678,6 +1683,10 @@ void MainWindow::setupAdditionalUi()
m_shortcuts.game_grid_zoom_out = m_shortcuts.game_grid_zoom_out =
new QShortcut(Qt::ControlModifier | Qt::Key_Minus, this, this, &MainWindow::onViewGameGridZoomOutActionTriggered); new QShortcut(Qt::ControlModifier | Qt::Key_Minus, this, this, &MainWindow::onViewGameGridZoomOutActionTriggered);
s_disable_window_rounded_corners = Host::GetBaseBoolSettingValue("Main", "DisableWindowRoundedCorners", false);
if (s_disable_window_rounded_corners)
PlatformMisc::SetWindowRoundedCornerState(reinterpret_cast<void*>(winId()), false);
#ifdef ENABLE_RAINTEGRATION #ifdef ENABLE_RAINTEGRATION
if (Achievements::IsUsingRAIntegration()) if (Achievements::IsUsingRAIntegration())
{ {
@ -2549,6 +2558,20 @@ void MainWindow::requestExit(bool allow_confirm /* = true */)
void MainWindow::checkForSettingChanges() void MainWindow::checkForSettingChanges()
{ {
if (const bool disable_window_rounded_corners =
Host::GetBaseBoolSettingValue("Main", "DisableWindowRoundedCorners", false);
disable_window_rounded_corners != s_disable_window_rounded_corners)
{
s_disable_window_rounded_corners = disable_window_rounded_corners;
PlatformMisc::SetWindowRoundedCornerState(reinterpret_cast<void*>(winId()), !s_disable_window_rounded_corners);
if (QWidget* container = getDisplayContainer(); container && !container->parent() && !container->isFullScreen())
{
PlatformMisc::SetWindowRoundedCornerState(reinterpret_cast<void*>(container->winId()),
!s_disable_window_rounded_corners);
}
}
LogWindow::updateSettings(); LogWindow::updateSettings();
updateWindowState(); updateWindowState();
} }
@ -2647,6 +2670,9 @@ bool MainWindow::onCreateAuxiliaryRenderWindow(RenderAPI render_api, qint32 x, q
if (!widget) if (!widget)
return false; return false;
if (s_disable_window_rounded_corners)
PlatformMisc::SetWindowRoundedCornerState(reinterpret_cast<void*>(widget->winId()), false);
const std::optional<WindowInfo> owi = QtUtils::GetWindowInfoForWidget(widget, render_api, error); const std::optional<WindowInfo> owi = QtUtils::GetWindowInfoForWidget(widget, render_api, error);
if (!owi.has_value()) if (!owi.has_value())
{ {

View File

@ -8,22 +8,33 @@
class Error; class Error;
namespace PlatformMisc { namespace PlatformMisc {
bool InitializeSocketSupport(Error* error); bool InitializeSocketSupport(Error* error);
void SuspendScreensaver(); void SuspendScreensaver();
void ResumeScreensaver(); void ResumeScreensaver();
/// Abstracts platform-specific code for asynchronously playing a sound. /// Abstracts platform-specific code for asynchronously playing a sound.
/// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound. /// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound.
bool PlaySoundAsync(const char* path); bool PlaySoundAsync(const char* path);
/// Sets the rounded corner state for a window.
/// Currently only supported on Windows.
bool SetWindowRoundedCornerState(void* window_handle, bool enabled, Error* error = nullptr);
} // namespace PlatformMisc } // namespace PlatformMisc
namespace Host { namespace Host {
/// Return the current window handle. Needed for DInput. /// Return the current window handle. Needed for DInput.
std::optional<WindowInfo> GetTopLevelWindowInfo(); std::optional<WindowInfo> GetTopLevelWindowInfo();
} // namespace Host } // namespace Host
// TODO: Move all the other Cocoa stuff in here. // TODO: Move all the other Cocoa stuff in here.
namespace CocoaTools { namespace CocoaTools {
/// Returns the refresh rate of the display the window is placed on. /// Returns the refresh rate of the display the window is placed on.
std::optional<float> GetViewRefreshRate(const WindowInfo& wi, Error* error); std::optional<float> GetViewRefreshRate(const WindowInfo& wi, Error* error);
} // namespace CocoaTools } // namespace CocoaTools

View File

@ -88,6 +88,12 @@ bool PlatformMisc::PlaySoundAsync(const char* path)
return result; return result;
} }
bool PlatformMisc::SetWindowRoundedCornerState(void* window_handle, bool enabled, Error* error /* = nullptr */)
{
Error::SetStringView(error, "Unsupported on this platform.");
return false;
}
void* CocoaTools::CreateMetalLayer(const WindowInfo& wi, Error* error) void* CocoaTools::CreateMetalLayer(const WindowInfo& wi, Error* error)
{ {
// Punt off to main thread if we're not calling from it already. // Punt off to main thread if we're not calling from it already.

View File

@ -234,3 +234,9 @@ bool PlatformMisc::PlaySoundAsync(const char* path)
return false; return false;
#endif #endif
} }
bool PlatformMisc::SetWindowRoundedCornerState(void* window_handle, bool enabled, Error* error /* = nullptr */)
{
Error::SetStringView(error, "Unsupported on this platform.");
return false;
}

View File

@ -16,6 +16,7 @@
#include "common/windows_headers.h" #include "common/windows_headers.h"
#include <Psapi.h> #include <Psapi.h>
#include <WinSock2.h> #include <WinSock2.h>
#include <dwmapi.h>
#include <mmsystem.h> #include <mmsystem.h>
LOG_CHANNEL(PlatformMisc); LOG_CHANNEL(PlatformMisc);
@ -26,18 +27,21 @@ static std::once_flag s_winsock_initializer;
bool PlatformMisc::InitializeSocketSupport(Error* error) bool PlatformMisc::InitializeSocketSupport(Error* error)
{ {
std::call_once(s_winsock_initializer, [](Error* error) { std::call_once(
WSADATA wsa = {}; s_winsock_initializer,
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) [](Error* error) {
{ WSADATA wsa = {};
Error::SetSocket(error, "WSAStartup() failed: ", WSAGetLastError()); if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return false; {
} Error::SetSocket(error, "WSAStartup() failed: ", WSAGetLastError());
return false;
}
s_winsock_initialized = true; s_winsock_initialized = true;
std::atexit([]() { WSACleanup(); }); std::atexit([]() { WSACleanup(); });
return true; return true;
}, error); },
error);
return s_winsock_initialized; return s_winsock_initialized;
} }
@ -83,3 +87,14 @@ bool PlatformMisc::PlaySoundAsync(const char* path)
const std::wstring wpath(FileSystem::GetWin32Path(path)); const std::wstring wpath(FileSystem::GetWin32Path(path));
return PlaySoundW(wpath.c_str(), NULL, SND_ASYNC | SND_NODEFAULT); return PlaySoundW(wpath.c_str(), NULL, SND_ASYNC | SND_NODEFAULT);
} }
bool PlatformMisc::SetWindowRoundedCornerState(void* window_handle, bool enabled, Error* error)
{
const DWM_WINDOW_CORNER_PREFERENCE value = enabled ? DWMWCP_DEFAULT : DWMWCP_DONOTROUND;
const HRESULT hr =
DwmSetWindowAttribute(static_cast<HWND>(window_handle), DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
if (FAILED(hr))
Error::SetHResult(error, "DwmSetWindowAttribute(DWMWA_WINDOW_CORNER_PREFERENCE) failed: ", hr);
return SUCCEEDED(hr);
}