[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;
|
QRect geometry() const override;
|
||||||
QSize physicalSize() 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.
|
* Current refresh rate in 1/ms.
|
||||||
*/
|
*/
|
||||||
|
@ -159,17 +170,6 @@ protected:
|
||||||
|
|
||||||
QSize orientateSize(const QSize &size) const;
|
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:
|
private:
|
||||||
void createWaylandOutput();
|
void createWaylandOutput();
|
||||||
void createXdgOutput();
|
void createXdgOutput();
|
||||||
|
|
|
@ -21,9 +21,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
|
||||||
|
// TODO: Make it compile also in testing environment
|
||||||
#ifndef KWIN_BUILD_TESTING
|
#ifndef KWIN_BUILD_TESTING
|
||||||
|
#include "../abstract_wayland_output.h"
|
||||||
|
#include "../main.h"
|
||||||
|
#include "../platform.h"
|
||||||
#include "../screens.h"
|
#include "../screens.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../logind.h"
|
#include "../logind.h"
|
||||||
#include "../udev.h"
|
#include "../udev.h"
|
||||||
#include "libinput_logging.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()
|
void Connection::processEvents()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
|
@ -385,8 +422,12 @@ void Connection::processEvents()
|
||||||
case LIBINPUT_EVENT_TOUCH_DOWN: {
|
case LIBINPUT_EVENT_TOUCH_DOWN: {
|
||||||
#ifndef KWIN_BUILD_TESTING
|
#ifndef KWIN_BUILD_TESTING
|
||||||
TouchEvent *te = static_cast<TouchEvent*>(event.data());
|
TouchEvent *te = static_cast<TouchEvent*>(event.data());
|
||||||
const auto &geo = screens()->geometry(te->device()->screenId());
|
const auto *output = static_cast<AbstractWaylandOutput*>(
|
||||||
emit touchDown(te->id(), geo.topLeft() + te->absolutePos(geo.size()), te->time(), te->device());
|
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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -398,8 +439,12 @@ void Connection::processEvents()
|
||||||
case LIBINPUT_EVENT_TOUCH_MOTION: {
|
case LIBINPUT_EVENT_TOUCH_MOTION: {
|
||||||
#ifndef KWIN_BUILD_TESTING
|
#ifndef KWIN_BUILD_TESTING
|
||||||
TouchEvent *te = static_cast<TouchEvent*>(event.data());
|
TouchEvent *te = static_cast<TouchEvent*>(event.data());
|
||||||
const auto &geo = screens()->geometry(te->device()->screenId());
|
const auto *output = static_cast<AbstractWaylandOutput*>(
|
||||||
emit touchMotion(te->id(), geo.topLeft() + te->absolutePos(geo.size()), te->time(), te->device());
|
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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue