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
11
input.cpp
11
input.cpp
|
@ -2265,16 +2265,19 @@ void InputDeviceHandler::update()
|
|||
if (!m_inited) {
|
||||
return;
|
||||
}
|
||||
const auto pos = position().toPoint();
|
||||
auto internalWindow = findInternalWindow(pos);
|
||||
|
||||
Toplevel *toplevel;
|
||||
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);
|
||||
|
||||
|
|
7
input.h
7
input.h
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
explicit TouchInputRedirection(InputRedirection *parent);
|
||||
virtual ~TouchInputRedirection();
|
||||
|
||||
bool positionValid() const override;
|
||||
bool focusUpdatesBlocked() override;
|
||||
void init();
|
||||
|
||||
|
|
Loading…
Reference in a new issue