Compare commits

..

No commits in common. "90b2fe42c63f471cd99a86da71eea33f906c5033" and "5b0d06307a23514fc415b97203f16db538a80050" have entirely different histories.

39 changed files with 302 additions and 408 deletions

View File

@ -25,7 +25,7 @@
cmake_minimum_required(VERSION 3.20)
project(FramelessHelper
VERSION "2.5.0"
VERSION "2.4.2"
DESCRIPTION "Cross-platform window customization framework for Qt Widgets and Qt Quick."
HOMEPAGE_URL "https://github.com/wangwenx190/framelesshelper/"
)

View File

@ -28,25 +28,17 @@ set(_@PROJECT_NAME@_supported_components Core Widgets Quick)
foreach(_comp ${@PROJECT_NAME@_FIND_COMPONENTS})
if(_comp IN_LIST _@PROJECT_NAME@_supported_components)
set(__target @PROJECT_NAME@::${_comp})
if(TARGET ${__target})
continue()
set(__targets_file "${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@${_comp}Targets.cmake")
if(EXISTS "${__targets_file}")
include("${__targets_file}")
else()
set(__target_full @PROJECT_NAME@${_comp})
set(__targets_file "${CMAKE_CURRENT_LIST_DIR}/${__target_full}Targets.cmake")
if(EXISTS "${__targets_file}")
include("${__targets_file}")
add_library(@PROJECT_NAME@::${__target_full} ALIAS ${__target_full})
add_library(${__target} ALIAS ${__target_full})
else()
set(@PROJECT_NAME@_FOUND FALSE)
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Can't find necessary configuration file for ${__target}, please make sure this component is built successfully and installed properly.")
break()
endif()
set(@PROJECT_NAME@_FOUND FALSE)
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Can't find necessary configuration file for @PROJECT_NAME@::${_comp}, please make sure this component is built successfully and installed properly.")
break()
endif()
else()
set(@PROJECT_NAME@_FOUND FALSE)
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Unknown component: ${__target}.")
set(@PROJECT_NAME@_NOT_FOUND_MESSAGE "Unknown component: @PROJECT_NAME@::${_comp}.")
break()
endif()
endforeach()

View File

@ -17,14 +17,6 @@ You can join our [Discord channel](https://discord.gg/grrM4Tmesy) to communicate
- Examples: Add demo projects that have transparent background and doesn't have rectangular window frame.
- Feature requests are welcome!
## Highlights v2.5
- General: The file size of FramelessHelper binaries should be smaller than before, due to most static string literals and some internal structures are constexpr now, this change may also help to improve the general performance.
- General: The performance should be improved quite some bit, due to most double lookups of Qt container types and unnecessary data copies are avoided now.
- Mica Material: FramelessHelper now prefers speed over quality. This change will lower the image quality but since the image is highly blurred anyway, there should not be any significant differences in the final user experience.
- Build system: Improved RPATH support.
- Routine bug fixes and internal refactorings.
## Highlights v2.4
- Widgets: Nested frameless windows are supported now!

2
cmake

@ -1 +1 @@
Subproject commit 68b2bcba1456bbad73309d748ce50dc6cefc04a2
Subproject commit d4c8265fa4afe6244fadff6648d1d091de0c5d68

View File

@ -28,11 +28,13 @@
#include <QtCore/qmath.h>
#include <QtCore/qpoint.h>
#include <QtCore/qsize.h>
#include <QtCore/qrect.h>
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
#include <QtGui/qcolor.h>
#include <QtGui/qwindowdefs.h>
#include <functional>
#include <optional>
#include <memory>
QT_BEGIN_NAMESPACE
class QEvent;
@ -290,8 +292,7 @@ enum class Option : quint8
EnableBlurBehindWindow,
ForceNonNativeBackgroundBlur,
DisableLazyInitializationForMicaMaterial,
ForceNativeBackgroundBlur,
Last = ForceNativeBackgroundBlur
ForceNativeBackgroundBlur
};
Q_ENUM_NS(Option)
@ -312,8 +313,7 @@ enum class SystemButtonType : quint8
Minimize,
Maximize,
Restore,
Close,
Last = Close
Close
};
Q_ENUM_NS(SystemButtonType)

View File

@ -25,6 +25,7 @@
#pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtCore/qrect.h>
FRAMELESSHELPER_BEGIN_NAMESPACE

View File

@ -25,7 +25,6 @@
#pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <functional>
QT_BEGIN_NAMESPACE
class QScreen;

View File

@ -31,7 +31,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
class MicaMaterial;
struct Transform
using Transform = struct Transform
{
qreal Horizontal = 0;
qreal Vertical = 0;

View File

@ -25,7 +25,6 @@
#pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <functional>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
# include <QtCore/qscopeguard.h>

View File

@ -89,7 +89,7 @@ struct VersionNumber
};
#ifdef Q_OS_WINDOWS
[[maybe_unused]] inline constexpr const std::array<VersionNumber, static_cast<int>(Global::WindowsVersion::Latest) + 1> WindowsVersions =
[[maybe_unused]] inline constexpr const std::array<VersionNumber, 27> WindowsVersions =
{
VersionNumber{ 5, 0, 2195 }, // Windows 2000
VersionNumber{ 5, 1, 2600 }, // Windows XP

View File

@ -74,8 +74,6 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_QUICK_URI[] = "org.wangwenx190.FramelessHelper";
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_QUICK_VERSION_MAJOR = 1;
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_QUICK_VERSION_MINOR = 0;
class FRAMELESSHELPER_QUICK_API QuickGlobal : public QObject
{

View File

@ -36,7 +36,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
class FramelessQuickHelper;
class QuickMicaMaterial;
class QuickWindowBorder;
struct FramelessQuickHelperData;
struct QuickHelperData;
class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
{
@ -89,10 +89,7 @@ public:
Q_NODISCARD bool isReady() const;
void waitForReady();
void repaintAllChildren(const quint32 delay = 0) const;
Q_NODISCARD quint32 readyWaitTime() const;
void setReadyWaitTime(const quint32 time);
void repaintAllChildren(const int delay = 0) const;
private:
Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
@ -100,8 +97,8 @@ private:
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
Q_NODISCARD const FramelessQuickHelperData *getWindowData() const;
Q_NODISCARD FramelessQuickHelperData *getWindowDataMutable() const;
Q_NODISCARD QuickHelperData getWindowData() const;
Q_NODISCARD QuickHelperData *getWindowDataMutable() const;
void rebindWindow();
private:
@ -111,7 +108,6 @@ private:
std::optional<bool> m_extendIntoTitleBar = std::nullopt;
bool m_destroying = false;
bool m_qpaReady = false;
quint32 m_qpaWaitTime = 0;
};
FRAMELESSHELPER_END_NAMESPACE

View File

@ -31,7 +31,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
class FramelessWidgetsHelper;
struct FramelessWidgetsHelperData;
struct WidgetsHelperData;
class WidgetsSharedHelper;
class MicaMaterial;
class WindowBorderPainter;
@ -90,10 +90,7 @@ public:
Q_NODISCARD bool isReady() const;
void waitForReady();
void repaintAllChildren(const quint32 delay = 0) const;
Q_NODISCARD quint32 readyWaitTime() const;
void setReadyWaitTime(const quint32 time);
void repaintAllChildren(const int delay = 0) const;
private:
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
@ -102,8 +99,8 @@ private:
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
void setSystemButtonState(const Global::SystemButtonType button, const Global::ButtonState state);
Q_NODISCARD QWidget *findTopLevelWindow() const;
Q_NODISCARD const FramelessWidgetsHelperData *getWindowData() const;
Q_NODISCARD FramelessWidgetsHelperData *getWindowDataMutable() const;
Q_NODISCARD WidgetsHelperData getWindowData() const;
Q_NODISCARD WidgetsHelperData *getWindowDataMutable() const;
private:
FramelessWidgetsHelper *q_ptr = nullptr;
@ -113,7 +110,6 @@ private:
bool m_destroying = false;
bool m_qpaReady = false;
QSizePolicy m_savedSizePolicy = {};
quint32 m_qpaWaitTime = 0;
};
FRAMELESSHELPER_END_NAMESPACE

View File

@ -34,10 +34,10 @@
#define _FRAMELESSHELPER_VERSION_DEFINED_
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_MAJOR = 2;
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_MINOR = 5;
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_PATCH = 0;
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_MINOR = 4;
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_PATCH = 2;
//[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_TWEAK = 0;
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_VERSION_STR[] = "2.5.0";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_VERSION_STR[] = "2.4.2";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMMIT_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMPILE_DATETIME_STR[] = "UNKNOWN";

View File

@ -22,6 +22,8 @@
SOFTWARE.
]]
include(GNUInstallDirs)
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
@ -273,7 +275,6 @@ else()
)
endif()
include(GNUInstallDirs)
target_include_directories(${SUB_MODULE_TARGET} PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_PREFIX}/../..>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_PREFIX}>"
@ -284,13 +285,8 @@ target_include_directories(${SUB_MODULE_TARGET} PUBLIC
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${SUB_MODULE_PATH}/private>"
)
if(NOT FRAMELESSHELPER_BUILD_STATIC)
setup_target_rpaths(TARGETS ${SUB_MODULE_TARGET})
endif()
setup_qt_stuff(TARGETS ${SUB_MODULE_TARGET})
set(__extra_flags "")
set(__extra_flags)
if(NOT FRAMELESSHELPER_NO_PERMISSIVE_CHECKS)
list(APPEND __extra_flags PERMISSIVE)
endif()
@ -313,7 +309,6 @@ if(FRAMELESSHELPER_FORCE_LTO)
list(APPEND __extra_flags FORCE_LTO)
endif()
setup_compile_params(TARGETS ${SUB_MODULE_TARGET} ${__extra_flags})
if(NOT FRAMELESSHELPER_NO_INSTALL)
setup_package_export(
TARGETS ${__export_targets}

View File

@ -53,7 +53,8 @@ ChromePalettePrivate::ChromePalettePrivate(ChromePalette *q) : QObject(q)
return;
}
q_ptr = q;
connect(FramelessManager::instance(), &FramelessManager::systemThemeChanged, this, &ChromePalettePrivate::refresh);
connect(FramelessManager::instance(),
&FramelessManager::systemThemeChanged, this, &ChromePalettePrivate::refresh);
refresh();
}

View File

@ -24,7 +24,6 @@
#include "framelessconfig_p.h"
#include <array>
#include <memory>
#include <QtCore/qdir.h>
#include <QtCore/qsettings.h>
#include <QtCore/qcoreapplication.h>
@ -33,7 +32,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcFramelessConfig, "wangwenx190.framelesshelper.core.framelessconfig")
static Q_LOGGING_CATEGORY(lcFramelessConfig, "wangwenx190.framelesshelper.core.framelessconfig")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -55,7 +54,7 @@ struct FramelessConfigEntry
const char *cfg = nullptr;
};
static constexpr const std::array<FramelessConfigEntry, static_cast<int>(Option::Last) + 1> FramelessOptionsTable =
static constexpr const std::array<FramelessConfigEntry, 10> FramelessOptionsTable =
{
FramelessConfigEntry{ "FRAMELESSHELPER_USE_CROSS_PLATFORM_QT_IMPLEMENTATION", "Options/UseCrossPlatformQtImplementation" },
FramelessConfigEntry{ "FRAMELESSHELPER_FORCE_HIDE_WINDOW_FRAME_BORDER", "Options/ForceHideWindowFrameBorder" },
@ -74,7 +73,7 @@ static constexpr const auto OptionCount = std::size(FramelessOptionsTable);
struct FramelessConfigData
{
bool loaded = false;
std::array<bool, OptionCount> options = {};
bool options[OptionCount] = {};
bool disableEnvVar = false;
bool disableCfgFile = false;
};
@ -140,7 +139,7 @@ void FramelessConfig::reload(const bool force)
&& (qEnvironmentVariableIntValue(FramelessOptionsTable.at(i).env) > 0));
const bool cfgFile = (!g_framelessConfigData()->disableCfgFile && configFile
&& configFile->value(QUtf8String(FramelessOptionsTable.at(i).cfg), false).toBool());
g_framelessConfigData()->options.at(i) = (envVar || cfgFile);
g_framelessConfigData()->options[i] = (envVar || cfgFile);
}
g_framelessConfigData()->loaded = true;
@ -149,12 +148,12 @@ void FramelessConfig::reload(const bool force)
void FramelessConfig::set(const Option option, const bool on)
{
g_framelessConfigData()->options.at(static_cast<int>(option)) = on;
g_framelessConfigData()->options[static_cast<int>(option)] = on;
}
bool FramelessConfig::isSet(const Option option) const
{
return g_framelessConfigData()->options.at(static_cast<int>(option));
return g_framelessConfigData()->options[static_cast<int>(option)];
}
void FramelessConfig::setLoadFromEnvironmentVariablesDisabled(const bool on)

View File

@ -58,9 +58,12 @@ struct FramelessQtHelperData
bool leftButtonPressed = false;
};
using FramelessQtHelperInternal = QHash<WId, FramelessQtHelperData>;
struct FramelessQtHelper
{
QHash<WId, FramelessQtHelperData> data = {};
};
Q_GLOBAL_STATIC(FramelessQtHelperInternal, g_framelessQtHelperData)
Q_GLOBAL_STATIC(FramelessQtHelper, g_framelessQtHelperData)
FramelessHelperQt::FramelessHelperQt(QObject *parent) : QObject(parent) {}
@ -73,8 +76,8 @@ void FramelessHelperQt::addWindow(FramelessParamsConst params)
return;
}
const WId windowId = params->getWindowId();
const auto it = g_framelessQtHelperData()->constFind(windowId);
if (it != g_framelessQtHelperData()->constEnd()) {
const auto it = g_framelessQtHelperData()->data.constFind(windowId);
if (it != g_framelessQtHelperData()->data.constEnd()) {
return;
}
FramelessQtHelperData data = {};
@ -82,7 +85,7 @@ void FramelessHelperQt::addWindow(FramelessParamsConst params)
QWindow *window = params->getWindowHandle();
// Give it a parent so that it can be automatically deleted by Qt.
data.eventFilter = new FramelessHelperQt(window);
g_framelessQtHelperData()->insert(windowId, data);
g_framelessQtHelperData()->data.insert(windowId, data);
const auto shouldApplyFramelessFlag = []() -> bool {
#ifdef Q_OS_MACOS
return false;
@ -114,11 +117,11 @@ void FramelessHelperQt::removeWindow(const WId windowId)
if (!windowId) {
return;
}
const auto it = g_framelessQtHelperData()->constFind(windowId);
if (it == g_framelessQtHelperData()->constEnd()) {
const auto it = g_framelessQtHelperData()->data.constFind(windowId);
if (it == g_framelessQtHelperData()->data.constEnd()) {
return;
}
g_framelessQtHelperData()->erase(it);
g_framelessQtHelperData()->data.erase(it);
#ifdef Q_OS_MACOS
Utils::removeWindowProxy(windowId);
#endif
@ -162,8 +165,8 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
}
const auto window = qobject_cast<QWindow *>(object);
const WId windowId = window->winId();
const auto it = g_framelessQtHelperData()->find(windowId);
if (it == g_framelessQtHelperData()->end()) {
const auto it = g_framelessQtHelperData()->data.find(windowId);
if (it == g_framelessQtHelperData()->data.end()) {
return QObject::eventFilter(object, event);
}
const FramelessQtHelperData &data = it.value();

View File

@ -31,7 +31,6 @@
#include "framelesshelper_windows.h"
#include "framelesshelpercore_global_p.h"
#include <optional>
#include <memory>
#include <QtCore/qhash.h>
#include <QtCore/qvariant.h>
#include <QtCore/qcoreapplication.h>
@ -41,7 +40,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcFramelessHelperWin, "wangwenx190.framelesshelper.core.impl.win")
static Q_LOGGING_CATEGORY(lcFramelessHelperWin, "wangwenx190.framelesshelper.core.impl.win")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -97,14 +96,14 @@ struct FramelessWin32HelperData
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
};
struct FramelessWin32HelperInternal
struct FramelessWin32Helper
{
std::unique_ptr<FramelessHelperWin> nativeEventFilter = nullptr;
QHash<WId, FramelessWin32HelperData> data = {};
QHash<WId, WId> fallbackTitleBarToParentWindowMapping = {};
};
Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
Q_GLOBAL_STATIC(FramelessWin32Helper, g_framelessWin32HelperData)
[[nodiscard]] extern bool operator==(const RECT &lhs, const RECT &rhs) noexcept;
[[nodiscard]] extern bool operator!=(const RECT &lhs, const RECT &rhs) noexcept;
@ -212,10 +211,7 @@ Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
case SystemButtonType::Close:
return HTCLOSE;
case SystemButtonType::Unknown:
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4702)
Q_UNREACHABLE_RETURN(HTNOWHERE);
QT_WARNING_POP
}
}
// Returns "HTTRANSPARENT" to let the mouse event pass through this invisible
@ -501,19 +497,15 @@ static inline void cleanupFallbackWindow()
return false;
}
const auto fallbackTitleBarWindowId = reinterpret_cast<WId>(fallbackTitleBarWindowHandle);
if (!resizeFallbackTitleBarWindow(parentWindowId, fallbackTitleBarWindowId, hide)) {
WARNING << "Failed to re-position the fallback title bar window.";
return false;
}
g_framelessWin32HelperData()->data[parentWindowId].fallbackTitleBarWindowId = fallbackTitleBarWindowId;
g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.insert(fallbackTitleBarWindowId, parentWindowId);
// We need some extra delay here. Experiments revealed that the time point
// is still too early when we call this function, and thus we failed to place
// the the fake title bar window in the correct position. Adding some delay
// fixes this issue. But when we are running in a slow environment (when we
// are debugging/the system overload is very high/the hardware is old), this
// delay may not be enough. But currently I haven't come up with a good solution
// that can perfectly fix this issue.
QTimer::singleShot(1000, qApp, [parentWindowId, fallbackTitleBarWindowId, hide]() -> void {
if (!resizeFallbackTitleBarWindow(parentWindowId, fallbackTitleBarWindowId, hide)) {
WARNING << "Failed to re-position the fallback title bar window.";
}
// ### Why do we need an extra resize here?
QTimer::singleShot(200, qApp, [parentWindowId, fallbackTitleBarWindowId, hide](){
std::ignore = resizeFallbackTitleBarWindow(parentWindowId, fallbackTitleBarWindowId, hide);
});
return true;
}

View File

@ -109,7 +109,7 @@ void framelesshelpercore_initResource()
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcCoreGlobal, "wangwenx190.framelesshelper.core.global")
static Q_LOGGING_CATEGORY(lcCoreGlobal, "wangwenx190.framelesshelper.core.global")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()

View File

@ -44,7 +44,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcFramelessManager, "wangwenx190.framelesshelper.core.framelessmanager")
static Q_LOGGING_CATEGORY(lcFramelessManager, "wangwenx190.framelesshelper.core.framelessmanager")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()

View File

@ -29,7 +29,6 @@
#include "framelessconfig_p.h"
#include "framelesshelpercore_global_p.h"
#include <optional>
#include <memory>
#include <QtCore/qsysinfo.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qmutex.h>
@ -46,7 +45,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcMicaMaterial, "wangwenx190.framelesshelper.core.micamaterial")
static Q_LOGGING_CATEGORY(lcMicaMaterial, "wangwenx190.framelesshelper.core.micamaterial")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -157,12 +156,16 @@ static inline void qt_blurrow(QImage &im, const int line, const int alpha)
int zR = 0, zG = 0, zB = 0, zA = 0;
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4127) // false alarm.
#ifdef Q_CC_MSVC
# pragma warning(push)
# pragma warning(disable:4127) // false alarm.
#endif // Q_CC_MSVC
if (alphaOnly && (im.format() != QImage::Format_Indexed8)) {
bptr += alphaIndex;
}
QT_WARNING_POP
#ifdef Q_CC_MSVC
# pragma warning(pop)
#endif // Q_CC_MSVC
const int stride = (im.depth() >> 3);
const int im_width = im.width();
@ -412,10 +415,8 @@ static inline void expblur(QImage &img, qreal radius, const bool improvedQuality
if (p) {
p->save();
// We need a blurry image anyway, we don't need high quality image processing.
p->setRenderHint(QPainter::Antialiasing, false);
p->setRenderHint(QPainter::TextAntialiasing, false);
p->setRenderHint(QPainter::SmoothPixmapTransform, false);
p->setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
p->scale(scale, scale);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0))
const QSize imageSize = blurImage.deviceIndependentSize().toSize();
@ -563,23 +564,19 @@ protected:
}
QSize newSize = image.size();
newSize.scale(imageSize, mode);
image = image.scaled(newSize);
image = image.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
}
static constexpr const QPoint desktopOriginPoint = {0, 0};
const QRect desktopRect = {desktopOriginPoint, imageSize};
if (aspectStyle == WallpaperAspectStyle::Tile) {
QPainter bufferPainter(&buffer);
// Same as above, we prefer speed than quality here.
bufferPainter.setRenderHint(QPainter::Antialiasing, false);
bufferPainter.setRenderHint(QPainter::TextAntialiasing, false);
bufferPainter.setRenderHint(QPainter::SmoothPixmapTransform, false);
bufferPainter.setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
bufferPainter.fillRect(desktopRect, QBrush(image));
} else {
QPainter bufferPainter(&buffer);
// Same here.
bufferPainter.setRenderHint(QPainter::Antialiasing, false);
bufferPainter.setRenderHint(QPainter::TextAntialiasing, false);
bufferPainter.setRenderHint(QPainter::SmoothPixmapTransform, false);
bufferPainter.setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
const QRect rect = alignedRect(Qt::LeftToRight, Qt::AlignCenter, image.size(), desktopRect);
bufferPainter.drawImage(rect.topLeft(), image);
}
@ -588,14 +585,12 @@ protected:
g_imageData()->blurredWallpaper = QPixmap(imageSize);
g_imageData()->blurredWallpaper.fill(kDefaultTransparentColor);
QPainter painter(&g_imageData()->blurredWallpaper);
// Same here.
painter.setRenderHint(QPainter::Antialiasing, false);
painter.setRenderHint(QPainter::TextAntialiasing, false);
painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
painter.setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE
painter.drawImage(desktopOriginPoint, buffer);
#else // !FRAMELESSHELPER_CORE_NO_PRIVATE
qt_blurImage(&painter, buffer, kDefaultBlurRadius, false, false);
qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false);
#endif // FRAMELESSHELPER_CORE_NO_PRIVATE
}
Q_EMIT imageUpdated(transform);
@ -678,10 +673,8 @@ void MicaMaterialPrivate::updateMaterialBrush()
fillColor.setAlphaF(0.9f);
micaTexture.fill(fillColor);
QPainter painter(&micaTexture);
// Same as above. We need speed, not quality.
painter.setRenderHint(QPainter::Antialiasing, false);
painter.setRenderHint(QPainter::TextAntialiasing, false);
painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
painter.setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
painter.setOpacity(tintOpacity);
const QRect rect = {QPoint(0, 0), micaTexture.size()};
painter.fillRect(rect, tintColor);
@ -706,10 +699,8 @@ void MicaMaterialPrivate::paint(QPainter *painter, const QRect &rect, const bool
static constexpr const QPoint originPoint = {0, 0};
const QRect mappedRect = mapToWallpaper(rect);
painter->save();
// Same as above. Speed is more important here.
painter->setRenderHint(QPainter::Antialiasing, false);
painter->setRenderHint(QPainter::TextAntialiasing, false);
painter->setRenderHint(QPainter::SmoothPixmapTransform, false);
painter->setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
if (active) {
const QMutexLocker locker(&g_imageData()->mutex);
painter->drawPixmap(originPoint, g_imageData()->blurredWallpaper, mappedRect);

View File

@ -57,7 +57,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcSysApiLoader, "wangwenx190.framelesshelper.core.sysapiloader")
static Q_LOGGING_CATEGORY(lcSysApiLoader, "wangwenx190.framelesshelper.core.sysapiloader")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -71,15 +71,14 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
# define CRITICAL qCCritical(lcSysApiLoader)
#endif
using SysApiLoaderData = QHash<QString, QFunctionPointer>;
struct SysApiLoaderData
{
QHash<QString, QFunctionPointer> functionCache = {};
};
Q_GLOBAL_STATIC(SysApiLoaderData, g_sysApiLoaderData)
[[nodiscard]] static inline bool isDebug()
{
static const bool flag = qEnvironmentVariableIntValue("FRAMELESSHELPER_SYSAPILOADER_DEBUG");
return flag;
}
static const bool LoaderDebugFlag = qEnvironmentVariableIntValue("FRAMELESSHELPER_SYSAPILOADER_DEBUG");
SysApiLoader::SysApiLoader(QObject *parent) : QObject(parent)
{
@ -114,11 +113,11 @@ QString SysApiLoader::platformSystemLibraryDirectory()
static const auto result = []() -> QString {
#ifdef Q_OS_WINDOWS
QVarLengthArray<wchar_t, MAX_PATH> buf = {};
const UINT len = ::GetSystemDirectoryW(buf.data(), MAX_PATH);
const UINT len = GetSystemDirectoryW(buf.data(), MAX_PATH);
if (len > MAX_PATH) {
// No need to +1 here, GetSystemDirectoryW() will always give us a null terminator.
buf.resize(len);
::GetSystemDirectoryW(buf.data(), len);
GetSystemDirectoryW(buf.data(), len);
}
return QString::fromWCharArray(buf.constData(), len);
#else
@ -185,16 +184,16 @@ bool SysApiLoader::isAvailable(const QString &library, const QString &function)
return false;
}
const QString key = generateUniqueKey(library, function);
const auto it = g_sysApiLoaderData()->constFind(key);
if (it != g_sysApiLoaderData()->constEnd()) {
if (isDebug()) {
const auto it = g_sysApiLoaderData()->functionCache.constFind(key);
if (it != g_sysApiLoaderData()->functionCache.constEnd()) {
if (LoaderDebugFlag) {
DEBUG << Q_FUNC_INFO << "Function cache found:" << key;
}
return (it.value() != nullptr);
} else {
const QFunctionPointer symbol = SysApiLoader::resolve(library, function);
g_sysApiLoaderData()->insert(key, symbol);
if (isDebug()) {
g_sysApiLoaderData()->functionCache.insert(key, symbol);
if (LoaderDebugFlag) {
DEBUG << Q_FUNC_INFO << "New function cache:" << key << (symbol ? "[VALID]" : "[NULL]");
}
if (symbol) {
@ -215,14 +214,14 @@ QFunctionPointer SysApiLoader::get(const QString &library, const QString &functi
return nullptr;
}
const QString key = generateUniqueKey(library, function);
const auto it = g_sysApiLoaderData()->constFind(key);
if (it != g_sysApiLoaderData()->constEnd()) {
if (isDebug()) {
const auto it = g_sysApiLoaderData()->functionCache.constFind(key);
if (it != g_sysApiLoaderData()->functionCache.constEnd()) {
if (LoaderDebugFlag) {
DEBUG << Q_FUNC_INFO << "Function cache found:" << key;
}
return it.value();
} else {
if (isDebug()) {
if (LoaderDebugFlag) {
DEBUG << Q_FUNC_INFO << "Function cache not found:" << key;
}
return nullptr;

View File

@ -46,7 +46,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcUtilsCommon, "wangwenx190.framelesshelper.core.utils.common")
static Q_LOGGING_CATEGORY(lcUtilsCommon, "wangwenx190.framelesshelper.core.utils.common")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -69,7 +69,7 @@ struct FONT_ICON
quint32 Fallback = 0;
};
static constexpr const std::array<FONT_ICON, static_cast<int>(SystemButtonType::Last) + 1> g_fontIconsTable =
static constexpr const std::array<FONT_ICON, 7> g_fontIconsTable =
{
FONT_ICON{ 0x0000, 0x0000 },
FONT_ICON{ 0xE756, 0x0000 },

View File

@ -54,7 +54,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcUtilsLinux, "wangwenx190.framelesshelper.core.utils.linux")
static Q_LOGGING_CATEGORY(lcUtilsLinux, "wangwenx190.framelesshelper.core.utils.linux")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()

View File

@ -27,8 +27,6 @@
#include "framelessmanager_p.h"
#include "framelessconfig_p.h"
#include "framelesshelpercore_global_p.h"
#include <functional>
#include <memory>
#include <QtCore/qhash.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qloggingcategory.h>
@ -67,7 +65,7 @@ FRAMELESSHELPER_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcUtilsMac, "wangwenx190.framelesshelper.core.utils.mac")
static Q_LOGGING_CATEGORY(lcUtilsMac, "wangwenx190.framelesshelper.core.utils.mac")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -469,12 +467,11 @@ private:
#if 0
const auto nswindow = reinterpret_cast<NSWindow *>(obj);
const auto it = instances.find(nswindow);
if (it == instances.end()) {
if (!instances.contains(nswindow)) {
return;
}
NSWindowProxy * const proxy = it.value();
NSWindowProxy * const proxy = instances[nswindow];
if (event.type == NSEventTypeLeftMouseDown) {
proxy->lastMouseDownEvent = event;
QCoreApplication::processEvents();
@ -513,7 +510,10 @@ private:
static inline sendEventPtr oldSendEvent = nil;
};
using MacUtilsData = QHash<WId, NSWindowProxy *>;
struct MacUtilsData
{
QHash<WId, NSWindowProxy *> hash = {};
};
Q_GLOBAL_STATIC(MacUtilsData, g_macUtilsData);
@ -533,18 +533,17 @@ Q_GLOBAL_STATIC(MacUtilsData, g_macUtilsData);
static inline void cleanupProxy()
{
if (g_macUtilsData()->isEmpty()) {
if (g_macUtilsData()->hash.isEmpty()) {
return;
}
const auto &data = *g_macUtilsData();
for (auto &&proxy : std::as_const(data)) {
for (auto &&proxy : std::as_const(g_macUtilsData()->hash)) {
Q_ASSERT(proxy);
if (!proxy) {
continue;
}
delete proxy;
}
g_macUtilsData()->clear();
g_macUtilsData()->hash.clear();
}
[[nodiscard]] static inline NSWindowProxy *ensureWindowProxy(const WId windowId)
@ -553,8 +552,7 @@ static inline void cleanupProxy()
if (!windowId) {
return nil;
}
auto it = g_macUtilsData()->find(windowId);
if (it == g_macUtilsData()->end()) {
if (!g_macUtilsData()->hash.contains(windowId)) {
QWindow * const qwindow = Utils::findWindow(windowId);
Q_ASSERT(qwindow);
if (!qwindow) {
@ -566,14 +564,14 @@ static inline void cleanupProxy()
return nil;
}
const auto proxy = new NSWindowProxy(qwindow, nswindow);
it = g_macUtilsData()->insert(windowId, proxy);
g_macUtilsData()->hash.insert(windowId, proxy);
}
static bool cleanerInstalled = false;
if (!cleanerInstalled) {
cleanerInstalled = true;
qAddPostRoutine(cleanupProxy);
}
return it.value();
return g_macUtilsData()->hash.value(windowId);
}
void Utils::setSystemTitleBarVisible(const WId windowId, const bool visible)
@ -735,16 +733,15 @@ void Utils::removeWindowProxy(const WId windowId)
if (!windowId) {
return;
}
const auto it = g_macUtilsData()->constFind(windowId);
if (it == g_macUtilsData()->constEnd()) {
if (!g_macUtilsData()->hash.contains(windowId)) {
return;
}
if (const auto proxy = it.value()) {
if (const auto proxy = g_macUtilsData()->hash.value(windowId)) {
// We'll restore everything to default in the destructor,
// so no need to do it manually here.
delete proxy;
}
g_macUtilsData()->erase(it);
g_macUtilsData()->hash.remove(windowId);
}
QColor Utils::getFrameBorderColor(const bool active)

View File

@ -57,7 +57,7 @@ Q_DECLARE_METATYPE(QMargins)
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcUtilsWin, "wangwenx190.framelesshelper.core.utils.win")
static Q_LOGGING_CATEGORY(lcUtilsWin, "wangwenx190.framelesshelper.core.utils.win")
#ifdef FRAMELESSHELPER_CORE_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -191,13 +191,13 @@ struct Win32UtilsData
SystemParameters params = {};
};
struct Win32UtilsInternal
struct Win32UtilsHelper
{
QHash<WId, Win32UtilsData> data = {};
QList<WId> micaWindowIds = {};
};
Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
Q_GLOBAL_STATIC(Win32UtilsHelper, g_win32UtilsData)
[[nodiscard]] bool operator==(const RECT &lhs, const RECT &rhs) noexcept
{
@ -1675,10 +1675,7 @@ void Utils::setCornerStyleForWindow(const WId windowId, const WindowCornerStyle
case WindowCornerStyle::Round:
return _DWMWCP_ROUND;
}
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4702)
Q_UNREACHABLE_RETURN(_DWMWCP_DEFAULT);
QT_WARNING_POP
}();
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmSetWindowAttribute,
hwnd, _DWMWA_WINDOW_CORNER_PREFERENCE, &wcp, sizeof(wcp));
@ -1731,10 +1728,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
}
return BlurMode::Windows_Aero;
}
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4702)
Q_UNREACHABLE_RETURN(BlurMode::Default);
QT_WARNING_POP
}();
if (blurMode == BlurMode::Disable) {
bool result = true;
@ -1840,10 +1834,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
policy.AccentState = ACCENT_ENABLE_BLURBEHIND;
policy.AccentFlags = ACCENT_NONE;
} else {
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4702)
Q_UNREACHABLE_RETURN(false);
QT_WARNING_POP
}
WINDOWCOMPOSITIONATTRIBDATA wcad;
SecureZeroMemory(&wcad, sizeof(wcad));

View File

@ -67,7 +67,7 @@ void WinVerHelper::initialize()
return;
}
for (int i = 0; i != size; ++i) {
m_flags.at(i) = (i <= no);
m_flags[i] = (i <= no);
}
};
#define ELIF(Version) \

View File

@ -22,6 +22,8 @@
SOFTWARE.
]]
include(GNUInstallDirs)
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
@ -258,7 +260,6 @@ target_link_libraries(${SUB_MODULE_TARGET} PUBLIC
${PROJECT_NAME}::Core
)
include(GNUInstallDirs)
target_include_directories(${SUB_MODULE_TARGET} PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_PREFIX}/../..>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_PREFIX}>"
@ -268,13 +269,8 @@ target_include_directories(${SUB_MODULE_TARGET} PUBLIC
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${SUB_MODULE_PATH}/private>"
)
if(NOT FRAMELESSHELPER_BUILD_STATIC)
setup_target_rpaths(TARGETS ${SUB_MODULE_TARGET})
endif()
setup_qt_stuff(TARGETS ${SUB_MODULE_TARGET} ALLOW_KEYWORD)
set(__extra_flags "")
set(__extra_flags)
if(NOT FRAMELESSHELPER_NO_PERMISSIVE_CHECKS)
list(APPEND __extra_flags PERMISSIVE)
endif()
@ -297,7 +293,6 @@ if(FRAMELESSHELPER_FORCE_LTO)
list(APPEND __extra_flags FORCE_LTO)
endif()
setup_compile_params(TARGETS ${SUB_MODULE_TARGET} ${__extra_flags})
if(NOT FRAMELESSHELPER_NO_INSTALL)
setup_package_export(
TARGETS ${__export_targets}

View File

@ -53,7 +53,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcFramelessQuickHelper, "wangwenx190.framelesshelper.quick.framelessquickhelper")
static Q_LOGGING_CATEGORY(lcFramelessQuickHelper, "wangwenx190.framelesshelper.quick.framelessquickhelper")
#ifdef FRAMELESSHELPER_QUICK_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -69,7 +69,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
using namespace Global;
struct FramelessQuickHelperData
struct QuickHelperData
{
bool ready = false;
SystemParameters params = {};
@ -83,9 +83,12 @@ struct FramelessQuickHelperData
QList<QRect> hitTestVisibleRects = {};
};
using FramelessQuickHelperInternal = QHash<WId, FramelessQuickHelperData>;
struct QuickHelper
{
QHash<WId, QuickHelperData> data = {};
};
Q_GLOBAL_STATIC(FramelessQuickHelperInternal, g_framelessQuickHelperData)
Q_GLOBAL_STATIC(QuickHelper, g_quickHelper)
FramelessQuickHelperPrivate::FramelessQuickHelperPrivate(FramelessQuickHelper *q) : QObject(q)
{
@ -125,8 +128,7 @@ const FramelessQuickHelperPrivate *FramelessQuickHelperPrivate::get(const Framel
bool FramelessQuickHelperPrivate::isContentExtendedIntoTitleBar() const
{
const FramelessQuickHelperData *data = getWindowData();
return (data ? data->ready : false);
return getWindowData().ready;
}
void FramelessQuickHelperPrivate::extendsContentIntoTitleBar(const bool value)
@ -147,8 +149,7 @@ void FramelessQuickHelperPrivate::extendsContentIntoTitleBar(const bool value)
QQuickItem *FramelessQuickHelperPrivate::getTitleBarItem() const
{
const FramelessQuickHelperData *data = getWindowData();
return (data ? data->titleBarItem : nullptr);
return getWindowData().titleBarItem;
}
void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
@ -157,8 +158,11 @@ void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
if (!value) {
return;
}
FramelessQuickHelperData *data = getWindowDataMutable();
if (!data || (data->titleBarItem == value)) {
QuickHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
if (data->titleBarItem == value) {
return;
}
data->titleBarItem = value;
@ -174,7 +178,7 @@ void FramelessQuickHelperPrivate::attach()
return;
}
FramelessQuickHelperData * const data = getWindowDataMutable();
QuickHelperData * const data = getWindowDataMutable();
if (!data || data->ready) {
return;
}
@ -226,7 +230,7 @@ void FramelessQuickHelperPrivate::attach()
// we reach here, and all the modifications from the Qt side will be lost
// due to QPA will reset the position and size of the window during it's
// initialization process.
QTimer::singleShot(m_qpaWaitTime, this, [this](){
QTimer::singleShot(0, this, [this](){
m_qpaReady = true;
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
moveWindowToDesktopCenter();
@ -246,11 +250,10 @@ void FramelessQuickHelperPrivate::detach()
return;
}
const WId windowId = w->winId();
const auto it = g_framelessQuickHelperData()->constFind(windowId);
if (it == g_framelessQuickHelperData()->constEnd()) {
if (!g_quickHelper()->data.contains(windowId)) {
return;
}
g_framelessQuickHelperData()->erase(it);
g_quickHelper()->data.remove(windowId);
FramelessManager::instance()->removeWindow(windowId);
}
@ -261,7 +264,7 @@ void FramelessQuickHelperPrivate::setSystemButton(QQuickItem *item, const QuickG
if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
return;
}
FramelessQuickHelperData *data = getWindowDataMutable();
QuickHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
@ -293,13 +296,15 @@ void FramelessQuickHelperPrivate::setHitTestVisible(QQuickItem *item, const bool
if (!item) {
return;
}
FramelessQuickHelperData *data = getWindowDataMutable();
QuickHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
if (visible) {
const bool exists = data->hitTestVisibleItems.contains(item);
if (visible && !exists) {
data->hitTestVisibleItems.append(item);
} else {
}
if (!visible && exists) {
data->hitTestVisibleItems.removeAll(item);
}
}
@ -310,13 +315,15 @@ void FramelessQuickHelperPrivate::setHitTestVisible(const QRect &rect, const boo
if (!rect.isValid()) {
return;
}
FramelessQuickHelperData *data = getWindowDataMutable();
QuickHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
if (visible) {
const bool exists = data->hitTestVisibleRects.contains(rect);
if (visible && !exists) {
data->hitTestVisibleRects.append(rect);
} else {
}
if (!visible && exists) {
data->hitTestVisibleRects.removeAll(rect);
}
}
@ -345,7 +352,8 @@ void FramelessQuickHelperPrivate::showSystemMenu(const QPoint &pos)
const WId windowId = window->winId();
const QPoint nativePos = Utils::toNativeGlobalPosition(window, pos);
#ifdef Q_OS_WINDOWS
Utils::showSystemMenu(windowId, nativePos, false, &getWindowData()->params);
const SystemParameters params = getWindowData().params;
Utils::showSystemMenu(windowId, nativePos, false, &params);
#elif defined(Q_OS_LINUX)
Utils::openSystemMenu(windowId, nativePos);
#else
@ -384,7 +392,8 @@ void FramelessQuickHelperPrivate::moveWindowToDesktopCenter()
if (!window) {
return;
}
Utils::moveWindowToDesktopCenter(&getWindowData()->params, true);
const SystemParameters params = getWindowData().params;
Utils::moveWindowToDesktopCenter(&params, true);
}
void FramelessQuickHelperPrivate::bringWindowToFront()
@ -668,7 +677,7 @@ void FramelessQuickHelperPrivate::waitForReady()
#endif
}
void FramelessQuickHelperPrivate::repaintAllChildren(const quint32 delay) const
void FramelessQuickHelperPrivate::repaintAllChildren(const int delay) const
{
Q_Q(const FramelessQuickHelper);
QQuickWindow * const window = q->window();
@ -700,19 +709,6 @@ void FramelessQuickHelperPrivate::repaintAllChildren(const quint32 delay) const
}
}
quint32 FramelessQuickHelperPrivate::readyWaitTime() const
{
return m_qpaWaitTime;
}
void FramelessQuickHelperPrivate::setReadyWaitTime(const quint32 time)
{
if (m_qpaWaitTime == time) {
return;
}
m_qpaWaitTime = time;
}
QRect FramelessQuickHelperPrivate::mapItemGeometryToScene(const QQuickItem * const item) const
{
Q_ASSERT(item);
@ -734,37 +730,34 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
if (!button) {
return false;
}
const FramelessQuickHelperData *data = getWindowData();
if (!data) {
return false;
}
*button = QuickGlobal::SystemButtonType::Unknown;
if (data->windowIconButton && data->windowIconButton->isVisible() && data->windowIconButton->isEnabled()) {
if (mapItemGeometryToScene(data->windowIconButton).contains(pos)) {
const QuickHelperData data = getWindowData();
if (data.windowIconButton && data.windowIconButton->isVisible() && data.windowIconButton->isEnabled()) {
if (mapItemGeometryToScene(data.windowIconButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::WindowIcon;
return true;
}
}
if (data->contextHelpButton && data->contextHelpButton->isVisible() && data->contextHelpButton->isEnabled()) {
if (mapItemGeometryToScene(data->contextHelpButton).contains(pos)) {
if (data.contextHelpButton && data.contextHelpButton->isVisible() && data.contextHelpButton->isEnabled()) {
if (mapItemGeometryToScene(data.contextHelpButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Help;
return true;
}
}
if (data->minimizeButton && data->minimizeButton->isVisible() && data->minimizeButton->isEnabled()) {
if (mapItemGeometryToScene(data->minimizeButton).contains(pos)) {
if (data.minimizeButton && data.minimizeButton->isVisible() && data.minimizeButton->isEnabled()) {
if (mapItemGeometryToScene(data.minimizeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Minimize;
return true;
}
}
if (data->maximizeButton && data->maximizeButton->isVisible() && data->maximizeButton->isEnabled()) {
if (mapItemGeometryToScene(data->maximizeButton).contains(pos)) {
if (data.maximizeButton && data.maximizeButton->isVisible() && data.maximizeButton->isEnabled()) {
if (mapItemGeometryToScene(data.maximizeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Maximize;
return true;
}
}
if (data->closeButton && data->closeButton->isVisible() && data->closeButton->isEnabled()) {
if (mapItemGeometryToScene(data->closeButton).contains(pos)) {
if (data.closeButton && data.closeButton->isVisible() && data.closeButton->isEnabled()) {
if (mapItemGeometryToScene(data.closeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Close;
return true;
}
@ -774,15 +767,12 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
{
const FramelessQuickHelperData *data = getWindowData();
if (!data) {
return false;
}
if (!data->titleBarItem) {
const QuickHelperData data = getWindowData();
if (!data.titleBarItem) {
// There's no title bar at all, the mouse will always be in the client area.
return false;
}
if (!data->titleBarItem->isVisible() || !data->titleBarItem->isEnabled()) {
if (!data.titleBarItem->isVisible() || !data.titleBarItem->isEnabled()) {
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
return false;
}
@ -794,32 +784,29 @@ bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) c
return false;
}
const QRect windowRect = {QPoint(0, 0), window->size()};
const QRect titleBarRect = mapItemGeometryToScene(data->titleBarItem);
const QRect titleBarRect = mapItemGeometryToScene(data.titleBarItem);
if (!titleBarRect.intersects(windowRect)) {
// The title bar is totally outside of the window for some reason,
// also treat it as there's no title bar.
return false;
}
QRegion region = titleBarRect;
const auto systemButtons = {
data->windowIconButton, data->contextHelpButton,
data->minimizeButton, data->maximizeButton,
data->closeButton
};
const auto systemButtons = {data.windowIconButton, data.contextHelpButton,
data.minimizeButton, data.maximizeButton, data.closeButton};
for (auto &&button : std::as_const(systemButtons)) {
if (button && button->isVisible() && button->isEnabled()) {
region -= mapItemGeometryToScene(button);
}
}
if (!data->hitTestVisibleItems.isEmpty()) {
for (auto &&item : std::as_const(data->hitTestVisibleItems)) {
if (!data.hitTestVisibleItems.isEmpty()) {
for (auto &&item : std::as_const(data.hitTestVisibleItems)) {
if (item && item->isVisible() && item->isEnabled()) {
region -= mapItemGeometryToScene(item);
}
}
}
if (!data->hitTestVisibleRects.isEmpty()) {
for (auto &&rect : std::as_const(data->hitTestVisibleRects)) {
if (!data.hitTestVisibleRects.isEmpty()) {
for (auto &&rect : std::as_const(data.hitTestVisibleRects)) {
if (rect.isValid()) {
region -= rect;
}
@ -861,44 +848,41 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
if (button == QuickGlobal::SystemButtonType::Unknown) {
return;
}
const FramelessQuickHelperData *data = getWindowData();
if (!data) {
return;
}
const QuickHelperData data = getWindowData();
QQuickAbstractButton *quickButton = nullptr;
switch (button) {
case QuickGlobal::SystemButtonType::WindowIcon:
if (data->windowIconButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data->windowIconButton)) {
if (data.windowIconButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.windowIconButton)) {
quickButton = btn;
}
}
break;
case QuickGlobal::SystemButtonType::Help:
if (data->contextHelpButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data->contextHelpButton)) {
if (data.contextHelpButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.contextHelpButton)) {
quickButton = btn;
}
}
break;
case QuickGlobal::SystemButtonType::Minimize:
if (data->minimizeButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data->minimizeButton)) {
if (data.minimizeButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.minimizeButton)) {
quickButton = btn;
}
}
break;
case QuickGlobal::SystemButtonType::Maximize:
case QuickGlobal::SystemButtonType::Restore:
if (data->maximizeButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data->maximizeButton)) {
if (data.maximizeButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.maximizeButton)) {
quickButton = btn;
}
}
break;
case QuickGlobal::SystemButtonType::Close:
if (data->closeButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data->closeButton)) {
if (data.closeButton) {
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.closeButton)) {
quickButton = btn;
}
}
@ -939,23 +923,22 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE
}
const FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowData() const
QuickHelperData FramelessQuickHelperPrivate::getWindowData() const
{
Q_Q(const FramelessQuickHelper);
const QQuickWindow * const window = q->window();
//Q_ASSERT(window);
if (!window) {
return nullptr;
return {};
}
const WId windowId = window->winId();
auto it = g_framelessQuickHelperData()->find(windowId);
if (it == g_framelessQuickHelperData()->end()) {
it = g_framelessQuickHelperData()->insert(windowId, {});
if (!g_quickHelper()->data.contains(windowId)) {
g_quickHelper()->data.insert(windowId, {});
}
return &it.value();
return g_quickHelper()->data.value(windowId);
}
FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowDataMutable() const
QuickHelperData *FramelessQuickHelperPrivate::getWindowDataMutable() const
{
Q_Q(const FramelessQuickHelper);
const QQuickWindow * const window = q->window();
@ -964,11 +947,10 @@ FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowDataMutable() co
return nullptr;
}
const WId windowId = window->winId();
auto it = g_framelessQuickHelperData()->find(windowId);
if (it == g_framelessQuickHelperData()->end()) {
it = g_framelessQuickHelperData()->insert(windowId, {});
if (!g_quickHelper()->data.contains(windowId)) {
g_quickHelper()->data.insert(windowId, {});
}
return &it.value();
return &g_quickHelper()->data[windowId];
}
void FramelessQuickHelperPrivate::rebindWindow()

View File

@ -40,11 +40,11 @@
#include <QtCore/qloggingcategory.h>
#ifndef QUICK_URI_SHORT
# define QUICK_URI_SHORT FRAMELESSHELPER_QUICK_URI, FRAMELESSHELPER_QUICK_VERSION_MAJOR
# define QUICK_URI_SHORT FRAMELESSHELPER_QUICK_URI, 1
#endif
#ifndef QUICK_URI_FULL
# define QUICK_URI_FULL QUICK_URI_SHORT, FRAMELESSHELPER_QUICK_VERSION_MINOR
# define QUICK_URI_FULL QUICK_URI_SHORT, 0
#endif
#ifndef QUICK_URI_EXPAND

View File

@ -32,7 +32,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcQuickImageItem, "wangwenx190.framelesshelper.quick.quickimageitem")
static Q_LOGGING_CATEGORY(lcQuickImageItem, "wangwenx190.framelesshelper.quick.quickimageitem")
#ifdef FRAMELESSHELPER_QUICK_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()

View File

@ -27,7 +27,6 @@
#include <FramelessHelper/Core/micamaterial.h>
#include <FramelessHelper/Core/framelessmanager.h>
#include <FramelessHelper/Core/private/micamaterial_p.h>
#include <memory>
#include <QtCore/qloggingcategory.h>
#include <QtGui/qpainter.h>
#include <QtQuick/qquickwindow.h>
@ -74,7 +73,7 @@ private:
private:
QPointer<QuickMicaMaterial> m_item = nullptr;
std::unique_ptr<QSGSimpleTextureNode> m_node = nullptr;
QSGSimpleTextureNode *m_node = nullptr;
std::unique_ptr<QSGTexture> m_texture = nullptr;
QPointer<MicaMaterial> m_mica{ nullptr };
QPointer<MicaMaterialPrivate> m_micaPriv{ nullptr };
@ -102,13 +101,14 @@ void WallpaperImageNode::initialize()
m_mica = QuickMicaMaterialPrivate::get(m_item)->m_micaMaterial;
m_micaPriv = MicaMaterialPrivate::get(m_mica);
m_node = std::make_unique<QSGSimpleTextureNode>();
// QtQuick's render engine will free it when appropriate.
m_node = new QSGSimpleTextureNode;
m_node->setFiltering(QSGTexture::Linear);
maybeGenerateWallpaperImageCache();
maybeUpdateWallpaperImageClipRect();
appendChildNode(m_node.get());
appendChildNode(m_node);
connect(m_window, &QQuickWindow::beforeRendering, this,
&WallpaperImageNode::maybeUpdateWallpaperImageClipRect, Qt::DirectConnection);
@ -178,14 +178,9 @@ void QuickMicaMaterialPrivate::initialize()
{
Q_Q(QuickMicaMaterial);
// Without this flag, our QQuickItem won't paint anything.
// We MUST enable this flag manually if we want to create a visible item.
q->setFlag(QuickMicaMaterial::ItemHasContents);
// No smooth needed.
q->setSmooth(false);
// We don't need anti-aliasing.
q->setAntialiasing(false);
// Enable clipping, to improve performance in some certain cases.
q->setSmooth(true);
q->setAntialiasing(true);
q->setClip(true);
m_micaMaterial = new MicaMaterial(this);
@ -265,6 +260,9 @@ void QuickMicaMaterialPrivate::appendNode(WallpaperImageNode *node)
if (!node) {
return;
}
if (m_nodes.contains(node)) {
return;
}
m_nodes.append(node);
}
@ -274,6 +272,9 @@ void QuickMicaMaterialPrivate::removeNode(WallpaperImageNode *node)
if (!node) {
return;
}
if (!m_nodes.contains(node)) {
return;
}
m_nodes.removeAll(node);
}

View File

@ -41,7 +41,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcQuickStandardTitleBar, "wangwenx190.framelesshelper.quick.quickstandardtitlebar")
static Q_LOGGING_CATEGORY(lcQuickStandardTitleBar, "wangwenx190.framelesshelper.quick.quickstandardtitlebar")
#ifdef FRAMELESSHELPER_QUICK_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()

View File

@ -22,6 +22,8 @@
SOFTWARE.
]]
include(GNUInstallDirs)
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
@ -145,7 +147,6 @@ target_link_libraries(${SUB_MODULE_TARGET} PUBLIC
${PROJECT_NAME}::Core
)
include(GNUInstallDirs)
target_include_directories(${SUB_MODULE_TARGET} PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_PREFIX}/../..>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_PREFIX}>"
@ -155,13 +156,8 @@ target_include_directories(${SUB_MODULE_TARGET} PUBLIC
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${SUB_MODULE_PATH}/private>"
)
if(NOT FRAMELESSHELPER_BUILD_STATIC)
setup_target_rpaths(TARGETS ${SUB_MODULE_TARGET})
endif()
setup_qt_stuff(TARGETS ${SUB_MODULE_TARGET})
set(__extra_flags "")
set(__extra_flags)
if(NOT FRAMELESSHELPER_NO_PERMISSIVE_CHECKS)
list(APPEND __extra_flags PERMISSIVE)
endif()
@ -184,7 +180,6 @@ if(FRAMELESSHELPER_FORCE_LTO)
list(APPEND __extra_flags FORCE_LTO)
endif()
setup_compile_params(TARGETS ${SUB_MODULE_TARGET} ${__extra_flags})
if(NOT FRAMELESSHELPER_NO_INSTALL)
setup_package_export(
TARGETS ${SUB_MODULE_TARGET}

View File

@ -49,7 +49,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcFramelessWidgetsHelper, "wangwenx190.framelesshelper.widgets.framelesswidgetshelper")
static Q_LOGGING_CATEGORY(lcFramelessWidgetsHelper, "wangwenx190.framelesshelper.widgets.framelesswidgetshelper")
#ifdef FRAMELESSHELPER_WIDGETS_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()
@ -65,7 +65,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
using namespace Global;
struct FramelessWidgetsHelperData
struct WidgetsHelperData
{
bool ready = false;
SystemParameters params = {};
@ -79,9 +79,12 @@ struct FramelessWidgetsHelperData
QList<QRect> hitTestVisibleRects = {};
};
using FramelessWidgetsHelperInternal = QHash<WId, FramelessWidgetsHelperData>;
struct WidgetsHelper
{
QHash<WId, WidgetsHelperData> data = {};
};
Q_GLOBAL_STATIC(FramelessWidgetsHelperInternal, g_framelessWidgetsHelperData)
Q_GLOBAL_STATIC(WidgetsHelper, g_widgetsHelper)
[[nodiscard]] static inline bool isWidgetFixedSize(const QWidget * const widget)
{
@ -405,7 +408,7 @@ void FramelessWidgetsHelperPrivate::waitForReady()
#endif
}
void FramelessWidgetsHelperPrivate::repaintAllChildren(const quint32 delay) const
void FramelessWidgetsHelperPrivate::repaintAllChildren(const int delay) const
{
if (!m_window) {
return;
@ -427,23 +430,9 @@ void FramelessWidgetsHelperPrivate::repaintAllChildren(const quint32 delay) cons
}
}
quint32 FramelessWidgetsHelperPrivate::readyWaitTime() const
{
return m_qpaWaitTime;
}
void FramelessWidgetsHelperPrivate::setReadyWaitTime(const quint32 time)
{
if (m_qpaWaitTime == time) {
return;
}
m_qpaWaitTime = time;
}
bool FramelessWidgetsHelperPrivate::isContentExtendedIntoTitleBar() const
{
const FramelessWidgetsHelperData *data = getWindowData();
return (data ? data->ready : false);
return getWindowData().ready;
}
void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
@ -452,8 +441,11 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
if (!widget) {
return;
}
FramelessWidgetsHelperData *data = getWindowDataMutable();
if (!data || (data->titleBarWidget == widget)) {
WidgetsHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
if (data->titleBarWidget == widget) {
return;
}
data->titleBarWidget = widget;
@ -462,8 +454,7 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const
{
const FramelessWidgetsHelperData *data = getWindowData();
return (data ? data->titleBarWidget : nullptr);
return getWindowData().titleBarWidget;
}
void FramelessWidgetsHelperPrivate::setHitTestVisible(QWidget *widget, const bool visible)
@ -472,13 +463,15 @@ void FramelessWidgetsHelperPrivate::setHitTestVisible(QWidget *widget, const boo
if (!widget) {
return;
}
FramelessWidgetsHelperData *data = getWindowDataMutable();
WidgetsHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
if (visible) {
const bool exists = data->hitTestVisibleWidgets.contains(widget);
if (visible && !exists) {
data->hitTestVisibleWidgets.append(widget);
} else {
}
if (!visible && exists) {
data->hitTestVisibleWidgets.removeAll(widget);
}
}
@ -489,13 +482,15 @@ void FramelessWidgetsHelperPrivate::setHitTestVisible(const QRect &rect, const b
if (!rect.isValid()) {
return;
}
FramelessWidgetsHelperData *data = getWindowDataMutable();
WidgetsHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
if (visible) {
const bool exists = data->hitTestVisibleRects.contains(rect);
if (visible && !exists) {
data->hitTestVisibleRects.append(rect);
} else {
}
if (!visible && exists) {
data->hitTestVisibleRects.removeAll(rect);
}
}
@ -533,7 +528,7 @@ void FramelessWidgetsHelperPrivate::attach()
window->setAttribute(Qt::WA_NativeWindow);
}
FramelessWidgetsHelperData * const data = getWindowDataMutable();
WidgetsHelperData * const data = getWindowDataMutable();
if (!data || data->ready) {
return;
}
@ -583,7 +578,7 @@ void FramelessWidgetsHelperPrivate::attach()
// we reach here, and all the modifications from the Qt side will be lost
// due to QPA will reset the position and size of the window during it's
// initialization process.
QTimer::singleShot(m_qpaWaitTime, this, [this](){
QTimer::singleShot(0, this, [this](){
m_qpaReady = true;
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
moveWindowToDesktopCenter();
@ -602,11 +597,10 @@ void FramelessWidgetsHelperPrivate::detach()
return;
}
const WId windowId = m_window->winId();
const auto it = g_framelessWidgetsHelperData()->constFind(windowId);
if (it == g_framelessWidgetsHelperData()->constEnd()) {
if (!g_widgetsHelper()->data.contains(windowId)) {
return;
}
g_framelessWidgetsHelperData()->erase(it);
g_widgetsHelper()->data.remove(windowId);
FramelessManager::instance()->removeWindow(windowId);
m_window = nullptr;
emitSignalForAllInstances("windowChanged");
@ -640,32 +634,30 @@ QWidget *FramelessWidgetsHelperPrivate::findTopLevelWindow() const
return nullptr;
}
const FramelessWidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowData() const
WidgetsHelperData FramelessWidgetsHelperPrivate::getWindowData() const
{
//Q_ASSERT(m_window);
if (!m_window) {
return nullptr;
return {};
}
const WId windowId = m_window->winId();
auto it = g_framelessWidgetsHelperData()->find(windowId);
if (it == g_framelessWidgetsHelperData()->end()) {
it = g_framelessWidgetsHelperData()->insert(windowId, {});
if (!g_widgetsHelper()->data.contains(windowId)) {
g_widgetsHelper()->data.insert(windowId, {});
}
return &it.value();
return g_widgetsHelper()->data.value(windowId);
}
FramelessWidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowDataMutable() const
WidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowDataMutable() const
{
//Q_ASSERT(m_window);
if (!m_window) {
return nullptr;
}
const WId windowId = m_window->winId();
auto it = g_framelessWidgetsHelperData()->find(windowId);
if (it == g_framelessWidgetsHelperData()->end()) {
it = g_framelessWidgetsHelperData()->insert(windowId, {});
if (!g_widgetsHelper()->data.contains(windowId)) {
g_widgetsHelper()->data.insert(windowId, {});
}
return &it.value();
return &g_widgetsHelper()->data[windowId];
}
QRect FramelessWidgetsHelperPrivate::mapWidgetGeometryToScene(const QWidget * const widget) const
@ -688,37 +680,34 @@ bool FramelessWidgetsHelperPrivate::isInSystemButtons(const QPoint &pos, SystemB
if (!button) {
return false;
}
const FramelessWidgetsHelperData *data = getWindowData();
if (!data) {
return false;
}
*button = SystemButtonType::Unknown;
if (data->windowIconButton && data->windowIconButton->isVisible() && data->windowIconButton->isEnabled()) {
if (data->windowIconButton->geometry().contains(pos)) {
const WidgetsHelperData data = getWindowData();
if (data.windowIconButton && data.windowIconButton->isVisible() && data.windowIconButton->isEnabled()) {
if (data.windowIconButton->geometry().contains(pos)) {
*button = SystemButtonType::WindowIcon;
return true;
}
}
if (data->contextHelpButton && data->contextHelpButton->isVisible() && data->contextHelpButton->isEnabled()) {
if (data->contextHelpButton->geometry().contains(pos)) {
if (data.contextHelpButton && data.contextHelpButton->isVisible() && data.contextHelpButton->isEnabled()) {
if (data.contextHelpButton->geometry().contains(pos)) {
*button = SystemButtonType::Help;
return true;
}
}
if (data->minimizeButton && data->minimizeButton->isVisible() && data->minimizeButton->isEnabled()) {
if (data->minimizeButton->geometry().contains(pos)) {
if (data.minimizeButton && data.minimizeButton->isVisible() && data.minimizeButton->isEnabled()) {
if (data.minimizeButton->geometry().contains(pos)) {
*button = SystemButtonType::Minimize;
return true;
}
}
if (data->maximizeButton && data->maximizeButton->isVisible() && data->maximizeButton->isEnabled()) {
if (data->maximizeButton->geometry().contains(pos)) {
if (data.maximizeButton && data.maximizeButton->isVisible() && data.maximizeButton->isEnabled()) {
if (data.maximizeButton->geometry().contains(pos)) {
*button = SystemButtonType::Maximize;
return true;
}
}
if (data->closeButton && data->closeButton->isVisible() && data->closeButton->isEnabled()) {
if (data->closeButton->geometry().contains(pos)) {
if (data.closeButton && data.closeButton->isVisible() && data.closeButton->isEnabled()) {
if (data.closeButton->geometry().contains(pos)) {
*button = SystemButtonType::Close;
return true;
}
@ -728,15 +717,12 @@ bool FramelessWidgetsHelperPrivate::isInSystemButtons(const QPoint &pos, SystemB
bool FramelessWidgetsHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
{
const FramelessWidgetsHelperData *data = getWindowData();
if (!data) {
return false;
}
if (!data->titleBarWidget) {
const WidgetsHelperData data = getWindowData();
if (!data.titleBarWidget) {
// There's no title bar at all, the mouse will always be in the client area.
return false;
}
if (!data->titleBarWidget->isVisible() || !data->titleBarWidget->isEnabled()) {
if (!data.titleBarWidget->isVisible() || !data.titleBarWidget->isEnabled()) {
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
return false;
}
@ -746,32 +732,29 @@ bool FramelessWidgetsHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos)
return false;
}
const QRect windowRect = {QPoint(0, 0), m_window->size()};
const QRect titleBarRect = mapWidgetGeometryToScene(data->titleBarWidget);
const QRect titleBarRect = mapWidgetGeometryToScene(data.titleBarWidget);
if (!titleBarRect.intersects(windowRect)) {
// The title bar is totally outside of the window for some reason,
// also treat it as there's no title bar.
return false;
}
QRegion region = titleBarRect;
const auto systemButtons = {
data->windowIconButton, data->contextHelpButton,
data->minimizeButton, data->maximizeButton,
data->closeButton
};
const auto systemButtons = {data.windowIconButton, data.contextHelpButton,
data.minimizeButton, data.maximizeButton, data.closeButton};
for (auto &&button : std::as_const(systemButtons)) {
if (button && button->isVisible() && button->isEnabled()) {
region -= mapWidgetGeometryToScene(button);
}
}
if (!data->hitTestVisibleWidgets.isEmpty()) {
for (auto &&widget : std::as_const(data->hitTestVisibleWidgets)) {
if (!data.hitTestVisibleWidgets.isEmpty()) {
for (auto &&widget : std::as_const(data.hitTestVisibleWidgets)) {
if (widget && widget->isVisible() && widget->isEnabled()) {
region -= mapWidgetGeometryToScene(widget);
}
}
}
if (!data->hitTestVisibleRects.isEmpty()) {
for (auto &&rect : std::as_const(data->hitTestVisibleRects)) {
if (!data.hitTestVisibleRects.isEmpty()) {
for (auto &&rect : std::as_const(data.hitTestVisibleRects)) {
if (rect.isValid()) {
region -= rect;
}
@ -806,36 +789,33 @@ void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType
if (button == SystemButtonType::Unknown) {
return;
}
const FramelessWidgetsHelperData *data = getWindowData();
if (!data) {
return;
}
const WidgetsHelperData data = getWindowData();
QWidget *widgetButton = nullptr;
switch (button) {
case SystemButtonType::WindowIcon:
if (data->windowIconButton) {
widgetButton = data->windowIconButton;
if (data.windowIconButton) {
widgetButton = data.windowIconButton;
}
break;
case SystemButtonType::Help:
if (data->contextHelpButton) {
widgetButton = data->contextHelpButton;
if (data.contextHelpButton) {
widgetButton = data.contextHelpButton;
}
break;
case SystemButtonType::Minimize:
if (data->minimizeButton) {
widgetButton = data->minimizeButton;
if (data.minimizeButton) {
widgetButton = data.minimizeButton;
}
break;
case SystemButtonType::Maximize:
case SystemButtonType::Restore:
if (data->maximizeButton) {
widgetButton = data->maximizeButton;
if (data.maximizeButton) {
widgetButton = data.maximizeButton;
}
break;
case SystemButtonType::Close:
if (data->closeButton) {
widgetButton = data->closeButton;
if (data.closeButton) {
widgetButton = data.closeButton;
}
break;
case SystemButtonType::Unknown:
@ -886,7 +866,8 @@ void FramelessWidgetsHelperPrivate::moveWindowToDesktopCenter()
if (!m_window) {
return;
}
Utils::moveWindowToDesktopCenter(&getWindowData()->params, true);
const SystemParameters params = getWindowData().params;
Utils::moveWindowToDesktopCenter(&params, true);
}
void FramelessWidgetsHelperPrivate::bringWindowToFront()
@ -916,7 +897,8 @@ void FramelessWidgetsHelperPrivate::showSystemMenu(const QPoint &pos)
const WId windowId = m_window->winId();
const QPoint nativePos = Utils::toNativeGlobalPosition(m_window->windowHandle(), pos);
#ifdef Q_OS_WINDOWS
Utils::showSystemMenu(windowId, nativePos, false, &getWindowData()->params);
const SystemParameters params = getWindowData().params;
Utils::showSystemMenu(windowId, nativePos, false, &params);
#elif defined(Q_OS_LINUX)
Utils::openSystemMenu(windowId, nativePos);
#else
@ -951,7 +933,7 @@ void FramelessWidgetsHelperPrivate::setSystemButton(QWidget *widget, const Syste
if (!widget || (buttonType == SystemButtonType::Unknown)) {
return;
}
FramelessWidgetsHelperData *data = getWindowDataMutable();
WidgetsHelperData *data = getWindowDataMutable();
if (!data) {
return;
}

View File

@ -177,7 +177,6 @@ void StandardSystemButtonPrivate::setHovered(const bool value)
m_hovered = value;
Q_Q(StandardSystemButton);
q->update();
#if 0
if (m_hovered) {
const QString toolTip = q->toolTip();
if (!toolTip.isEmpty() && !QToolTip::isVisible()) {
@ -185,10 +184,10 @@ void StandardSystemButtonPrivate::setHovered(const bool value)
static const int h = kDefaultSystemButtonSize.height();
if (const QWidget * const window = q->window()) {
if (Utils::windowStatesToWindowState(window->windowState()) == Qt::WindowMaximized) {
return std::round(qreal(h) * qreal(0.5));
return std::round(h * 0.5);
}
}
return -std::round(qreal(h) * qreal(1.3));
return -std::round(h * 1.3);
}();
QToolTip::showText(q->mapToGlobal(QPoint(-2, yPos)), toolTip, q, q->geometry());
}
@ -197,7 +196,6 @@ void StandardSystemButtonPrivate::setHovered(const bool value)
QToolTip::hideText();
}
}
#endif
Q_EMIT q->hoveredChanged();
}

View File

@ -37,7 +37,7 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
[[maybe_unused]] static Q_LOGGING_CATEGORY(lcStandardTitleBar, "wangwenx190.framelesshelper.widgets.standardtitlebar")
static Q_LOGGING_CATEGORY(lcStandardTitleBar, "wangwenx190.framelesshelper.widgets.standardtitlebar")
#ifdef FRAMELESSHELPER_WIDGETS_NO_DEBUG_OUTPUT
# define INFO QT_NO_QDEBUG_MACRO()

View File

@ -240,7 +240,7 @@ void WidgetsSharedHelper::handleScreenChanged(QScreen *screen)
this, [this](const qreal dpi){
Q_UNUSED(dpi);
const qreal currentDpr = m_screen->devicePixelRatio();
if (qFuzzyCompare(m_screenDpr, currentDpr)) {
if (m_screenDpr == currentDpr) {
return;
}
m_screenDpr = currentDpr;