Compare commits

...

10 Commits

Author SHA1 Message Date
CostPerUnit
70dbdf2766
Merge a8eafa4ccd into 24b0bf01d5 2025-06-08 10:11:29 +02:00
JMC47
24b0bf01d5
Merge pull request #12836 from JosJuice/opensles-buffer-size
Android: Ask system for optimal audio buffer size and sample rate
2025-06-07 23:07:37 -04:00
Tilka
19fbbf0dba
Merge pull request #13727 from JoshuaVandaele/fmt-11.2.0-localtime-deprec
fmt: Replace deprecated `fmt::localtime` usage with `Common::LocalTime`
2025-06-08 04:04:37 +01:00
Jordan Woyak
1786e34bd3
Merge pull request #13665 from jordan-woyak/dark-mode-filter
DolphinQt: Replace widespread SetQWidgetWindowDecorations calls with an event filter.
2025-06-07 18:19:13 -05:00
Jordan Woyak
5906512847 DolphinQt: Replace widespread SetQWidgetWindowDecorations calls with an event filter. 2025-06-07 16:15:34 -05:00
Joshua Vandaële
4b65cc9a4c
fmt: Replace deprecated fmt::localtime usage with Common::LocalTime 2025-06-04 13:32:12 +02:00
Jordan Woyak
a8eafa4ccd DolphinQt: Move the "Point (Passthrough)" "Enabled" checkbox below the mapping indicator. 2025-05-29 19:46:53 -05:00
CostPerUnit
a5b4a0b9e4 InputCommon/DolphinQt: Add advanced settings button for "Point" and "Point (Passthrough)" "Enabled" checkboxes. 2025-05-29 19:39:10 -05:00
JosJuice
f99d3dbd5c Android: Ask system for optimal audio buffer size and sample rate
This can reduce audio latency according to
https://developer.android.com/ndk/guides/audio/opensl/opensl-prog-notes#perform.

Previously we were using the hardcoded values of 48000 Hz and 256 frames
per buffer. The sample rate we use with this change is 48000 Hz on all
devices I'm aware of, but the buffer size does vary across devices.

Terminology note: The old code used the term "sample" to refer to what
Android refers to as a "frame". "Frame" is a clearer term to use for
this, so I've changed OpenSLESStream's terminology. One frame consists
of one sample per channel.
2025-05-25 11:59:33 +02:00
JosJuice
34e8fb068f Android: Get rid of OpenSLESStream's global state
Not sure if we're ever going to want to have more than one of these at
the same time, but these global variables are a code smell nonetheless.

I'm also deleting the existing member variables because they were
unused.
2025-05-25 11:55:22 +02:00
68 changed files with 372 additions and 316 deletions

View File

@ -0,0 +1,28 @@
package org.dolphinemu.dolphinemu.utils
import android.content.Context
import android.media.AudioManager
import androidx.annotation.Keep
import org.dolphinemu.dolphinemu.DolphinApplication
object AudioUtils {
@JvmStatic @Keep
fun getSampleRate(): Int =
getAudioServiceProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE, 48000)
@JvmStatic @Keep
fun getFramesPerBuffer(): Int =
getAudioServiceProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER, 256)
private fun getAudioServiceProperty(property: String, fallback: Int): Int {
return try {
val context = DolphinApplication.getAppContext()
val am = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
Integer.parseUnsignedInt(am.getProperty(property))
} catch (e: NullPointerException) {
fallback
} catch (e: NumberFormatException) {
fallback
}
}
}

View File

@ -122,6 +122,10 @@ static jmethodID s_permission_handler_request_record_audio_permission;
static jmethodID s_runnable_run;
static jclass s_audio_utils_class;
static jmethodID s_audio_utils_get_sample_rate;
static jmethodID s_audio_utils_get_frames_per_buffer;
namespace IDCache
{
JNIEnv* GetEnvForThread()
@ -562,6 +566,21 @@ jmethodID GetRunnableRun()
return s_runnable_run;
}
jclass GetAudioUtilsClass()
{
return s_audio_utils_class;
}
jmethodID GetAudioUtilsGetSampleRate()
{
return s_audio_utils_get_sample_rate;
}
jmethodID GetAudioUtilsGetFramesPerBuffer()
{
return s_audio_utils_get_frames_per_buffer;
}
} // namespace IDCache
extern "C" {
@ -798,6 +817,13 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
s_runnable_run = env->GetMethodID(runnable_class, "run", "()V");
env->DeleteLocalRef(runnable_class);
const jclass audio_utils_class = env->FindClass("org/dolphinemu/dolphinemu/utils/AudioUtils");
s_audio_utils_class = reinterpret_cast<jclass>(env->NewGlobalRef(audio_utils_class));
s_audio_utils_get_sample_rate = env->GetStaticMethodID(audio_utils_class, "getSampleRate", "()I");
s_audio_utils_get_frames_per_buffer =
env->GetStaticMethodID(audio_utils_class, "getFramesPerBuffer", "()I");
env->DeleteLocalRef(audio_utils_class);
return JNI_VERSION;
}
@ -834,5 +860,6 @@ JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)
env->DeleteGlobalRef(s_core_device_control_class);
env->DeleteGlobalRef(s_input_detector_class);
env->DeleteGlobalRef(s_permission_handler_class);
env->DeleteGlobalRef(s_audio_utils_class);
}
}

View File

@ -121,4 +121,8 @@ jmethodID GetPermissionHandlerRequestRecordAudioPermission();
jmethodID GetRunnableRun();
jclass GetAudioUtilsClass();
jmethodID GetAudioUtilsGetSampleRate();
jmethodID GetAudioUtilsGetFramesPerBuffer();
} // namespace IDCache

View File

@ -55,14 +55,14 @@ JNIEXPORT jboolean JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_ControlGroup_getEnabled(
JNIEnv* env, jobject obj)
{
return static_cast<jboolean>(GetPointer(env, obj)->enabled);
return static_cast<jboolean>(GetPointer(env, obj)->enabled.GetValue());
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_ControlGroup_setEnabled(
JNIEnv* env, jobject obj, jboolean value)
{
GetPointer(env, obj)->enabled = value;
GetPointer(env, obj)->enabled.SetValue(value);
}
JNIEXPORT jint JNICALL

View File

@ -16,6 +16,7 @@
#include "AudioCommon/WASAPIStream.h"
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/TimeUtil.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/System.h"
@ -219,8 +220,11 @@ void StartAudioDump(Core::System& system)
std::string path_prefix = File::GetUserPath(D_DUMPAUDIO_IDX) + SConfig::GetInstance().GetGameID();
std::string base_name =
fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, fmt::localtime(start_time));
const auto local_time = Common::LocalTime(start_time);
if (!local_time)
return;
std::string base_name = fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, *local_time);
const std::string audio_file_name_dtk = fmt::format("{}_dtkdump.wav", base_name);
const std::string audio_file_name_dsp = fmt::format("{}_dspdump.wav", base_name);

View File

@ -8,40 +8,27 @@
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <jni.h>
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Core/ConfigManager.h"
#include "jni/AndroidCommon/IDCache.h"
// engine interfaces
static SLObjectItf engineObject;
static SLEngineItf engineEngine;
static SLObjectItf outputMixObject;
// buffer queue player interfaces
static SLObjectItf bqPlayerObject = nullptr;
static SLPlayItf bqPlayerPlay;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
static SLVolumeItf bqPlayerVolume;
static Mixer* g_mixer;
#define BUFFER_SIZE 512
#define BUFFER_SIZE_IN_SAMPLES (BUFFER_SIZE / 2)
// Double buffering.
static short buffer[2][BUFFER_SIZE];
static int curBuffer = 0;
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
void OpenSLESStream::BQPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
{
ASSERT(bq == bqPlayerBufferQueue);
ASSERT(nullptr == context);
reinterpret_cast<OpenSLESStream*>(context)->PushSamples(bq);
}
void OpenSLESStream::PushSamples(SLAndroidSimpleBufferQueueItf bq)
{
ASSERT(bq == m_bq_player_buffer_queue);
// Render to the fresh buffer
g_mixer->Mix(reinterpret_cast<short*>(buffer[curBuffer]), BUFFER_SIZE_IN_SAMPLES);
SLresult result =
(*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[0]));
curBuffer ^= 1; // Switch buffer
m_mixer->Mix(m_buffer[m_current_buffer].data(), m_frames_per_buffer);
SLresult result = (*bq)->Enqueue(bq, m_buffer[m_current_buffer].data(), m_bytes_per_buffer);
m_current_buffer ^= 1; // Switch buffer
// Comment from sample code:
// the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
@ -51,61 +38,78 @@ static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
bool OpenSLESStream::Init()
{
JNIEnv* env = IDCache::GetEnvForThread();
jclass audio_utils = IDCache::GetAudioUtilsClass();
const SLuint32 sample_rate =
env->CallStaticIntMethod(audio_utils, IDCache::GetAudioUtilsGetSampleRate());
m_frames_per_buffer =
env->CallStaticIntMethod(audio_utils, IDCache::GetAudioUtilsGetFramesPerBuffer());
INFO_LOG_FMT(AUDIO, "OpenSLES configuration: {} Hz, {} frames per buffer", sample_rate,
m_frames_per_buffer);
constexpr SLuint32 channels = 2;
const SLuint32 samples_per_buffer = m_frames_per_buffer * channels;
m_bytes_per_buffer = m_frames_per_buffer * channels * sizeof(m_buffer[0][0]);
for (std::vector<short>& buffer : m_buffer)
buffer.resize(samples_per_buffer);
SLresult result;
// create engine
result = slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
result = slCreateEngine(&m_engine_object, 0, nullptr, 0, nullptr, nullptr);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
result = (*m_engine_object)->Realize(m_engine_object, SL_BOOLEAN_FALSE);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
result = (*m_engine_object)->GetInterface(m_engine_object, SL_IID_ENGINE, &m_engine_engine);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
result = (*m_engine_engine)->CreateOutputMix(m_engine_engine, &m_output_mix_object, 0, 0, 0);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
result = (*m_output_mix_object)->Realize(m_output_mix_object, SL_BOOLEAN_FALSE);
ASSERT(SL_RESULT_SUCCESS == result);
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,
2,
m_mixer->GetSampleRate() * 1000,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
SL_BYTEORDER_LITTLEENDIAN};
SLDataFormat_PCM format_pcm = {
SL_DATAFORMAT_PCM, channels,
sample_rate * 1000, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
SL_BYTEORDER_LITTLEENDIAN};
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, m_output_mix_object};
SLDataSink audioSnk = {&loc_outmix, nullptr};
// create audio player
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result =
(*engineEngine)
->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
result = (*m_engine_engine)
->CreateAudioPlayer(m_engine_engine, &m_bq_player_object, &audioSrc, &audioSnk, 2,
ids, req);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
result = (*m_bq_player_object)->Realize(m_bq_player_object, SL_BOOLEAN_FALSE);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
result = (*m_bq_player_object)->GetInterface(m_bq_player_object, SL_IID_PLAY, &m_bq_player_play);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*m_bq_player_object)
->GetInterface(m_bq_player_object, SL_IID_BUFFERQUEUE, &m_bq_player_buffer_queue);
ASSERT(SL_RESULT_SUCCESS == result);
result =
(*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, &bqPlayerBufferQueue);
(*m_bq_player_object)->GetInterface(m_bq_player_object, SL_IID_VOLUME, &m_bq_player_volume);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
result = (*m_bq_player_buffer_queue)
->RegisterCallback(m_bq_player_buffer_queue, BQPlayerCallback, this);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, nullptr);
ASSERT(SL_RESULT_SUCCESS == result);
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
result = (*m_bq_player_play)->SetPlayState(m_bq_player_play, SL_PLAYSTATE_PLAYING);
ASSERT(SL_RESULT_SUCCESS == result);
// Render and enqueue a first buffer.
curBuffer ^= 1;
g_mixer = m_mixer.get();
m_current_buffer ^= 1;
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[0], sizeof(buffer[0]));
result = (*m_bq_player_buffer_queue)
->Enqueue(m_bq_player_buffer_queue, m_buffer[0].data(), m_bytes_per_buffer);
if (SL_RESULT_SUCCESS != result)
return false;
@ -114,39 +118,39 @@ bool OpenSLESStream::Init()
OpenSLESStream::~OpenSLESStream()
{
if (bqPlayerObject != nullptr)
if (m_bq_player_object != nullptr)
{
(*bqPlayerObject)->Destroy(bqPlayerObject);
bqPlayerObject = nullptr;
bqPlayerPlay = nullptr;
bqPlayerBufferQueue = nullptr;
bqPlayerVolume = nullptr;
(*m_bq_player_object)->Destroy(m_bq_player_object);
m_bq_player_object = nullptr;
m_bq_player_play = nullptr;
m_bq_player_buffer_queue = nullptr;
m_bq_player_volume = nullptr;
}
if (outputMixObject != nullptr)
if (m_output_mix_object != nullptr)
{
(*outputMixObject)->Destroy(outputMixObject);
outputMixObject = nullptr;
(*m_output_mix_object)->Destroy(m_output_mix_object);
m_output_mix_object = nullptr;
}
if (engineObject != nullptr)
if (m_engine_object != nullptr)
{
(*engineObject)->Destroy(engineObject);
engineObject = nullptr;
engineEngine = nullptr;
(*m_engine_object)->Destroy(m_engine_object);
m_engine_object = nullptr;
m_engine_engine = nullptr;
}
}
bool OpenSLESStream::SetRunning(bool running)
{
SLuint32 new_state = running ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_PAUSED;
return (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, new_state) == SL_RESULT_SUCCESS;
return (*m_bq_player_play)->SetPlayState(m_bq_player_play, new_state) == SL_RESULT_SUCCESS;
}
void OpenSLESStream::SetVolume(int volume)
{
const SLmillibel attenuation =
volume <= 0 ? SL_MILLIBEL_MIN : static_cast<SLmillibel>(2000 * std::log10(volume / 100.0f));
(*bqPlayerVolume)->SetVolumeLevel(bqPlayerVolume, attenuation);
(*m_bq_player_volume)->SetVolumeLevel(m_bq_player_volume, attenuation);
}
#endif // HAVE_OPENSL_ES

View File

@ -3,10 +3,15 @@
#pragma once
#include <thread>
#ifdef HAVE_OPENSL_ES
#include <array>
#include <vector>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#endif // HAVE_OPENSL_ES
#include "AudioCommon/SoundStream.h"
#include "Common/Event.h"
class OpenSLESStream final : public SoundStream
{
@ -19,7 +24,25 @@ public:
static bool IsValid() { return true; }
private:
std::thread thread;
Common::Event soundSyncEvent;
static void BQPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context);
void PushSamples(SLAndroidSimpleBufferQueueItf bq);
// engine interfaces
SLObjectItf m_engine_object;
SLEngineItf m_engine_engine;
SLObjectItf m_output_mix_object;
// buffer queue player interfaces
SLObjectItf m_bq_player_object = nullptr;
SLPlayItf m_bq_player_play;
SLAndroidSimpleBufferQueueItf m_bq_player_buffer_queue;
SLVolumeItf m_bq_player_volume;
SLuint32 m_frames_per_buffer;
SLuint32 m_bytes_per_buffer;
// Double buffering.
std::array<std::vector<short>, 2> m_buffer;
int m_current_buffer = 0;
#endif // HAVE_OPENSL_ES
};

View File

@ -25,6 +25,7 @@
#include "Common/Logging/Log.h"
#include "Common/ScopeGuard.h"
#include "Common/StringUtil.h"
#include "Common/TimeUtil.h"
#include "Core/Config/MainSettings.h"
@ -95,12 +96,7 @@ int SDCardDiskIOCtl(File::IOFile* image, u8 pdrv, u8 cmd, void* buff)
u32 GetSystemTimeFAT()
{
const std::time_t time = std::time(nullptr);
std::tm tm;
#ifdef _WIN32
localtime_s(&tm, &time);
#else
localtime_r(&time, &tm);
#endif
std::tm tm = *Common::LocalTime(time);
DWORD fattime = 0;
fattime |= (tm.tm_year - 80) << 25;

View File

@ -122,7 +122,6 @@ std::string SettingsWriter::GenerateSerialNumber()
// Must be 9 characters at most; otherwise the serial number will be rejected by SDK libraries,
// as there is a check to ensure the string length is strictly lower than 10.
// 3 for %j, 2 for %H, 2 for %M, 2 for %S.
return fmt::format("{:%j%H%M%S}", fmt::localtime(t));
return fmt::format("{:09}", t % 1000000000);
}
} // namespace Common

View File

@ -2,23 +2,25 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Common/TimeUtil.h"
#include "Common/Logging/Log.h"
#include <ctime>
#include <optional>
namespace Common
{
std::optional<std::tm> Localtime(std::time_t time)
std::optional<std::tm> LocalTime(std::time_t time)
{
std::tm local_time;
#ifdef _MSC_VER
if (localtime_s(&local_time, &time) != 0)
return std::nullopt;
#else
std::tm* result = localtime_r(&time, &local_time);
if (result != &local_time)
return std::nullopt;
if (localtime_r(&time, &local_time) == NULL)
#endif
{
ERROR_LOG_FMT(COMMON, "Failed to convert time to local time: {}", std::strerror(errno));
return std::nullopt;
}
return local_time;
}
} // Namespace Common

View File

@ -9,5 +9,5 @@
namespace Common
{
// Threadsafe and error-checking variant of std::localtime()
std::optional<std::tm> Localtime(std::time_t time);
std::optional<std::tm> LocalTime(std::time_t time);
} // Namespace Common

View File

@ -8,6 +8,7 @@
#include <cstring>
#include <functional>
#include <mutex>
#include <optional>
#include <queue>
#include <utility>
#include <variant>
@ -34,6 +35,7 @@
#include "Common/ScopeGuard.h"
#include "Common/StringUtil.h"
#include "Common/Thread.h"
#include "Common/TimeUtil.h"
#include "Common/Version.h"
#include "Core/AchievementManager.h"
@ -733,15 +735,17 @@ static std::string GenerateScreenshotFolderPath()
return path;
}
static std::string GenerateScreenshotName()
static std::optional<std::string> GenerateScreenshotName()
{
// append gameId, path only contains the folder here.
const std::string path_prefix =
GenerateScreenshotFolderPath() + SConfig::GetInstance().GetGameID();
const std::time_t cur_time = std::time(nullptr);
const std::string base_name =
fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, fmt::localtime(cur_time));
const auto local_time = Common::LocalTime(cur_time);
if (!local_time)
return std::nullopt;
const std::string base_name = fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, *local_time);
// First try a filename without any suffixes, if already exists then append increasing numbers
std::string name = fmt::format("{}.png", base_name);
@ -757,7 +761,9 @@ static std::string GenerateScreenshotName()
void SaveScreenShot()
{
const Core::CPUThreadGuard guard(Core::System::GetInstance());
g_frame_dumper->SaveScreenshot(GenerateScreenshotName());
std::optional<std::string> name = GenerateScreenshotName();
if (name)
g_frame_dumper->SaveScreenshot(*name);
}
void SaveScreenShot(std::string_view name)

View File

@ -311,7 +311,7 @@ void EmulateIMUCursor(IMUCursorState* state, ControllerEmu::IMUCursor* imu_ir_gr
const auto ang_vel = imu_gyroscope_group->GetState();
// Reset if pointing is disabled or we have no gyro data.
if (!imu_ir_group->enabled || !ang_vel.has_value())
if (!imu_ir_group->enabled.GetValue() || !ang_vel.has_value())
{
*state = {};
return;

View File

@ -497,7 +497,7 @@ void Wiimote::BuildDesiredWiimoteState(DesiredWiimoteState* target_state,
ConvertAccelData(GetTotalAcceleration(), ACCEL_ZERO_G << 2, ACCEL_ONE_G << 2);
// Calculate IR camera state.
if (m_ir_passthrough->enabled)
if (m_ir_passthrough->enabled.GetValue())
{
target_state->camera_points = GetPassthroughCameraPoints(m_ir_passthrough);
}

View File

@ -16,6 +16,7 @@
#include "Common/Network.h"
#include "Common/PcapFile.h"
#include "Common/ScopeGuard.h"
#include "Common/TimeUtil.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
@ -82,7 +83,7 @@ PCAPSSLCaptureLogger::PCAPSSLCaptureLogger()
{
const std::string filepath =
fmt::format("{}{} {:%Y-%m-%d %Hh%Mm%Ss}.pcap", File::GetUserPath(D_DUMPSSL_IDX),
SConfig::GetInstance().GetGameID(), fmt::localtime(std::time(nullptr)));
SConfig::GetInstance().GetGameID(), *Common::LocalTime(std::time(nullptr)));
m_file = std::make_unique<Common::PCAP>(
new File::IOFile(filepath, "wb", File::SharedAccess::Read), Common::PCAP::LinkType::Ethernet);
}

View File

@ -281,7 +281,7 @@ static std::string SystemTimeAsDoubleToString(double time)
{
// revert adjustments from GetSystemTimeAsDouble() to get a normal Unix timestamp again
const time_t seconds = static_cast<time_t>(time) + DOUBLE_TIME_OFFSET;
const auto local_time = Common::Localtime(seconds);
const auto local_time = Common::LocalTime(seconds);
if (!local_time)
return "";

View File

@ -23,7 +23,6 @@
#include "DolphinQt/Config/CheatWarningWidget.h"
#include "DolphinQt/Config/HardcoreWarningWidget.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
ARCodeWidget::ARCodeWidget(std::string game_id, u16 game_revision, bool restart_required)
: m_game_id(std::move(game_id)), m_game_revision(game_revision),
@ -257,7 +256,6 @@ void ARCodeWidget::OnCodeAddClicked()
ar.enabled = true;
m_cheat_code_editor->SetARCode(&ar);
SetQWidgetWindowDecorations(m_cheat_code_editor);
if (m_cheat_code_editor->exec() == QDialog::Rejected)
return;
@ -275,7 +273,6 @@ void ARCodeWidget::OnCodeEditClicked()
const auto* const selected = items[0];
auto& current_ar = m_ar_codes[m_code_list->row(selected)];
SetQWidgetWindowDecorations(m_cheat_code_editor);
if (current_ar.user_defined)
{

View File

@ -13,7 +13,6 @@
#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
@ -60,7 +59,6 @@ void CommonControllersWidget::OnControllerInterfaceConfigure()
ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this);
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
}

View File

@ -14,7 +14,6 @@
#include "Common/Config/Config.h"
#include "DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h"
DualShockUDPClientWidget::DualShockUDPClientWidget()
@ -112,7 +111,6 @@ void DualShockUDPClientWidget::OnServerAdded()
DualShockUDPClientAddServerDialog add_server_dialog(this);
connect(&add_server_dialog, &DualShockUDPClientAddServerDialog::accepted, this,
&DualShockUDPClientWidget::RefreshServerList);
SetQWidgetWindowDecorations(&add_server_dialog);
add_server_dialog.exec();
}

View File

@ -25,7 +25,6 @@
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "UICommon/UICommon.h"
@ -367,7 +366,6 @@ void FilesystemWidget::ExtractDirectory(const DiscIO::Partition& partition, cons
dialog.Reset();
});
SetQWidgetWindowDecorations(dialog.GetRaw());
dialog.GetRaw()->exec();
future.get();
}

View File

@ -19,7 +19,6 @@
#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
FreeLookWidget::FreeLookWidget(QWidget* parent) : QWidget(parent)
@ -104,7 +103,6 @@ void FreeLookWidget::OnFreeLookControllerConfigured()
MappingWindow* window = new MappingWindow(this, MappingWindow::Type::MAPPING_FREELOOK, index);
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
}

View File

@ -24,7 +24,6 @@
#include "DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.h"
#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
@ -140,7 +139,6 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index)
case SerialInterface::SIDEVICE_WIIU_ADAPTER:
{
GCPadWiiUConfigDialog dialog(static_cast<int>(index), this);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
@ -166,7 +164,6 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index)
MappingWindow* window = new MappingWindow(this, type, static_cast<int>(index));
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
}

View File

@ -30,7 +30,6 @@
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
GeckoCodeWidget::GeckoCodeWidget(std::string game_id, std::string gametdb_id, u16 game_revision,
@ -210,7 +209,6 @@ void GeckoCodeWidget::AddCode()
code.enabled = true;
m_cheat_code_editor->SetGeckoCode(&code);
SetQWidgetWindowDecorations(m_cheat_code_editor);
if (m_cheat_code_editor->exec() == QDialog::Rejected)
return;
@ -228,7 +226,6 @@ void GeckoCodeWidget::EditCode()
const int index = item->data(Qt::UserRole).toInt();
m_cheat_code_editor->SetGeckoCode(&m_gecko_codes[index]);
SetQWidgetWindowDecorations(m_cheat_code_editor);
if (m_cheat_code_editor->exec() == QDialog::Rejected)
return;

View File

@ -25,7 +25,6 @@
#include "DolphinQt/Config/Graphics/PostProcessingConfigWindow.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipPushButton.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
#include "VideoCommon/PostProcessing.h"
@ -629,7 +628,6 @@ void EnhancementsWidget::AddDescriptions()
void EnhancementsWidget::ConfigureColorCorrection()
{
ColorCorrectionConfigWindow dialog(this);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
}
@ -637,6 +635,5 @@ void EnhancementsWidget::ConfigurePostProcessingShader()
{
const std::string shader = ReadSetting(Config::GFX_ENHANCE_POST_SHADER);
PostProcessingConfigWindow dialog(this, shader);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
}

View File

@ -27,7 +27,6 @@
#include "DolphinQt/Config/Graphics/GraphicsWindow.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
#include "VideoCommon/VideoBackendBase.h"
@ -199,7 +198,6 @@ void GeneralWidget::BackendWarning()
confirm_sw.setWindowTitle(tr("Confirm backend change"));
confirm_sw.setText(tr(warningMessage->c_str()));
SetQWidgetWindowDecorations(&confirm_sw);
if (confirm_sw.exec() != QMessageBox::Yes)
{
m_backend_combo->setCurrentIndex(m_previous_backend);

View File

@ -11,7 +11,6 @@
#include "Core/FreeLookManager.h"
#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "InputCommon/InputConfig.h"
FreeLookRotation::FreeLookRotation(MappingWindow* window) : MappingWidget(window)
@ -34,7 +33,6 @@ void FreeLookRotation::CreateMainLayout()
ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this);
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
});
m_main_layout->addLayout(alternate_input_layout, 0, 0, 1, -1);

View File

@ -28,7 +28,6 @@
#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/QtUtils/BlockUserInputFilter.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
#include "InputCommon/ControlReference/ControlReference.h"
@ -259,8 +258,6 @@ IOWindow::IOWindow(MappingWindow* window, ControllerEmu::EmulatedController* con
: QDialog(window), m_reference(ref), m_original_expression(ref->GetExpression()),
m_controller(controller), m_type(type)
{
SetQWidgetWindowDecorations(this);
CreateMainLayout();
connect(window, &MappingWindow::Update, this, &IOWindow::Update);

View File

@ -893,7 +893,8 @@ void IRPassthroughMappingIndicator::Draw()
p.scale(1.0, -1.0);
auto pen = GetInputDotPen(m_ir_group.enabled ? GetAdjustedInputColor() : GetRawInputColor());
auto pen =
GetInputDotPen(m_ir_group.enabled.GetValue() ? GetAdjustedInputColor() : GetRawInputColor());
for (std::size_t i = 0; i != WiimoteEmu::CameraLogic::NUM_POINTS; ++i)
{

View File

@ -18,7 +18,6 @@
#include "DolphinQt/Config/Mapping/MappingIndicator.h"
#include "DolphinQt/Config/Mapping/MappingNumeric.h"
#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "InputCommon/ControllerEmu/Control/Control.h"
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
@ -103,15 +102,48 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con
break;
}
if (indicator)
// Mapping indicator.
if (indicator != nullptr)
{
const auto indicator_layout = new QBoxLayout(QBoxLayout::Direction::Down);
auto* const indicator_layout = new QBoxLayout(QBoxLayout::Direction::Down);
indicator_layout->addWidget(indicator);
indicator_layout->setAlignment(Qt::AlignCenter);
form_layout->addRow(indicator_layout);
connect(this, &MappingWidget::Update, indicator, qOverload<>(&MappingIndicator::update));
}
// "Enabled" checkbox.
if (group->HasEnabledSetting())
{
AddSettingWidget(form_layout, group->enabled_setting.get());
auto enable_labels = [form_layout, start_index = form_layout->rowCount()](bool enabled) {
// Skipping the "Enabled" checkbox row itself and the mapping indicator, if it exists.
for (int i = start_index; i < form_layout->count(); ++i)
{
auto* const item = form_layout->itemAt(i, QFormLayout::LabelRole);
if (item == nullptr)
continue;
auto* const widget = item->widget();
if (widget == nullptr)
continue;
widget->setEnabled(enabled);
}
};
connect(this, &MappingWidget::Update, this, [group, enable_labels, enabled = true]() mutable {
if (enabled == group->enabled_setting->GetValue())
return;
enable_labels(enabled = !enabled);
});
}
// "Calibrate" button.
if (indicator != nullptr)
{
const bool need_calibration = group->type == ControllerEmu::GroupType::Cursor ||
group->type == ControllerEmu::GroupType::Stick ||
group->type == ControllerEmu::GroupType::Tilt ||
@ -132,28 +164,6 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con
AddSettingWidgets(form_layout, group, ControllerEmu::SettingVisibility::Normal);
if (group->default_value != ControllerEmu::ControlGroup::DefaultValue::AlwaysEnabled)
{
QLabel* group_enable_label = new QLabel(tr("Enable"));
QCheckBox* group_enable_checkbox = new QCheckBox();
group_enable_checkbox->setChecked(group->enabled);
form_layout->insertRow(0, group_enable_label, group_enable_checkbox);
auto enable_group_by_checkbox = [group, form_layout, group_enable_label,
group_enable_checkbox] {
group->enabled = group_enable_checkbox->isChecked();
for (int i = 0; i < form_layout->count(); ++i)
{
QWidget* widget = form_layout->itemAt(i)->widget();
if (widget != nullptr && widget != group_enable_label && widget != group_enable_checkbox)
widget->setEnabled(group->enabled);
}
};
enable_group_by_checkbox();
connect(group_enable_checkbox, &QCheckBox::toggled, this, enable_group_by_checkbox);
connect(this, &MappingWidget::ConfigChanged, this,
[group_enable_checkbox, group] { group_enable_checkbox->setChecked(group->enabled); });
}
const auto advanced_setting_count =
std::ranges::count(group->numeric_settings, ControllerEmu::SettingVisibility::Advanced,
&ControllerEmu::NumericSettingBase::GetVisibility);
@ -202,36 +212,42 @@ void MappingWidget::AddSettingWidgets(QFormLayout* layout, ControllerEmu::Contro
if (setting->GetVisibility() != visibility)
continue;
QWidget* setting_widget = nullptr;
AddSettingWidget(layout, setting.get());
}
}
switch (setting->GetType())
{
case ControllerEmu::SettingType::Double:
setting_widget = new MappingDouble(
this, static_cast<ControllerEmu::NumericSetting<double>*>(setting.get()));
break;
void MappingWidget::AddSettingWidget(QFormLayout* layout,
ControllerEmu::NumericSettingBase* setting)
{
QWidget* setting_widget = nullptr;
case ControllerEmu::SettingType::Bool:
setting_widget =
new MappingBool(this, static_cast<ControllerEmu::NumericSetting<bool>*>(setting.get()));
break;
switch (setting->GetType())
{
case ControllerEmu::SettingType::Double:
setting_widget =
new MappingDouble(this, static_cast<ControllerEmu::NumericSetting<double>*>(setting));
break;
default:
// FYI: Widgets for additional types can be implemented as needed.
break;
}
case ControllerEmu::SettingType::Bool:
setting_widget =
new MappingBool(this, static_cast<ControllerEmu::NumericSetting<bool>*>(setting));
break;
if (setting_widget)
{
const auto hbox = new QHBoxLayout;
default:
// FYI: Widgets for additional types can be implemented as needed.
break;
}
hbox->addWidget(setting_widget);
setting_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
if (setting_widget != nullptr)
{
auto* const hbox = new QHBoxLayout;
hbox->addWidget(CreateSettingAdvancedMappingButton(*setting));
hbox->addWidget(setting_widget);
setting_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
layout->addRow(tr(setting->GetUIName()), hbox);
}
hbox->addWidget(CreateSettingAdvancedMappingButton(*setting));
layout->addRow(tr(setting->GetUIName()), hbox);
}
}
@ -282,7 +298,6 @@ void MappingWidget::ShowAdvancedControlGroupDialog(ControllerEmu::ControlGroup*
// Enable "Close" button functionality.
connect(button_box, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
}

View File

@ -50,8 +50,11 @@ protected:
int columns);
void CreateControl(const ControllerEmu::Control* control, QFormLayout* layout, bool indicator);
QPushButton* CreateSettingAdvancedMappingButton(ControllerEmu::NumericSettingBase& setting);
void AddSettingWidget(QFormLayout* layout, ControllerEmu::NumericSettingBase* setting);
void AddSettingWidgets(QFormLayout* layout, ControllerEmu::ControlGroup* group,
ControllerEmu::SettingVisibility visibility);
void ShowAdvancedControlGroupDialog(ControllerEmu::ControlGroup* group);
private:

View File

@ -51,7 +51,6 @@
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/WindowActivationEventFilter.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "DolphinQt/Settings.h"
@ -271,7 +270,6 @@ void MappingWindow::OnDeleteProfilePressed()
error.setIcon(QMessageBox::Critical);
error.setWindowTitle(tr("Error"));
error.setText(tr("The profile '%1' does not exist").arg(profile_name));
SetQWidgetWindowDecorations(&error);
error.exec();
return;
}
@ -284,7 +282,6 @@ void MappingWindow::OnDeleteProfilePressed()
confirm.setInformativeText(tr("This cannot be undone!"));
confirm.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
SetQWidgetWindowDecorations(&confirm);
if (confirm.exec() != QMessageBox::Yes)
{
return;
@ -312,7 +309,6 @@ void MappingWindow::OnLoadProfilePressed()
error.setIcon(QMessageBox::Critical);
error.setWindowTitle(tr("Error"));
error.setText(tr("The profile '%1' does not exist").arg(m_profiles_combo->currentText()));
SetQWidgetWindowDecorations(&error);
error.exec();
return;
}

View File

@ -15,7 +15,6 @@
#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "InputCommon/InputConfig.h"
@ -43,7 +42,6 @@ void WiimoteEmuExtensionMotionInput::CreateNunchukLayout()
warning_layout->addWidget(warning_input_sources_button);
connect(warning_input_sources_button, &QPushButton::clicked, this, [this] {
ControllerInterfaceWindow window{this};
SetQWidgetWindowDecorations(&window);
window.exec();
});
layout->addLayout(warning_layout, 0, 0, 1, -1);

View File

@ -16,7 +16,6 @@
#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "InputCommon/InputConfig.h"
@ -41,7 +40,6 @@ void WiimoteEmuMotionControlIMU::CreateMainLayout()
warning_layout->addWidget(warning_input_sources_button);
connect(warning_input_sources_button, &QPushButton::clicked, this, [this] {
ControllerInterfaceWindow window{this};
SetQWidgetWindowDecorations(&window);
window.exec();
});

View File

@ -16,7 +16,6 @@
#include "DolphinQt/Config/HardcoreWarningWidget.h"
#include "DolphinQt/Config/NewPatchDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "UICommon/GameFile.h"
@ -94,7 +93,6 @@ void PatchesWidget::OnAdd()
bool new_patch_confirmed = false;
{
NewPatchDialog dialog(this, patch);
SetQWidgetWindowDecorations(&dialog);
new_patch_confirmed = dialog.exec();
}
if (new_patch_confirmed)
@ -124,7 +122,6 @@ void PatchesWidget::OnEdit()
bool new_patch_confirmed = false;
{
NewPatchDialog dialog(this, patch);
SetQWidgetWindowDecorations(&dialog);
new_patch_confirmed = dialog.exec();
}
if (new_patch_confirmed)

View File

@ -21,7 +21,6 @@
#include "DiscIO/Volume.h"
#include "DiscIO/VolumeVerifier.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
VerifyWidget::VerifyWidget(std::shared_ptr<DiscIO::Volume> volume) : m_volume(std::move(volume))
@ -180,7 +179,6 @@ void VerifyWidget::Verify()
progress.Reset();
return verifier.GetResult();
});
SetQWidgetWindowDecorations(progress.GetRaw());
progress.GetRaw()->exec();
std::optional<DiscIO::VolumeVerifier::Result> result = future.get();

View File

@ -37,7 +37,6 @@
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
@ -378,7 +377,6 @@ void WiimoteControllersWidget::OnWiimoteConfigure(size_t index)
MappingWindow* window = new MappingWindow(this, type, static_cast<int>(index));
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
}

View File

@ -31,7 +31,6 @@
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "UICommon/GameFile.h"
#include "UICommon/UICommon.h"
@ -283,7 +282,6 @@ bool ConvertDialog::ShowAreYouSureDialog(const QString& text)
warning.setInformativeText(text);
warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
SetQWidgetWindowDecorations(&warning);
return warning.exec() == QMessageBox::Yes;
}
@ -408,7 +406,6 @@ void ConvertDialog::Convert()
.arg(dst_info.fileName()));
confirm_replace.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
SetQWidgetWindowDecorations(&confirm_replace);
if (confirm_replace.exec() == QMessageBox::No)
continue;
}
@ -519,7 +516,6 @@ void ConvertDialog::Convert()
break;
}
SetQWidgetWindowDecorations(progress_dialog.GetRaw());
progress_dialog.GetRaw()->exec();
if (!success.get())
{

View File

@ -47,7 +47,6 @@
#include "DolphinQt/Host.h"
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"

View File

@ -30,7 +30,6 @@
#include "DolphinQt/Debugger/BreakpointDialog.h"
#include "DolphinQt/Debugger/MemoryWidget.h"
#include "DolphinQt/Host.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
@ -443,7 +442,6 @@ void BreakpointWidget::OnNewBreakpoint()
{
BreakpointDialog* dialog = new BreakpointDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
SetQWidgetWindowDecorations(dialog);
dialog->exec();
}
@ -454,7 +452,6 @@ void BreakpointWidget::OnEditBreakpoint(u32 address, bool is_instruction_bp)
auto* dialog = new BreakpointDialog(
this, m_system.GetPowerPC().GetBreakPoints().GetRegularBreakpoint(address));
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
SetQWidgetWindowDecorations(dialog);
dialog->exec();
}
else
@ -462,7 +459,6 @@ void BreakpointWidget::OnEditBreakpoint(u32 address, bool is_instruction_bp)
auto* dialog =
new BreakpointDialog(this, m_system.GetPowerPC().GetMemChecks().GetMemCheck(address));
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
SetQWidgetWindowDecorations(dialog);
dialog->exec();
}

View File

@ -40,7 +40,6 @@
#include "DolphinQt/Debugger/PatchInstructionDialog.h"
#include "DolphinQt/Host.h"
#include "DolphinQt/QtUtils/FromStdString.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
@ -743,7 +742,6 @@ void CodeViewWidget::AutoStep(CodeTrace::AutoStop option)
.arg(QString::fromStdString(fmt::format("{:#x}", fmt::join(mem_out, ", "))));
msgbox.setInformativeText(msgtext);
SetQWidgetWindowDecorations(&msgbox);
msgbox.exec();
} while (msgbox.clickedButton() == (QAbstractButton*)run_button);
@ -1031,7 +1029,6 @@ void CodeViewWidget::DoPatchInstruction(bool assemble)
if (assemble)
{
AssembleInstructionDialog dialog(this, addr, debug_interface.ReadInstruction(guard, addr));
SetQWidgetWindowDecorations(&dialog);
if (dialog.exec() == QDialog::Accepted)
{
debug_interface.SetPatch(guard, addr, dialog.GetCode());
@ -1041,7 +1038,6 @@ void CodeViewWidget::DoPatchInstruction(bool assemble)
else
{
PatchInstructionDialog dialog(this, addr, debug_interface.ReadInstruction(guard, addr));
SetQWidgetWindowDecorations(&dialog);
if (dialog.exec() == QDialog::Accepted)
{
debug_interface.SetPatch(guard, addr, dialog.GetCode());

View File

@ -29,7 +29,6 @@
#include "Core/System.h"
#include "DolphinQt/Debugger/BranchWatchDialog.h"
#include "DolphinQt/Host.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
static const QString BOX_SPLITTER_STYLESHEET = QStringLiteral(
@ -222,7 +221,6 @@ void CodeWidget::OnBranchWatchDialog()
m_branch_watch_dialog = new BranchWatchDialog(m_system, m_system.GetPowerPC().GetBranchWatch(),
m_ppc_symbol_db, this, this);
}
SetQWidgetWindowDecorations(m_branch_watch_dialog);
m_branch_watch_dialog->show();
m_branch_watch_dialog->raise();
m_branch_watch_dialog->activateWindow();

View File

@ -18,7 +18,6 @@
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "DolphinQt/Host.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
RegisterWidget::RegisterWidget(QWidget* parent)
@ -309,7 +308,6 @@ void RegisterWidget::AutoStep(const std::string& reg) const
break;
// Can keep running and try again after a time out.
SetQWidgetWindowDecorations(&msgbox);
msgbox.exec();
if (msgbox.clickedButton() != (QAbstractButton*)run_button)
break;

View File

@ -16,7 +16,6 @@
#include "DolphinQt/DiscordJoinRequestDialog.h"
#include "DolphinQt/QtUtils/RunOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
DiscordHandler::DiscordHandler(QWidget* parent) : QObject{parent}, m_parent{parent}
{
@ -61,7 +60,6 @@ void DiscordHandler::ShowNewJoinRequest(const std::string& id, const std::string
std::lock_guard<std::mutex> lock(m_request_dialogs_mutex);
m_request_dialogs.emplace_front(m_parent, id, discord_tag, avatar);
DiscordJoinRequestDialog& request_dialog = m_request_dialogs.front();
SetQWidgetWindowDecorations(&request_dialog);
request_dialog.show();
request_dialog.raise();
request_dialog.activateWindow();

View File

@ -29,7 +29,6 @@
#include "Core/System.h"
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Settings/GameCubePane.h"
@ -492,7 +491,6 @@ void GBAWidget::contextMenuEvent(QContextMenuEvent* event)
size_menu->addAction(x4_action);
menu->move(event->globalPos());
SetQWidgetWindowDecorations(menu);
menu->show();
}

View File

@ -42,7 +42,6 @@
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
using namespace ExpansionInterface;
@ -695,7 +694,6 @@ void GCMemcardManager::FixChecksums()
void GCMemcardManager::CreateNewCard(Slot slot)
{
GCMemcardCreateNewDialog dialog(this);
SetQWidgetWindowDecorations(&dialog);
if (dialog.exec() == QDialog::Accepted)
m_slot_file_edit[slot]->setText(QString::fromStdString(dialog.GetMemoryCardPath()));
}

View File

@ -67,7 +67,6 @@
#include "DolphinQt/QtUtils/DoubleClickEventFilter.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/WiiUpdate.h"
@ -588,7 +587,6 @@ void GameList::OpenProperties()
&GameList::OpenAchievementSettings);
#endif // USE_RETRO_ACHIEVEMENTS
SetQWidgetWindowDecorations(properties);
properties->show();
}
@ -643,7 +641,6 @@ void GameList::ConvertFile()
return;
ConvertDialog dialog{std::move(games), this};
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
}
@ -661,7 +658,6 @@ void GameList::InstallWAD()
result_dialog.setWindowTitle(success ? tr("Success") : tr("Failure"));
result_dialog.setText(success ? tr("Successfully installed this title to the NAND.") :
tr("Failed to install this title to the NAND."));
SetQWidgetWindowDecorations(&result_dialog);
result_dialog.exec();
}
@ -679,7 +675,6 @@ void GameList::UninstallWAD()
"this title from the NAND without deleting its save data. Continue?"));
warning_dialog.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
SetQWidgetWindowDecorations(&warning_dialog);
if (warning_dialog.exec() == QMessageBox::No)
return;
@ -691,7 +686,6 @@ void GameList::UninstallWAD()
result_dialog.setWindowTitle(success ? tr("Success") : tr("Failure"));
result_dialog.setText(success ? tr("Successfully removed this title from the NAND.") :
tr("Failed to remove this title from the NAND."));
SetQWidgetWindowDecorations(&result_dialog);
result_dialog.exec();
}
@ -860,7 +854,6 @@ void GameList::DeleteFile()
confirm_dialog.setInformativeText(tr("This cannot be undone!"));
confirm_dialog.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
SetQWidgetWindowDecorations(&confirm_dialog);
if (confirm_dialog.exec() == QMessageBox::Yes)
{
for (const auto& game : GetSelectedGames())
@ -886,7 +879,6 @@ void GameList::DeleteFile()
"delete the file or whether it's still in use."));
error_dialog.setStandardButtons(QMessageBox::Retry | QMessageBox::Abort);
SetQWidgetWindowDecorations(&error_dialog);
if (error_dialog.exec() == QMessageBox::Abort)
break;
}

View File

@ -26,7 +26,6 @@
#include "Core/System.h"
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
@ -159,7 +158,6 @@ void InfinityBaseWindow::LoadFigure(FigureUIPosition slot)
void InfinityBaseWindow::CreateFigure(FigureUIPosition slot)
{
CreateFigureDialog create_dlg(this, slot);
SetQWidgetWindowDecorations(&create_dlg);
if (create_dlg.exec() == CreateFigureDialog::Accepted)
{
LoadFigurePath(slot, create_dlg.GetFilePath());

View File

@ -92,7 +92,6 @@ static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no
return QMessageBox::NoIcon;
}());
SetQWidgetWindowDecorations(&message_box);
const int button = message_box.exec();
if (button == QMessageBox::Yes)
return true;
@ -170,6 +169,8 @@ int main(int argc, char* argv[])
const std::vector<std::string> args = parser->args();
#ifdef _WIN32
QtUtils::InstallWindowDecorationFilter(&app);
FreeConsole();
#endif
@ -281,7 +282,6 @@ int main(int argc, char* argv[])
"This authorization can be revoked at any time through Dolphin's "
"settings."));
SetQWidgetWindowDecorations(&analytics_prompt);
const int answer = analytics_prompt.exec();
Config::SetBase(Config::MAIN_ANALYTICS_PERMISSION_ASKED, true);

View File

@ -112,7 +112,6 @@
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/QtUtils/RunOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/WindowActivationEventFilter.h"
#include "DolphinQt/RenderWidget.h"
#include "DolphinQt/ResourcePackManager.h"
@ -243,7 +242,6 @@ MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boo
restoreGeometry(settings.value(QStringLiteral("mainwindow/geometry")).toByteArray());
if (!Settings::Instance().IsBatchModeEnabled())
{
SetQWidgetWindowDecorations(this);
show();
}
@ -1299,7 +1297,6 @@ void MainWindow::ShowFreeLookWindow()
#endif // USE_RETRO_ACHIEVEMENTS
}
SetQWidgetWindowDecorations(m_freelook_window);
m_freelook_window->show();
m_freelook_window->raise();
m_freelook_window->activateWindow();
@ -1313,7 +1310,6 @@ void MainWindow::ShowSettingsWindow()
InstallHotkeyFilter(m_settings_window);
}
SetQWidgetWindowDecorations(m_settings_window);
m_settings_window->show();
m_settings_window->raise();
m_settings_window->activateWindow();
@ -1334,7 +1330,6 @@ void MainWindow::ShowGeneralWindow()
void MainWindow::ShowAboutDialog()
{
AboutDialog about{this};
SetQWidgetWindowDecorations(&about);
about.exec();
}
@ -1346,7 +1341,6 @@ void MainWindow::ShowHotkeyDialog()
InstallHotkeyFilter(m_hotkey_window);
}
SetQWidgetWindowDecorations(m_hotkey_window);
m_hotkey_window->show();
m_hotkey_window->raise();
m_hotkey_window->activateWindow();
@ -1369,7 +1363,6 @@ void MainWindow::ShowGraphicsWindow()
InstallHotkeyFilter(m_graphics_window);
}
SetQWidgetWindowDecorations(m_graphics_window);
m_graphics_window->show();
m_graphics_window->raise();
m_graphics_window->activateWindow();
@ -1377,7 +1370,6 @@ void MainWindow::ShowGraphicsWindow()
void MainWindow::ShowNetPlaySetupDialog()
{
SetQWidgetWindowDecorations(m_netplay_setup_dialog);
m_netplay_setup_dialog->show();
m_netplay_setup_dialog->raise();
m_netplay_setup_dialog->activateWindow();
@ -1388,7 +1380,6 @@ void MainWindow::ShowNetPlayBrowser()
auto* browser = new NetPlayBrowser(this);
browser->setAttribute(Qt::WA_DeleteOnClose, true);
connect(browser, &NetPlayBrowser::Join, this, &MainWindow::NetPlayJoin);
SetQWidgetWindowDecorations(browser);
browser->exec();
}
@ -1401,7 +1392,6 @@ void MainWindow::ShowFIFOPlayer()
[this](const QString& path) { StartGame(path, ScanForSecondDisc::No); });
}
SetQWidgetWindowDecorations(m_fifo_window);
m_fifo_window->show();
m_fifo_window->raise();
m_fifo_window->activateWindow();
@ -1414,7 +1404,6 @@ void MainWindow::ShowSkylanderPortal()
m_skylander_window = new SkylanderPortalWindow();
}
SetQWidgetWindowDecorations(m_skylander_window);
m_skylander_window->show();
m_skylander_window->raise();
m_skylander_window->activateWindow();
@ -1427,7 +1416,6 @@ void MainWindow::ShowInfinityBase()
m_infinity_window = new InfinityBaseWindow();
}
SetQWidgetWindowDecorations(m_infinity_window);
m_infinity_window->show();
m_infinity_window->raise();
m_infinity_window->activateWindow();
@ -1852,7 +1840,6 @@ void MainWindow::OnImportNANDBackup()
dialog.Reset();
});
SetQWidgetWindowDecorations(dialog.GetRaw());
dialog.GetRaw()->exec();
result.wait();
@ -1966,7 +1953,6 @@ void MainWindow::ShowTASInput()
const auto si_device = Config::Get(Config::GetInfoForSIDevice(i));
if (si_device == SerialInterface::SIDEVICE_GC_GBA_EMULATED)
{
SetQWidgetWindowDecorations(m_gba_tas_input_windows[i]);
m_gba_tas_input_windows[i]->show();
m_gba_tas_input_windows[i]->raise();
m_gba_tas_input_windows[i]->activateWindow();
@ -1974,7 +1960,6 @@ void MainWindow::ShowTASInput()
else if (si_device != SerialInterface::SIDEVICE_NONE &&
si_device != SerialInterface::SIDEVICE_GC_GBA)
{
SetQWidgetWindowDecorations(m_gc_tas_input_windows[i]);
m_gc_tas_input_windows[i]->show();
m_gc_tas_input_windows[i]->raise();
m_gc_tas_input_windows[i]->activateWindow();
@ -1986,7 +1971,6 @@ void MainWindow::ShowTASInput()
if (Config::Get(Config::GetInfoForWiimoteSource(i)) == WiimoteSource::Emulated &&
(!Core::IsRunning(m_system) || m_system.IsWii()))
{
SetQWidgetWindowDecorations(m_wii_tas_input_windows[i]);
m_wii_tas_input_windows[i]->show();
m_wii_tas_input_windows[i]->raise();
m_wii_tas_input_windows[i]->activateWindow();
@ -2012,7 +1996,6 @@ void MainWindow::ShowAchievementsWindow()
m_achievements_window = new AchievementsWindow(this);
}
SetQWidgetWindowDecorations(m_achievements_window);
m_achievements_window->show();
m_achievements_window->raise();
m_achievements_window->activateWindow();
@ -2037,7 +2020,6 @@ void MainWindow::ShowMemcardManager()
{
GCMemcardManager manager(this);
SetQWidgetWindowDecorations(&manager);
manager.exec();
}
@ -2045,13 +2027,11 @@ void MainWindow::ShowResourcePackManager()
{
ResourcePackManager manager(this);
SetQWidgetWindowDecorations(&manager);
manager.exec();
}
void MainWindow::ShowCheatsManager()
{
SetQWidgetWindowDecorations(m_cheats_manager);
m_cheats_manager->show();
}
@ -2070,7 +2050,6 @@ void MainWindow::ShowRiivolutionBootWidget(const UICommon::GameFile& game)
auto& disc = std::get<BootParameters::Disc>(boot_params->parameters);
RiivolutionBootWidget w(disc.volume->GetGameID(), disc.volume->GetRevision(),
disc.volume->GetDiscNumber(), game.GetFilePath(), this);
SetQWidgetWindowDecorations(&w);
#ifdef USE_RETRO_ACHIEVEMENTS
connect(&w, &RiivolutionBootWidget::OpenAchievementSettings, this,

View File

@ -67,7 +67,6 @@
#include "DolphinQt/QtUtils/NonAutodismissibleMenu.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Updater.h"
@ -1393,7 +1392,6 @@ void MenuBar::CheckNAND()
{
NANDRepairDialog dialog(result, this);
SetQWidgetWindowDecorations(&dialog);
if (dialog.exec() != QDialog::Accepted)
return;
}
@ -1564,7 +1562,6 @@ void MenuBar::GenerateSymbolsFromRSOAuto()
return matches;
});
SetQWidgetWindowDecorations(progress.GetRaw());
progress.GetRaw()->exec();
const auto matches = future.get();

View File

@ -14,7 +14,6 @@
#include "Common/Config/Config.h"
#include "Core/Config/MainSettings.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
bool NKitWarningDialog::ShowUnlessDisabled(QWidget* parent)
@ -23,7 +22,6 @@ bool NKitWarningDialog::ShowUnlessDisabled(QWidget* parent)
return true;
NKitWarningDialog dialog(parent);
SetQWidgetWindowDecorations(&dialog);
return dialog.exec() == QDialog::Accepted;
}

View File

@ -26,7 +26,6 @@
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
NetPlayBrowser::NetPlayBrowser(QWidget* parent) : QDialog(parent)
@ -301,7 +300,6 @@ void NetPlayBrowser::accept()
dialog.setWindowModality(Qt::WindowModal);
dialog.setTextEchoMode(QLineEdit::Password);
SetQWidgetWindowDecorations(&dialog);
if (dialog.exec() != QDialog::Accepted)
return;

View File

@ -54,7 +54,6 @@
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/QtUtils/RunOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Settings/GameCubePane.h"
@ -215,7 +214,6 @@ void NetPlayDialog::CreateMainLayout()
m_game_digest_menu->addAction(tr("Other game..."), this, [this] {
GameListDialog gld(m_game_list_model, this);
SetQWidgetWindowDecorations(&gld);
if (gld.exec() != QDialog::Accepted)
return;
Settings::Instance().GetNetPlayServer()->ComputeGameDigest(
@ -337,7 +335,6 @@ void NetPlayDialog::ConnectWidgets()
Settings::Instance().GetNetPlayServer()->KickPlayer(id);
});
connect(m_assign_ports_button, &QPushButton::clicked, [this] {
SetQWidgetWindowDecorations(m_pad_mapping);
m_pad_mapping->exec();
Settings::Instance().GetNetPlayServer()->SetPadMapping(m_pad_mapping->GetGCPadArray());
@ -383,7 +380,6 @@ void NetPlayDialog::ConnectWidgets()
connect(m_game_button, &QPushButton::clicked, [this] {
GameListDialog gld(m_game_list_model, this);
SetQWidgetWindowDecorations(&gld);
if (gld.exec() == QDialog::Accepted)
{
Settings& settings = Settings::Instance();

View File

@ -5,8 +5,6 @@
#include <QApplication>
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
ModalMessageBox::ModalMessageBox(QWidget* parent, Qt::WindowModality modality)
: QMessageBox(parent != nullptr ? parent->window() : nullptr)
{
@ -31,7 +29,6 @@ static inline int ExecMessageBox(ModalMessageBox::Icon icon, QWidget* parent, co
msg.setDefaultButton(default_button);
msg.setDetailedText(detailed_text);
SetQWidgetWindowDecorations(&msg);
return msg.exec();
}

View File

@ -1,25 +1,81 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#if defined(_WIN32)
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include <QApplication>
#include <QEvent>
#include <QWidget>
#include <dwmapi.h>
#include "DolphinQt/Settings.h"
#ifdef _WIN32
#include <dwmapi.h>
#endif
namespace
{
void SetQWidgetWindowDecorations(QWidget* widget)
{
#ifdef _WIN32
if (!Settings::Instance().IsThemeDark())
return;
BOOL use_dark_title_bar = TRUE;
DwmSetWindowAttribute(HWND(widget->winId()),
20 /* DWMWINDOWATTRIBUTE::DWMWA_USE_IMMERSIVE_DARK_MODE */,
&use_dark_title_bar, DWORD(sizeof(use_dark_title_bar)));
#endif
constexpr DWORD attribute = 20; // DWMWINDOWATTRIBUTE::DWMWA_USE_IMMERSIVE_DARK_MODE
constexpr BOOL use_dark_title_bar = TRUE;
DwmSetWindowAttribute(HWND(widget->winId()), attribute, &use_dark_title_bar,
DWORD(sizeof(use_dark_title_bar)));
}
class WindowDecorationFilter final : public QObject
{
public:
using QObject::QObject;
bool eventFilter(QObject* obj, QEvent* event) override
{
if (event->type() == QEvent::Show || event->type() == QEvent::ApplicationPaletteChange)
{
SetQWidgetWindowDecorations(static_cast<QWidget*>(obj));
}
return QObject::eventFilter(obj, event);
}
};
class WindowDecorationFilterInstaller final : public QObject
{
public:
using QObject::QObject;
bool eventFilter(QObject* obj, QEvent* event) override
{
if (event->type() == QEvent::WinIdChange)
{
auto* const widget = qobject_cast<QWidget*>(obj);
// Install the real filter on actual Window QWidgets.
// This avoids the need for a qobject_cast on literally every QEvent::Show.
if (widget && widget->isWindow())
widget->installEventFilter(m_decoration_filter);
}
return QObject::eventFilter(obj, event);
}
private:
QObject* const m_decoration_filter = new WindowDecorationFilter{this};
};
} // namespace
namespace QtUtils
{
void InstallWindowDecorationFilter(QApplication* app)
{
app->installEventFilter(new WindowDecorationFilterInstaller{app});
}
} // namespace QtUtils
#endif

View File

@ -3,7 +3,14 @@
#pragma once
class QWidget;
#if defined(_WIN32)
// Changes the window decorations (title bar) to dark if the user uses dark mode on Windows.
void SetQWidgetWindowDecorations(QWidget* widget);
class QApplication;
namespace QtUtils
{
// Changes the window decorations (title bar) for Windows "Dark" mode or "Dark" Dolphin Style.
void InstallWindowDecorationFilter(QApplication*);
} // namespace QtUtils
#endif

View File

@ -14,7 +14,6 @@
#include "Common/FileUtil.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "UICommon/ResourcePack/Manager.h"
ResourcePackManager::ResourcePackManager(QWidget* widget) : QDialog(widget)
@ -241,7 +240,6 @@ void ResourcePackManager::Remove()
box.setIcon(QMessageBox::Warning);
box.setStandardButtons(QMessageBox::Yes | QMessageBox::Abort);
SetQWidgetWindowDecorations(&box);
if (box.exec() != QMessageBox::Yes)
return;

View File

@ -39,7 +39,6 @@
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Settings/BroadbandAdapterSettingsDialog.h"
@ -381,28 +380,24 @@ void GameCubePane::OnConfigPressed(ExpansionInterface::Slot slot)
{
// TODO: convert MappingWindow to use Slot?
MappingWindow dialog(this, MappingWindow::Type::MAPPING_GC_MICROPHONE, static_cast<int>(slot));
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
case ExpansionInterface::EXIDeviceType::Ethernet:
{
BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::Ethernet);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
case ExpansionInterface::EXIDeviceType::EthernetXLink:
{
BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::XLinkKai);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
case ExpansionInterface::EXIDeviceType::EthernetTapServer:
{
BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::TapServer);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
@ -410,14 +405,12 @@ void GameCubePane::OnConfigPressed(ExpansionInterface::Slot slot)
{
BroadbandAdapterSettingsDialog dialog(this,
BroadbandAdapterSettingsDialog::Type::ModemTapServer);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
case ExpansionInterface::EXIDeviceType::EthernetBuiltIn:
{
BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::BuiltIn);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}

View File

@ -29,7 +29,6 @@
#include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h"
#include "DolphinQt/Config/ToolTipControls/ToolTipPushButton.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
@ -361,7 +360,6 @@ void GeneralPane::GenerateNewIdentity()
message_box.setIcon(QMessageBox::Information);
message_box.setWindowTitle(tr("Identity Generation"));
message_box.setText(tr("New identity generated."));
SetQWidgetWindowDecorations(&message_box);
message_box.exec();
}
#endif

View File

@ -36,7 +36,6 @@
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h"
@ -284,7 +283,6 @@ void WiiPane::CreateSDCard()
progress_dialog.Reset();
return good;
});
SetQWidgetWindowDecorations(progress_dialog.GetRaw());
progress_dialog.GetRaw()->exec();
if (!success.get())
ModalMessageBox::warning(this, tr(Common::SD_PACK_TEXT), tr("Conversion failed."));
@ -309,7 +307,6 @@ void WiiPane::CreateSDCard()
progress_dialog.Reset();
return good;
});
SetQWidgetWindowDecorations(progress_dialog.GetRaw());
progress_dialog.GetRaw()->exec();
if (!success.get())
ModalMessageBox::warning(this, tr(Common::SD_UNPACK_TEXT), tr("Conversion failed."));
@ -467,7 +464,6 @@ void WiiPane::OnUSBWhitelistAddButton()
USBDeviceAddToWhitelistDialog usb_whitelist_dialog(this);
connect(&usb_whitelist_dialog, &USBDeviceAddToWhitelistDialog::accepted, this,
&WiiPane::PopulateUSBPassthroughListWidget);
SetQWidgetWindowDecorations(&usb_whitelist_dialog);
usb_whitelist_dialog.exec();
}

View File

@ -18,7 +18,6 @@
#include "Core/System.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
SkylanderModifyDialog::SkylanderModifyDialog(QWidget* parent, u8 slot)
: QDialog(parent), m_slot(slot)
@ -107,8 +106,6 @@ SkylanderModifyDialog::SkylanderModifyDialog(QWidget* parent, u8 slot)
this->setLayout(layout);
SetQWidgetWindowDecorations(this);
if (should_show)
{
this->show();

View File

@ -35,7 +35,6 @@
#include "Core/System.h"
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
#include "SkylanderModifyDialog.h"
@ -635,7 +634,6 @@ void SkylanderPortalWindow::CreateSkylanderAdvanced()
connect(buttons, &QDialogButtonBox::rejected, create_window, &QDialog::reject);
SetQWidgetWindowDecorations(create_window);
create_window->show();
create_window->raise();
}

View File

@ -29,7 +29,6 @@
#include "DolphinQt/QtUtils/AspectRatioWidget.h"
#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/TAS/IRWidget.h"
#include "DolphinQt/TAS/TASCheckBox.h"
#include "DolphinQt/TAS/TASSpinBox.h"
@ -435,21 +434,15 @@ void WiiTASInputWindow::UpdateControlVisibility()
if (m_active_extension == WiimoteEmu::ExtensionNumber::NUNCHUK)
{
setWindowTitle(tr("Wii TAS Input %1 - Wii Remote + Nunchuk").arg(m_num + 1));
SetQWidgetWindowDecorations(m_ir_box);
m_ir_box->show();
SetQWidgetWindowDecorations(m_nunchuk_stick_box);
m_nunchuk_stick_box->show();
m_classic_right_stick_box->hide();
m_classic_left_stick_box->hide();
SetQWidgetWindowDecorations(m_remote_accelerometer_box);
m_remote_accelerometer_box->show();
m_remote_gyroscope_box->setVisible(m_is_motion_plus_attached);
SetQWidgetWindowDecorations(m_nunchuk_accelerometer_box);
m_nunchuk_accelerometer_box->show();
m_triggers_box->hide();
SetQWidgetWindowDecorations(m_nunchuk_buttons_box);
m_nunchuk_buttons_box->show();
SetQWidgetWindowDecorations(m_remote_buttons_box);
m_remote_buttons_box->show();
m_classic_buttons_box->hide();
}
@ -458,18 +451,14 @@ void WiiTASInputWindow::UpdateControlVisibility()
setWindowTitle(tr("Wii TAS Input %1 - Classic Controller").arg(m_num + 1));
m_ir_box->hide();
m_nunchuk_stick_box->hide();
SetQWidgetWindowDecorations(m_classic_right_stick_box);
m_classic_right_stick_box->show();
SetQWidgetWindowDecorations(m_classic_left_stick_box);
m_classic_left_stick_box->show();
m_remote_accelerometer_box->hide();
m_remote_gyroscope_box->hide();
m_nunchuk_accelerometer_box->hide();
SetQWidgetWindowDecorations(m_triggers_box);
m_triggers_box->show();
m_remote_buttons_box->hide();
m_nunchuk_buttons_box->hide();
SetQWidgetWindowDecorations(m_classic_buttons_box);
m_classic_buttons_box->show();
}
else
@ -479,12 +468,10 @@ void WiiTASInputWindow::UpdateControlVisibility()
m_nunchuk_stick_box->hide();
m_classic_right_stick_box->hide();
m_classic_left_stick_box->hide();
SetQWidgetWindowDecorations(m_remote_accelerometer_box);
m_remote_accelerometer_box->show();
m_remote_gyroscope_box->setVisible(m_is_motion_plus_attached);
m_nunchuk_accelerometer_box->hide();
m_triggers_box->hide();
SetQWidgetWindowDecorations(m_remote_buttons_box);
m_remote_buttons_box->show();
m_nunchuk_buttons_box->hide();
m_classic_buttons_box->hide();

View File

@ -17,7 +17,6 @@
#include "Common/Version.h"
#include "DolphinQt/QtUtils/RunOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
// Refer to docs/autoupdate_overview.md for a detailed overview of the autoupdate process
@ -101,7 +100,6 @@ void Updater::OnUpdateAvailable(const NewVersionInformation& info)
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
SetQWidgetWindowDecorations(dialog);
return dialog->exec();
});

View File

@ -21,7 +21,6 @@
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
namespace WiiUpdate
{
@ -130,7 +129,6 @@ static WiiUtils::UpdateResult ShowProgress(QWidget* parent, Callable function, A
return res;
});
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return result.get();
}

View File

@ -13,8 +13,9 @@
namespace ControllerEmu
{
ControlGroup::ControlGroup(std::string name_, const GroupType type_, DefaultValue default_value_)
: name(name_), ui_name(std::move(name_)), type(type_), default_value(default_value_)
ControlGroup::ControlGroup(const std::string& name_, const GroupType type_,
DefaultValue default_value_)
: ControlGroup{name_, name_, type_, default_value_}
{
}
@ -23,6 +24,12 @@ ControlGroup::ControlGroup(std::string name_, std::string ui_name_, const GroupT
: name(std::move(name_)), ui_name(std::move(ui_name_)), type(type_),
default_value(default_value_)
{
if (default_value_ != DefaultValue::AlwaysEnabled)
{
enabled_setting = std::make_unique<NumericSetting<bool>>(
&enabled, NumericSettingDetails{_trans("Enabled")},
(default_value_ == DefaultValue::Enabled), false, true);
}
}
void ControlGroup::AddVirtualNotchSetting(SettingValue<double>* value, double max_virtual_notch_deg)
@ -53,8 +60,8 @@ void ControlGroup::LoadConfig(Common::IniFile::Section* sec, const std::string&
const std::string group(base + name + "/");
// enabled
if (default_value != DefaultValue::AlwaysEnabled)
sec->Get(group + "Enabled", &enabled, default_value != DefaultValue::Disabled);
if (HasEnabledSetting())
enabled_setting->LoadFromIni(*sec, group);
for (auto& setting : numeric_settings)
setting->LoadFromIni(*sec, group);
@ -79,7 +86,8 @@ void ControlGroup::SaveConfig(Common::IniFile::Section* sec, const std::string&
const std::string group(base + name + "/");
// enabled
sec->Set(group + "Enabled", enabled, default_value != DefaultValue::Disabled);
if (HasEnabledSetting())
enabled_setting->SaveToIni(*sec, group);
for (auto& setting : numeric_settings)
setting->SaveToIni(*sec, group);
@ -99,6 +107,9 @@ void ControlGroup::SaveConfig(Common::IniFile::Section* sec, const std::string&
void ControlGroup::UpdateReferences(ciface::ExpressionParser::ControlEnvironment& env)
{
if (HasEnabledSetting())
enabled_setting->GetInputReference().UpdateReference(env);
for (auto& control : controls)
control->control_ref->UpdateReference(env);
@ -126,4 +137,9 @@ void ControlGroup::AddOutput(Translatability translate, std::string name_)
controls.emplace_back(std::make_unique<Output>(translate, std::move(name_)));
}
bool ControlGroup::HasEnabledSetting() const
{
return enabled_setting != nullptr;
}
} // namespace ControllerEmu

View File

@ -15,6 +15,7 @@
#include "Common/IniFile.h"
#include "InputCommon/ControllerEmu/Control/Control.h"
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"
#include "InputCommon/ControllerInterface/CoreDevice.h"
namespace ControllerEmu
@ -62,7 +63,7 @@ public:
Disabled,
};
explicit ControlGroup(std::string name, GroupType type = GroupType::Other,
explicit ControlGroup(const std::string& name, GroupType type = GroupType::Other,
DefaultValue default_value = DefaultValue::AlwaysEnabled);
ControlGroup(std::string name, std::string ui_name, GroupType type = GroupType::Other,
DefaultValue default_value = DefaultValue::AlwaysEnabled);
@ -98,12 +99,17 @@ public:
return std::copysign(std::max(T{0}, std::abs(input) - deadzone) / (T{1} - deadzone), input);
}
bool HasEnabledSetting() const;
const std::string name;
const std::string ui_name;
const GroupType type;
const DefaultValue default_value;
bool enabled = true;
// The default "enabled" state.
const DefaultValue default_value;
SettingValue<bool> enabled;
std::unique_ptr<NumericSetting<bool>> enabled_setting;
std::vector<std::unique_ptr<Control>> controls;
std::vector<std::unique_ptr<NumericSettingBase>> numeric_settings;
};

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "VideoCommon/FrameDumpFFMpeg.h"
#include "Common/TimeUtil.h"
#if defined(__FreeBSD__)
#define __STDC_CONSTANT_MACROS 1
@ -124,11 +125,15 @@ std::string GetDumpPath(const std::string& extension, std::time_t time, u32 inde
if (!dump_path.empty())
return dump_path;
const auto local_time = Common::LocalTime(time);
if (!local_time)
return "";
const std::string path_prefix =
File::GetUserPath(D_DUMPFRAMES_IDX) + SConfig::GetInstance().GetGameID();
const std::string base_name =
fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}_{}", path_prefix, fmt::localtime(time), index);
fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}_{}", path_prefix, *local_time, index);
const std::string path = fmt::format("{}.{}", base_name, extension);