view src/sys/win32/dark_theme.cc @ 118:39521c47c7a3

*: another huge megacommit, SORRY The torrents page works a lot better now Added the edit option to the anime list right click menu Vectorized currently playing files Available player and extensions are now loaded at runtime from files in (dotpath)/players.json and (dotpath)/extensions.json These paths are not permanent and will likely be moved to (dotpath)/recognition ... ... ...
author Paper <mrpapersonic@gmail.com>
date Tue, 07 Nov 2023 23:40:54 -0500
parents c8c72278f6fd
children bc8d2ccff09c
line wrap: on
line source

#include "sys/win32/dark_theme.h"
#include <QApplication>
#include <QDebug>
#include <QOperatingSystemVersion>
#include <QSettings>
#include <QWidget>
#include <iostream>
#include <dwmapi.h>

/* let's make a class wrapper around HINSTANCE, 
   so we don't fuck anything up :). */
class Library {
	public:
		Library() {}
		~Library() {
			Unload();
		}
		void Unload() {
			if (hInstance) {
				FreeLibrary(hInstance);
				hInstance = nullptr;
			}
			loaded = false;
		}
		void Load(LPCWSTR name) {
			if (loaded)
				Unload();
			hInstance = LoadLibraryW(name);
			if (hInstance)
				loaded = true;
		}
		HINSTANCE GetInstance() {
			return hInstance;
		}
		bool IsLoaded() {
			return loaded;
		}
	private:
		HINSTANCE hInstance = nullptr;
		bool loaded = false;
};

Library dwmapi;

namespace win32 {

#define GET_FUNCTION(f, i) \
	reinterpret_cast<decltype(::f)*>(GetProcAddress(i, #f))

static HRESULT SetWindowAttribute(HWND hWnd, DWORD key, LPCVOID data, DWORD sz_data) {
	if (!dwmapi.IsLoaded()) {
		dwmapi.Load(L"dwmapi.dll");
		if (!dwmapi.IsLoaded())
			return false;
	}

	HINSTANCE hInstance = dwmapi.GetInstance();
	if (!hInstance)
		return false;

	auto set_wind_attrib = GET_FUNCTION(DwmSetWindowAttribute, hInstance);
	if (!set_wind_attrib)
		return false;

	return set_wind_attrib(hWnd, key, data, sz_data);
}

bool SetTitleBarToBlack(QWidget* win, bool enabled) {
	BOOL b = enabled;

	/* MAGIC NUMBERS: 19 and 20 are both DWMWA_USE_IMMERSIVE_DARK_MODE.
	   clarification: it's 20 on newer versions of windows (i.e. win11 and late win10),
	   but it's 19 on very old versions of win10 nobody ought to be using. */
	{
		HRESULT result = SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), 20, &b, sizeof(b));
		if (result == S_OK)
			return b;
	}

	{
		HRESULT result = SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), 19, &b, sizeof(b));
		if (result == S_OK)
			return b;
	}

	return b;
}

void SetTitleBarsToBlack(bool enabled) {
	for (QWidget* widget : qApp->topLevelWidgets()) {
		SetTitleBarToBlack(widget, enabled);
	}
}

bool DarkThemeAvailable() {
	const auto& ver = QOperatingSystemVersion::current();
	return (ver.majorVersion() > 10) ? true : (ver.majorVersion() == 10 && ver.microVersion() >= 17763);
}

bool IsInDarkTheme() {
	QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
	                   QSettings::NativeFormat);
	return settings.value("AppsUseLightTheme", 1).toInt() == 0;
}

} // namespace win32