3 changes: 3 additions & 0 deletions Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp
Expand Up @@ -16,6 +16,7 @@
#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/ControlReference/ControlReference.h"
#include "InputCommon/ControllerEmu/Control/Control.h"
Expand Down Expand Up @@ -248,6 +249,7 @@ void MappingWidget::ShowAdvancedControlGroupDialog(ControllerEmu::ControlGroup*
// Enable "Close" button functionality.
connect(button_box, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);

SetQWidgetWindowDecorations(&dialog);
dialog.exec();
}

Expand Down Expand Up @@ -303,6 +305,7 @@ MappingWidget::CreateSettingAdvancedMappingButton(ControllerEmu::NumericSettingB
setting.SetExpressionFromValue();

IOWindow io(this, GetController(), &setting.GetInputReference(), IOWindow::Type::Input);
SetQWidgetWindowDecorations(&io);
io.exec();

setting.SimplifyIfPossible();
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp
Expand Up @@ -49,6 +49,7 @@
#include "DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/WindowActivationEventFilter.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "DolphinQt/Settings.h"
Expand Down Expand Up @@ -255,6 +256,7 @@ 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;
}
Expand All @@ -267,6 +269,7 @@ void MappingWindow::OnDeleteProfilePressed()
confirm.setInformativeText(tr("This cannot be undone!"));
confirm.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);

SetQWidgetWindowDecorations(&confirm);
if (confirm.exec() != QMessageBox::Yes)
{
return;
Expand Down Expand Up @@ -294,6 +297,7 @@ 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;
}
Expand Down
Expand Up @@ -14,6 +14,7 @@
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"

#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"

#include "InputCommon/InputConfig.h"

Expand Down Expand Up @@ -42,6 +43,7 @@ void WiimoteEmuExtensionMotionInput::CreateNunchukLayout()
ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this);
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
});
layout->addLayout(warning_layout, 0, 0, 1, -1);
Expand Down
Expand Up @@ -15,6 +15,7 @@
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"

#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"

#include "InputCommon/InputConfig.h"

Expand All @@ -40,6 +41,7 @@ void WiimoteEmuMotionControlIMU::CreateMainLayout()
ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this);
window->setAttribute(Qt::WA_DeleteOnClose, true);
window->setWindowModality(Qt::WindowModality::WindowModal);
SetQWidgetWindowDecorations(window);
window->show();
});

Expand Down
17 changes: 15 additions & 2 deletions Source/Core/DolphinQt/Config/PatchesWidget.cpp
Expand Up @@ -15,6 +15,7 @@
#include "Core/PatchEngine.h"

#include "DolphinQt/Config/NewPatchDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"

#include "UICommon/GameFile.h"

Expand Down Expand Up @@ -74,7 +75,13 @@ void PatchesWidget::OnAdd()
PatchEngine::Patch patch;
patch.user_defined = true;

if (NewPatchDialog(this, patch).exec())
bool new_patch_confirmed = false;
{
NewPatchDialog dialog(this, patch);
SetQWidgetWindowDecorations(&dialog);
new_patch_confirmed = dialog.exec();
}
if (new_patch_confirmed)
{
m_patches.push_back(patch);
SavePatches();
Expand All @@ -98,7 +105,13 @@ void PatchesWidget::OnEdit()
patch.name = tr("%1 (Copy)").arg(QString::fromStdString(patch.name)).toStdString();
}

if (NewPatchDialog(this, patch).exec())
bool new_patch_confirmed = false;
{
NewPatchDialog dialog(this, patch);
SetQWidgetWindowDecorations(&dialog);
new_patch_confirmed = dialog.exec();
}
if (new_patch_confirmed)
{
if (patch.user_defined)
{
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/Config/VerifyWidget.cpp
Expand Up @@ -20,6 +20,7 @@
#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))
Expand Down Expand Up @@ -180,6 +181,7 @@ void VerifyWidget::Verify()

return result;
});
SetQWidgetWindowDecorations(progress.GetRaw());
progress.GetRaw()->exec();

std::optional<DiscIO::VolumeVerifier::Result> result = future.get();
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp
Expand Up @@ -33,6 +33,7 @@
#include "DolphinQt/Config/Mapping/MappingWindow.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"

Expand Down Expand Up @@ -261,6 +262,7 @@ 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();
}

Expand Down
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/ConvertDialog.cpp
Expand Up @@ -31,6 +31,7 @@
#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"

Expand Down Expand Up @@ -285,6 +286,7 @@ bool ConvertDialog::ShowAreYouSureDialog(const QString& text)
warning.setInformativeText(text);
warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No);

SetQWidgetWindowDecorations(&warning);
return warning.exec() == QMessageBox::Yes;
}

Expand Down Expand Up @@ -409,6 +411,7 @@ void ConvertDialog::Convert()
.arg(dst_info.fileName()));
confirm_replace.setStandardButtons(QMessageBox::Yes | QMessageBox::No);

SetQWidgetWindowDecorations(&confirm_replace);
if (confirm_replace.exec() == QMessageBox::No)
continue;
}
Expand Down Expand Up @@ -519,6 +522,7 @@ void ConvertDialog::Convert()
break;
}

SetQWidgetWindowDecorations(progress_dialog.GetRaw());
progress_dialog.GetRaw()->exec();
if (!success.get())
{
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp
Expand Up @@ -22,6 +22,7 @@

#include "DolphinQt/Debugger/BreakpointDialog.h"
#include "DolphinQt/Debugger/MemoryWidget.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"

Expand Down Expand Up @@ -313,6 +314,7 @@ void BreakpointWidget::OnClear()
void BreakpointWidget::OnNewBreakpoint()
{
BreakpointDialog* dialog = new BreakpointDialog(this);
SetQWidgetWindowDecorations(dialog);
dialog->exec();
}

Expand All @@ -322,12 +324,14 @@ void BreakpointWidget::OnEditBreakpoint(u32 address, bool is_instruction_bp)
{
auto* dialog =
new BreakpointDialog(this, m_system.GetPowerPC().GetBreakPoints().GetBreakpoint(address));
SetQWidgetWindowDecorations(dialog);
dialog->exec();
}
else
{
auto* dialog =
new BreakpointDialog(this, m_system.GetPowerPC().GetMemChecks().GetMemCheck(address));
SetQWidgetWindowDecorations(dialog);
dialog->exec();
}

Expand Down
9 changes: 6 additions & 3 deletions Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp
Expand Up @@ -37,6 +37,7 @@
#include "Core/System.h"
#include "DolphinQt/Debugger/PatchInstructionDialog.h"
#include "DolphinQt/Host.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"

Expand Down Expand Up @@ -306,7 +307,7 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard)
const std::optional<u32> pc =
guard ? std::make_optional(power_pc.GetPPCState().pc) : std::nullopt;

const bool dark_theme = qApp->palette().color(QPalette::Base).valueF() < 0.5;
const bool dark_theme = Settings::Instance().IsThemeDark();

m_branches.clear();

Expand Down Expand Up @@ -349,7 +350,7 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard)
}
else if (color != 0xFFFFFF)
{
item->setBackground(dark_theme ? QColor(color).darker(240) : QColor(color));
item->setBackground(dark_theme ? QColor(color).darker(400) : QColor(color));
}
}

Expand All @@ -371,7 +372,7 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard)

description_item->setText(
tr("--> %1").arg(QString::fromStdString(debug_interface.GetDescription(branch_addr))));
param_item->setForeground(Qt::magenta);
param_item->setForeground(dark_theme ? QColor(255, 135, 255) : Qt::magenta);
}

if (ins == "blr")
Expand Down Expand Up @@ -733,6 +734,7 @@ 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);
Expand Down Expand Up @@ -1010,6 +1012,7 @@ void CodeViewWidget::OnReplaceInstruction()
auto& debug_interface = m_system.GetPowerPC().GetDebugInterface();
PatchInstructionDialog dialog(this, addr, debug_interface.ReadInstruction(guard, addr));

SetQWidgetWindowDecorations(&dialog);
if (dialog.exec() == QDialog::Accepted)
{
debug_interface.SetPatch(guard, addr, dialog.GetCode());
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/Debugger/CodeWidget.cpp
Expand Up @@ -28,6 +28,7 @@
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "DolphinQt/Host.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"

static const QString BOX_SPLITTER_STYLESHEET = QStringLiteral(
Expand Down Expand Up @@ -213,6 +214,7 @@ void CodeWidget::OnDiff()
if (!m_diff_dialog)
m_diff_dialog = new CodeDiffDialog(this);
m_diff_dialog->setWindowFlag(Qt::WindowMinimizeButtonHint);
SetQWidgetWindowDecorations(m_diff_dialog);
m_diff_dialog->show();
m_diff_dialog->raise();
m_diff_dialog->activateWindow();
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/Debugger/RegisterWidget.cpp
Expand Up @@ -18,6 +18,7 @@
#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)
Expand Down Expand Up @@ -307,6 +308,7 @@ 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;
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/DiscordHandler.cpp
Expand Up @@ -16,6 +16,7 @@

#include "DolphinQt/DiscordJoinRequestDialog.h"
#include "DolphinQt/QtUtils/RunOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"

DiscordHandler::DiscordHandler(QWidget* parent) : QObject{parent}, m_parent{parent}
{
Expand Down Expand Up @@ -60,6 +61,7 @@ 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();
Expand Down
6 changes: 6 additions & 0 deletions Source/Core/DolphinQt/DolphinQt.vcxproj
Expand Up @@ -188,6 +188,7 @@
<ClCompile Include="QtUtils\ModalMessageBox.cpp" />
<ClCompile Include="QtUtils\NonDefaultQPushButton.cpp" />
<ClCompile Include="QtUtils\PartiallyClosableTabWidget.cpp" />
<ClCompile Include="QtUtils\SetWindowDecorations.cpp" />
<ClCompile Include="QtUtils\UTF8CodePointCountValidator.cpp" />
<ClCompile Include="QtUtils\WindowActivationEventFilter.cpp" />
<ClCompile Include="QtUtils\WrapInScrollArea.cpp" />
Expand Down Expand Up @@ -379,6 +380,7 @@
<QtMoc Include="QtUtils\FileOpenEventFilter.h" />
<QtMoc Include="QtUtils\ParallelProgressDialog.h" />
<QtMoc Include="QtUtils\PartiallyClosableTabWidget.h" />
<ClInclude Include="QtUtils\SetWindowDecorations.h" />
<QtMoc Include="QtUtils\UTF8CodePointCountValidator.h" />
<QtMoc Include="QtUtils\WindowActivationEventFilter.h" />
<QtMoc Include="RenderWidget.h" />
Expand Down Expand Up @@ -415,6 +417,10 @@
<ItemGroup>
<Natvis Include="qt6.natvis" />
</ItemGroup>
<ItemGroup>
<Text Include="Styles\Dark\dark.qss" />
<QtRcc Include="Styles\Dark\dark.qrc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(CoreDir)DolphinLib.vcxproj">
<Project>{D79392F7-06D6-4B4B-A39F-4D587C215D3A}</Project>
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/GBAWidget.cpp
Expand Up @@ -29,6 +29,7 @@
#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"
Expand Down Expand Up @@ -486,6 +487,7 @@ void GBAWidget::contextMenuEvent(QContextMenuEvent* event)
size_menu->addAction(x4_action);

menu->move(event->globalPos());
SetQWidgetWindowDecorations(menu);
menu->show();
}

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/GCMemcardManager.cpp
Expand Up @@ -42,6 +42,7 @@
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"

using namespace ExpansionInterface;

Expand Down Expand Up @@ -695,6 +696,7 @@ 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()));
}
Expand Down
8 changes: 8 additions & 0 deletions Source/Core/DolphinQt/GameList/GameList.cpp
Expand Up @@ -67,6 +67,7 @@
#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"
Expand Down Expand Up @@ -546,6 +547,7 @@ void GameList::OpenProperties()
connect(properties, &PropertiesDialog::OpenGraphicsSettings, this,
&GameList::OpenGraphicsSettings);

SetQWidgetWindowDecorations(properties);
properties->show();
}

Expand Down Expand Up @@ -600,6 +602,7 @@ void GameList::ConvertFile()
return;

ConvertDialog dialog{std::move(games), this};
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
}

Expand All @@ -617,6 +620,7 @@ 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();
}

Expand All @@ -634,6 +638,7 @@ 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;

Expand All @@ -645,6 +650,7 @@ 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();
}

Expand Down Expand Up @@ -818,6 +824,7 @@ 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())
Expand All @@ -843,6 +850,7 @@ 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;
}
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp
Expand Up @@ -26,6 +26,7 @@
#include "Core/System.h"

#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"

// Qt is not guaranteed to keep track of file paths using native file pickers, so we use this
Expand Down Expand Up @@ -149,6 +150,7 @@ void InfinityBaseWindow::LoadFigure(u8 slot)
void InfinityBaseWindow::CreateFigure(u8 slot)
{
CreateFigureDialog create_dlg(this, slot);
SetQWidgetWindowDecorations(&create_dlg);
if (create_dlg.exec() == CreateFigureDialog::Accepted)
{
LoadFigurePath(slot, create_dlg.GetFilePath());
Expand Down
10 changes: 8 additions & 2 deletions Source/Core/DolphinQt/Main.cpp
Expand Up @@ -2,11 +2,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later

#ifdef _WIN32
#include <cstdio>
#include <string>
#include <vector>

#include <Windows.h>
#include <cstdio>
#endif

#ifdef __linux__
Expand All @@ -33,6 +33,7 @@
#include "DolphinQt/MainWindow.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/RunOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Translation.h"
Expand Down Expand Up @@ -90,6 +91,7 @@ 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;
Expand Down Expand Up @@ -243,8 +245,11 @@ int main(int argc, char* argv[])
{
DolphinAnalytics::Instance().ReportDolphinStart("qt");

MainWindow win{std::move(boot), static_cast<const char*>(options.get("movie"))};
Settings::Instance().InitDefaultPalette();
Settings::Instance().UpdateSystemDark();
Settings::Instance().SetCurrentUserStyle(Settings::Instance().GetCurrentUserStyle());

MainWindow win{std::move(boot), static_cast<const char*>(options.get("movie"))};
win.Show();

#if defined(USE_ANALYTICS) && USE_ANALYTICS
Expand All @@ -268,6 +273,7 @@ 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);
Expand Down
54 changes: 54 additions & 0 deletions Source/Core/DolphinQt/MainWindow.cpp
Expand Up @@ -108,6 +108,7 @@
#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"
Expand Down Expand Up @@ -1225,6 +1226,7 @@ void MainWindow::ShowControllersWindow()
InstallHotkeyFilter(m_controllers_window);
}

SetQWidgetWindowDecorations(m_controllers_window);
m_controllers_window->show();
m_controllers_window->raise();
m_controllers_window->activateWindow();
Expand All @@ -1238,6 +1240,7 @@ void MainWindow::ShowFreeLookWindow()
InstallHotkeyFilter(m_freelook_window);
}

SetQWidgetWindowDecorations(m_freelook_window);
m_freelook_window->show();
m_freelook_window->raise();
m_freelook_window->activateWindow();
Expand All @@ -1251,6 +1254,7 @@ void MainWindow::ShowSettingsWindow()
InstallHotkeyFilter(m_settings_window);
}

SetQWidgetWindowDecorations(m_settings_window);
m_settings_window->show();
m_settings_window->raise();
m_settings_window->activateWindow();
Expand All @@ -1271,6 +1275,7 @@ void MainWindow::ShowGeneralWindow()
void MainWindow::ShowAboutDialog()
{
AboutDialog about{this};
SetQWidgetWindowDecorations(&about);
about.exec();
}

Expand All @@ -1282,6 +1287,7 @@ void MainWindow::ShowHotkeyDialog()
InstallHotkeyFilter(m_hotkey_window);
}

SetQWidgetWindowDecorations(m_hotkey_window);
m_hotkey_window->show();
m_hotkey_window->raise();
m_hotkey_window->activateWindow();
Expand All @@ -1304,13 +1310,15 @@ void MainWindow::ShowGraphicsWindow()
InstallHotkeyFilter(m_graphics_window);
}

SetQWidgetWindowDecorations(m_graphics_window);
m_graphics_window->show();
m_graphics_window->raise();
m_graphics_window->activateWindow();
}

void MainWindow::ShowNetPlaySetupDialog()
{
SetQWidgetWindowDecorations(m_netplay_setup_dialog);
m_netplay_setup_dialog->show();
m_netplay_setup_dialog->raise();
m_netplay_setup_dialog->activateWindow();
Expand All @@ -1321,6 +1329,7 @@ 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();
}

Expand All @@ -1333,6 +1342,7 @@ 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();
Expand All @@ -1345,6 +1355,7 @@ void MainWindow::ShowSkylanderPortal()
m_skylander_window = new SkylanderPortalWindow();
}

SetQWidgetWindowDecorations(m_skylander_window);
m_skylander_window->show();
m_skylander_window->raise();
m_skylander_window->activateWindow();
Expand All @@ -1357,6 +1368,7 @@ void MainWindow::ShowInfinityBase()
m_infinity_window = new InfinityBaseWindow();
}

SetQWidgetWindowDecorations(m_infinity_window);
m_infinity_window->show();
m_infinity_window->raise();
m_infinity_window->activateWindow();
Expand Down Expand Up @@ -1703,6 +1715,36 @@ QSize MainWindow::sizeHint() const
return QSize(800, 600);
}

#ifdef _WIN32
bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr* result)
{
auto* msg = reinterpret_cast<MSG*>(message);
if (msg && msg->message == WM_SETTINGCHANGE && msg->lParam != NULL &&
std::wstring_view(L"ImmersiveColorSet")
.compare(reinterpret_cast<const wchar_t*>(msg->lParam)) == 0)
{
// Windows light/dark theme has changed. Update our flag and refresh the theme.
auto& settings = Settings::Instance();
const bool was_dark_before = settings.IsSystemDark();
settings.UpdateSystemDark();
if (settings.IsSystemDark() != was_dark_before)
{
settings.SetCurrentUserStyle(settings.GetCurrentUserStyle());

// force the colors in the Skylander window to update
if (m_skylander_window)
m_skylander_window->RefreshList();
}

// TODO: When switching from light to dark, the window decorations remain light. Qt seems very
// convinced that it needs to change these in response to this message, so even if we set them
// to dark here, Qt sets them back to light afterwards.
}

return false;
}
#endif

void MainWindow::OnBootGameCubeIPL(DiscIO::Region region)
{
StartGame(std::make_unique<BootParameters>(BootParameters::IPL{region}));
Expand Down Expand Up @@ -1759,6 +1801,7 @@ void MainWindow::OnImportNANDBackup()
dialog.Reset();
});

SetQWidgetWindowDecorations(dialog.GetRaw());
dialog.GetRaw()->exec();

result.wait();
Expand Down Expand Up @@ -1866,13 +1909,15 @@ 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();
}
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();
Expand All @@ -1884,6 +1929,7 @@ void MainWindow::ShowTASInput()
if (Config::Get(Config::GetInfoForWiimoteSource(i)) == WiimoteSource::Emulated &&
(!Core::IsRunning() || SConfig::GetInstance().bWii))
{
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();
Expand All @@ -1910,6 +1956,7 @@ 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();
Expand All @@ -1920,18 +1967,21 @@ void MainWindow::ShowMemcardManager()
{
GCMemcardManager manager(this);

SetQWidgetWindowDecorations(&manager);
manager.exec();
}

void MainWindow::ShowResourcePackManager()
{
ResourcePackManager manager(this);

SetQWidgetWindowDecorations(&manager);
manager.exec();
}

void MainWindow::ShowCheatsManager()
{
SetQWidgetWindowDecorations(m_cheats_manager);
m_cheats_manager->show();
}

Expand All @@ -1950,6 +2000,7 @@ 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);
w.exec();
if (!w.ShouldBoot())
return;
Expand All @@ -1961,7 +2012,10 @@ void MainWindow::ShowRiivolutionBootWidget(const UICommon::GameFile& game)
void MainWindow::Show()
{
if (!Settings::Instance().IsBatchModeEnabled())
{
SetQWidgetWindowDecorations(this);
QWidget::show();
}

// If the booting of a game was requested on start up, do that now
if (m_pending_boot != nullptr)
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/MainWindow.h
Expand Up @@ -210,6 +210,11 @@ class MainWindow final : public QMainWindow
void dropEvent(QDropEvent* event) override;
QSize sizeHint() const override;

#ifdef _WIN32
// This gets called for each event from the Windows message queue.
bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;
#endif

#ifdef HAVE_XRANDR
std::unique_ptr<X11Utils::XRRConfiguration> m_xrr_config;
#endif
Expand Down
10 changes: 8 additions & 2 deletions Source/Core/DolphinQt/MenuBar.cpp
Expand Up @@ -59,6 +59,7 @@
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Updater.h"

Expand Down Expand Up @@ -1178,8 +1179,12 @@ void MenuBar::CheckNAND()
return;
}

if (NANDRepairDialog(result, this).exec() != QDialog::Accepted)
return;
{
NANDRepairDialog dialog(result, this);
SetQWidgetWindowDecorations(&dialog);
if (dialog.exec() != QDialog::Accepted)
return;
}

if (WiiUtils::RepairNAND(ios))
{
Expand Down Expand Up @@ -1336,6 +1341,7 @@ void MenuBar::GenerateSymbolsFromRSOAuto()

return matches;
});
SetQWidgetWindowDecorations(progress.GetRaw());
progress.GetRaw()->exec();

const auto matches = future.get();
Expand Down
7 changes: 5 additions & 2 deletions Source/Core/DolphinQt/NKitWarningDialog.cpp
Expand Up @@ -14,14 +14,17 @@

#include "Common/Config/Config.h"
#include "Core/Config/MainSettings.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"

bool NKitWarningDialog::ShowUnlessDisabled(QWidget* parent)
{
if (Config::Get(Config::MAIN_SKIP_NKIT_WARNING))
return true;
else
return NKitWarningDialog(parent).exec() == QDialog::Accepted;

NKitWarningDialog dialog(parent);
SetQWidgetWindowDecorations(&dialog);
return dialog.exec() == QDialog::Accepted;
}

NKitWarningDialog::NKitWarningDialog(QWidget* parent) : QDialog(parent)
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp
Expand Up @@ -26,6 +26,7 @@

#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)
Expand Down Expand Up @@ -303,6 +304,7 @@ void NetPlayBrowser::accept()
dialog->setWindowModality(Qt::WindowModal);
dialog->setTextEchoMode(QLineEdit::Password);

SetQWidgetWindowDecorations(dialog);
if (dialog->exec() != QDialog::Accepted)
return;

Expand Down
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp
Expand Up @@ -51,6 +51,7 @@
#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"
Expand Down Expand Up @@ -213,6 +214,7 @@ 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(
Expand Down Expand Up @@ -335,6 +337,7 @@ 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());
Expand Down Expand Up @@ -380,6 +383,7 @@ 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();
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/DolphinQt/QtUtils/ModalMessageBox.cpp
Expand Up @@ -5,6 +5,8 @@

#include <QApplication>

#include "DolphinQt/QtUtils/SetWindowDecorations.h"

ModalMessageBox::ModalMessageBox(QWidget* parent, Qt::WindowModality modality)
: QMessageBox(parent != nullptr ? parent->window() : nullptr)
{
Expand All @@ -28,6 +30,7 @@ static inline int ExecMessageBox(ModalMessageBox::Icon icon, QWidget* parent, co
msg.setStandardButtons(buttons);
msg.setDefaultButton(default_button);

SetQWidgetWindowDecorations(&msg);
return msg.exec();
}

Expand Down
25 changes: 25 additions & 0 deletions Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp
@@ -0,0 +1,25 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "DolphinQt/QtUtils/SetWindowDecorations.h"

#include <QWidget>

#include "DolphinQt/Settings.h"

#ifdef _WIN32
#include <dwmapi.h>
#endif

void SetQWidgetWindowDecorations(QWidget* widget)
{
#ifdef _WIN32
if (!Settings::Instance().IsSystemDark())
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
}
9 changes: 9 additions & 0 deletions Source/Core/DolphinQt/QtUtils/SetWindowDecorations.h
@@ -0,0 +1,9 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

class QWidget;

// Changes the window decorations (title bar) to dark if the user uses dark mode on Windows.
void SetQWidgetWindowDecorations(QWidget* widget);
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/ResourcePackManager.cpp
Expand Up @@ -14,6 +14,7 @@
#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)
Expand Down Expand Up @@ -241,6 +242,7 @@ void ResourcePackManager::Remove()
box.setIcon(QMessageBox::Warning);
box.setStandardButtons(QMessageBox::Yes | QMessageBox::Abort);

SetQWidgetWindowDecorations(&box);
if (box.exec() != QMessageBox::Yes)
return;

Expand Down
85 changes: 83 additions & 2 deletions Source/Core/DolphinQt/Settings.cpp
Expand Up @@ -4,21 +4,25 @@
#include "DolphinQt/Settings.h"

#include <atomic>
#include <memory>

#include <QApplication>
#include <QColor>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QFontDatabase>
#include <QPalette>
#include <QRadioButton>
#include <QSize>
#include <QStyle>
#include <QWidget>

#ifdef _WIN32
#include <memory>

#include <fmt/format.h>

#include <winrt/Windows.UI.ViewManagement.h>

#include <QTabBar>
#include <QToolButton>
#endif
Expand Down Expand Up @@ -47,6 +51,9 @@
#include "VideoCommon/NetPlayChatUI.h"
#include "VideoCommon/NetPlayGolfUI.h"

static bool s_system_dark = false;
static std::unique_ptr<QPalette> s_default_palette;

Settings::Settings()
{
qRegisterMetaType<Core::State>();
Expand Down Expand Up @@ -125,6 +132,42 @@ QString Settings::GetCurrentUserStyle() const
return QFileInfo(GetQSettings().value(QStringLiteral("userstyle/path")).toString()).fileName();
}

void Settings::InitDefaultPalette()
{
s_default_palette = std::make_unique<QPalette>(qApp->palette());
}

void Settings::UpdateSystemDark()
{
#ifdef _WIN32
// Check if the system is set to dark mode so we can set the default theme and window
// decorations accordingly.
{
using namespace winrt::Windows::UI::ViewManagement;
const UISettings settings;
const auto& color = settings.GetColorValue(UIColorType::Foreground);

const bool is_system_dark = 5 * color.G + 2 * color.R + color.B > 8 * 128;
Settings::Instance().SetSystemDark(is_system_dark);
}
#endif
}

void Settings::SetSystemDark(bool dark)
{
s_system_dark = dark;
}

bool Settings::IsSystemDark()
{
return s_system_dark;
}

bool Settings::IsThemeDark()
{
return qApp->palette().color(QPalette::Base).valueF() < 0.5;
}

// Calling this before the main window has been created breaks the style of some widgets.
void Settings::SetCurrentUserStyle(const QString& stylesheet_name)
{
Expand All @@ -141,6 +184,44 @@ void Settings::SetCurrentUserStyle(const QString& stylesheet_name)
stylesheet_contents = QString::fromUtf8(stylesheet.readAll().data());
}

#ifdef _WIN32
if (stylesheet_contents.isEmpty())
{
// No theme selected or found. Usually we would just fallthrough and set an empty stylesheet
// which would select Qt's default theme, but unlike other OSes we don't automatically get a
// default dark theme on Windows when the user has selected dark mode in the Windows settings.
// So manually check if the user wants dark mode and, if yes, load our embedded dark theme.
if (IsSystemDark())
{
QFile file(QStringLiteral(":/dolphin_dark_win/dark.qss"));
if (file.open(QFile::ReadOnly))
stylesheet_contents = QString::fromUtf8(file.readAll().data());

QPalette palette = qApp->style()->standardPalette();
palette.setColor(QPalette::Window, QColor(32, 32, 32));
palette.setColor(QPalette::WindowText, QColor(220, 220, 220));
palette.setColor(QPalette::Base, QColor(32, 32, 32));
palette.setColor(QPalette::AlternateBase, QColor(48, 48, 48));
palette.setColor(QPalette::PlaceholderText, QColor(126, 126, 126));
palette.setColor(QPalette::Text, QColor(220, 220, 220));
palette.setColor(QPalette::Button, QColor(48, 48, 48));
palette.setColor(QPalette::ButtonText, QColor(220, 220, 220));
palette.setColor(QPalette::BrightText, QColor(255, 255, 255));
palette.setColor(QPalette::Highlight, QColor(0, 120, 215));
palette.setColor(QPalette::HighlightedText, QColor(255, 255, 255));
palette.setColor(QPalette::Link, QColor(100, 160, 220));
palette.setColor(QPalette::LinkVisited, QColor(100, 160, 220));
qApp->setPalette(palette);
}
else
{
// reset any palette changes that may exist from a previously set dark mode
if (s_default_palette)
qApp->setPalette(*s_default_palette);
}
}
#endif

// Define tooltips style if not already defined
if (!stylesheet_contents.contains(QStringLiteral("QToolTip"), Qt::CaseSensitive))
{
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/Settings.h
Expand Up @@ -52,6 +52,11 @@ class Settings final : public QObject

// UI
void SetThemeName(const QString& theme_name);
void InitDefaultPalette();
void UpdateSystemDark();
void SetSystemDark(bool dark);
bool IsSystemDark();
bool IsThemeDark();
void SetCurrentUserStyle(const QString& stylesheet_name);
QString GetCurrentUserStyle() const;

Expand Down
19 changes: 15 additions & 4 deletions Source/Core/DolphinQt/Settings/GameCubePane.cpp
Expand Up @@ -39,6 +39,7 @@
#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"
Expand Down Expand Up @@ -379,22 +380,32 @@ void GameCubePane::OnConfigPressed(ExpansionInterface::Slot slot)
BrowseAGPRom(slot);
return;
case ExpansionInterface::EXIDeviceType::Microphone:
{
// TODO: convert MappingWindow to use Slot?
MappingWindow(this, MappingWindow::Type::MAPPING_GC_MICROPHONE, static_cast<int>(slot)).exec();
MappingWindow dialog(this, MappingWindow::Type::MAPPING_GC_MICROPHONE, static_cast<int>(slot));
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
case ExpansionInterface::EXIDeviceType::Ethernet:
{
BroadbandAdapterSettingsDialog(this, BroadbandAdapterSettingsDialog::Type::Ethernet).exec();
BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::Ethernet);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
case ExpansionInterface::EXIDeviceType::EthernetXLink:
{
BroadbandAdapterSettingsDialog(this, BroadbandAdapterSettingsDialog::Type::XLinkKai).exec();
BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::XLinkKai);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
case ExpansionInterface::EXIDeviceType::EthernetBuiltIn:
{
BroadbandAdapterSettingsDialog(this, BroadbandAdapterSettingsDialog::Type::BuiltIn).exec();
BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::BuiltIn);
SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return;
}
default:
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/Settings/GeneralPane.cpp
Expand Up @@ -24,6 +24,7 @@

#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"

Expand Down Expand Up @@ -370,6 +371,7 @@ 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
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Settings/WiiPane.cpp
Expand Up @@ -35,6 +35,7 @@
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/ParallelProgressDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
#include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h"
Expand Down Expand Up @@ -288,6 +289,7 @@ void WiiPane::CreateSDCard()
progress_dialog.Reset();
return good;
});
SetQWidgetWindowDecorations(progress_dialog.GetRaw());
progress_dialog.GetRaw()->exec();
if (!success.get())
ModalMessageBox::warning(this, tr("Convert Folder to File Now"), tr("Conversion failed."));
Expand All @@ -312,6 +314,7 @@ void WiiPane::CreateSDCard()
progress_dialog.Reset();
return good;
});
SetQWidgetWindowDecorations(progress_dialog.GetRaw());
progress_dialog.GetRaw()->exec();
if (!success.get())
ModalMessageBox::warning(this, tr("Convert File to Folder Now"), tr("Conversion failed."));
Expand Down Expand Up @@ -468,6 +471,7 @@ 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();
}

Expand Down
44 changes: 32 additions & 12 deletions Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp
Expand Up @@ -34,6 +34,7 @@
#include "Core/System.h"

#include "DolphinQt/QtUtils/DolphinFileDialog.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"

Expand Down Expand Up @@ -560,6 +561,7 @@ void SkylanderPortalWindow::CreateSkylanderAdvanced()

connect(buttons, &QDialogButtonBox::rejected, create_window, &QDialog::reject);

SetQWidgetWindowDecorations(create_window);
create_window->show();
create_window->raise();
}
Expand Down Expand Up @@ -610,6 +612,8 @@ void SkylanderPortalWindow::UpdateCurrentIDs()

void SkylanderPortalWindow::RefreshList()
{
const bool is_dark_theme = Settings::Instance().IsThemeDark();

const int row = m_skylander_list->currentRow();
m_skylander_list->clear();
if (m_only_show_collection->isChecked())
Expand All @@ -633,8 +637,16 @@ void SkylanderPortalWindow::RefreshList()
{
const uint qvar = (ids.first << 16) | ids.second;
QListWidgetItem* skylander = new QListWidgetItem(file.baseName());
skylander->setBackground(GetBaseColor(ids));
skylander->setForeground(QBrush(QColor(0, 0, 0, 255)));
if (is_dark_theme)
{
skylander->setBackground(GetBaseColor(ids, true));
skylander->setForeground(QBrush(QColor(220, 220, 220)));
}
else
{
skylander->setBackground(GetBaseColor(ids, false));
skylander->setForeground(QBrush(QColor(0, 0, 0)));
}
skylander->setData(1, qvar);
m_skylander_list->addItem(skylander);
}
Expand All @@ -650,8 +662,16 @@ void SkylanderPortalWindow::RefreshList()
{
const uint qvar = (entry.first.first << 16) | entry.first.second;
QListWidgetItem* skylander = new QListWidgetItem(tr(entry.second.name));
skylander->setBackground(GetBaseColor(entry.first));
skylander->setForeground(QBrush(QColor(0, 0, 0, 255)));
if (is_dark_theme)
{
skylander->setBackground(GetBaseColor(entry.first, true));
skylander->setForeground(QBrush(QColor(220, 220, 220)));
}
else
{
skylander->setBackground(GetBaseColor(entry.first, false));
skylander->setForeground(QBrush(QColor(0, 0, 0)));
}
skylander->setData(1, qvar);
m_skylander_list->addItem(skylander);
}
Expand Down Expand Up @@ -895,27 +915,27 @@ int SkylanderPortalWindow::GetElementRadio()
return -1;
}

QBrush SkylanderPortalWindow::GetBaseColor(std::pair<const u16, const u16> ids)
QBrush SkylanderPortalWindow::GetBaseColor(std::pair<const u16, const u16> ids, bool dark_theme)
{
auto skylander = IOS::HLE::USB::list_skylanders.find(ids);

if (skylander == IOS::HLE::USB::list_skylanders.end())
return QBrush(QColor(255, 255, 255, 255));
return QBrush(dark_theme ? QColor(32, 32, 32) : QColor(255, 255, 255));

switch ((*skylander).second.game)
{
case IOS::HLE::USB::Game::SpyrosAdv:
return QBrush(QColor(240, 255, 240, 255));
return QBrush(dark_theme ? QColor(10, 42, 90) : QColor(240, 255, 240));
case IOS::HLE::USB::Game::Giants:
return QBrush(QColor(255, 240, 215, 255));
return QBrush(dark_theme ? QColor(120, 16, 12) : QColor(255, 240, 215));
case IOS::HLE::USB::Game::SwapForce:
return QBrush(QColor(240, 245, 255, 255));
return QBrush(dark_theme ? QColor(28, 45, 12) : QColor(240, 245, 255));
case IOS::HLE::USB::Game::TrapTeam:
return QBrush(QColor(255, 240, 240, 255));
return QBrush(dark_theme ? QColor(0, 56, 76) : QColor(255, 240, 240));
case IOS::HLE::USB::Game::Superchargers:
return QBrush(QColor(247, 228, 215, 255));
return QBrush(dark_theme ? QColor(90, 12, 12) : QColor(247, 228, 215));
default:
return QBrush(QColor(255, 255, 255, 255));
return QBrush(dark_theme ? QColor(32, 32, 32) : QColor(255, 255, 255));
}
}

Expand Down
5 changes: 3 additions & 2 deletions Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h
Expand Up @@ -37,6 +37,8 @@ class SkylanderPortalWindow : public QWidget
explicit SkylanderPortalWindow(QWidget* parent = nullptr);
~SkylanderPortalWindow() override;

void RefreshList();

protected:
std::array<QLineEdit*, MAX_SKYLANDERS> m_edit_skylanders;
std::array<std::optional<Skylander>, MAX_SKYLANDERS> m_sky_slots;
Expand All @@ -60,7 +62,6 @@ class SkylanderPortalWindow : public QWidget
// Behind the scenes
void OnEmulationStateChanged(Core::State state);
void OnCollectionPathChanged();
void RefreshList();
void UpdateCurrentIDs();
void CreateSkyfile(const QString& path, bool load_after);
void LoadSkyfilePath(u8 slot, const QString& path);
Expand All @@ -71,7 +72,7 @@ class SkylanderPortalWindow : public QWidget
QString GetFilePath(u16 id, u16 var);
u8 GetCurrentSlot();
int GetElementRadio();
QBrush GetBaseColor(std::pair<const u16, const u16> ids);
QBrush GetBaseColor(std::pair<const u16, const u16> ids, bool dark_theme);
int GetGameID(IOS::HLE::USB::Game game);
int GetElementID(IOS::HLE::USB::Element elem);

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/checkbox-checked.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/checkbox-empty-disabled.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/checkbox-empty.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/checkbox-half-disabled.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/checkbox-half.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/dark.qrc
@@ -0,0 +1,30 @@
<RCC>
<qresource prefix="/dolphin_dark_win">
<file>dark.qss</file>
<file>checkbox-checked.svg</file>
<file>checkbox-checked-disabled.svg</file>
<file>checkbox-empty.svg</file>
<file>checkbox-empty-disabled.svg</file>
<file>checkbox-half.svg</file>
<file>checkbox-half-disabled.svg</file>
<file>dockwidget-close.svg</file>
<file>dockwidget-undock.svg</file>
<file>down-triangle.svg</file>
<file>down-triangle-spinbox.svg</file>
<file>dropdown-arrow.svg</file>
<file>left-triangle-tabbar.svg</file>
<file>radiobutton-checked.svg</file>
<file>radiobutton-checked-disabled.svg</file>
<file>radiobutton-empty.svg</file>
<file>radiobutton-empty-disabled.svg</file>
<file>right-triangle-tabbar.svg</file>
<file>scrollbar-arrow-down.svg</file>
<file>scrollbar-arrow-left.svg</file>
<file>scrollbar-arrow-right.svg</file>
<file>scrollbar-arrow-up.svg</file>
<file>table-header-sort-arrow-down.svg</file>
<file>table-header-sort-arrow-up.svg</file>
<file>up-triangle.svg</file>
<file>up-triangle-spinbox.svg</file>
</qresource>
</RCC>
487 changes: 487 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/dark.qss

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/dockwidget-close.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/dockwidget-undock.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/down-triangle-spinbox.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/down-triangle.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/dropdown-arrow.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/left-triangle-tabbar.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/radiobutton-checked.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/radiobutton-empty.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/right-triangle-tabbar.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-down.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-left.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-right.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-up.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/up-triangle-spinbox.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Styles/Dark/up-triangle.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp
Expand Up @@ -28,6 +28,7 @@

#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"
Expand Down Expand Up @@ -395,15 +396,21 @@ void WiiTASInputWindow::UpdateExt()
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();
}
Expand All @@ -412,14 +419,18 @@ void WiiTASInputWindow::UpdateExt()
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
Expand All @@ -429,10 +440,12 @@ void WiiTASInputWindow::UpdateExt()
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();
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/Updater.cpp
Expand Up @@ -17,6 +17,7 @@
#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
Expand Down Expand Up @@ -100,6 +101,7 @@ 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();
});

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/DolphinQt/WiiUpdate.cpp
Expand Up @@ -21,6 +21,7 @@

#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"

namespace WiiUpdate
{
Expand Down Expand Up @@ -130,6 +131,7 @@ static WiiUtils::UpdateResult ShowProgress(QWidget* parent, Callable function, A
return res;
});

SetQWidgetWindowDecorations(&dialog);
dialog.exec();
return result.get();
}
Expand Down
2 changes: 2 additions & 0 deletions Source/VSProps/Base.Dolphin.props
Expand Up @@ -79,6 +79,8 @@
<AdditionalDependencies>avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<!--libcurl needs Crypt32.lib-->
<AdditionalDependencies>Crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<!--Needed to set window decorations for dark theme-->
<AdditionalDependencies>dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<!--See Common/CompatPatches.cpp-->
<ForceSymbolReferences>enableCompatPatches</ForceSymbolReferences>
</Link>
Expand Down
37 changes: 34 additions & 3 deletions Source/VSProps/QtCompile.props
Expand Up @@ -51,9 +51,14 @@
but not the include paths, as passing include paths drastically slows down
moc, and it doesn't appear to actually need them anyway.
-->
<Import Project="qtmoc.props" />
<Import Project="qt_globals.targets"/>
<Import Project="qt_tasks.targets"/>
<ItemDefinitionGroup>
<!--From qtmoc.props-->
<QtMoc>
<ExecutionDescription>moc %(Identity)</ExecutionDescription>
<QTDIR>$(QtHostToolsDir)</QTDIR>
<InputFile>%(FullPath)</InputFile>
<!--
moc task does not properly detect outputs are outdated if Qt version changes
(possibly causing Q_MOC_OUTPUT_REVISION to change). This *might* be because we
Expand All @@ -62,15 +67,41 @@
to avoid conflicts. (the numeric postfix is the value of Q_MOC_OUTPUT_REVISION)
-->
<OutputFile>$(QtToolOutDir)moc_68\moc_%(Filename).cpp</OutputFile>
<QtMocDir>$(QtToolOutDir)moc_68\</QtMocDir>
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
<DynamicSource>output</DynamicSource>
<ParallelProcess>true</ParallelProcess>
<CommandLineTemplate>[AllOptions] [AdditionalOptions]</CommandLineTemplate>
<Outputs>%(OutputFile)</Outputs>
<OverrideClCompile>false</OverrideClCompile>
</QtMoc>
</ItemDefinitionGroup>
<Import Project="qt_globals.targets"/>
<Import Project="qt_tasks.targets"/>
<Import Project="qtmoc.targets" />
<Target Name="QtCheckQtDir" BeforeTargets="QtMocInit" Condition="!$(QtDirValid)">
<Error Text="QTDIR not set or non-existent (pull the submodule?)" />
</Target>

<!--Similar story with rcc-->
<ItemDefinitionGroup>
<!--From qtrcc.props-->
<QtRcc>
<ExecutionDescription>rcc %(Identity)</ExecutionDescription>
<QTDIR>$(QtHostToolsDir)</QTDIR>
<InputFile>%(FullPath)</InputFile>
<OutputFile>$(QtToolOutDir)rcc\qrc_%(Filename).cpp</OutputFile>
<QtRccDir>$(QtToolOutDir)rcc\</QtRccDir>
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
<InitFuncName>%(Filename)</InitFuncName>
<Compression>default</Compression>
<TwoPass>false</TwoPass>
<DynamicSource>output</DynamicSource>
<ParallelProcess>true</ParallelProcess>
<CommandLineTemplate>[AllOptions] [AdditionalOptions]</CommandLineTemplate>
<Outputs>%(OutputFile)</Outputs>
</QtRcc>
</ItemDefinitionGroup>
<Import Project="qtrcc.targets" />

<!--Expose the new targets to VS-->
<ItemGroup>
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />
Expand Down
83 changes: 0 additions & 83 deletions Source/VSProps/qtmoc.props

This file was deleted.

File renamed without changes.
580 changes: 580 additions & 0 deletions Source/VSProps/qtrcc.targets

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Source/VSProps/qtrcc.xml
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">
<ItemType Name="QtRcc" DisplayName="Qt Resource File" />
<ContentType Name="QtRcc" DisplayName="Qt Resource Compiler" />
</ProjectSchemaDefinitions>