CURSORINFO.flags should be checked before capturing its bitmap
BUG=566178, 428886 Review-Url: https://codereview.webrtc.org/1959863002 Cr-Commit-Position: refs/heads/master@{#12739}
This commit is contained in:
parent
3f90087ce8
commit
99f8cd0ae2
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user