Client: Use a QWaylandSurface for pointer focus
Task-number: QTBUG-74373 Change-Id: Idfd94442ff542b81956d4852e07eb3b5dff80712 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
parent
5d1b75d9c1
commit
4b40d01819
@ -47,6 +47,7 @@
|
||||
#include "qwaylandinputdevice_p.h"
|
||||
#include "qwaylanddisplay_p.h"
|
||||
#include "qwaylandabstractdecoration_p.h"
|
||||
#include "qwaylandsurface_p.h"
|
||||
|
||||
#include <QtCore/QMimeData>
|
||||
#include <QtGui/QGuiApplication>
|
||||
@ -107,9 +108,10 @@ void QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon)
|
||||
m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData));
|
||||
connect(m_dragSource.data(), &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::dragSourceCancelled);
|
||||
|
||||
QWaylandWindow *origin = m_display->currentInputDevice()->pointerFocus();
|
||||
auto *seat = m_display->currentInputDevice();
|
||||
auto *origin = seat->pointerFocus();
|
||||
if (!origin)
|
||||
origin = m_display->currentInputDevice()->touchFocus();
|
||||
origin = seat->touchFocus();
|
||||
|
||||
start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial());
|
||||
}
|
||||
|
@ -189,6 +189,11 @@ QWaylandInputDevice::Pointer::~Pointer()
|
||||
wl_pointer_destroy(object());
|
||||
}
|
||||
|
||||
QWaylandWindow *QWaylandInputDevice::Pointer::focusWindow() const
|
||||
{
|
||||
return mFocus ? mFocus->waylandWindow() : nullptr;
|
||||
}
|
||||
|
||||
#if QT_CONFIG(cursor)
|
||||
|
||||
class WlCallback : public QtWayland::wl_callback {
|
||||
@ -498,7 +503,7 @@ void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button)
|
||||
|
||||
QWaylandWindow *QWaylandInputDevice::pointerFocus() const
|
||||
{
|
||||
return mPointer ? mPointer->mFocus : nullptr;
|
||||
return mPointer ? mPointer->focusWindow() : nullptr;
|
||||
}
|
||||
|
||||
QWaylandWindow *QWaylandInputDevice::keyboardFocus() const
|
||||
@ -596,8 +601,8 @@ void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surf
|
||||
<< "attempting to work around it by invalidating the current focus";
|
||||
invalidateFocus();
|
||||
}
|
||||
mFocus = window;
|
||||
connect(mFocus, &QWaylandWindow::wlSurfaceDestroyed, this, &Pointer::handleFocusDestroyed);
|
||||
mFocus = window->waylandSurface();
|
||||
connect(mFocus, &QObject::destroyed, this, &Pointer::handleFocusDestroyed);
|
||||
|
||||
mSurfacePos = QPointF(wl_fixed_to_double(sx), wl_fixed_to_double(sy));
|
||||
mGlobalPos = window->window()->mapToGlobal(mSurfacePos.toPoint());
|
||||
@ -657,7 +662,7 @@ public:
|
||||
|
||||
void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||
{
|
||||
QWaylandWindow *window = mFocus;
|
||||
QWaylandWindow *window = focusWindow();
|
||||
if (!window) {
|
||||
// We destroyed the pointer focus surface, but the server didn't get the message yet...
|
||||
// or the server didn't send an enter event first. In either case, ignore the event.
|
||||
@ -709,7 +714,7 @@ public:
|
||||
void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time,
|
||||
uint32_t button, uint32_t state)
|
||||
{
|
||||
QWaylandWindow *window = mFocus;
|
||||
QWaylandWindow *window = focusWindow();
|
||||
if (!window) {
|
||||
// We destroyed the pointer focus surface, but the server didn't get the message yet...
|
||||
// or the server didn't send an enter event first. In either case, ignore the event.
|
||||
@ -754,7 +759,7 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time
|
||||
|
||||
QPointF pos = mSurfacePos;
|
||||
QPointF global = mGlobalPos;
|
||||
if (grab && grab != mFocus) {
|
||||
if (grab && grab != focusWindow()) {
|
||||
pos = QPointF(-1, -1);
|
||||
global = grab->window()->mapToGlobal(pos.toPoint());
|
||||
|
||||
@ -769,7 +774,7 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time
|
||||
|
||||
void QWaylandInputDevice::Pointer::invalidateFocus()
|
||||
{
|
||||
disconnect(mFocus, &QWaylandWindow::wlSurfaceDestroyed, this, &Pointer::handleFocusDestroyed);
|
||||
disconnect(mFocus, &QObject::destroyed, this, &Pointer::handleFocusDestroyed);
|
||||
mFocus = nullptr;
|
||||
mEnterSerial = 0;
|
||||
}
|
||||
@ -777,9 +782,11 @@ void QWaylandInputDevice::Pointer::invalidateFocus()
|
||||
void QWaylandInputDevice::Pointer::releaseButtons()
|
||||
{
|
||||
mButtons = Qt::NoButton;
|
||||
MotionEvent e(mFocus, mParent->mTime, mSurfacePos, mGlobalPos, mButtons, mParent->modifiers());
|
||||
if (mFocus)
|
||||
mFocus->handleMouse(mParent, e);
|
||||
|
||||
if (auto *window = focusWindow()) {
|
||||
MotionEvent e(focusWindow(), mParent->mTime, mSurfacePos, mGlobalPos, mButtons, mParent->modifiers());
|
||||
window->handleMouse(mParent, e);
|
||||
}
|
||||
}
|
||||
|
||||
class WheelEvent : public QWaylandPointerEvent
|
||||
@ -796,9 +803,7 @@ public:
|
||||
|
||||
void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, int32_t value)
|
||||
{
|
||||
QWaylandWindow *window = mFocus;
|
||||
|
||||
if (!window) {
|
||||
if (!focusWindow()) {
|
||||
// We destroyed the pointer focus surface, but the server didn't get the message yet...
|
||||
// or the server didn't send an enter event first. In either case, ignore the event.
|
||||
return;
|
||||
@ -851,8 +856,7 @@ void QWaylandInputDevice::Pointer::pointer_axis_source(uint32_t source)
|
||||
|
||||
void QWaylandInputDevice::Pointer::pointer_axis_stop(uint32_t time, uint32_t axis)
|
||||
{
|
||||
QWaylandWindow *window = mFocus;
|
||||
if (window == nullptr)
|
||||
if (!focusWindow())
|
||||
return;
|
||||
|
||||
mParent->mTime = time;
|
||||
@ -882,9 +886,9 @@ void QWaylandInputDevice::Pointer::pointer_axis_stop(uint32_t time, uint32_t axi
|
||||
|
||||
QWaylandWindow *target = QWaylandWindow::mouseGrab();
|
||||
if (!target)
|
||||
target = mFocus;
|
||||
target = focusWindow();
|
||||
Qt::KeyboardModifiers mods = mParent->modifiers();
|
||||
WheelEvent wheelEvent(mFocus, Qt::ScrollEnd, mParent->mTime, mSurfacePos, mGlobalPos,
|
||||
WheelEvent wheelEvent(focusWindow(), Qt::ScrollEnd, mParent->mTime, mSurfacePos, mGlobalPos,
|
||||
QPoint(), QPoint(), Qt::MouseEventNotSynthesized, mods);
|
||||
target->handleMouse(mParent, wheelEvent);
|
||||
mScrollBeginSent = false;
|
||||
@ -893,8 +897,7 @@ void QWaylandInputDevice::Pointer::pointer_axis_stop(uint32_t time, uint32_t axi
|
||||
|
||||
void QWaylandInputDevice::Pointer::pointer_axis_discrete(uint32_t axis, int32_t value)
|
||||
{
|
||||
QWaylandWindow *window = mFocus;
|
||||
if (window == nullptr)
|
||||
if (!focusWindow())
|
||||
return;
|
||||
|
||||
switch (axis) {
|
||||
@ -999,11 +1002,11 @@ void QWaylandInputDevice::Pointer::flushScrollEvent()
|
||||
if (!angleDelta.isNull()) {
|
||||
QWaylandWindow *target = QWaylandWindow::mouseGrab();
|
||||
if (!target)
|
||||
target = mFocus;
|
||||
target = focusWindow();
|
||||
|
||||
if (isDefinitelyTerminated(mFrameData.axisSource) && !mScrollBeginSent) {
|
||||
qCDebug(lcQpaWaylandInput) << "Flushing scroll event sending ScrollBegin";
|
||||
target->handleMouse(mParent, WheelEvent(mFocus, Qt::ScrollBegin, mParent->mTime,
|
||||
target->handleMouse(mParent, WheelEvent(focusWindow(), Qt::ScrollBegin, mParent->mTime,
|
||||
mSurfacePos, mGlobalPos, QPoint(), QPoint(),
|
||||
Qt::MouseEventNotSynthesized,
|
||||
mParent->modifiers()));
|
||||
@ -1016,7 +1019,7 @@ void QWaylandInputDevice::Pointer::flushScrollEvent()
|
||||
Qt::MouseEventSource source = mFrameData.wheelEventSource();
|
||||
|
||||
qCDebug(lcQpaWaylandInput) << "Flushing scroll event" << phase << pixelDelta << angleDelta;
|
||||
target->handleMouse(mParent, WheelEvent(mFocus, phase, mParent->mTime, mSurfacePos, mGlobalPos,
|
||||
target->handleMouse(mParent, WheelEvent(focusWindow(), phase, mParent->mTime, mSurfacePos, mGlobalPos,
|
||||
pixelDelta, angleDelta, source, mParent->modifiers()));
|
||||
}
|
||||
|
||||
@ -1366,7 +1369,7 @@ void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::Touch
|
||||
|
||||
//is it possible that mTouchFocus is null;
|
||||
if (!win && mPointer)
|
||||
win = mPointer->mFocus;
|
||||
win = mPointer->focusWindow();
|
||||
if (!win && mKeyboard)
|
||||
win = mKeyboard->focusWindow();
|
||||
if (!win || !win->window())
|
||||
|
@ -258,6 +258,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice::Pointer : public QObject, pub
|
||||
public:
|
||||
explicit Pointer(QWaylandInputDevice *seat);
|
||||
~Pointer() override;
|
||||
QWaylandWindow *focusWindow() const;
|
||||
#if QT_CONFIG(cursor)
|
||||
QString cursorThemeName() const;
|
||||
int cursorSize() const; // in surface coordinates
|
||||
@ -294,7 +295,7 @@ public:
|
||||
void releaseButtons();
|
||||
|
||||
QWaylandInputDevice *mParent = nullptr;
|
||||
QPointer<QWaylandWindow> mFocus;
|
||||
QPointer<QWaylandSurface> mFocus;
|
||||
uint32_t mEnterSerial = 0;
|
||||
#if QT_CONFIG(cursor)
|
||||
struct {
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
explicit QWaylandSurface(QWaylandDisplay *display);
|
||||
~QWaylandSurface() override;
|
||||
QWaylandScreen *oldestEnteredScreen();
|
||||
QWaylandWindow *waylandWindow() const { return m_window; }
|
||||
|
||||
static QWaylandSurface *fromWlSurface(::wl_surface *surface);
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "qwaylandtouch_p.h"
|
||||
#include "qwaylandinputdevice_p.h"
|
||||
#include "qwaylanddisplay_p.h"
|
||||
#include "qwaylandsurface_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -127,6 +127,7 @@ public:
|
||||
QSize surfaceSize() const;
|
||||
QRect windowGeometry() const;
|
||||
|
||||
QWaylandSurface *waylandSurface() const { return mSurface.data(); }
|
||||
::wl_surface *wlSurface();
|
||||
static QWaylandWindow *fromWlSurface(::wl_surface *surface);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user