cleanup & optimize, part 2

The file size of FramelessHelper binaries should be smaller than before. Core: Win32 MSVC2022 x64 release build, -20KB
The general performance should be improved, due to double lookups are all eliminated.
This commit is contained in:
Yuhang Zhao 2023-07-30 18:28:38 +08:00
parent 20ab4f7d4b
commit 86bc1c0142
23 changed files with 289 additions and 223 deletions

View File

@ -28,13 +28,11 @@
#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;
@ -292,7 +290,8 @@ enum class Option : quint8
EnableBlurBehindWindow,
ForceNonNativeBackgroundBlur,
DisableLazyInitializationForMicaMaterial,
ForceNativeBackgroundBlur
ForceNativeBackgroundBlur,
Last = ForceNativeBackgroundBlur
};
Q_ENUM_NS(Option)
@ -313,7 +312,8 @@ enum class SystemButtonType : quint8
Minimize,
Maximize,
Restore,
Close
Close,
Last = Close
};
Q_ENUM_NS(SystemButtonType)

View File

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

View File

@ -25,6 +25,7 @@
#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;
using Transform = struct Transform
struct Transform
{
qreal Horizontal = 0;
qreal Vertical = 0;

View File

@ -25,6 +25,7 @@
#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, 27> WindowsVersions =
[[maybe_unused]] inline constexpr const std::array<VersionNumber, static_cast<int>(Global::WindowsVersion::Latest) + 1> WindowsVersions =
{
VersionNumber{ 5, 0, 2195 }, // Windows 2000
VersionNumber{ 5, 1, 2600 }, // Windows XP

View File

@ -74,6 +74,8 @@
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 QuickHelperData;
struct FramelessQuickHelperData;
class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
{
@ -89,7 +89,10 @@ public:
Q_NODISCARD bool isReady() const;
void waitForReady();
void repaintAllChildren(const int delay = 0) const;
void repaintAllChildren(const quint32 delay = 0) const;
Q_NODISCARD quint32 readyWaitTime() const;
void setReadyWaitTime(const quint32 time);
private:
Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
@ -97,8 +100,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 QuickHelperData getWindowData() const;
Q_NODISCARD QuickHelperData *getWindowDataMutable() const;
Q_NODISCARD const FramelessQuickHelperData *getWindowData() const;
Q_NODISCARD FramelessQuickHelperData *getWindowDataMutable() const;
void rebindWindow();
private:
@ -108,6 +111,7 @@ 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 WidgetsHelperData;
struct FramelessWidgetsHelperData;
class WidgetsSharedHelper;
class MicaMaterial;
class WindowBorderPainter;
@ -90,7 +90,10 @@ public:
Q_NODISCARD bool isReady() const;
void waitForReady();
void repaintAllChildren(const int delay = 0) const;
void repaintAllChildren(const quint32 delay = 0) const;
Q_NODISCARD quint32 readyWaitTime() const;
void setReadyWaitTime(const quint32 time);
private:
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
@ -99,8 +102,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 WidgetsHelperData getWindowData() const;
Q_NODISCARD WidgetsHelperData *getWindowDataMutable() const;
Q_NODISCARD const FramelessWidgetsHelperData *getWindowData() const;
Q_NODISCARD FramelessWidgetsHelperData *getWindowDataMutable() const;
private:
FramelessWidgetsHelper *q_ptr = nullptr;
@ -110,6 +113,7 @@ private:
bool m_destroying = false;
bool m_qpaReady = false;
QSizePolicy m_savedSizePolicy = {};
quint32 m_qpaWaitTime = 0;
};
FRAMELESSHELPER_END_NAMESPACE

View File

@ -24,6 +24,7 @@
#include "framelessconfig_p.h"
#include <array>
#include <memory>
#include <QtCore/qdir.h>
#include <QtCore/qsettings.h>
#include <QtCore/qcoreapplication.h>
@ -54,7 +55,7 @@ struct FramelessConfigEntry
const char *cfg = nullptr;
};
static constexpr const std::array<FramelessConfigEntry, 10> FramelessOptionsTable =
static constexpr const std::array<FramelessConfigEntry, static_cast<int>(Option::Last) + 1> FramelessOptionsTable =
{
FramelessConfigEntry{ "FRAMELESSHELPER_USE_CROSS_PLATFORM_QT_IMPLEMENTATION", "Options/UseCrossPlatformQtImplementation" },
FramelessConfigEntry{ "FRAMELESSHELPER_FORCE_HIDE_WINDOW_FRAME_BORDER", "Options/ForceHideWindowFrameBorder" },
@ -73,7 +74,7 @@ static constexpr const auto OptionCount = std::size(FramelessOptionsTable);
struct FramelessConfigData
{
bool loaded = false;
bool options[OptionCount] = {};
std::array<bool, OptionCount> options = {};
bool disableEnvVar = false;
bool disableCfgFile = false;
};
@ -139,7 +140,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[i] = (envVar || cfgFile);
g_framelessConfigData()->options.at(i) = (envVar || cfgFile);
}
g_framelessConfigData()->loaded = true;
@ -148,12 +149,12 @@ void FramelessConfig::reload(const bool force)
void FramelessConfig::set(const Option option, const bool on)
{
g_framelessConfigData()->options[static_cast<int>(option)] = on;
g_framelessConfigData()->options.at(static_cast<int>(option)) = on;
}
bool FramelessConfig::isSet(const Option option) const
{
return g_framelessConfigData()->options[static_cast<int>(option)];
return g_framelessConfigData()->options.at(static_cast<int>(option));
}
void FramelessConfig::setLoadFromEnvironmentVariablesDisabled(const bool on)

View File

@ -58,12 +58,12 @@ struct FramelessQtHelperData
bool leftButtonPressed = false;
};
struct FramelessQtHelper
struct FramelessQtHelperInternal
{
QHash<WId, FramelessQtHelperData> data = {};
};
Q_GLOBAL_STATIC(FramelessQtHelper, g_framelessQtHelperData)
Q_GLOBAL_STATIC(FramelessQtHelperInternal, g_framelessQtHelperData)
FramelessHelperQt::FramelessHelperQt(QObject *parent) : QObject(parent) {}

View File

@ -31,6 +31,7 @@
#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>
@ -96,14 +97,14 @@ struct FramelessWin32HelperData
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
};
struct FramelessWin32Helper
struct FramelessWin32HelperInternal
{
std::unique_ptr<FramelessHelperWin> nativeEventFilter = nullptr;
QHash<WId, FramelessWin32HelperData> data = {};
QHash<WId, WId> fallbackTitleBarToParentWindowMapping = {};
};
Q_GLOBAL_STATIC(FramelessWin32Helper, g_framelessWin32HelperData)
Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
[[nodiscard]] extern bool operator==(const RECT &lhs, const RECT &rhs) noexcept;
[[nodiscard]] extern bool operator!=(const RECT &lhs, const RECT &rhs) noexcept;
@ -497,15 +498,19 @@ 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);
// ### Why do we need an extra resize here?
QTimer::singleShot(200, qApp, [parentWindowId, fallbackTitleBarWindowId, hide](){
std::ignore = resizeFallbackTitleBarWindow(parentWindowId, fallbackTitleBarWindowId, hide);
// 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.";
}
});
return true;
}

View File

@ -29,6 +29,7 @@
#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>

View File

@ -69,7 +69,7 @@ struct FONT_ICON
quint32 Fallback = 0;
};
static constexpr const std::array<FONT_ICON, 7> g_fontIconsTable =
static constexpr const std::array<FONT_ICON, static_cast<int>(SystemButtonType::Last) + 1> g_fontIconsTable =
{
FONT_ICON{ 0x0000, 0x0000 },
FONT_ICON{ 0xE756, 0x0000 },

View File

@ -27,6 +27,8 @@
#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>
@ -467,11 +469,12 @@ private:
#if 0
const auto nswindow = reinterpret_cast<NSWindow *>(obj);
if (!instances.contains(nswindow)) {
const auto it = instances.find(nswindow);
if (it == instances.end()) {
return;
}
NSWindowProxy * const proxy = instances[nswindow];
NSWindowProxy * const proxy = it.value();
if (event.type == NSEventTypeLeftMouseDown) {
proxy->lastMouseDownEvent = event;
QCoreApplication::processEvents();
@ -552,7 +555,8 @@ static inline void cleanupProxy()
if (!windowId) {
return nil;
}
if (!g_macUtilsData()->hash.contains(windowId)) {
auto it = g_macUtilsData()->hash.find(windowId);
if (it == g_macUtilsData()->hash.end()) {
QWindow * const qwindow = Utils::findWindow(windowId);
Q_ASSERT(qwindow);
if (!qwindow) {
@ -564,14 +568,14 @@ static inline void cleanupProxy()
return nil;
}
const auto proxy = new NSWindowProxy(qwindow, nswindow);
g_macUtilsData()->hash.insert(windowId, proxy);
it = g_macUtilsData()->hash.insert(windowId, proxy);
}
static bool cleanerInstalled = false;
if (!cleanerInstalled) {
cleanerInstalled = true;
qAddPostRoutine(cleanupProxy);
}
return g_macUtilsData()->hash.value(windowId);
return it.value();
}
void Utils::setSystemTitleBarVisible(const WId windowId, const bool visible)
@ -733,15 +737,16 @@ void Utils::removeWindowProxy(const WId windowId)
if (!windowId) {
return;
}
if (!g_macUtilsData()->hash.contains(windowId)) {
const auto it = g_macUtilsData()->hash.constFind(windowId);
if (it == g_macUtilsData()->hash.constEnd()) {
return;
}
if (const auto proxy = g_macUtilsData()->hash.value(windowId)) {
if (const auto proxy = it.value()) {
// We'll restore everything to default in the destructor,
// so no need to do it manually here.
delete proxy;
}
g_macUtilsData()->hash.remove(windowId);
g_macUtilsData()->hash.erase(it);
}
QColor Utils::getFrameBorderColor(const bool active)

View File

@ -191,13 +191,13 @@ struct Win32UtilsData
SystemParameters params = {};
};
struct Win32UtilsHelper
struct Win32UtilsInternal
{
QHash<WId, Win32UtilsData> data = {};
QList<WId> micaWindowIds = {};
};
Q_GLOBAL_STATIC(Win32UtilsHelper, g_win32UtilsData)
Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
[[nodiscard]] bool operator==(const RECT &lhs, const RECT &rhs) noexcept
{

View File

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

View File

@ -69,7 +69,7 @@ static Q_LOGGING_CATEGORY(lcFramelessQuickHelper, "wangwenx190.framelesshelper.q
using namespace Global;
struct QuickHelperData
struct FramelessQuickHelperData
{
bool ready = false;
SystemParameters params = {};
@ -83,12 +83,12 @@ struct QuickHelperData
QList<QRect> hitTestVisibleRects = {};
};
struct QuickHelper
struct FramelessQuickHelperInternal
{
QHash<WId, QuickHelperData> data = {};
QHash<WId, FramelessQuickHelperData> data = {};
};
Q_GLOBAL_STATIC(QuickHelper, g_quickHelper)
Q_GLOBAL_STATIC(FramelessQuickHelperInternal, g_framelessQuickHelperData)
FramelessQuickHelperPrivate::FramelessQuickHelperPrivate(FramelessQuickHelper *q) : QObject(q)
{
@ -128,7 +128,8 @@ const FramelessQuickHelperPrivate *FramelessQuickHelperPrivate::get(const Framel
bool FramelessQuickHelperPrivate::isContentExtendedIntoTitleBar() const
{
return getWindowData().ready;
const FramelessQuickHelperData *data = getWindowData();
return (data ? data->ready : false);
}
void FramelessQuickHelperPrivate::extendsContentIntoTitleBar(const bool value)
@ -149,7 +150,8 @@ void FramelessQuickHelperPrivate::extendsContentIntoTitleBar(const bool value)
QQuickItem *FramelessQuickHelperPrivate::getTitleBarItem() const
{
return getWindowData().titleBarItem;
const FramelessQuickHelperData *data = getWindowData();
return (data ? data->titleBarItem : nullptr);
}
void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
@ -158,11 +160,8 @@ void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
if (!value) {
return;
}
QuickHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
if (data->titleBarItem == value) {
FramelessQuickHelperData *data = getWindowDataMutable();
if (!data || (data->titleBarItem == value)) {
return;
}
data->titleBarItem = value;
@ -178,7 +177,7 @@ void FramelessQuickHelperPrivate::attach()
return;
}
QuickHelperData * const data = getWindowDataMutable();
FramelessQuickHelperData * const data = getWindowDataMutable();
if (!data || data->ready) {
return;
}
@ -230,7 +229,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(0, this, [this](){
QTimer::singleShot(m_qpaWaitTime, this, [this](){
m_qpaReady = true;
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
moveWindowToDesktopCenter();
@ -250,10 +249,11 @@ void FramelessQuickHelperPrivate::detach()
return;
}
const WId windowId = w->winId();
if (!g_quickHelper()->data.contains(windowId)) {
const auto it = g_framelessQuickHelperData()->data.constFind(windowId);
if (it == g_framelessQuickHelperData()->data.constEnd()) {
return;
}
g_quickHelper()->data.remove(windowId);
g_framelessQuickHelperData()->data.erase(it);
FramelessManager::instance()->removeWindow(windowId);
}
@ -264,7 +264,7 @@ void FramelessQuickHelperPrivate::setSystemButton(QQuickItem *item, const QuickG
if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
return;
}
QuickHelperData *data = getWindowDataMutable();
FramelessQuickHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
@ -296,15 +296,13 @@ void FramelessQuickHelperPrivate::setHitTestVisible(QQuickItem *item, const bool
if (!item) {
return;
}
QuickHelperData *data = getWindowDataMutable();
FramelessQuickHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
const bool exists = data->hitTestVisibleItems.contains(item);
if (visible && !exists) {
if (visible) {
data->hitTestVisibleItems.append(item);
}
if (!visible && exists) {
} else {
data->hitTestVisibleItems.removeAll(item);
}
}
@ -315,15 +313,13 @@ void FramelessQuickHelperPrivate::setHitTestVisible(const QRect &rect, const boo
if (!rect.isValid()) {
return;
}
QuickHelperData *data = getWindowDataMutable();
FramelessQuickHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
const bool exists = data->hitTestVisibleRects.contains(rect);
if (visible && !exists) {
if (visible) {
data->hitTestVisibleRects.append(rect);
}
if (!visible && exists) {
} else {
data->hitTestVisibleRects.removeAll(rect);
}
}
@ -352,8 +348,7 @@ void FramelessQuickHelperPrivate::showSystemMenu(const QPoint &pos)
const WId windowId = window->winId();
const QPoint nativePos = Utils::toNativeGlobalPosition(window, pos);
#ifdef Q_OS_WINDOWS
const SystemParameters params = getWindowData().params;
Utils::showSystemMenu(windowId, nativePos, false, &params);
Utils::showSystemMenu(windowId, nativePos, false, &getWindowData()->params);
#elif defined(Q_OS_LINUX)
Utils::openSystemMenu(windowId, nativePos);
#else
@ -392,8 +387,7 @@ void FramelessQuickHelperPrivate::moveWindowToDesktopCenter()
if (!window) {
return;
}
const SystemParameters params = getWindowData().params;
Utils::moveWindowToDesktopCenter(&params, true);
Utils::moveWindowToDesktopCenter(&getWindowData()->params, true);
}
void FramelessQuickHelperPrivate::bringWindowToFront()
@ -677,7 +671,7 @@ void FramelessQuickHelperPrivate::waitForReady()
#endif
}
void FramelessQuickHelperPrivate::repaintAllChildren(const int delay) const
void FramelessQuickHelperPrivate::repaintAllChildren(const quint32 delay) const
{
Q_Q(const FramelessQuickHelper);
QQuickWindow * const window = q->window();
@ -709,6 +703,19 @@ void FramelessQuickHelperPrivate::repaintAllChildren(const int 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);
@ -730,34 +737,37 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
if (!button) {
return false;
}
const FramelessQuickHelperData *data = getWindowData();
if (!data) {
return false;
}
*button = QuickGlobal::SystemButtonType::Unknown;
const QuickHelperData data = getWindowData();
if (data.windowIconButton && data.windowIconButton->isVisible() && data.windowIconButton->isEnabled()) {
if (mapItemGeometryToScene(data.windowIconButton).contains(pos)) {
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;
}
@ -767,12 +777,15 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
{
const QuickHelperData data = getWindowData();
if (!data.titleBarItem) {
const FramelessQuickHelperData *data = getWindowData();
if (!data) {
return false;
}
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;
}
@ -784,29 +797,32 @@ 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;
}
@ -848,41 +864,44 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
if (button == QuickGlobal::SystemButtonType::Unknown) {
return;
}
const QuickHelperData data = getWindowData();
const FramelessQuickHelperData *data = getWindowData();
if (!data) {
return;
}
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;
}
}
@ -923,22 +942,7 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE
}
QuickHelperData FramelessQuickHelperPrivate::getWindowData() const
{
Q_Q(const FramelessQuickHelper);
const QQuickWindow * const window = q->window();
//Q_ASSERT(window);
if (!window) {
return {};
}
const WId windowId = window->winId();
if (!g_quickHelper()->data.contains(windowId)) {
g_quickHelper()->data.insert(windowId, {});
}
return g_quickHelper()->data.value(windowId);
}
QuickHelperData *FramelessQuickHelperPrivate::getWindowDataMutable() const
const FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowData() const
{
Q_Q(const FramelessQuickHelper);
const QQuickWindow * const window = q->window();
@ -947,10 +951,27 @@ QuickHelperData *FramelessQuickHelperPrivate::getWindowDataMutable() const
return nullptr;
}
const WId windowId = window->winId();
if (!g_quickHelper()->data.contains(windowId)) {
g_quickHelper()->data.insert(windowId, {});
auto it = g_framelessQuickHelperData()->data.find(windowId);
if (it == g_framelessQuickHelperData()->data.end()) {
it = g_framelessQuickHelperData()->data.insert(windowId, {});
}
return &g_quickHelper()->data[windowId];
return &it.value();
}
FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowDataMutable() const
{
Q_Q(const FramelessQuickHelper);
const QQuickWindow * const window = q->window();
//Q_ASSERT(window);
if (!window) {
return nullptr;
}
const WId windowId = window->winId();
auto it = g_framelessQuickHelperData()->data.find(windowId);
if (it == g_framelessQuickHelperData()->data.end()) {
it = g_framelessQuickHelperData()->data.insert(windowId, {});
}
return &it.value();
}
void FramelessQuickHelperPrivate::rebindWindow()

View File

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

View File

@ -27,6 +27,7 @@
#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>
@ -73,7 +74,7 @@ private:
private:
QPointer<QuickMicaMaterial> m_item = nullptr;
QSGSimpleTextureNode *m_node = nullptr;
std::unique_ptr<QSGSimpleTextureNode> m_node = nullptr;
std::unique_ptr<QSGTexture> m_texture = nullptr;
QPointer<MicaMaterial> m_mica{ nullptr };
QPointer<MicaMaterialPrivate> m_micaPriv{ nullptr };
@ -101,14 +102,13 @@ void WallpaperImageNode::initialize()
m_mica = QuickMicaMaterialPrivate::get(m_item)->m_micaMaterial;
m_micaPriv = MicaMaterialPrivate::get(m_mica);
// QtQuick's render engine will free it when appropriate.
m_node = new QSGSimpleTextureNode;
m_node = std::make_unique<QSGSimpleTextureNode>();
m_node->setFiltering(QSGTexture::Linear);
maybeGenerateWallpaperImageCache();
maybeUpdateWallpaperImageClipRect();
appendChildNode(m_node);
appendChildNode(m_node.get());
connect(m_window, &QQuickWindow::beforeRendering, this,
&WallpaperImageNode::maybeUpdateWallpaperImageClipRect, Qt::DirectConnection);
@ -178,9 +178,14 @@ 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);
q->setSmooth(true);
q->setAntialiasing(true);
// 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->setClip(true);
m_micaMaterial = new MicaMaterial(this);
@ -260,9 +265,6 @@ void QuickMicaMaterialPrivate::appendNode(WallpaperImageNode *node)
if (!node) {
return;
}
if (m_nodes.contains(node)) {
return;
}
m_nodes.append(node);
}
@ -272,9 +274,6 @@ void QuickMicaMaterialPrivate::removeNode(WallpaperImageNode *node)
if (!node) {
return;
}
if (!m_nodes.contains(node)) {
return;
}
m_nodes.removeAll(node);
}

View File

@ -65,7 +65,7 @@ static Q_LOGGING_CATEGORY(lcFramelessWidgetsHelper, "wangwenx190.framelesshelper
using namespace Global;
struct WidgetsHelperData
struct FramelessWidgetsHelperData
{
bool ready = false;
SystemParameters params = {};
@ -79,12 +79,12 @@ struct WidgetsHelperData
QList<QRect> hitTestVisibleRects = {};
};
struct WidgetsHelper
struct FramelessWidgetsHelperInternal
{
QHash<WId, WidgetsHelperData> data = {};
QHash<WId, FramelessWidgetsHelperData> data = {};
};
Q_GLOBAL_STATIC(WidgetsHelper, g_widgetsHelper)
Q_GLOBAL_STATIC(FramelessWidgetsHelperInternal, g_framelessWidgetsHelperData)
[[nodiscard]] static inline bool isWidgetFixedSize(const QWidget * const widget)
{
@ -408,7 +408,7 @@ void FramelessWidgetsHelperPrivate::waitForReady()
#endif
}
void FramelessWidgetsHelperPrivate::repaintAllChildren(const int delay) const
void FramelessWidgetsHelperPrivate::repaintAllChildren(const quint32 delay) const
{
if (!m_window) {
return;
@ -430,9 +430,23 @@ void FramelessWidgetsHelperPrivate::repaintAllChildren(const int delay) const
}
}
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
{
return getWindowData().ready;
const FramelessWidgetsHelperData *data = getWindowData();
return (data ? data->ready : false);
}
void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
@ -441,11 +455,8 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
if (!widget) {
return;
}
WidgetsHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
if (data->titleBarWidget == widget) {
FramelessWidgetsHelperData *data = getWindowDataMutable();
if (!data || (data->titleBarWidget == widget)) {
return;
}
data->titleBarWidget = widget;
@ -454,7 +465,8 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const
{
return getWindowData().titleBarWidget;
const FramelessWidgetsHelperData *data = getWindowData();
return (data ? data->titleBarWidget : nullptr);
}
void FramelessWidgetsHelperPrivate::setHitTestVisible(QWidget *widget, const bool visible)
@ -463,15 +475,13 @@ void FramelessWidgetsHelperPrivate::setHitTestVisible(QWidget *widget, const boo
if (!widget) {
return;
}
WidgetsHelperData *data = getWindowDataMutable();
FramelessWidgetsHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
const bool exists = data->hitTestVisibleWidgets.contains(widget);
if (visible && !exists) {
if (visible) {
data->hitTestVisibleWidgets.append(widget);
}
if (!visible && exists) {
} else {
data->hitTestVisibleWidgets.removeAll(widget);
}
}
@ -482,15 +492,13 @@ void FramelessWidgetsHelperPrivate::setHitTestVisible(const QRect &rect, const b
if (!rect.isValid()) {
return;
}
WidgetsHelperData *data = getWindowDataMutable();
FramelessWidgetsHelperData *data = getWindowDataMutable();
if (!data) {
return;
}
const bool exists = data->hitTestVisibleRects.contains(rect);
if (visible && !exists) {
if (visible) {
data->hitTestVisibleRects.append(rect);
}
if (!visible && exists) {
} else {
data->hitTestVisibleRects.removeAll(rect);
}
}
@ -528,7 +536,7 @@ void FramelessWidgetsHelperPrivate::attach()
window->setAttribute(Qt::WA_NativeWindow);
}
WidgetsHelperData * const data = getWindowDataMutable();
FramelessWidgetsHelperData * const data = getWindowDataMutable();
if (!data || data->ready) {
return;
}
@ -578,7 +586,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(0, this, [this](){
QTimer::singleShot(m_qpaWaitTime, this, [this](){
m_qpaReady = true;
if (FramelessConfig::instance()->isSet(Option::CenterWindowBeforeShow)) {
moveWindowToDesktopCenter();
@ -597,10 +605,11 @@ void FramelessWidgetsHelperPrivate::detach()
return;
}
const WId windowId = m_window->winId();
if (!g_widgetsHelper()->data.contains(windowId)) {
const auto it = g_framelessWidgetsHelperData()->data.constFind(windowId);
if (it == g_framelessWidgetsHelperData()->data.constEnd()) {
return;
}
g_widgetsHelper()->data.remove(windowId);
g_framelessWidgetsHelperData()->data.erase(it);
FramelessManager::instance()->removeWindow(windowId);
m_window = nullptr;
emitSignalForAllInstances("windowChanged");
@ -634,30 +643,32 @@ QWidget *FramelessWidgetsHelperPrivate::findTopLevelWindow() const
return nullptr;
}
WidgetsHelperData FramelessWidgetsHelperPrivate::getWindowData() const
{
//Q_ASSERT(m_window);
if (!m_window) {
return {};
}
const WId windowId = m_window->winId();
if (!g_widgetsHelper()->data.contains(windowId)) {
g_widgetsHelper()->data.insert(windowId, {});
}
return g_widgetsHelper()->data.value(windowId);
}
WidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowDataMutable() const
const FramelessWidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowData() const
{
//Q_ASSERT(m_window);
if (!m_window) {
return nullptr;
}
const WId windowId = m_window->winId();
if (!g_widgetsHelper()->data.contains(windowId)) {
g_widgetsHelper()->data.insert(windowId, {});
auto it = g_framelessWidgetsHelperData()->data.find(windowId);
if (it == g_framelessWidgetsHelperData()->data.end()) {
it = g_framelessWidgetsHelperData()->data.insert(windowId, {});
}
return &g_widgetsHelper()->data[windowId];
return &it.value();
}
FramelessWidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowDataMutable() const
{
//Q_ASSERT(m_window);
if (!m_window) {
return nullptr;
}
const WId windowId = m_window->winId();
auto it = g_framelessWidgetsHelperData()->data.find(windowId);
if (it == g_framelessWidgetsHelperData()->data.end()) {
it = g_framelessWidgetsHelperData()->data.insert(windowId, {});
}
return &it.value();
}
QRect FramelessWidgetsHelperPrivate::mapWidgetGeometryToScene(const QWidget * const widget) const
@ -680,34 +691,37 @@ bool FramelessWidgetsHelperPrivate::isInSystemButtons(const QPoint &pos, SystemB
if (!button) {
return false;
}
const FramelessWidgetsHelperData *data = getWindowData();
if (!data) {
return false;
}
*button = SystemButtonType::Unknown;
const WidgetsHelperData data = getWindowData();
if (data.windowIconButton && data.windowIconButton->isVisible() && data.windowIconButton->isEnabled()) {
if (data.windowIconButton->geometry().contains(pos)) {
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;
}
@ -717,12 +731,15 @@ bool FramelessWidgetsHelperPrivate::isInSystemButtons(const QPoint &pos, SystemB
bool FramelessWidgetsHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
{
const WidgetsHelperData data = getWindowData();
if (!data.titleBarWidget) {
const FramelessWidgetsHelperData *data = getWindowData();
if (!data) {
return false;
}
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;
}
@ -732,29 +749,32 @@ 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;
}
@ -789,33 +809,36 @@ void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType
if (button == SystemButtonType::Unknown) {
return;
}
const WidgetsHelperData data = getWindowData();
const FramelessWidgetsHelperData *data = getWindowData();
if (!data) {
return;
}
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:
@ -866,8 +889,7 @@ void FramelessWidgetsHelperPrivate::moveWindowToDesktopCenter()
if (!m_window) {
return;
}
const SystemParameters params = getWindowData().params;
Utils::moveWindowToDesktopCenter(&params, true);
Utils::moveWindowToDesktopCenter(&getWindowData()->params, true);
}
void FramelessWidgetsHelperPrivate::bringWindowToFront()
@ -897,8 +919,7 @@ 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
const SystemParameters params = getWindowData().params;
Utils::showSystemMenu(windowId, nativePos, false, &params);
Utils::showSystemMenu(windowId, nativePos, false, &getWindowData()->params);
#elif defined(Q_OS_LINUX)
Utils::openSystemMenu(windowId, nativePos);
#else
@ -933,7 +954,7 @@ void FramelessWidgetsHelperPrivate::setSystemButton(QWidget *widget, const Syste
if (!widget || (buttonType == SystemButtonType::Unknown)) {
return;
}
WidgetsHelperData *data = getWindowDataMutable();
FramelessWidgetsHelperData *data = getWindowDataMutable();
if (!data) {
return;
}

View File

@ -177,6 +177,7 @@ 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()) {
@ -184,10 +185,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(h * 0.5);
return std::round(qreal(h) * qreal(0.5));
}
}
return -std::round(h * 1.3);
return -std::round(qreal(h) * qreal(1.3));
}();
QToolTip::showText(q->mapToGlobal(QPoint(-2, yPos)), toolTip, q, q->geometry());
}
@ -196,6 +197,7 @@ void StandardSystemButtonPrivate::setHovered(const bool value)
QToolTip::hideText();
}
}
#endif
Q_EMIT q->hoveredChanged();
}

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 (m_screenDpr == currentDpr) {
if (qFuzzyCompare(m_screenDpr, currentDpr)) {
return;
}
m_screenDpr = currentDpr;