diff --git a/launcher/Application.cpp b/launcher/Application.cpp index eb022aa9..86ef3400 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1168,9 +1168,9 @@ void Application::setApplicationTheme(const QString& name, bool initial) #ifdef Q_OS_WIN if (m_mainWindow) { if (QString::compare(theme->id(), "dark") == 0) { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); + WinDarkmode::setWindowDarkModeEnabled((HWND)m_mainWindow->winId(), true); } else { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + WinDarkmode::setWindowDarkModeEnabled((HWND)m_mainWindow->winId(), false); } } #endif @@ -1408,9 +1408,9 @@ MainWindow* Application::showMainWindow(bool minimized) m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray())); #ifdef Q_OS_WIN if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); + WinDarkmode::setWindowDarkModeEnabled((HWND)m_mainWindow->winId(), true); } else { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + WinDarkmode::setWindowDarkModeEnabled((HWND)m_mainWindow->winId(), false); } #endif if(minimized) diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 74bf126b..036f02ad 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -37,7 +37,6 @@ void Flame::FileResolvingTask::executeTask() void Flame::FileResolvingTask::netJobFinished() { setProgress(1, 3); - int index = 0; // job to check modrinth for blocked projects auto job = new NetJob("Modrinth check", m_network); blockedProjects = QMap(); @@ -73,7 +72,6 @@ void Flame::FileResolvingTask::netJobFinished() blockedProjects.insert(&out, output); } } - index++; } connect(job, &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished); diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp index 8dd3a846..a92ec37a 100644 --- a/launcher/modplatform/flame/FlameCheckUpdate.cpp +++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp @@ -158,7 +158,7 @@ void FlameCheckUpdate::executeTask() pack.addonId = mod->metadata()->project_id; pack.websiteUrl = mod->homeurl(); for (auto& author : mod->authors()) - pack.authors.append({ author }); + pack.authors.append({ author, "" }); pack.description = mod->description(); pack.provider = ModPlatform::Provider::FLAME; diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 97ce1dc6..3e4cc30c 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -135,8 +135,6 @@ void PackInstallTask::resolveMods() m_file_id_map.clear(); Flame::Manifest manifest; - int index = 0; - for (auto const& file : m_version.files) { if (!file.serverOnly && file.url.isEmpty()) { if (file.curseforge.file_id <= 0) { @@ -154,8 +152,6 @@ void PackInstallTask::resolveMods() } else { m_file_id_map.append(-1); } - - index++; } m_mod_id_resolver_task = new Flame::FileResolvingTask(APPLICATION->network(), manifest); diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index e2d27547..856f12ac 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -150,7 +150,7 @@ void ModrinthCheckUpdate::executeTask() pack.addonId = mod->metadata()->project_id; pack.websiteUrl = mod->homeurl(); for (auto& author : mod->authors()) - pack.authors.append({ author }); + pack.authors.append({ author, "" }); pack.description = mod->description(); pack.provider = ModPlatform::Provider::MODRINTH; diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp index b7f9defd..64020dca 100644 --- a/launcher/translations/TranslationsModel.cpp +++ b/launcher/translations/TranslationsModel.cpp @@ -259,7 +259,6 @@ void readIndex(const QString & path, QMap& languages) return; } - int index = 1; try { auto toplevel_doc = Json::requireDocument(data); @@ -292,7 +291,6 @@ void readIndex(const QString & path, QMap& languages) lang.file_size = Json::requireInteger(langObj, "size"); languages.insert(lang.key, lang); - index++; } } catch (Json::JsonException & e) diff --git a/launcher/ui/WinDarkmode.cpp b/launcher/ui/WinDarkmode.cpp index 8f5553d9..fad01eff 100644 --- a/launcher/ui/WinDarkmode.cpp +++ b/launcher/ui/WinDarkmode.cpp @@ -4,28 +4,90 @@ namespace WinDarkmode { -/* See https://github.com/statiolake/neovim-qt/commit/da8eaba7f0e38b6b51f3bacd02a8cc2d1f7a34d8 */ -void setDarkWinTitlebar(WId winid, bool darkmode) +template __attribute((naked)) uint32_t __fastcall WinSyscall([[maybe_unused]] arglist... args) { - HWND hwnd = reinterpret_cast(winid); - BOOL dark = (BOOL)darkmode; + asm volatile("mov %%rcx, %%r10; movl %0, %%eax; syscall; ret" + :: "i"(syscall_id)); +} - HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); - HMODULE hUser32 = GetModuleHandleW(L"user32.dll"); +VOID ApplyStringProp(HWND hWnd, LPCWSTR lpString, WORD Property) +{ + WORD Prop = (uint16_t)(uint64_t)GetPropW(hWnd, (LPCWSTR)(uint64_t)Property); + if (Prop) + { + DeleteAtom(Prop); + RemovePropW(hWnd, (LPCWSTR)(uint64_t)Property); + } + if (lpString) + { + ATOM v = AddAtomW(lpString); + if (v) + SetPropW(hWnd, (LPCWSTR)(uint64_t)Property, (HANDLE)(uint64_t)v); + } +} - // For those confused how this works, dlls have export numbers but some can have no name and these have no name. So an address is gotten by export number. If this ever changes, it will break. - fnAllowDarkModeForWindow AllowDarkModeForWindow = (fnAllowDarkModeForWindow)(PVOID)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133)); - fnSetPreferredAppMode SetPreferredAppMode = (fnSetPreferredAppMode)(PVOID)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135)); - fnSetWindowCompositionAttribute SetWindowCompositionAttribute = (fnSetWindowCompositionAttribute)(PVOID)GetProcAddress(hUser32, "SetWindowCompositionAttribute"); +VOID AllowDarkModeForWindow(HWND hWnd, BOOL Enable) +{ + if (hWnd) + { + ApplyStringProp(hWnd, Enable ? L"Enabled" : NULL, 0xA91E); + } + return; +} - SetPreferredAppMode(AllowDark); - AllowDarkModeForWindow(hwnd, dark); +BOOL IsWindows11() +{ + HMODULE hKern32 = GetModuleHandleW(L"kernel32.dll"); + return GetProcAddress(hKern32, "Wow64SetThreadDefaultGuestMachine") != NULL; // Win11 21h2+ +} + +BOOL IsWindows10_Only() +{ + HMODULE hKern32 = GetModuleHandleW(L"kernel32.dll"); + HMODULE hNtuser = GetModuleHandleW(L"ntdll.dll"); + return GetProcAddress(hKern32, "SetThreadSelectedCpuSets") != NULL + && GetProcAddress(hNtuser, "ZwSetInformationCpuPartition") == NULL; +} + +BOOL IsWindows8_0_Only() +{ + HMODULE hKern32 = GetModuleHandleW(L"kernel32.dll"); + return GetProcAddress(hKern32, "CreateFile2") != NULL // Export added in 6.2 (8) + && GetProcAddress(hKern32, "AppXFreeMemory") != NULL; // Export added in 6.2 (8), removed in 6.3 (8.1) +} + +BOOL IsWindows8_1_Only() +{ + HMODULE hKern32 = GetModuleHandleW(L"kernel32.dll"); + return GetProcAddress(hKern32, "CalloutOnFiberStack") != NULL // Export added in 6.3 (8.1), Removed in 10.0.10586 + && GetProcAddress(hKern32, "SetThreadSelectedCpuSets") == NULL; // Export added in 10.0 (10) +} + +void setWindowDarkModeEnabled(HWND hWnd, bool Enabled) +{ + AllowDarkModeForWindow(hWnd, Enabled); + BOOL DarkEnabled = (BOOL)Enabled; WINDOWCOMPOSITIONATTRIBDATA data = { WCA_USEDARKMODECOLORS, - &dark, - sizeof(dark) + &DarkEnabled, + sizeof(DarkEnabled) }; - SetWindowCompositionAttribute(hwnd, &data); + + constexpr int NtUserSetWindowCompositionAttribute_NT6_2 = 0x13b4; + constexpr int NtUserSetWindowCompositionAttribute_NT6_3 = 0x13e5; + if (IsWindows8_0_Only()) + WinSyscall(hWnd, &data); + else if (IsWindows8_1_Only()) + WinSyscall(hWnd, &data); + else if (IsWindows10_Only() || IsWindows11()) + { + ((fnSetWindowCompositionAttribute)(PVOID)GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetWindowCompositionAttribute")) + (hWnd, &data); + // Verified this ordinal is the same through Win11 22H2 (5/8/2023) + ((fnSetPreferredAppMode)(PVOID)GetProcAddress(GetModuleHandleW(L"uxtheme.dll"), MAKEINTRESOURCEA(135))) + (AppMode_AllowDark); + } + } } diff --git a/launcher/ui/WinDarkmode.h b/launcher/ui/WinDarkmode.h index 5b567c6b..e697ddbc 100644 --- a/launcher/ui/WinDarkmode.h +++ b/launcher/ui/WinDarkmode.h @@ -6,14 +6,14 @@ namespace WinDarkmode { -void setDarkWinTitlebar(WId winid, bool darkmode); +void setWindowDarkModeEnabled(HWND hWnd, bool Enabled); enum PreferredAppMode { - Default, - AllowDark, - ForceDark, - ForceLight, - Max + AppMode_Default, + AppMode_AllowDark, + AppMode_ForceDark, + AppMode_ForceLight, + AppMode_Max }; enum WINDOWCOMPOSITIONATTRIB { diff --git a/launcher/ui/dialogs/NewsDialog.cpp b/launcher/ui/dialogs/NewsDialog.cpp index d3b21627..91d32312 100644 --- a/launcher/ui/dialogs/NewsDialog.cpp +++ b/launcher/ui/dialogs/NewsDialog.cpp @@ -30,7 +30,8 @@ NewsDialog::~NewsDialog() void NewsDialog::selectedArticleChanged(const QString& new_title) { - auto const& article_entry = m_entries.constFind(new_title).value(); + auto const& article_entry_ptr = m_entries.constFind(new_title); + auto const& article_entry = article_entry_ptr.value(); ui->articleTitleLabel->setText(QString("%2").arg(article_entry->link, new_title)); ui->currentArticleContentBrowser->setText(article_entry->content); diff --git a/launcher/ui/instanceview/AccessibleInstanceView.cpp b/launcher/ui/instanceview/AccessibleInstanceView.cpp index 7de3ac72..b3d37c56 100644 --- a/launcher/ui/instanceview/AccessibleInstanceView.cpp +++ b/launcher/ui/instanceview/AccessibleInstanceView.cpp @@ -218,11 +218,11 @@ bool AccessibleInstanceView::selectRow(int row) if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) { view()->clearSelection(); } - break; - } - default: { break; } + default: + qWarning() << "Unhandled QAbstractItemView selection type!"; + break; } view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); @@ -248,7 +248,7 @@ bool AccessibleInstanceView::selectColumn(int column) if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1) { return false; } - // fallthrough intentional + [[fallthrough]]; } case QAbstractItemView::ContiguousSelection: { if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { @@ -279,7 +279,7 @@ bool AccessibleInstanceView::unselectRow(int row) QItemSelection selection(index, index); auto selectionModel = view()->selectionModel(); - switch (view()->selectionMode()) { + switch (const auto selectionType = view()->selectionMode()) { case QAbstractItemView::SingleSelection: // no unselect if (selectedRowCount() == 1) { @@ -298,8 +298,13 @@ bool AccessibleInstanceView::unselectRow(int row) //the ones which are down the current row will be deselected selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex())); } + break; } + case QAbstractItemView::NoSelection: + break; default: { + // FIXME: See if MultiSelection / ExtendedSelection need to be handled + qWarning() << "Unhandled QAbstractItemView selection type!" << selectionType; break; } } @@ -342,6 +347,7 @@ bool AccessibleInstanceView::unselectColumn(int column) //of the current row, the ones which are at the right will be deselected selection = QItemSelection(index, model->index(0, columnCount() - 1, view()->rootIndex())); } + break; default: break; } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index fd7a3537..7d546ea8 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -178,10 +178,9 @@ void ModpackListModel::refresh() performPaginatedSearch(); } -static auto sortFromIndex(int index) -> QString +static QString sortFromIndex(int index, bool& unhandled) { switch(index){ - default: case 0: return "relevance"; case 1: @@ -192,6 +191,10 @@ static auto sortFromIndex(int index) -> QString return "newest"; case 4: return "updated"; + default: + unhandled = true; + qWarning() << QString("Unhandled case in sortFromIndex (%i)").arg(QString::number(index)); + break; } return {}; @@ -199,11 +202,11 @@ static auto sortFromIndex(int index) -> QString void ModpackListModel::searchWithTerm(const QString& term, const int sort) { - if(sort > 5 || sort < 0) + bool unhandled = false; + auto sort_str = sortFromIndex(sort, unhandled); + if (unhandled) return; - auto sort_str = sortFromIndex(sort); - if (currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull() && currentSort == sort_str) { return; } @@ -311,6 +314,8 @@ void ModpackListModel::searchRequestFinished(QJsonDocument& doc_all) void ModpackListModel::searchRequestFailed(QString reason) { + qWarning() << QString("searchRequestFailed reason: %1").arg(reason); + auto failed_action = jobPtr->getFailedActions().at(0); if (!failed_action->m_reply) { // Network error diff --git a/libraries/murmur2/src/MurmurHash2.cpp b/libraries/murmur2/src/MurmurHash2.cpp index b625efb1..0d62837e 100644 --- a/libraries/murmur2/src/MurmurHash2.cpp +++ b/libraries/murmur2/src/MurmurHash2.cpp @@ -89,8 +89,10 @@ void FourBytes_MurmurHash2(const unsigned char* data, IncrementalHashInfo& prev) switch (prev.len) { case 3: prev.h ^= data[2] << 16; + [[fallthrough]]; case 2: prev.h ^= data[1] << 8; + [[fallthrough]]; case 1: prev.h ^= data[0]; prev.h *= m;