@@ -98,6 +98,22 @@ std::unordered_set<ui::LogicalDisplayId> getPrivacySensitiveDisplaysFromWindowIn
9898 return privacySensitiveDisplays;
9999}
100100
101+ vec2 calculatePositionOnDestinationViewport (const DisplayViewport& destinationViewport,
102+ float pointerOffset,
103+ DisplayTopologyPosition sourceBoundary) {
104+ // destination is opposite of the source boundary
105+ switch (sourceBoundary) {
106+ case DisplayTopologyPosition::RIGHT:
107+ return {0 , pointerOffset}; // left edge
108+ case DisplayTopologyPosition::TOP:
109+ return {pointerOffset, destinationViewport.logicalBottom }; // bottom edge
110+ case DisplayTopologyPosition::LEFT:
111+ return {destinationViewport.logicalRight , pointerOffset}; // right edge
112+ case DisplayTopologyPosition::BOTTOM:
113+ return {pointerOffset, 0 }; // top edge
114+ }
115+ }
116+
101117} // namespace
102118
103119// --- PointerChoreographer ---
@@ -327,19 +343,19 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
327343 // except sometimes near the corners.
328344 // In these cases this behaviour is not noticeable. We also do not apply unconsumed delta on
329345 // the destination display for the same reason.
330- DisplayPosition sourceBoundary;
346+ DisplayTopologyPosition sourceBoundary;
331347 float cursorOffset = 0 .0f ;
332348 if (rotatedUnconsumedDelta.x > 0 ) {
333- sourceBoundary = DisplayPosition ::RIGHT;
349+ sourceBoundary = DisplayTopologyPosition ::RIGHT;
334350 cursorOffset = rotatedCursorPosition.y ;
335351 } else if (rotatedUnconsumedDelta.x < 0 ) {
336- sourceBoundary = DisplayPosition ::LEFT;
352+ sourceBoundary = DisplayTopologyPosition ::LEFT;
337353 cursorOffset = rotatedCursorPosition.y ;
338354 } else if (rotatedUnconsumedDelta.y > 0 ) {
339- sourceBoundary = DisplayPosition ::BOTTOM;
355+ sourceBoundary = DisplayTopologyPosition ::BOTTOM;
340356 cursorOffset = rotatedCursorPosition.x ;
341357 } else {
342- sourceBoundary = DisplayPosition ::TOP;
358+ sourceBoundary = DisplayTopologyPosition ::TOP;
343359 cursorOffset = rotatedCursorPosition.x ;
344360 }
345361
@@ -369,8 +385,9 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
369385 pc.fade (PointerControllerInterface::Transition::IMMEDIATE);
370386 pc.setDisplayViewport (destinationViewport);
371387 vec2 destinationPosition =
372- calculateDestinationPosition (destinationViewport, cursorOffset - destinationOffset,
373- sourceBoundary);
388+ calculatePositionOnDestinationViewport (destinationViewport,
389+ cursorOffset - destinationOffset,
390+ sourceBoundary);
374391
375392 // Transform position back to un-rotated coordinate space before sending it to controller
376393 destinationPosition = pc.getDisplayTransform ().inverse ().transform (destinationPosition.x ,
@@ -379,22 +396,6 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
379396 pc.unfade (PointerControllerInterface::Transition::IMMEDIATE);
380397}
381398
382- vec2 PointerChoreographer::calculateDestinationPosition (const DisplayViewport& destinationViewport,
383- float pointerOffset,
384- DisplayPosition sourceBoundary) {
385- // destination is opposite of the source boundary
386- switch (sourceBoundary) {
387- case DisplayPosition::RIGHT:
388- return {0 , pointerOffset}; // left edge
389- case DisplayPosition::TOP:
390- return {pointerOffset, destinationViewport.logicalBottom }; // bottom edge
391- case DisplayPosition::LEFT:
392- return {destinationViewport.logicalRight , pointerOffset}; // right edge
393- case DisplayPosition::BOTTOM:
394- return {pointerOffset, 0 }; // top edge
395- }
396- }
397-
398399void PointerChoreographer::processDrawingTabletEventLocked (const android::NotifyMotionArgs& args) {
399400 if (args.displayId == ui::LogicalDisplayId::INVALID) {
400401 return ;
@@ -540,8 +541,7 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args)
540541}
541542
542543void PointerChoreographer::onControllerAddedOrRemovedLocked () {
543- if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows () &&
544- !com::android::input::flags::connected_displays_cursor ()) {
544+ if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows ()) {
545545 return ;
546546 }
547547 bool requireListener = !mTouchPointersByDevice .empty () || !mMousePointersByDisplay .empty () ||
@@ -607,11 +607,16 @@ void PointerChoreographer::notifyPointerCaptureChanged(
607607 mNextListener .notify (args);
608608}
609609
610- void PointerChoreographer::setDisplayTopology (
611- const std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>>&
612- displayTopology) {
610+ void PointerChoreographer::setDisplayTopology (const DisplayTopologyGraph& displayTopologyGraph) {
613611 std::scoped_lock _l (getLock ());
614- mTopology = displayTopology;
612+ mTopology = displayTopologyGraph;
613+
614+ // make primary display default mouse display, if it was not set
615+ // or the existing display was removed
616+ if (mDefaultMouseDisplayId == ui::LogicalDisplayId::INVALID ||
617+ mTopology .graph .find (mDefaultMouseDisplayId ) != mTopology .graph .end ()) {
618+ mDefaultMouseDisplayId = mTopology .primaryDisplayId ;
619+ }
615620}
616621
617622void PointerChoreographer::dump (std::string& dump) {
@@ -985,73 +990,17 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusContr
985990 return ConstructorDelegate (std::move (ctor));
986991}
987992
988- void PointerChoreographer::populateFakeDisplayTopologyLocked (
989- const std::vector<gui::DisplayInfo>& displayInfos) {
990- if (!com::android::input::flags::connected_displays_cursor ()) {
991- return ;
992- }
993-
994- if (displayInfos.size () == mTopology .size ()) {
995- bool displaysChanged = false ;
996- for (const auto & displayInfo : displayInfos) {
997- if (mTopology .find (displayInfo.displayId ) == mTopology .end ()) {
998- displaysChanged = true ;
999- break ;
1000- }
1001- }
1002-
1003- if (!displaysChanged) {
1004- return ;
1005- }
1006- }
1007-
1008- // create a fake topology assuming following order
1009- // default-display (top-edge) -> next-display (right-edge) -> next-display (right-edge) ...
1010- // This also adds a 100px offset on corresponding edge for better manual testing
1011- // ┌────────┐
1012- // │ next ├─────────┐
1013- // ┌─└───────┐┤ next 2 │ ...
1014- // │ default │└─────────┘
1015- // └─────────┘
1016- mTopology .clear ();
1017-
1018- // treat default display as base, in real topology it should be the primary-display
1019- ui::LogicalDisplayId previousDisplay = ui::LogicalDisplayId::DEFAULT;
1020- for (const auto & displayInfo : displayInfos) {
1021- if (displayInfo.displayId == ui::LogicalDisplayId::DEFAULT) {
1022- continue ;
1023- }
1024- if (previousDisplay == ui::LogicalDisplayId::DEFAULT) {
1025- mTopology [previousDisplay].push_back (
1026- {displayInfo.displayId , DisplayPosition::TOP, 100 });
1027- mTopology [displayInfo.displayId ].push_back (
1028- {previousDisplay, DisplayPosition::BOTTOM, -100 });
1029- } else {
1030- mTopology [previousDisplay].push_back (
1031- {displayInfo.displayId , DisplayPosition::RIGHT, 100 });
1032- mTopology [displayInfo.displayId ].push_back (
1033- {previousDisplay, DisplayPosition::LEFT, -100 });
1034- }
1035- previousDisplay = displayInfo.displayId ;
1036- }
1037-
1038- // update default pointer display. In real topology it should be the primary-display
1039- if (mTopology .find (mDefaultMouseDisplayId ) == mTopology .end ()) {
1040- mDefaultMouseDisplayId = ui::LogicalDisplayId::DEFAULT;
1041- }
1042- }
1043-
1044993std::optional<std::pair<const DisplayViewport*, float /* offset*/ >>
1045994PointerChoreographer::findDestinationDisplayLocked (const ui::LogicalDisplayId sourceDisplayId,
1046- const DisplayPosition sourceBoundary,
995+ const DisplayTopologyPosition sourceBoundary,
1047996 float cursorOffset) const {
1048- const auto & sourceNode = mTopology .find (sourceDisplayId);
1049- if (sourceNode == mTopology .end ()) {
997+ const auto & sourceNode = mTopology .graph . find (sourceDisplayId);
998+ if (sourceNode == mTopology .graph . end ()) {
1050999 // Topology is likely out of sync with viewport info, wait for it to be updated
10511000 LOG (WARNING) << " Source display missing from topology " << sourceDisplayId;
10521001 return std::nullopt ;
10531002 }
1054- for (const AdjacentDisplay & adjacentDisplay : sourceNode->second ) {
1003+ for (const DisplayTopologyAdjacentDisplay & adjacentDisplay : sourceNode->second ) {
10551004 if (adjacentDisplay.position != sourceBoundary) {
10561005 continue ;
10571006 }
@@ -1064,8 +1013,8 @@ PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId so
10641013 continue ;
10651014 }
10661015 // target position must be within target display boundary
1067- const int32_t edgeSize =
1068- sourceBoundary == DisplayPosition::TOP || sourceBoundary == DisplayPosition ::BOTTOM
1016+ const int32_t edgeSize = sourceBoundary == DisplayTopologyPosition::TOP ||
1017+ sourceBoundary == DisplayTopologyPosition ::BOTTOM
10691018 ? (destinationViewport->logicalRight - destinationViewport->logicalLeft )
10701019 : (destinationViewport->logicalBottom - destinationViewport->logicalTop );
10711020 if (cursorOffset >= adjacentDisplay.offsetPx &&
@@ -1093,7 +1042,6 @@ void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfo
10931042 mPrivacySensitiveDisplays = std::move (newPrivacySensitiveDisplays);
10941043 mPointerChoreographer ->onPrivacySensitiveDisplaysChangedLocked (mPrivacySensitiveDisplays );
10951044 }
1096- mPointerChoreographer ->populateFakeDisplayTopologyLocked (windowInfosUpdate.displayInfos );
10971045}
10981046
10991047void PointerChoreographer::PointerChoreographerDisplayInfoListener::setInitialDisplayInfosLocked (
0 commit comments