forked from github_mirror/framelesshelper
Compare commits
1 Commits
main
...
wip/snap-l
Author | SHA1 | Date |
---|---|---|
|
0a33aafb5f |
|
@ -259,145 +259,148 @@ Q_NAMESPACE_EXPORT(FRAMELESSHELPER_CORE_API)
|
||||||
[[maybe_unused]] inline const QByteArray kSysMenuDisableRestoreVar
|
[[maybe_unused]] inline const QByteArray kSysMenuDisableRestoreVar
|
||||||
= FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_SYSTEM_MENU_DISABLE_RESTORE");
|
= FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_SYSTEM_MENU_DISABLE_RESTORE");
|
||||||
|
|
||||||
enum class Option
|
enum class Option : quint8
|
||||||
{
|
{
|
||||||
UseCrossPlatformQtImplementation = 0,
|
UseCrossPlatformQtImplementation,
|
||||||
ForceHideWindowFrameBorder = 1,
|
ForceHideWindowFrameBorder,
|
||||||
ForceShowWindowFrameBorder = 2,
|
ForceShowWindowFrameBorder,
|
||||||
DisableWindowsSnapLayout = 3,
|
DisableWindowsSnapLayout,
|
||||||
WindowUseRoundCorners = 4,
|
WindowUseRoundCorners,
|
||||||
CenterWindowBeforeShow = 5,
|
CenterWindowBeforeShow,
|
||||||
EnableBlurBehindWindow = 6,
|
EnableBlurBehindWindow,
|
||||||
ForceNonNativeBackgroundBlur = 7,
|
ForceNonNativeBackgroundBlur,
|
||||||
DisableLazyInitializationForMicaMaterial = 8,
|
DisableLazyInitializationForMicaMaterial,
|
||||||
ForceNativeBackgroundBlur = 9
|
ForceNativeBackgroundBlur
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(Option)
|
Q_ENUM_NS(Option)
|
||||||
|
|
||||||
enum class SystemTheme
|
enum class SystemTheme : quint8
|
||||||
{
|
{
|
||||||
Unknown = -1,
|
Unknown,
|
||||||
Light = 0,
|
Light,
|
||||||
Dark = 1,
|
Dark,
|
||||||
HighContrast = 2
|
HighContrast
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(SystemTheme)
|
Q_ENUM_NS(SystemTheme)
|
||||||
|
|
||||||
enum class SystemButtonType
|
enum class SystemButtonType : quint8
|
||||||
{
|
{
|
||||||
Unknown = -1,
|
Unknown,
|
||||||
WindowIcon = 0,
|
WindowIcon,
|
||||||
Help = 1,
|
Help,
|
||||||
Minimize = 2,
|
Minimize,
|
||||||
Maximize = 3,
|
Maximize,
|
||||||
Restore = 4,
|
Restore,
|
||||||
Close = 5
|
Close
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(SystemButtonType)
|
Q_ENUM_NS(SystemButtonType)
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
enum class DwmColorizationArea
|
enum class DwmColorizationArea : quint8
|
||||||
{
|
{
|
||||||
None = 0,
|
None,
|
||||||
StartMenu_TaskBar_ActionCenter = 1,
|
StartMenu_TaskBar_ActionCenter,
|
||||||
TitleBar_WindowBorder = 2,
|
TitleBar_WindowBorder,
|
||||||
All = 3
|
All
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(DwmColorizationArea)
|
Q_ENUM_NS(DwmColorizationArea)
|
||||||
#endif // Q_OS_WINDOWS
|
#endif // Q_OS_WINDOWS
|
||||||
|
|
||||||
enum class ButtonState
|
enum class ButtonState : quint8
|
||||||
{
|
{
|
||||||
Unspecified = -1,
|
MouseEntered,
|
||||||
Hovered = 0,
|
MouseLeaved,
|
||||||
Pressed = 1,
|
MouseMoving,
|
||||||
Clicked = 2
|
MousePressed,
|
||||||
|
MouseReleased
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(ButtonState)
|
Q_ENUM_NS(ButtonState)
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
enum class WindowsVersion
|
enum class WindowsVersion : quint8
|
||||||
{
|
{
|
||||||
_2000 = 0,
|
_2000,
|
||||||
_XP = 1,
|
_XP,
|
||||||
_XP_64 = 2,
|
_XP_64,
|
||||||
|
_Vista,
|
||||||
|
_Vista_SP1,
|
||||||
|
_Vista_SP2,
|
||||||
|
_7,
|
||||||
|
_7_SP1,
|
||||||
|
_8,
|
||||||
|
_8_1,
|
||||||
|
_8_1_Update1,
|
||||||
|
_10_1507,
|
||||||
|
_10_1511,
|
||||||
|
_10_1607,
|
||||||
|
_10_1703,
|
||||||
|
_10_1709,
|
||||||
|
_10_1803,
|
||||||
|
_10_1809,
|
||||||
|
_10_1903,
|
||||||
|
_10_1909,
|
||||||
|
_10_2004,
|
||||||
|
_10_20H2,
|
||||||
|
_10_21H1,
|
||||||
|
_10_21H2,
|
||||||
|
_10_22H2,
|
||||||
|
_11_21H2,
|
||||||
|
_11_22H2,
|
||||||
|
|
||||||
_WS_03 = _XP_64, // Windows Server 2003
|
_WS_03 = _XP_64, // Windows Server 2003
|
||||||
_Vista = 3,
|
|
||||||
_Vista_SP1 = 4,
|
|
||||||
_Vista_SP2 = 5,
|
|
||||||
_7 = 6,
|
|
||||||
_7_SP1 = 7,
|
|
||||||
_8 = 8,
|
|
||||||
_8_1 = 9,
|
|
||||||
_8_1_Update1 = 10,
|
|
||||||
_10_1507 = 11,
|
|
||||||
_10_1511 = 12,
|
|
||||||
_10_1607 = 13,
|
|
||||||
_10_1703 = 14,
|
|
||||||
_10_1709 = 15,
|
|
||||||
_10_1803 = 16,
|
|
||||||
_10_1809 = 17,
|
|
||||||
_10_1903 = 18,
|
|
||||||
_10_1909 = 19,
|
|
||||||
_10_2004 = 20,
|
|
||||||
_10_20H2 = 21,
|
|
||||||
_10_21H1 = 22,
|
|
||||||
_10_21H2 = 23,
|
|
||||||
_10_22H2 = 24,
|
|
||||||
_10 = _10_1507,
|
_10 = _10_1507,
|
||||||
_11_21H2 = 25,
|
|
||||||
_11_22H2 = 26,
|
|
||||||
_11 = _11_21H2,
|
_11 = _11_21H2,
|
||||||
|
|
||||||
Latest = _11_22H2
|
Latest = _11_22H2
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(WindowsVersion)
|
Q_ENUM_NS(WindowsVersion)
|
||||||
#endif // Q_OS_WINDOWS
|
#endif // Q_OS_WINDOWS
|
||||||
|
|
||||||
enum class BlurMode
|
enum class BlurMode : quint8
|
||||||
{
|
{
|
||||||
Disable = 0, // Do not enable blur behind window
|
Disable, // Do not enable blur behind window
|
||||||
Default = 1, // Use platform default blur mode
|
Default, // Use platform default blur mode
|
||||||
Windows_Aero = 2, // Windows only, use the traditional DWM blur
|
Windows_Aero, // Windows only, use the traditional DWM blur
|
||||||
Windows_Acrylic = 3, // Windows only, use the Acrylic blur
|
Windows_Acrylic, // Windows only, use the Acrylic blur
|
||||||
Windows_Mica = 4, // Windows only, use the Mica material
|
Windows_Mica, // Windows only, use the Mica material
|
||||||
Windows_MicaAlt = 5 // Windows only, use the Mica Alt material
|
Windows_MicaAlt // Windows only, use the Mica Alt material
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(BlurMode)
|
Q_ENUM_NS(BlurMode)
|
||||||
|
|
||||||
enum class WallpaperAspectStyle
|
enum class WallpaperAspectStyle : quint8
|
||||||
{
|
{
|
||||||
Fill = 0, // Keep aspect ratio to fill, expand/crop if necessary.
|
Fill, // Keep aspect ratio to fill, expand/crop if necessary.
|
||||||
Fit = 1, // Keep aspect ratio to fill, but don't expand/crop.
|
Fit, // Keep aspect ratio to fill, but don't expand/crop.
|
||||||
Stretch = 2, // Ignore aspect ratio to fill.
|
Stretch, // Ignore aspect ratio to fill.
|
||||||
Tile = 3,
|
Tile,
|
||||||
Center = 4,
|
Center,
|
||||||
Span = 5 // ???
|
Span // ???
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(WallpaperAspectStyle)
|
Q_ENUM_NS(WallpaperAspectStyle)
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
enum class RegistryRootKey
|
enum class RegistryRootKey : quint8
|
||||||
{
|
{
|
||||||
ClassesRoot = 0,
|
ClassesRoot,
|
||||||
CurrentUser = 1,
|
CurrentUser,
|
||||||
LocalMachine = 2,
|
LocalMachine,
|
||||||
Users = 3,
|
Users,
|
||||||
PerformanceData = 4,
|
PerformanceData,
|
||||||
CurrentConfig = 5,
|
CurrentConfig,
|
||||||
DynData = 6,
|
DynData,
|
||||||
CurrentUserLocalSettings = 7,
|
CurrentUserLocalSettings,
|
||||||
PerformanceText = 8,
|
PerformanceText,
|
||||||
PerformanceNlsText = 9
|
PerformanceNlsText
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(RegistryRootKey)
|
Q_ENUM_NS(RegistryRootKey)
|
||||||
#endif // Q_OS_WINDOWS
|
#endif // Q_OS_WINDOWS
|
||||||
|
|
||||||
enum class WindowEdge : quint32
|
enum class WindowEdge : quint8
|
||||||
{
|
{
|
||||||
Left = 0x00000001,
|
Left = 1 << 0,
|
||||||
Top = 0x00000002,
|
Top = 1 << 1,
|
||||||
Right = 0x00000004,
|
Right = 1 << 2,
|
||||||
Bottom = 0x00000008
|
Bottom = 1 << 3
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(WindowEdge)
|
Q_ENUM_NS(WindowEdge)
|
||||||
Q_DECLARE_FLAGS(WindowEdges, WindowEdge)
|
Q_DECLARE_FLAGS(WindowEdges, WindowEdge)
|
||||||
|
@ -405,23 +408,23 @@ Q_FLAG_NS(WindowEdges)
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(WindowEdges)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(WindowEdges)
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
enum class DpiAwareness
|
enum class DpiAwareness : quint8
|
||||||
{
|
{
|
||||||
Unknown = -1,
|
Unknown,
|
||||||
Unaware = 0,
|
Unaware,
|
||||||
System = 1,
|
System,
|
||||||
PerMonitor = 2,
|
PerMonitor,
|
||||||
PerMonitorVersion2 = 3,
|
PerMonitorVersion2,
|
||||||
Unaware_GdiScaled = 4
|
Unaware_GdiScaled
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(DpiAwareness)
|
Q_ENUM_NS(DpiAwareness)
|
||||||
#endif // Q_OS_WINDOWS
|
#endif // Q_OS_WINDOWS
|
||||||
|
|
||||||
enum class WindowCornerStyle
|
enum class WindowCornerStyle : quint8
|
||||||
{
|
{
|
||||||
Default = 0,
|
Default,
|
||||||
Square = 1,
|
Square,
|
||||||
Round = 2
|
Round
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(WindowCornerStyle)
|
Q_ENUM_NS(WindowCornerStyle)
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ using ScreenToWindowCallback = std::function<QPoint(const QPoint &)>;
|
||||||
using IsInsideSystemButtonsCallback = std::function<bool(const QPoint &, Global::SystemButtonType *)>;
|
using IsInsideSystemButtonsCallback = std::function<bool(const QPoint &, Global::SystemButtonType *)>;
|
||||||
using IsInsideTitleBarDraggableAreaCallback = std::function<bool(const QPoint &)>;
|
using IsInsideTitleBarDraggableAreaCallback = std::function<bool(const QPoint &)>;
|
||||||
using GetWindowDevicePixelRatioCallback = std::function<qreal()>;
|
using GetWindowDevicePixelRatioCallback = std::function<qreal()>;
|
||||||
using SetSystemButtonStateCallback = std::function<void(const Global::SystemButtonType, const Global::ButtonState)>;
|
using SetSystemButtonStateCallback = std::function<void(const Global::SystemButtonType, const Global::ButtonState, const QPoint &)>;
|
||||||
using GetWindowIdCallback = std::function<WId()>;
|
using GetWindowIdCallback = std::function<WId()>;
|
||||||
using ShouldIgnoreMouseEventsCallback = std::function<bool(const QPoint &)>;
|
using ShouldIgnoreMouseEventsCallback = std::function<bool(const QPoint &)>;
|
||||||
using ShowSystemMenuCallback = std::function<void(const QPoint &)>;
|
using ShowSystemMenuCallback = std::function<void(const QPoint &)>;
|
||||||
|
|
|
@ -90,7 +90,7 @@ public:
|
||||||
explicit QuickGlobal(QObject *parent = nullptr);
|
explicit QuickGlobal(QObject *parent = nullptr);
|
||||||
~QuickGlobal() override;
|
~QuickGlobal() override;
|
||||||
|
|
||||||
enum class SystemTheme
|
enum class SystemTheme : quint8
|
||||||
{
|
{
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemTheme, Unknown)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemTheme, Unknown)
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemTheme, Light)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemTheme, Light)
|
||||||
|
@ -99,7 +99,7 @@ public:
|
||||||
};
|
};
|
||||||
Q_ENUM(SystemTheme)
|
Q_ENUM(SystemTheme)
|
||||||
|
|
||||||
enum class SystemButtonType
|
enum class SystemButtonType : quint8
|
||||||
{
|
{
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemButtonType, Unknown)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemButtonType, Unknown)
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemButtonType, WindowIcon)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(SystemButtonType, WindowIcon)
|
||||||
|
@ -111,16 +111,17 @@ public:
|
||||||
};
|
};
|
||||||
Q_ENUM(SystemButtonType)
|
Q_ENUM(SystemButtonType)
|
||||||
|
|
||||||
enum class ButtonState
|
enum class ButtonState : quint8
|
||||||
{
|
{
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Unspecified)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, MouseEntered)
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Hovered)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, MouseLeaved)
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Pressed)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, MouseMoving)
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, Clicked)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, MousePressed)
|
||||||
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(ButtonState, MouseReleased)
|
||||||
};
|
};
|
||||||
Q_ENUM(ButtonState)
|
Q_ENUM(ButtonState)
|
||||||
|
|
||||||
enum class BlurMode
|
enum class BlurMode : quint8
|
||||||
{
|
{
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Disable)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Disable)
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Default)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(BlurMode, Default)
|
||||||
|
@ -131,7 +132,7 @@ public:
|
||||||
};
|
};
|
||||||
Q_ENUM(BlurMode)
|
Q_ENUM(BlurMode)
|
||||||
|
|
||||||
enum class WindowEdge : quint32
|
enum class WindowEdge : quint8
|
||||||
{
|
{
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowEdge, Left)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowEdge, Left)
|
||||||
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowEdge, Top)
|
FRAMELESSHELPER_QUICK_ENUM_VALUE(WindowEdge, Top)
|
||||||
|
|
|
@ -93,7 +93,7 @@ private:
|
||||||
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const;
|
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const;
|
||||||
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
||||||
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
||||||
void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
|
void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state, const QPoint &globalPos);
|
||||||
Q_NODISCARD QuickHelperData getWindowData() const;
|
Q_NODISCARD QuickHelperData getWindowData() const;
|
||||||
Q_NODISCARD QuickHelperData *getWindowDataMutable() const;
|
Q_NODISCARD QuickHelperData *getWindowDataMutable() const;
|
||||||
void rebindWindow();
|
void rebindWindow();
|
||||||
|
|
|
@ -94,7 +94,7 @@ private:
|
||||||
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, Global::SystemButtonType *button) const;
|
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, Global::SystemButtonType *button) const;
|
||||||
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
||||||
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
||||||
void setSystemButtonState(const Global::SystemButtonType button, const Global::ButtonState state);
|
void setSystemButtonState(const Global::SystemButtonType button, const Global::ButtonState state, const QPoint &globalPos);
|
||||||
Q_NODISCARD QWidget *findTopLevelWindow() const;
|
Q_NODISCARD QWidget *findTopLevelWindow() const;
|
||||||
Q_NODISCARD WidgetsHelperData getWindowData() const;
|
Q_NODISCARD WidgetsHelperData getWindowData() const;
|
||||||
Q_NODISCARD WidgetsHelperData *getWindowDataMutable() const;
|
Q_NODISCARD WidgetsHelperData *getWindowDataMutable() const;
|
||||||
|
|
|
@ -115,14 +115,14 @@ void ChromePalettePrivate::refresh()
|
||||||
titleBarInactiveForegroundColor_sys = kDefaultDarkGrayColor;
|
titleBarInactiveForegroundColor_sys = kDefaultDarkGrayColor;
|
||||||
chromeButtonNormalColor_sys = kDefaultTransparentColor;
|
chromeButtonNormalColor_sys = kDefaultTransparentColor;
|
||||||
chromeButtonHoverColor_sys =
|
chromeButtonHoverColor_sys =
|
||||||
Utils::calculateSystemButtonBackgroundColor(SystemButtonType::Minimize, ButtonState::Hovered);
|
Utils::calculateSystemButtonBackgroundColor(SystemButtonType::Minimize, ButtonState::MouseEntered);
|
||||||
chromeButtonPressColor_sys =
|
chromeButtonPressColor_sys =
|
||||||
Utils::calculateSystemButtonBackgroundColor(SystemButtonType::Minimize, ButtonState::Pressed);
|
Utils::calculateSystemButtonBackgroundColor(SystemButtonType::Minimize, ButtonState::MousePressed);
|
||||||
closeButtonNormalColor_sys = kDefaultTransparentColor;
|
closeButtonNormalColor_sys = kDefaultTransparentColor;
|
||||||
closeButtonHoverColor_sys =
|
closeButtonHoverColor_sys =
|
||||||
Utils::calculateSystemButtonBackgroundColor(SystemButtonType::Close, ButtonState::Hovered);
|
Utils::calculateSystemButtonBackgroundColor(SystemButtonType::Close, ButtonState::MouseEntered);
|
||||||
closeButtonPressColor_sys =
|
closeButtonPressColor_sys =
|
||||||
Utils::calculateSystemButtonBackgroundColor(SystemButtonType::Close, ButtonState::Pressed);
|
Utils::calculateSystemButtonBackgroundColor(SystemButtonType::Close, ButtonState::MousePressed);
|
||||||
Q_Q(ChromePalette);
|
Q_Q(ChromePalette);
|
||||||
Q_EMIT q->titleBarActiveBackgroundColorChanged();
|
Q_EMIT q->titleBarActiveBackgroundColorChanged();
|
||||||
Q_EMIT q->titleBarInactiveBackgroundColorChanged();
|
Q_EMIT q->titleBarInactiveBackgroundColorChanged();
|
||||||
|
|
|
@ -158,39 +158,38 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||||
// Hit-testing event should not be considered as a mouse event.
|
// Hit-testing event should not be considered as a mouse event.
|
||||||
const bool isMouseEvent = (((uMsg >= WM_MOUSEFIRST) && (uMsg <= WM_MOUSELAST)) ||
|
const bool isMouseEvent = (((uMsg >= WM_MOUSEFIRST) && (uMsg <= WM_MOUSELAST)) ||
|
||||||
((uMsg >= WM_NCMOUSEMOVE) && (uMsg <= WM_NCXBUTTONDBLCLK)));
|
((uMsg >= WM_NCMOUSEMOVE) && (uMsg <= WM_NCXBUTTONDBLCLK)));
|
||||||
const auto releaseButtons = [&data](const std::optional<SystemButtonType> exclude) -> void {
|
const auto resetButtons = [&data](const std::optional<SystemButtonType> exclude, const QPoint &globalPos) -> void {
|
||||||
static constexpr const auto defaultButtonState = ButtonState::Unspecified;
|
|
||||||
const SystemButtonType button = exclude.value_or(SystemButtonType::Unknown);
|
const SystemButtonType button = exclude.value_or(SystemButtonType::Unknown);
|
||||||
if (button != SystemButtonType::WindowIcon) {
|
if (button != SystemButtonType::WindowIcon) {
|
||||||
data.params.setSystemButtonState(SystemButtonType::WindowIcon, defaultButtonState);
|
data.params.setSystemButtonState(SystemButtonType::WindowIcon, ButtonState::MouseLeaved, globalPos);
|
||||||
}
|
}
|
||||||
if (button != SystemButtonType::Help) {
|
if (button != SystemButtonType::Help) {
|
||||||
data.params.setSystemButtonState(SystemButtonType::Help, defaultButtonState);
|
data.params.setSystemButtonState(SystemButtonType::Help, ButtonState::MouseLeaved, globalPos);
|
||||||
}
|
}
|
||||||
if (button != SystemButtonType::Minimize) {
|
if (button != SystemButtonType::Minimize) {
|
||||||
data.params.setSystemButtonState(SystemButtonType::Minimize, defaultButtonState);
|
data.params.setSystemButtonState(SystemButtonType::Minimize, ButtonState::MouseLeaved, globalPos);
|
||||||
}
|
}
|
||||||
if (button != SystemButtonType::Maximize) {
|
if (button != SystemButtonType::Maximize) {
|
||||||
data.params.setSystemButtonState(SystemButtonType::Maximize, defaultButtonState);
|
data.params.setSystemButtonState(SystemButtonType::Maximize, ButtonState::MouseLeaved, globalPos);
|
||||||
}
|
}
|
||||||
if (button != SystemButtonType::Restore) {
|
if (button != SystemButtonType::Restore) {
|
||||||
data.params.setSystemButtonState(SystemButtonType::Restore, defaultButtonState);
|
data.params.setSystemButtonState(SystemButtonType::Restore, ButtonState::MouseLeaved, globalPos);
|
||||||
}
|
}
|
||||||
if (button != SystemButtonType::Close) {
|
if (button != SystemButtonType::Close) {
|
||||||
data.params.setSystemButtonState(SystemButtonType::Close, defaultButtonState);
|
data.params.setSystemButtonState(SystemButtonType::Close, ButtonState::MouseLeaved, globalPos);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const auto hoverButton = [&releaseButtons, &data](const SystemButtonType button) -> void {
|
const auto hoverButton = [&resetButtons, &data](const SystemButtonType button, const QPoint &globalPos) -> void {
|
||||||
releaseButtons(button);
|
resetButtons(button, globalPos);
|
||||||
data.params.setSystemButtonState(button, ButtonState::Hovered);
|
data.params.setSystemButtonState(button, ButtonState::MouseMoving, globalPos);
|
||||||
};
|
};
|
||||||
const auto pressButton = [&releaseButtons, &data](const SystemButtonType button) -> void {
|
const auto pressButton = [&resetButtons, &data](const SystemButtonType button, const QPoint &globalPos) -> void {
|
||||||
releaseButtons(button);
|
resetButtons(button, globalPos);
|
||||||
data.params.setSystemButtonState(button, ButtonState::Pressed);
|
data.params.setSystemButtonState(button, ButtonState::MousePressed, globalPos);
|
||||||
};
|
};
|
||||||
const auto clickButton = [&releaseButtons, &data](const SystemButtonType button) -> void {
|
const auto releaseButton = [&resetButtons, &data](const SystemButtonType button, const QPoint &globalPos) -> void {
|
||||||
releaseButtons(button);
|
resetButtons(button, globalPos);
|
||||||
data.params.setSystemButtonState(button, ButtonState::Clicked);
|
data.params.setSystemButtonState(button, ButtonState::MouseReleased, globalPos);
|
||||||
};
|
};
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
case WM_NCHITTEST: {
|
case WM_NCHITTEST: {
|
||||||
|
@ -235,32 +234,33 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||||
// it can update its visuals.
|
// it can update its visuals.
|
||||||
// - If we're over a button, hover it.
|
// - If we're over a button, hover it.
|
||||||
// - If we're over _anything else_, stop hovering the buttons.
|
// - If we're over _anything else_, stop hovering the buttons.
|
||||||
|
const QPoint globalPos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||||
switch (wParam) {
|
switch (wParam) {
|
||||||
case HTTOP:
|
case HTTOP:
|
||||||
case HTCAPTION: {
|
case HTCAPTION: {
|
||||||
releaseButtons(std::nullopt);
|
resetButtons(std::nullopt, globalPos);
|
||||||
// Pass caption-related nonclient messages to the parent window.
|
// Pass caption-related nonclient messages to the parent window.
|
||||||
// Make sure to do this for the HTTOP, which is the top resize
|
// Make sure to do this for the HTTOP, which is the top resize
|
||||||
// border, so we can resize the window on the top.
|
// border, so we can resize the window on the top.
|
||||||
return SendMessageW(parentWindowHandle, uMsg, wParam, lParam);
|
return SendMessageW(parentWindowHandle, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
case HTSYSMENU:
|
case HTSYSMENU:
|
||||||
hoverButton(SystemButtonType::WindowIcon);
|
hoverButton(SystemButtonType::WindowIcon, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTHELP:
|
case HTHELP:
|
||||||
hoverButton(SystemButtonType::Help);
|
hoverButton(SystemButtonType::Help, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTREDUCE:
|
case HTREDUCE:
|
||||||
hoverButton(SystemButtonType::Minimize);
|
hoverButton(SystemButtonType::Minimize, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTZOOM:
|
case HTZOOM:
|
||||||
hoverButton(SystemButtonType::Maximize);
|
hoverButton(SystemButtonType::Maximize, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTCLOSE:
|
case HTCLOSE:
|
||||||
hoverButton(SystemButtonType::Close);
|
hoverButton(SystemButtonType::Close, globalPos);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
releaseButtons(std::nullopt);
|
resetButtons(std::nullopt, globalPos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// If we haven't previously asked for mouse tracking, request mouse
|
// If we haven't previously asked for mouse tracking, request mouse
|
||||||
|
@ -291,7 +291,8 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||||
case WM_NCMOUSELEAVE:
|
case WM_NCMOUSELEAVE:
|
||||||
case WM_MOUSELEAVE: {
|
case WM_MOUSELEAVE: {
|
||||||
// When the mouse leaves the drag rect, make sure to dismiss any hover.
|
// When the mouse leaves the drag rect, make sure to dismiss any hover.
|
||||||
releaseButtons(std::nullopt);
|
const DWORD pos = GetMessagePos();
|
||||||
|
resetButtons(std::nullopt, {GET_X_LPARAM(pos), GET_Y_LPARAM(pos)});
|
||||||
const QMutexLocker locker(&g_win32Helper()->mutex);
|
const QMutexLocker locker(&g_win32Helper()->mutex);
|
||||||
g_win32Helper()->data[parentWindowId].trackingMouse = false;
|
g_win32Helper()->data[parentWindowId].trackingMouse = false;
|
||||||
} break;
|
} break;
|
||||||
|
@ -307,6 +308,7 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||||
// If it's not in a caption button, then just forward the message along
|
// If it's not in a caption button, then just forward the message along
|
||||||
// to the root HWND. Make sure to do this for the HTTOP, which is the
|
// to the root HWND. Make sure to do this for the HTTOP, which is the
|
||||||
// top resize border.
|
// top resize border.
|
||||||
|
const QPoint globalPos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||||
switch (wParam) {
|
switch (wParam) {
|
||||||
case HTTOP:
|
case HTTOP:
|
||||||
case HTCAPTION:
|
case HTCAPTION:
|
||||||
|
@ -315,19 +317,19 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||||
// The buttons won't work as you'd expect; we need to handle those
|
// The buttons won't work as you'd expect; we need to handle those
|
||||||
// ourselves.
|
// ourselves.
|
||||||
case HTSYSMENU:
|
case HTSYSMENU:
|
||||||
pressButton(SystemButtonType::WindowIcon);
|
pressButton(SystemButtonType::WindowIcon, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTHELP:
|
case HTHELP:
|
||||||
pressButton(SystemButtonType::Help);
|
pressButton(SystemButtonType::Help, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTREDUCE:
|
case HTREDUCE:
|
||||||
pressButton(SystemButtonType::Minimize);
|
pressButton(SystemButtonType::Minimize, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTZOOM:
|
case HTZOOM:
|
||||||
pressButton(SystemButtonType::Maximize);
|
pressButton(SystemButtonType::Maximize, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTCLOSE:
|
case HTCLOSE:
|
||||||
pressButton(SystemButtonType::Close);
|
pressButton(SystemButtonType::Close, globalPos);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -340,6 +342,7 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||||
//
|
//
|
||||||
// If it's not in a caption button, then just forward the message along
|
// If it's not in a caption button, then just forward the message along
|
||||||
// to the root HWND.
|
// to the root HWND.
|
||||||
|
const QPoint globalPos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||||
switch (wParam) {
|
switch (wParam) {
|
||||||
case HTTOP:
|
case HTTOP:
|
||||||
case HTCAPTION:
|
case HTCAPTION:
|
||||||
|
@ -347,19 +350,19 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||||
return SendMessageW(parentWindowHandle, uMsg, wParam, lParam);
|
return SendMessageW(parentWindowHandle, uMsg, wParam, lParam);
|
||||||
// The buttons won't work as you'd expect; we need to handle those ourselves.
|
// The buttons won't work as you'd expect; we need to handle those ourselves.
|
||||||
case HTSYSMENU:
|
case HTSYSMENU:
|
||||||
clickButton(SystemButtonType::WindowIcon);
|
releaseButton(SystemButtonType::WindowIcon, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTHELP:
|
case HTHELP:
|
||||||
clickButton(SystemButtonType::Help);
|
releaseButton(SystemButtonType::Help, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTREDUCE:
|
case HTREDUCE:
|
||||||
clickButton(SystemButtonType::Minimize);
|
releaseButton(SystemButtonType::Minimize, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTZOOM:
|
case HTZOOM:
|
||||||
clickButton(SystemButtonType::Maximize);
|
releaseButton(SystemButtonType::Maximize, globalPos);
|
||||||
break;
|
break;
|
||||||
case HTCLOSE:
|
case HTCLOSE:
|
||||||
clickButton(SystemButtonType::Close);
|
releaseButton(SystemButtonType::Close, globalPos);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -127,7 +127,7 @@ static Q_LOGGING_CATEGORY(lcCoreGlobal, "wangwenx190.framelesshelper.core.global
|
||||||
using namespace Global;
|
using namespace Global;
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
static_assert(std::size(WindowsVersions) == (static_cast<int>(WindowsVersion::Latest) + 1));
|
static_assert(std::size(WindowsVersions) == (static_cast<quint8>(WindowsVersion::Latest) + 1));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
|
|
|
@ -265,12 +265,12 @@ bool Utils::isThemeChangeEvent(const QEvent * const event)
|
||||||
|
|
||||||
QColor Utils::calculateSystemButtonBackgroundColor(const SystemButtonType button, const ButtonState state)
|
QColor Utils::calculateSystemButtonBackgroundColor(const SystemButtonType button, const ButtonState state)
|
||||||
{
|
{
|
||||||
if (state == ButtonState::Unspecified) {
|
if (state == ButtonState::MouseLeaved) {
|
||||||
return kDefaultTransparentColor;
|
return kDefaultTransparentColor;
|
||||||
}
|
}
|
||||||
const bool isClose = (button == SystemButtonType::Close);
|
const bool isClose = (button == SystemButtonType::Close);
|
||||||
const bool isTitleColor = isTitleBarColorized();
|
const bool isTitleColor = isTitleBarColorized();
|
||||||
const bool isHovered = (state == ButtonState::Hovered);
|
const bool isPressed = (state == ButtonState::MousePressed);
|
||||||
const auto result = [isClose, isTitleColor]() -> QColor {
|
const auto result = [isClose, isTitleColor]() -> QColor {
|
||||||
if (isClose) {
|
if (isClose) {
|
||||||
return kDefaultSystemCloseButtonBackgroundColor;
|
return kDefaultSystemCloseButtonBackgroundColor;
|
||||||
|
@ -289,12 +289,12 @@ QColor Utils::calculateSystemButtonBackgroundColor(const SystemButtonType button
|
||||||
return kDefaultSystemButtonBackgroundColor;
|
return kDefaultSystemButtonBackgroundColor;
|
||||||
}();
|
}();
|
||||||
if (isClose) {
|
if (isClose) {
|
||||||
return (isHovered ? result.lighter(110) : result.lighter(140));
|
return (isPressed ? result.lighter(140) : result.lighter(110));
|
||||||
}
|
}
|
||||||
if (!isTitleColor) {
|
if (!isTitleColor) {
|
||||||
return (isHovered ? result.lighter(110) : result);
|
return (isPressed ? result : result.lighter(110));
|
||||||
}
|
}
|
||||||
return (isHovered ? result.lighter(150) : result.lighter(120));
|
return (isPressed ? result.lighter(120) : result.lighter(150));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utils::shouldAppsUseDarkMode()
|
bool Utils::shouldAppsUseDarkMode()
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
#include <QtCore/qtimer.h>
|
#include <QtCore/qtimer.h>
|
||||||
#include <QtCore/qeventloop.h>
|
#include <QtCore/qeventloop.h>
|
||||||
#include <QtCore/qloggingcategory.h>
|
#include <QtCore/qloggingcategory.h>
|
||||||
|
#include <QtCore/qcoreevent.h>
|
||||||
|
#include <QtCore/qcoreapplication.h>
|
||||||
|
#include <QtGui/qevent.h>
|
||||||
#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE
|
#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE
|
||||||
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
# include <QtGui/qpa/qplatformwindow.h> // For QWINDOWSIZE_MAX
|
# include <QtGui/qpa/qplatformwindow.h> // For QWINDOWSIZE_MAX
|
||||||
|
@ -44,8 +47,7 @@
|
||||||
# include <QtGui/private/qwindow_p.h> // For QWINDOWSIZE_MAX
|
# include <QtGui/private/qwindow_p.h> // For QWINDOWSIZE_MAX
|
||||||
# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
# include <QtQuick/private/qquickitem_p.h>
|
# include <QtQuick/private/qquickitem_p.h>
|
||||||
# include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
|
# include <QtQuickTemplates2/private/qquickcontrol_p.h>
|
||||||
# include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h>
|
|
||||||
#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE
|
#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE
|
||||||
|
|
||||||
#ifndef QWINDOWSIZE_MAX
|
#ifndef QWINDOWSIZE_MAX
|
||||||
|
@ -213,9 +215,9 @@ void FramelessQuickHelperPrivate::attach()
|
||||||
};
|
};
|
||||||
params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
||||||
params.getWindowDevicePixelRatio = [window]() -> qreal { return window->effectiveDevicePixelRatio(); };
|
params.getWindowDevicePixelRatio = [window]() -> qreal { return window->effectiveDevicePixelRatio(); };
|
||||||
params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void {
|
params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state, const QPoint &globalPos) -> void {
|
||||||
setSystemButtonState(FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemButtonType, button),
|
setSystemButtonState(FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemButtonType, button),
|
||||||
FRAMELESSHELPER_ENUM_CORE_TO_QUICK(ButtonState, state));
|
FRAMELESSHELPER_ENUM_CORE_TO_QUICK(ButtonState, state), globalPos);
|
||||||
};
|
};
|
||||||
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||||
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
|
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
|
||||||
|
@ -297,6 +299,9 @@ void FramelessQuickHelperPrivate::setSystemButton(QQuickItem *item, const QuickG
|
||||||
data->closeButton = item;
|
data->closeButton = item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (const auto control = qobject_cast<QQuickControl *>(item)) {
|
||||||
|
control->setHoverEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickHelperPrivate::setHitTestVisible(QQuickItem *item, const bool visible)
|
void FramelessQuickHelperPrivate::setHitTestVisible(QQuickItem *item, const bool visible)
|
||||||
|
@ -814,7 +819,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,
|
||||||
|
const QPoint &nativeGlobalPos)
|
||||||
{
|
{
|
||||||
#ifdef FRAMELESSHELPER_QUICK_NO_PRIVATE
|
#ifdef FRAMELESSHELPER_QUICK_NO_PRIVATE
|
||||||
Q_UNUSED(button);
|
Q_UNUSED(button);
|
||||||
|
@ -825,76 +831,102 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const QuickHelperData data = getWindowData();
|
const QuickHelperData data = getWindowData();
|
||||||
QQuickAbstractButton *quickButton = nullptr;
|
QQuickItem *quickButton = nullptr;
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case QuickGlobal::SystemButtonType::Unknown:
|
case QuickGlobal::SystemButtonType::Unknown:
|
||||||
Q_UNREACHABLE_RETURN(void(0));
|
Q_UNREACHABLE_RETURN(void(0));
|
||||||
case QuickGlobal::SystemButtonType::WindowIcon:
|
case QuickGlobal::SystemButtonType::WindowIcon:
|
||||||
if (data.windowIconButton) {
|
if (data.windowIconButton) {
|
||||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.windowIconButton)) {
|
quickButton = data.windowIconButton;
|
||||||
quickButton = btn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Help:
|
case QuickGlobal::SystemButtonType::Help:
|
||||||
if (data.contextHelpButton) {
|
if (data.contextHelpButton) {
|
||||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.contextHelpButton)) {
|
quickButton = data.contextHelpButton;
|
||||||
quickButton = btn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Minimize:
|
case QuickGlobal::SystemButtonType::Minimize:
|
||||||
if (data.minimizeButton) {
|
if (data.minimizeButton) {
|
||||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.minimizeButton)) {
|
quickButton = data.minimizeButton;
|
||||||
quickButton = btn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Maximize:
|
case QuickGlobal::SystemButtonType::Maximize:
|
||||||
case QuickGlobal::SystemButtonType::Restore:
|
case QuickGlobal::SystemButtonType::Restore:
|
||||||
if (data.maximizeButton) {
|
if (data.maximizeButton) {
|
||||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.maximizeButton)) {
|
quickButton = data.maximizeButton;
|
||||||
quickButton = btn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Close:
|
case QuickGlobal::SystemButtonType::Close:
|
||||||
if (data.closeButton) {
|
if (data.closeButton) {
|
||||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.closeButton)) {
|
quickButton = data.closeButton;
|
||||||
quickButton = btn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (quickButton) {
|
if (!quickButton) {
|
||||||
const auto updateButtonState = [state](QQuickAbstractButton *btn) -> void {
|
return;
|
||||||
Q_ASSERT(btn);
|
|
||||||
if (!btn) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (state) {
|
|
||||||
case QuickGlobal::ButtonState::Unspecified: {
|
|
||||||
btn->setPressed(false);
|
|
||||||
btn->setHovered(false);
|
|
||||||
} break;
|
|
||||||
case QuickGlobal::ButtonState::Hovered: {
|
|
||||||
btn->setPressed(false);
|
|
||||||
btn->setHovered(true);
|
|
||||||
} break;
|
|
||||||
case QuickGlobal::ButtonState::Pressed: {
|
|
||||||
btn->setHovered(true);
|
|
||||||
btn->setPressed(true);
|
|
||||||
} break;
|
|
||||||
case QuickGlobal::ButtonState::Clicked: {
|
|
||||||
// Clicked: pressed --> released, so behave like hovered.
|
|
||||||
btn->setPressed(false);
|
|
||||||
btn->setHovered(true);
|
|
||||||
QQuickAbstractButtonPrivate::get(btn)->click();
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
updateButtonState(quickButton);
|
|
||||||
}
|
}
|
||||||
|
const auto updateButtonState = [&nativeGlobalPos, state](QQuickItem *btn) -> void {
|
||||||
|
Q_ASSERT(btn);
|
||||||
|
if (!btn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QQuickWindow * const btnWin = btn->window();
|
||||||
|
if (!btnWin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QPoint qtGlobalPos = Utils::fromNativeGlobalPosition(btnWin, nativeGlobalPos);
|
||||||
|
const QPoint scenePos = btnWin->mapFromGlobal(qtGlobalPos);
|
||||||
|
const QPoint localPos = btn->mapFromGlobal(qtGlobalPos).toPoint();
|
||||||
|
const auto sendEnterEvent = [&qtGlobalPos, &scenePos, btn]() -> void {
|
||||||
|
// QEvent::Enter event is for QWidget only and will be ignored by QQuickItem,
|
||||||
|
// but after some experiments, I found QEvent::HoverEnter event can achieve similar effect.
|
||||||
|
QHoverEvent event(QEvent::HoverEnter, scenePos, qtGlobalPos, {});
|
||||||
|
QCoreApplication::sendEvent(btn, &event);
|
||||||
|
};
|
||||||
|
const auto sendLeaveEvent = [&qtGlobalPos, &scenePos, btn]() -> void {
|
||||||
|
// QEvent::Leave event is for QWidget only and will be ignored by QQuickItem,
|
||||||
|
// but after some experiments, I found QEvent::HoverLeave event can achieve similar effect.
|
||||||
|
QHoverEvent event(QEvent::HoverLeave, scenePos, qtGlobalPos, {});
|
||||||
|
QCoreApplication::sendEvent(btn, &event);
|
||||||
|
};
|
||||||
|
const auto sendPressEvent = [&qtGlobalPos, &scenePos, &localPos, btn]() -> void {
|
||||||
|
QMouseEvent event(QEvent::MouseButtonPress, localPos, scenePos, qtGlobalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||||
|
QCoreApplication::sendEvent(btn, &event);
|
||||||
|
};
|
||||||
|
const auto sendReleaseEvent = [&qtGlobalPos, &scenePos, &localPos, btn]() -> void {
|
||||||
|
QMouseEvent event(QEvent::MouseButtonRelease, localPos, scenePos, qtGlobalPos, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
|
||||||
|
QCoreApplication::sendEvent(btn, &event);
|
||||||
|
};
|
||||||
|
const auto sendMoveEvent = [&qtGlobalPos, &scenePos, &localPos, btn]() -> void {
|
||||||
|
// According to Qt docs, we should send both MouseMove event and HoverMove event.
|
||||||
|
QMouseEvent mouseEvent(QEvent::MouseMove, localPos, scenePos, qtGlobalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
||||||
|
QCoreApplication::sendEvent(btn, &mouseEvent);
|
||||||
|
QHoverEvent hoverEvent(QEvent::HoverMove, scenePos, qtGlobalPos, {});
|
||||||
|
QCoreApplication::sendEvent(btn, &hoverEvent);
|
||||||
|
};
|
||||||
|
switch (state) {
|
||||||
|
case QuickGlobal::ButtonState::MouseEntered: {
|
||||||
|
sendEnterEvent();
|
||||||
|
// The visual state won't change without a mouse move event.
|
||||||
|
sendMoveEvent();
|
||||||
|
} break;
|
||||||
|
case QuickGlobal::ButtonState::MouseLeaved: {
|
||||||
|
// The visual state won't change without a mouse move event.
|
||||||
|
sendMoveEvent();
|
||||||
|
sendLeaveEvent();
|
||||||
|
} break;
|
||||||
|
case QuickGlobal::ButtonState::MouseMoving:
|
||||||
|
sendMoveEvent();
|
||||||
|
break;
|
||||||
|
case QuickGlobal::ButtonState::MousePressed:
|
||||||
|
sendPressEvent();
|
||||||
|
break;
|
||||||
|
case QuickGlobal::ButtonState::MouseReleased:
|
||||||
|
sendReleaseEvent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
updateButtonState(quickButton);
|
||||||
#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE
|
#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,6 +268,7 @@ void QuickStandardSystemButton::initialize()
|
||||||
setAntialiasing(true);
|
setAntialiasing(true);
|
||||||
setSmooth(true);
|
setSmooth(true);
|
||||||
setClip(true);
|
setClip(true);
|
||||||
|
setHoverEnabled(true);
|
||||||
|
|
||||||
setImplicitWidth(kDefaultSystemButtonSize.width());
|
setImplicitWidth(kDefaultSystemButtonSize.width());
|
||||||
setImplicitHeight(kDefaultSystemButtonSize.height());
|
setImplicitHeight(kDefaultSystemButtonSize.height());
|
||||||
|
|
|
@ -40,6 +40,9 @@
|
||||||
#include <QtCore/qtimer.h>
|
#include <QtCore/qtimer.h>
|
||||||
#include <QtCore/qeventloop.h>
|
#include <QtCore/qeventloop.h>
|
||||||
#include <QtCore/qloggingcategory.h>
|
#include <QtCore/qloggingcategory.h>
|
||||||
|
#include <QtCore/qcoreapplication.h>
|
||||||
|
#include <QtCore/qcoreevent.h>
|
||||||
|
#include <QtGui/qevent.h>
|
||||||
#include <QtGui/qwindow.h>
|
#include <QtGui/qwindow.h>
|
||||||
#include <QtGui/qpalette.h>
|
#include <QtGui/qpalette.h>
|
||||||
#include <QtWidgets/qwidget.h>
|
#include <QtWidgets/qwidget.h>
|
||||||
|
@ -479,7 +482,7 @@ void FramelessWidgetsHelperPrivate::attach()
|
||||||
params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool { return isInSystemButtons(pos, button); };
|
params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool { return isInSystemButtons(pos, button); };
|
||||||
params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
||||||
params.getWindowDevicePixelRatio = [window]() -> qreal { return window->devicePixelRatioF(); };
|
params.getWindowDevicePixelRatio = [window]() -> qreal { return window->devicePixelRatioF(); };
|
||||||
params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void { setSystemButtonState(button, state); };
|
params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state, const QPoint &globalPos) -> void { setSystemButtonState(button, state, globalPos); };
|
||||||
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||||
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
|
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
|
||||||
params.setProperty = [this](const QByteArray &name, const QVariant &value) -> void { setProperty(name, value); };
|
params.setProperty = [this](const QByteArray &name, const QVariant &value) -> void { setProperty(name, value); };
|
||||||
|
@ -707,7 +710,7 @@ bool FramelessWidgetsHelperPrivate::shouldIgnoreMouseEvents(const QPoint &pos) c
|
||||||
return ((Utils::windowStatesToWindowState(m_window->windowState()) == Qt::WindowNoState) && withinFrameBorder);
|
return ((Utils::windowStatesToWindowState(m_window->windowState()) == Qt::WindowNoState) && withinFrameBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType button, const ButtonState state)
|
void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType button, const ButtonState state, const QPoint &nativeGlobalPos)
|
||||||
{
|
{
|
||||||
Q_ASSERT(button != SystemButtonType::Unknown);
|
Q_ASSERT(button != SystemButtonType::Unknown);
|
||||||
if (button == SystemButtonType::Unknown) {
|
if (button == SystemButtonType::Unknown) {
|
||||||
|
@ -745,43 +748,79 @@ void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (widgetButton) {
|
if (!widgetButton) {
|
||||||
const auto updateButtonState = [state](QWidget *btn) -> void {
|
return;
|
||||||
Q_ASSERT(btn);
|
|
||||||
if (!btn) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (state) {
|
|
||||||
case ButtonState::Unspecified: {
|
|
||||||
QMetaObject::invokeMethod(btn, "setPressed", Q_ARG(bool, false));
|
|
||||||
QMetaObject::invokeMethod(btn, "setHovered", Q_ARG(bool, false));
|
|
||||||
} break;
|
|
||||||
case ButtonState::Hovered: {
|
|
||||||
QMetaObject::invokeMethod(btn, "setPressed", Q_ARG(bool, false));
|
|
||||||
QMetaObject::invokeMethod(btn, "setHovered", Q_ARG(bool, true));
|
|
||||||
} break;
|
|
||||||
case ButtonState::Pressed: {
|
|
||||||
QMetaObject::invokeMethod(btn, "setHovered", Q_ARG(bool, true));
|
|
||||||
QMetaObject::invokeMethod(btn, "setPressed", Q_ARG(bool, true));
|
|
||||||
} break;
|
|
||||||
case ButtonState::Clicked: {
|
|
||||||
// Clicked: pressed --> released, so behave like hovered.
|
|
||||||
QMetaObject::invokeMethod(btn, "setPressed", Q_ARG(bool, false));
|
|
||||||
QMetaObject::invokeMethod(btn, "setHovered", Q_ARG(bool, true));
|
|
||||||
// Trigger the clicked signal.
|
|
||||||
QMetaObject::invokeMethod(btn, "clicked");
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (const auto mo = widgetButton->metaObject()) {
|
|
||||||
const int pressedIndex = mo->indexOfSlot(QMetaObject::normalizedSignature("setPressed(bool)").constData());
|
|
||||||
const int hoveredIndex = mo->indexOfSlot(QMetaObject::normalizedSignature("setHovered(bool)").constData());
|
|
||||||
const int clickedIndex = mo->indexOfSignal(QMetaObject::normalizedSignature("clicked()").constData());
|
|
||||||
if ((pressedIndex >= 0) && (hoveredIndex >= 0) && (clickedIndex >= 0)) {
|
|
||||||
updateButtonState(widgetButton);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const auto updateButtonState = [&nativeGlobalPos, state](QWidget *btn) -> void {
|
||||||
|
Q_ASSERT(btn);
|
||||||
|
if (!btn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QWidget * const btnWin = btn->window();
|
||||||
|
if (!btnWin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QWindow * const btnRawWin = btnWin->windowHandle();
|
||||||
|
if (!btnRawWin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QPoint qtGlobalPos = Utils::fromNativeGlobalPosition(btnRawWin, nativeGlobalPos);
|
||||||
|
const QPoint scenePos = btnWin->mapFromGlobal(qtGlobalPos);
|
||||||
|
const QPoint localPos = btn->mapFromGlobal(qtGlobalPos);
|
||||||
|
const auto sendEnterEvent = [&qtGlobalPos, &scenePos, &localPos, btn]() -> void {
|
||||||
|
QEnterEvent mouseEvent(localPos, scenePos, qtGlobalPos);
|
||||||
|
QCoreApplication::sendEvent(btn, &mouseEvent);
|
||||||
|
// We'd better send the mouse hover event at the same time, in case some widgets need it.
|
||||||
|
QHoverEvent hoverEvent(QEvent::HoverEnter, scenePos, qtGlobalPos, {});
|
||||||
|
QCoreApplication::sendEvent(btn, &hoverEvent);
|
||||||
|
};
|
||||||
|
const auto sendLeaveEvent = [&qtGlobalPos, &scenePos, btn]() -> void {
|
||||||
|
QEvent mouseEvent(QEvent::Leave);
|
||||||
|
QCoreApplication::sendEvent(btn, &mouseEvent);
|
||||||
|
// We'd better send the mouse hover event at the same time, in case some widgets need it.
|
||||||
|
QHoverEvent hoverEvent(QEvent::HoverLeave, scenePos, qtGlobalPos, {});
|
||||||
|
QCoreApplication::sendEvent(btn, &hoverEvent);
|
||||||
|
};
|
||||||
|
const auto sendPressEvent = [&qtGlobalPos, &scenePos, &localPos, btn]() -> void {
|
||||||
|
QMouseEvent event(QEvent::MouseButtonPress, localPos, scenePos, qtGlobalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||||
|
QCoreApplication::sendEvent(btn, &event);
|
||||||
|
};
|
||||||
|
const auto sendReleaseEvent = [&qtGlobalPos, &scenePos, &localPos, btn]() -> void {
|
||||||
|
QMouseEvent event(QEvent::MouseButtonRelease, localPos, scenePos, qtGlobalPos, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
|
||||||
|
QCoreApplication::sendEvent(btn, &event);
|
||||||
|
QMetaObject::invokeMethod(btn, "clicked"); // Why do we need this ???
|
||||||
|
};
|
||||||
|
const auto sendMoveEvent = [&qtGlobalPos, &scenePos, &localPos, btn]() -> void {
|
||||||
|
// According to Qt docs, we should send both MouseMove event and HoverMove event.
|
||||||
|
QMouseEvent mouseEvent(QEvent::MouseMove, localPos, scenePos, qtGlobalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
||||||
|
QCoreApplication::sendEvent(btn, &mouseEvent);
|
||||||
|
QHoverEvent hoverEvent(QEvent::HoverMove, scenePos, qtGlobalPos, {});
|
||||||
|
QCoreApplication::sendEvent(btn, &hoverEvent);
|
||||||
|
};
|
||||||
|
switch (state) {
|
||||||
|
case ButtonState::MouseEntered: {
|
||||||
|
sendEnterEvent();
|
||||||
|
// The visual state won't change without a mouse move event.
|
||||||
|
sendMoveEvent();
|
||||||
|
} break;
|
||||||
|
case ButtonState::MouseLeaved: {
|
||||||
|
// The visual state won't change without a mouse move event.
|
||||||
|
sendMoveEvent();
|
||||||
|
sendLeaveEvent();
|
||||||
|
} break;
|
||||||
|
case ButtonState::MouseMoving:
|
||||||
|
//sendMoveEvent();
|
||||||
|
sendEnterEvent();
|
||||||
|
break;
|
||||||
|
case ButtonState::MousePressed:
|
||||||
|
sendPressEvent();
|
||||||
|
break;
|
||||||
|
case ButtonState::MouseReleased:
|
||||||
|
sendReleaseEvent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
updateButtonState(widgetButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessWidgetsHelperPrivate::moveWindowToDesktopCenter()
|
void FramelessWidgetsHelperPrivate::moveWindowToDesktopCenter()
|
||||||
|
@ -881,6 +920,8 @@ void FramelessWidgetsHelperPrivate::setSystemButton(QWidget *widget, const Syste
|
||||||
data->closeButton = widget;
|
data->closeButton = widget;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
widget->setMouseTracking(true);
|
||||||
|
widget->setAttribute(Qt::WA_Hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
FramelessWidgetsHelper::FramelessWidgetsHelper(QObject *parent)
|
FramelessWidgetsHelper::FramelessWidgetsHelper(QObject *parent)
|
||||||
|
|
|
@ -333,6 +333,7 @@ void StandardSystemButtonPrivate::leaveEventHandler(QEvent *event)
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
setPressed(false);
|
||||||
setHovered(false);
|
setHovered(false);
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
@ -395,6 +396,8 @@ void StandardSystemButtonPrivate::initialize()
|
||||||
q->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
q->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
q->setFixedSize(kDefaultSystemButtonSize);
|
q->setFixedSize(kDefaultSystemButtonSize);
|
||||||
q->setIconSize(kDefaultSystemButtonIconSize);
|
q->setIconSize(kDefaultSystemButtonIconSize);
|
||||||
|
q->setMouseTracking(true);
|
||||||
|
q->setAttribute(Qt::WA_Hover);
|
||||||
connect(q, &StandardSystemButton::pressed, this, [this](){ setPressed(true); });
|
connect(q, &StandardSystemButton::pressed, this, [this](){ setPressed(true); });
|
||||||
connect(q, &StandardSystemButton::released, this, [this](){ setPressed(false); });
|
connect(q, &StandardSystemButton::released, this, [this](){ setPressed(false); });
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue