Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Commit

Permalink
win: replace an old workaround with new one
Browse files Browse the repository at this point in the history
  • Loading branch information
wangwenx190 committed Aug 24, 2023
1 parent a130fef commit 4a1f5fb
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ using SetCursorCallback = std::function<void(const QCursor &)>;
using UnsetCursorCallback = std::function<void()>;
using GetWidgetHandleCallback = std::function<QObject *()>;
using ForceChildrenRepaintCallback = std::function<void(const int)>;
using ResetQtGrabbedControlCallback = std::function<void()>;

struct SystemParameters
{
Expand Down Expand Up @@ -93,6 +94,7 @@ struct SystemParameters
UnsetCursorCallback unsetCursor = nullptr;
GetWidgetHandleCallback getWidgetHandle = nullptr;
ForceChildrenRepaintCallback forceChildrenRepaint = nullptr;
ResetQtGrabbedControlCallback resetQtGrabbedControl = nullptr;
};

using FramelessParams = SystemParameters *;
Expand Down
16 changes: 9 additions & 7 deletions src/core/framelesshelper_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ enum class WindowPart : quint8
ClientArea,
ChromeButton,
ResizeBorder,
FixBorder,
FixedBorder,
TitleBar
};

Expand Down Expand Up @@ -157,7 +157,7 @@ Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
return result;
}

[[nodiscard]] static inline WindowPart getHittedWindowPart(const LRESULT hitTestResult)
[[nodiscard]] static inline WindowPart getHittedWindowPart(const int hitTestResult)
{
switch (hitTestResult) {
case HTCLIENT:
Expand All @@ -180,7 +180,7 @@ Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
case HTBOTTOMRIGHT:
return WindowPart::ResizeBorder;
case HTBORDER:
return WindowPart::FixBorder;
return WindowPart::FixedBorder;
default:
break;
}
Expand Down Expand Up @@ -422,8 +422,8 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// 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)) {
SystemButtonType dummy = SystemButtonType::Unknown;
if (data.params.isInsideSystemButtons(qtScenePos, &dummy)) {
*result = FALSE;
return true;
}
Expand Down Expand Up @@ -807,8 +807,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
const bool full = Utils::isFullScreen(windowId);
const int frameSizeY = Utils::getResizeBorderThickness(windowId, false, true);
const bool isTop = (nativeLocalPos.y < frameSizeY);
const bool leftButtonPressed = (Utils::getKeyState() & MK_LBUTTON);
const bool isTitleBar = (data.params.isInsideTitleBarDraggableArea(qtScenePos) && leftButtonPressed);
const bool isTitleBar = data.params.isInsideTitleBarDraggableArea(qtScenePos);
const bool isFixedSize = data.params.isWindowFixedSize();
const bool dontOverrideCursor = data.params.getProperty(kDontOverrideCursorVar, false).toBool();
const bool dontToggleMaximize = data.params.getProperty(kDontToggleMaximizeVar, false).toBool();
Expand Down Expand Up @@ -960,6 +959,9 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
}
}
} else {
if ((uMsg == WM_NCMOUSEMOVE) && (nowWindowPart != WindowPart::ChromeButton)) {
data.params.resetQtGrabbedControl();
}
if (nowWindowPart == WindowPart::ChromeButton) {
emulateClientAreaMessage();
*result = (isXButtonMessage ? TRUE : FALSE);
Expand Down
4 changes: 2 additions & 2 deletions src/core/utils_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
#include <AppKit/AppKit.h>

QT_BEGIN_NAMESPACE
[[nodiscard]] Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode(); // Since 5.12
[[nodiscard]] Q_GUI_EXPORT QColor qt_mac_toQColor(const NSColor *color); // Since 5.8
[[nodiscard]] extern Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode(); // Since 5.12
[[nodiscard]] extern Q_GUI_EXPORT QColor qt_mac_toQColor(const NSColor *color); // Since 5.8
QT_END_NAMESPACE

FRAMELESSHELPER_BEGIN_NAMESPACE
Expand Down
10 changes: 8 additions & 2 deletions src/quick/framelessquickhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ void FramelessQuickHelperPrivate::attach()
params.unsetCursor = [window]() -> void { window->unsetCursor(); };
params.getWidgetHandle = []() -> QObject * { return nullptr; };
params.forceChildrenRepaint = [this](const int delay) -> void { repaintAllChildren(delay); };
params.resetQtGrabbedControl = []() -> void {};

FramelessManager::instance()->addWindow(&params);

Expand Down Expand Up @@ -676,19 +677,24 @@ void FramelessQuickHelperPrivate::repaintAllChildren(const quint32 delay) const
return;
}
const auto update = [window]() -> void {
window->requestUpdate();
#ifdef Q_OS_WINDOWS
// Sync the internal window frame margins with the latest DPI, otherwise
// we will get wrong window sizes after the DPI change.
std::ignore = Utils::updateInternalWindowFrameMargins(window, true);
#endif // Q_OS_WINDOWS
// No need to repaint the window when it's hidden.
if (!window->isVisible()) {
return;
}
window->requestUpdate();
const QList<QQuickItem *> items = window->findChildren<QQuickItem *>();
if (items.isEmpty()) {
return;
}
for (auto &&item : std::as_const(items)) {
// Only items with the "QQuickItem::ItemHasContents" flag enabled are allowed to call "update()".
if (item->flags() & QQuickItem::ItemHasContents) {
// And don't repaint the item if it's hidden.
if ((item->flags() & QQuickItem::ItemHasContents) && item->isVisible()) {
item->update();
}
}
Expand Down
29 changes: 18 additions & 11 deletions src/widgets/framelesswidgetshelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
# define QWIDGETSIZE_MAX ((1 << 24) - 1)
#endif // QWIDGETSIZE_MAX

extern Q_WIDGETS_EXPORT QWidget *qt_button_down;

FRAMELESSHELPER_BEGIN_NAMESPACE

[[maybe_unused]] static Q_LOGGING_CATEGORY(lcFramelessWidgetsHelper, "wangwenx190.framelesshelper.widgets.framelesswidgetshelper")
Expand Down Expand Up @@ -115,6 +117,21 @@ static inline void forceWidgetRepaint(QWidget * const widget)
if (!widget) {
return;
}
#ifdef Q_OS_WINDOWS
// There's some additional things to do for top level windows on Windows.
if (widget->isWindow()) {
// Don't crash if the QWindow instance has not been created yet.
if (QWindow * const window = widget->windowHandle()) {
// Sync the internal window frame margins with the latest DPI, otherwise
// we will get wrong window sizes after the DPI change.
std::ignore = Utils::updateInternalWindowFrameMargins(window, true);
}
}
#endif // Q_OS_WINDOWS
// Don't do unnecessary repaints if the widget is hidden.
if (!widget->isVisible()) {
return;
}
// Tell the widget to repaint itself, but it may not happen due to QWidget's
// internal painting optimizations.
widget->update();
Expand All @@ -137,17 +154,6 @@ static inline void forceWidgetRepaint(QWidget * const widget)
widget->move(originalPosition + offset);
widget->move(originalPosition);
}
#ifdef Q_OS_WINDOWS
// There's some additional things to do for top level windows on Windows.
if (widget->isWindow()) {
// Don't crash if the QWindow instance has not been created yet.
if (QWindow * const window = widget->windowHandle()) {
// Sync the internal window frame margins with the latest DPI, otherwise
// we will get wrong window sizes after the DPI change.
std::ignore = Utils::updateInternalWindowFrameMargins(window, true);
}
}
#endif // Q_OS_WINDOWS
// Let's try again with the ordinary way.
widget->update();
// ### TODO: I observed the font size is often wrong after DPI changes,
Expand Down Expand Up @@ -573,6 +579,7 @@ void FramelessWidgetsHelperPrivate::attach()
params.unsetCursor = [window]() -> void { window->unsetCursor(); };
params.getWidgetHandle = [window]() -> QObject * { return window; };
params.forceChildrenRepaint = [this](const int delay) -> void { repaintAllChildren(delay); };
params.resetQtGrabbedControl = []() -> void { qt_button_down = nullptr; };

FramelessManager::instance()->addWindow(&params);

Expand Down

0 comments on commit 4a1f5fb

Please sign in to comment.