win: refactor
This commit is contained in:
parent
644266923b
commit
a130fef677
|
@ -89,11 +89,6 @@ FRAMELESSHELPER_CORE_API void moveWindowToDesktopCenter(
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 defaultScreenDpi();
|
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 defaultScreenDpi();
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowAccelerated(const QWindow *window);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowAccelerated(const QWindow *window);
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowTransparent(const QWindow *window);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowTransparent(const QWindow *window);
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::MouseButtons queryMouseButtons();
|
|
||||||
FRAMELESSHELPER_CORE_API void emulateQtMouseEvent(
|
|
||||||
const QObject *target, const QWindow *window, const Global::ButtonState buttonState,
|
|
||||||
const QPoint &globalPos, const QPoint &scenePos, const QPoint &localPos,
|
|
||||||
const bool underMouse, const bool hoverEnabled);
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowsVersionOrGreater(const Global::WindowsVersion version);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowsVersionOrGreater(const Global::WindowsVersion version);
|
||||||
|
@ -151,7 +146,7 @@ FRAMELESSHELPER_CORE_API void emulateQtMouseEvent(
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint getWindowPlacementOffset(const WId windowId);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint getWindowPlacementOffset(const WId windowId);
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QRect getWindowRestoreGeometry(const WId windowId);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API QRect getWindowRestoreGeometry(const WId windowId);
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool removeMicaWindow(const WId windowId);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API bool removeMicaWindow(const WId windowId);
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint64 getMouseButtonsAndModifiers(const bool async);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API quint64 getKeyState();
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidWindow(const WId windowId, const bool checkVisible, const bool checkTopLevel);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidWindow(const WId windowId, const bool checkVisible, const bool checkTopLevel);
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool updateFramebufferTransparency(const WId windowId);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API bool updateFramebufferTransparency(const WId windowId);
|
||||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QMargins getWindowSystemFrameMargins(const WId windowId);
|
[[nodiscard]] FRAMELESSHELPER_CORE_API QMargins getWindowSystemFrameMargins(const WId windowId);
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
Q_NODISCARD QColor getActiveForegroundColor() const;
|
Q_NODISCARD QColor getActiveForegroundColor() const;
|
||||||
Q_NODISCARD QColor getInactiveForegroundColor() const;
|
Q_NODISCARD QColor getInactiveForegroundColor() const;
|
||||||
Q_NODISCARD bool isActive() const;
|
Q_NODISCARD bool isActive() const;
|
||||||
Q_NODISCARD int iconSize2() const;
|
Q_NODISCARD int glyphSize() const;
|
||||||
|
|
||||||
void setHoverColor(const QColor &value);
|
void setHoverColor(const QColor &value);
|
||||||
void setPressColor(const QColor &value);
|
void setPressColor(const QColor &value);
|
||||||
|
@ -71,7 +71,7 @@ public:
|
||||||
void setActiveForegroundColor(const QColor &value);
|
void setActiveForegroundColor(const QColor &value);
|
||||||
void setInactiveForegroundColor(const QColor &value);
|
void setInactiveForegroundColor(const QColor &value);
|
||||||
void setActive(const bool value);
|
void setActive(const bool value);
|
||||||
void setIconSize2(const int value);
|
void setGlyphSize(const int value);
|
||||||
|
|
||||||
void paintEventHandler(QPaintEvent *event);
|
void paintEventHandler(QPaintEvent *event);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ private:
|
||||||
QColor m_activeForegroundColor = {};
|
QColor m_activeForegroundColor = {};
|
||||||
QColor m_inactiveForegroundColor = {};
|
QColor m_inactiveForegroundColor = {};
|
||||||
bool m_active = false;
|
bool m_active = false;
|
||||||
std::optional<int> m_iconSize2 = std::nullopt;
|
std::optional<int> m_glyphSize = std::nullopt;
|
||||||
};
|
};
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -44,7 +44,7 @@ class FRAMELESSHELPER_WIDGETS_API StandardSystemButton : public QPushButton
|
||||||
Q_PROPERTY(QColor activeForegroundColor READ activeForegroundColor WRITE setActiveForegroundColor NOTIFY activeForegroundColorChanged FINAL)
|
Q_PROPERTY(QColor activeForegroundColor READ activeForegroundColor WRITE setActiveForegroundColor NOTIFY activeForegroundColorChanged FINAL)
|
||||||
Q_PROPERTY(QColor inactiveForegroundColor READ inactiveForegroundColor WRITE setInactiveForegroundColor NOTIFY inactiveForegroundColorChanged FINAL)
|
Q_PROPERTY(QColor inactiveForegroundColor READ inactiveForegroundColor WRITE setInactiveForegroundColor NOTIFY inactiveForegroundColorChanged FINAL)
|
||||||
Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged FINAL)
|
Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged FINAL)
|
||||||
Q_PROPERTY(int iconSize2 READ iconSize2 WRITE setIconSize2 NOTIFY iconSize2Changed FINAL)
|
Q_PROPERTY(int glyphSize READ glyphSize WRITE setGlyphSize NOTIFY glyphSizeChanged FINAL)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StandardSystemButton(QWidget *parent = nullptr);
|
explicit StandardSystemButton(QWidget *parent = nullptr);
|
||||||
|
@ -60,7 +60,7 @@ public:
|
||||||
Q_NODISCARD QColor activeForegroundColor() const;
|
Q_NODISCARD QColor activeForegroundColor() const;
|
||||||
Q_NODISCARD QColor inactiveForegroundColor() const;
|
Q_NODISCARD QColor inactiveForegroundColor() const;
|
||||||
Q_NODISCARD bool isActive() const;
|
Q_NODISCARD bool isActive() const;
|
||||||
Q_NODISCARD int iconSize2() const;
|
Q_NODISCARD int glyphSize() const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setButtonType(const Global::SystemButtonType value);
|
void setButtonType(const Global::SystemButtonType value);
|
||||||
|
@ -71,7 +71,7 @@ public Q_SLOTS:
|
||||||
void setActiveForegroundColor(const QColor &value);
|
void setActiveForegroundColor(const QColor &value);
|
||||||
void setInactiveForegroundColor(const QColor &value);
|
void setInactiveForegroundColor(const QColor &value);
|
||||||
void setActive(const bool value);
|
void setActive(const bool value);
|
||||||
void setIconSize2(const int value);
|
void setGlyphSize(const int value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
@ -85,7 +85,7 @@ Q_SIGNALS:
|
||||||
void activeForegroundColorChanged();
|
void activeForegroundColorChanged();
|
||||||
void inactiveForegroundColorChanged();
|
void inactiveForegroundColorChanged();
|
||||||
void activeChanged();
|
void activeChanged();
|
||||||
void iconSize2Changed();
|
void glyphSizeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<StandardSystemButtonPrivate> d_ptr;
|
QScopedPointer<StandardSystemButtonPrivate> d_ptr;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "winverhelper_p.h"
|
#include "winverhelper_p.h"
|
||||||
#include "framelesshelper_windows.h"
|
#include "framelesshelper_windows.h"
|
||||||
#include "framelesshelpercore_global_p.h"
|
#include "framelesshelpercore_global_p.h"
|
||||||
|
#include "scopeguard_p.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QtCore/qhash.h>
|
#include <QtCore/qhash.h>
|
||||||
|
@ -85,10 +86,20 @@ FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(GetWindowPlacement)
|
FRAMELESSHELPER_STRING_CONSTANT(GetWindowPlacement)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(SetWindowPlacement)
|
FRAMELESSHELPER_STRING_CONSTANT(SetWindowPlacement)
|
||||||
|
|
||||||
|
enum class WindowPart : quint8
|
||||||
|
{
|
||||||
|
NotInterested,
|
||||||
|
ClientArea,
|
||||||
|
ChromeButton,
|
||||||
|
ResizeBorder,
|
||||||
|
FixBorder,
|
||||||
|
TitleBar
|
||||||
|
};
|
||||||
|
|
||||||
struct FramelessWin32HelperData
|
struct FramelessWin32HelperData
|
||||||
{
|
{
|
||||||
SystemParameters params = {};
|
SystemParameters params = {};
|
||||||
bool trackingMouse = false;
|
int hitTestResult = HTNOWHERE;
|
||||||
Dpi dpi = {};
|
Dpi dpi = {};
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||||
QRect restoreGeometry = {};
|
QRect restoreGeometry = {};
|
||||||
|
@ -146,6 +157,36 @@ Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static inline WindowPart getHittedWindowPart(const LRESULT hitTestResult)
|
||||||
|
{
|
||||||
|
switch (hitTestResult) {
|
||||||
|
case HTCLIENT:
|
||||||
|
return WindowPart::ClientArea;
|
||||||
|
case HTCAPTION:
|
||||||
|
return WindowPart::TitleBar;
|
||||||
|
case HTSYSMENU:
|
||||||
|
case HTHELP:
|
||||||
|
case HTREDUCE:
|
||||||
|
case HTZOOM:
|
||||||
|
case HTCLOSE:
|
||||||
|
return WindowPart::ChromeButton;
|
||||||
|
case HTLEFT:
|
||||||
|
case HTRIGHT:
|
||||||
|
case HTTOP:
|
||||||
|
case HTTOPLEFT:
|
||||||
|
case HTTOPRIGHT:
|
||||||
|
case HTBOTTOM:
|
||||||
|
case HTBOTTOMLEFT:
|
||||||
|
case HTBOTTOMRIGHT:
|
||||||
|
return WindowPart::ResizeBorder;
|
||||||
|
case HTBORDER:
|
||||||
|
return WindowPart::FixBorder;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return WindowPart::NotInterested;
|
||||||
|
}
|
||||||
|
|
||||||
FramelessHelperWin::FramelessHelperWin() : QAbstractNativeEventFilter() {}
|
FramelessHelperWin::FramelessHelperWin() : QAbstractNativeEventFilter() {}
|
||||||
|
|
||||||
FramelessHelperWin::~FramelessHelperWin() = default;
|
FramelessHelperWin::~FramelessHelperWin() = default;
|
||||||
|
@ -288,48 +329,12 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
};
|
};
|
||||||
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||||
|
|
||||||
#if 0
|
|
||||||
const auto releaseButtons = [&data](const std::optional<SystemButtonType> exclude) -> void {
|
|
||||||
static constexpr const auto defaultButtonState = ButtonState::Normal;
|
|
||||||
const SystemButtonType button = exclude.value_or(SystemButtonType::Unknown);
|
|
||||||
if (button != SystemButtonType::WindowIcon) {
|
|
||||||
data.params.setSystemButtonState(SystemButtonType::WindowIcon, defaultButtonState);
|
|
||||||
}
|
|
||||||
if (button != SystemButtonType::Help) {
|
|
||||||
data.params.setSystemButtonState(SystemButtonType::Help, defaultButtonState);
|
|
||||||
}
|
|
||||||
if (button != SystemButtonType::Minimize) {
|
|
||||||
data.params.setSystemButtonState(SystemButtonType::Minimize, defaultButtonState);
|
|
||||||
}
|
|
||||||
if (button != SystemButtonType::Maximize) {
|
|
||||||
data.params.setSystemButtonState(SystemButtonType::Maximize, defaultButtonState);
|
|
||||||
}
|
|
||||||
if (button != SystemButtonType::Restore) {
|
|
||||||
data.params.setSystemButtonState(SystemButtonType::Restore, defaultButtonState);
|
|
||||||
}
|
|
||||||
if (button != SystemButtonType::Close) {
|
|
||||||
data.params.setSystemButtonState(SystemButtonType::Close, defaultButtonState);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const auto hoverButton = [&releaseButtons, &data](const SystemButtonType button) -> void {
|
|
||||||
releaseButtons(button);
|
|
||||||
data.params.setSystemButtonState(button, ButtonState::Hovered);
|
|
||||||
};
|
|
||||||
const auto pressButton = [&releaseButtons, &data](const SystemButtonType button) -> void {
|
|
||||||
releaseButtons(button);
|
|
||||||
data.params.setSystemButtonState(button, ButtonState::Pressed);
|
|
||||||
};
|
|
||||||
const auto clickButton = [&releaseButtons, &data](const SystemButtonType button) -> void {
|
|
||||||
releaseButtons(button);
|
|
||||||
data.params.setSystemButtonState(button, ButtonState::Released);
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
const auto emulateClientAreaMessage = [hWnd, uMsg, wParam, lParam]() -> void {
|
const auto emulateClientAreaMessage = [hWnd, uMsg, wParam, lParam]() -> void {
|
||||||
const auto wparam = [uMsg, wParam]() -> WPARAM {
|
const auto wparam = [uMsg, wParam]() -> WPARAM {
|
||||||
if (uMsg == WM_NCMOUSELEAVE) {
|
if (uMsg == WM_NCMOUSELEAVE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const quint64 keyState = Utils::getMouseButtonsAndModifiers(false);
|
const quint64 keyState = Utils::getKeyState();
|
||||||
if ((uMsg >= WM_NCXBUTTONDOWN) && (uMsg <= WM_NCXBUTTONDBLCLK)) {
|
if ((uMsg >= WM_NCXBUTTONDOWN) && (uMsg <= WM_NCXBUTTONDBLCLK)) {
|
||||||
const auto xButtonMask = GET_XBUTTON_WPARAM(wParam);
|
const auto xButtonMask = GET_XBUTTON_WPARAM(wParam);
|
||||||
return MAKEWPARAM(keyState, xButtonMask);
|
return MAKEWPARAM(keyState, xButtonMask);
|
||||||
|
@ -348,45 +353,51 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
}
|
}
|
||||||
return MAKELPARAM(clientPos.x, clientPos.y);
|
return MAKELPARAM(clientPos.x, clientPos.y);
|
||||||
}();
|
}();
|
||||||
|
#if 0
|
||||||
|
# define SEND_MESSAGE ::SendMessageW
|
||||||
|
#else
|
||||||
|
# define SEND_MESSAGE ::PostMessageW
|
||||||
|
#endif
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
|
case WM_NCHITTEST: // Treat hit test messages as mouse move events.
|
||||||
case WM_NCMOUSEMOVE:
|
case WM_NCMOUSEMOVE:
|
||||||
::SendMessageW(hWnd, WM_MOUSEMOVE, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_MOUSEMOVE, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCLBUTTONDOWN:
|
case WM_NCLBUTTONDOWN:
|
||||||
::SendMessageW(hWnd, WM_LBUTTONDOWN, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_LBUTTONDOWN, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCLBUTTONUP:
|
case WM_NCLBUTTONUP:
|
||||||
::SendMessageW(hWnd, WM_LBUTTONUP, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_LBUTTONUP, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCLBUTTONDBLCLK:
|
case WM_NCLBUTTONDBLCLK:
|
||||||
::SendMessageW(hWnd, WM_LBUTTONDBLCLK, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_LBUTTONDBLCLK, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCRBUTTONDOWN:
|
case WM_NCRBUTTONDOWN:
|
||||||
::SendMessageW(hWnd, WM_RBUTTONDOWN, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_RBUTTONDOWN, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCRBUTTONUP:
|
case WM_NCRBUTTONUP:
|
||||||
::SendMessageW(hWnd, WM_RBUTTONUP, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_RBUTTONUP, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCRBUTTONDBLCLK:
|
case WM_NCRBUTTONDBLCLK:
|
||||||
::SendMessageW(hWnd, WM_RBUTTONDBLCLK, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_RBUTTONDBLCLK, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCMBUTTONDOWN:
|
case WM_NCMBUTTONDOWN:
|
||||||
::SendMessageW(hWnd, WM_MBUTTONDOWN, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_MBUTTONDOWN, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCMBUTTONUP:
|
case WM_NCMBUTTONUP:
|
||||||
::SendMessageW(hWnd, WM_MBUTTONUP, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_MBUTTONUP, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCMBUTTONDBLCLK:
|
case WM_NCMBUTTONDBLCLK:
|
||||||
::SendMessageW(hWnd, WM_MBUTTONDBLCLK, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_MBUTTONDBLCLK, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCXBUTTONDOWN:
|
case WM_NCXBUTTONDOWN:
|
||||||
::SendMessageW(hWnd, WM_XBUTTONDOWN, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_XBUTTONDOWN, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCXBUTTONUP:
|
case WM_NCXBUTTONUP:
|
||||||
::SendMessageW(hWnd, WM_XBUTTONUP, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_XBUTTONUP, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCXBUTTONDBLCLK:
|
case WM_NCXBUTTONDBLCLK:
|
||||||
::SendMessageW(hWnd, WM_XBUTTONDBLCLK, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_XBUTTONDBLCLK, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
#if 0
|
#if 0
|
||||||
case WM_NCPOINTERUPDATE:
|
case WM_NCPOINTERUPDATE:
|
||||||
|
@ -395,16 +406,28 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case WM_NCMOUSEHOVER:
|
case WM_NCMOUSEHOVER:
|
||||||
::SendMessageW(hWnd, WM_MOUSEHOVER, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_MOUSEHOVER, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
case WM_NCMOUSELEAVE:
|
case WM_NCMOUSELEAVE:
|
||||||
::SendMessageW(hWnd, WM_MOUSELEAVE, wparam, lparam);
|
SEND_MESSAGE(hWnd, WM_MOUSELEAVE, wparam, lparam);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
if (isSnapLayoutEnabled() && (uMsg == WM_MOUSELEAVE)) {
|
||||||
|
// For some unknown reason, there will be many invalid mouse leave events generated
|
||||||
|
// when the mouse is hovering above our chrome buttons, which will cause Qt to ignore
|
||||||
|
// all our mouse move events and thus break the hover state of our controls.
|
||||||
|
// So we filter out these superfluous mouse leave events here.
|
||||||
|
const QPoint qtScenePos = Utils::fromNativeLocalPosition(window, QPoint{ msg->pt.x, msg->pt.y });
|
||||||
|
SystemButtonType sysButtonType = SystemButtonType::Unknown;
|
||||||
|
if (data.params.isInsideSystemButtons(qtScenePos, &sysButtonType)) {
|
||||||
|
*result = FALSE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0)) // Qt has done this for us since 5.9.0
|
#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0)) // Qt has done this for us since 5.9.0
|
||||||
|
@ -504,8 +527,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// implement an elaborate client-area preservation technique, and
|
// implement an elaborate client-area preservation technique, and
|
||||||
// simply return 0, which means "preserve the entire old client area
|
// simply return 0, which means "preserve the entire old client area
|
||||||
// and align it with the upper-left corner of our new client area".
|
// and align it with the upper-left corner of our new client area".
|
||||||
const auto clientRect = ((static_cast<BOOL>(wParam) == FALSE) ?
|
const auto clientRect = ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
||||||
reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
|
||||||
if (frameBorderVisible) {
|
if (frameBorderVisible) {
|
||||||
// Store the original top margin before the default window procedure applies the default frame.
|
// Store the original top margin before the default window procedure applies the default frame.
|
||||||
const LONG originalTop = clientRect->top;
|
const LONG originalTop = clientRect->top;
|
||||||
|
@ -518,7 +540,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// totally OK but since we want to preserve as much original frame as possible, we
|
// totally OK but since we want to preserve as much original frame as possible, we
|
||||||
// can't use that solution.
|
// can't use that solution.
|
||||||
const LRESULT hitTestResult = ::DefWindowProcW(hWnd, WM_NCCALCSIZE, wParam, lParam);
|
const LRESULT hitTestResult = ::DefWindowProcW(hWnd, WM_NCCALCSIZE, wParam, lParam);
|
||||||
if (hitTestResult != FALSE) {
|
if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) {
|
||||||
*result = hitTestResult;
|
*result = hitTestResult;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -657,7 +679,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// from Windows 7 to Windows 10. Not tested on Windows 11 yet. Don't know
|
// from Windows 7 to Windows 10. Not tested on Windows 11 yet. Don't know
|
||||||
// whether it exists on Windows XP to Windows Vista or not.
|
// whether it exists on Windows XP to Windows Vista or not.
|
||||||
static const bool needD3DWorkaround = (qEnvironmentVariableIntValue("FRAMELESSHELPER_USE_D3D_WORKAROUND") != 0);
|
static const bool needD3DWorkaround = (qEnvironmentVariableIntValue("FRAMELESSHELPER_USE_D3D_WORKAROUND") != 0);
|
||||||
*result = (((static_cast<BOOL>(wParam) == FALSE) || needD3DWorkaround) ? FALSE : WVR_REDRAW);
|
*result = (((wParam == FALSE) || needD3DWorkaround) ? FALSE : WVR_REDRAW);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case WM_NCHITTEST: {
|
case WM_NCHITTEST: {
|
||||||
|
@ -742,6 +764,8 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// color, our homemade top border can almost have exactly the same
|
// color, our homemade top border can almost have exactly the same
|
||||||
// appearance with the system's one.
|
// appearance with the system's one.
|
||||||
|
|
||||||
|
const auto hitTestRecorder = qScopeGuard([&muData, &result](){ muData.hitTestResult = *result; });
|
||||||
|
|
||||||
const auto nativeGlobalPos = POINT{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
const auto nativeGlobalPos = POINT{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||||
POINT nativeLocalPos = nativeGlobalPos;
|
POINT nativeLocalPos = nativeGlobalPos;
|
||||||
if (::ScreenToClient(hWnd, &nativeLocalPos) == FALSE) {
|
if (::ScreenToClient(hWnd, &nativeLocalPos) == FALSE) {
|
||||||
|
@ -783,7 +807,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
const bool full = Utils::isFullScreen(windowId);
|
const bool full = Utils::isFullScreen(windowId);
|
||||||
const int frameSizeY = Utils::getResizeBorderThickness(windowId, false, true);
|
const int frameSizeY = Utils::getResizeBorderThickness(windowId, false, true);
|
||||||
const bool isTop = (nativeLocalPos.y < frameSizeY);
|
const bool isTop = (nativeLocalPos.y < frameSizeY);
|
||||||
const bool leftButtonPressed = (Utils::getMouseButtonsAndModifiers(true) & MK_LBUTTON);
|
const bool leftButtonPressed = (Utils::getKeyState() & MK_LBUTTON);
|
||||||
const bool isTitleBar = (data.params.isInsideTitleBarDraggableArea(qtScenePos) && leftButtonPressed);
|
const bool isTitleBar = (data.params.isInsideTitleBarDraggableArea(qtScenePos) && leftButtonPressed);
|
||||||
const bool isFixedSize = data.params.isWindowFixedSize();
|
const bool isFixedSize = data.params.isWindowFixedSize();
|
||||||
const bool dontOverrideCursor = data.params.getProperty(kDontOverrideCursorVar, false).toBool();
|
const bool dontOverrideCursor = data.params.getProperty(kDontOverrideCursorVar, false).toBool();
|
||||||
|
@ -843,20 +867,18 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!isFixedSize) {
|
if (!isFixedSize) {
|
||||||
RECT clientRect = {0, 0, 0, 0};
|
auto clientRect = RECT{ 0, 0, 0, 0 };
|
||||||
if (::GetClientRect(hWnd, &clientRect) == FALSE) {
|
if (::GetClientRect(hWnd, &clientRect) == FALSE) {
|
||||||
WARNING << Utils::getSystemErrorMessage(kGetClientRect);
|
WARNING << Utils::getSystemErrorMessage(kGetClientRect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const LONG width = clientRect.right;
|
const bool isBottom = (nativeLocalPos.y >= (RECT_HEIGHT(clientRect) - frameSizeY));
|
||||||
const LONG height = clientRect.bottom;
|
|
||||||
const bool isBottom = (nativeLocalPos.y >= (height - frameSizeY));
|
|
||||||
// Make the border a little wider to let the user easy to resize on corners.
|
// Make the border a little wider to let the user easy to resize on corners.
|
||||||
const qreal scaleFactor = ((isTop || isBottom) ? 2.0 : 1.0);
|
const auto scaleFactor = ((isTop || isBottom) ? qreal(2) : qreal(1));
|
||||||
const int frameSizeX = Utils::getResizeBorderThickness(windowId, true, true);
|
const int frameSizeX = Utils::getResizeBorderThickness(windowId, true, true);
|
||||||
const int scaledFrameSizeX = std::round(qreal(frameSizeX) * scaleFactor);
|
const int scaledFrameSizeX = std::round(qreal(frameSizeX) * scaleFactor);
|
||||||
const bool isLeft = (nativeLocalPos.x < scaledFrameSizeX);
|
const bool isLeft = (nativeLocalPos.x < scaledFrameSizeX);
|
||||||
const bool isRight = (nativeLocalPos.x >= (width - scaledFrameSizeX));
|
const bool isRight = (nativeLocalPos.x >= (RECT_WIDTH(clientRect) - scaledFrameSizeX));
|
||||||
if (dontOverrideCursor && (isTop || isBottom || isLeft || isRight)) {
|
if (dontOverrideCursor && (isTop || isBottom || isLeft || isRight)) {
|
||||||
// Return HTCLIENT instead of HTBORDER here, because the mouse is
|
// Return HTCLIENT instead of HTBORDER here, because the mouse is
|
||||||
// inside the window now, return HTCLIENT to let the controls
|
// inside the window now, return HTCLIENT to let the controls
|
||||||
|
@ -925,45 +947,23 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
#endif
|
#endif
|
||||||
case WM_NCMOUSEHOVER:
|
case WM_NCMOUSEHOVER:
|
||||||
case WM_NCMOUSELEAVE: {
|
case WM_NCMOUSELEAVE: {
|
||||||
if (uMsg == WM_NCMOUSELEAVE) {
|
const WindowPart previousWindowPart = getHittedWindowPart(data.hitTestResult);
|
||||||
muData.trackingMouse = false;
|
|
||||||
emulateClientAreaMessage();
|
|
||||||
//*result = FALSE;
|
|
||||||
//return true;
|
|
||||||
} else {
|
|
||||||
if ((uMsg == WM_NCMOUSEMOVE) && !data.trackingMouse) {
|
|
||||||
TRACKMOUSEEVENT tme;
|
|
||||||
SecureZeroMemory(&tme, sizeof(tme));
|
|
||||||
tme.cbSize = sizeof(tme);
|
|
||||||
// TME_NONCLIENT is absolutely critical here. In my experimentation,
|
|
||||||
// we'd get WM_MOUSELEAVE messages after just a HOVER_DEFAULT
|
|
||||||
// timeout even though we're not requesting TME_HOVER, which kinda
|
|
||||||
// ruined the whole point of this.
|
|
||||||
tme.dwFlags = (TME_LEAVE | TME_NONCLIENT);
|
|
||||||
tme.hwndTrack = hWnd;
|
|
||||||
tme.dwHoverTime = HOVER_DEFAULT; // We don't _really_ care about this.
|
|
||||||
if (::TrackMouseEvent(&tme) == FALSE) {
|
|
||||||
WARNING << Utils::getSystemErrorMessage(kTrackMouseEvent);
|
|
||||||
} else {
|
|
||||||
muData.trackingMouse = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const bool isXButtonMessage = ((uMsg >= WM_NCXBUTTONDOWN) && (uMsg <= WM_NCXBUTTONDBLCLK));
|
const bool isXButtonMessage = ((uMsg >= WM_NCXBUTTONDOWN) && (uMsg <= WM_NCXBUTTONDBLCLK));
|
||||||
const auto hitTestResult = (isXButtonMessage ? GET_NCHITTEST_WPARAM(wParam) : wParam);
|
const WindowPart nowWindowPart = getHittedWindowPart(isXButtonMessage ? GET_NCHITTEST_WPARAM(wParam) : wParam);
|
||||||
switch (hitTestResult) {
|
if (uMsg == WM_NCMOUSELEAVE) {
|
||||||
case HTSYSMENU:
|
if (previousWindowPart == WindowPart::ChromeButton) {
|
||||||
case HTHELP:
|
if (nowWindowPart == WindowPart::ClientArea) {
|
||||||
case HTREDUCE:
|
*result = FALSE;
|
||||||
case HTZOOM:
|
return true;
|
||||||
case HTCLOSE: {
|
} else {
|
||||||
|
emulateClientAreaMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (nowWindowPart == WindowPart::ChromeButton) {
|
||||||
emulateClientAreaMessage();
|
emulateClientAreaMessage();
|
||||||
//if ((uMsg != WM_NCMOUSEMOVE) && (uMsg != WM_NCMOUSEHOVER)) {
|
|
||||||
*result = (isXButtonMessage ? TRUE : FALSE);
|
*result = (isXButtonMessage ? TRUE : FALSE);
|
||||||
return true;
|
return true;
|
||||||
//}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -1119,7 +1119,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// window activation state change.
|
// window activation state change.
|
||||||
*result = ::DefWindowProcW(hWnd, WM_NCACTIVATE, wParam, -1);
|
*result = ::DefWindowProcW(hWnd, WM_NCACTIVATE, wParam, -1);
|
||||||
} else {
|
} else {
|
||||||
if (static_cast<BOOL>(wParam) == FALSE) {
|
if (wParam == FALSE) {
|
||||||
*result = TRUE;
|
*result = TRUE;
|
||||||
} else {
|
} else {
|
||||||
*result = FALSE;
|
*result = FALSE;
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include <QtGui/qpalette.h>
|
#include <QtGui/qpalette.h>
|
||||||
#include <QtGui/qsurface.h>
|
#include <QtGui/qsurface.h>
|
||||||
#include <QtGui/qsurfaceformat.h>
|
#include <QtGui/qsurfaceformat.h>
|
||||||
#include <QtGui/qevent.h>
|
|
||||||
#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE
|
#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE
|
||||||
# include <QtGui/private/qhighdpiscaling_p.h>
|
# include <QtGui/private/qhighdpiscaling_p.h>
|
||||||
# include <QtGui/private/qwindow_p.h>
|
# include <QtGui/private/qwindow_p.h>
|
||||||
|
@ -631,157 +630,4 @@ bool Utils::isWindowTransparent(const QWindow *window)
|
||||||
return window->format().hasAlpha();
|
return window->format().hasAlpha();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::emulateQtMouseEvent(const QObject *target, const QWindow *window, const ButtonState buttonState,
|
|
||||||
const QPoint &globalPos, const QPoint &scenePos, const QPoint &localPos, const bool underMouse, const bool enableHover)
|
|
||||||
{
|
|
||||||
Q_ASSERT(target);
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!target || !window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto targetObj = const_cast<QObject *>(target);
|
|
||||||
const auto windowObj = static_cast<QObject *>(const_cast<QWindow *>(window));
|
|
||||||
const bool isWidget = target->isWidgetType();
|
|
||||||
static constexpr const char kMouseTrackingProp[] = "mouseTracking";
|
|
||||||
const bool mouseTrackingEnabled = (isWidget ? target->property(kMouseTrackingProp).toBool() : true);
|
|
||||||
const bool hoverEnabled = (isWidget ? enableHover : true);
|
|
||||||
static constexpr const QPoint oldPos = {}; // Not needed.
|
|
||||||
static constexpr const Qt::MouseButton button = Qt::LeftButton;
|
|
||||||
const Qt::MouseButtons buttons = QGuiApplication::mouseButtons();
|
|
||||||
const Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers();
|
|
||||||
static constexpr const char kEnteredFlag[] = "__FRAMELESSHELPER_WIDGET_QUICKITEM_ENTERED";
|
|
||||||
const bool entered = target->property(kEnteredFlag).toBool();
|
|
||||||
const bool leftButtonPressed = (queryMouseButtons() & Qt::LeftButton);
|
|
||||||
const auto sendEnterEvent = [&localPos, &scenePos, &globalPos, &modifiers, hoverEnabled](QObject *obj) -> void {
|
|
||||||
Q_ASSERT(obj);
|
|
||||||
if (!obj) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
|
||||||
QEnterEvent enterEvent(localPos, scenePos, globalPos);
|
|
||||||
#else
|
|
||||||
QEvent enterEvent(QEvent::Enter);
|
|
||||||
#endif
|
|
||||||
QCoreApplication::sendEvent(obj, &enterEvent);
|
|
||||||
if (hoverEnabled) {
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
|
||||||
QHoverEvent hoverEnterEvent(QEvent::HoverEnter, scenePos, globalPos, oldPos, modifiers);
|
|
||||||
#elif (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
|
|
||||||
QHoverEvent hoverEnterEvent(QEvent::HoverEnter, localPos, globalPos, oldPos, modifiers);
|
|
||||||
#else
|
|
||||||
QHoverEvent hoverEnterEvent(QEvent::HoverEnter, localPos, oldPos, modifiers);
|
|
||||||
#endif
|
|
||||||
QCoreApplication::sendEvent(obj, &hoverEnterEvent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const auto sendLeaveEvent = [&localPos, &scenePos, &globalPos, &modifiers, hoverEnabled](QObject *obj) -> void {
|
|
||||||
Q_ASSERT(obj);
|
|
||||||
if (!obj) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QEvent leaveEvent(QEvent::Leave);
|
|
||||||
QCoreApplication::sendEvent(obj, &leaveEvent);
|
|
||||||
if (hoverEnabled) {
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
|
||||||
Q_UNUSED(localPos);
|
|
||||||
QHoverEvent hoverLeaveEvent(QEvent::HoverLeave, scenePos, globalPos, oldPos, modifiers);
|
|
||||||
#elif (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
|
|
||||||
QHoverEvent hoverLeaveEvent(QEvent::HoverLeave, localPos, globalPos, oldPos, modifiers);
|
|
||||||
#else
|
|
||||||
QHoverEvent hoverLeaveEvent(QEvent::HoverLeave, localPos, oldPos, modifiers);
|
|
||||||
#endif
|
|
||||||
QCoreApplication::sendEvent(obj, &hoverLeaveEvent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const auto sendMouseMoveEvent = [&localPos, &scenePos, &globalPos, &buttons, &modifiers, leftButtonPressed](QObject *obj) -> void {
|
|
||||||
Q_ASSERT(obj);
|
|
||||||
if (!obj) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const Qt::MouseButton actualButton = (leftButtonPressed ? button : Qt::NoButton);
|
|
||||||
QMouseEvent event(QEvent::MouseMove, localPos, scenePos, globalPos, actualButton, buttons, modifiers);
|
|
||||||
QCoreApplication::sendEvent(obj, &event);
|
|
||||||
};
|
|
||||||
const auto sendHoverMoveEvent = [&localPos, &scenePos, &globalPos, &modifiers, hoverEnabled](QObject *obj) -> void {
|
|
||||||
Q_ASSERT(obj);
|
|
||||||
if (!obj) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!hoverEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
|
||||||
Q_UNUSED(localPos);
|
|
||||||
QHoverEvent event(QEvent::HoverMove, scenePos, globalPos, oldPos, modifiers);
|
|
||||||
#elif (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
|
|
||||||
QHoverEvent event(QEvent::HoverMove, localPos, globalPos, oldPos, modifiers);
|
|
||||||
#else
|
|
||||||
QHoverEvent event(QEvent::HoverMove, localPos, oldPos, modifiers);
|
|
||||||
#endif
|
|
||||||
QCoreApplication::sendEvent(obj, &event);
|
|
||||||
};
|
|
||||||
const auto sendMousePressEvent = [&localPos, &scenePos, &globalPos, &buttons, &modifiers](QObject *obj) -> void {
|
|
||||||
Q_ASSERT(obj);
|
|
||||||
if (!obj) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QMouseEvent event(QEvent::MouseButtonPress, localPos, scenePos, globalPos, button, buttons, modifiers);
|
|
||||||
QCoreApplication::sendEvent(obj, &event);
|
|
||||||
};
|
|
||||||
const auto sendMouseReleaseEvent = [&localPos, &scenePos, &globalPos, &buttons, &modifiers](QObject *obj) -> void {
|
|
||||||
Q_ASSERT(obj);
|
|
||||||
if (!obj) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QMouseEvent event(QEvent::MouseButtonRelease, localPos, scenePos, globalPos, button, buttons, modifiers);
|
|
||||||
QCoreApplication::sendEvent(obj, &event);
|
|
||||||
};
|
|
||||||
switch (buttonState) {
|
|
||||||
case ButtonState::Normal: {
|
|
||||||
targetObj->setProperty(kEnteredFlag, {});
|
|
||||||
// Send an extra mouse release event to let the control dismiss it's hover state.
|
|
||||||
// But only when the mouse is not still hovering above the control, otherwise Qt will
|
|
||||||
// generate a mouse click event, which is not what the user would expect.
|
|
||||||
if (!underMouse) {
|
|
||||||
sendMouseReleaseEvent(targetObj);
|
|
||||||
}
|
|
||||||
if (isWidget) {
|
|
||||||
sendLeaveEvent(targetObj);
|
|
||||||
} else {
|
|
||||||
sendLeaveEvent(windowObj);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case ButtonState::Hovered: {
|
|
||||||
if (!entered) {
|
|
||||||
targetObj->setProperty(kEnteredFlag, true);
|
|
||||||
if (isWidget) {
|
|
||||||
sendEnterEvent(targetObj);
|
|
||||||
} else {
|
|
||||||
sendEnterEvent(windowObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isWidget) {
|
|
||||||
sendHoverMoveEvent(targetObj);
|
|
||||||
} else {
|
|
||||||
sendHoverMoveEvent(windowObj);
|
|
||||||
}
|
|
||||||
if (leftButtonPressed || mouseTrackingEnabled) {
|
|
||||||
if (isWidget) {
|
|
||||||
sendMouseMoveEvent(targetObj);
|
|
||||||
} else {
|
|
||||||
sendMouseMoveEvent(windowObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case ButtonState::Pressed:
|
|
||||||
// Sending mouse event to the window has no effect.
|
|
||||||
sendMousePressEvent(targetObj);
|
|
||||||
break;
|
|
||||||
case ButtonState::Released:
|
|
||||||
// Sending mouse event to the window has no effect.
|
|
||||||
sendMouseReleaseEvent(targetObj);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -992,10 +992,4 @@ bool Utils::setPlatformPropertiesForWindow(QWindow *window, const QVariantHash &
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::MouseButtons Utils::queryMouseButtons()
|
|
||||||
{
|
|
||||||
// ### FIXME
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -755,12 +755,6 @@ QColor Utils::getFrameBorderColor(const bool active)
|
||||||
return (active ? getAccentColor() : kDefaultDarkGrayColor);
|
return (active ? getAccentColor() : kDefaultDarkGrayColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::MouseButtons Utils::queryMouseButtons()
|
|
||||||
{
|
|
||||||
// ### FIXME
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
||||||
#include "utils_mac.moc"
|
#include "utils_mac.moc"
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <QtCore/qhash.h>
|
#include <QtCore/qhash.h>
|
||||||
#include <QtCore/qloggingcategory.h>
|
#include <QtCore/qloggingcategory.h>
|
||||||
#include <QtCore/qabstracteventdispatcher.h>
|
#include <QtCore/qabstracteventdispatcher.h>
|
||||||
|
#include <QtCore/qtextstream.h>
|
||||||
#include <QtGui/qwindow.h>
|
#include <QtGui/qwindow.h>
|
||||||
#include <QtGui/qguiapplication.h>
|
#include <QtGui/qguiapplication.h>
|
||||||
#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE
|
#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE
|
||||||
|
@ -188,6 +189,7 @@ FRAMELESSHELPER_STRING_CONSTANT(SetActiveWindow)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(RedrawWindow)
|
FRAMELESSHELPER_STRING_CONSTANT(RedrawWindow)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient)
|
FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(DwmFlush)
|
FRAMELESSHELPER_STRING_CONSTANT(DwmFlush)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(GetCursorPos)
|
||||||
|
|
||||||
struct Win32UtilsData
|
struct Win32UtilsData
|
||||||
{
|
{
|
||||||
|
@ -203,6 +205,300 @@ struct Win32UtilsInternal
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
||||||
|
|
||||||
|
struct Win32Message
|
||||||
|
{
|
||||||
|
UINT Code = 0;
|
||||||
|
LPCSTR Str = nullptr;
|
||||||
|
|
||||||
|
[[nodiscard]] friend inline constexpr bool operator==(const Win32Message &lhs, const Win32Message &rhs) noexcept
|
||||||
|
{
|
||||||
|
return (lhs.Code == rhs.Code);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] friend inline constexpr bool operator!=(const Win32Message &lhs, const Win32Message &rhs) noexcept
|
||||||
|
{
|
||||||
|
return !operator==(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] friend inline constexpr bool operator>(const Win32Message &lhs, const Win32Message &rhs) noexcept
|
||||||
|
{
|
||||||
|
return (lhs.Code > rhs.Code);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] friend inline constexpr bool operator>=(const Win32Message &lhs, const Win32Message &rhs) noexcept
|
||||||
|
{
|
||||||
|
return (operator>(lhs, rhs) || operator==(lhs, rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] friend inline constexpr bool operator<(const Win32Message &lhs, const Win32Message &rhs) noexcept
|
||||||
|
{
|
||||||
|
return (operator!=(lhs, rhs) && !operator>(lhs, rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] friend inline constexpr bool operator<=(const Win32Message &lhs, const Win32Message &rhs) noexcept
|
||||||
|
{
|
||||||
|
return (operator<(lhs, rhs) || operator==(lhs, rhs));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFINE_WIN32_MESSAGE(Message) Win32Message{ Message, #Message },
|
||||||
|
static constexpr const std::array<Win32Message, 252> g_win32MessageMap =
|
||||||
|
{
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NULL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CREATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DESTROY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MOVE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SIZE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ACTIVATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SETFOCUS)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_KILLFOCUS)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ENABLE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SETREDRAW)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SETTEXT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETTEXT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETTEXTLENGTH)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PAINT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CLOSE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_QUERYENDSESSION)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_QUERYOPEN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ENDSESSION)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_QUIT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ERASEBKGND)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SYSCOLORCHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SHOWWINDOW)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SETTINGCHANGE) // WM_WININICHANGE
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DEVMODECHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ACTIVATEAPP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_FONTCHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_TIMECHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CANCELMODE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SETCURSOR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MOUSEACTIVATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CHILDACTIVATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_QUEUESYNC)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETMINMAXINFO)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PAINTICON)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ICONERASEBKGND)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NEXTDLGCTL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SPOOLERSTATUS)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DRAWITEM)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MEASUREITEM)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DELETEITEM)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_VKEYTOITEM)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CHARTOITEM)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SETFONT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETFONT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SETHOTKEY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETHOTKEY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_QUERYDRAGICON)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_COMPAREITEM)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETOBJECT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_COMPACTING)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_COMMNOTIFY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_WINDOWPOSCHANGING)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_WINDOWPOSCHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POWER)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_COPYDATA)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CANCELJOURNAL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NOTIFY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_INPUTLANGCHANGEREQUEST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_INPUTLANGCHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_TCARD)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_HELP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_USERCHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NOTIFYFORMAT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CONTEXTMENU)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_STYLECHANGING)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_STYLECHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DISPLAYCHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETICON)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SETICON)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCCREATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCDESTROY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCCALCSIZE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCHITTEST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCPAINT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCACTIVATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETDLGCODE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SYNCPAINT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCMOUSEMOVE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCLBUTTONDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCLBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCLBUTTONDBLCLK)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCRBUTTONDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCRBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCRBUTTONDBLCLK)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCMBUTTONDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCMBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCMBUTTONDBLCLK)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCXBUTTONDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCXBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCXBUTTONDBLCLK)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_INPUT_DEVICE_CHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_INPUT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_KEYDOWN) // WM_KEYFIRST
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_KEYUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CHAR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DEADCHAR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SYSKEYDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SYSKEYUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SYSCHAR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SYSDEADCHAR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_UNICHAR) // WM_KEYLAST
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_STARTCOMPOSITION)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_ENDCOMPOSITION)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_COMPOSITION) // WM_IME_KEYLAST
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_INITDIALOG)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_COMMAND)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SYSCOMMAND)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_TIMER)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_HSCROLL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_VSCROLL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_INITMENU)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_INITMENUPOPUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GESTURE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GESTURENOTIFY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MENUSELECT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MENUCHAR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ENTERIDLE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MENURBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MENUDRAG)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MENUGETOBJECT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_UNINITMENUPOPUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MENUCOMMAND)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CHANGEUISTATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_UPDATEUISTATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_QUERYUISTATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CTLCOLORMSGBOX)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CTLCOLOREDIT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CTLCOLORLISTBOX)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CTLCOLORBTN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CTLCOLORDLG)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CTLCOLORSCROLLBAR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CTLCOLORSTATIC)
|
||||||
|
DEFINE_WIN32_MESSAGE(MN_GETHMENU)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MOUSEMOVE) // WM_MOUSEFIRST
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_LBUTTONDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_LBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_LBUTTONDBLCLK)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_RBUTTONDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_RBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_RBUTTONDBLCLK)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MBUTTONDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MBUTTONDBLCLK)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MOUSEWHEEL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_XBUTTONDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_XBUTTONUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_XBUTTONDBLCLK)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MOUSEHWHEEL) // WM_MOUSELAST
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PARENTNOTIFY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ENTERMENULOOP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_EXITMENULOOP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NEXTMENU)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SIZING)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CAPTURECHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MOVING)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POWERBROADCAST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DEVICECHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDICREATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDIDESTROY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDIACTIVATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDIRESTORE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDINEXT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDIMAXIMIZE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDITILE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDICASCADE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDIICONARRANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDIGETACTIVE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDISETMENU)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ENTERSIZEMOVE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_EXITSIZEMOVE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DROPFILES)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MDIREFRESHMENU)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERDEVICECHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERDEVICEINRANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERDEVICEOUTOFRANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_TOUCH)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCPOINTERUPDATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCPOINTERDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCPOINTERUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERUPDATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERENTER)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERLEAVE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERACTIVATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERCAPTURECHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_TOUCHHITTESTING)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERWHEEL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERHWHEEL)
|
||||||
|
DEFINE_WIN32_MESSAGE(DM_POINTERHITTEST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERROUTEDTO)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERROUTEDAWAY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_POINTERROUTEDRELEASED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_SETCONTEXT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_NOTIFY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_CONTROL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_COMPOSITIONFULL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_SELECT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_CHAR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_REQUEST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_KEYDOWN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_IME_KEYUP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MOUSEHOVER)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_MOUSELEAVE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCMOUSEHOVER)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_NCMOUSELEAVE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_WTSSESSION_CHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_TABLET_FIRST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_TABLET_LAST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DPICHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DPICHANGED_BEFOREPARENT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DPICHANGED_AFTERPARENT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETDPISCALEDSIZE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CUT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_COPY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PASTE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CLEAR)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_UNDO)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_RENDERFORMAT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_RENDERALLFORMATS)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DESTROYCLIPBOARD)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DRAWCLIPBOARD)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PAINTCLIPBOARD)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_VSCROLLCLIPBOARD)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_SIZECLIPBOARD)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_ASKCBFORMATNAME)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CHANGECBCHAIN)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_HSCROLLCLIPBOARD)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_QUERYNEWPALETTE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PALETTEISCHANGING)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PALETTECHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_HOTKEY)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PRINT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PRINTCLIENT)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_APPCOMMAND)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_THEMECHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_CLIPBOARDUPDATE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DWMCOMPOSITIONCHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DWMNCRENDERINGCHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DWMCOLORIZATIONCOLORCHANGED)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DWMWINDOWMAXIMIZEDCHANGE)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DWMSENDICONICTHUMBNAIL)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_DWMSENDICONICLIVEPREVIEWBITMAP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_GETTITLEBARINFOEX)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_HANDHELDFIRST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_HANDHELDLAST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_AFXFIRST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_AFXLAST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PENWINFIRST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_PENWINLAST)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_APP)
|
||||||
|
DEFINE_WIN32_MESSAGE(WM_USER)
|
||||||
|
};
|
||||||
|
#undef DEFINE_WIN32_MESSAGE
|
||||||
|
|
||||||
[[nodiscard]] bool operator==(const POINT &lhs, const POINT &rhs) noexcept
|
[[nodiscard]] bool operator==(const POINT &lhs, const POINT &rhs) noexcept
|
||||||
{
|
{
|
||||||
return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
|
return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
|
||||||
|
@ -530,6 +826,12 @@ Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static inline bool isWin32MessageDebuggingEnabled()
|
||||||
|
{
|
||||||
|
static const bool result = (qEnvironmentVariableIntValue("FRAMELESSHELPER_ENABLE_WIN32_MESSAGE_DEBUGGING") != 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] static inline QByteArray qtNativeEventType()
|
[[nodiscard]] static inline QByteArray qtNativeEventType()
|
||||||
{
|
{
|
||||||
static const auto result = FRAMELESSHELPER_BYTEARRAY_LITERAL("windows_generic_MSG");
|
static const auto result = FRAMELESSHELPER_BYTEARRAY_LITERAL("windows_generic_MSG");
|
||||||
|
@ -556,6 +858,26 @@ Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static inline bool isMouseMessage(const UINT message, bool *isNonClient = nullptr)
|
||||||
|
{
|
||||||
|
if (((message >= WM_MOUSEFIRST) && (message <= WM_MOUSELAST))
|
||||||
|
|| ((message == WM_MOUSEHOVER) || (message == WM_MOUSELEAVE))) {
|
||||||
|
if (isNonClient) {
|
||||||
|
*isNonClient = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (((message >= WM_NCMOUSEMOVE) && (message <= WM_NCMBUTTONDBLCLK))
|
||||||
|
|| ((message >= WM_NCXBUTTONDOWN) && (message <= WM_NCXBUTTONDBLCLK))
|
||||||
|
|| ((message == WM_NCMOUSEHOVER) || (message == WM_NCMOUSELEAVE))) {
|
||||||
|
if (isNonClient) {
|
||||||
|
*isNonClient = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] static inline bool usePureQtImplementation()
|
[[nodiscard]] static inline bool usePureQtImplementation()
|
||||||
{
|
{
|
||||||
static const bool result = FramelessConfig::instance()->isSet(Option::UseCrossPlatformQtImplementation);
|
static const bool result = FramelessConfig::instance()->isSet(Option::UseCrossPlatformQtImplementation);
|
||||||
|
@ -569,6 +891,61 @@ Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
||||||
if (!hWnd) {
|
if (!hWnd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (isWin32MessageDebuggingEnabled()) {
|
||||||
|
const auto it = std::find(g_win32MessageMap.cbegin(), g_win32MessageMap.cend(), Win32Message{ uMsg, nullptr });
|
||||||
|
if (it != g_win32MessageMap.cend()) {
|
||||||
|
QString text = {};
|
||||||
|
QTextStream stream(&text);
|
||||||
|
stream << "Win32 message received: " << it->Str << " (0x"
|
||||||
|
<< QString::number(uMsg, 16).toUpper().rightJustified(4, u'0') << ')';
|
||||||
|
bool isNonClientMouseMessage = false;
|
||||||
|
if (isMouseMessage(uMsg, &isNonClientMouseMessage)) {
|
||||||
|
if (isNonClientMouseMessage) {
|
||||||
|
const auto screenPos = [uMsg, lParam]() -> POINT {
|
||||||
|
if (uMsg == WM_NCMOUSELEAVE) {
|
||||||
|
const DWORD dwScreenPos = ::GetMessagePos();
|
||||||
|
return POINT{ GET_X_LPARAM(dwScreenPos), GET_Y_LPARAM(dwScreenPos) };
|
||||||
|
} else {
|
||||||
|
return POINT{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
POINT clientPos = screenPos;
|
||||||
|
if (::ScreenToClient(hWnd, &clientPos) == FALSE) {
|
||||||
|
WARNING << Utils::getSystemErrorMessage(kScreenToClient);
|
||||||
|
clientPos = {};
|
||||||
|
}
|
||||||
|
stream << ", screen coordinate: POINT(x: " << screenPos.x << ", y: "
|
||||||
|
<< screenPos.y << "), client coordinate: POINT(x: "
|
||||||
|
<< clientPos.x << ", y: " << clientPos.y << ')';
|
||||||
|
} else {
|
||||||
|
const auto clientPos = [hWnd, uMsg, lParam]() -> POINT {
|
||||||
|
if (uMsg == WM_MOUSELEAVE) {
|
||||||
|
const DWORD dwScreenPos = ::GetMessagePos();
|
||||||
|
const auto screenPos = POINT{ GET_X_LPARAM(dwScreenPos), GET_Y_LPARAM(dwScreenPos) };
|
||||||
|
POINT clientPos = screenPos;
|
||||||
|
if (::ScreenToClient(hWnd, &clientPos) == FALSE) {
|
||||||
|
WARNING << Utils::getSystemErrorMessage(kScreenToClient);
|
||||||
|
return {};
|
||||||
|
} else {
|
||||||
|
return clientPos;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return POINT{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
POINT screenPos = clientPos;
|
||||||
|
if (::ClientToScreen(hWnd, &screenPos) == FALSE) {
|
||||||
|
WARNING << Utils::getSystemErrorMessage(kClientToScreen);
|
||||||
|
screenPos = {};
|
||||||
|
}
|
||||||
|
stream << ", screen coordinate: POINT(x: " << screenPos.x << ", y: "
|
||||||
|
<< screenPos.y << "), client coordinate: POINT(x: "
|
||||||
|
<< clientPos.x << ", y: " << clientPos.y << ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG.noquote() << text;
|
||||||
|
}
|
||||||
|
}
|
||||||
const auto windowId = reinterpret_cast<WId>(hWnd);
|
const auto windowId = reinterpret_cast<WId>(hWnd);
|
||||||
const auto it = g_win32UtilsData()->data.constFind(windowId);
|
const auto it = g_win32UtilsData()->data.constFind(windowId);
|
||||||
if (it == g_win32UtilsData()->data.constEnd()) {
|
if (it == g_win32UtilsData()->data.constEnd()) {
|
||||||
|
@ -593,9 +970,16 @@ Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
||||||
message.wParam = wParam;
|
message.wParam = wParam;
|
||||||
message.lParam = lParam;
|
message.lParam = lParam;
|
||||||
message.time = ::GetMessageTime();
|
message.time = ::GetMessageTime();
|
||||||
|
#if 1
|
||||||
const DWORD dwScreenPos = ::GetMessagePos();
|
const DWORD dwScreenPos = ::GetMessagePos();
|
||||||
message.pt.x = GET_X_LPARAM(dwScreenPos);
|
message.pt.x = GET_X_LPARAM(dwScreenPos);
|
||||||
message.pt.y = GET_Y_LPARAM(dwScreenPos);
|
message.pt.y = GET_Y_LPARAM(dwScreenPos);
|
||||||
|
#else
|
||||||
|
if (::GetCursorPos(&message.pt) == FALSE) {
|
||||||
|
WARNING << Utils::getSystemErrorMessage(kGetCursorPos);
|
||||||
|
message.pt = {};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (!isNonClientMessage(uMsg)) {
|
if (!isNonClientMessage(uMsg)) {
|
||||||
if (::ScreenToClient(hWnd, &message.pt) == FALSE) {
|
if (::ScreenToClient(hWnd, &message.pt) == FALSE) {
|
||||||
WARNING << Utils::getSystemErrorMessage(kScreenToClient);
|
WARNING << Utils::getSystemErrorMessage(kScreenToClient);
|
||||||
|
@ -2649,12 +3033,11 @@ bool Utils::removeMicaWindow(const WId windowId)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 Utils::getMouseButtonsAndModifiers(const bool async)
|
quint64 Utils::getKeyState()
|
||||||
{
|
{
|
||||||
quint64 result = 0;
|
quint64 result = 0;
|
||||||
const auto get = [async](const int virtualKey) -> bool {
|
const auto get = [](const int virtualKey) -> bool {
|
||||||
const auto stateCode = (async ? ::GetAsyncKeyState(virtualKey) : ::GetKeyState(virtualKey));
|
return (::GetAsyncKeyState(virtualKey) < 0);
|
||||||
return (stateCode < 0);
|
|
||||||
};
|
};
|
||||||
const bool buttonSwapped = (::GetSystemMetrics(SM_SWAPBUTTON) != FALSE);
|
const bool buttonSwapped = (::GetSystemMetrics(SM_SWAPBUTTON) != FALSE);
|
||||||
if (get(VK_LBUTTON)) {
|
if (get(VK_LBUTTON)) {
|
||||||
|
@ -2663,12 +3046,6 @@ quint64 Utils::getMouseButtonsAndModifiers(const bool async)
|
||||||
if (get(VK_RBUTTON)) {
|
if (get(VK_RBUTTON)) {
|
||||||
result |= (buttonSwapped ? MK_LBUTTON : MK_RBUTTON);
|
result |= (buttonSwapped ? MK_LBUTTON : MK_RBUTTON);
|
||||||
}
|
}
|
||||||
if (get(VK_SHIFT)) {
|
|
||||||
result |= MK_SHIFT;
|
|
||||||
}
|
|
||||||
if (get(VK_CONTROL)) {
|
|
||||||
result |= MK_CONTROL;
|
|
||||||
}
|
|
||||||
if (get(VK_MBUTTON)) {
|
if (get(VK_MBUTTON)) {
|
||||||
result |= MK_MBUTTON;
|
result |= MK_MBUTTON;
|
||||||
}
|
}
|
||||||
|
@ -2681,31 +3058,6 @@ quint64 Utils::getMouseButtonsAndModifiers(const bool async)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::MouseButtons Utils::queryMouseButtons()
|
|
||||||
{
|
|
||||||
const quint64 buttonMask = getMouseButtonsAndModifiers(false);
|
|
||||||
if (buttonMask == 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
Qt::MouseButtons buttons = {};
|
|
||||||
if (buttonMask & MK_LBUTTON) {
|
|
||||||
buttons |= Qt::LeftButton;
|
|
||||||
}
|
|
||||||
if (buttonMask & MK_RBUTTON) {
|
|
||||||
buttons |= Qt::RightButton;
|
|
||||||
}
|
|
||||||
if (buttonMask & MK_MBUTTON) {
|
|
||||||
buttons |= Qt::MiddleButton;
|
|
||||||
}
|
|
||||||
if (buttonMask & MK_XBUTTON1) {
|
|
||||||
buttons |= Qt::XButton1;
|
|
||||||
}
|
|
||||||
if (buttonMask & MK_XBUTTON2) {
|
|
||||||
buttons |= Qt::XButton2;
|
|
||||||
}
|
|
||||||
return buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Utils::isValidWindow(const WId windowId, const bool checkVisible, const bool checkTopLevel)
|
bool Utils::isValidWindow(const WId windowId, const bool checkVisible, const bool checkTopLevel)
|
||||||
{
|
{
|
||||||
Q_ASSERT(windowId);
|
Q_ASSERT(windowId);
|
||||||
|
|
|
@ -853,69 +853,8 @@ bool FramelessQuickHelperPrivate::shouldIgnoreMouseEvents(const QPoint &pos) con
|
||||||
void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::SystemButtonType button,
|
void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::SystemButtonType button,
|
||||||
const QuickGlobal::ButtonState state)
|
const QuickGlobal::ButtonState state)
|
||||||
{
|
{
|
||||||
#ifdef FRAMELESSHELPER_QUICK_NO_PRIVATE
|
|
||||||
Q_UNUSED(button);
|
Q_UNUSED(button);
|
||||||
Q_UNUSED(state);
|
Q_UNUSED(state);
|
||||||
#else // !FRAMELESSHELPER_QUICK_NO_PRIVATE
|
|
||||||
Q_ASSERT(button != QuickGlobal::SystemButtonType::Unknown);
|
|
||||||
if (button == QuickGlobal::SystemButtonType::Unknown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const FramelessQuickHelperData *data = getWindowData();
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QQuickItem *quickButton = nullptr;
|
|
||||||
switch (button) {
|
|
||||||
case QuickGlobal::SystemButtonType::WindowIcon:
|
|
||||||
quickButton = data->windowIconButton;
|
|
||||||
break;
|
|
||||||
case QuickGlobal::SystemButtonType::Help:
|
|
||||||
quickButton = data->contextHelpButton;
|
|
||||||
break;
|
|
||||||
case QuickGlobal::SystemButtonType::Minimize:
|
|
||||||
quickButton = data->minimizeButton;
|
|
||||||
break;
|
|
||||||
case QuickGlobal::SystemButtonType::Maximize:
|
|
||||||
case QuickGlobal::SystemButtonType::Restore:
|
|
||||||
quickButton = data->maximizeButton;
|
|
||||||
break;
|
|
||||||
case QuickGlobal::SystemButtonType::Close:
|
|
||||||
quickButton = data->closeButton;
|
|
||||||
break;
|
|
||||||
case QuickGlobal::SystemButtonType::Unknown:
|
|
||||||
Q_UNREACHABLE_RETURN(void(0));
|
|
||||||
}
|
|
||||||
if (!quickButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto updateButtonState = [state](QQuickItem *btn) -> void {
|
|
||||||
Q_ASSERT(btn);
|
|
||||||
if (!btn) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const QQuickWindow *window = btn->window();
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const QScreen *screen = (window->screen() ? window->screen() : QGuiApplication::primaryScreen());
|
|
||||||
const QPoint globalPos = (screen ? QCursor::pos(screen) : QCursor::pos());
|
|
||||||
const QPoint localPos = btn->mapFromGlobal(globalPos).toPoint();
|
|
||||||
const QPoint scenePos = window->mapFromGlobal(globalPos);
|
|
||||||
const auto underMouse = [btn, &globalPos]() -> bool {
|
|
||||||
const QPointF originPoint = btn->mapToGlobal(QPointF{ 0, 0 });
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
|
||||||
const QSizeF size = btn->size();
|
|
||||||
#else
|
|
||||||
const auto size = QSizeF{ btn->width(), btn->height() };
|
|
||||||
#endif
|
|
||||||
return QRectF{ originPoint, size }.contains(globalPos);
|
|
||||||
}();
|
|
||||||
Utils::emulateQtMouseEvent(btn, window, FRAMELESSHELPER_ENUM_QUICK_TO_CORE(ButtonState, state), globalPos, scenePos, localPos, underMouse, true);
|
|
||||||
};
|
|
||||||
updateButtonState(quickButton);
|
|
||||||
#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowData() const
|
const FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowData() const
|
||||||
|
|
|
@ -803,76 +803,8 @@ bool FramelessWidgetsHelperPrivate::shouldIgnoreMouseEvents(const QPoint &pos) c
|
||||||
|
|
||||||
void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType button, const ButtonState state)
|
void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType button, const ButtonState state)
|
||||||
{
|
{
|
||||||
Q_ASSERT(button != SystemButtonType::Unknown);
|
Q_UNUSED(button);
|
||||||
if (button == SystemButtonType::Unknown) {
|
Q_UNUSED(state);
|
||||||
return;
|
|
||||||
}
|
|
||||||
const FramelessWidgetsHelperData *data = getWindowData();
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QWidget *widgetButton = nullptr;
|
|
||||||
switch (button) {
|
|
||||||
case SystemButtonType::WindowIcon:
|
|
||||||
if (data->windowIconButton) {
|
|
||||||
widgetButton = data->windowIconButton;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SystemButtonType::Help:
|
|
||||||
if (data->contextHelpButton) {
|
|
||||||
widgetButton = data->contextHelpButton;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SystemButtonType::Minimize:
|
|
||||||
if (data->minimizeButton) {
|
|
||||||
widgetButton = data->minimizeButton;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SystemButtonType::Maximize:
|
|
||||||
case SystemButtonType::Restore:
|
|
||||||
if (data->maximizeButton) {
|
|
||||||
widgetButton = data->maximizeButton;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SystemButtonType::Close:
|
|
||||||
if (data->closeButton) {
|
|
||||||
widgetButton = data->closeButton;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SystemButtonType::Unknown:
|
|
||||||
Q_UNREACHABLE_RETURN(void(0));
|
|
||||||
}
|
|
||||||
if (!widgetButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto updateButtonState = [state](QWidget *btn) -> void {
|
|
||||||
Q_ASSERT(btn);
|
|
||||||
if (!btn) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const QWidget *window = btn->window();
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
|
||||||
const QScreen *screen = window->screen();
|
|
||||||
#else
|
|
||||||
const QScreen *screen = QGuiApplication::primaryScreen();
|
|
||||||
#endif
|
|
||||||
const QPoint globalPos = (screen ? QCursor::pos(screen) : QCursor::pos());
|
|
||||||
const QPoint localPos = btn->mapFromGlobal(globalPos);
|
|
||||||
const QPoint scenePos = window->mapFromGlobal(globalPos);
|
|
||||||
#if 0
|
|
||||||
const auto underMouse = [btn, &globalPos]() -> bool {
|
|
||||||
const QPoint originPoint = btn->mapToGlobal(QPoint{ 0, 0 });
|
|
||||||
return QRect{ originPoint, btn->size() }.contains(globalPos);
|
|
||||||
}();
|
|
||||||
#endif
|
|
||||||
const bool hoverEnabled = btn->testAttribute(Qt::WA_Hover);
|
|
||||||
Utils::emulateQtMouseEvent(btn, window->windowHandle(), state, globalPos, scenePos, localPos, btn->underMouse(), hoverEnabled);
|
|
||||||
};
|
|
||||||
updateButtonState(widgetButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessWidgetsHelperPrivate::moveWindowToDesktopCenter()
|
void FramelessWidgetsHelperPrivate::moveWindowToDesktopCenter()
|
||||||
|
|
|
@ -154,9 +154,9 @@ bool StandardSystemButtonPrivate::isActive() const
|
||||||
return m_active;
|
return m_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StandardSystemButtonPrivate::iconSize2() const
|
int StandardSystemButtonPrivate::glyphSize() const
|
||||||
{
|
{
|
||||||
return m_iconSize2.value_or(FramelessManagerPrivate::getIconFont().pointSize());
|
return m_glyphSize.value_or(FramelessManagerPrivate::getIconFont().pointSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandardSystemButtonPrivate::setHoverColor(const QColor &value)
|
void StandardSystemButtonPrivate::setHoverColor(const QColor &value)
|
||||||
|
@ -245,19 +245,19 @@ void StandardSystemButtonPrivate::setActive(const bool value)
|
||||||
Q_EMIT q->activeChanged();
|
Q_EMIT q->activeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandardSystemButtonPrivate::setIconSize2(const int value)
|
void StandardSystemButtonPrivate::setGlyphSize(const int value)
|
||||||
{
|
{
|
||||||
Q_ASSERT(value > 0);
|
Q_ASSERT(value > 0);
|
||||||
if (value <= 0) {
|
if (value <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (iconSize2() == value) {
|
if (glyphSize() == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_iconSize2 = value;
|
m_glyphSize = value;
|
||||||
Q_Q(StandardSystemButton);
|
Q_Q(StandardSystemButton);
|
||||||
q->update();
|
q->update();
|
||||||
Q_EMIT q->iconSize2Changed();
|
Q_EMIT q->glyphSizeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandardSystemButtonPrivate::paintEventHandler(QPaintEvent *event)
|
void StandardSystemButtonPrivate::paintEventHandler(QPaintEvent *event)
|
||||||
|
@ -300,8 +300,8 @@ void StandardSystemButtonPrivate::paintEventHandler(QPaintEvent *event)
|
||||||
}());
|
}());
|
||||||
painter.setFont([this]() -> QFont {
|
painter.setFont([this]() -> QFont {
|
||||||
QFont font = FramelessManagerPrivate::getIconFont();
|
QFont font = FramelessManagerPrivate::getIconFont();
|
||||||
if (m_iconSize2.has_value()) {
|
if (m_glyphSize.has_value()) {
|
||||||
font.setPointSize(m_iconSize2.value());
|
font.setPointSize(m_glyphSize.value());
|
||||||
}
|
}
|
||||||
return font;
|
return font;
|
||||||
}());
|
}());
|
||||||
|
@ -316,8 +316,10 @@ void StandardSystemButtonPrivate::initialize()
|
||||||
FramelessManagerPrivate::initializeIconFont();
|
FramelessManagerPrivate::initializeIconFont();
|
||||||
Q_Q(StandardSystemButton);
|
Q_Q(StandardSystemButton);
|
||||||
q->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
q->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
q->setFixedSize(kDefaultSystemButtonSize);
|
q->setFixedSize(getRecommendedButtonSize());
|
||||||
q->setIconSize(kDefaultSystemButtonIconSize);
|
q->setIconSize(kDefaultSystemButtonIconSize);
|
||||||
|
q->setMouseTracking(true);
|
||||||
|
q->setAttribute(Qt::WA_Hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardSystemButton::StandardSystemButton(QWidget *parent)
|
StandardSystemButton::StandardSystemButton(QWidget *parent)
|
||||||
|
@ -405,10 +407,10 @@ bool StandardSystemButton::isActive() const
|
||||||
return d->isActive();
|
return d->isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
int StandardSystemButton::iconSize2() const
|
int StandardSystemButton::glyphSize() const
|
||||||
{
|
{
|
||||||
Q_D(const StandardSystemButton);
|
Q_D(const StandardSystemButton);
|
||||||
return d->iconSize2();
|
return d->glyphSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandardSystemButton::setPressColor(const QColor &value)
|
void StandardSystemButton::setPressColor(const QColor &value)
|
||||||
|
@ -441,10 +443,10 @@ void StandardSystemButton::setActive(const bool value)
|
||||||
d->setActive(value);
|
d->setActive(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandardSystemButton::setIconSize2(const int value)
|
void StandardSystemButton::setGlyphSize(const int value)
|
||||||
{
|
{
|
||||||
Q_D(StandardSystemButton);
|
Q_D(StandardSystemButton);
|
||||||
d->setIconSize2(value);
|
d->setGlyphSize(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandardSystemButton::paintEvent(QPaintEvent *event)
|
void StandardSystemButton::paintEvent(QPaintEvent *event)
|
||||||
|
|
Loading…
Reference in New Issue