Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(805)

Unified Diff: webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm

Issue 2350743003: Bug Fix: Mac Retina Screen Capture's Mouse Cursor Too Small (Closed)
Patch Set: No round Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/desktop_capture/desktop_frame.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm
diff --git a/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm b/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm
index 5d6a9b0089c6ddbff18ce7db4b6083b65eab70ba..6e079b6662f262c9a1eb90e6f0a74f78c5de7cd3 100644
--- a/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm
+++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm
@@ -30,6 +30,25 @@
namespace webrtc {
+namespace {
+// Paint the image, so that we can get a bitmap representation compatible with
+// current context. For example, in the retina display, we are going to get an
+// image with same visual size but underlying pixel size conforms to the retina
+// setting.
+NSImage* PaintInCurrentContext(NSImage* source) {
+ NSSize size = [source size];
+ NSImage* new_image = [[[NSImage alloc] initWithSize:size] autorelease];
+ [new_image lockFocus];
+ NSRect frame = NSMakeRect(0, 0, size.width, size.height);
+ [source drawInRect:frame
+ fromRect:frame
+ operation:NSCompositeCopy
+ fraction:1.0];
+ [new_image unlockFocus];
+ return new_image;
+}
+} // namespace
+
class MouseCursorMonitorMac : public MouseCursorMonitor {
public:
MouseCursorMonitorMac(const DesktopCaptureOptions& options,
@@ -47,7 +66,7 @@ class MouseCursorMonitorMac : public MouseCursorMonitor {
void DisplaysReconfigured(CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags);
- void CaptureImage();
+ void CaptureImage(float scale);
rtc::scoped_refptr<DesktopConfigurationMonitor> configuration_monitor_;
CGWindowID window_id_;
@@ -91,11 +110,6 @@ void MouseCursorMonitorMac::Init(Callback* callback, Mode mode) {
void MouseCursorMonitorMac::Capture() {
assert(callback_);
- CaptureImage();
-
- if (mode_ != SHAPE_AND_POSITION)
- return;
-
CursorState state = INSIDE;
CGEventRef event = CGEventCreate(NULL);
@@ -113,12 +127,18 @@ void MouseCursorMonitorMac::Capture() {
// Find the dpi to physical pixel scale for the screen where the mouse cursor
// is.
for (MacDisplayConfigurations::iterator it = configuration.displays.begin();
- it != configuration.displays.end(); ++it) {
+ it != configuration.displays.end(); ++it) {
if (it->bounds.Contains(position)) {
scale = it->dip_to_pixel_scale;
break;
}
}
+
+ CaptureImage(scale);
+
+ if (mode_ != SHAPE_AND_POSITION)
+ return;
+
// If we are capturing cursor for a specific window then we need to figure out
// if the current mouse position is covered by another window and also adjust
// |position| to make it relative to the window origin.
@@ -228,24 +248,32 @@ void MouseCursorMonitorMac::Capture() {
callback_->OnMouseCursorPosition(state, position);
}
-void MouseCursorMonitorMac::CaptureImage() {
+void MouseCursorMonitorMac::CaptureImage(float scale) {
NSCursor* nscursor = [NSCursor currentSystemCursor];
NSImage* nsimage = [nscursor image];
- NSSize nssize = [nsimage size];
- DesktopSize size(nssize.width, nssize.height);
+ NSSize nssize = [nsimage size]; // DIP size
+
+ // For retina screen, we need to paint the cursor in current graphic context
+ // to get retina representation.
+ if (scale != 1.0)
+ nsimage = PaintInCurrentContext(nsimage);
+
+ DesktopSize size(round(nssize.width * scale),
+ round(nssize.height * scale)); // Pixel size
NSPoint nshotspot = [nscursor hotSpot];
DesktopVector hotspot(
- std::max(0, std::min(size.width(), static_cast<int>(nshotspot.x))),
- std::max(0, std::min(size.height(), static_cast<int>(nshotspot.y))));
+ std::max(0,
+ std::min(size.width(), static_cast<int>(nshotspot.x * scale))),
+ std::max(0,
+ std::min(size.height(), static_cast<int>(nshotspot.y * scale))));
CGImageRef cg_image =
[nsimage CGImageForProposedRect:NULL context:nil hints:nil];
if (!cg_image)
return;
if (CGImageGetBitsPerPixel(cg_image) != DesktopFrame::kBytesPerPixel * 8 ||
- CGImageGetBytesPerRow(cg_image) !=
- static_cast<size_t>(DesktopFrame::kBytesPerPixel * size.width()) ||
+ CGImageGetWidth(cg_image) != static_cast<size_t>(size.width()) ||
CGImageGetBitsPerComponent(cg_image) != 8) {
return;
}
@@ -272,8 +300,9 @@ void MouseCursorMonitorMac::CaptureImage() {
// the client.
std::unique_ptr<DesktopFrame> image(
new BasicDesktopFrame(DesktopSize(size.width(), size.height())));
- memcpy(image->data(), src_data,
- size.width() * size.height() * DesktopFrame::kBytesPerPixel);
+
+ int src_stride = CGImageGetBytesPerRow(cg_image);
+ image->CopyPixelsFrom(src_data, src_stride, DesktopRect::MakeSize(size));
CFRelease(image_data_ref);
« no previous file with comments | « webrtc/modules/desktop_capture/desktop_frame.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698