sysapiloader: minor improvements

And some other minor refactors.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2023-02-16 14:55:26 +08:00
parent 7fb9b312b1
commit 02f70d1ade
8 changed files with 178 additions and 98 deletions

View File

@ -44,7 +44,7 @@ option(FRAMELESSHELPER_NO_PERMISSIVE_CHECKS "MSVC only: disable the additional p
option(FRAMELESSHELPER_NO_INSTALL "Don't install any files." OFF)
option(FRAMELESSHELPER_NO_SUMMARY "Don't show CMake configure summary." OFF)
option(FRAMELESSHELPER_ENABLE_SPECTRE "Mitigate Spectre security vulnerabilities." OFF)
option(FRAMELESSHELPER_ENABLE_EHCONTGUARD "Enable EH Continuation (EHCONT) Metadata." OFF)
option(FRAMELESSHELPER_ENABLE_EHCONTGUARD "MSVC only: Enable EH Continuation (EHCONT) Metadata." OFF)
option(FRAMELESSHELPER_ENABLE_INTELCET "Enable Intel CET." ON)
option(FRAMELESSHELPER_ENABLE_INTELJCC "Enable Intel JCC." ON)
option(FRAMELESSHELPER_ENABLE_CFGUARD "Enable Control Flow Guard (CFG)." ON)
@ -176,7 +176,7 @@ if(NOT FRAMELESSHELPER_NO_SUMMARY)
message("[MSVC] Disable permissive checks: ${FRAMELESSHELPER_NO_PERMISSIVE_CHECKS}")
message("Do not install anything for CMake install: ${FRAMELESSHELPER_NO_INSTALL}")
message("Mitigate Spectre security vulnerabilities: ${FRAMELESSHELPER_ENABLE_SPECTRE}")
message("Enable EH Continuation (EHCONT) Metadata: ${FRAMELESSHELPER_ENABLE_EHCONTGUARD}")
message("[MSVC] Enable EH Continuation (EHCONT) Metadata: ${FRAMELESSHELPER_ENABLE_EHCONTGUARD}")
message("Enable Intel CET: ${FRAMELESSHELPER_ENABLE_INTELCET}")
message("Enable Intel JCC: ${FRAMELESSHELPER_ENABLE_INTELJCC}")
message("Enable Control Flow Guard (CFG): ${FRAMELESSHELPER_ENABLE_CFGUARD}")

View File

@ -39,18 +39,21 @@ public:
Q_NODISCARD static SysApiLoader *instance();
Q_NODISCARD static QString platformSharedLibrarySuffixName();
Q_NODISCARD static QString generateUniqueKey(const QString &library, const QString &function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const char *function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QByteArray &function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QString &function);
Q_NODISCARD bool isAvailable(const QString &library, const QString &function);
Q_NODISCARD QFunctionPointer get(const QString &function);
Q_NODISCARD QFunctionPointer get(const QString &library, const QString &function);
template<typename T>
Q_NODISCARD T get(const QString &function)
Q_NODISCARD T get(const QString &library, const QString &function)
{
return reinterpret_cast<T>(get(function));
return reinterpret_cast<T>(get(library, function));
}
};
@ -59,18 +62,18 @@ FRAMELESSHELPER_END_NAMESPACE
#define API_AVAILABLE(lib, func) \
(FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->isAvailable(k##lib, k##func))
#define API_CALL_FUNCTION(func, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION(lib, func, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##lib, k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION2(func, type, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<type>(k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION2(lib, func, type, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<type>(k##lib, k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION3(func, name, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##name))(__VA_ARGS__))
#define API_CALL_FUNCTION3(lib, func, name, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##lib, k##name))(__VA_ARGS__))
#define API_CALL_FUNCTION4(func, ...) API_CALL_FUNCTION3(_##func, func, __VA_ARGS__)
#define API_CALL_FUNCTION4(lib, func, ...) API_CALL_FUNCTION3(lib, _##func, func, __VA_ARGS__)
#define API_CALL_FUNCTION5(func, ...) API_CALL_FUNCTION3(func##2, func, __VA_ARGS__)
#define API_CALL_FUNCTION5(lib, func, ...) API_CALL_FUNCTION3(lib, func##2, func, __VA_ARGS__)
#ifdef Q_OS_WINDOWS
# define API_USER_AVAILABLE(func) API_AVAILABLE(user32, func)

View File

@ -355,7 +355,12 @@ void FramelessManagerPrivate::initialize()
QStyleHints * const styleHints = QGuiApplication::styleHints();
Q_ASSERT(styleHints);
if (styleHints) {
connect(styleHints, &QStyleHints::colorSchemeChanged, this, [this](const Qt::ColorScheme colorScheme){
#if 0 // Unreleased 6.5 change.
connect(styleHints, &QStyleHints::colorSchemeChanged, this, [this](const Qt::ColorScheme colorScheme)
#else
connect(styleHints, &QStyleHints::appearanceChanged, this, [this](const Qt::Appearance colorScheme)
#endif
{
Q_UNUSED(colorScheme);
notifySystemThemeHasChangedOrNot();
});

View File

@ -43,7 +43,7 @@ XInitThreads(
if (!API_XLIB_AVAILABLE(XInitThreads)) {
return 0;
}
return API_CALL_FUNCTION(XInitThreads);
return API_CALL_FUNCTION(libX11, XInitThreads);
}
#endif // FRAMELESSHELPER_HAS_XLIB
@ -85,7 +85,7 @@ xcb_send_event(
if (!API_XCB_AVAILABLE(xcb_send_event)) {
return {};
}
return API_CALL_FUNCTION(xcb_send_event, connection, propagate, destination, event_mask, event);
return API_CALL_FUNCTION(libxcb, xcb_send_event, connection, propagate, destination, event_mask, event);
}
extern "C" int
@ -96,7 +96,7 @@ xcb_flush(
if (!API_XCB_AVAILABLE(xcb_flush)) {
return 0;
}
return API_CALL_FUNCTION(xcb_flush, connection);
return API_CALL_FUNCTION(libxcb, xcb_flush, connection);
}
extern "C" xcb_intern_atom_cookie_t
@ -110,7 +110,7 @@ xcb_intern_atom(
if (!API_XCB_AVAILABLE(xcb_intern_atom)) {
return {};
}
return API_CALL_FUNCTION(xcb_intern_atom, connection, only_if_exists, name_len, name);
return API_CALL_FUNCTION(libxcb, xcb_intern_atom, connection, only_if_exists, name_len, name);
}
extern "C" xcb_intern_atom_reply_t *
@ -123,7 +123,7 @@ xcb_intern_atom_reply(
if (!API_XCB_AVAILABLE(xcb_intern_atom_reply)) {
return nullptr;
}
return API_CALL_FUNCTION(xcb_intern_atom_reply, connection, cookie, error);
return API_CALL_FUNCTION(libxcb, xcb_intern_atom_reply, connection, cookie, error);
}
extern "C" xcb_void_cookie_t
@ -135,7 +135,7 @@ xcb_ungrab_pointer(
if (!API_XCB_AVAILABLE(xcb_ungrab_pointer)) {
return {};
}
return API_CALL_FUNCTION(xcb_ungrab_pointer, connection, time);
return API_CALL_FUNCTION(libxcb, xcb_ungrab_pointer, connection, time);
}
extern "C" xcb_void_cookie_t
@ -153,7 +153,7 @@ xcb_change_property(
if (!API_XCB_AVAILABLE(xcb_change_property)) {
return {};
}
return API_CALL_FUNCTION(xcb_change_property, connection,
return API_CALL_FUNCTION(libxcb, xcb_change_property, connection,
mode, window, property, type, format, data_len, data);
}
@ -167,7 +167,7 @@ xcb_delete_property_checked(
if (!API_XCB_AVAILABLE(xcb_delete_property_checked)) {
return {};
}
return API_CALL_FUNCTION(xcb_delete_property_checked, connection, window, property);
return API_CALL_FUNCTION(libxcb, xcb_delete_property_checked, connection, window, property);
}
extern "C" xcb_get_property_cookie_t
@ -184,7 +184,7 @@ xcb_get_property(
if (!API_XCB_AVAILABLE(xcb_get_property)) {
return {};
}
return API_CALL_FUNCTION(xcb_get_property, connection,
return API_CALL_FUNCTION(libxcb, xcb_get_property, connection,
_delete, window, property, type, long_offset, long_length);
}
@ -198,7 +198,7 @@ xcb_get_property_reply(
if (!API_XCB_AVAILABLE(xcb_get_property_reply)) {
return nullptr;
}
return API_CALL_FUNCTION(xcb_get_property_reply, connection, cookie, error);
return API_CALL_FUNCTION(libxcb, xcb_get_property_reply, connection, cookie, error);
}
extern "C" void *
@ -209,7 +209,7 @@ xcb_get_property_value(
if (!API_XCB_AVAILABLE(xcb_get_property_value)) {
return nullptr;
}
return API_CALL_FUNCTION(xcb_get_property_value, reply);
return API_CALL_FUNCTION(libxcb, xcb_get_property_value, reply);
}
extern "C" int
@ -220,7 +220,7 @@ xcb_get_property_value_length(
if (!API_XCB_AVAILABLE(xcb_get_property_value_length)) {
return 0;
}
return API_CALL_FUNCTION(xcb_get_property_value_length, reply);
return API_CALL_FUNCTION(libxcb, xcb_get_property_value_length, reply);
}
extern "C" xcb_list_properties_cookie_t
@ -232,7 +232,7 @@ xcb_list_properties(
if (!API_XCB_AVAILABLE(xcb_list_properties)) {
return {};
}
return API_CALL_FUNCTION(xcb_list_properties, connection, window);
return API_CALL_FUNCTION(libxcb, xcb_list_properties, connection, window);
}
extern "C" xcb_list_properties_reply_t *
@ -245,7 +245,7 @@ xcb_list_properties_reply(
if (!API_XCB_AVAILABLE(xcb_list_properties_reply)) {
return nullptr;
}
return API_CALL_FUNCTION(xcb_list_properties_reply, connection, cookie, error);
return API_CALL_FUNCTION(libxcb, xcb_list_properties_reply, connection, cookie, error);
}
extern "C" int
@ -256,7 +256,7 @@ xcb_list_properties_atoms_length(
if (!API_XCB_AVAILABLE(xcb_list_properties_atoms_length)) {
return 0;
}
return API_CALL_FUNCTION(xcb_list_properties_atoms_length, atom);
return API_CALL_FUNCTION(libxcb, xcb_list_properties_atoms_length, atom);
}
extern "C" xcb_atom_t *
@ -267,7 +267,7 @@ xcb_list_properties_atoms(
if (!API_XCB_AVAILABLE(xcb_list_properties_atoms)) {
return nullptr;
}
return API_CALL_FUNCTION(xcb_list_properties_atoms, atom);
return API_CALL_FUNCTION(libxcb, xcb_list_properties_atoms, atom);
}
extern "C" xcb_get_property_cookie_t
@ -284,7 +284,7 @@ xcb_get_property_unchecked(
if (!API_XCB_AVAILABLE(xcb_get_property_unchecked)) {
return {};
}
return API_CALL_FUNCTION(xcb_get_property_unchecked, connection,
return API_CALL_FUNCTION(libxcb, xcb_get_property_unchecked, connection,
_delete, window, property, type, long_offset, long_length);
}
@ -339,7 +339,7 @@ gtk_init(
if (!API_GTK_AVAILABLE(gtk_init)) {
return;
}
API_CALL_FUNCTION(gtk_init, argc, argv);
API_CALL_FUNCTION(libgtk, gtk_init, argc, argv);
}
extern "C" GValue *
@ -351,7 +351,7 @@ g_value_init(
if (!API_GTK_AVAILABLE(g_value_init)) {
return nullptr;
}
return API_CALL_FUNCTION(g_value_init, value, g_type);
return API_CALL_FUNCTION(libgtk, g_value_init, value, g_type);
}
extern "C" GValue *
@ -362,7 +362,7 @@ g_value_reset(
if (!API_GTK_AVAILABLE(g_value_reset)) {
return nullptr;
}
return API_CALL_FUNCTION(g_value_reset, value);
return API_CALL_FUNCTION(libgtk, g_value_reset, value);
}
extern "C" void
@ -373,7 +373,7 @@ g_value_unset(
if (!API_GTK_AVAILABLE(g_value_unset)) {
return;
}
API_CALL_FUNCTION(g_value_unset, value);
API_CALL_FUNCTION(libgtk, g_value_unset, value);
}
extern "C" gboolean
@ -384,7 +384,7 @@ g_value_get_boolean(
if (!API_GTK_AVAILABLE(g_value_get_boolean)) {
return false;
}
return API_CALL_FUNCTION(g_value_get_boolean, value);
return API_CALL_FUNCTION(libgtk, g_value_get_boolean, value);
}
extern "C" const gchar *
@ -395,7 +395,7 @@ g_value_get_string(
if (!API_GTK_AVAILABLE(g_value_get_string)) {
return nullptr;
}
return API_CALL_FUNCTION(g_value_get_string, value);
return API_CALL_FUNCTION(libgtk, g_value_get_string, value);
}
extern "C" GtkSettings *
@ -406,7 +406,7 @@ gtk_settings_get_default(
if (!API_GTK_AVAILABLE(gtk_settings_get_default)) {
return nullptr;
}
return API_CALL_FUNCTION(gtk_settings_get_default);
return API_CALL_FUNCTION(libgtk, gtk_settings_get_default);
}
extern "C" void
@ -419,7 +419,7 @@ g_object_get_property(
if (!API_GTK_AVAILABLE(g_object_get_property)) {
return;
}
API_CALL_FUNCTION(g_object_get_property, object, property_name, value);
API_CALL_FUNCTION(libgtk, g_object_get_property, object, property_name, value);
}
extern "C" gulong
@ -435,7 +435,7 @@ g_signal_connect_data(
if (!API_GTK_AVAILABLE(g_signal_connect_data)) {
return 0;
}
return API_CALL_FUNCTION(g_signal_connect_data, instance, detailed_signal, c_handler, data, destroy_data, connect_flags);
return API_CALL_FUNCTION(libgtk, g_signal_connect_data, instance, detailed_signal, c_handler, data, destroy_data, connect_flags);
}
extern "C" void
@ -446,7 +446,7 @@ g_free(
if (!API_GTK_AVAILABLE(g_free)) {
return;
}
API_CALL_FUNCTION(g_free, mem);
API_CALL_FUNCTION(libgtk, g_free, mem);
}
extern "C" void
@ -457,7 +457,7 @@ g_object_unref(
if (!API_GTK_AVAILABLE(g_object_unref)) {
return;
}
API_CALL_FUNCTION(g_object_unref, object);
API_CALL_FUNCTION(libgtk, g_object_unref, object);
}
extern "C" void
@ -468,7 +468,7 @@ g_clear_object(
if (!API_GTK_AVAILABLE(g_clear_object)) {
return;
}
API_CALL_FUNCTION(g_clear_object, object_ptr);
API_CALL_FUNCTION(libgtk, g_clear_object, object_ptr);
}
GTKSETTINGS_IMPL(bool, const bool result = g_value_get_boolean(&value);)

View File

@ -55,7 +55,7 @@ _GetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvD
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return API_CALL_FUNCTION4(GetWindowCompositionAttribute, hWnd, pvData);
return API_CALL_FUNCTION4(user32, GetWindowCompositionAttribute, hWnd, pvData);
}
EXTERN_C BOOL WINAPI
@ -71,7 +71,7 @@ _SetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvD
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
return API_CALL_FUNCTION4(SetWindowCompositionAttribute, hWnd, pvData);
return API_CALL_FUNCTION4(user32, SetWindowCompositionAttribute, hWnd, pvData);
}
EXTERN_C HRESULT WINAPI
@ -88,7 +88,7 @@ _SetWindowThemeAttribute(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib
if (!API_THEME_AVAILABLE(SetWindowThemeAttribute)) {
return E_NOTIMPL;
}
return API_CALL_FUNCTION4(SetWindowThemeAttribute, hWnd, attrib, pvData, cbData);
return API_CALL_FUNCTION4(uxtheme, SetWindowThemeAttribute, hWnd, attrib, pvData, cbData);
}
EXTERN_C HRESULT WINAPI

View File

@ -73,13 +73,15 @@ static Q_LOGGING_CATEGORY(lcSysApiLoader, "wangwenx190.framelesshelper.core.sysa
struct SysApiLoaderData
{
QMutex mutex;
QHash<QString, std::optional<QFunctionPointer>> functionCache = {};
QHash<QString, QFunctionPointer> functionCache = {};
};
Q_GLOBAL_STATIC(SysApiLoaderData, g_loaderData)
Q_GLOBAL_STATIC(SysApiLoader, g_sysApiLoader)
static const bool LoaderDebug = qEnvironmentVariableIntValue("FRAMELESSHELPER_SYSAPILOADER_DEBUG");
SysApiLoader::SysApiLoader(QObject *parent) : QObject(parent)
{
}
@ -91,6 +93,55 @@ SysApiLoader *SysApiLoader::instance()
return g_sysApiLoader();
}
QString SysApiLoader::platformSharedLibrarySuffixName()
{
static const auto result = []() -> QString {
#ifdef Q_OS_WINDOWS
return FRAMELESSHELPER_STRING_LITERAL(".dll");
#elif defined(Q_OS_LINUX)
return FRAMELESSHELPER_STRING_LITERAL(".so");
#elif defined(Q_OS_MACOS)
return FRAMELESSHELPER_STRING_LITERAL(".dylib");
#else
#error Unsupported platform!
#endif
}();
return result;
}
QString SysApiLoader::generateUniqueKey(const QString &library, const QString &function)
{
Q_ASSERT(!library.isEmpty());
Q_ASSERT(!function.isEmpty());
if (library.isEmpty() || function.isEmpty()) {
return {};
}
QString key = library;
// Remove path, only keep the file name.
const auto lastSeparatorPos = [&key]() -> qsizetype {
if (const qsizetype pos1 = key.lastIndexOf(u'/'); pos1 >= 0) {
return pos1;
} else if (const qsizetype pos2 = key.lastIndexOf(u'\\'); pos2 >= 0) {
return pos2;
} else {
return -1;
}
}();
if (lastSeparatorPos >= 0) {
key.remove(0, lastSeparatorPos);
}
#ifdef Q_OS_WINDOWS
key = key.toLower();
#endif // Q_OS_WINDOWS
static const QString suffix = platformSharedLibrarySuffixName();
if (!key.endsWith(suffix)) {
key.append(suffix);
}
key.append(u':');
key.append(function);
return key;
}
QFunctionPointer SysApiLoader::resolve(const QString &library, const char *function)
{
Q_ASSERT(!library.isEmpty());
@ -133,32 +184,49 @@ bool SysApiLoader::isAvailable(const QString &library, const QString &function)
if (library.isEmpty() || function.isEmpty()) {
return false;
}
const QString key = generateUniqueKey(library, function);
const QMutexLocker locker(&g_loaderData()->mutex);
if (g_loaderData()->functionCache.contains(function)) {
return g_loaderData()->functionCache.value(function).has_value();
if (g_loaderData()->functionCache.contains(key)) {
if (LoaderDebug) {
DEBUG << "Function cache found:" << key;
}
return (g_loaderData()->functionCache.value(key) != nullptr);
} else {
const QFunctionPointer symbol = SysApiLoader::resolve(library, function);
g_loaderData()->functionCache.insert(key, symbol);
if (LoaderDebug) {
DEBUG << "New function cache:" << key << (symbol ? "[VALID]" : "[NULL]");
}
if (symbol) {
g_loaderData()->functionCache.insert(function, symbol);
DEBUG << "Successfully loaded" << function << "from" << library;
return true;
}
g_loaderData()->functionCache.insert(function, std::nullopt);
} else {
WARNING << "Failed to load" << function << "from" << library;
return false;
}
}
}
QFunctionPointer SysApiLoader::get(const QString &function)
QFunctionPointer SysApiLoader::get(const QString &library, const QString &function)
{
Q_ASSERT(!library.isEmpty());
Q_ASSERT(!function.isEmpty());
if (function.isEmpty()) {
if (library.isEmpty() || function.isEmpty()) {
return nullptr;
}
const QString key = generateUniqueKey(library, function);
const QMutexLocker locker(&g_loaderData()->mutex);
if (g_loaderData()->functionCache.contains(function)) {
return g_loaderData()->functionCache.value(function).value_or(nullptr);
if (g_loaderData()->functionCache.contains(key)) {
if (LoaderDebug) {
DEBUG << "Function cache found:" << key;
}
return g_loaderData()->functionCache.value(key);
} else {
if (LoaderDebug) {
DEBUG << "Function cache not found:" << key;
}
return nullptr;
}
}
FRAMELESSHELPER_END_NAMESPACE

View File

@ -282,7 +282,11 @@ QColor Utils::calculateSystemButtonBackgroundColor(const SystemButtonType button
bool Utils::shouldAppsUseDarkMode()
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
#if 0 // Unreleased 6.5 change.
return (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark);
#else
return (QGuiApplication::styleHints()->appearance() == Qt::Appearance::Dark);
#endif
#elif ((QT_VERSION >= QT_VERSION_CHECK(6, 2, 1)) && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE))
if (const QPlatformTheme * const theme = QGuiApplicationPrivate::platformTheme()) {
return (theme->appearance() == QPlatformTheme::Appearance::Dark);

View File

@ -260,7 +260,7 @@ struct SYSTEM_METRIC
if (API_NT_AVAILABLE(RtlGetVersion)) {
using RtlGetVersionPtr = _NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW);
const auto pRtlGetVersion =
reinterpret_cast<RtlGetVersionPtr>(SysApiLoader::instance()->get(kRtlGetVersion));
reinterpret_cast<RtlGetVersionPtr>(SysApiLoader::instance()->get(kntdll, kRtlGetVersion));
RTL_OSVERSIONINFOEXW osvi;
SecureZeroMemory(&osvi, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
@ -592,7 +592,7 @@ bool Utils::isDwmCompositionEnabled()
return resultFromRegistry();
}
BOOL enabled = FALSE;
const HRESULT hr = API_CALL_FUNCTION(DwmIsCompositionEnabled, &enabled);
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmIsCompositionEnabled, &enabled);
if (FAILED(hr)) {
WARNING << __getSystemErrorMessage(kDwmIsCompositionEnabled, hr);
return resultFromRegistry();
@ -647,7 +647,7 @@ void Utils::updateWindowFrameMargins(const WId windowId, const bool reset)
return {1, 1, 1, 1};
}();
const auto hwnd = reinterpret_cast<HWND>(windowId);
const HRESULT hr = API_CALL_FUNCTION(DwmExtendFrameIntoClientArea, hwnd, &margins);
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmExtendFrameIntoClientArea, hwnd, &margins);
if (FAILED(hr)) {
WARNING << __getSystemErrorMessage(kDwmExtendFrameIntoClientArea, hr);
return;
@ -733,7 +733,7 @@ QColor Utils::getDwmColorizationColor()
}
DWORD color = 0;
BOOL opaque = FALSE;
const HRESULT hr = API_CALL_FUNCTION(DwmGetColorizationColor, &color, &opaque);
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmGetColorizationColor, &color, &opaque);
if (FAILED(hr)) {
WARNING << __getSystemErrorMessage(kDwmGetColorizationColor, hr);
return resultFromRegistry();
@ -882,12 +882,12 @@ void Utils::syncWmPaintWithDwm()
return;
}
_TIMECAPS tc = {};
if (API_CALL_FUNCTION4(timeGetDevCaps, &tc, sizeof(tc)) != MMSYSERR_NOERROR) {
if (API_CALL_FUNCTION4(winmm, timeGetDevCaps, &tc, sizeof(tc)) != MMSYSERR_NOERROR) {
WARNING << "timeGetDevCaps() failed.";
return;
}
const UINT ms_granularity = tc.wPeriodMin;
if (API_CALL_FUNCTION4(timeBeginPeriod, ms_granularity) != TIMERR_NOERROR) {
if (API_CALL_FUNCTION4(winmm, timeBeginPeriod, ms_granularity) != TIMERR_NOERROR) {
WARNING << "timeBeginPeriod() failed.";
return;
}
@ -900,7 +900,7 @@ void Utils::syncWmPaintWithDwm()
DWM_TIMING_INFO dti;
SecureZeroMemory(&dti, sizeof(dti));
dti.cbSize = sizeof(dti);
const HRESULT hr = API_CALL_FUNCTION(DwmGetCompositionTimingInfo, nullptr, &dti);
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmGetCompositionTimingInfo, nullptr, &dti);
if (FAILED(hr)) {
WARNING << getSystemErrorMessage(kDwmGetCompositionTimingInfo);
return;
@ -928,7 +928,7 @@ void Utils::syncWmPaintWithDwm()
Q_ASSERT(m < period);
const qreal m_ms = (1000.0 * qreal(m) / qreal(freq.QuadPart));
Sleep(static_cast<DWORD>(std::round(m_ms)));
if (API_CALL_FUNCTION4(timeEndPeriod, ms_granularity) != TIMERR_NOERROR) {
if (API_CALL_FUNCTION4(winmm, timeEndPeriod, ms_granularity) != TIMERR_NOERROR) {
WARNING << "timeEndPeriod() failed.";
}
}
@ -952,7 +952,7 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
// GetDpiForMonitor() is only available on Windows 8 and onwards.
if (API_SHCORE_AVAILABLE(GetDpiForMonitor)) {
UINT dpiX = 0, dpiY = 0;
const HRESULT hr = API_CALL_FUNCTION4(GetDpiForMonitor, hMonitor, _MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
const HRESULT hr = API_CALL_FUNCTION4(shcore, GetDpiForMonitor, hMonitor, _MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
if (SUCCEEDED(hr) && (dpiX > 0) && (dpiY > 0)) {
return (horizontal ? dpiX : dpiY);
} else {
@ -962,7 +962,7 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
// GetScaleFactorForMonitor() is only available on Windows 8 and onwards.
if (API_SHCORE_AVAILABLE(GetScaleFactorForMonitor)) {
_DEVICE_SCALE_FACTOR factor = _DEVICE_SCALE_FACTOR_INVALID;
const HRESULT hr = API_CALL_FUNCTION4(GetScaleFactorForMonitor, hMonitor, &factor);
const HRESULT hr = API_CALL_FUNCTION4(shcore, GetScaleFactorForMonitor, hMonitor, &factor);
if (SUCCEEDED(hr) && (factor != _DEVICE_SCALE_FACTOR_INVALID)) {
return quint32(std::round(qreal(USER_DEFAULT_SCREEN_DPI) * qreal(factor) / qreal(100)));
} else {
@ -1005,7 +1005,7 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
using D2D1CreateFactoryPtr =
HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **);
const auto pD2D1CreateFactory =
reinterpret_cast<D2D1CreateFactoryPtr>(SysApiLoader::instance()->get(kD2D1CreateFactory));
reinterpret_cast<D2D1CreateFactoryPtr>(SysApiLoader::instance()->get(kd2d1, kD2D1CreateFactory));
ID2D1Factory *d2dFactory = nullptr;
HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory),
nullptr, reinterpret_cast<void **>(&d2dFactory));
@ -1082,7 +1082,7 @@ quint32 Utils::getWindowDpi(const WId windowId, const bool horizontal)
if (API_USER_AVAILABLE(GetSystemDpiForProcess)) {
const HANDLE process = GetCurrentProcess();
if (process) {
const UINT dpi = API_CALL_FUNCTION4(GetSystemDpiForProcess, process);
const UINT dpi = API_CALL_FUNCTION4(user32, GetSystemDpiForProcess, process);
if (dpi > 0) {
return dpi;
} else {
@ -1093,7 +1093,7 @@ quint32 Utils::getWindowDpi(const WId windowId, const bool horizontal)
}
}
if (API_USER_AVAILABLE(GetDpiForSystem)) {
const UINT dpi = API_CALL_FUNCTION4(GetDpiForSystem);
const UINT dpi = API_CALL_FUNCTION4(user32, GetDpiForSystem);
if (dpi > 0) {
return dpi;
} else {
@ -1218,7 +1218,7 @@ quint32 Utils::getFrameBorderThickness(const WId windowId, const bool scaled)
const qreal scaleFactor = (qreal(dpi) / qreal(USER_DEFAULT_SCREEN_DPI));
const auto hwnd = reinterpret_cast<HWND>(windowId);
UINT value = 0;
const HRESULT hr = API_CALL_FUNCTION(DwmGetWindowAttribute, hwnd,
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmGetWindowAttribute, hwnd,
_DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &value, sizeof(value));
if (SUCCEEDED(hr)) {
const qreal dpr = (scaled ? 1.0 : scaleFactor);
@ -1485,7 +1485,7 @@ void Utils::tryToEnableHighestDpiAwarenessLevel()
if (!context) {
return false;
}
if (API_CALL_FUNCTION4(SetProcessDpiAwarenessContext, context) != FALSE) {
if (API_CALL_FUNCTION4(user32, SetProcessDpiAwarenessContext, context) != FALSE) {
return true;
}
const DWORD dwError = GetLastError();
@ -1526,7 +1526,7 @@ void Utils::tryToEnableHighestDpiAwarenessLevel()
}
if (API_SHCORE_AVAILABLE(SetProcessDpiAwareness)) {
const auto SetProcessDpiAwareness2 = [](const _PROCESS_DPI_AWARENESS pda) -> bool {
const HRESULT hr = API_CALL_FUNCTION4(SetProcessDpiAwareness, pda);
const HRESULT hr = API_CALL_FUNCTION4(shcore, SetProcessDpiAwareness, pda);
if (SUCCEEDED(hr)) {
return true;
}
@ -1571,7 +1571,7 @@ void Utils::tryToEnableHighestDpiAwarenessLevel()
if (currentAwareness == DpiAwareness::System) {
return;
}
if (API_CALL_FUNCTION4(SetProcessDPIAware) == FALSE) {
if (API_CALL_FUNCTION4(user32, SetProcessDPIAware) == FALSE) {
WARNING << getSystemErrorMessage(kSetProcessDPIAware);
}
}
@ -1602,7 +1602,7 @@ void Utils::updateGlobalWin32ControlsTheme(const WId windowId, const bool dark)
return;
}
const auto hwnd = reinterpret_cast<HWND>(windowId);
const HRESULT hr = API_CALL_FUNCTION(SetWindowTheme, hwnd,
const HRESULT hr = API_CALL_FUNCTION(uxtheme, SetWindowTheme, hwnd,
(dark ? kSystemDarkThemeResourceName : kSystemLightThemeResourceName), nullptr);
if (FAILED(hr)) {
WARNING << __getSystemErrorMessage(kSetWindowTheme, hr);
@ -1682,7 +1682,7 @@ void Utils::setCornerStyleForWindow(const WId windowId, const WindowCornerStyle
}
Q_UNREACHABLE_RETURN(_DWMWCP_DEFAULT);
}();
const HRESULT hr = API_CALL_FUNCTION(DwmSetWindowAttribute,
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmSetWindowAttribute,
hwnd, _DWMWA_WINDOW_CORNER_PREFERENCE, &wcp, sizeof(wcp));
if (FAILED(hr)) {
WARNING << __getSystemErrorMessage(kDwmSetWindowAttribute, hr);
@ -1743,7 +1743,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
bool result = true;
if (WindowsVersionHelper::isWin1122H2OrGreater()) {
const _DWM_SYSTEMBACKDROP_TYPE dwmsbt = _DWMSBT_NONE;
const HRESULT hr = API_CALL_FUNCTION(DwmSetWindowAttribute,
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmSetWindowAttribute,
hwnd, _DWMWA_SYSTEMBACKDROP_TYPE, &dwmsbt, sizeof(dwmsbt));
if (FAILED(hr)) {
result = false;
@ -1751,7 +1751,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
}
} else if (WindowsVersionHelper::isWin11OrGreater()) {
const BOOL enable = FALSE;
HRESULT hr = API_CALL_FUNCTION(DwmSetWindowAttribute,
HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmSetWindowAttribute,
hwnd, _DWMWA_MICA_EFFECT, &enable, sizeof(enable));
if (FAILED(hr)) {
result = false;
@ -1799,13 +1799,13 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
// will still be broken because Qt Quick still use GDI to render some native controls
// such as the window menu.
const MARGINS margins = {-1, -1, -1, -1};
HRESULT hr = API_CALL_FUNCTION(DwmExtendFrameIntoClientArea, hwnd, &margins);
HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmExtendFrameIntoClientArea, hwnd, &margins);
if (SUCCEEDED(hr)) {
if (WindowsVersionHelper::isWin1122H2OrGreater()) {
const auto dwmsbt = (
((blurMode == BlurMode::Windows_MicaAlt) || preferMicaAlt)
? _DWMSBT_TABBEDWINDOW : _DWMSBT_MAINWINDOW);
hr = API_CALL_FUNCTION(DwmSetWindowAttribute, hwnd,
hr = API_CALL_FUNCTION(dwmapi, DwmSetWindowAttribute, hwnd,
_DWMWA_SYSTEMBACKDROP_TYPE, &dwmsbt, sizeof(dwmsbt));
if (SUCCEEDED(hr)) {
return true;
@ -1814,7 +1814,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
}
} else {
const BOOL enable = TRUE;
hr = API_CALL_FUNCTION(DwmSetWindowAttribute,
hr = API_CALL_FUNCTION(dwmapi, DwmSetWindowAttribute,
hwnd, _DWMWA_MICA_EFFECT, &enable, sizeof(enable));
if (SUCCEEDED(hr)) {
return true;
@ -1888,7 +1888,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
}
return TRUE;
}();
const HRESULT hr = API_CALL_FUNCTION(DwmEnableBlurBehindWindow, hwnd, &dwmbb);
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmEnableBlurBehindWindow, hwnd, &dwmbb);
if (SUCCEEDED(hr)) {
return true;
}
@ -2078,7 +2078,7 @@ void Utils::refreshWin32ThemeResources(const WId windowId, const bool dark)
WARNING << getSystemErrorMessage(kSetPropW);
}
}
const HRESULT hr = API_CALL_FUNCTION(DwmSetWindowAttribute, hWnd, borderFlag, &darkFlag, sizeof(darkFlag));
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmSetWindowAttribute, hWnd, borderFlag, &darkFlag, sizeof(darkFlag));
if (FAILED(hr)) {
WARNING << __getSystemErrorMessage(kDwmSetWindowAttribute, hr);
}
@ -2106,7 +2106,7 @@ void Utils::refreshWin32ThemeResources(const WId windowId, const bool dark)
WARNING << getSystemErrorMessage(kSetPropW);
}
}
const HRESULT hr = API_CALL_FUNCTION(DwmSetWindowAttribute, hWnd, borderFlag, &darkFlag, sizeof(darkFlag));
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmSetWindowAttribute, hWnd, borderFlag, &darkFlag, sizeof(darkFlag));
if (FAILED(hr)) {
WARNING << __getSystemErrorMessage(kDwmSetWindowAttribute, hr);
}
@ -2137,7 +2137,7 @@ void Utils::enableNonClientAreaDpiScalingForWindow(const WId windowId)
return;
}
const auto hwnd = reinterpret_cast<HWND>(windowId);
if (API_CALL_FUNCTION4(EnableNonClientDpiScaling, hwnd) == FALSE) {
if (API_CALL_FUNCTION4(user32, EnableNonClientDpiScaling, hwnd) == FALSE) {
WARNING << getSystemErrorMessage(kEnableNonClientDpiScaling);
}
}
@ -2152,7 +2152,7 @@ DpiAwareness Utils::getDpiAwarenessForCurrentProcess(bool *highest)
if (API_USER_AVAILABLE(GetDpiAwarenessContextForProcess)) {
const HANDLE process = GetCurrentProcess();
if (process) {
const _DPI_AWARENESS_CONTEXT result = API_CALL_FUNCTION4(GetDpiAwarenessContextForProcess, process);
const _DPI_AWARENESS_CONTEXT result = API_CALL_FUNCTION4(user32, GetDpiAwarenessContextForProcess, process);
if (result) {
return result;
}
@ -2161,7 +2161,7 @@ DpiAwareness Utils::getDpiAwarenessForCurrentProcess(bool *highest)
WARNING << getSystemErrorMessage(kGetCurrentProcess);
}
}
const _DPI_AWARENESS_CONTEXT result = API_CALL_FUNCTION4(GetThreadDpiAwarenessContext);
const _DPI_AWARENESS_CONTEXT result = API_CALL_FUNCTION4(user32, GetThreadDpiAwarenessContext);
if (result) {
return result;
}
@ -2174,14 +2174,14 @@ DpiAwareness Utils::getDpiAwarenessForCurrentProcess(bool *highest)
auto result = DpiAwareness::Unknown;
// We have to use another API to compare PMv2 and GdiScaled because it seems the
// GetAwarenessFromDpiAwarenessContext() function won't give us these two values.
if (API_CALL_FUNCTION4(AreDpiAwarenessContextsEqual, context,
if (API_CALL_FUNCTION4(user32, AreDpiAwarenessContextsEqual, context,
_DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) != FALSE) {
result = DpiAwareness::PerMonitorVersion2;
} else if (API_CALL_FUNCTION4(AreDpiAwarenessContextsEqual, context,
} else if (API_CALL_FUNCTION4(user32, AreDpiAwarenessContextsEqual, context,
_DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED) != FALSE) {
result = DpiAwareness::Unaware_GdiScaled;
} else {
const _DPI_AWARENESS awareness = API_CALL_FUNCTION4(GetAwarenessFromDpiAwarenessContext, context);
const _DPI_AWARENESS awareness = API_CALL_FUNCTION4(user32, GetAwarenessFromDpiAwarenessContext, context);
switch (awareness) {
case _DPI_AWARENESS_INVALID:
break;
@ -2209,7 +2209,7 @@ DpiAwareness Utils::getDpiAwarenessForCurrentProcess(bool *highest)
}
if (API_SHCORE_AVAILABLE(GetProcessDpiAwareness)) {
_PROCESS_DPI_AWARENESS pda = _PROCESS_DPI_UNAWARE;
const HRESULT hr = API_CALL_FUNCTION4(GetProcessDpiAwareness, nullptr, &pda);
const HRESULT hr = API_CALL_FUNCTION4(shcore, GetProcessDpiAwareness, nullptr, &pda);
if (FAILED(hr)) {
WARNING << __getSystemErrorMessage(kGetProcessDpiAwareness, hr);
return DpiAwareness::Unknown;
@ -2238,7 +2238,7 @@ DpiAwareness Utils::getDpiAwarenessForCurrentProcess(bool *highest)
return result;
}
if (API_USER_AVAILABLE(IsProcessDPIAware)) {
const BOOL isAware = API_CALL_FUNCTION(IsProcessDPIAware);
const BOOL isAware = API_CALL_FUNCTION(user32, IsProcessDPIAware);
const auto result = ((isAware == FALSE) ? DpiAwareness::Unaware : DpiAwareness::System);
if (highest) {
*highest = (result == DpiAwareness::System);