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

Unified Diff: remoting/host/input_injector_mac.cc

Issue 422503004: Adding ability to stream windows and inject events to them (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: I updated the code with almost all of the comments Lambros had. The exceptions are the redesign of … Created 6 years, 5 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
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

Powered by Google App Engine
This is Rietveld 408576698