misc: minor tweaks

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-04-14 10:22:57 +08:00
parent a57011bd11
commit d353c81c5e
5 changed files with 148 additions and 76 deletions

View File

@ -58,12 +58,25 @@ static const QString qThemeSettingChangeEventName = QString::fromWCharArray(kThe
FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow) FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow)
FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW) FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW)
FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient) FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient)
FRAMELESSHELPER_STRING_CONSTANT(ClientToScreen)
FRAMELESSHELPER_STRING_CONSTANT(GetClientRect) FRAMELESSHELPER_STRING_CONSTANT(GetClientRect)
FRAMELESSHELPER_STRING_CONSTANT(GetWindowLongPtrW) #ifdef Q_PROCESSOR_X86_64
FRAMELESSHELPER_STRING_CONSTANT(SetWindowLongPtrW) FRAMELESSHELPER_STRING_CONSTANT(GetWindowLongPtrW)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowLongPtrW)
#else
// WinUser.h defines G/SetClassLongPtr as G/SetClassLong due to the
// "Ptr" suffixed APIs are not available on 32-bit platforms, so we
// have to add the following workaround. Undefine the macros and then
// redefine them is also an option but the following solution is more simple.
FRAMELESSHELPER_STRING_CONSTANT2(GetWindowLongPtrW, "GetWindowLongW")
FRAMELESSHELPER_STRING_CONSTANT2(SetWindowLongPtrW, "SetWindowLongW")
#endif
[[nodiscard]] static inline Qt::MouseButtons keyStateToMouseButtons(const WPARAM wParam) [[nodiscard]] static inline Qt::MouseButtons keyStateToMouseButtons(const WPARAM wParam)
{ {
if (wParam == 0) {
return {};
}
Qt::MouseButtons result = {}; Qt::MouseButtons result = {};
if (wParam & MK_LBUTTON) { if (wParam & MK_LBUTTON) {
result |= Qt::LeftButton; result |= Qt::LeftButton;
@ -132,17 +145,23 @@ FRAMELESSHELPER_STRING_CONSTANT(SetWindowLongPtrW)
if (isNonClientMouseEvent) { if (isNonClientMouseEvent) {
nativeScreenPos = nativePosExtractedFromLParam; nativeScreenPos = nativePosExtractedFromLParam;
nativeWindowPos = nativeScreenPos; nativeWindowPos = nativeScreenPos;
ScreenToClient(hWnd, &nativeWindowPos); if (ScreenToClient(hWnd, &nativeWindowPos) == FALSE) {
qWarning() << Utils::getSystemErrorMessage(kScreenToClient);
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
} }
if (isClientMouseEvent) { if (isClientMouseEvent) {
nativeWindowPos = nativePosExtractedFromLParam; nativeWindowPos = nativePosExtractedFromLParam;
nativeScreenPos = nativeWindowPos; nativeScreenPos = nativeWindowPos;
ClientToScreen(hWnd, &nativeScreenPos); if (ClientToScreen(hWnd, &nativeScreenPos) == FALSE) {
qWarning() << Utils::getSystemErrorMessage(kClientToScreen);
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
} }
const qreal devicePixelRatio = data.params.getWindowDevicePixelRatio(); const qreal devicePixelRatio = data.params.getWindowDevicePixelRatio();
const QPoint qtScenePos = QPointF(QPointF(qreal(nativeWindowPos.x), qreal(nativeWindowPos.y)) / devicePixelRatio).toPoint(); const QPoint qtScenePos = QPointF(QPointF(qreal(nativeWindowPos.x), qreal(nativeWindowPos.y)) / devicePixelRatio).toPoint();
SystemButtonType currentButtonType = SystemButtonType::Unknown; SystemButtonType currentButtonType = SystemButtonType::Unknown;
const ButtonState defaultButtonState = ButtonState::Unspecified; static constexpr const auto defaultButtonState = ButtonState::Unspecified;
data.params.setSystemButtonState(SystemButtonType::WindowIcon, defaultButtonState); data.params.setSystemButtonState(SystemButtonType::WindowIcon, defaultButtonState);
data.params.setSystemButtonState(SystemButtonType::Help, defaultButtonState); data.params.setSystemButtonState(SystemButtonType::Help, defaultButtonState);
data.params.setSystemButtonState(SystemButtonType::Minimize, defaultButtonState); data.params.setSystemButtonState(SystemButtonType::Minimize, defaultButtonState);
@ -765,7 +784,6 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
} }
return true; return true;
} }
#if 0 // This block of code is causing some problems in my own Qt Quick applications. Needs some more investigation.
case WM_SETICON: case WM_SETICON:
case WM_SETTEXT: { case WM_SETTEXT: {
// Disable painting while these messages are handled to prevent them // Disable painting while these messages are handled to prevent them
@ -795,7 +813,6 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
*result = ret; *result = ret;
return true; return true;
} }
#endif
default: default:
break; break;
} }

View File

@ -482,29 +482,45 @@ bool FramelessQuickWindowPrivate::isInSystemButtons(const QPoint &pos, SystemBut
return false; return false;
} }
*button = SystemButtonType::Unknown; *button = SystemButtonType::Unknown;
if (!m_settings.minimizeButton || !m_settings.maximizeButton || !m_settings.closeButton) { if (!m_settings.windowIconButton && !m_settings.contextHelpButton
&& !m_settings.minimizeButton && !m_settings.maximizeButton && !m_settings.closeButton) {
return false; return false;
} }
if (!m_settings.minimizeButton->inherits(QT_QUICKITEM_CLASS_NAME) if (m_settings.windowIconButton && m_settings.windowIconButton->inherits(QT_QUICKITEM_CLASS_NAME)) {
|| !m_settings.maximizeButton->inherits(QT_QUICKITEM_CLASS_NAME) const auto iconBtn = qobject_cast<QQuickItem *>(m_settings.windowIconButton);
|| !m_settings.closeButton->inherits(QT_QUICKITEM_CLASS_NAME)) { if (mapItemGeometryToScene(iconBtn).contains(pos)) {
return false; *button = SystemButtonType::WindowIcon;
return true;
} }
}
if (m_settings.contextHelpButton && m_settings.contextHelpButton->inherits(QT_QUICKITEM_CLASS_NAME)) {
const auto helpBtn = qobject_cast<QQuickItem *>(m_settings.contextHelpButton);
if (mapItemGeometryToScene(helpBtn).contains(pos)) {
*button = SystemButtonType::Help;
return true;
}
}
if (m_settings.minimizeButton && m_settings.minimizeButton->inherits(QT_QUICKITEM_CLASS_NAME)) {
const auto minBtn = qobject_cast<QQuickItem *>(m_settings.minimizeButton); const auto minBtn = qobject_cast<QQuickItem *>(m_settings.minimizeButton);
if (mapItemGeometryToScene(minBtn).contains(pos)) { if (mapItemGeometryToScene(minBtn).contains(pos)) {
*button = SystemButtonType::Minimize; *button = SystemButtonType::Minimize;
return true; return true;
} }
}
if (m_settings.maximizeButton && m_settings.maximizeButton->inherits(QT_QUICKITEM_CLASS_NAME)) {
const auto maxBtn = qobject_cast<QQuickItem *>(m_settings.maximizeButton); const auto maxBtn = qobject_cast<QQuickItem *>(m_settings.maximizeButton);
if (mapItemGeometryToScene(maxBtn).contains(pos)) { if (mapItemGeometryToScene(maxBtn).contains(pos)) {
*button = SystemButtonType::Maximize; *button = SystemButtonType::Maximize;
return true; return true;
} }
}
if (m_settings.closeButton && m_settings.closeButton->inherits(QT_QUICKITEM_CLASS_NAME)) {
const auto closeBtn = qobject_cast<QQuickItem *>(m_settings.closeButton); const auto closeBtn = qobject_cast<QQuickItem *>(m_settings.closeButton);
if (mapItemGeometryToScene(closeBtn).contains(pos)) { if (mapItemGeometryToScene(closeBtn).contains(pos)) {
*button = SystemButtonType::Close; *button = SystemButtonType::Close;
return true; return true;
} }
}
return false; return false;
} }

View File

@ -32,6 +32,7 @@ set(SOURCES
${INCLUDE_PREFIX}/framelesswidget.h ${INCLUDE_PREFIX}/framelesswidget.h
${INCLUDE_PREFIX}/framelessmainwindow.h ${INCLUDE_PREFIX}/framelessmainwindow.h
${INCLUDE_PREFIX}/standardsystembutton.h ${INCLUDE_PREFIX}/standardsystembutton.h
standardsystembutton_p.h
framelessmainwindow.cpp framelessmainwindow.cpp
framelesswidgetshelper.cpp framelesswidgetshelper.cpp
framelesswidget.cpp framelesswidget.cpp

View File

@ -23,6 +23,7 @@
*/ */
#include "standardsystembutton.h" #include "standardsystembutton.h"
#include "standardsystembutton_p.h"
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#include <QtGui/qpainter.h> #include <QtGui/qpainter.h>
#include <framelesswindowsmanager.h> #include <framelesswindowsmanager.h>
@ -36,54 +37,6 @@ static constexpr const QRect g_buttonRect = {QPoint(0, 0), kDefaultSystemButtonS
static constexpr const auto g_buttonIconX = static_cast<int>(qRound(qreal(kDefaultSystemButtonSize.width() - kDefaultSystemButtonIconSize.width()) / 2.0)); static constexpr const auto g_buttonIconX = static_cast<int>(qRound(qreal(kDefaultSystemButtonSize.width() - kDefaultSystemButtonIconSize.width()) / 2.0));
static constexpr const auto g_buttonIconY = static_cast<int>(qRound(qreal(kDefaultSystemButtonSize.height() - kDefaultSystemButtonIconSize.height()) / 2.0)); static constexpr const auto g_buttonIconY = static_cast<int>(qRound(qreal(kDefaultSystemButtonSize.height() - kDefaultSystemButtonIconSize.height()) / 2.0));
class StandardSystemButtonPrivate : public QObject
{
Q_OBJECT
Q_DECLARE_PUBLIC(StandardSystemButton)
Q_DISABLE_COPY_MOVE(StandardSystemButtonPrivate)
public:
explicit StandardSystemButtonPrivate(StandardSystemButton *q);
~StandardSystemButtonPrivate() override;
void refreshButtonTheme(const bool force);
Q_NODISCARD SystemButtonType getButtonType() const;
void setButtonType(const SystemButtonType type);
void setIcon(const QIcon &value, const bool reverse);
void setPixmap(const QPixmap &value, const bool reverse);
void setImage(const QImage &value, const bool reverse);
Q_NODISCARD QSize getRecommendedButtonSize() const;
Q_NODISCARD bool isHover() const;
Q_NODISCARD QColor getHoverColor() const;
Q_NODISCARD QColor getPressColor() const;
void setHover(const bool value);
void setHoverColor(const QColor &value);
void setPressColor(const QColor &value);
void enterEventHandler(QT_ENTER_EVENT_TYPE *event);
void leaveEventHandler(QEvent *event);
void paintEventHandler(QPaintEvent *event);
private:
void initialize();
private:
StandardSystemButton *q_ptr;
SystemTheme m_buttonTheme = SystemTheme::Unknown;
SystemButtonType m_buttonType = SystemButtonType::Unknown;
QPixmap m_icon = {};
QPixmap m_reversedIcon = {};
QColor m_hoverColor = {};
QColor m_pressColor = {};
bool m_hovered = false;
bool m_pressed = false;
};
StandardSystemButtonPrivate::StandardSystemButtonPrivate(StandardSystemButton *q) : QObject(q) StandardSystemButtonPrivate::StandardSystemButtonPrivate(StandardSystemButton *q) : QObject(q)
{ {
Q_ASSERT(q); Q_ASSERT(q);
@ -321,9 +274,8 @@ void StandardSystemButtonPrivate::initialize()
this, [this](){ refreshButtonTheme(false); }); this, [this](){ refreshButtonTheme(false); });
} }
StandardSystemButton::StandardSystemButton(QWidget *parent) : QAbstractButton(parent) StandardSystemButton::StandardSystemButton(QWidget *parent) : QAbstractButton(parent), d_ptr(new StandardSystemButtonPrivate(this))
{ {
d_ptr.reset(new StandardSystemButtonPrivate(this));
} }
StandardSystemButton::StandardSystemButton(const SystemButtonType type, QWidget *parent) : StandardSystemButton(parent) StandardSystemButton::StandardSystemButton(const SystemButtonType type, QWidget *parent) : StandardSystemButton(parent)
@ -415,5 +367,3 @@ void StandardSystemButton::paintEvent(QPaintEvent *event)
} }
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE
#include "standardsystembutton.moc"

View File

@ -0,0 +1,88 @@
/*
* MIT License
*
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
#include <QtCore/qobject.h>
#include <QtGui/qpixmap.h>
#include "framelesshelperwidgets_global.h"
QT_BEGIN_NAMESPACE
class QEnterEvent;
class QPaintEvent;
QT_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE
class StandardSystemButton;
class StandardSystemButtonPrivate : public QObject
{
Q_OBJECT
Q_DECLARE_PUBLIC(StandardSystemButton)
Q_DISABLE_COPY_MOVE(StandardSystemButtonPrivate)
public:
explicit StandardSystemButtonPrivate(StandardSystemButton *q);
~StandardSystemButtonPrivate() override;
void refreshButtonTheme(const bool force);
Q_NODISCARD Global::SystemButtonType getButtonType() const;
void setButtonType(const Global::SystemButtonType type);
void setIcon(const QIcon &value, const bool reverse);
void setPixmap(const QPixmap &value, const bool reverse);
void setImage(const QImage &value, const bool reverse);
Q_NODISCARD QSize getRecommendedButtonSize() const;
Q_NODISCARD bool isHover() const;
Q_NODISCARD QColor getHoverColor() const;
Q_NODISCARD QColor getPressColor() const;
void setHover(const bool value);
void setHoverColor(const QColor &value);
void setPressColor(const QColor &value);
void enterEventHandler(QT_ENTER_EVENT_TYPE *event);
void leaveEventHandler(QEvent *event);
void paintEventHandler(QPaintEvent *event);
private:
void initialize();
private:
StandardSystemButton *q_ptr;
Global::SystemTheme m_buttonTheme = Global::SystemTheme::Unknown;
Global::SystemButtonType m_buttonType = Global::SystemButtonType::Unknown;
QPixmap m_icon = {};
QPixmap m_reversedIcon = {};
QColor m_hoverColor = {};
QColor m_pressColor = {};
bool m_hovered = false;
bool m_pressed = false;
};
FRAMELESSHELPER_END_NAMESPACE