[libinput] Send touch events with respect to device rotation
Summary: Touch events coming from libinput devices must be transformed according to the current device rotation. Test Plan: Manually. Reviewers: #kwin Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D25921
This commit is contained in:
parent
7c70b344f5
commit
5b6e081af2
2 changed files with 60 additions and 15 deletions
|
@ -86,6 +86,17 @@ public:
|
|||
QRect geometry() const override;
|
||||
QSize physicalSize() const override;
|
||||
|
||||
/**
|
||||
* Returns the orientation of this output.
|
||||
*
|
||||
* - Flipped along the vertical axis is landscape + inv. portrait.
|
||||
* - Rotated 90° and flipped along the horizontal axis is portrait + inv. landscape
|
||||
* - Rotated 180° and flipped along the vertical axis is inv. landscape + inv. portrait
|
||||
* - Rotated 270° and flipped along the horizontal axis is inv. portrait + inv. landscape +
|
||||
* portrait
|
||||
*/
|
||||
Transform transform() const;
|
||||
|
||||
/**
|
||||
* Current refresh rate in 1/ms.
|
||||
*/
|
||||
|
@ -159,17 +170,6 @@ protected:
|
|||
|
||||
QSize orientateSize(const QSize &size) const;
|
||||
|
||||
/**
|
||||
* Returns the orientation of this output.
|
||||
*
|
||||
* - Flipped along the vertical axis is landscape + inv. portrait.
|
||||
* - Rotated 90° and flipped along the horizontal axis is portrait + inv. landscape
|
||||
* - Rotated 180° and flipped along the vertical axis is inv. landscape + inv. portrait
|
||||
* - Rotated 270° and flipped along the horizontal axis is inv. portrait + inv. landscape +
|
||||
* portrait
|
||||
*/
|
||||
Transform transform() const;
|
||||
|
||||
private:
|
||||
void createWaylandOutput();
|
||||
void createXdgOutput();
|
||||
|
|
|
@ -21,9 +21,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "context.h"
|
||||
#include "device.h"
|
||||
#include "events.h"
|
||||
|
||||
// TODO: Make it compile also in testing environment
|
||||
#ifndef KWIN_BUILD_TESTING
|
||||
#include "../abstract_wayland_output.h"
|
||||
#include "../main.h"
|
||||
#include "../platform.h"
|
||||
#include "../screens.h"
|
||||
#endif
|
||||
|
||||
#include "../logind.h"
|
||||
#include "../udev.h"
|
||||
#include "libinput_logging.h"
|
||||
|
@ -244,6 +250,37 @@ void Connection::handleEvent()
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef KWIN_BUILD_TESTING
|
||||
QPointF devicePointToGlobalPosition(const QPointF &devicePos, const AbstractWaylandOutput *output)
|
||||
{
|
||||
using Transform = AbstractWaylandOutput::Transform;
|
||||
|
||||
QPointF pos = devicePos;
|
||||
// TODO: Do we need to handle the flipped cases differently?
|
||||
switch (output->transform()) {
|
||||
case Transform::Normal:
|
||||
case Transform::Flipped:
|
||||
break;
|
||||
case Transform::Rotated90:
|
||||
case Transform::Flipped90:
|
||||
pos = QPointF(output->modeSize().height() - devicePos.y(), devicePos.x());
|
||||
break;
|
||||
case Transform::Rotated180:
|
||||
case Transform::Flipped180:
|
||||
pos = QPointF(output->modeSize().width() - devicePos.x(),
|
||||
output->modeSize().height() - devicePos.y());
|
||||
break;
|
||||
case Transform::Rotated270:
|
||||
case Transform::Flipped270:
|
||||
pos = QPointF(devicePos.y(), output->modeSize().width() - devicePos.x());
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
return output->geometry().topLeft() + pos / output->scale();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Connection::processEvents()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
@ -385,8 +422,12 @@ void Connection::processEvents()
|
|||
case LIBINPUT_EVENT_TOUCH_DOWN: {
|
||||
#ifndef KWIN_BUILD_TESTING
|
||||
TouchEvent *te = static_cast<TouchEvent*>(event.data());
|
||||
const auto &geo = screens()->geometry(te->device()->screenId());
|
||||
emit touchDown(te->id(), geo.topLeft() + te->absolutePos(geo.size()), te->time(), te->device());
|
||||
const auto *output = static_cast<AbstractWaylandOutput*>(
|
||||
kwinApp()->platform()->enabledOutputs()[te->device()->screenId()]);
|
||||
const QPointF globalPos =
|
||||
devicePointToGlobalPosition(te->absolutePos(output->modeSize()),
|
||||
output);
|
||||
emit touchDown(te->id(), globalPos, te->time(), te->device());
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
@ -398,8 +439,12 @@ void Connection::processEvents()
|
|||
case LIBINPUT_EVENT_TOUCH_MOTION: {
|
||||
#ifndef KWIN_BUILD_TESTING
|
||||
TouchEvent *te = static_cast<TouchEvent*>(event.data());
|
||||
const auto &geo = screens()->geometry(te->device()->screenId());
|
||||
emit touchMotion(te->id(), geo.topLeft() + te->absolutePos(geo.size()), te->time(), te->device());
|
||||
const auto *output = static_cast<AbstractWaylandOutput*>(
|
||||
kwinApp()->platform()->enabledOutputs()[te->device()->screenId()]);
|
||||
const QPointF globalPos =
|
||||
devicePointToGlobalPosition(te->absolutePos(output->modeSize()),
|
||||
output);
|
||||
emit touchMotion(te->id(), globalPos, te->time(), te->device());
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue