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_INSTALL "Don't install any files." OFF)
option(FRAMELESSHELPER_NO_SUMMARY "Don't show CMake configure summary." OFF) option(FRAMELESSHELPER_NO_SUMMARY "Don't show CMake configure summary." OFF)
option(FRAMELESSHELPER_ENABLE_SPECTRE "Mitigate Spectre security vulnerabilities." 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_INTELCET "Enable Intel CET." ON)
option(FRAMELESSHELPER_ENABLE_INTELJCC "Enable Intel JCC." ON) option(FRAMELESSHELPER_ENABLE_INTELJCC "Enable Intel JCC." ON)
option(FRAMELESSHELPER_ENABLE_CFGUARD "Enable Control Flow Guard (CFG)." 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("[MSVC] Disable permissive checks: ${FRAMELESSHELPER_NO_PERMISSIVE_CHECKS}")
message("Do not install anything for CMake install: ${FRAMELESSHELPER_NO_INSTALL}") message("Do not install anything for CMake install: ${FRAMELESSHELPER_NO_INSTALL}")
message("Mitigate Spectre security vulnerabilities: ${FRAMELESSHELPER_ENABLE_SPECTRE}") 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 CET: ${FRAMELESSHELPER_ENABLE_INTELCET}")
message("Enable Intel JCC: ${FRAMELESSHELPER_ENABLE_INTELJCC}") message("Enable Intel JCC: ${FRAMELESSHELPER_ENABLE_INTELJCC}")
message("Enable Control Flow Guard (CFG): ${FRAMELESSHELPER_ENABLE_CFGUARD}") message("Enable Control Flow Guard (CFG): ${FRAMELESSHELPER_ENABLE_CFGUARD}")

View File

@ -39,18 +39,21 @@ public:
Q_NODISCARD static SysApiLoader *instance(); 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 char *function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QByteArray &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 static QFunctionPointer resolve(const QString &library, const QString &function);
Q_NODISCARD bool isAvailable(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> 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) \ #define API_AVAILABLE(lib, func) \
(FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->isAvailable(k##lib, k##func)) (FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->isAvailable(k##lib, k##func))
#define API_CALL_FUNCTION(func, ...) \ #define API_CALL_FUNCTION(lib, func, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##func))(__VA_ARGS__)) ((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##lib, k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION2(func, type, ...) \ #define API_CALL_FUNCTION2(lib, func, type, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<type>(k##func))(__VA_ARGS__)) ((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<type>(k##lib, k##func))(__VA_ARGS__))
#define API_CALL_FUNCTION3(func, name, ...) \ #define API_CALL_FUNCTION3(lib, func, name, ...) \
((FRAMELESSHELPER_PREPEND_NAMESPACE(SysApiLoader)::instance()->get<decltype(&func)>(k##name))(__VA_ARGS__)) ((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 #ifdef Q_OS_WINDOWS
# define API_USER_AVAILABLE(func) API_AVAILABLE(user32, func) # define API_USER_AVAILABLE(func) API_AVAILABLE(user32, func)

View File

@ -355,7 +355,12 @@ void FramelessManagerPrivate::initialize()
QStyleHints * const styleHints = QGuiApplication::styleHints(); QStyleHints * const styleHints = QGuiApplication::styleHints();
Q_ASSERT(styleHints); Q_ASSERT(styleHints);
if (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); Q_UNUSED(colorScheme);
notifySystemThemeHasChangedOrNot(); notifySystemThemeHasChangedOrNot();
}); });

View File

@ -43,7 +43,7 @@ XInitThreads(
if (!API_XLIB_AVAILABLE(XInitThreads)) { if (!API_XLIB_AVAILABLE(XInitThreads)) {
return 0; return 0;
} }
return API_CALL_FUNCTION(XInitThreads); return API_CALL_FUNCTION(libX11, XInitThreads);
} }
#endif // FRAMELESSHELPER_HAS_XLIB #endif // FRAMELESSHELPER_HAS_XLIB
@ -85,7 +85,7 @@ xcb_send_event(
if (!API_XCB_AVAILABLE(xcb_send_event)) { if (!API_XCB_AVAILABLE(xcb_send_event)) {
return {}; 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 extern "C" int
@ -96,7 +96,7 @@ xcb_flush(
if (!API_XCB_AVAILABLE(xcb_flush)) { if (!API_XCB_AVAILABLE(xcb_flush)) {
return 0; return 0;
} }
return API_CALL_FUNCTION(xcb_flush, connection); return API_CALL_FUNCTION(libxcb, xcb_flush, connection);
} }
extern "C" xcb_intern_atom_cookie_t extern "C" xcb_intern_atom_cookie_t
@ -110,7 +110,7 @@ xcb_intern_atom(
if (!API_XCB_AVAILABLE(xcb_intern_atom)) { if (!API_XCB_AVAILABLE(xcb_intern_atom)) {
return {}; 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 * extern "C" xcb_intern_atom_reply_t *
@ -123,7 +123,7 @@ xcb_intern_atom_reply(
if (!API_XCB_AVAILABLE(xcb_intern_atom_reply)) { if (!API_XCB_AVAILABLE(xcb_intern_atom_reply)) {
return nullptr; 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 extern "C" xcb_void_cookie_t
@ -135,7 +135,7 @@ xcb_ungrab_pointer(
if (!API_XCB_AVAILABLE(xcb_ungrab_pointer)) { if (!API_XCB_AVAILABLE(xcb_ungrab_pointer)) {
return {}; 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 extern "C" xcb_void_cookie_t
@ -153,7 +153,7 @@ xcb_change_property(
if (!API_XCB_AVAILABLE(xcb_change_property)) { if (!API_XCB_AVAILABLE(xcb_change_property)) {
return {}; 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); mode, window, property, type, format, data_len, data);
} }
@ -167,7 +167,7 @@ xcb_delete_property_checked(
if (!API_XCB_AVAILABLE(xcb_delete_property_checked)) { if (!API_XCB_AVAILABLE(xcb_delete_property_checked)) {
return {}; 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 extern "C" xcb_get_property_cookie_t
@ -184,7 +184,7 @@ xcb_get_property(
if (!API_XCB_AVAILABLE(xcb_get_property)) { if (!API_XCB_AVAILABLE(xcb_get_property)) {
return {}; 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); _delete, window, property, type, long_offset, long_length);
} }
@ -198,7 +198,7 @@ xcb_get_property_reply(
if (!API_XCB_AVAILABLE(xcb_get_property_reply)) { if (!API_XCB_AVAILABLE(xcb_get_property_reply)) {
return nullptr; 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 * extern "C" void *
@ -209,7 +209,7 @@ xcb_get_property_value(
if (!API_XCB_AVAILABLE(xcb_get_property_value)) { if (!API_XCB_AVAILABLE(xcb_get_property_value)) {
return nullptr; return nullptr;
} }
return API_CALL_FUNCTION(xcb_get_property_value, reply); return API_CALL_FUNCTION(libxcb, xcb_get_property_value, reply);
} }
extern "C" int extern "C" int
@ -220,7 +220,7 @@ xcb_get_property_value_length(
if (!API_XCB_AVAILABLE(xcb_get_property_value_length)) { if (!API_XCB_AVAILABLE(xcb_get_property_value_length)) {
return 0; 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 extern "C" xcb_list_properties_cookie_t
@ -232,7 +232,7 @@ xcb_list_properties(
if (!API_XCB_AVAILABLE(xcb_list_properties)) { if (!API_XCB_AVAILABLE(xcb_list_properties)) {
return {}; 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 * extern "C" xcb_list_properties_reply_t *
@ -245,7 +245,7 @@ xcb_list_properties_reply(
if (!API_XCB_AVAILABLE(xcb_list_properties_reply)) { if (!API_XCB_AVAILABLE(xcb_list_properties_reply)) {
return nullptr; 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 extern "C" int
@ -256,7 +256,7 @@ xcb_list_properties_atoms_length(
if (!API_XCB_AVAILABLE(xcb_list_properties_atoms_length)) { if (!API_XCB_AVAILABLE(xcb_list_properties_atoms_length)) {
return 0; 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 * extern "C" xcb_atom_t *
@ -267,7 +267,7 @@ xcb_list_properties_atoms(
if (!API_XCB_AVAILABLE(xcb_list_properties_atoms)) { if (!API_XCB_AVAILABLE(xcb_list_properties_atoms)) {
return nullptr; 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 extern "C" xcb_get_property_cookie_t
@ -284,7 +284,7 @@ xcb_get_property_unchecked(
if (!API_XCB_AVAILABLE(xcb_get_property_unchecked)) { if (!API_XCB_AVAILABLE(xcb_get_property_unchecked)) {
return {}; 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); _delete, window, property, type, long_offset, long_length);
} }
@ -339,7 +339,7 @@ gtk_init(
if (!API_GTK_AVAILABLE(gtk_init)) { if (!API_GTK_AVAILABLE(gtk_init)) {
return; return;
} }
API_CALL_FUNCTION(gtk_init, argc, argv); API_CALL_FUNCTION(libgtk, gtk_init, argc, argv);
} }
extern "C" GValue * extern "C" GValue *
@ -351,7 +351,7 @@ g_value_init(
if (!API_GTK_AVAILABLE(g_value_init)) { if (!API_GTK_AVAILABLE(g_value_init)) {
return nullptr; 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 * extern "C" GValue *
@ -362,7 +362,7 @@ g_value_reset(
if (!API_GTK_AVAILABLE(g_value_reset)) { if (!API_GTK_AVAILABLE(g_value_reset)) {
return nullptr; return nullptr;
} }
return API_CALL_FUNCTION(g_value_reset, value); return API_CALL_FUNCTION(libgtk, g_value_reset, value);
} }
extern "C" void extern "C" void
@ -373,7 +373,7 @@ g_value_unset(
if (!API_GTK_AVAILABLE(g_value_unset)) { if (!API_GTK_AVAILABLE(g_value_unset)) {
return; return;
} }
API_CALL_FUNCTION(g_value_unset, value); API_CALL_FUNCTION(libgtk, g_value_unset, value);
} }
extern "C" gboolean extern "C" gboolean
@ -384,7 +384,7 @@ g_value_get_boolean(
if (!API_GTK_AVAILABLE(g_value_get_boolean)) { if (!API_GTK_AVAILABLE(g_value_get_boolean)) {
return false; 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 * extern "C" const gchar *
@ -395,7 +395,7 @@ g_value_get_string(
if (!API_GTK_AVAILABLE(g_value_get_string)) { if (!API_GTK_AVAILABLE(g_value_get_string)) {
return nullptr; return nullptr;
} }
return API_CALL_FUNCTION(g_value_get_string, value); return API_CALL_FUNCTION(libgtk, g_value_get_string, value);
} }
extern "C" GtkSettings * extern "C" GtkSettings *
@ -406,7 +406,7 @@ gtk_settings_get_default(
if (!API_GTK_AVAILABLE(gtk_settings_get_default)) { if (!API_GTK_AVAILABLE(gtk_settings_get_default)) {
return nullptr; return nullptr;
} }
return API_CALL_FUNCTION(gtk_settings_get_default); return API_CALL_FUNCTION(libgtk, gtk_settings_get_default);
} }
extern "C" void extern "C" void
@ -419,7 +419,7 @@ g_object_get_property(
if (!API_GTK_AVAILABLE(g_object_get_property)) { if (!API_GTK_AVAILABLE(g_object_get_property)) {
return; 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 extern "C" gulong
@ -435,7 +435,7 @@ g_signal_connect_data(
if (!API_GTK_AVAILABLE(g_signal_connect_data)) { if (!API_GTK_AVAILABLE(g_signal_connect_data)) {
return 0; 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 extern "C" void
@ -446,7 +446,7 @@ g_free(
if (!API_GTK_AVAILABLE(g_free)) { if (!API_GTK_AVAILABLE(g_free)) {
return; return;
} }
API_CALL_FUNCTION(g_free, mem); API_CALL_FUNCTION(libgtk, g_free, mem);
} }
extern "C" void extern "C" void
@ -457,7 +457,7 @@ g_object_unref(
if (!API_GTK_AVAILABLE(g_object_unref)) { if (!API_GTK_AVAILABLE(g_object_unref)) {
return; return;
} }
API_CALL_FUNCTION(g_object_unref, object); API_CALL_FUNCTION(libgtk, g_object_unref, object);
} }
extern "C" void extern "C" void
@ -468,7 +468,7 @@ g_clear_object(
if (!API_GTK_AVAILABLE(g_clear_object)) { if (!API_GTK_AVAILABLE(g_clear_object)) {
return; 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);) 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); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
} }
return API_CALL_FUNCTION4(GetWindowCompositionAttribute, hWnd, pvData); return API_CALL_FUNCTION4(user32, GetWindowCompositionAttribute, hWnd, pvData);
} }
EXTERN_C BOOL WINAPI EXTERN_C BOOL WINAPI
@ -71,7 +71,7 @@ _SetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvD
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
} }
return API_CALL_FUNCTION4(SetWindowCompositionAttribute, hWnd, pvData); return API_CALL_FUNCTION4(user32, SetWindowCompositionAttribute, hWnd, pvData);
} }
EXTERN_C HRESULT WINAPI EXTERN_C HRESULT WINAPI
@ -88,7 +88,7 @@ _SetWindowThemeAttribute(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib
if (!API_THEME_AVAILABLE(SetWindowThemeAttribute)) { if (!API_THEME_AVAILABLE(SetWindowThemeAttribute)) {
return E_NOTIMPL; 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 EXTERN_C HRESULT WINAPI

View File

@ -73,13 +73,15 @@ static Q_LOGGING_CATEGORY(lcSysApiLoader, "wangwenx190.framelesshelper.core.sysa
struct SysApiLoaderData struct SysApiLoaderData
{ {
QMutex mutex; QMutex mutex;
QHash<QString, std::optional<QFunctionPointer>> functionCache = {}; QHash<QString, QFunctionPointer> functionCache = {};
}; };
Q_GLOBAL_STATIC(SysApiLoaderData, g_loaderData) Q_GLOBAL_STATIC(SysApiLoaderData, g_loaderData)
Q_GLOBAL_STATIC(SysApiLoader, g_sysApiLoader) Q_GLOBAL_STATIC(SysApiLoader, g_sysApiLoader)
static const bool LoaderDebug = qEnvironmentVariableIntValue("FRAMELESSHELPER_SYSAPILOADER_DEBUG");
SysApiLoader::SysApiLoader(QObject *parent) : QObject(parent) SysApiLoader::SysApiLoader(QObject *parent) : QObject(parent)
{ {
} }
@ -91,6 +93,55 @@ SysApiLoader *SysApiLoader::instance()
return g_sysApiLoader(); 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) QFunctionPointer SysApiLoader::resolve(const QString &library, const char *function)
{ {
Q_ASSERT(!library.isEmpty()); Q_ASSERT(!library.isEmpty());
@ -133,32 +184,49 @@ bool SysApiLoader::isAvailable(const QString &library, const QString &function)
if (library.isEmpty() || function.isEmpty()) { if (library.isEmpty() || function.isEmpty()) {
return false; return false;
} }
const QString key = generateUniqueKey(library, function);
const QMutexLocker locker(&g_loaderData()->mutex); const QMutexLocker locker(&g_loaderData()->mutex);
if (g_loaderData()->functionCache.contains(function)) { if (g_loaderData()->functionCache.contains(key)) {
return g_loaderData()->functionCache.value(function).has_value(); if (LoaderDebug) {
DEBUG << "Function cache found:" << key;
} }
return (g_loaderData()->functionCache.value(key) != nullptr);
} else {
const QFunctionPointer symbol = SysApiLoader::resolve(library, function); 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) { if (symbol) {
g_loaderData()->functionCache.insert(function, symbol);
DEBUG << "Successfully loaded" << function << "from" << library; DEBUG << "Successfully loaded" << function << "from" << library;
return true; return true;
} } else {
g_loaderData()->functionCache.insert(function, std::nullopt);
WARNING << "Failed to load" << function << "from" << library; WARNING << "Failed to load" << function << "from" << library;
return false; 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()); Q_ASSERT(!function.isEmpty());
if (function.isEmpty()) { if (library.isEmpty() || function.isEmpty()) {
return nullptr; return nullptr;
} }
const QString key = generateUniqueKey(library, function);
const QMutexLocker locker(&g_loaderData()->mutex); const QMutexLocker locker(&g_loaderData()->mutex);
if (g_loaderData()->functionCache.contains(function)) { if (g_loaderData()->functionCache.contains(key)) {
return g_loaderData()->functionCache.value(function).value_or(nullptr); if (LoaderDebug) {
DEBUG << "Function cache found:" << key;
}
return g_loaderData()->functionCache.value(key);
} else {
if (LoaderDebug) {
DEBUG << "Function cache not found:" << key;
} }
return nullptr; return nullptr;
} }
}
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

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

View File

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