Fix bug, fix more warnings (See commit description)
This ends my series of patches fixing warnings throughout the codebase. Now, there are NO warnings except for unused parameters, tested on GCC 13.1.1 and Clang 16.0.2 with -Wall -Wextra. Fixed dark mode crashing on Windows 8.1, 8 and 7, and removed a need for an export by moving in the function. Any people looking at the Windows code and asking why I didn't use official version querying API's, those typically have some sort of unwanted behavior, plus checking exports to determine versions is shorter.
This commit is contained in:
parent
549cfa8833
commit
eabd225b06
@ -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)
|
||||
|
@ -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<File *,QByteArray *>();
|
||||
@ -73,7 +72,6 @@ void Flame::FileResolvingTask::netJobFinished()
|
||||
blockedProjects.insert(&out, output);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
connect(job, &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -259,7 +259,6 @@ void readIndex(const QString & path, QMap<QString, Language>& languages)
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 1;
|
||||
try
|
||||
{
|
||||
auto toplevel_doc = Json::requireDocument(data);
|
||||
@ -292,7 +291,6 @@ void readIndex(const QString & path, QMap<QString, Language>& languages)
|
||||
lang.file_size = Json::requireInteger(langObj, "size");
|
||||
|
||||
languages.insert(lang.key, lang);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
catch (Json::JsonException & e)
|
||||
|
@ -4,28 +4,90 @@
|
||||
|
||||
namespace WinDarkmode {
|
||||
|
||||
/* See https://github.com/statiolake/neovim-qt/commit/da8eaba7f0e38b6b51f3bacd02a8cc2d1f7a34d8 */
|
||||
void setDarkWinTitlebar(WId winid, bool darkmode)
|
||||
template<int syscall_id, typename... arglist> __attribute((naked)) uint32_t __fastcall WinSyscall([[maybe_unused]] arglist... args)
|
||||
{
|
||||
HWND hwnd = reinterpret_cast<HWND>(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<NtUserSetWindowCompositionAttribute_NT6_2>(hWnd, &data);
|
||||
else if (IsWindows8_1_Only())
|
||||
WinSyscall<NtUserSetWindowCompositionAttribute_NT6_3>(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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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("<a href='%1'>%2</a>").arg(article_entry->link, new_title));
|
||||
ui->currentArticleContentBrowser->setText(article_entry->content);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user