Changeset View
Changeset View
Standalone View
Standalone View
pointer_input.cpp
Show First 20 Lines • Show All 538 Lines • ▼ Show 20 Line(s) | 529 | [this] { | |||
---|---|---|---|---|---|
539 | if (m_window.data()->surface() != seat->focusedPointerSurface()) { | 539 | if (m_window.data()->surface() != seat->focusedPointerSurface()) { | ||
540 | return; | 540 | return; | ||
541 | } | 541 | } | ||
542 | seat->setFocusedPointerSurfaceTransformation(m_window.data()->inputTransformation()); | 542 | seat->setFocusedPointerSurfaceTransformation(m_window.data()->inputTransformation()); | ||
543 | } | 543 | } | ||
544 | ); | 544 | ); | ||
545 | m_constraintsConnection = connect(m_window->surface(), &KWayland::Server::SurfaceInterface::pointerConstraintsChanged, | 545 | m_constraintsConnection = connect(m_window->surface(), &KWayland::Server::SurfaceInterface::pointerConstraintsChanged, | ||
546 | this, &PointerInputRedirection::updatePointerConstraints); | 546 | this, &PointerInputRedirection::updatePointerConstraints); | ||
547 | m_constraintsActivatedConnection = connect(workspace(), &Workspace::clientActivated, | ||||
548 | this, &PointerInputRedirection::updatePointerConstraints); | ||||
547 | // check whether a pointer confinement/lock fires | 549 | // check whether a pointer confinement/lock fires | ||
548 | m_blockConstraint = false; | 550 | m_blockConstraint = false; | ||
549 | updatePointerConstraints(); | 551 | updatePointerConstraints(); | ||
550 | } else { | 552 | } else { | ||
551 | m_window.clear(); | 553 | m_window.clear(); | ||
552 | warpXcbOnSurfaceLeft(nullptr); | 554 | warpXcbOnSurfaceLeft(nullptr); | ||
553 | seat->setFocusedPointerSurface(nullptr); | 555 | seat->setFocusedPointerSurface(nullptr); | ||
554 | t = nullptr; | 556 | t = nullptr; | ||
Show All 28 Lines | 584 | { | |||
583 | disconnect(m_confinedPointerRegionConnection); | 585 | disconnect(m_confinedPointerRegionConnection); | ||
584 | m_confinedPointerRegionConnection = QMetaObject::Connection(); | 586 | m_confinedPointerRegionConnection = QMetaObject::Connection(); | ||
585 | } | 587 | } | ||
586 | 588 | | |||
587 | void PointerInputRedirection::disconnectPointerConstraintsConnection() | 589 | void PointerInputRedirection::disconnectPointerConstraintsConnection() | ||
588 | { | 590 | { | ||
589 | disconnect(m_constraintsConnection); | 591 | disconnect(m_constraintsConnection); | ||
590 | m_constraintsConnection = QMetaObject::Connection(); | 592 | m_constraintsConnection = QMetaObject::Connection(); | ||
593 | | ||||
594 | disconnect(m_constraintsActivatedConnection); | ||||
595 | m_constraintsActivatedConnection = QMetaObject::Connection(); | ||||
591 | } | 596 | } | ||
592 | 597 | | |||
593 | template <typename T> | 598 | template <typename T> | ||
594 | static QRegion getConstraintRegion(Toplevel *t, T *constraint) | 599 | static QRegion getConstraintRegion(Toplevel *t, T *constraint) | ||
595 | { | 600 | { | ||
596 | const QRegion windowShape = t->inputShape(); | 601 | const QRegion windowShape = t->inputShape(); | ||
597 | const QRegion windowRegion = windowShape.isEmpty() ? QRegion(0, 0, t->clientSize().width(), t->clientSize().height()) : windowShape; | 602 | const QRegion windowRegion = windowShape.isEmpty() ? QRegion(0, 0, t->clientSize().width(), t->clientSize().height()) : windowShape; | ||
598 | const QRegion intersected = constraint->region().isEmpty() ? windowRegion : windowRegion.intersected(constraint->region()); | 603 | const QRegion intersected = constraint->region().isEmpty() ? windowRegion : windowRegion.intersected(constraint->region()); | ||
Show All 13 Lines | 616 | if (s != waylandServer()->seat()->focusedPointerSurface()) { | |||
612 | return; | 617 | return; | ||
613 | } | 618 | } | ||
614 | if (!supportsWarping()) { | 619 | if (!supportsWarping()) { | ||
615 | return; | 620 | return; | ||
616 | } | 621 | } | ||
617 | if (m_blockConstraint) { | 622 | if (m_blockConstraint) { | ||
618 | return; | 623 | return; | ||
619 | } | 624 | } | ||
625 | const bool windowIsActive = m_window == workspace()->activeClient(); | ||||
620 | const auto cf = s->confinedPointer(); | 626 | const auto cf = s->confinedPointer(); | ||
621 | if (cf) { | 627 | if (cf) { | ||
622 | if (cf->isConfined()) { | 628 | if (cf->isConfined()) { | ||
629 | if (!windowIsActive) { | ||||
romangg: I compare here the pointer focus surface with the keyboard focus surface. It might make more… | |||||
graesslin: Client would be better as there might be weird multi surface situations. | |||||
630 | cf->setConfined(false); | ||||
631 | m_confined = false; | ||||
632 | disconnectConfinedPointerRegionConnection(); | ||||
633 | } | ||||
623 | return; | 634 | return; | ||
624 | } | 635 | } | ||
625 | const QRegion r = getConstraintRegion(m_window.data(), cf.data()); | 636 | const QRegion r = getConstraintRegion(m_window.data(), cf.data()); | ||
626 | if (r.contains(m_pos.toPoint())) { | 637 | if (windowIsActive && r.contains(m_pos.toPoint())) { | ||
627 | cf->setConfined(true); | 638 | cf->setConfined(true); | ||
628 | m_confined = true; | 639 | m_confined = true; | ||
629 | m_confinedPointerRegionConnection = connect(cf.data(), &KWayland::Server::ConfinedPointerInterface::regionChanged, this, | 640 | m_confinedPointerRegionConnection = connect(cf.data(), &KWayland::Server::ConfinedPointerInterface::regionChanged, this, | ||
630 | [this] { | 641 | [this] { | ||
631 | if (!m_window) { | 642 | if (!m_window) { | ||
632 | return; | 643 | return; | ||
633 | } | 644 | } | ||
634 | const auto s = m_window->surface(); | 645 | const auto s = m_window->surface(); | ||
Show All 20 Lines | |||||
655 | } | 666 | } | ||
656 | } else { | 667 | } else { | ||
657 | m_confined = false; | 668 | m_confined = false; | ||
658 | disconnectConfinedPointerRegionConnection(); | 669 | disconnectConfinedPointerRegionConnection(); | ||
659 | } | 670 | } | ||
660 | const auto lock = s->lockedPointer(); | 671 | const auto lock = s->lockedPointer(); | ||
661 | if (lock) { | 672 | if (lock) { | ||
662 | if (lock->isLocked()) { | 673 | if (lock->isLocked()) { | ||
674 | if (!windowIsActive) { | ||||
675 | lock->setLocked(false); | ||||
676 | m_locked = false; | ||||
677 | } | ||||
663 | return; | 678 | return; | ||
664 | } | 679 | } | ||
665 | const QRegion r = getConstraintRegion(m_window.data(), lock.data()); | 680 | const QRegion r = getConstraintRegion(m_window.data(), lock.data()); | ||
666 | if (r.contains(m_pos.toPoint())) { | 681 | if (windowIsActive && r.contains(m_pos.toPoint())) { | ||
667 | lock->setLocked(true); | 682 | lock->setLocked(true); | ||
668 | m_locked = true; | 683 | m_locked = true; | ||
669 | OSD::show(i18nc("notification about mouse pointer locked", | 684 | OSD::show(i18nc("notification about mouse pointer locked", | ||
670 | "Pointer locked to current position.\nTo end pointer lock hold Escape for 3 seconds."), | 685 | "Pointer locked to current position.\nTo end pointer lock hold Escape for 3 seconds."), | ||
671 | QStringLiteral("preferences-desktop-mouse"), 5000); | 686 | QStringLiteral("preferences-desktop-mouse"), 5000); | ||
672 | // TODO: connect to region change - is it needed at all? If the pointer is locked it's always in the region | 687 | // TODO: connect to region change - is it needed at all? If the pointer is locked it's always in the region | ||
673 | } | 688 | } | ||
674 | } else { | 689 | } else { | ||
▲ Show 20 Lines • Show All 649 Lines • Show Last 20 Lines |
I compare here the pointer focus surface with the keyboard focus surface. It might make more sense to compare the activated client with the client of the pointer focus surface, since I connected to the clientActivated signal.
I tried it out and the new autotest works as well. Any opinions on this?