Changeset View
Changeset View
Standalone View
Standalone View
pointer_input.cpp
Show First 20 Lines • Show All 214 Lines • ▼ Show 20 Line(s) | 192 | { | |||
---|---|---|---|---|---|
215 | waylandServer()->seat()->setFocusedPointerSurface(nullptr); | 215 | waylandServer()->seat()->setFocusedPointerSurface(nullptr); | ||
216 | } | 216 | } | ||
217 | 217 | | |||
218 | void PointerInputRedirection::processMotion(const QPointF &pos, uint32_t time, LibInput::Device *device) | 218 | void PointerInputRedirection::processMotion(const QPointF &pos, uint32_t time, LibInput::Device *device) | ||
219 | { | 219 | { | ||
220 | processMotion(pos, QSizeF(), QSizeF(), time, 0, device); | 220 | processMotion(pos, QSizeF(), QSizeF(), time, 0, device); | ||
221 | } | 221 | } | ||
222 | 222 | | |||
223 | class PositionUpdateBlocker | ||||
224 | { | ||||
225 | public: | ||||
226 | PositionUpdateBlocker(PointerInputRedirection *pointer) | ||||
227 | : m_pointer(pointer) | ||||
228 | { | ||||
229 | s_counter++; | ||||
230 | } | ||||
231 | ~PositionUpdateBlocker() { | ||||
232 | s_counter--; | ||||
233 | if (s_counter == 0) { | ||||
234 | if (!s_scheduledPositions.isEmpty()) { | ||||
235 | const auto pos = s_scheduledPositions.takeFirst(); | ||||
236 | m_pointer->processMotion(pos.pos, pos.delta, pos.deltaNonAccelerated, pos.time, pos.timeUsec, nullptr); | ||||
anthonyfieroni: This can lead to strange side effect
1. isPositionBlocked == true
2. s_scheduledPositions.size… | |||||
No it is fine. You need to look at the big picture. This will invoke the first queued element for processMotion. Which in turn creates a new blocker and when going out of processMotion the next item will be processed. It is a recursive dequeueing of all elements. If another motion gets scheduled it just gets put to the end of the queue. graesslin: No it is fine. You need to look at the big picture. This will invoke the first queued element… | |||||
anthonyfieroni: Ah, great :) | |||||
237 | } | ||||
238 | } | ||||
239 | } | ||||
240 | | ||||
241 | static bool isPositionBlocked() { | ||||
242 | return s_counter > 0; | ||||
243 | } | ||||
244 | | ||||
245 | static void schedulePosition(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec) { | ||||
246 | s_scheduledPositions.append({pos, delta, deltaNonAccelerated, time, timeUsec}); | ||||
247 | } | ||||
248 | | ||||
249 | private: | ||||
250 | static int s_counter; | ||||
251 | struct ScheduledPosition { | ||||
252 | QPointF pos; | ||||
253 | QSizeF delta; | ||||
254 | QSizeF deltaNonAccelerated; | ||||
255 | quint32 time; | ||||
256 | quint64 timeUsec; | ||||
257 | }; | ||||
258 | static QVector<ScheduledPosition> s_scheduledPositions; | ||||
259 | | ||||
260 | PointerInputRedirection *m_pointer; | ||||
261 | }; | ||||
262 | | ||||
263 | int PositionUpdateBlocker::s_counter = 0; | ||||
264 | QVector<PositionUpdateBlocker::ScheduledPosition> PositionUpdateBlocker::s_scheduledPositions; | ||||
265 | | ||||
223 | void PointerInputRedirection::processMotion(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, LibInput::Device *device) | 266 | void PointerInputRedirection::processMotion(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, LibInput::Device *device) | ||
224 | { | 267 | { | ||
225 | if (!m_inited) { | 268 | if (!m_inited) { | ||
226 | return; | 269 | return; | ||
227 | } | 270 | } | ||
271 | if (PositionUpdateBlocker::isPositionBlocked()) { | ||||
272 | PositionUpdateBlocker::schedulePosition(pos, delta, deltaNonAccelerated, time, timeUsec); | ||||
273 | return; | ||||
274 | } | ||||
275 | | ||||
276 | PositionUpdateBlocker blocker(this); | ||||
228 | updatePosition(pos); | 277 | updatePosition(pos); | ||
229 | MouseEvent event(QEvent::MouseMove, m_pos, Qt::NoButton, m_qtButtons, | 278 | MouseEvent event(QEvent::MouseMove, m_pos, Qt::NoButton, m_qtButtons, | ||
230 | m_input->keyboardModifiers(), time, | 279 | m_input->keyboardModifiers(), time, | ||
231 | delta, deltaNonAccelerated, timeUsec, device); | 280 | delta, deltaNonAccelerated, timeUsec, device); | ||
232 | event.setModifiersRelevantForGlobalShortcuts(m_input->modifiersRelevantForGlobalShortcuts()); | 281 | event.setModifiersRelevantForGlobalShortcuts(m_input->modifiersRelevantForGlobalShortcuts()); | ||
233 | 282 | | |||
234 | m_input->processSpies(std::bind(&InputEventSpy::pointerEvent, std::placeholders::_1, &event)); | 283 | m_input->processSpies(std::bind(&InputEventSpy::pointerEvent, std::placeholders::_1, &event)); | ||
235 | m_input->processFilters(std::bind(&InputEventFilter::pointerEvent, std::placeholders::_1, &event, 0)); | 284 | m_input->processFilters(std::bind(&InputEventFilter::pointerEvent, std::placeholders::_1, &event, 0)); | ||
▲ Show 20 Lines • Show All 987 Lines • Show Last 20 Lines |
This can lead to strange side effect
In next block/unblock will be triggered pertty old motion event, no? Maybe it's better to steal all blocked events except last one.