snap layout: fix qt events
This commit is contained in:
parent
2c8bd8ce8c
commit
ca968b7ba6
|
@ -89,9 +89,11 @@ FRAMELESSHELPER_CORE_API void registerThemeChangeNotification();
|
|||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 defaultScreenDpi();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowAccelerated(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 QPoint &globalPos, const QPoint &scenePos, const QPoint &localPos,
|
||||
const bool underMouse, const bool hoverEnabled);
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowsVersionOrGreater(const Global::WindowsVersion version);
|
||||
|
|
|
@ -631,8 +631,8 @@ bool Utils::isWindowTransparent(const QWindow *window)
|
|||
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)
|
||||
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);
|
||||
|
@ -642,14 +642,17 @@ void Utils::emulateQtMouseEvent(const QObject *target, const QWindow *window,
|
|||
const auto targetObj = const_cast<QObject *>(target);
|
||||
const auto windowObj = static_cast<QObject *>(const_cast<QWindow *>(window));
|
||||
const bool isWidget = target->isWidgetType();
|
||||
const bool mouseTrackingEnabled = (isWidget ? target->property("mouseTracking").toBool() : true);
|
||||
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_ITEM_ENTERED";
|
||||
static constexpr const char kEnteredFlag[] = "__FRAMELESSHELPER_WIDGET_QUICKITEM_ENTERED";
|
||||
const bool entered = target->property(kEnteredFlag).toBool();
|
||||
const auto sendEnterEvent = [&localPos, &scenePos, &globalPos, &modifiers](QObject *obj) -> void {
|
||||
const bool leftButtonPressed = (queryMouseButtons() & Qt::LeftButton);
|
||||
const auto sendEnterEvent = [&localPos, &scenePos, &globalPos, &modifiers, hoverEnabled](QObject *obj) -> void {
|
||||
Q_ASSERT(obj);
|
||||
if (!obj) {
|
||||
return;
|
||||
|
@ -659,33 +662,41 @@ void Utils::emulateQtMouseEvent(const QObject *target, const QWindow *window,
|
|||
#else
|
||||
QEvent enterEvent(QEvent::Enter);
|
||||
#endif
|
||||
QHoverEvent hoverEnterEvent(QEvent::HoverEnter, scenePos, globalPos, oldPos, modifiers);
|
||||
QCoreApplication::sendEvent(obj, &enterEvent);
|
||||
QCoreApplication::sendEvent(obj, &hoverEnterEvent);
|
||||
if (hoverEnabled) {
|
||||
QHoverEvent hoverEnterEvent(QEvent::HoverEnter, scenePos, globalPos, oldPos, modifiers);
|
||||
QCoreApplication::sendEvent(obj, &hoverEnterEvent);
|
||||
}
|
||||
};
|
||||
const auto sendLeaveEvent = [&scenePos, &globalPos, &modifiers](QObject *obj) -> void {
|
||||
const auto sendLeaveEvent = [&scenePos, &globalPos, &modifiers, hoverEnabled](QObject *obj) -> void {
|
||||
Q_ASSERT(obj);
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
QEvent leaveEvent(QEvent::Leave);
|
||||
QHoverEvent hoverLeaveEvent(QEvent::HoverLeave, scenePos, globalPos, oldPos, modifiers);
|
||||
QCoreApplication::sendEvent(obj, &leaveEvent);
|
||||
QCoreApplication::sendEvent(obj, &hoverLeaveEvent);
|
||||
if (hoverEnabled) {
|
||||
QHoverEvent hoverLeaveEvent(QEvent::HoverLeave, scenePos, globalPos, oldPos, modifiers);
|
||||
QCoreApplication::sendEvent(obj, &hoverLeaveEvent);
|
||||
}
|
||||
};
|
||||
const auto sendMouseMoveEvent = [&localPos, &scenePos, &globalPos, &buttons, &modifiers](QObject *obj) -> void {
|
||||
const auto sendMouseMoveEvent = [&localPos, &scenePos, &globalPos, &buttons, &modifiers, leftButtonPressed](QObject *obj) -> void {
|
||||
Q_ASSERT(obj);
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
QMouseEvent event(QEvent::MouseMove, localPos, scenePos, globalPos, Qt::NoButton, buttons, modifiers);
|
||||
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 = [&scenePos, &globalPos, &modifiers](QObject *obj) -> void {
|
||||
const auto sendHoverMoveEvent = [&scenePos, &globalPos, &modifiers, hoverEnabled](QObject *obj) -> void {
|
||||
Q_ASSERT(obj);
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
if (!hoverEnabled) {
|
||||
return;
|
||||
}
|
||||
QHoverEvent event(QEvent::HoverMove, scenePos, globalPos, oldPos, modifiers);
|
||||
QCoreApplication::sendEvent(obj, &event);
|
||||
};
|
||||
|
@ -697,53 +708,59 @@ void Utils::emulateQtMouseEvent(const QObject *target, const QWindow *window,
|
|||
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 {
|
||||
const auto sendMouseReleaseEvent = [&localPos, &scenePos, &globalPos, &buttons, &modifiers](QObject *obj, const bool fake = false) -> void {
|
||||
Q_ASSERT(obj);
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
QMouseEvent event(QEvent::MouseButtonRelease, localPos, scenePos, globalPos, button, buttons, modifiers);
|
||||
static constexpr const auto fakePos = QPoint{ -999, -999 };
|
||||
const QPoint tweakedLocalPos = (fake ? fakePos : localPos);
|
||||
const QPoint tweakedScenePos = (fake ? fakePos : scenePos);
|
||||
const QPoint tweakedGlobalPos = (fake ? fakePos : globalPos);
|
||||
QMouseEvent event(QEvent::MouseButtonRelease, tweakedLocalPos, tweakedScenePos, tweakedGlobalPos, button, buttons, modifiers);
|
||||
QCoreApplication::sendEvent(obj, &event);
|
||||
};
|
||||
switch (buttonState) {
|
||||
case ButtonState::Normal: {
|
||||
targetObj->setProperty(kEnteredFlag, {});
|
||||
// sendMouseReleaseEvent(windowObj);
|
||||
// if (isWidget) {
|
||||
// sendMouseReleaseEvent(targetObj);
|
||||
// }
|
||||
sendLeaveEvent(windowObj);
|
||||
// Send an extra mouse release event to let the control dismiss it's hover state.
|
||||
sendMouseReleaseEvent(targetObj, true);
|
||||
if (isWidget) {
|
||||
sendLeaveEvent(targetObj);
|
||||
} else {
|
||||
sendLeaveEvent(windowObj);
|
||||
}
|
||||
} break;
|
||||
case ButtonState::Hovered: {
|
||||
if (!entered) {
|
||||
targetObj->setProperty(kEnteredFlag, true);
|
||||
sendEnterEvent(windowObj);
|
||||
if (isWidget) {
|
||||
sendEnterEvent(targetObj);
|
||||
} else {
|
||||
sendEnterEvent(windowObj);
|
||||
}
|
||||
}
|
||||
sendHoverMoveEvent(windowObj);
|
||||
if (isWidget) {
|
||||
sendHoverMoveEvent(targetObj);
|
||||
} else {
|
||||
sendHoverMoveEvent(windowObj);
|
||||
}
|
||||
if (mouseTrackingEnabled) {
|
||||
sendMouseMoveEvent(windowObj);
|
||||
if (leftButtonPressed || mouseTrackingEnabled) {
|
||||
if (isWidget) {
|
||||
sendMouseMoveEvent(targetObj);
|
||||
} else {
|
||||
sendMouseMoveEvent(windowObj);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case ButtonState::Pressed: {
|
||||
sendMousePressEvent(windowObj);
|
||||
case ButtonState::Pressed:
|
||||
// Sending mouse event to the window has no effect.
|
||||
sendMousePressEvent(targetObj);
|
||||
} break;
|
||||
case ButtonState::Released: {
|
||||
sendMouseReleaseEvent(windowObj);
|
||||
break;
|
||||
case ButtonState::Released:
|
||||
// Sending mouse event to the window has no effect.
|
||||
sendMouseReleaseEvent(targetObj);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -987,4 +987,10 @@ bool Utils::setPlatformPropertiesForWindow(QWindow *window, const QVariantHash &
|
|||
return true;
|
||||
}
|
||||
|
||||
Qt::MouseButtons Utils::queryMouseButtons()
|
||||
{
|
||||
// ### FIXME
|
||||
return {};
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -752,6 +752,12 @@ QColor Utils::getFrameBorderColor(const bool active)
|
|||
return (active ? getAccentColor() : kDefaultDarkGrayColor);
|
||||
}
|
||||
|
||||
Qt::MouseButtons Utils::queryMouseButtons()
|
||||
{
|
||||
// ### FIXME
|
||||
return {};
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
#include "utils_mac.moc"
|
||||
|
|
|
@ -2571,6 +2571,31 @@ quint64 Utils::queryMouseButtonState()
|
|||
return result;
|
||||
}
|
||||
|
||||
Qt::MouseButtons Utils::queryMouseButtons()
|
||||
{
|
||||
const quint64 buttonMask = queryMouseButtonState();
|
||||
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)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
|
|
|
@ -903,7 +903,16 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
|
|||
const QPoint globalPos = (screen ? QCursor::pos(screen) : QCursor::pos());
|
||||
const QPoint localPos = btn->mapFromGlobal(globalPos).toPoint();
|
||||
const QPoint scenePos = window->mapFromGlobal(globalPos);
|
||||
Utils::emulateQtMouseEvent(btn, window, FRAMELESSHELPER_ENUM_QUICK_TO_CORE(ButtonState, state), globalPos, scenePos, localPos);
|
||||
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
|
||||
|
|
|
@ -863,7 +863,14 @@ void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType
|
|||
const QPoint globalPos = (screen ? QCursor::pos(screen) : QCursor::pos());
|
||||
const QPoint localPos = btn->mapFromGlobal(globalPos);
|
||||
const QPoint scenePos = window->mapFromGlobal(globalPos);
|
||||
Utils::emulateQtMouseEvent(btn, window->windowHandle(), state, globalPos, scenePos, localPos);
|
||||
#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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue