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
This commit is contained in:
parent
e14a523ef0
commit
05ca6c97f8
4 changed files with 29 additions and 11 deletions
19
input.cpp
19
input.cpp
|
@ -2265,16 +2265,19 @@ void InputDeviceHandler::update()
|
||||||
if (!m_inited) {
|
if (!m_inited) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto pos = position().toPoint();
|
|
||||||
auto internalWindow = findInternalWindow(pos);
|
|
||||||
|
|
||||||
Toplevel *toplevel;
|
Toplevel *toplevel = nullptr;
|
||||||
if (internalWindow) {
|
QWindow *internalWindow = nullptr;
|
||||||
toplevel = waylandServer()->findClient(internalWindow);
|
|
||||||
} else {
|
if (!positionValid()) {
|
||||||
toplevel = input()->findToplevel(pos);
|
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.
|
// Always set the toplevel at the position of the input device.
|
||||||
setAt(toplevel);
|
setAt(toplevel);
|
||||||
|
|
||||||
|
|
7
input.h
7
input.h
|
@ -424,6 +424,13 @@ protected:
|
||||||
|
|
||||||
virtual void focusUpdate(Toplevel *old, Toplevel *now) = 0;
|
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() {
|
virtual bool focusUpdatesBlocked() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,13 +78,20 @@ bool TouchInputRedirection::focusUpdatesBlocked()
|
||||||
if (waylandServer()->seat()->isDragTouch()) {
|
if (waylandServer()->seat()->isDragTouch()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (m_touches > 0) {
|
if (m_touches > 1) {
|
||||||
// first touch defines focus
|
// first touch defines focus
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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)
|
void TouchInputRedirection::focusUpdate(Toplevel *focusOld, Toplevel *focusNow)
|
||||||
{
|
{
|
||||||
// TODO: handle pointer grab aka popups
|
// TODO: handle pointer grab aka popups
|
||||||
|
@ -171,10 +178,10 @@ void TouchInputRedirection::processDown(qint32 id, const QPointF &pos, quint32 t
|
||||||
}
|
}
|
||||||
m_lastPosition = pos;
|
m_lastPosition = pos;
|
||||||
m_windowUpdatedInCycle = false;
|
m_windowUpdatedInCycle = false;
|
||||||
if (m_touches == 0) {
|
m_touches++;
|
||||||
|
if (m_touches == 1) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
m_touches++;
|
|
||||||
input()->processSpies(std::bind(&InputEventSpy::touchDown, std::placeholders::_1, id, pos, time));
|
input()->processSpies(std::bind(&InputEventSpy::touchDown, std::placeholders::_1, id, pos, time));
|
||||||
input()->processFilters(std::bind(&InputEventFilter::touchDown, std::placeholders::_1, id, pos, time));
|
input()->processFilters(std::bind(&InputEventFilter::touchDown, std::placeholders::_1, id, pos, time));
|
||||||
m_windowUpdatedInCycle = false;
|
m_windowUpdatedInCycle = false;
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
explicit TouchInputRedirection(InputRedirection *parent);
|
explicit TouchInputRedirection(InputRedirection *parent);
|
||||||
virtual ~TouchInputRedirection();
|
virtual ~TouchInputRedirection();
|
||||||
|
|
||||||
|
bool positionValid() const override;
|
||||||
bool focusUpdatesBlocked() override;
|
bool focusUpdatesBlocked() override;
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue