Index: remoting/host/input_injector_mac.cc |
diff --git a/remoting/host/input_injector_mac.cc b/remoting/host/input_injector_mac.cc |
index c5e870026e3deff4e3e9205e2a6902b76f579821..ba5739961a0a0db732ff92f7baa32bf4390844e8 100644 |
--- a/remoting/host/input_injector_mac.cc |
+++ b/remoting/host/input_injector_mac.cc |
@@ -60,6 +60,7 @@ class InputInjectorMac : public InputInjector { |
public: |
explicit InputInjectorMac( |
scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ |
virtual ~InputInjectorMac(); |
// ClipboardStub interface. |
@@ -73,8 +74,10 @@ class InputInjectorMac : public InputInjector { |
// InputInjector interface. |
virtual void Start( |
scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; |
+ void EnableWindowInjection(webrtc::WindowId window_id); |
private: |
+ CGWindowID window_id_input_injector_mac_; |
Wez
2014/08/01 23:41:53
Members appear after type definitions (see style g
ronakvora do not use
2014/08/05 19:54:49
Got it. Removed anyhow since it was not needed, as
|
// The actual implementation resides in InputInjectorMac::Core class. |
class Core : public base::RefCountedThreadSafe<Core> { |
public: |
@@ -90,12 +93,14 @@ class InputInjectorMac : public InputInjector { |
// Mirrors the InputInjector interface. |
void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard); |
+ void EnableWindowInjection(CGWindowID window_id); |
void Stop(); |
private: |
friend class base::RefCountedThreadSafe<Core>; |
virtual ~Core(); |
+ CGRect FindCGRectOfWindow(webrtc::MacDesktopConfiguration desktop_config); |
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
webrtc::DesktopVector mouse_pos_; |
@@ -103,6 +108,8 @@ class InputInjectorMac : public InputInjector { |
scoped_ptr<Clipboard> clipboard_; |
CGEventFlags left_modifiers_; |
CGEventFlags right_modifiers_; |
+ CGWindowID window_id_core_; |
+ bool window_injection_enabled_; |
DISALLOW_COPY_AND_ASSIGN(Core); |
}; |
@@ -142,6 +149,11 @@ void InputInjectorMac::Start( |
core_->Start(client_clipboard.Pass()); |
} |
+void InputInjectorMac::EnableWindowInjection(webrtc::WindowId window_id) { |
+ window_id_input_injector_mac_ = (CGWindowID) window_id; |
Wez
2014/08/01 23:41:53
Why do you need to store this in the InputInjector
ronakvora do not use
2014/08/05 19:54:49
Don't. Removed!
|
+ core_->EnableWindowInjection(window_id_input_injector_mac_); |
+} |
+ |
InputInjectorMac::Core::Core( |
scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
: task_runner_(task_runner), |
@@ -163,6 +175,11 @@ InputInjectorMac::Core::Core( |
#pragma clang diagnostic pop |
} |
+void InputInjectorMac::Core::EnableWindowInjection(CGWindowID window_id) { |
+ window_id_core_ = window_id; |
+ window_injection_enabled_ = true; |
+} |
+ |
void InputInjectorMac::Core::InjectClipboardEvent(const ClipboardEvent& event) { |
if (!task_runner_->BelongsToCurrentThread()) { |
task_runner_->PostTask( |
@@ -228,6 +245,44 @@ void InputInjectorMac::Core::InjectTextEvent(const TextEvent& event) { |
CreateAndPostKeyEvent(kVK_Space, false, 0, text); |
} |
+// This method is used if we are capturing a window instead of a screen. |
+// It finds the rectangle of the window we are streaming using |
+// |window_id_core_|. The InputInjector can then use this rectangle |
+// to translate the input event to coordinates of the window rather |
+// than the screen. |
+CGRect InputInjectorMac::Core::FindCGRectOfWindow( |
+ webrtc::MacDesktopConfiguration desktop_config) { |
+ CGRect rect; |
+ CGWindowID ids[1] = {window_id_core_}; |
+ CFArrayRef window_id_array = |
+ CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL); |
+ CFArrayRef window_array = |
+ CGWindowListCreateDescriptionFromArray(window_id_array); |
+ if (window_array == NULL || 0 == CFArrayGetCount(window_array)) { |
+ // Could not find the window. It might have been closed. |
+ LOG(ERROR) << "Specified window to stream not found for id: " |
+ << window_id_core_; |
+ CFRelease(window_id_array); |
+ CFRelease(window_array); |
+ return CGRectNull; |
+ } |
+ CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( |
+ CFArrayGetValueAtIndex(window_array, 0)); |
+ |
+ if (CFDictionaryContainsKey(window, kCGWindowBounds)) { |
+ CFDictionaryRef bounds = |
+ reinterpret_cast<CFDictionaryRef> |
+ (CFDictionaryGetValue(window, kCGWindowBounds)); |
+ if (bounds) { |
+ CGRectMakeWithDictionaryRepresentation(bounds, &rect); |
+ } |
+ } |
+ |
+ CFRelease(window_id_array); |
+ CFRelease(window_array); |
+ return rect; |
+} |
+ |
void InputInjectorMac::Core::InjectMouseEvent(const MouseEvent& event) { |
if (event.has_x() && event.has_y()) { |
// On multi-monitor systems (0,0) refers to the top-left of the "main" |
@@ -263,6 +318,17 @@ void InputInjectorMac::Core::InjectMouseEvent(const MouseEvent& event) { |
mouse_pos_.set(mouse_pos_.x() / desktop_config.dip_to_pixel_scale, |
mouse_pos_.y() / desktop_config.dip_to_pixel_scale); |
+ if (window_injection_enabled_) { |
+ CGRect windowRect = FindCGRectOfWindow(desktop_config); |
+ if (CGRectEqualToRect(windowRect, CGRectNull)) { |
+ LOG(ERROR) << "Can't find rectangle of window."; |
+ return; |
+ } |
+ mouse_pos_ = mouse_pos_.add( |
+ webrtc::DesktopVector(CGRectGetMinX(windowRect), |
+ CGRectGetMinY(windowRect))); |
Wez
2014/08/01 23:41:54
Do you mean to clamp input to the window width & h
ronakvora do not use
2014/08/05 19:54:49
I don't know what you mean by clamp input to windo
|
+ } |
+ |
VLOG(3) << "Moving mouse to " << mouse_pos_.x() << "," << mouse_pos_.y(); |
} |
if (event.has_button() && event.has_button_down()) { |
@@ -341,4 +407,13 @@ scoped_ptr<InputInjector> InputInjector::Create( |
return scoped_ptr<InputInjector>(new InputInjectorMac(main_task_runner)); |
} |
+scoped_ptr<InputInjector> InputInjector::CreateForWindow( |
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
+ webrtc::WindowId window_id) { |
+ scoped_ptr<InputInjectorMac>injector(new InputInjectorMac(main_task_runner)); |
+ injector->EnableWindowInjection(window_id); |
+ return injector.PassAs<InputInjector>(); |
+} |
+ |
} // namespace remoting |