Unset touch targets on no current touch points

Summary:
Certain input devices like touch screens can be in a state of having no input
target at all. In case of touch screens when there are no current touch points.

In this case unset and block at-surface targets until a touch point is
available again.

Test Plan: Auto test window-selection passes again.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: graesslin, davidedmundson, zzag, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D17537
icc-effect-5.17.5
Roman Gilg 2018-12-13 10:46:21 +01:00
parent e14a523ef0
commit 05ca6c97f8
4 changed files with 29 additions and 11 deletions

View File

@ -2265,16 +2265,19 @@ void InputDeviceHandler::update()
if (!m_inited) {
return;
}
const auto pos = position().toPoint();
auto internalWindow = findInternalWindow(pos);
Toplevel *toplevel;
if (internalWindow) {
toplevel = waylandServer()->findClient(internalWindow);
} else {
toplevel = input()->findToplevel(pos);
Toplevel *toplevel = nullptr;
QWindow *internalWindow = nullptr;
if (!positionValid()) {
const auto pos = position().toPoint();
internalWindow = findInternalWindow(pos);
if (internalWindow) {
toplevel = waylandServer()->findClient(internalWindow);
} else {
toplevel = input()->findToplevel(pos);
}
}
// Always set the toplevel at the position of the input device.
setAt(toplevel);

View File

@ -424,6 +424,13 @@ protected:
virtual void focusUpdate(Toplevel *old, Toplevel *now) = 0;
/* Certain input devices can be in a state of having no valid
* position. An example are touch screens when no finger/pen
* is resting on the surface (no touch point).
*/
virtual bool positionValid() const {
return false;
}
virtual bool focusUpdatesBlocked() {
return false;
}

View File

@ -78,13 +78,20 @@ bool TouchInputRedirection::focusUpdatesBlocked()
if (waylandServer()->seat()->isDragTouch()) {
return true;
}
if (m_touches > 0) {
if (m_touches > 1) {
// first touch defines focus
return true;
}
return false;
}
bool TouchInputRedirection::positionValid() const
{
Q_ASSERT(m_touches >= 0);
// we can only determine a position with atleast one touch point
return m_touches == 0;
}
void TouchInputRedirection::focusUpdate(Toplevel *focusOld, Toplevel *focusNow)
{
// TODO: handle pointer grab aka popups
@ -171,10 +178,10 @@ void TouchInputRedirection::processDown(qint32 id, const QPointF &pos, quint32 t
}
m_lastPosition = pos;
m_windowUpdatedInCycle = false;
if (m_touches == 0) {
m_touches++;
if (m_touches == 1) {
update();
}
m_touches++;
input()->processSpies(std::bind(&InputEventSpy::touchDown, std::placeholders::_1, id, pos, time));
input()->processFilters(std::bind(&InputEventFilter::touchDown, std::placeholders::_1, id, pos, time));
m_windowUpdatedInCycle = false;

View File

@ -50,6 +50,7 @@ public:
explicit TouchInputRedirection(InputRedirection *parent);
virtual ~TouchInputRedirection();
bool positionValid() const override;
bool focusUpdatesBlocked() override;
void init();