Changeset View
Changeset View
Standalone View
Standalone View
pointer_input.cpp
Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Line(s) | 102 | for (int i = 0; i < screens()->count(); ++i) { | |||
---|---|---|---|---|---|
103 | if (screens()->geometry(i).contains(pos.toPoint())) { | 103 | if (screens()->geometry(i).contains(pos.toPoint())) { | ||
104 | return true; | 104 | return true; | ||
105 | } | 105 | } | ||
106 | } | 106 | } | ||
107 | return false; | 107 | return false; | ||
108 | } | 108 | } | ||
109 | 109 | | |||
110 | PointerInputRedirection::PointerInputRedirection(InputRedirection* parent) | 110 | PointerInputRedirection::PointerInputRedirection(InputRedirection* parent) | ||
111 | : QObject(parent) | 111 | : InputDeviceHandler(parent) | ||
112 | , m_input(parent) | | |||
113 | , m_cursor(nullptr) | 112 | , m_cursor(nullptr) | ||
114 | , m_supportsWarping(Application::usesLibinput()) | 113 | , m_supportsWarping(Application::usesLibinput()) | ||
115 | { | 114 | { | ||
116 | } | 115 | } | ||
117 | 116 | | |||
118 | PointerInputRedirection::~PointerInputRedirection() = default; | 117 | PointerInputRedirection::~PointerInputRedirection() = default; | ||
119 | 118 | | |||
120 | void PointerInputRedirection::init() | 119 | void PointerInputRedirection::init() | ||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Line(s) | 229 | if (waylandServer()->seat()->isDragPointer()) { | |||
231 | // ignore during drag and drop | 230 | // ignore during drag and drop | ||
232 | return; | 231 | return; | ||
233 | } | 232 | } | ||
234 | // TODO: handle pointer grab aka popups | 233 | // TODO: handle pointer grab aka popups | ||
235 | Toplevel *t = m_input->findToplevel(m_pos.toPoint()); | 234 | Toplevel *t = m_input->findToplevel(m_pos.toPoint()); | ||
236 | const auto oldDeco = m_decoration; | 235 | const auto oldDeco = m_decoration; | ||
237 | updateInternalWindow(); | 236 | updateInternalWindow(); | ||
238 | if (!m_internalWindow) { | 237 | if (!m_internalWindow) { | ||
239 | updateDecoration(t); | 238 | updateDecoration(t, m_pos); | ||
240 | } else { | 239 | } else { | ||
241 | // TODO: send hover leave to decoration | 240 | // TODO: send hover leave to decoration | ||
242 | if (m_decoration) { | 241 | if (m_decoration) { | ||
243 | m_decoration->client()->leaveEvent(); | 242 | m_decoration->client()->leaveEvent(); | ||
244 | } | 243 | } | ||
245 | m_decoration.clear(); | 244 | m_decoration.clear(); | ||
246 | } | 245 | } | ||
247 | if (m_decoration || m_internalWindow) { | 246 | if (m_decoration || m_internalWindow) { | ||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Line(s) | 349 | QEnterEvent event(m_pos - m_internalWindow->position(), | |||
351 | m_pos - m_internalWindow->position(), | 350 | m_pos - m_internalWindow->position(), | ||
352 | m_pos); | 351 | m_pos); | ||
353 | QCoreApplication::sendEvent(m_internalWindow.data(), &event); | 352 | QCoreApplication::sendEvent(m_internalWindow.data(), &event); | ||
354 | return; | 353 | return; | ||
355 | } | 354 | } | ||
356 | } | 355 | } | ||
357 | } | 356 | } | ||
358 | 357 | | |||
359 | void PointerInputRedirection::updateDecoration(Toplevel *t) | | |||
360 | { | | |||
361 | const auto oldDeco = m_decoration; | | |||
362 | bool needsReset = waylandServer()->isScreenLocked(); | | |||
363 | if (AbstractClient *c = dynamic_cast<AbstractClient*>(t)) { | | |||
364 | // check whether it's on a Decoration | | |||
365 | if (c->decoratedClient()) { | | |||
366 | const QRect clientRect = QRect(c->clientPos(), c->clientSize()).translated(c->pos()); | | |||
367 | if (!clientRect.contains(m_pos.toPoint())) { | | |||
368 | m_decoration = c->decoratedClient(); | | |||
369 | } else { | | |||
370 | needsReset = true; | | |||
371 | } | | |||
372 | } else { | | |||
373 | needsReset = true; | | |||
374 | } | | |||
375 | } else { | | |||
376 | needsReset = true; | | |||
377 | } | | |||
378 | if (needsReset) { | | |||
379 | m_decoration.clear(); | | |||
380 | } | | |||
381 | | ||||
382 | bool leftSend = false; | | |||
383 | auto oldWindow = qobject_cast<AbstractClient*>(m_window.data()); | | |||
384 | if (oldWindow && (m_decoration && m_decoration->client() != oldWindow)) { | | |||
385 | leftSend = true; | | |||
386 | oldWindow->leaveEvent(); | | |||
387 | } | | |||
388 | | ||||
389 | if (oldDeco && oldDeco != m_decoration) { | | |||
390 | if (oldDeco->client() != t && !leftSend) { | | |||
391 | leftSend = true; | | |||
392 | oldDeco->client()->leaveEvent(); | | |||
393 | } | | |||
394 | // send leave | | |||
395 | QHoverEvent event(QEvent::HoverLeave, QPointF(), QPointF()); | | |||
396 | QCoreApplication::instance()->sendEvent(oldDeco->decoration(), &event); | | |||
397 | } | | |||
398 | if (m_decoration) { | | |||
399 | if (m_decoration->client() != oldWindow) { | | |||
400 | m_decoration->client()->enterEvent(m_pos.toPoint()); | | |||
401 | workspace()->updateFocusMousePosition(m_pos.toPoint()); | | |||
402 | } | | |||
403 | const QPointF p = m_pos - t->pos(); | | |||
404 | QHoverEvent event(QEvent::HoverMove, p, p); | | |||
405 | QCoreApplication::instance()->sendEvent(m_decoration->decoration(), &event); | | |||
406 | m_decoration->client()->processDecorationMove(p.toPoint(), m_pos.toPoint()); | | |||
407 | } | | |||
408 | } | | |||
409 | | ||||
410 | void PointerInputRedirection::updatePosition(const QPointF &pos) | 358 | void PointerInputRedirection::updatePosition(const QPointF &pos) | ||
411 | { | 359 | { | ||
412 | // verify that at least one screen contains the pointer position | 360 | // verify that at least one screen contains the pointer position | ||
413 | QPointF p = pos; | 361 | QPointF p = pos; | ||
414 | if (!screenContainsPos(p)) { | 362 | if (!screenContainsPos(p)) { | ||
415 | // allow either x or y to pass | 363 | // allow either x or y to pass | ||
416 | p = QPointF(m_pos.x(), pos.y()); | 364 | p = QPointF(m_pos.x(), pos.y()); | ||
417 | if (!screenContainsPos(p)) { | 365 | if (!screenContainsPos(p)) { | ||
▲ Show 20 Lines • Show All 494 Lines • Show Last 20 Lines |