| Index: webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc
|
| diff --git a/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc b/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc
|
| index 204bb00b1602f9d32344e7f0da6145244e1979ca..479a39a021726b351b2ead41924756baab39abe5 100644
|
| --- a/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc
|
| +++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc
|
| @@ -11,10 +11,12 @@
|
| #include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
|
|
|
| #include <assert.h>
|
| +#include <string.h>
|
|
|
| #include <memory>
|
|
|
| #include "webrtc/modules/desktop_capture/desktop_frame.h"
|
| +#include "webrtc/modules/desktop_capture/desktop_geometry.h"
|
| #include "webrtc/modules/desktop_capture/mouse_cursor.h"
|
| #include "webrtc/modules/desktop_capture/win/cursor.h"
|
| #include "webrtc/modules/desktop_capture/win/window_capture_utils.h"
|
| @@ -22,6 +24,17 @@
|
|
|
| namespace webrtc {
|
|
|
| +namespace {
|
| +
|
| +bool IsSameCursorShape(const CURSORINFO& left, const CURSORINFO& right) {
|
| + // If the cursors are not showing, we do not care the hCursor handle.
|
| + return left.flags == right.flags &&
|
| + (left.flags != CURSOR_SHOWING ||
|
| + left.hCursor == right.hCursor);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| class MouseCursorMonitorWin : public MouseCursorMonitor {
|
| public:
|
| explicit MouseCursorMonitorWin(HWND window);
|
| @@ -45,7 +58,8 @@ class MouseCursorMonitorWin : public MouseCursorMonitor {
|
|
|
| HDC desktop_dc_;
|
|
|
| - HCURSOR last_cursor_;
|
| + // The last CURSORINFO (converted to MouseCursor) we have sent to the client.
|
| + CURSORINFO last_cursor_;
|
| };
|
|
|
| MouseCursorMonitorWin::MouseCursorMonitorWin(HWND window)
|
| @@ -53,8 +67,8 @@ MouseCursorMonitorWin::MouseCursorMonitorWin(HWND window)
|
| screen_(kInvalidScreenId),
|
| callback_(NULL),
|
| mode_(SHAPE_AND_POSITION),
|
| - desktop_dc_(NULL),
|
| - last_cursor_(NULL) {
|
| + desktop_dc_(NULL) {
|
| + memset(&last_cursor_, 0, sizeof(CURSORINFO));
|
| }
|
|
|
| MouseCursorMonitorWin::MouseCursorMonitorWin(ScreenId screen)
|
| @@ -62,9 +76,9 @@ MouseCursorMonitorWin::MouseCursorMonitorWin(ScreenId screen)
|
| screen_(screen),
|
| callback_(NULL),
|
| mode_(SHAPE_AND_POSITION),
|
| - desktop_dc_(NULL),
|
| - last_cursor_(NULL) {
|
| + desktop_dc_(NULL) {
|
| assert(screen >= kFullDesktopScreenId);
|
| + memset(&last_cursor_, 0, sizeof(CURSORINFO));
|
| }
|
|
|
| MouseCursorMonitorWin::~MouseCursorMonitorWin() {
|
| @@ -92,13 +106,31 @@ void MouseCursorMonitorWin::Capture() {
|
| return;
|
| }
|
|
|
| - if (last_cursor_ != cursor_info.hCursor) {
|
| - last_cursor_ = cursor_info.hCursor;
|
| - // Note that |cursor_info.hCursor| does not need to be freed.
|
| - std::unique_ptr<MouseCursor> cursor(
|
| - CreateMouseCursorFromHCursor(desktop_dc_, cursor_info.hCursor));
|
| - if (cursor.get())
|
| - callback_->OnMouseCursor(cursor.release());
|
| + if (!IsSameCursorShape(cursor_info, last_cursor_)) {
|
| + if (cursor_info.flags == CURSOR_SUPPRESSED) {
|
| + // The cursor is intentionally hidden now, send an empty bitmap.
|
| + last_cursor_ = cursor_info;
|
| + callback_->OnMouseCursor(new MouseCursor(
|
| + new BasicDesktopFrame(DesktopSize()), DesktopVector()));
|
| + } else {
|
| + // According to MSDN https://goo.gl/u6gyuC, HCURSOR instances returned by
|
| + // functions other than CreateCursor do not need to be actively destroyed.
|
| + // And CloseHandle function (https://goo.gl/ja5ycW) does not close a
|
| + // cursor, so assume a HCURSOR does not need to be closed.
|
| + if (cursor_info.flags == 0) {
|
| + // Host machine does not have a hardware mouse attached, we will send a
|
| + // default one instead.
|
| + // Note, Windows automatically caches cursor resource, so we do not need
|
| + // to cache the result of LoadCursor.
|
| + cursor_info.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
| + }
|
| + std::unique_ptr<MouseCursor> cursor(
|
| + CreateMouseCursorFromHCursor(desktop_dc_, cursor_info.hCursor));
|
| + if (cursor) {
|
| + last_cursor_ = cursor_info;
|
| + callback_->OnMouseCursor(cursor.release());
|
| + }
|
| + }
|
| }
|
|
|
| if (mode_ != SHAPE_AND_POSITION)
|
|
|