From ff45105b427edf507cc1a1b45bdabf9b98c389d4 Mon Sep 17 00:00:00 2001 From: Jeroen Dhollander Date: Fri, 10 Jun 2022 13:23:04 +0000 Subject: [PATCH] Fix clearing of mouse cursor if display uses a scale factor When a display uses a scale factor (different than 1.0) the previous cursor position is not properly cleared during a CRD connection on ChromeOS (see b/235191365). The issue was that the fix for crbug.com/1323241 does not take device scaling into account, so that fix would incorrectly not mark the previous location of the mouse cursor as modified. Adding proper boundary checks is hard and risky though, as the way the position of the mouse cursor is reported seems to be platform dependent (ChromeOS vs Linux vs ...). So because crbug.com/1323241 only solves a theoretical crash that is rarely if ever hit in the field, I decided to for now undo the fix for crbug.com/1323241. A proper boundary check can then later be introduced without any pressure from a looming release Bug: chromium:1323241 Bug: b/235191365 Fixed: b/235191365 Test: Manually deployed Change-Id: Ib09b6cc5e396bd52538332edfc4395ed80c6786e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265391 Reviewed-by: Alexander Cooper Reviewed-by: Joe Downing Commit-Queue: Jeroen Dhollander Cr-Commit-Position: refs/heads/main@{#37274} --- .../desktop_and_cursor_composer.cc | 11 +++--- .../desktop_and_cursor_composer_unittest.cc | 35 ------------------- 2 files changed, 6 insertions(+), 40 deletions(-) diff --git a/modules/desktop_capture/desktop_and_cursor_composer.cc b/modules/desktop_capture/desktop_and_cursor_composer.cc index 7ff983c2d1..dd688ac5f2 100644 --- a/modules/desktop_capture/desktop_and_cursor_composer.cc +++ b/modules/desktop_capture/desktop_and_cursor_composer.cc @@ -105,11 +105,12 @@ DesktopFrameWithCursor::DesktopFrameWithCursor( if (!previous_cursor_rect.equals(cursor_rect_)) { mutable_updated_region()->AddRect(cursor_rect_); - - // Only add the previous cursor if it is inside the frame. - // (it can be outside the frame if the desktop has been resized). - if (original_frame_->rect().ContainsRect(previous_cursor_rect)) - mutable_updated_region()->AddRect(previous_cursor_rect); + // TODO(crbug:1323241) Update this code to properly handle the case where + // |previous_cursor_rect| is outside of the boundaries of |frame|. + // Any boundary check has to take into account the fact that + // |previous_cursor_rect| can be in DPI or in pixels, based on the platform + // we're running on. + mutable_updated_region()->AddRect(previous_cursor_rect); } else if (cursor_changed) { mutable_updated_region()->AddRect(cursor_rect_); } diff --git a/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc b/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc index 4d879a740e..179e002bc5 100644 --- a/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc +++ b/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc @@ -105,15 +105,6 @@ MouseCursor* CreateTestCursor(DesktopVector hotspot) { return new MouseCursor(image.release(), hotspot); } -std::vector GetUpdatedRegions(const DesktopFrame& frame) { - std::vector result; - for (webrtc::DesktopRegion::Iterator i(frame.updated_region()); !i.IsAtEnd(); - i.Advance()) { - result.push_back(i.rect()); - } - return result; -} - class FakeScreenCapturer : public DesktopCapturer { public: FakeScreenCapturer() {} @@ -436,32 +427,6 @@ TEST_F(DesktopAndCursorComposerNoCursorMonitorTest, EXPECT_TRUE(frame_->updated_region().Equals(expected_region)); } -TEST_F(DesktopAndCursorComposerNoCursorMonitorTest, - UpdatedRegionDoesNotIncludeOldCursorIfOutOfBounds) { - blender_.OnMouseCursor(CreateTestCursor(DesktopVector(0, 0))); - - std::unique_ptr first_frame( - SharedDesktopFrame::Wrap(CreateTestFrame(1000, 1000))); - blender_.OnMouseCursorPosition(DesktopVector(900, 900)); - fake_screen_->SetNextFrame(first_frame->Share()); - - blender_.CaptureFrame(); - - // Second frame is smaller than first frame, and the first cursor is outside - // of the bounds of the new frame, so it should not be in the updated region. - std::unique_ptr second_frame( - SharedDesktopFrame::Wrap(CreateTestFrame(500, 500))); - auto second_cursor_rect = - DesktopRect::MakeXYWH(400, 400, kCursorWidth, kCursorHeight); - blender_.OnMouseCursorPosition(DesktopVector(400, 400)); - fake_screen_->SetNextFrame(second_frame->Share()); - blender_.CaptureFrame(); - - DesktopRegion expected_region; - expected_region.AddRect(second_cursor_rect); - EXPECT_THAT(GetUpdatedRegions(*frame_), ElementsAre(second_cursor_rect)); -} - TEST_F(DesktopAndCursorComposerNoCursorMonitorTest, UpdatedRegionIncludesOldAndNewCursorRectsIfShapeChanged) { std::unique_ptr frame(