diff --git a/src/wayland/tablet_v2.cpp b/src/wayland/tablet_v2.cpp index c8ac597bc6..d7c2833db3 100644 --- a/src/wayland/tablet_v2.cpp +++ b/src/wayland/tablet_v2.cpp @@ -215,6 +215,7 @@ public: Display *const m_display; quint32 m_proximitySerial = 0; + std::optional m_downSerial; bool m_cleanup = false; bool m_removed = false; QPointer m_surface; @@ -295,6 +296,11 @@ quint32 TabletToolV2Interface::proximitySerial() const return d->m_proximitySerial; } +std::optional TabletToolV2Interface::downSerial() const +{ + return d->m_downSerial; +} + bool TabletToolV2Interface::isClientSupported() const { return d->m_surface && !d->targetResources().empty(); @@ -399,6 +405,7 @@ void TabletToolV2Interface::sendDown() for (auto *resource : d->targetResources()) { d->send_down(resource->handle, serial); } + d->m_downSerial = serial; } void TabletToolV2Interface::sendUp() @@ -406,6 +413,7 @@ void TabletToolV2Interface::sendUp() for (auto *resource : d->targetResources()) { d->send_up(resource->handle); } + d->m_downSerial.reset(); } class TabletPadRingV2InterfacePrivate : public QtWaylandServer::zwp_tablet_pad_ring_v2 @@ -963,6 +971,15 @@ bool TabletSeatV2Interface::isClientSupported(ClientConnection *client) const return d->resourceMap().value(*client); } +bool TabletSeatV2Interface::hasImplicitGrab(quint32 serial) const +{ + return std::any_of(d->m_tools.cbegin(), d->m_tools.cend(), [serial](const auto &tools) { + return std::any_of(tools.cbegin(), tools.cend(), [serial](const auto tool) { + return tool->downSerial() == serial; + }); + }); +} + TabletManagerV2Interface::~TabletManagerV2Interface() = default; } // namespace KWin diff --git a/src/wayland/tablet_v2.h b/src/wayland/tablet_v2.h index 4895fa0ee2..6f54e38c1e 100644 --- a/src/wayland/tablet_v2.h +++ b/src/wayland/tablet_v2.h @@ -120,6 +120,7 @@ public: bool isClientSupported() const; quint32 proximitySerial() const; + std::optional downSerial() const; void sendProximityIn(TabletV2Interface *tablet); void sendProximityOut(); @@ -295,6 +296,8 @@ public: bool isClientSupported(ClientConnection *client) const; + bool hasImplicitGrab(quint32 serial) const; + private: friend class TabletManagerV2InterfacePrivate; explicit TabletSeatV2Interface(Display *display, QObject *parent); diff --git a/src/xdgshellwindow.cpp b/src/xdgshellwindow.cpp index 465ce72ad2..7f8508422b 100644 --- a/src/xdgshellwindow.cpp +++ b/src/xdgshellwindow.cpp @@ -17,6 +17,7 @@ #include "killprompt.h" #include "placement.h" #include "pointer_input.h" +#include "tablet_input.h" #include "touch_input.h" #include "utils/subsurfacemonitor.h" #include "virtualdesktops.h" @@ -27,6 +28,7 @@ #include "wayland/server_decoration.h" #include "wayland/server_decoration_palette.h" #include "wayland/surface.h" +#include "wayland/tablet_v2.h" #include "wayland/xdgdecoration_v1.h" #include "wayland_server.h" #include "workspace.h" @@ -913,15 +915,18 @@ void XdgToplevelWindow::handleWindowMenuRequested(SeatInterface *seat, const QPo void XdgToplevelWindow::handleMoveRequested(SeatInterface *seat, quint32 serial) { - if (!seat->hasImplicitPointerGrab(serial) && !seat->hasImplicitTouchGrab(serial)) { + if (!seat->hasImplicitPointerGrab(serial) && !seat->hasImplicitTouchGrab(serial) + && !waylandServer()->tabletManagerV2()->seat(seat)->hasImplicitGrab(serial)) { return; } if (isMovable()) { QPointF cursorPos; if (seat->hasImplicitPointerGrab(serial)) { cursorPos = input()->pointer()->pos(); - } else { + } else if (seat->hasImplicitTouchGrab(serial)) { cursorPos = input()->touch()->position(); + } else { + cursorPos = input()->tablet()->position(); } performMouseCommand(Options::MouseMove, cursorPos); } else { @@ -931,7 +936,8 @@ void XdgToplevelWindow::handleMoveRequested(SeatInterface *seat, quint32 serial) void XdgToplevelWindow::handleResizeRequested(SeatInterface *seat, XdgToplevelInterface::ResizeAnchor anchor, quint32 serial) { - if (!seat->hasImplicitPointerGrab(serial) && !seat->hasImplicitTouchGrab(serial)) { + if (!seat->hasImplicitPointerGrab(serial) && !seat->hasImplicitTouchGrab(serial) + && !waylandServer()->tabletManagerV2()->seat(seat)->hasImplicitGrab(serial)) { return; } if (!isResizable() || isShade()) { @@ -944,8 +950,10 @@ void XdgToplevelWindow::handleResizeRequested(SeatInterface *seat, XdgToplevelIn QPointF cursorPos; if (seat->hasImplicitPointerGrab(serial)) { cursorPos = input()->pointer()->pos(); - } else { + } else if (seat->hasImplicitTouchGrab(serial)) { cursorPos = input()->touch()->position(); + } else { + cursorPos = input()->tablet()->position(); } setInteractiveMoveOffset(cursorPos - pos()); // map from global setInvertedInteractiveMoveOffset(rect().bottomRight() - interactiveMoveOffset());