core: Batch pointer input device events
This change introduces InputDevice::pointerFrame(). The main motivation behind it is to allow batching multiple pointer events within a single event frame. BUG: 454428
This commit is contained in:
parent
60205c1348
commit
e6b5cf283e
10 changed files with 77 additions and 10 deletions
|
@ -1497,36 +1497,42 @@ void pointerAxisHorizontal(qreal delta, quint32 time, qint32 discreteDelta, Inpu
|
|||
{
|
||||
auto virtualPointer = static_cast<WaylandTestApplication *>(kwinApp())->virtualPointer();
|
||||
Q_EMIT virtualPointer->pointerAxisChanged(InputRedirection::PointerAxis::PointerAxisHorizontal, delta, discreteDelta, source, std::chrono::milliseconds(time), virtualPointer);
|
||||
Q_EMIT virtualPointer->pointerFrame(virtualPointer);
|
||||
}
|
||||
|
||||
void pointerAxisVertical(qreal delta, quint32 time, qint32 discreteDelta, InputRedirection::PointerAxisSource source)
|
||||
{
|
||||
auto virtualPointer = static_cast<WaylandTestApplication *>(kwinApp())->virtualPointer();
|
||||
Q_EMIT virtualPointer->pointerAxisChanged(InputRedirection::PointerAxis::PointerAxisVertical, delta, discreteDelta, source, std::chrono::milliseconds(time), virtualPointer);
|
||||
Q_EMIT virtualPointer->pointerFrame(virtualPointer);
|
||||
}
|
||||
|
||||
void pointerButtonPressed(quint32 button, quint32 time)
|
||||
{
|
||||
auto virtualPointer = static_cast<WaylandTestApplication *>(kwinApp())->virtualPointer();
|
||||
Q_EMIT virtualPointer->pointerButtonChanged(button, InputRedirection::PointerButtonState::PointerButtonPressed, std::chrono::milliseconds(time), virtualPointer);
|
||||
Q_EMIT virtualPointer->pointerFrame(virtualPointer);
|
||||
}
|
||||
|
||||
void pointerButtonReleased(quint32 button, quint32 time)
|
||||
{
|
||||
auto virtualPointer = static_cast<WaylandTestApplication *>(kwinApp())->virtualPointer();
|
||||
Q_EMIT virtualPointer->pointerButtonChanged(button, InputRedirection::PointerButtonState::PointerButtonReleased, std::chrono::milliseconds(time), virtualPointer);
|
||||
Q_EMIT virtualPointer->pointerFrame(virtualPointer);
|
||||
}
|
||||
|
||||
void pointerMotion(const QPointF &position, quint32 time)
|
||||
{
|
||||
auto virtualPointer = static_cast<WaylandTestApplication *>(kwinApp())->virtualPointer();
|
||||
Q_EMIT virtualPointer->pointerMotionAbsolute(position, std::chrono::milliseconds(time), virtualPointer);
|
||||
Q_EMIT virtualPointer->pointerFrame(virtualPointer);
|
||||
}
|
||||
|
||||
void pointerMotionRelative(const QPointF &delta, quint32 time)
|
||||
{
|
||||
auto virtualPointer = static_cast<WaylandTestApplication *>(kwinApp())->virtualPointer();
|
||||
Q_EMIT virtualPointer->pointerMotion(delta, delta, std::chrono::milliseconds(time), virtualPointer);
|
||||
Q_EMIT virtualPointer->pointerFrame(virtualPointer);
|
||||
}
|
||||
|
||||
void touchCancel()
|
||||
|
|
|
@ -22,18 +22,22 @@ FakeInputDevice::FakeInputDevice(KWaylandServer::FakeInputDevice *device, QObjec
|
|||
connect(device, &KWaylandServer::FakeInputDevice::pointerMotionRequested, this, [this](const QPointF &delta) {
|
||||
const auto time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
Q_EMIT pointerMotion(delta, delta, time, this);
|
||||
Q_EMIT pointerFrame(this);
|
||||
});
|
||||
connect(device, &KWaylandServer::FakeInputDevice::pointerMotionAbsoluteRequested, this, [this](const QPointF &pos) {
|
||||
const auto time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
Q_EMIT pointerMotionAbsolute(pos, time, this);
|
||||
Q_EMIT pointerFrame(this);
|
||||
});
|
||||
connect(device, &KWaylandServer::FakeInputDevice::pointerButtonPressRequested, this, [this](quint32 button) {
|
||||
const auto time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
Q_EMIT pointerButtonChanged(button, InputRedirection::PointerButtonPressed, time, this);
|
||||
Q_EMIT pointerFrame(this);
|
||||
});
|
||||
connect(device, &KWaylandServer::FakeInputDevice::pointerButtonReleaseRequested, this, [this](quint32 button) {
|
||||
const auto time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
Q_EMIT pointerButtonChanged(button, InputRedirection::PointerButtonReleased, time, this);
|
||||
Q_EMIT pointerFrame(this);
|
||||
});
|
||||
connect(device, &KWaylandServer::FakeInputDevice::pointerAxisRequested, this, [this](Qt::Orientation orientation, qreal delta) {
|
||||
InputRedirection::PointerAxis axis;
|
||||
|
@ -50,6 +54,7 @@ FakeInputDevice::FakeInputDevice(KWaylandServer::FakeInputDevice *device, QObjec
|
|||
}
|
||||
const auto time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
Q_EMIT pointerAxisChanged(axis, delta, 0, InputRedirection::PointerAxisSourceUnknown, time, this);
|
||||
Q_EMIT pointerFrame(this);
|
||||
});
|
||||
connect(device, &KWaylandServer::FakeInputDevice::touchDownRequested, this, [this](qint32 id, const QPointF &pos) {
|
||||
const auto time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
|
|
|
@ -318,6 +318,7 @@ void Connection::processEvents()
|
|||
pointerEvent->time(),
|
||||
pointerEvent->device());
|
||||
}
|
||||
Q_EMIT pointerEvent->device()->pointerFrame(pointerEvent->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_SCROLL_FINGER: {
|
||||
|
@ -331,6 +332,7 @@ void Connection::processEvents()
|
|||
pointerEvent->time(),
|
||||
pointerEvent->device());
|
||||
}
|
||||
Q_EMIT pointerEvent->device()->pointerFrame(pointerEvent->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS: {
|
||||
|
@ -344,11 +346,13 @@ void Connection::processEvents()
|
|||
pointerEvent->time(),
|
||||
pointerEvent->device());
|
||||
}
|
||||
Q_EMIT pointerEvent->device()->pointerFrame(pointerEvent->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_BUTTON: {
|
||||
PointerEvent *pe = static_cast<PointerEvent *>(event.get());
|
||||
Q_EMIT pe->device()->pointerButtonChanged(pe->button(), pe->buttonState(), pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pointerFrame(pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_MOTION: {
|
||||
|
@ -369,12 +373,14 @@ void Connection::processEvents()
|
|||
}
|
||||
}
|
||||
Q_EMIT pe->device()->pointerMotion(delta, deltaNonAccel, latestTime, pe->device());
|
||||
Q_EMIT pe->device()->pointerFrame(pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: {
|
||||
PointerEvent *pe = static_cast<PointerEvent *>(event.get());
|
||||
if (workspace()) {
|
||||
Q_EMIT pe->device()->pointerMotionAbsolute(pe->absolutePos(workspace()->geometry().size()), pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pointerFrame(pe->device());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -126,6 +126,10 @@ WaylandInputDevice::WaylandInputDevice(KWayland::Client::Pointer *pointer, Wayla
|
|||
Q_EMIT pointerAxisChanged(axis, delta, 0, InputRedirection::PointerAxisSourceUnknown, std::chrono::milliseconds(time), this);
|
||||
});
|
||||
|
||||
connect(pointer, &Pointer::frame, this, [this]() {
|
||||
Q_EMIT pointerFrame(this);
|
||||
});
|
||||
|
||||
KWayland::Client::PointerGestures *pointerGestures = m_seat->backend()->display()->pointerGestures();
|
||||
if (pointerGestures) {
|
||||
m_pinchGesture.reset(pointerGestures->createPinchGesture(m_pointer.get(), this));
|
||||
|
|
|
@ -416,6 +416,7 @@ void X11WindowedBackend::handleEvent(xcb_generic_event_t *e)
|
|||
}
|
||||
const QPointF position = output->mapFromGlobal(QPointF(event->root_x, event->root_y));
|
||||
Q_EMIT m_pointerDevice->pointerMotionAbsolute(position, std::chrono::milliseconds(event->time), m_pointerDevice.get());
|
||||
Q_EMIT m_pointerDevice->pointerFrame(m_pointerDevice.get());
|
||||
} break;
|
||||
case XCB_KEY_PRESS:
|
||||
case XCB_KEY_RELEASE: {
|
||||
|
@ -575,6 +576,7 @@ void X11WindowedBackend::handleButtonPress(xcb_button_press_event_t *event)
|
|||
InputRedirection::PointerAxisSourceUnknown,
|
||||
std::chrono::milliseconds(event->time),
|
||||
m_pointerDevice.get());
|
||||
Q_EMIT m_pointerDevice->pointerFrame(m_pointerDevice.get());
|
||||
return;
|
||||
}
|
||||
uint32_t button = 0;
|
||||
|
@ -601,6 +603,7 @@ void X11WindowedBackend::handleButtonPress(xcb_button_press_event_t *event)
|
|||
} else {
|
||||
Q_EMIT m_pointerDevice->pointerButtonChanged(button, InputRedirection::PointerButtonReleased, std::chrono::milliseconds(event->time), m_pointerDevice.get());
|
||||
}
|
||||
Q_EMIT m_pointerDevice->pointerFrame(m_pointerDevice.get());
|
||||
}
|
||||
|
||||
void X11WindowedBackend::handleExpose(xcb_expose_event_t *event)
|
||||
|
|
|
@ -54,6 +54,7 @@ Q_SIGNALS:
|
|||
void pointerMotion(const QPointF &delta, const QPointF &deltaNonAccelerated, std::chrono::microseconds time, InputDevice *device);
|
||||
void pointerAxisChanged(InputRedirection::PointerAxis axis, qreal delta, qint32 deltaV120,
|
||||
InputRedirection::PointerAxisSource source, std::chrono::microseconds time, InputDevice *device);
|
||||
void pointerFrame(InputDevice *device);
|
||||
void touchFrame(InputDevice *device);
|
||||
void touchCanceled(InputDevice *device);
|
||||
void touchDown(qint32 id, const QPointF &absolutePos, std::chrono::microseconds time, InputDevice *device);
|
||||
|
|
|
@ -111,6 +111,11 @@ bool InputEventFilter::pointerEvent(MouseEvent *event, quint32 nativeButton)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::pointerFrame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputEventFilter::wheelEvent(WheelEvent *event)
|
||||
{
|
||||
return false;
|
||||
|
@ -322,7 +327,6 @@ public:
|
|||
if (pointerSurfaceAllowed()) {
|
||||
// TODO: should the pointer position always stay in sync, i.e. not do the check?
|
||||
seat->notifyPointerMotion(event->screenPos());
|
||||
seat->notifyPointerFrame();
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) {
|
||||
if (pointerSurfaceAllowed()) {
|
||||
|
@ -332,11 +336,21 @@ public:
|
|||
? KWaylandServer::PointerButtonState::Pressed
|
||||
: KWaylandServer::PointerButtonState::Released;
|
||||
seat->notifyPointerButton(nativeButton, state);
|
||||
seat->notifyPointerFrame();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool pointerFrame() override
|
||||
{
|
||||
if (!waylandServer()->isScreenLocked()) {
|
||||
return false;
|
||||
}
|
||||
auto seat = waylandServer()->seat();
|
||||
if (pointerSurfaceAllowed()) {
|
||||
seat->notifyPointerFrame();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool wheelEvent(WheelEvent *event) override
|
||||
{
|
||||
if (!waylandServer()->isScreenLocked()) {
|
||||
|
@ -349,7 +363,6 @@ public:
|
|||
seat->notifyPointerAxis(wheelEvent->orientation(), wheelEvent->delta(),
|
||||
wheelEvent->deltaV120(),
|
||||
kwinAxisSourceToKWaylandAxisSource(wheelEvent->axisSource()));
|
||||
seat->notifyPointerFrame();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1774,22 +1787,25 @@ public:
|
|||
if (!e->delta().isNull()) {
|
||||
seat->relativePointerMotion(e->delta(), e->deltaUnaccelerated(), e->timestamp());
|
||||
}
|
||||
seat->notifyPointerFrame();
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonPress:
|
||||
seat->notifyPointerButton(nativeButton, KWaylandServer::PointerButtonState::Pressed);
|
||||
seat->notifyPointerFrame();
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
seat->notifyPointerButton(nativeButton, KWaylandServer::PointerButtonState::Released);
|
||||
seat->notifyPointerFrame();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool pointerFrame() override
|
||||
{
|
||||
auto seat = waylandServer()->seat();
|
||||
seat->notifyPointerFrame();
|
||||
return true;
|
||||
}
|
||||
bool wheelEvent(WheelEvent *event) override
|
||||
{
|
||||
auto seat = waylandServer()->seat();
|
||||
|
@ -1797,7 +1813,6 @@ public:
|
|||
auto _event = static_cast<WheelEvent *>(event);
|
||||
seat->notifyPointerAxis(_event->orientation(), _event->delta(), _event->deltaV120(),
|
||||
kwinAxisSourceToKWaylandAxisSource(_event->axisSource()));
|
||||
seat->notifyPointerFrame();
|
||||
return true;
|
||||
}
|
||||
bool keyEvent(KeyEvent *event) override
|
||||
|
@ -2399,7 +2414,6 @@ public:
|
|||
case QEvent::MouseMove: {
|
||||
const auto pos = input()->globalPointer();
|
||||
seat->notifyPointerMotion(pos);
|
||||
seat->notifyPointerFrame();
|
||||
|
||||
Window *dragTarget = pickDragTarget(pos);
|
||||
if (dragTarget) {
|
||||
|
@ -2438,13 +2452,11 @@ public:
|
|||
}
|
||||
case QEvent::MouseButtonPress:
|
||||
seat->notifyPointerButton(nativeButton, KWaylandServer::PointerButtonState::Pressed);
|
||||
seat->notifyPointerFrame();
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
raiseDragTarget();
|
||||
m_dragTarget = nullptr;
|
||||
seat->notifyPointerButton(nativeButton, KWaylandServer::PointerButtonState::Released);
|
||||
seat->notifyPointerFrame();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2453,6 +2465,20 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool pointerFrame() override
|
||||
{
|
||||
auto seat = waylandServer()->seat();
|
||||
if (!seat->isDragPointer()) {
|
||||
return false;
|
||||
}
|
||||
if (seat->isDragTouch()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
seat->notifyPointerFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time) override
|
||||
{
|
||||
auto seat = waylandServer()->seat();
|
||||
|
@ -2916,6 +2942,8 @@ void InputRedirection::addInputDevice(InputDevice *device)
|
|||
m_pointer, &PointerInputRedirection::processButton);
|
||||
connect(device, &InputDevice::pointerAxisChanged,
|
||||
m_pointer, &PointerInputRedirection::processAxis);
|
||||
connect(device, &InputDevice::pointerFrame,
|
||||
m_pointer, &PointerInputRedirection::processFrame);
|
||||
connect(device, &InputDevice::pinchGestureBegin,
|
||||
m_pointer, &PointerInputRedirection::processPinchGestureBegin);
|
||||
connect(device, &InputDevice::pinchGestureUpdate,
|
||||
|
|
|
@ -384,6 +384,7 @@ public:
|
|||
* @return @c true to stop further event processing, @c false to pass to next filter
|
||||
*/
|
||||
virtual bool pointerEvent(MouseEvent *event, quint32 nativeButton);
|
||||
virtual bool pointerFrame();
|
||||
/**
|
||||
* Event filter for pointer axis events.
|
||||
*
|
||||
|
|
|
@ -433,6 +433,15 @@ void PointerInputRedirection::processHoldGestureCancelled(std::chrono::microseco
|
|||
input()->processFilters(std::bind(&InputEventFilter::holdGestureCancelled, std::placeholders::_1, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processFrame(KWin::InputDevice *device)
|
||||
{
|
||||
if (!inited()) {
|
||||
return;
|
||||
}
|
||||
|
||||
input()->processFilters(std::bind(&InputEventFilter::pointerFrame, std::placeholders::_1));
|
||||
}
|
||||
|
||||
bool PointerInputRedirection::areButtonsPressed() const
|
||||
{
|
||||
for (auto state : m_buttons) {
|
||||
|
|
|
@ -143,6 +143,10 @@ public:
|
|||
* @internal
|
||||
*/
|
||||
void processHoldGestureCancelled(std::chrono::microseconds time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processFrame(KWin::InputDevice *device = nullptr);
|
||||
|
||||
private:
|
||||
void processMotionInternal(const QPointF &pos, const QPointF &delta, const QPointF &deltaNonAccelerated, std::chrono::microseconds time, InputDevice *device);
|
||||
|
|
Loading…
Reference in a new issue