Send proper mouse enter events
The wl_pointer.event carries the surface local position of the pointer. Notify Qt of it, without pretending it to be a motion event. Change-Id: Ibbe1d125a93b478f9c350a50bfea25b01f628178 Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
This commit is contained in:
parent
7fd1af437b
commit
92eac38d68
@ -345,12 +345,17 @@ void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EnterEvent : public QWaylandPointerEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EnterEvent(const QPointF &l, const QPointF &g)
|
||||||
|
: QWaylandPointerEvent(QWaylandPointerEvent::Enter, 0, l, g, 0, Qt::NoModifier)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surface *surface,
|
void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surface *surface,
|
||||||
wl_fixed_t sx, wl_fixed_t sy)
|
wl_fixed_t sx, wl_fixed_t sy)
|
||||||
{
|
{
|
||||||
Q_UNUSED(sx);
|
|
||||||
Q_UNUSED(sy);
|
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -358,15 +363,16 @@ void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surf
|
|||||||
window->window()->setCursor(window->window()->cursor());
|
window->window()->setCursor(window->window()->cursor());
|
||||||
|
|
||||||
mFocus = window;
|
mFocus = window;
|
||||||
|
mSurfacePos = QPointF(wl_fixed_to_double(sx), wl_fixed_to_double(sy));
|
||||||
|
mGlobalPos = window->window()->mapToGlobal(mSurfacePos.toPoint());
|
||||||
|
|
||||||
mParent->mTime = QWaylandDisplay::currentTimeMillisec();
|
|
||||||
mParent->mSerial = serial;
|
mParent->mSerial = serial;
|
||||||
mEnterSerial = serial;
|
mEnterSerial = serial;
|
||||||
|
|
||||||
QWaylandWindow *grab = QWaylandWindow::mouseGrab();
|
QWaylandWindow *grab = QWaylandWindow::mouseGrab();
|
||||||
if (!grab) {
|
if (!grab) {
|
||||||
window->handleMouseEnter(mParent);
|
EnterEvent evt(mSurfacePos, mGlobalPos);
|
||||||
window->handleMouse(mParent, mParent->mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
window->handleMouse(mParent, evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,11 +393,17 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
|
|||||||
mParent->mTime = time;
|
mParent->mTime = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MotionEvent : public QWaylandPointerEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MotionEvent(ulong t, const QPointF &l, const QPointF &g, Qt::MouseButtons b, Qt::KeyboardModifiers m)
|
||||||
|
: QWaylandPointerEvent(QWaylandPointerEvent::Motion, t, l, g, b, m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||||
{
|
{
|
||||||
Q_UNUSED(surface_x);
|
|
||||||
Q_UNUSED(surface_y);
|
|
||||||
|
|
||||||
QWaylandWindow *window = mFocus;
|
QWaylandWindow *window = mFocus;
|
||||||
|
|
||||||
if (window == NULL) {
|
if (window == NULL) {
|
||||||
@ -415,9 +427,12 @@ void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surf
|
|||||||
// so we just set it outside of the window boundaries.
|
// so we just set it outside of the window boundaries.
|
||||||
pos = QPointF(-1, -1);
|
pos = QPointF(-1, -1);
|
||||||
global = grab->window()->mapToGlobal(pos.toPoint());
|
global = grab->window()->mapToGlobal(pos.toPoint());
|
||||||
grab->handleMouse(mParent, time, pos, global, mButtons, Qt::NoModifier);
|
MotionEvent e(time, pos, global, mButtons, Qt::NoModifier);
|
||||||
} else
|
grab->handleMouse(mParent, e);
|
||||||
window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
} else {
|
||||||
|
MotionEvent e(time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
||||||
|
window->handleMouse(mParent, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time,
|
void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time,
|
||||||
@ -461,9 +476,12 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time
|
|||||||
if (grab && grab != mFocus) {
|
if (grab && grab != mFocus) {
|
||||||
QPointF pos = QPointF(-1, -1);
|
QPointF pos = QPointF(-1, -1);
|
||||||
QPointF global = grab->window()->mapToGlobal(pos.toPoint());
|
QPointF global = grab->window()->mapToGlobal(pos.toPoint());
|
||||||
grab->handleMouse(mParent, time, pos, global, mButtons, Qt::NoModifier);
|
MotionEvent e(time, pos, global, mButtons, Qt::NoModifier);
|
||||||
} else if (window)
|
grab->handleMouse(mParent, e);
|
||||||
window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
} else if (window) {
|
||||||
|
MotionEvent e(time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
||||||
|
window->handleMouse(mParent, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, int32_t value)
|
void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, int32_t value)
|
||||||
|
@ -260,7 +260,29 @@ public:
|
|||||||
QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints;
|
QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QWaylandPointerEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Enter,
|
||||||
|
Motion
|
||||||
|
};
|
||||||
|
inline QWaylandPointerEvent(Type t, ulong ts, const QPointF &l, const QPointF &g, Qt::MouseButtons b, Qt::KeyboardModifiers m)
|
||||||
|
: type(t)
|
||||||
|
, timestamp(ts)
|
||||||
|
, local(l)
|
||||||
|
, global(g)
|
||||||
|
, buttons(b)
|
||||||
|
, modifiers(m)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
ulong timestamp;
|
||||||
|
QPointF local;
|
||||||
|
QPointF global;
|
||||||
|
Qt::MouseButtons buttons;
|
||||||
|
Qt::KeyboardModifiers modifiers;
|
||||||
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
@ -603,27 +603,28 @@ QWaylandWindow *QWaylandWindow::transientParent() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e)
|
||||||
{
|
{
|
||||||
if (b != Qt::NoButton) {
|
if (e.buttons != Qt::NoButton) {
|
||||||
mMouseSerial = inputDevice->serial();
|
mMouseSerial = inputDevice->serial();
|
||||||
mMouseDevice = inputDevice;
|
mMouseDevice = inputDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mWindowDecoration) {
|
if (mWindowDecoration) {
|
||||||
handleMouseEventWithDecoration(inputDevice, timestamp,local,global,b,mods);
|
handleMouseEventWithDecoration(inputDevice, e);
|
||||||
return;
|
} else {
|
||||||
|
switch (e.type) {
|
||||||
|
case QWaylandPointerEvent::Enter:
|
||||||
|
QWindowSystemInterface::handleEnterEvent(window(), e.local, e.global);
|
||||||
|
break;
|
||||||
|
case QWaylandPointerEvent::Motion:
|
||||||
|
QWindowSystemInterface::handleMouseEvent(window(), e.timestamp, e.local, e.global, e.buttons, e.modifiers);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWindowSystemInterface::handleMouseEvent(window(),timestamp,local,global,b,mods);
|
if (e.type == QWaylandPointerEvent::Enter)
|
||||||
}
|
restoreMouseCursor(inputDevice);
|
||||||
|
|
||||||
void QWaylandWindow::handleMouseEnter(QWaylandInputDevice *inputDevice)
|
|
||||||
{
|
|
||||||
if (!mWindowDecoration) {
|
|
||||||
QWindowSystemInterface::handleEnterEvent(window());
|
|
||||||
}
|
|
||||||
restoreMouseCursor(inputDevice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice)
|
void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice)
|
||||||
@ -645,19 +646,22 @@ bool QWaylandWindow::touchDragDecoration(QWaylandInputDevice *inputDevice, const
|
|||||||
return mWindowDecoration->handleTouch(inputDevice, local, global, state, mods);
|
return mWindowDecoration->handleTouch(inputDevice, local, global, state, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e)
|
||||||
{
|
{
|
||||||
if (mWindowDecoration->handleMouse(inputDevice,local,global,b,mods))
|
if (mWindowDecoration->handleMouse(inputDevice, e.local, e.global, e.buttons, e.modifiers)) {
|
||||||
|
if (mMouseEventsInContentArea)
|
||||||
|
QWindowSystemInterface::handleLeaveEvent(window());
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QMargins marg = frameMargins();
|
QMargins marg = frameMargins();
|
||||||
QRect windowRect(0 + marg.left(),
|
QRect windowRect(0 + marg.left(),
|
||||||
0 + marg.top(),
|
0 + marg.top(),
|
||||||
geometry().size().width() - marg.right(),
|
geometry().size().width() - marg.right(),
|
||||||
geometry().size().height() - marg.bottom());
|
geometry().size().height() - marg.bottom());
|
||||||
if (windowRect.contains(local.toPoint()) || mMousePressedInContentArea != Qt::NoButton) {
|
if (windowRect.contains(e.local.toPoint()) || mMousePressedInContentArea != Qt::NoButton) {
|
||||||
QPointF localTranslated = local;
|
QPointF localTranslated = e.local;
|
||||||
QPointF globalTranslated = global;
|
QPointF globalTranslated = e.global;
|
||||||
localTranslated.setX(localTranslated.x() - marg.left());
|
localTranslated.setX(localTranslated.x() - marg.left());
|
||||||
localTranslated.setY(localTranslated.y() - marg.top());
|
localTranslated.setY(localTranslated.y() - marg.top());
|
||||||
globalTranslated.setX(globalTranslated.x() - marg.left());
|
globalTranslated.setX(globalTranslated.x() - marg.left());
|
||||||
@ -666,15 +670,23 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe
|
|||||||
restoreMouseCursor(inputDevice);
|
restoreMouseCursor(inputDevice);
|
||||||
QWindowSystemInterface::handleEnterEvent(window());
|
QWindowSystemInterface::handleEnterEvent(window());
|
||||||
}
|
}
|
||||||
QWindowSystemInterface::handleMouseEvent(window(), timestamp, localTranslated, globalTranslated, b, mods);
|
|
||||||
|
switch (e.type) {
|
||||||
|
case QWaylandPointerEvent::Enter:
|
||||||
|
QWindowSystemInterface::handleEnterEvent(window(), localTranslated, globalTranslated);
|
||||||
|
break;
|
||||||
|
case QWaylandPointerEvent::Motion:
|
||||||
|
QWindowSystemInterface::handleMouseEvent(window(), e.timestamp, localTranslated, globalTranslated, e.buttons, e.modifiers);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
mMouseEventsInContentArea = true;
|
mMouseEventsInContentArea = true;
|
||||||
mMousePressedInContentArea = b;
|
mMousePressedInContentArea = e.buttons;
|
||||||
} else {
|
} else {
|
||||||
if (mMouseEventsInContentArea) {
|
if (mMouseEventsInContentArea) {
|
||||||
QWindowSystemInterface::handleLeaveEvent(window());
|
QWindowSystemInterface::handleLeaveEvent(window());
|
||||||
mMouseEventsInContentArea = false;
|
mMouseEventsInContentArea = false;
|
||||||
}
|
}
|
||||||
mWindowDecoration->handleMouse(inputDevice,local,global,b,mods);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ class QWaylandAbstractDecoration;
|
|||||||
class QWaylandInputDevice;
|
class QWaylandInputDevice;
|
||||||
class QWaylandScreen;
|
class QWaylandScreen;
|
||||||
class QWaylandShmBackingStore;
|
class QWaylandShmBackingStore;
|
||||||
|
class QWaylandPointerEvent;
|
||||||
|
|
||||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowConfigure
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowConfigure
|
||||||
{
|
{
|
||||||
@ -151,13 +152,7 @@ public:
|
|||||||
|
|
||||||
QWaylandAbstractDecoration *decoration() const;
|
QWaylandAbstractDecoration *decoration() const;
|
||||||
|
|
||||||
void handleMouse(QWaylandInputDevice *inputDevice,
|
void handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
|
||||||
ulong timestamp,
|
|
||||||
const QPointF & local,
|
|
||||||
const QPointF & global,
|
|
||||||
Qt::MouseButtons b,
|
|
||||||
Qt::KeyboardModifiers mods);
|
|
||||||
void handleMouseEnter(QWaylandInputDevice *inputDevice);
|
|
||||||
void handleMouseLeave(QWaylandInputDevice *inputDevice);
|
void handleMouseLeave(QWaylandInputDevice *inputDevice);
|
||||||
|
|
||||||
bool touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
|
bool touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
|
||||||
@ -237,12 +232,7 @@ private:
|
|||||||
bool setWindowStateInternal(Qt::WindowState flags);
|
bool setWindowStateInternal(Qt::WindowState flags);
|
||||||
void setGeometry_helper(const QRect &rect);
|
void setGeometry_helper(const QRect &rect);
|
||||||
|
|
||||||
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice,
|
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
|
||||||
ulong timestamp,
|
|
||||||
const QPointF & local,
|
|
||||||
const QPointF & global,
|
|
||||||
Qt::MouseButtons b,
|
|
||||||
Qt::KeyboardModifiers mods);
|
|
||||||
|
|
||||||
static const wl_callback_listener callbackListener;
|
static const wl_callback_listener callbackListener;
|
||||||
static void frameCallback(void *data, struct wl_callback *wl_callback, uint32_t time);
|
static void frameCallback(void *data, struct wl_callback *wl_callback, uint32_t time);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user