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,
|
||||
wl_fixed_t sx, wl_fixed_t sy)
|
||||
{
|
||||
Q_UNUSED(sx);
|
||||
Q_UNUSED(sy);
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
@ -358,15 +363,16 @@ void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surf
|
||||
window->window()->setCursor(window->window()->cursor());
|
||||
|
||||
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;
|
||||
mEnterSerial = serial;
|
||||
|
||||
QWaylandWindow *grab = QWaylandWindow::mouseGrab();
|
||||
if (!grab) {
|
||||
window->handleMouseEnter(mParent);
|
||||
window->handleMouse(mParent, mParent->mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
||||
EnterEvent evt(mSurfacePos, mGlobalPos);
|
||||
window->handleMouse(mParent, evt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,11 +393,17 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
|
||||
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)
|
||||
{
|
||||
Q_UNUSED(surface_x);
|
||||
Q_UNUSED(surface_y);
|
||||
|
||||
QWaylandWindow *window = mFocus;
|
||||
|
||||
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.
|
||||
pos = QPointF(-1, -1);
|
||||
global = grab->window()->mapToGlobal(pos.toPoint());
|
||||
grab->handleMouse(mParent, time, pos, global, mButtons, Qt::NoModifier);
|
||||
} else
|
||||
window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
||||
MotionEvent e(time, pos, global, mButtons, Qt::NoModifier);
|
||||
grab->handleMouse(mParent, e);
|
||||
} else {
|
||||
MotionEvent e(time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
||||
window->handleMouse(mParent, e);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
QPointF pos = QPointF(-1, -1);
|
||||
QPointF global = grab->window()->mapToGlobal(pos.toPoint());
|
||||
grab->handleMouse(mParent, time, pos, global, mButtons, Qt::NoModifier);
|
||||
} else if (window)
|
||||
window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
||||
MotionEvent e(time, pos, global, mButtons, Qt::NoModifier);
|
||||
grab->handleMouse(mParent, e);
|
||||
} 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)
|
||||
|
@ -260,7 +260,29 @@ public:
|
||||
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
|
||||
|
||||
|
@ -603,27 +603,28 @@ QWaylandWindow *QWaylandWindow::transientParent() const
|
||||
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();
|
||||
mMouseDevice = inputDevice;
|
||||
}
|
||||
|
||||
if (mWindowDecoration) {
|
||||
handleMouseEventWithDecoration(inputDevice, timestamp,local,global,b,mods);
|
||||
return;
|
||||
handleMouseEventWithDecoration(inputDevice, e);
|
||||
} 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);
|
||||
}
|
||||
|
||||
void QWaylandWindow::handleMouseEnter(QWaylandInputDevice *inputDevice)
|
||||
{
|
||||
if (!mWindowDecoration) {
|
||||
QWindowSystemInterface::handleEnterEvent(window());
|
||||
}
|
||||
restoreMouseCursor(inputDevice);
|
||||
if (e.type == QWaylandPointerEvent::Enter)
|
||||
restoreMouseCursor(inputDevice);
|
||||
}
|
||||
|
||||
void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice)
|
||||
@ -645,19 +646,22 @@ bool QWaylandWindow::touchDragDecoration(QWaylandInputDevice *inputDevice, const
|
||||
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;
|
||||
}
|
||||
|
||||
QMargins marg = frameMargins();
|
||||
QRect windowRect(0 + marg.left(),
|
||||
0 + marg.top(),
|
||||
geometry().size().width() - marg.right(),
|
||||
geometry().size().height() - marg.bottom());
|
||||
if (windowRect.contains(local.toPoint()) || mMousePressedInContentArea != Qt::NoButton) {
|
||||
QPointF localTranslated = local;
|
||||
QPointF globalTranslated = global;
|
||||
if (windowRect.contains(e.local.toPoint()) || mMousePressedInContentArea != Qt::NoButton) {
|
||||
QPointF localTranslated = e.local;
|
||||
QPointF globalTranslated = e.global;
|
||||
localTranslated.setX(localTranslated.x() - marg.left());
|
||||
localTranslated.setY(localTranslated.y() - marg.top());
|
||||
globalTranslated.setX(globalTranslated.x() - marg.left());
|
||||
@ -666,15 +670,23 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe
|
||||
restoreMouseCursor(inputDevice);
|
||||
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;
|
||||
mMousePressedInContentArea = b;
|
||||
mMousePressedInContentArea = e.buttons;
|
||||
} else {
|
||||
if (mMouseEventsInContentArea) {
|
||||
QWindowSystemInterface::handleLeaveEvent(window());
|
||||
mMouseEventsInContentArea = false;
|
||||
}
|
||||
mWindowDecoration->handleMouse(inputDevice,local,global,b,mods);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ class QWaylandAbstractDecoration;
|
||||
class QWaylandInputDevice;
|
||||
class QWaylandScreen;
|
||||
class QWaylandShmBackingStore;
|
||||
class QWaylandPointerEvent;
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowConfigure
|
||||
{
|
||||
@ -151,13 +152,7 @@ public:
|
||||
|
||||
QWaylandAbstractDecoration *decoration() const;
|
||||
|
||||
void handleMouse(QWaylandInputDevice *inputDevice,
|
||||
ulong timestamp,
|
||||
const QPointF & local,
|
||||
const QPointF & global,
|
||||
Qt::MouseButtons b,
|
||||
Qt::KeyboardModifiers mods);
|
||||
void handleMouseEnter(QWaylandInputDevice *inputDevice);
|
||||
void handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
|
||||
void handleMouseLeave(QWaylandInputDevice *inputDevice);
|
||||
|
||||
bool touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
|
||||
@ -237,12 +232,7 @@ private:
|
||||
bool setWindowStateInternal(Qt::WindowState flags);
|
||||
void setGeometry_helper(const QRect &rect);
|
||||
|
||||
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice,
|
||||
ulong timestamp,
|
||||
const QPointF & local,
|
||||
const QPointF & global,
|
||||
Qt::MouseButtons b,
|
||||
Qt::KeyboardModifiers mods);
|
||||
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
|
||||
|
||||
static const wl_callback_listener callbackListener;
|
||||
static void frameCallback(void *data, struct wl_callback *wl_callback, uint32_t time);
|
||||
|
Loading…
x
Reference in New Issue
Block a user