| Index: remoting/host/event_executor_mac.cc
|
| diff --git a/remoting/host/event_executor_mac.cc b/remoting/host/event_executor_mac.cc
|
| index 971ca510ea6bd563c6e57164516c55785cba433c..47320f91369acff786c12ca1fd4b1ea43fe24f8c 100644
|
| --- a/remoting/host/event_executor_mac.cc
|
| +++ b/remoting/host/event_executor_mac.cc
|
| @@ -17,6 +17,7 @@
|
| #include "remoting/proto/internal.pb.h"
|
| #include "remoting/protocol/message_decoder.h"
|
| #include "third_party/skia/include/core/SkPoint.h"
|
| +#include "third_party/skia/include/core/SkRect.h"
|
|
|
| namespace remoting {
|
|
|
| @@ -31,6 +32,17 @@ using protocol::MouseEvent;
|
| #include "ui/base/keycodes/usb_keycode_map.h"
|
| #undef USB_KEYMAP
|
|
|
| +// skia/ext/skia_utils_mac.h only defines CGRectToSkRect().
|
| +SkIRect CGRectToSkIRect(const CGRect& rect) {
|
| + SkIRect sk_rect = {
|
| + SkScalarRound(rect.origin.x),
|
| + SkScalarRound(rect.origin.y),
|
| + SkScalarRound(rect.origin.x + rect.size.width),
|
| + SkScalarRound(rect.origin.y + rect.size.height)
|
| + };
|
| + return sk_rect;
|
| +}
|
| +
|
| // A class to generate events on Mac.
|
| class EventExecutorMac : public EventExecutor {
|
| public:
|
| @@ -307,11 +319,40 @@ void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) {
|
|
|
| void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) {
|
| if (event.has_x() && event.has_y()) {
|
| - // TODO(wez): This code assumes that MouseEvent(0,0) (top-left of client view)
|
| - // corresponds to local (0,0) (top-left of primary monitor). That won't in
|
| - // general be true on multi-monitor systems, though.
|
| - VLOG(3) << "Moving mouse to " << event.x() << "," << event.y();
|
| + // On multi-monitor systems (0,0) refers to the top-left of the "main"
|
| + // display, whereas our coordinate scheme places (0,0) at the top-left of
|
| + // the bounding rectangle around all the displays, so we need to translate
|
| + // accordingly.
|
| + // TODO(wez): Move display config tracking into a separate class used both
|
| + // here and in the Capturer.
|
| +
|
| + // Set the mouse position assuming single-monitor.
|
| mouse_pos_ = SkIPoint::Make(event.x(), event.y());
|
| +
|
| + // Determine how many active displays there are.
|
| + CGDisplayCount display_count;
|
| + CGError error = CGGetActiveDisplayList(0, NULL, &display_count);
|
| + CHECK_EQ(error, CGDisplayNoErr);
|
| +
|
| + if (display_count > 1) {
|
| + // Determine the bounding box of the displays, to get the top-left origin.
|
| + std::vector<CGDirectDisplayID> display_ids(display_count);
|
| + error = CGGetActiveDisplayList(display_count, &display_ids[0],
|
| + &display_count);
|
| + CHECK_EQ(error, CGDisplayNoErr);
|
| + CHECK_EQ(display_count, display_ids.size());
|
| +
|
| + SkIRect desktop_bounds = SkIRect::MakeEmpty();
|
| + for (unsigned int d = 0; d < display_count; ++d) {
|
| + CGRect display_bounds = CGDisplayBounds(display_ids[d]);
|
| + desktop_bounds.join(CGRectToSkIRect(display_bounds));
|
| + }
|
| +
|
| + // Adjust the injected mouse event position.
|
| + mouse_pos_ += SkIPoint::Make(desktop_bounds.left(), desktop_bounds.top());
|
| + }
|
| +
|
| + VLOG(3) << "Moving mouse to " << event.x() << "," << event.y();
|
| }
|
| if (event.has_button() && event.has_button_down()) {
|
| if (event.button() >= 1 && event.button() <= 3) {
|
|
|