From e4c01f3187417f6404a826d646f3136696dc9578 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 27 Aug 2015 11:22:39 +0200 Subject: [PATCH 01/41] Offscreen render support base --- .gitmodules | 2 +- atom/app/atom_main.cc | 8 ++-- atom/browser/api/atom_api_window.cc | 11 +++++ atom/browser/api/atom_api_window.h | 1 + atom/browser/native_window.cc | 58 ++++++++++++++++++++++++++- atom/browser/native_window.h | 30 ++++++++++++++ atom/browser/native_window_observer.h | 2 + atom/common/options_switches.cc | 2 + atom/common/options_switches.h | 2 + vendor/native_mate | 2 +- 10 files changed, 112 insertions(+), 6 deletions(-) diff --git a/.gitmodules b/.gitmodules index c6e53ed39a..a3afcef28c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ url = https://github.com/atom/chromium-breakpad.git [submodule "vendor/native_mate"] path = vendor/native_mate - url = https://github.com/zcbenz/native-mate.git + url = https://github.com/brenca/native-mate.git [submodule "vendor/crashpad"] path = vendor/crashpad url = https://github.com/atom/crashpad.git diff --git a/atom/app/atom_main.cc b/atom/app/atom_main.cc index 47be348522..5677adb2ee 100644 --- a/atom/app/atom_main.cc +++ b/atom/app/atom_main.cc @@ -90,9 +90,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) { if (env->GetVar("OS", &os) && os != "cygwin") { AttachConsole(ATTACH_PARENT_PROCESS); - FILE* dontcare; - freopen_s(&dontcare, "CON", "w", stdout); - freopen_s(&dontcare, "CON", "w", stderr); + FILE* dontcare, *out, *err; + out = fopen("out.txt", "w"); + err = fopen("err.txt", "w"); + freopen_s(&out, "CON", "w", stdout); + freopen_s(&err, "CON", "w", stderr); freopen_s(&dontcare, "CON", "r", stdin); } diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index e6d16fe6fa..c19cf6f7d9 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -17,6 +17,7 @@ #include "native_mate/constructor.h" #include "native_mate/dictionary.h" #include "ui/gfx/geometry/rect.h" +#include "v8/include/v8.h" #if defined(OS_WIN) #include "atom/browser/native_window_views.h" @@ -92,6 +93,16 @@ void Window::WillCloseWindow(bool* prevent_default) { *prevent_default = Emit("close"); } +void Window::OnFrameRendered(scoped_ptr rgb, const int size) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + + v8::Local data = v8::ArrayBuffer::New(isolate(), rgb.get(), size); + v8::Local uint_data = v8::Uint8ClampedArray::New(data, 0, size); + + Emit("frame-rendered", uint_data, size); +} + void Window::OnWindowClosed() { if (api_web_contents_) { api_web_contents_->DestroyWebContents(); diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index de2f093ea3..925aa67497 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -53,6 +53,7 @@ class Window : public mate::TrackableObject, void OnPageTitleUpdated(bool* prevent_default, const std::string& title) override; void WillCloseWindow(bool* prevent_default) override; + void OnFrameRendered(scoped_ptr rgb, const int size) override; void OnWindowClosed() override; void OnWindowBlur() override; void OnWindowFocus() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 96085846bc..b21d04aa23 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -8,6 +8,9 @@ #include #include +#include "content/public/browser/render_widget_host_view_frame_subscriber.h" +#include "media/base/video_frame.h" +#include "media/base/yuv_convert.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/window_list.h" @@ -147,8 +150,9 @@ NativeWindow* NativeWindow::FromWebContents( content::WebContents* web_contents) { WindowList& window_list = *WindowList::GetInstance(); for (NativeWindow* window : window_list) { - if (window->web_contents() == web_contents) + if (window->web_contents() == web_contents){ return window; + } } return nullptr; } @@ -201,6 +205,9 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { options.Get(switches::kTitle, &title); SetTitle(title); + offscreen_ = false; + options.Get(switches::kOffScreenRender, &offscreen_); + // Then show it. bool show = true; options.Get(switches::kShow, &show); @@ -540,6 +547,18 @@ void NativeWindow::DevToolsClosed() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed()); } +void NativeWindow::RenderViewReady(){ + if(offscreen_){ + const auto view = web_contents()->GetRenderWidgetHostView(); + + scoped_ptr subscriber(new RenderSubscriber( + view->GetVisibleViewportSize(), base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)) + )); + + view->BeginFrameSubscription(subscriber.Pass()); + } +} + void NativeWindow::RenderViewCreated( content::RenderViewHost* render_view_host) { if (!transparent_) @@ -617,4 +636,41 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, callback.Run(bitmap); } +void NativeWindow::OnFrameReceived(bool result, scoped_refptr frame) { + if(result){ + gfx::Rect rect = frame->visible_rect(); + + const int rgb_arr_size = rect.width()*rect.height()*4; + scoped_ptr rgb_bytes(new uint8[rgb_arr_size]); + + // Convert a frame of YUV to 32 bit ARGB. + media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane), + frame->data(media::VideoFrame::kUPlane), + frame->data(media::VideoFrame::kVPlane), + rgb_bytes.get(), + rect.width(), rect.height(), + frame->stride(media::VideoFrame::kYPlane), + frame->stride(media::VideoFrame::kUVPlane), + rect.width()*4, + media::YV12); + + FOR_EACH_OBSERVER(NativeWindowObserver, + observers_, + OnFrameRendered(rgb_bytes.Pass(), rgb_arr_size)); + } +} + +bool RenderSubscriber::ShouldCaptureFrame(const gfx::Rect& damage_rect, + base::TimeTicks present_time, + scoped_refptr* storage, + DeliverFrameCallback* callback) { + last_present_time_ = present_time; + *storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_, + gfx::Rect(size_), size_, + base::TimeDelta()); + + *callback = base::Bind(&RenderSubscriber::CallbackMethod, callback_, *storage); + return true; +} + } // namespace atom diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index b9294d38c9..793bd614c8 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -9,6 +9,8 @@ #include #include +#include "media/base/video_frame.h" +#include "content/public/browser/render_widget_host_view_frame_subscriber.h" #include "atom/browser/native_window_observer.h" #include "atom/browser/ui/accelerator_util.h" #include "base/cancelable_callback.h" @@ -232,6 +234,8 @@ class NativeWindow : public content::WebContentsObserver, has_dialog_attached_ = has_dialog_attached; } + void OnFrameReceived(bool result, scoped_refptr frame); + protected: NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, const mate::Dictionary& options); @@ -243,6 +247,7 @@ class NativeWindow : public content::WebContentsObserver, // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; + void RenderViewReady() override; void BeforeUnloadDialogCancelled() override; void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; bool OnMessageReceived(const IPC::Message& message) override; @@ -263,6 +268,8 @@ class NativeWindow : public content::WebContentsObserver, const SkBitmap& bitmap, content::ReadbackResponse response); + bool offscreen_; + // Whether window has standard frame. bool has_frame_; @@ -317,6 +324,29 @@ class NativeWindow : public content::WebContentsObserver, DISALLOW_COPY_AND_ASSIGN(NativeWindow); }; +class RenderSubscriber : public content::RenderWidgetHostViewFrameSubscriber { + public: + RenderSubscriber(gfx::Size size, base::Callback)> callback) : size_(size), callback_(callback) {} + + bool ShouldCaptureFrame(const gfx::Rect& damage_rect, + base::TimeTicks present_time, + scoped_refptr* storage, + DeliverFrameCallback* callback) override; + + base::TimeTicks last_present_time() const { return last_present_time_; } + + static void CallbackMethod(base::Callback)> callback, + scoped_refptr frame, + base::TimeTicks present_time, + bool success) { + callback.Run(success, frame); + } + + private: + gfx::Size size_; + base::Callback)> callback_; + base::TimeTicks last_present_time_; +}; // This class provides a hook to get a NativeWindow from a WebContents. class NativeWindowRelay : diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 5b0a0c56b3..db6587de1f 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -27,6 +27,8 @@ class NativeWindowObserver { const std::string& partition_id, WindowOpenDisposition disposition) {} + virtual void OnFrameRendered(scoped_ptr rgb, const int size) {} + // Called when user is starting an navigation in web page. virtual void WillNavigate(bool* prevent_default, const GURL& url) {} diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 8f457116ec..73a54157fa 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -110,6 +110,8 @@ const char kRegisterStandardSchemes[] = "register-standard-schemes"; // The browser process app model ID const char kAppUserModelId[] = "app-user-model-id"; +const char kOffScreenRender[] = "offscreen-render"; + } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 2dd48ee32a..edd37ff035 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -60,6 +60,8 @@ extern const char kRegisterStandardSchemes[]; extern const char kAppUserModelId[]; +extern const char kOffScreenRender[]; + } // namespace switches } // namespace atom diff --git a/vendor/native_mate b/vendor/native_mate index 67d9eaa215..31b6395d99 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 67d9eaa215e8727d86dc7b1f7a10be8699848f1f +Subproject commit 31b6395d9938558ea39a77ef2f432beaf2dcd4cb From 58081ca9e9faee876f9f47ac72856da6a9bbe1d2 Mon Sep 17 00:00:00 2001 From: gellert Date: Sat, 29 Aug 2015 00:45:00 +0200 Subject: [PATCH 02/41] setOffscreenRender and api docs added --- atom/browser/api/atom_api_window.cc | 5 ++++ atom/browser/api/atom_api_window.h | 1 + atom/browser/native_window.cc | 45 ++++++++++++++++++++--------- atom/browser/native_window.h | 17 +++++++---- docs/api/browser-window.md | 16 ++++++++++ 5 files changed, 65 insertions(+), 19 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index c19cf6f7d9..df14e23176 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -440,6 +440,10 @@ void Window::CapturePage(mate::Arguments* args) { rect, base::Bind(&OnCapturePageDone, args->isolate(), callback)); } +void Window::SetOffscreenRender(bool isOffscreen) { + window_->SetOffscreenRender(isOffscreen); +} + void Window::SetProgressBar(double progress) { window_->SetProgressBar(progress); } @@ -602,6 +606,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, #if defined(OS_MACOSX) .SetMethod("showDefinitionForSelection", &Window::ShowDefinitionForSelection) + .SetMethod("setOffscreenRender", &Window::SetOffscreenRender) #endif .SetProperty("id", &Window::ID, true) .SetProperty("webContents", &Window::WebContents, true) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 925aa67497..8163ecbdd9 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -138,6 +138,7 @@ class Window : public mate::TrackableObject, void SetMenuBarVisibility(bool visible); bool IsMenuBarVisible(); void SetAspectRatio(double aspect_ratio, mate::Arguments* args); + void SetOffscreenRender(bool isOffscreen); #if defined(OS_MACOSX) void ShowDefinitionForSelection(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index b21d04aa23..fc911d00a0 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -330,6 +330,29 @@ void NativeWindow::CapturePage(const gfx::Rect& rect, kBGRA_8888_SkColorType); } +void NativeWindow::SetOffscreenRender(bool isOffscreen) { + if (!isOffscreen && !offscreen_) return; + + const auto view = web_contents()->GetRenderWidgetHostView(); + + if (view) { + if (isOffscreen) { + scoped_ptr subscriber( + new RenderSubscriber( + view->GetVisibleViewportSize(), + base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)) + ) + ); + + view->BeginFrameSubscription(subscriber.Pass()); + } else { + view->EndFrameSubscription(); + } + + offscreen_ = isOffscreen; + } +} + void NativeWindow::RequestToClosePage() { bool prevent_default = false; FOR_EACH_OBSERVER(NativeWindowObserver, @@ -548,15 +571,7 @@ void NativeWindow::DevToolsClosed() { } void NativeWindow::RenderViewReady(){ - if(offscreen_){ - const auto view = web_contents()->GetRenderWidgetHostView(); - - scoped_ptr subscriber(new RenderSubscriber( - view->GetVisibleViewportSize(), base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)) - )); - - view->BeginFrameSubscription(subscriber.Pass()); - } + SetOffscreenRender(offscreen_); } void NativeWindow::RenderViewCreated( @@ -636,11 +651,12 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, callback.Run(bitmap); } -void NativeWindow::OnFrameReceived(bool result, scoped_refptr frame) { - if(result){ +void NativeWindow::OnFrameReceived(bool result, + scoped_refptr frame) { + if (result) { gfx::Rect rect = frame->visible_rect(); - const int rgb_arr_size = rect.width()*rect.height()*4; + const int rgb_arr_size = rect.width() * rect.height() * 4; scoped_ptr rgb_bytes(new uint8[rgb_arr_size]); // Convert a frame of YUV to 32 bit ARGB. @@ -651,7 +667,7 @@ void NativeWindow::OnFrameReceived(bool result, scoped_refptr rect.width(), rect.height(), frame->stride(media::VideoFrame::kYPlane), frame->stride(media::VideoFrame::kUVPlane), - rect.width()*4, + rect.width() * 4, media::YV12); FOR_EACH_OBSERVER(NativeWindowObserver, @@ -660,7 +676,8 @@ void NativeWindow::OnFrameReceived(bool result, scoped_refptr } } -bool RenderSubscriber::ShouldCaptureFrame(const gfx::Rect& damage_rect, +bool RenderSubscriber::ShouldCaptureFrame( + const gfx::Rect& damage_rect, base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 793bd614c8..a07e7d641b 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -162,6 +162,9 @@ class NativeWindow : public content::WebContentsObserver, virtual void CapturePage(const gfx::Rect& rect, const CapturePageCallback& callback); + // Offscreen render + virtual void SetOffscreenRender(bool isOffscreen); + // Show popup dictionary. virtual void ShowDefinitionForSelection(); @@ -326,7 +329,10 @@ class NativeWindow : public content::WebContentsObserver, class RenderSubscriber : public content::RenderWidgetHostViewFrameSubscriber { public: - RenderSubscriber(gfx::Size size, base::Callback)> callback) : size_(size), callback_(callback) {} + RenderSubscriber( + gfx::Size size, + base::Callback)> callback) + : size_(size), callback_(callback) { } bool ShouldCaptureFrame(const gfx::Rect& damage_rect, base::TimeTicks present_time, @@ -335,10 +341,11 @@ class RenderSubscriber : public content::RenderWidgetHostViewFrameSubscriber { base::TimeTicks last_present_time() const { return last_present_time_; } - static void CallbackMethod(base::Callback)> callback, - scoped_refptr frame, - base::TimeTicks present_time, - bool success) { + static void CallbackMethod( + base::Callback)> callback, + scoped_refptr frame, + base::TimeTicks present_time, + bool success) { callback.Run(success, frame); } diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 612b3ce4f3..f0b8abc279 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -74,6 +74,8 @@ You can also create a window without chrome by using Linux. * `standard-window` Boolean - Uses the OS X's standard window instead of the textured window. Defaults to `true`. + * `offscreen-render` Boolean - The frame of the window will be accessible + through the `frame-rendered` event in a buffer. Defaults to `false`. * `web-preferences` Object - Settings of web page's features * `javascript` Boolean * `web-security` Boolean - When setting `false`, it will disable the same-origin @@ -226,6 +228,15 @@ Emitted when devtools is closed. Emitted when devtools is focused / opened. +### Event: 'frame-rendered' + +* `event` Event +* `frame` Buffer +* `size` Number + +Emitted when *offscreen render* is enabled, the current frame's pixel data +and size are available. + ### Event: 'app-command': Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx) is invoked. These are typically related to keyboard media keys or browser commands, as well as the "Back" button built into some mice on Windows. @@ -721,6 +732,11 @@ Returns whether the window is visible on all workspaces. **Note:** This API always returns false on Windows. +### BrowserWindow.setOffscreenRender(isOffscreen) + +Sets the offscreen rendering, if `true` the `frame-rendered` event will fire, +when the frame changes. + ## Class: WebContents A `WebContents` is responsible for rendering and controlling a web page. From c59c0bd5b3893bf720ea04699386dc5520934626 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Mon, 31 Aug 2015 18:32:33 +0200 Subject: [PATCH 03/41] Mouse event handling and keyboard event handling (not totally working yet) --- atom/browser/api/atom_api_window.cc | 142 ++++++++++++++++++++++++++++ atom/browser/api/atom_api_window.h | 2 + atom/browser/native_window.cc | 67 ++++++++++++- atom/browser/native_window.h | 7 ++ atom/common/event_types.cc | 45 +++++++++ atom/common/event_types.h | 48 ++++++++++ atom/common/options_switches.cc | 10 ++ atom/common/options_switches.h | 10 ++ filenames.gypi | 2 + 9 files changed, 330 insertions(+), 3 deletions(-) create mode 100644 atom/common/event_types.cc create mode 100644 atom/common/event_types.h diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index c19cf6f7d9..977a241a7d 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -8,6 +8,8 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" #include "atom/browser/native_window.h" +#include "atom/common/options_switches.h" +#include "atom/common/event_types.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" @@ -516,6 +518,144 @@ bool Window::IsVisibleOnAllWorkspaces() { return window_->IsVisibleOnAllWorkspaces(); } +void Window::SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& data){ + auto type = blink::WebInputEvent::Type::Char; + int modifiers = 0; + int keycode = 0; + std::string type_str = ""; + std::vector modifier_array; + + data.Get(switches::kMouseEventType, &type_str); + data.Get(switches::kModifiers, &modifier_array); + data.Get(switches::kKeyCode, &keycode); + + if(type_str.compare(event_types::kKeyDown) == 0){ + type = blink::WebInputEvent::Type::KeyDown; + }else if(type_str.compare(event_types::kKeyUp) == 0){ + type = blink::WebInputEvent::Type::KeyUp; + }else if(type_str.compare(event_types::kChar) == 0){ + type = blink::WebInputEvent::Type::Char; + } + + for(std::vector::iterator mod = modifier_array.begin(); mod != modifier_array.end(); ++mod) { + if(mod->compare(event_types::kModifierIsKeyPad) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::IsKeyPad; + }else if(mod->compare(event_types::kModifierIsAutoRepeat) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::IsAutoRepeat; + }else if(mod->compare(event_types::kModifierIsLeft) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::IsLeft; + }else if(mod->compare(event_types::kModifierIsRight) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::IsRight; + }else if(mod->compare(event_types::kModifierShiftKey) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::ShiftKey; + }else if(mod->compare(event_types::kModifierControlKey) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::ControlKey; + }else if(mod->compare(event_types::kModifierAltKey) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::AltKey; + }else if(mod->compare(event_types::kModifierMetaKey) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::MetaKey; + }else if(mod->compare(event_types::kModifierCapsLockOn) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::CapsLockOn; + }else if(mod->compare(event_types::kModifierNumLockOn) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::NumLockOn; + } + } + + window_->SendKeyboardEvent(type, modifiers, keycode); +} + +void Window::SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data){ + int x, y, movementX, movementY, clickCount; + std::string type_str = ""; + std::string button_str = ""; + std::vector modifier_array; + + blink::WebInputEvent::Type type = blink::WebInputEvent::Type::MouseMove; + blink::WebMouseEvent::Button button = blink::WebMouseEvent::Button::ButtonNone; + int modifiers = 0; + + data.Get(switches::kMouseEventType, &type_str); + data.Get(switches::kMouseEventButton, &button_str); + data.Get(switches::kModifiers, &modifier_array); + + if(type_str.compare(event_types::kMouseDown) == 0){ + type = blink::WebInputEvent::Type::MouseDown; + }else if(type_str.compare(event_types::kMouseUp) == 0){ + type = blink::WebInputEvent::Type::MouseUp; + }else if(type_str.compare(event_types::kMouseMove) == 0){ + type = blink::WebInputEvent::Type::MouseMove; + }else if(type_str.compare(event_types::kMouseEnter) == 0){ + type = blink::WebInputEvent::Type::MouseEnter; + }else if(type_str.compare(event_types::kMouseLeave) == 0){ + type = blink::WebInputEvent::Type::MouseLeave; + }else if(type_str.compare(event_types::kContextMenu) == 0){ + type = blink::WebInputEvent::Type::ContextMenu; + }else if(type_str.compare(event_types::kMouseWheel) == 0){ + type = blink::WebInputEvent::Type::MouseWheel; + } + + if(button_str.compare(event_types::kMouseLeftButton) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::LeftButtonDown; + button = blink::WebMouseEvent::Button::ButtonLeft; + }else if(button_str.compare(event_types::kMouseRightButton) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::RightButtonDown; + button = blink::WebMouseEvent::Button::ButtonRight; + }else if(button_str.compare(event_types::kMouseMiddleButton) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::MiddleButtonDown; + button = blink::WebMouseEvent::Button::ButtonMiddle; + } + + for(std::vector::iterator mod = modifier_array.begin(); mod != modifier_array.end(); ++mod) { + if(mod->compare(event_types::kModifierLeftButtonDown) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::LeftButtonDown; + }else if(mod->compare(event_types::kModifierMiddleButtonDown) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::MiddleButtonDown; + }else if(mod->compare(event_types::kModifierRightButtonDown) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::RightButtonDown; + }else if(mod->compare(event_types::kModifierShiftKey) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::ShiftKey; + }else if(mod->compare(event_types::kModifierControlKey) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::ControlKey; + }else if(mod->compare(event_types::kModifierAltKey) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::AltKey; + }else if(mod->compare(event_types::kModifierMetaKey) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::MetaKey; + }else if(mod->compare(event_types::kModifierCapsLockOn) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::CapsLockOn; + }else if(mod->compare(event_types::kModifierNumLockOn) == 0){ + modifiers = modifiers & blink::WebInputEvent::Modifiers::NumLockOn; + } + } + + if(type == blink::WebInputEvent::Type::MouseWheel){ + bool precise = true; + + x = 0; + y = 0; + data.Get(switches::kX, &x); + data.Get(switches::kY, &y); + data.Get(switches::kMouseWheelPrecise, &precise); + + window_->SendMouseWheelEvent(modifiers, x, y, precise); + }else{ + if (data.Get(switches::kX, &x) && data.Get(switches::kY, &y)) { + if(!data.Get(switches::kMovementX, &movementX)){ + movementX = 0; + } + + if(!data.Get(switches::kMovementY, &movementY)){ + movementY = 0; + } + + if(!data.Get(switches::kClickCount, &clickCount)){ + clickCount = 0; + } + + window_->SendMouseEvent(type, modifiers, button, x, y, movementX, movementY, clickCount); + } + } +} + int32_t Window::ID() const { return weak_map_id(); } @@ -599,6 +739,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, &Window::SetVisibleOnAllWorkspaces) .SetMethod("isVisibleOnAllWorkspaces", &Window::IsVisibleOnAllWorkspaces) + .SetMethod("sendMouseEvent", &Window::SendMouseEvent) + .SetMethod("sendKeyboardEvent", &Window::SendKeyboardEvent) #if defined(OS_MACOSX) .SetMethod("showDefinitionForSelection", &Window::ShowDefinitionForSelection) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 925aa67497..8bff976946 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -138,6 +138,8 @@ class Window : public mate::TrackableObject, void SetMenuBarVisibility(bool visible); bool IsMenuBarVisible(); void SetAspectRatio(double aspect_ratio, mate::Arguments* args); + void SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& data); + void SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data); #if defined(OS_MACOSX) void ShowDefinitionForSelection(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index b21d04aa23..da7218d2ea 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -9,6 +9,8 @@ #include #include "content/public/browser/render_widget_host_view_frame_subscriber.h" +#include "content/public/browser/native_web_keyboard_event.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" #include "media/base/video_frame.h" #include "media/base/yuv_convert.h" #include "atom/browser/atom_browser_context.h" @@ -547,10 +549,69 @@ void NativeWindow::DevToolsClosed() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed()); } -void NativeWindow::RenderViewReady(){ - if(offscreen_){ - const auto view = web_contents()->GetRenderWidgetHostView(); +void NativeWindow::SendKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, int keycode){ + auto keyb_event = new content::NativeWebKeyboardEvent; + keyb_event->nativeKeyCode = keycode; + keyb_event->windowsKeyCode = keycode; + keyb_event->setKeyIdentifierFromWindowsKeyCode(); + keyb_event->type = type; + keyb_event->modifiers = modifiers; + keyb_event->isSystemKey = false; + keyb_event->timeStampSeconds = base::Time::Now().ToDoubleT(); + keyb_event->skip_in_browser = false; + + if (type == blink::WebInputEvent::Char || type == blink::WebInputEvent::KeyDown) { + keyb_event->text[0] = keycode; + keyb_event->unmodifiedText[0] = keycode; + } + + const auto view = web_contents()->GetRenderWidgetHostView(); + const auto host = view ? view->GetRenderWidgetHost() : nullptr; + host->ForwardKeyboardEvent(*keyb_event); +} + +void NativeWindow::SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount){ + auto mouse_event = new blink::WebMouseEvent(); + + mouse_event->x = x; + mouse_event->y = y; + mouse_event->windowX = x; + mouse_event->windowY = y; + mouse_event->clickCount = clickCount; + mouse_event->type = type; + mouse_event->modifiers = modifiers; + mouse_event->button = button; + + mouse_event->timeStampSeconds = base::Time::Now().ToDoubleT(); + + const auto view = web_contents()->GetRenderWidgetHostView(); + const auto host = view ? view->GetRenderWidgetHost() : nullptr; + host->ForwardMouseEvent(*mouse_event); +} + +void NativeWindow::SendMouseWheelEvent(int modifiers, int x, int y, bool precise){ + auto wheel_event = new blink::WebMouseWheelEvent(); + + wheel_event->type = blink::WebInputEvent::MouseWheel; + wheel_event->deltaX = x; + wheel_event->deltaY = y; + if(x) wheel_event->wheelTicksX = x > 0.0f ? 1.0f : -1.0f; + if(y) wheel_event->wheelTicksY = y > 0.0f ? 1.0f : -1.0f; + wheel_event->modifiers = modifiers; + wheel_event->hasPreciseScrollingDeltas = precise; + wheel_event->canScroll = true; + + const auto view = web_contents()->GetRenderWidgetHostView(); + const auto host = view ? view->GetRenderWidgetHost() : nullptr; + host->ForwardWheelEvent(*wheel_event); +} + +void NativeWindow::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { + const auto view = web_contents()->GetRenderWidgetHostView(); + const auto host = view ? view->GetRenderWidgetHost() : nullptr; + + if(offscreen_){ scoped_ptr subscriber(new RenderSubscriber( view->GetVisibleViewportSize(), base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)) )); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 793bd614c8..88686ee22f 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -11,6 +11,8 @@ #include "media/base/video_frame.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" +#include "content/public/browser/native_web_keyboard_event.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" #include "atom/browser/native_window_observer.h" #include "atom/browser/ui/accelerator_util.h" #include "base/cancelable_callback.h" @@ -236,6 +238,10 @@ class NativeWindow : public content::WebContentsObserver, void OnFrameReceived(bool result, scoped_refptr frame); + void SendKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, int keycode); + void SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount); + void SendMouseWheelEvent(int modifiers, int x, int y, bool clickCount); + protected: NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, const mate::Dictionary& options); @@ -248,6 +254,7 @@ class NativeWindow : public content::WebContentsObserver, // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; void RenderViewReady() override; + void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override; void BeforeUnloadDialogCancelled() override; void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; bool OnMessageReceived(const IPC::Message& message) override; diff --git a/atom/common/event_types.cc b/atom/common/event_types.cc new file mode 100644 index 0000000000..dd87783e68 --- /dev/null +++ b/atom/common/event_types.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/event_types.h" + +namespace atom { + +namespace event_types { + +const char kMouseDown[] = "down"; +const char kMouseUp[] = "up"; +const char kMouseMove[] = "move"; +const char kMouseEnter[] = "enter"; +const char kMouseLeave[] = "leave"; +const char kContextMenu[] = "context-menu"; +const char kMouseWheel[] = "wheel"; + +const char kKeyDown[] = "key-down"; +const char kKeyUp[] = "key-up"; +const char kChar[] = "char"; + +const char kMouseLeftButton[] = "left"; +const char kMouseRightButton[] = "right"; +const char kMouseMiddleButton[] = "middle"; + +const char kModifierLeftButtonDown[] = "left-button-down"; +const char kModifierMiddleButtonDown[] = "middle-button-down"; +const char kModifierRightButtonDown[] = "right-button-down"; + +const char kModifierShiftKey[] = "shift"; +const char kModifierControlKey[] = "control"; +const char kModifierAltKey[] = "alt"; +const char kModifierMetaKey[] = "meta"; +const char kModifierCapsLockOn[] = "caps-lock"; +const char kModifierNumLockOn[] = "num-lock"; + +const char kModifierIsKeyPad[] = "keypad"; +const char kModifierIsAutoRepeat[] = "auto-repeat"; +const char kModifierIsLeft[] = "left"; +const char kModifierIsRight[] = "right"; + +} // namespace switches + +} // namespace atom diff --git a/atom/common/event_types.h b/atom/common/event_types.h new file mode 100644 index 0000000000..b7eae781fc --- /dev/null +++ b/atom/common/event_types.h @@ -0,0 +1,48 @@ +// Copyright (c) 2013 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_EVENT_TYPES_H_ +#define ATOM_COMMON_EVENT_TYPES_H_ + +namespace atom { + +namespace event_types { + +extern const char kMouseDown[]; +extern const char kMouseUp[]; +extern const char kMouseMove[]; +extern const char kMouseEnter[]; +extern const char kMouseLeave[]; +extern const char kContextMenu[]; +extern const char kMouseWheel[]; + +extern const char kKeyDown[]; +extern const char kKeyUp[]; +extern const char kChar[]; + +extern const char kMouseLeftButton[]; +extern const char kMouseRightButton[]; +extern const char kMouseMiddleButton[]; + +extern const char kModifierLeftButtonDown[]; +extern const char kModifierMiddleButtonDown[]; +extern const char kModifierRightButtonDown[]; + +extern const char kModifierShiftKey[]; +extern const char kModifierControlKey[]; +extern const char kModifierAltKey[]; +extern const char kModifierMetaKey[]; +extern const char kModifierCapsLockOn[]; +extern const char kModifierNumLockOn[]; + +extern const char kModifierIsKeyPad[]; +extern const char kModifierIsAutoRepeat[]; +extern const char kModifierIsLeft[]; +extern const char kModifierIsRight[]; + +} // namespace switches + +} // namespace atom + +#endif // ATOM_COMMON_EVENT_TYPES_H_ diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 73a54157fa..ee70080ae6 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -112,6 +112,16 @@ const char kAppUserModelId[] = "app-user-model-id"; const char kOffScreenRender[] = "offscreen-render"; +const char kModifiers[] = "modifiers"; +const char kKeyCode[] = "keycode"; + +const char kMovementX[] = "movement-x"; +const char kMovementY[] = "movement-y"; +const char kClickCount[] = "click-count"; +const char kMouseEventType[] = "type"; +const char kMouseEventButton[] = "button"; +const char kMouseWheelPrecise[] = "precise"; + } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index edd37ff035..505305deb4 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -62,6 +62,16 @@ extern const char kAppUserModelId[]; extern const char kOffScreenRender[]; +extern const char kModifiers[]; +extern const char kKeyCode[]; + +extern const char kMovementX[]; +extern const char kMovementY[]; +extern const char kClickCount[]; +extern const char kMouseEventType[]; +extern const char kMouseEventButton[]; +extern const char kMouseWheelPrecise[]; + } // namespace switches } // namespace atom diff --git a/filenames.gypi b/filenames.gypi index 40af1ebb1f..2e84b73c2c 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -301,6 +301,8 @@ 'atom/common/node_includes.h', 'atom/common/options_switches.cc', 'atom/common/options_switches.h', + 'atom/common/event_types.cc', + 'atom/common/event_types.h', 'atom/common/platform_util.h', 'atom/common/platform_util_linux.cc', 'atom/common/platform_util_mac.mm', From dbcd0a4235ddcbd9ed28082984ca04a8f94ca285 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 2 Sep 2015 02:33:40 +0200 Subject: [PATCH 04/41] Key event sending update. --- atom/browser/api/atom_api_window.cc | 8 +++-- atom/browser/native_window.cc | 12 +++++-- atom/browser/native_window.h | 2 +- atom/common/event_types.cc | 4 +-- atom/common/options_switches.cc | 5 +-- atom/common/options_switches.h | 3 +- docs/api/browser-window.md | 55 +++++++++++++++++++++++++++++ 7 files changed, 77 insertions(+), 12 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 7ee19783b0..3c523f8ccd 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -526,12 +526,14 @@ void Window::SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& dat auto type = blink::WebInputEvent::Type::Char; int modifiers = 0; int keycode = 0; + int native = 0; std::string type_str = ""; std::vector modifier_array; - data.Get(switches::kMouseEventType, &type_str); + data.Get(switches::kEventType, &type_str); data.Get(switches::kModifiers, &modifier_array); data.Get(switches::kKeyCode, &keycode); + data.Get(switches::kNativeKeyCode, &native); if(type_str.compare(event_types::kKeyDown) == 0){ type = blink::WebInputEvent::Type::KeyDown; @@ -565,7 +567,7 @@ void Window::SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& dat } } - window_->SendKeyboardEvent(type, modifiers, keycode); + window_->SendKeyboardEvent(type, modifiers, keycode, native); } void Window::SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data){ @@ -578,7 +580,7 @@ void Window::SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data){ blink::WebMouseEvent::Button button = blink::WebMouseEvent::Button::ButtonNone; int modifiers = 0; - data.Get(switches::kMouseEventType, &type_str); + data.Get(switches::kEventType, &type_str); data.Get(switches::kMouseEventButton, &button_str); data.Get(switches::kModifiers, &modifier_array); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index f28a3a8bd4..a9e0631489 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -47,6 +47,7 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/screen.h" #include "ui/gl/gpu_switching_manager.h" +#include "ui/events/event.h" #if defined(OS_WIN) #include "ui/gfx/switches.h" @@ -572,10 +573,10 @@ void NativeWindow::DevToolsClosed() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed()); } -void NativeWindow::SendKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, int keycode){ +void NativeWindow::SendKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, int keycode, int nativeKeycode){ auto keyb_event = new content::NativeWebKeyboardEvent; - keyb_event->nativeKeyCode = keycode; + keyb_event->nativeKeyCode = nativeKeycode; keyb_event->windowsKeyCode = keycode; keyb_event->setKeyIdentifierFromWindowsKeyCode(); keyb_event->type = type; @@ -584,7 +585,7 @@ void NativeWindow::SendKeyboardEvent(blink::WebInputEvent::Type type, int modifi keyb_event->timeStampSeconds = base::Time::Now().ToDoubleT(); keyb_event->skip_in_browser = false; - if (type == blink::WebInputEvent::Char || type == blink::WebInputEvent::KeyDown) { + if (type == blink::WebInputEvent::Char || type == blink::WebInputEvent::RawKeyDown) { keyb_event->text[0] = keycode; keyb_event->unmodifiedText[0] = keycode; } @@ -592,6 +593,11 @@ void NativeWindow::SendKeyboardEvent(blink::WebInputEvent::Type type, int modifi const auto view = web_contents()->GetRenderWidgetHostView(); const auto host = view ? view->GetRenderWidgetHost() : nullptr; host->ForwardKeyboardEvent(*keyb_event); + + if(keyb_event->type == blink::WebInputEvent::Type::KeyDown){ + keyb_event->type = blink::WebInputEvent::RawKeyDown; + host->ForwardKeyboardEvent(*keyb_event); + } } void NativeWindow::SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount){ diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 8cc1d2ff2b..d361fcf696 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -238,7 +238,7 @@ class NativeWindow : public content::WebContentsObserver, void OnFrameReceived(bool result, scoped_refptr frame); - void SendKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, int keycode); + void SendKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, int keycode, int nativeKeycode); void SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount); void SendMouseWheelEvent(int modifiers, int x, int y, bool clickCount); diff --git a/atom/common/event_types.cc b/atom/common/event_types.cc index dd87783e68..3d3b901ed3 100644 --- a/atom/common/event_types.cc +++ b/atom/common/event_types.cc @@ -16,8 +16,8 @@ const char kMouseLeave[] = "leave"; const char kContextMenu[] = "context-menu"; const char kMouseWheel[] = "wheel"; -const char kKeyDown[] = "key-down"; -const char kKeyUp[] = "key-up"; +const char kKeyDown[] = "down"; +const char kKeyUp[] = "up"; const char kChar[] = "char"; const char kMouseLeftButton[] = "left"; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index ee70080ae6..b47e801c41 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -113,12 +113,13 @@ const char kAppUserModelId[] = "app-user-model-id"; const char kOffScreenRender[] = "offscreen-render"; const char kModifiers[] = "modifiers"; -const char kKeyCode[] = "keycode"; +const char kKeyCode[] = "code"; +const char kNativeKeyCode[] = "native"; const char kMovementX[] = "movement-x"; const char kMovementY[] = "movement-y"; const char kClickCount[] = "click-count"; -const char kMouseEventType[] = "type"; +const char kEventType[] = "type"; const char kMouseEventButton[] = "button"; const char kMouseWheelPrecise[] = "precise"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 505305deb4..062ee68466 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -64,11 +64,12 @@ extern const char kOffScreenRender[]; extern const char kModifiers[]; extern const char kKeyCode[]; +extern const char kNativeKeyCode[]; extern const char kMovementX[]; extern const char kMovementY[]; extern const char kClickCount[]; -extern const char kMouseEventType[]; +extern const char kEventType[]; extern const char kMouseEventButton[]; extern const char kMouseWheelPrecise[]; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index f0b8abc279..217844897a 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -737,6 +737,61 @@ Returns whether the window is visible on all workspaces. Sets the offscreen rendering, if `true` the `frame-rendered` event will fire, when the frame changes. +### BrowserWindow.sendMouseEvent(options) + +Sends a mouse event to the BrowserWindow. +* `options` Object + * `type` String - The type of the mouse event. + * `down` String - Mouse down event. + * `up` String - Mouse up event. + * `move` String - Mouse move event. + * `enter` String - Mouse enter event. + * `leave` String - Mouse leave event. + * `context-menu` String - Context menu event. + * `wheel` String - Mouse wheel event. + * `x` Integer - The x component of the location of the mouse event. + * `y` Integer - The y component of the location of the mouse event. + * `movement-x` Integer - The x component of the mouse movement since the last event. + * `movement-y` Integer - The y component of the mouse movement since the last event. + * `button` String - The mouse button associated with the mouse event. Also sets the associated modifier values on the event. + * `left` String - The left button was pressed. + * `right` String - The right button was pressed. + * `middle` String - The middle button was pressed. + * `click-count` Integer - The number of clicks associated with the mouse event. + * `precise` Boolean - For the `wheel` event type, this option sets the `hasPreciseScrollingDeltas` option of the event. + * `modifiers` Array of Strings - The modifier values associated with the event. + * `left-button-down` String - The left mouse button was pressed. + * `middle-button-down` String - The right mouse button was pressed. + * `right-button-down` String - The middle mouse button was pressed. + * `shift` String - The shift key was pressed. + * `control` String - The control key was pressed. + * `alt` String - The alt key was pressed. + * `meta` String - The meta key was pressed. + * `caps-lock` String - The caps-lock key was pressed. + * `num-lock` String - The num-lock key was pressed. + +### BrowserWindow.sendKeyboardEvent(options) + +Sends a keyboard event to the BrowserWindow. +* `options` Object + * `type` String - The type of the keyboard event. + * `down` String - Key down event. + * `up` String - Key up event. + * `char` String - Character event. + * `code` Integer - The key code of the key that generated the event. + * `native` Integer - The native key code of the key that generated the event. + * `modifiers` Array of Strings - The modifier values associated with the event. + * `keypad` String - Sets the `IsKeyPad` option of the event. + * `auto-repeat` String - Sets the `IsAutoRepeat` option of the event. + * `left` String - Sets the `IsLeft` option of the event. + * `right` String - Sets the `IsRight` option of the event. + * `shift` String - The shift key was pressed. + * `control` String - The control key was pressed. + * `alt` String - The alt key was pressed. + * `meta` String - The meta key was pressed. + * `caps-lock` String - The caps-lock key was pressed. + * `num-lock` String - The num-lock key was pressed. + ## Class: WebContents A `WebContents` is responsible for rendering and controlling a web page. From b2af3702497c487cd7d5a8f94e50a585f9a0091b Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 10 Sep 2015 02:10:47 +0200 Subject: [PATCH 05/41] Changed StringArray options to regular js objects with boolean values for better readability from the js side --- atom/browser/api/atom_api_window.cc | 93 ++++++++++++----------------- atom/browser/native_window.h | 1 + atom/common/event_types.cc | 75 ++++++++++++++++++++++- atom/common/event_types.h | 6 +- docs/api/browser-window.md | 42 ++++++------- vendor/native_mate | 2 +- 6 files changed, 139 insertions(+), 80 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 3c523f8ccd..b9b592a283 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -528,10 +528,10 @@ void Window::SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& dat int keycode = 0; int native = 0; std::string type_str = ""; - std::vector modifier_array; + mate::Dictionary modifier_list = mate::Dictionary::CreateEmpty(isolate); data.Get(switches::kEventType, &type_str); - data.Get(switches::kModifiers, &modifier_array); + data.Get(switches::kModifiers, &modifier_list); data.Get(switches::kKeyCode, &keycode); data.Get(switches::kNativeKeyCode, &native); @@ -543,28 +543,22 @@ void Window::SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& dat type = blink::WebInputEvent::Type::Char; } - for(std::vector::iterator mod = modifier_array.begin(); mod != modifier_array.end(); ++mod) { - if(mod->compare(event_types::kModifierIsKeyPad) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::IsKeyPad; - }else if(mod->compare(event_types::kModifierIsAutoRepeat) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::IsAutoRepeat; - }else if(mod->compare(event_types::kModifierIsLeft) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::IsLeft; - }else if(mod->compare(event_types::kModifierIsRight) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::IsRight; - }else if(mod->compare(event_types::kModifierShiftKey) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::ShiftKey; - }else if(mod->compare(event_types::kModifierControlKey) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::ControlKey; - }else if(mod->compare(event_types::kModifierAltKey) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::AltKey; - }else if(mod->compare(event_types::kModifierMetaKey) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::MetaKey; - }else if(mod->compare(event_types::kModifierCapsLockOn) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::CapsLockOn; - }else if(mod->compare(event_types::kModifierNumLockOn) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::NumLockOn; - } + std::map modifier_types; + modifier_types[event_types::kModifierIsKeyPad] = false; + modifier_types[event_types::kModifierIsAutoRepeat] = false; + modifier_types[event_types::kModifierIsLeft] = false; + modifier_types[event_types::kModifierIsRight] = false; + modifier_types[event_types::kModifierShiftKey] = false; + modifier_types[event_types::kModifierControlKey] = false; + modifier_types[event_types::kModifierAltKey] = false; + modifier_types[event_types::kModifierMetaKey] = false; + modifier_types[event_types::kModifierCapsLockOn] = false; + modifier_types[event_types::kModifierNumLockOn] = false; + + for(std::map::iterator it = modifier_types.begin(); it != modifier_types.end(); ++it){ + modifier_list.Get(it->first,&(it->second)); + + if(it->second) modifiers = modifiers & event_types::modifierStrToWebModifier(it->first); } window_->SendKeyboardEvent(type, modifiers, keycode, native); @@ -574,7 +568,7 @@ void Window::SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data){ int x, y, movementX, movementY, clickCount; std::string type_str = ""; std::string button_str = ""; - std::vector modifier_array; + mate::Dictionary modifier_list = mate::Dictionary::CreateEmpty(isolate); blink::WebInputEvent::Type type = blink::WebInputEvent::Type::MouseMove; blink::WebMouseEvent::Button button = blink::WebMouseEvent::Button::ButtonNone; @@ -582,7 +576,7 @@ void Window::SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data){ data.Get(switches::kEventType, &type_str); data.Get(switches::kMouseEventButton, &button_str); - data.Get(switches::kModifiers, &modifier_array); + data.Get(switches::kModifiers, &modifier_list); if(type_str.compare(event_types::kMouseDown) == 0){ type = blink::WebInputEvent::Type::MouseDown; @@ -600,37 +594,24 @@ void Window::SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data){ type = blink::WebInputEvent::Type::MouseWheel; } - if(button_str.compare(event_types::kMouseLeftButton) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::LeftButtonDown; - button = blink::WebMouseEvent::Button::ButtonLeft; - }else if(button_str.compare(event_types::kMouseRightButton) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::RightButtonDown; - button = blink::WebMouseEvent::Button::ButtonRight; - }else if(button_str.compare(event_types::kMouseMiddleButton) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::MiddleButtonDown; - button = blink::WebMouseEvent::Button::ButtonMiddle; - } + std::map modifier_types; + modifier_types[event_types::kMouseLeftButton] = false; + modifier_types[event_types::kMouseRightButton] = false; + modifier_types[event_types::kMouseMiddleButton] = false; + modifier_types[event_types::kModifierLeftButtonDown] = false; + modifier_types[event_types::kModifierMiddleButtonDown] = false; + modifier_types[event_types::kModifierRightButtonDown] = false; + modifier_types[event_types::kModifierShiftKey] = false; + modifier_types[event_types::kModifierControlKey] = false; + modifier_types[event_types::kModifierAltKey] = false; + modifier_types[event_types::kModifierMetaKey] = false; + modifier_types[event_types::kModifierCapsLockOn] = false; + modifier_types[event_types::kModifierNumLockOn] = false; - for(std::vector::iterator mod = modifier_array.begin(); mod != modifier_array.end(); ++mod) { - if(mod->compare(event_types::kModifierLeftButtonDown) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::LeftButtonDown; - }else if(mod->compare(event_types::kModifierMiddleButtonDown) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::MiddleButtonDown; - }else if(mod->compare(event_types::kModifierRightButtonDown) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::RightButtonDown; - }else if(mod->compare(event_types::kModifierShiftKey) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::ShiftKey; - }else if(mod->compare(event_types::kModifierControlKey) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::ControlKey; - }else if(mod->compare(event_types::kModifierAltKey) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::AltKey; - }else if(mod->compare(event_types::kModifierMetaKey) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::MetaKey; - }else if(mod->compare(event_types::kModifierCapsLockOn) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::CapsLockOn; - }else if(mod->compare(event_types::kModifierNumLockOn) == 0){ - modifiers = modifiers & blink::WebInputEvent::Modifiers::NumLockOn; - } + for(std::map::iterator it = modifier_types.begin(); it != modifier_types.end(); ++it){ + modifier_list.Get(it->first,&(it->second)); + + if(it->second) modifiers = modifiers & event_types::modifierStrToWebModifier(it->first); } if(type == blink::WebInputEvent::Type::MouseWheel){ diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d361fcf696..7131894a1f 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -332,6 +332,7 @@ class NativeWindow : public content::WebContentsObserver, DISALLOW_COPY_AND_ASSIGN(NativeWindow); }; +//This class provides a way to listen to frame renders and to use the rendered frames for offscreen rendering class RenderSubscriber : public content::RenderWidgetHostViewFrameSubscriber { public: RenderSubscriber(gfx::Size size, base::Callback)> callback) : size_(size), callback_(callback) {} diff --git a/atom/common/event_types.cc b/atom/common/event_types.cc index 3d3b901ed3..be08481289 100644 --- a/atom/common/event_types.cc +++ b/atom/common/event_types.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "atom/common/event_types.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" namespace atom { @@ -40,6 +41,78 @@ const char kModifierIsAutoRepeat[] = "auto-repeat"; const char kModifierIsLeft[] = "left"; const char kModifierIsRight[] = "right"; -} // namespace switches +int modifierStrToWebModifier(std::string modifier){ + if(modifier.compare(event_types::kModifierLeftButtonDown) == 0){ + + return blink::WebInputEvent::Modifiers::LeftButtonDown; + + }else if(modifier.compare(event_types::kModifierMiddleButtonDown) == 0){ + + return blink::WebInputEvent::Modifiers::MiddleButtonDown; + + }else if(modifier.compare(event_types::kModifierRightButtonDown) == 0){ + + return blink::WebInputEvent::Modifiers::RightButtonDown; + + }else if(modifier.compare(event_types::kMouseLeftButton) == 0){ + + return blink::WebInputEvent::Modifiers::LeftButtonDown; + + }else if(modifier.compare(event_types::kMouseRightButton) == 0){ + + return blink::WebInputEvent::Modifiers::RightButtonDown; + + }else if(modifier.compare(event_types::kMouseMiddleButton) == 0){ + + return blink::WebInputEvent::Modifiers::MiddleButtonDown; + + }else if(modifier.compare(event_types::kModifierIsKeyPad) == 0){ + + return blink::WebInputEvent::Modifiers::IsKeyPad; + + }else if(modifier.compare(event_types::kModifierIsAutoRepeat) == 0){ + + return blink::WebInputEvent::Modifiers::IsAutoRepeat; + + }else if(modifier.compare(event_types::kModifierIsLeft) == 0){ + + return blink::WebInputEvent::Modifiers::IsLeft; + + }else if(modifier.compare(event_types::kModifierIsRight) == 0){ + + return blink::WebInputEvent::Modifiers::IsRight; + + }else if(modifier.compare(event_types::kModifierShiftKey) == 0){ + + return blink::WebInputEvent::Modifiers::ShiftKey; + + }else if(modifier.compare(event_types::kModifierControlKey) == 0){ + + return blink::WebInputEvent::Modifiers::ControlKey; + + }else if(modifier.compare(event_types::kModifierAltKey) == 0){ + + return blink::WebInputEvent::Modifiers::AltKey; + + }else if(modifier.compare(event_types::kModifierMetaKey) == 0){ + + return blink::WebInputEvent::Modifiers::MetaKey; + + }else if(modifier.compare(event_types::kModifierCapsLockOn) == 0){ + + return blink::WebInputEvent::Modifiers::CapsLockOn; + + }else if(modifier.compare(event_types::kModifierNumLockOn) == 0){ + + return blink::WebInputEvent::Modifiers::NumLockOn; + + }else{ + + return 0; + + } +} + +} // namespace event_types } // namespace atom diff --git a/atom/common/event_types.h b/atom/common/event_types.h index b7eae781fc..d4769db2d7 100644 --- a/atom/common/event_types.h +++ b/atom/common/event_types.h @@ -5,6 +5,8 @@ #ifndef ATOM_COMMON_EVENT_TYPES_H_ #define ATOM_COMMON_EVENT_TYPES_H_ +#include "third_party/WebKit/public/web/WebInputEvent.h" + namespace atom { namespace event_types { @@ -41,7 +43,9 @@ extern const char kModifierIsAutoRepeat[]; extern const char kModifierIsLeft[]; extern const char kModifierIsRight[]; -} // namespace switches +int modifierStrToWebModifier(std::string modifier); + +} // namespace event_types } // namespace atom diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 217844897a..09d38bc9ad 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -759,16 +759,16 @@ Sends a mouse event to the BrowserWindow. * `middle` String - The middle button was pressed. * `click-count` Integer - The number of clicks associated with the mouse event. * `precise` Boolean - For the `wheel` event type, this option sets the `hasPreciseScrollingDeltas` option of the event. - * `modifiers` Array of Strings - The modifier values associated with the event. - * `left-button-down` String - The left mouse button was pressed. - * `middle-button-down` String - The right mouse button was pressed. - * `right-button-down` String - The middle mouse button was pressed. - * `shift` String - The shift key was pressed. - * `control` String - The control key was pressed. - * `alt` String - The alt key was pressed. - * `meta` String - The meta key was pressed. - * `caps-lock` String - The caps-lock key was pressed. - * `num-lock` String - The num-lock key was pressed. + * `modifiers` Object - The modifier values associated with the event. + * `left-button-down` Boolean - The left mouse button was pressed. + * `middle-button-down` Boolean - The right mouse button was pressed. + * `right-button-down` Boolean - The middle mouse button was pressed. + * `shift` Boolean - The shift key was pressed. + * `control` Boolean - The control key was pressed. + * `alt` Boolean - The alt key was pressed. + * `meta` Boolean - The meta key was pressed. + * `caps-lock` Boolean - The caps-lock key was on. + * `num-lock` Boolean - The num-lock key was on. ### BrowserWindow.sendKeyboardEvent(options) @@ -780,17 +780,17 @@ Sends a keyboard event to the BrowserWindow. * `char` String - Character event. * `code` Integer - The key code of the key that generated the event. * `native` Integer - The native key code of the key that generated the event. - * `modifiers` Array of Strings - The modifier values associated with the event. - * `keypad` String - Sets the `IsKeyPad` option of the event. - * `auto-repeat` String - Sets the `IsAutoRepeat` option of the event. - * `left` String - Sets the `IsLeft` option of the event. - * `right` String - Sets the `IsRight` option of the event. - * `shift` String - The shift key was pressed. - * `control` String - The control key was pressed. - * `alt` String - The alt key was pressed. - * `meta` String - The meta key was pressed. - * `caps-lock` String - The caps-lock key was pressed. - * `num-lock` String - The num-lock key was pressed. + * `modifiers` Object - The modifier values associated with the event. + * `keypad` Boolean - Sets the `IsKeyPad` option of the event. + * `auto-repeat` Boolean - Sets the `IsAutoRepeat` option of the event. + * `left` Boolean - Sets the `IsLeft` option of the event. + * `right` Boolean - Sets the `IsRight` option of the event. + * `shift` Boolean - The shift key was pressed. + * `control` Boolean - The control key was pressed. + * `alt` Boolean - The alt key was pressed. + * `meta` Boolean - The meta key was pressed. + * `caps-lock` Boolean - The caps-lock key was on. + * `num-lock` Boolean - The num-lock key was on. ## Class: WebContents diff --git a/vendor/native_mate b/vendor/native_mate index 31b6395d99..c71b1694e5 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 31b6395d9938558ea39a77ef2f432beaf2dcd4cb +Subproject commit c71b1694e51fe62f646a0e92e39329d8ab569d5c From f807a8f1e715ca7879d55277494a7e47c1399630 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 10 Sep 2015 02:16:41 +0200 Subject: [PATCH 06/41] Reset native-mate to the original repo --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index a3afcef28c..c6e53ed39a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ url = https://github.com/atom/chromium-breakpad.git [submodule "vendor/native_mate"] path = vendor/native_mate - url = https://github.com/brenca/native-mate.git + url = https://github.com/zcbenz/native-mate.git [submodule "vendor/crashpad"] path = vendor/crashpad url = https://github.com/atom/crashpad.git From 69769f9319cdad4ea07e76b1cfde7c3f73b4db39 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 10 Sep 2015 02:23:12 +0200 Subject: [PATCH 07/41] Resetting debug changes --- atom/app/atom_main.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/atom/app/atom_main.cc b/atom/app/atom_main.cc index 5677adb2ee..d782d15eb4 100644 --- a/atom/app/atom_main.cc +++ b/atom/app/atom_main.cc @@ -90,12 +90,9 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) { if (env->GetVar("OS", &os) && os != "cygwin") { AttachConsole(ATTACH_PARENT_PROCESS); - FILE* dontcare, *out, *err; - out = fopen("out.txt", "w"); - err = fopen("err.txt", "w"); - freopen_s(&out, "CON", "w", stdout); - freopen_s(&err, "CON", "w", stderr); - freopen_s(&dontcare, "CON", "r", stdin); + FILE* dontcare; + freopen_s(&dontcare, "CON", "w", stdout); + freopen_s(&dontcare, "CON", "w", stderr); } // Convert argv to to UTF8 From 1497e7e2ac93a98e84707bd1031ab82b833dc938 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 10 Sep 2015 02:24:08 +0200 Subject: [PATCH 08/41] Whoops, missed a line last time. --- atom/app/atom_main.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/app/atom_main.cc b/atom/app/atom_main.cc index d782d15eb4..47be348522 100644 --- a/atom/app/atom_main.cc +++ b/atom/app/atom_main.cc @@ -93,6 +93,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) { FILE* dontcare; freopen_s(&dontcare, "CON", "w", stdout); freopen_s(&dontcare, "CON", "w", stderr); + freopen_s(&dontcare, "CON", "r", stdin); } // Convert argv to to UTF8 From ceef06b344895edeb7d3770edcf64e387f0203f5 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 16 Sep 2015 02:59:16 +0200 Subject: [PATCH 09/41] Renamed setOffscreenRender to begin/endFrameSubscription because the name was a bit misleading, and replaced the ArrayBuffer creation with a node::Buffer::New call. --- atom/browser/api/atom_api_window.cc | 17 +++++++++++------ atom/browser/api/atom_api_window.h | 3 ++- atom/browser/native_window.cc | 4 ++-- atom/browser/native_window.h | 2 +- docs/api/browser-window.md | 14 ++++++++++---- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index b9b592a283..78d9376165 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -8,6 +8,7 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" #include "atom/browser/native_window.h" +#include "atom/common/node_includes.h" #include "atom/common/options_switches.h" #include "atom/common/event_types.h" #include "atom/common/native_mate_converters/callback.h" @@ -99,10 +100,9 @@ void Window::OnFrameRendered(scoped_ptr rgb, const int size) { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - v8::Local data = v8::ArrayBuffer::New(isolate(), rgb.get(), size); - v8::Local uint_data = v8::Uint8ClampedArray::New(data, 0, size); + auto data = node::Buffer::New(isolate(), reinterpret_cast(rgb.get()), static_cast(size)); - Emit("frame-rendered", uint_data, size); + Emit("frame-rendered", data, size); } void Window::OnWindowClosed() { @@ -442,8 +442,12 @@ void Window::CapturePage(mate::Arguments* args) { rect, base::Bind(&OnCapturePageDone, args->isolate(), callback)); } -void Window::SetOffscreenRender(bool isOffscreen) { - window_->SetOffscreenRender(isOffscreen); +void Window::BeginFrameSubscription() { + window_->SetFrameSubscription(true); +} + +void Window::EndFrameSubscription() { + window_->SetFrameSubscription(false); } void Window::SetProgressBar(double progress) { @@ -728,7 +732,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, &Window::IsVisibleOnAllWorkspaces) .SetMethod("sendMouseEvent", &Window::SendMouseEvent) .SetMethod("sendKeyboardEvent", &Window::SendKeyboardEvent) - .SetMethod("setOffscreenRender", &Window::SetOffscreenRender) + .SetMethod("beginFrameSubscription", &Window::BeginFrameSubscription) + .SetMethod("endFrameSubscription", &Window::EndFrameSubscription) #if defined(OS_MACOSX) .SetMethod("showDefinitionForSelection", &Window::ShowDefinitionForSelection) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 727cacd3d6..b5125f9c1f 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -141,7 +141,8 @@ class Window : public mate::TrackableObject, void SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& data); void SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data); - void SetOffscreenRender(bool isOffscreen); + void BeginFrameSubscription(); + void EndFrameSubscription(); #if defined(OS_MACOSX) void ShowDefinitionForSelection(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index a9e0631489..e8a4c5a9ea 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -333,7 +333,7 @@ void NativeWindow::CapturePage(const gfx::Rect& rect, kBGRA_8888_SkColorType); } -void NativeWindow::SetOffscreenRender(bool isOffscreen) { +void NativeWindow::SetFrameSubscription(bool isOffscreen) { if (!isOffscreen && !offscreen_) return; const auto view = web_contents()->GetRenderWidgetHostView(); @@ -637,7 +637,7 @@ void NativeWindow::SendMouseWheelEvent(int modifiers, int x, int y, bool precise } void NativeWindow::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { - SetOffscreenRender(offscreen_); + SetFrameSubscription(offscreen_); } void NativeWindow::RenderViewCreated( diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 7131894a1f..f439962e7c 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -242,7 +242,7 @@ class NativeWindow : public content::WebContentsObserver, void SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount); void SendMouseWheelEvent(int modifiers, int x, int y, bool clickCount); - void SetOffscreenRender(bool isOffscreen); + void SetFrameSubscription(bool isOffscreen); protected: NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 09d38bc9ad..c338f24707 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -75,7 +75,8 @@ You can also create a window without chrome by using * `standard-window` Boolean - Uses the OS X's standard window instead of the textured window. Defaults to `true`. * `offscreen-render` Boolean - The frame of the window will be accessible - through the `frame-rendered` event in a buffer. Defaults to `false`. + through the `frame-rendered` event in a buffer (Uint8, BGRA). Defaults to + `false`. * `web-preferences` Object - Settings of web page's features * `javascript` Boolean * `web-security` Boolean - When setting `false`, it will disable the same-origin @@ -732,10 +733,15 @@ Returns whether the window is visible on all workspaces. **Note:** This API always returns false on Windows. -### BrowserWindow.setOffscreenRender(isOffscreen) +### BrowserWindow.beginFrameSubscription() -Sets the offscreen rendering, if `true` the `frame-rendered` event will fire, -when the frame changes. +Enables offscreen rendering, after this call `frame-rendered` events will be +fired when the window receives a new frame from the renderer. + +### BrowserWindow.endFrameSubscription() + +Enables offscreen rendering, after this call `frame-rendered` events will +no longer be fired if offscreen rendering was enabled before. ### BrowserWindow.sendMouseEvent(options) From 5269380b6d7551b1c7da83639849111cfefbde00 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 16 Sep 2015 03:12:49 +0200 Subject: [PATCH 10/41] Removed duplicate keydown event sending. --- atom/browser/native_window.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index e8a4c5a9ea..19120da07a 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -592,12 +592,8 @@ void NativeWindow::SendKeyboardEvent(blink::WebInputEvent::Type type, int modifi const auto view = web_contents()->GetRenderWidgetHostView(); const auto host = view ? view->GetRenderWidgetHost() : nullptr; - host->ForwardKeyboardEvent(*keyb_event); - if(keyb_event->type == blink::WebInputEvent::Type::KeyDown){ - keyb_event->type = blink::WebInputEvent::RawKeyDown; - host->ForwardKeyboardEvent(*keyb_event); - } + host->ForwardKeyboardEvent(*keyb_event); } void NativeWindow::SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount){ From 90064eeddda903f6fd554e2c484e1ec5a86a1e8a Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 16 Sep 2015 03:29:23 +0200 Subject: [PATCH 11/41] Returning to original native_mate. --- vendor/native_mate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/native_mate b/vendor/native_mate index c71b1694e5..b7387da085 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit c71b1694e51fe62f646a0e92e39329d8ab569d5c +Subproject commit b7387da0854b20d376fdae0d93a01f83d080668d From 9fd5a64cd8f853d12a6fdf594f3ce3ad278041ab Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 11:25:27 +0800 Subject: [PATCH 12/41] Update brightray to unsubscribe from NSNotificationCenter --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index d385c9b1b8..f103af2f6b 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit d385c9b1b88da3ba1b5426861ec7c63e8c884135 +Subproject commit f103af2f6bb38bb4ceeabd8688d8dee87ccefca1 From e3c64d79716fa40e000827355d3d2d6f744554ee Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 11:30:17 +0800 Subject: [PATCH 13/41] Release the native window after window gets closed Previously we delete the window after the JS object gets garbage collected, which is too late for releasing some resources. --- atom/browser/api/atom_api_window.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 1a76c3e5f0..3503fb4eb0 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -116,6 +116,9 @@ void Window::OnWindowClosed() { window_->RemoveObserver(this); Emit("closed"); + + // Clean up the resources after window has been closed. + base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release()); } void Window::OnWindowBlur() { From e73c655d653b59f139f02b49c3a6d2224049ce14 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 11:32:19 +0800 Subject: [PATCH 14/41] No need to delete window in Destory The native window is now automatically deleted after it gets closed. --- atom/browser/api/atom_api_window.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 3503fb4eb0..4c82ef1fad 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -223,10 +223,8 @@ bool Window::IsDestroyed() const { } void Window::Destroy() { - if (window_) { + if (window_) window_->CloseContents(nullptr); - window_.reset(); - } } void Window::Close() { From e30dd943dbf105e25108d96a0322a941c5d1cfeb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 15:01:33 +0800 Subject: [PATCH 15/41] Update brightray for #2808 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index f103af2f6b..25f3a9d0a5 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit f103af2f6bb38bb4ceeabd8688d8dee87ccefca1 +Subproject commit 25f3a9d0a5b73ec170a65f4e2e4c9ad91e23fc8c From 93639a080c22974b71e5f9992c6b7c976035587f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 15:12:15 +0800 Subject: [PATCH 16/41] spec: setImmediate should work in forked scripts --- spec/fixtures/module/set-immediate.js | 11 +++++++++++ spec/node-spec.coffee | 7 +++++++ 2 files changed, 18 insertions(+) create mode 100644 spec/fixtures/module/set-immediate.js diff --git a/spec/fixtures/module/set-immediate.js b/spec/fixtures/module/set-immediate.js new file mode 100644 index 0000000000..e7d44a75d1 --- /dev/null +++ b/spec/fixtures/module/set-immediate.js @@ -0,0 +1,11 @@ +process.on('uncaughtException', function(error) { + process.send(error.message); + process.exit(1); +}); + +process.on('message', function(msg) { + setImmediate(function() { + process.send('ok'); + process.exit(0); + }); +}); diff --git a/spec/node-spec.coffee b/spec/node-spec.coffee index 94174c38b7..f998a8c5b7 100644 --- a/spec/node-spec.coffee +++ b/spec/node-spec.coffee @@ -56,6 +56,13 @@ describe 'node feature', -> done() child.send 'message' + it 'has setImmediate working in script', (done) -> + child = child_process.fork path.join(fixtures, 'module', 'set-immediate.js') + child.on 'message', (msg) -> + assert.equal msg, 'ok' + done() + child.send 'message' + describe 'contexts', -> describe 'setTimeout in fs callback', -> it 'does not crash', (done) -> From 5604655d547b13532efcf1aeb36863f4f57e90cf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 16:06:19 +0800 Subject: [PATCH 17/41] spec: vm.createContext should not crash --- spec/node-spec.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/node-spec.coffee b/spec/node-spec.coffee index f998a8c5b7..c8d569e01a 100644 --- a/spec/node-spec.coffee +++ b/spec/node-spec.coffee @@ -148,3 +148,7 @@ describe 'node feature', -> # Not reliable on some machines xit 'should have isTTY defined', -> assert.equal typeof(process.stdout.isTTY), 'boolean' + + describe 'vm.createContext', -> + it 'should not crash', -> + require('vm').runInNewContext('') From 2be6bdcf4a0c6927f4e7e32f754072ca6eab2d5c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 16:06:35 +0800 Subject: [PATCH 18/41] Update to node v4.1.0 --- vendor/node | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/node b/vendor/node index 4098d45fbb..aa9c7a2316 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit 4098d45fbb822370c19d2fe7b88162759db4eb96 +Subproject commit aa9c7a2316ba7762f1d04d091585695be3e6be22 From d28789b5098ad9797b888c804da026487c380a58 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 16:11:14 +0800 Subject: [PATCH 19/41] Change version to v0.32.4 This makes sure the native modules are built against the headers of v0.32.4, since Node.js v4.1.0 has bumped the module version. --- atom.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom.gyp b/atom.gyp index 63defa4273..b49f3ac64b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.32.3', + 'version%': '0.32.4', }, 'includes': [ 'filenames.gypi', From 01ed2c4222bf77c2592dcd234d8c99a8636497cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionic=C4=83=20Biz=C4=83u?= Date: Thu, 17 Sep 2015 12:24:12 +0300 Subject: [PATCH 20/41] Fixed the mapNumbers require call Since mapNumber.js is a file, we should prefix it with "./", otherwise an error is thrown. --- docs/api/remote.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/remote.md b/docs/api/remote.md index 1c5c831a17..55893c65f1 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -79,7 +79,7 @@ exports.withLocalCallback = function() { ```javascript // renderer process -var mapNumbers = require("remote").require("mapNumbers"); +var mapNumbers = require("remote").require("./mapNumbers"); var withRendererCb = mapNumbers.withRendererCallback(function(x) { return x + 1; From a46cb8cebb432d6d80ce24b7dbe1c47ed396bbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionic=C4=83=20Biz=C4=83u?= Date: Thu, 17 Sep 2015 12:34:15 +0300 Subject: [PATCH 21/41] Fix the git commit messages hash link --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 516f6289ac..6ca3ea5d2f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ possible with your report. If you can, please include: * Follow the CoffeeScript, JavaScript, C++ and Python [coding style defined in docs](/docs/development/coding-style.md). * Write documentation in [Markdown](https://daringfireball.net/projects/markdown). See the [Documentation Styleguide](/docs/styleguide.md). -* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages-styleguide). +* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages). ## Styleguides From 1348e18a81706c7764f5b5543baf0f6409a78cd4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Sep 2015 18:31:12 +0800 Subject: [PATCH 22/41] Bump v0.33.0 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/atom.gyp b/atom.gyp index b49f3ac64b..c9d5f92478 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.32.4', + 'version%': '0.33.0', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index dd4e610d91..54ba3546a7 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.32.3 + 0.33.0 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index cf894f6b5c..8863d8be76 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,32,3,0 - PRODUCTVERSION 0,32,3,0 + FILEVERSION 0,33,0,0 + PRODUCTVERSION 0,33,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.32.3" + VALUE "FileVersion", "0.33.0" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.32.3" + VALUE "ProductVersion", "0.33.0" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 8d71e91505..deb0958543 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,8 +6,8 @@ #define ATOM_VERSION_H #define ATOM_MAJOR_VERSION 0 -#define ATOM_MINOR_VERSION 32 -#define ATOM_PATCH_VERSION 3 +#define ATOM_MINOR_VERSION 33 +#define ATOM_PATCH_VERSION 0 #define ATOM_VERSION_IS_RELEASE 1 From 6b875110ed8b20c0da142c56b96d0d61b1564c3b Mon Sep 17 00:00:00 2001 From: Gohy Leandre Date: Mon, 31 Aug 2015 11:19:19 +0200 Subject: [PATCH 23/41] Add device emulation API --- atom/browser/api/atom_api_web_contents.cc | 88 +++++++++++++++++++++++ atom/browser/api/atom_api_web_contents.h | 2 + docs/api/web-contents.md | 35 +++++++++ 3 files changed, 125 insertions(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a24200e5a8..2231a591f7 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -27,6 +27,7 @@ #include "brightray/browser/inspectable_web_contents.h" #include "chrome/browser/printing/print_view_manager_basic.h" #include "chrome/browser/printing/print_preview_message_handler.h" +#include "content/common/view_messages.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" @@ -44,6 +45,7 @@ #include "net/http/http_response_headers.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" +#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" #include "atom/common/node_includes.h" @@ -640,6 +642,88 @@ bool WebContents::IsDevToolsOpened() { return managed_web_contents()->IsDevToolsViewShowing(); } +void WebContents::EnableDeviceEmulation(const base::DictionaryValue& dict) { + if (type_ == REMOTE) + return; + + blink::WebDeviceEmulationParams params; + + if (dict.HasKey("screenPosition")) { + std::string screen_position; + if (!dict.GetString("screenPosition", &screen_position)) + return; + + screen_position = base::StringToLowerASCII(screen_position); + + if (screen_position == "mobile") { + params.screenPosition = blink::WebDeviceEmulationParams::Mobile; + } else if (screen_position == "desktop") { + params.screenPosition = blink::WebDeviceEmulationParams::Desktop; + } else { + return; + } + } + + if (dict.HasKey("screenSize")) { + if (!dict.GetInteger("screenSize.width", ¶ms.screenSize.width)) + return; + if (!dict.GetInteger("screenSize.height", ¶ms.screenSize.height)) + return; + } + + if (dict.HasKey("viewPosition")) { + if (!dict.GetInteger("viewPosition.x", ¶ms.viewPosition.x)) + return; + if (!dict.GetInteger("viewPosition.y", ¶ms.viewPosition.y)) + return; + } + + if (dict.HasKey("deviceScaleFactor")) { + double device_scale_factor; + if (!dict.GetDouble("deviceScaleFactor", &device_scale_factor)) + return; + params.deviceScaleFactor = static_cast(device_scale_factor); + } + + if (dict.HasKey("viewSize")) { + if (!dict.GetInteger("viewSize.width", ¶ms.viewSize.width)) + return; + if (!dict.GetInteger("viewSize.height", ¶ms.viewSize.height)) + return; + } + + if (dict.HasKey("fitToView")) { + if (!dict.GetBoolean("fitToView", ¶ms.fitToView)) + return; + } + + if (dict.HasKey("offset")) { + double x, y; + if (!dict.GetDouble("offset.x", &x)) + return; + if (!dict.GetDouble("offset.y", &y)) + return; + params.offset.x = static_cast(x); + params.offset.y = static_cast(y); + } + + if (dict.HasKey("scale")) { + double scale; + if (!dict.GetDouble("scale", &scale)) + return; + params.scale = static_cast(scale); + } + + Send(new ViewMsg_EnableDeviceEmulation(routing_id(), params)); +} + +void WebContents::DisableDeviceEmulation() { + if (type_ == REMOTE) + return; + + Send(new ViewMsg_DisableDeviceEmulation(routing_id())); +} + void WebContents::ToggleDevTools() { if (IsDevToolsOpened()) CloseDevTools(); @@ -836,6 +920,10 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("openDevTools", &WebContents::OpenDevTools) .SetMethod("closeDevTools", &WebContents::CloseDevTools) .SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened) + .SetMethod("enableDeviceEmulation", + &WebContents::EnableDeviceEmulation) + .SetMethod("disableDeviceEmulation", + &WebContents::DisableDeviceEmulation) .SetMethod("toggleDevTools", &WebContents::ToggleDevTools) .SetMethod("inspectElement", &WebContents::InspectElement) .SetMethod("setAudioMuted", &WebContents::SetAudioMuted) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 0001d3e8ef..c765e5cbf4 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -74,6 +74,8 @@ class WebContents : public mate::TrackableObject, void CloseDevTools(); bool IsDevToolsOpened(); void ToggleDevTools(); + void EnableDeviceEmulation(const base::DictionaryValue&); + void DisableDeviceEmulation(); void InspectElement(int x, int y); void InspectServiceWorker(); v8::Local Session(v8::Isolate* isolate); diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 92d91d170e..8b4ebcc337 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -476,3 +476,38 @@ app.on('ready', function() { which is different from the handlers in the main process. 2. There is no way to send synchronous messages from the main process to a renderer process, because it would be very easy to cause dead locks. + +### `webContents.enableDeviceEmulation(parameters)` + +`parameters` Object, properties: + +* `screenPosition` String - Specify the screen type to emulate + (default: `desktop`) + * `desktop` + * `mobile` +* `screenSize` Object - Set the emulated screen size (screenPosition == mobile) + * `width` Integer - Set the emulated screen width + * `height` Integer - Set the emulated screen height +* `viewPosition` Object - Position the view on the screen + (screenPosition == mobile) (default: `{x: 0, y: 0}`) + * `x` Integer - Set the x axis offset from top left corner + * `y` Integer - Set the y axis offset from top left corner +* `deviceScaleFactor` Integer - Set the device scale factor (if zero defaults to + original device scale factor) (default: `0`) +* `viewSize` Object - Set the emulated view size (empty means no override) + * `width` Integer - Set the emulated view width + * `height` Integer - Set the emulated view height +* `fitToView` Boolean - Whether emulated view should be scaled down if + necessary to fit into available space (default: `false`) +* `offset` Object - Offset of the emulated view inside available space (not in + fit to view mode) (default: `{x: 0, y: 0}`) + * `x` Float - Set the x axis offset from top left corner + * `y` Float - Set the y axis offset from top left corner +* `scale` Float - Scale of emulated view inside available space (not in fit to + view mode) (default: `1`) + +Enable device emulation with the given parameters. + +### `webContents.disableDeviceEmulation()` + +Disable device emulation enabled by `webContents.enableDeviceEmulation`. From 7dc7ee1c4195351eee08d0fe5cef172c3c201a0f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 11:06:38 +0800 Subject: [PATCH 24/41] Move the converters for blink structures to another file It makes the api::WebContents smaller. --- atom/browser/api/atom_api_web_contents.cc | 73 +------------------ atom/browser/api/atom_api_web_contents.h | 6 +- .../native_mate_converters/blink_converter.cc | 65 +++++++++++++++++ .../native_mate_converters/blink_converter.h | 45 ++++++++++++ filenames.gypi | 2 + 5 files changed, 120 insertions(+), 71 deletions(-) create mode 100644 atom/common/native_mate_converters/blink_converter.cc create mode 100644 atom/common/native_mate_converters/blink_converter.h diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 2231a591f7..d4cb6cd227 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -15,6 +15,7 @@ #include "atom/browser/web_view_guest_delegate.h" #include "atom/common/api/api_messages.h" #include "atom/common/api/event_emitter_caller.h" +#include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h" @@ -45,7 +46,6 @@ #include "net/http/http_response_headers.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" -#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" #include "atom/common/node_includes.h" @@ -642,78 +642,11 @@ bool WebContents::IsDevToolsOpened() { return managed_web_contents()->IsDevToolsViewShowing(); } -void WebContents::EnableDeviceEmulation(const base::DictionaryValue& dict) { +void WebContents::EnableDeviceEmulation( + const blink::WebDeviceEmulationParams& params) { if (type_ == REMOTE) return; - blink::WebDeviceEmulationParams params; - - if (dict.HasKey("screenPosition")) { - std::string screen_position; - if (!dict.GetString("screenPosition", &screen_position)) - return; - - screen_position = base::StringToLowerASCII(screen_position); - - if (screen_position == "mobile") { - params.screenPosition = blink::WebDeviceEmulationParams::Mobile; - } else if (screen_position == "desktop") { - params.screenPosition = blink::WebDeviceEmulationParams::Desktop; - } else { - return; - } - } - - if (dict.HasKey("screenSize")) { - if (!dict.GetInteger("screenSize.width", ¶ms.screenSize.width)) - return; - if (!dict.GetInteger("screenSize.height", ¶ms.screenSize.height)) - return; - } - - if (dict.HasKey("viewPosition")) { - if (!dict.GetInteger("viewPosition.x", ¶ms.viewPosition.x)) - return; - if (!dict.GetInteger("viewPosition.y", ¶ms.viewPosition.y)) - return; - } - - if (dict.HasKey("deviceScaleFactor")) { - double device_scale_factor; - if (!dict.GetDouble("deviceScaleFactor", &device_scale_factor)) - return; - params.deviceScaleFactor = static_cast(device_scale_factor); - } - - if (dict.HasKey("viewSize")) { - if (!dict.GetInteger("viewSize.width", ¶ms.viewSize.width)) - return; - if (!dict.GetInteger("viewSize.height", ¶ms.viewSize.height)) - return; - } - - if (dict.HasKey("fitToView")) { - if (!dict.GetBoolean("fitToView", ¶ms.fitToView)) - return; - } - - if (dict.HasKey("offset")) { - double x, y; - if (!dict.GetDouble("offset.x", &x)) - return; - if (!dict.GetDouble("offset.y", &y)) - return; - params.offset.x = static_cast(x); - params.offset.y = static_cast(y); - } - - if (dict.HasKey("scale")) { - double scale; - if (!dict.GetDouble("scale", &scale)) - return; - params.scale = static_cast(scale); - } - Send(new ViewMsg_EnableDeviceEmulation(routing_id(), params)); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index c765e5cbf4..0ce47237e4 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -15,6 +15,10 @@ #include "native_mate/handle.h" #include "ui/gfx/image/image.h" +namespace blink { +struct WebDeviceEmulationParams; +} + namespace brightray { class InspectableWebContents; } @@ -74,7 +78,7 @@ class WebContents : public mate::TrackableObject, void CloseDevTools(); bool IsDevToolsOpened(); void ToggleDevTools(); - void EnableDeviceEmulation(const base::DictionaryValue&); + void EnableDeviceEmulation(const blink::WebDeviceEmulationParams& params); void DisableDeviceEmulation(); void InspectElement(int x, int y); void InspectServiceWorker(); diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc new file mode 100644 index 0000000000..9225f54838 --- /dev/null +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -0,0 +1,65 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/native_mate_converters/blink_converter.h" + +#include "base/strings/string_util.h" +#include "native_mate/dictionary.h" +#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" + +namespace mate { + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, blink::WebFloatPoint* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + return dict.Get("x", &out->x) && dict.Get("y", &out->y); +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, blink::WebPoint* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + return dict.Get("x", &out->x) && dict.Get("y", &out->y); +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, blink::WebSize* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + return dict.Get("width", &out->width) && dict.Get("height", &out->height); +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + blink::WebDeviceEmulationParams* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + + std::string screen_position; + if (dict.Get("screenPosition", &screen_position)) { + screen_position = base::StringToLowerASCII(screen_position); + if (screen_position == "mobile") + out->screenPosition = blink::WebDeviceEmulationParams::Mobile; + else if (screen_position == "desktop") + out->screenPosition = blink::WebDeviceEmulationParams::Desktop; + else + return false; + } + + dict.Get("screenSize", &out->screenSize); + dict.Get("viewPosition", &out->viewPosition); + dict.Get("deviceScaleFactor", &out->deviceScaleFactor); + dict.Get("viewSize", &out->viewSize); + dict.Get("fitToView", &out->fitToView); + dict.Get("offset", &out->offset); + dict.Get("scale", &out->scale); + return true; +} + +} // namespace mate diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h new file mode 100644 index 0000000000..bbd2af0e67 --- /dev/null +++ b/atom/common/native_mate_converters/blink_converter.h @@ -0,0 +1,45 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ +#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ + +#include "native_mate/converter.h" + +namespace blink { +struct WebDeviceEmulationParams; +struct WebFloatPoint; +struct WebPoint; +struct WebSize; +} + +namespace mate { + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebFloatPoint* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebPoint* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebSize* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebDeviceEmulationParams* out); +}; + +} // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ diff --git a/filenames.gypi b/filenames.gypi index 461c812753..ce67964033 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -286,6 +286,8 @@ 'atom/common/linux/application_info.cc', 'atom/common/native_mate_converters/accelerator_converter.cc', 'atom/common/native_mate_converters/accelerator_converter.h', + 'atom/common/native_mate_converters/blink_converter.cc', + 'atom/common/native_mate_converters/blink_converter.h', 'atom/common/native_mate_converters/callback.h', 'atom/common/native_mate_converters/file_path_converter.h', 'atom/common/native_mate_converters/gfx_converter.cc', From 5aa7cf7a3021c19dc30af3505b1f975a89934978 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 11:10:32 +0800 Subject: [PATCH 25/41] Fix cpplint warning --- atom/common/native_mate_converters/blink_converter.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index 9225f54838..5d3ff62086 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -4,6 +4,8 @@ #include "atom/common/native_mate_converters/blink_converter.h" +#include + #include "base/strings/string_util.h" #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" From ec90d03d74102133d62a1e24155580338bdb36dd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 12:10:00 +0800 Subject: [PATCH 26/41] Fix compilation error --- atom/browser/api/atom_api_window.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 6d6316d913..b8d2c463eb 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -9,7 +9,6 @@ #include "atom/browser/browser.h" #include "atom/browser/native_window.h" #include "atom/common/node_includes.h" -#include "atom/common/options_switches.h" #include "atom/common/event_types.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" @@ -21,7 +20,6 @@ #include "native_mate/constructor.h" #include "native_mate/dictionary.h" #include "ui/gfx/geometry/rect.h" -#include "v8/include/v8.h" #if defined(OS_WIN) #include "atom/browser/native_window_views.h" @@ -112,10 +110,11 @@ void Window::WillCloseWindow(bool* prevent_default) { void Window::OnFrameRendered(scoped_ptr rgb, const int size) { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - - auto data = node::Buffer::New(isolate(), reinterpret_cast(rgb.get()), static_cast(size)); - - Emit("frame-rendered", data, size); + v8::MaybeLocal data = node::Buffer::New( + isolate(), + reinterpret_cast(rgb.release()), + static_cast(size)); + Emit("frame-rendered", data.ToLocalChecked(), size); } void Window::OnWindowClosed() { From d7bac5a10b252c17ffe060840ea26dd275005e76 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 12:15:13 +0800 Subject: [PATCH 27/41] Remove the offscreen-render option We are going to move the APIs to WebContents --- atom/browser/native_window.cc | 11 ----------- atom/browser/native_window.h | 3 --- atom/common/options_switches.cc | 2 -- atom/common/options_switches.h | 2 -- 4 files changed, 18 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index b88c37576d..9121f0cb88 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -167,9 +167,6 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { options.Get(switches::kTitle, &title); SetTitle(title); - offscreen_ = false; - options.Get(switches::kOffScreenRender, &offscreen_); - // Then show it. bool show = true; options.Get(switches::kShow, &show); @@ -297,8 +294,6 @@ void NativeWindow::CapturePage(const gfx::Rect& rect, } void NativeWindow::SetFrameSubscription(bool isOffscreen) { - if (!isOffscreen && !offscreen_) return; - const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { @@ -314,8 +309,6 @@ void NativeWindow::SetFrameSubscription(bool isOffscreen) { } else { view->EndFrameSubscription(); } - - offscreen_ = isOffscreen; } } @@ -520,10 +513,6 @@ void NativeWindow::SendMouseWheelEvent(int modifiers, int x, int y, bool precise host->ForwardWheelEvent(*wheel_event); } -void NativeWindow::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { - SetFrameSubscription(offscreen_); -} - void NativeWindow::RenderViewCreated( content::RenderViewHost* render_view_host) { if (!transparent_) diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index e7de4ebc65..5784743af8 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -246,7 +246,6 @@ class NativeWindow : public content::WebContentsObserver, // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; - void DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) override; void BeforeUnloadDialogCancelled() override; void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; bool OnMessageReceived(const IPC::Message& message) override; @@ -267,8 +266,6 @@ class NativeWindow : public content::WebContentsObserver, const SkBitmap& bitmap, content::ReadbackResponse response); - bool offscreen_; - // Whether window has standard frame. bool has_frame_; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 75688ec45b..2268a40395 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -116,8 +116,6 @@ const char kRegisterStandardSchemes[] = "register-standard-schemes"; // The browser process app model ID const char kAppUserModelId[] = "app-user-model-id"; -const char kOffScreenRender[] = "offscreen-render"; - const char kModifiers[] = "modifiers"; const char kKeyCode[] = "code"; const char kNativeKeyCode[] = "native"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 6ce6d7f4ed..eb7842e787 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -62,8 +62,6 @@ extern const char kRegisterStandardSchemes[]; extern const char kAppUserModelId[]; -extern const char kOffScreenRender[]; - extern const char kModifiers[]; extern const char kKeyCode[]; extern const char kNativeKeyCode[]; From 84ce441fb6e7bd73d9ab404e5d81a390acd78f2f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 13:33:06 +0800 Subject: [PATCH 28/41] Add converters for WebInputEvent --- atom/browser/ui/accelerator_util.cc | 71 +------ atom/common/keyboad_util.cc | 73 +++++++ atom/common/keyboad_util.h | 18 ++ .../native_mate_converters/blink_converter.cc | 184 ++++++++++++++++++ .../native_mate_converters/blink_converter.h | 38 ++++ filenames.gypi | 2 + 6 files changed, 317 insertions(+), 69 deletions(-) create mode 100644 atom/common/keyboad_util.cc create mode 100644 atom/common/keyboad_util.h diff --git a/atom/browser/ui/accelerator_util.cc b/atom/browser/ui/accelerator_util.cc index 41dde7acf7..e25e14b796 100644 --- a/atom/browser/ui/accelerator_util.cc +++ b/atom/browser/ui/accelerator_util.cc @@ -9,6 +9,7 @@ #include #include +#include "atom/common/keyboad_util.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -17,74 +18,6 @@ namespace accelerator_util { -namespace { - -// Return key code of the char. -ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted) { - *shifted = false; - switch (c) { - case 8: case 0x7F: return ui::VKEY_BACK; - case 9: return ui::VKEY_TAB; - case 0xD: case 3: return ui::VKEY_RETURN; - case 0x1B: return ui::VKEY_ESCAPE; - case ' ': return ui::VKEY_SPACE; - - case 'a': return ui::VKEY_A; - case 'b': return ui::VKEY_B; - case 'c': return ui::VKEY_C; - case 'd': return ui::VKEY_D; - case 'e': return ui::VKEY_E; - case 'f': return ui::VKEY_F; - case 'g': return ui::VKEY_G; - case 'h': return ui::VKEY_H; - case 'i': return ui::VKEY_I; - case 'j': return ui::VKEY_J; - case 'k': return ui::VKEY_K; - case 'l': return ui::VKEY_L; - case 'm': return ui::VKEY_M; - case 'n': return ui::VKEY_N; - case 'o': return ui::VKEY_O; - case 'p': return ui::VKEY_P; - case 'q': return ui::VKEY_Q; - case 'r': return ui::VKEY_R; - case 's': return ui::VKEY_S; - case 't': return ui::VKEY_T; - case 'u': return ui::VKEY_U; - case 'v': return ui::VKEY_V; - case 'w': return ui::VKEY_W; - case 'x': return ui::VKEY_X; - case 'y': return ui::VKEY_Y; - case 'z': return ui::VKEY_Z; - - case ')': *shifted = true; case '0': return ui::VKEY_0; - case '!': *shifted = true; case '1': return ui::VKEY_1; - case '@': *shifted = true; case '2': return ui::VKEY_2; - case '#': *shifted = true; case '3': return ui::VKEY_3; - case '$': *shifted = true; case '4': return ui::VKEY_4; - case '%': *shifted = true; case '5': return ui::VKEY_5; - case '^': *shifted = true; case '6': return ui::VKEY_6; - case '&': *shifted = true; case '7': return ui::VKEY_7; - case '*': *shifted = true; case '8': return ui::VKEY_8; - case '(': *shifted = true; case '9': return ui::VKEY_9; - - case ':': *shifted = true; case ';': return ui::VKEY_OEM_1; - case '+': *shifted = true; case '=': return ui::VKEY_OEM_PLUS; - case '<': *shifted = true; case ',': return ui::VKEY_OEM_COMMA; - case '_': *shifted = true; case '-': return ui::VKEY_OEM_MINUS; - case '>': *shifted = true; case '.': return ui::VKEY_OEM_PERIOD; - case '?': *shifted = true; case '/': return ui::VKEY_OEM_2; - case '~': *shifted = true; case '`': return ui::VKEY_OEM_3; - case '{': *shifted = true; case '[': return ui::VKEY_OEM_4; - case '|': *shifted = true; case '\\': return ui::VKEY_OEM_5; - case '}': *shifted = true; case ']': return ui::VKEY_OEM_6; - case '"': *shifted = true; case '\'': return ui::VKEY_OEM_7; - - default: return ui::VKEY_UNKNOWN; - } -} - -} // namespace - bool StringToAccelerator(const std::string& description, ui::Accelerator* accelerator) { if (!base::IsStringASCII(description)) { @@ -104,7 +37,7 @@ bool StringToAccelerator(const std::string& description, // to be correct and usually only uses few special tokens. if (tokens[i].size() == 1) { bool shifted = false; - key = KeyboardCodeFromCharCode(tokens[i][0], &shifted); + key = atom::KeyboardCodeFromCharCode(tokens[i][0], &shifted); if (shifted) modifiers |= ui::EF_SHIFT_DOWN; } else if (tokens[i] == "ctrl" || tokens[i] == "control") { diff --git a/atom/common/keyboad_util.cc b/atom/common/keyboad_util.cc new file mode 100644 index 0000000000..1baa829ff7 --- /dev/null +++ b/atom/common/keyboad_util.cc @@ -0,0 +1,73 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/common/keyboad_util.h" + +namespace atom { + +// Return key code of the char. +ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted) { + *shifted = false; + switch (c) { + case 8: case 0x7F: return ui::VKEY_BACK; + case 9: return ui::VKEY_TAB; + case 0xD: case 3: return ui::VKEY_RETURN; + case 0x1B: return ui::VKEY_ESCAPE; + case ' ': return ui::VKEY_SPACE; + + case 'a': return ui::VKEY_A; + case 'b': return ui::VKEY_B; + case 'c': return ui::VKEY_C; + case 'd': return ui::VKEY_D; + case 'e': return ui::VKEY_E; + case 'f': return ui::VKEY_F; + case 'g': return ui::VKEY_G; + case 'h': return ui::VKEY_H; + case 'i': return ui::VKEY_I; + case 'j': return ui::VKEY_J; + case 'k': return ui::VKEY_K; + case 'l': return ui::VKEY_L; + case 'm': return ui::VKEY_M; + case 'n': return ui::VKEY_N; + case 'o': return ui::VKEY_O; + case 'p': return ui::VKEY_P; + case 'q': return ui::VKEY_Q; + case 'r': return ui::VKEY_R; + case 's': return ui::VKEY_S; + case 't': return ui::VKEY_T; + case 'u': return ui::VKEY_U; + case 'v': return ui::VKEY_V; + case 'w': return ui::VKEY_W; + case 'x': return ui::VKEY_X; + case 'y': return ui::VKEY_Y; + case 'z': return ui::VKEY_Z; + + case ')': *shifted = true; case '0': return ui::VKEY_0; + case '!': *shifted = true; case '1': return ui::VKEY_1; + case '@': *shifted = true; case '2': return ui::VKEY_2; + case '#': *shifted = true; case '3': return ui::VKEY_3; + case '$': *shifted = true; case '4': return ui::VKEY_4; + case '%': *shifted = true; case '5': return ui::VKEY_5; + case '^': *shifted = true; case '6': return ui::VKEY_6; + case '&': *shifted = true; case '7': return ui::VKEY_7; + case '*': *shifted = true; case '8': return ui::VKEY_8; + case '(': *shifted = true; case '9': return ui::VKEY_9; + + case ':': *shifted = true; case ';': return ui::VKEY_OEM_1; + case '+': *shifted = true; case '=': return ui::VKEY_OEM_PLUS; + case '<': *shifted = true; case ',': return ui::VKEY_OEM_COMMA; + case '_': *shifted = true; case '-': return ui::VKEY_OEM_MINUS; + case '>': *shifted = true; case '.': return ui::VKEY_OEM_PERIOD; + case '?': *shifted = true; case '/': return ui::VKEY_OEM_2; + case '~': *shifted = true; case '`': return ui::VKEY_OEM_3; + case '{': *shifted = true; case '[': return ui::VKEY_OEM_4; + case '|': *shifted = true; case '\\': return ui::VKEY_OEM_5; + case '}': *shifted = true; case ']': return ui::VKEY_OEM_6; + case '"': *shifted = true; case '\'': return ui::VKEY_OEM_7; + + default: return ui::VKEY_UNKNOWN; + } +} + +} // namespace atom diff --git a/atom/common/keyboad_util.h b/atom/common/keyboad_util.h new file mode 100644 index 0000000000..0496886e40 --- /dev/null +++ b/atom/common/keyboad_util.h @@ -0,0 +1,18 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_KEYBOAD_UTIL_H_ +#define ATOM_COMMON_KEYBOAD_UTIL_H_ + +#include "ui/events/keycodes/keyboard_codes.h" + +namespace atom { + +// Return key code of the char, and also determine whether the SHIFT key is +// pressed. +ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted); + +} // namespace atom + +#endif // ATOM_COMMON_KEYBOAD_UTIL_H_ diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index 5d3ff62086..afafa10b11 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -5,13 +5,197 @@ #include "atom/common/native_mate_converters/blink_converter.h" #include +#include +#include "atom/common/keyboad_util.h" #include "base/strings/string_util.h" +#include "content/public/browser/native_web_keyboard_event.h" #include "native_mate/dictionary.h" #include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" + +namespace { + +template +int VectorToBitArray(const std::vector& vec) { + int bits = 0; + for (const T& item : vec) + bits |= item; + return bits; +} + +} // namespace namespace mate { +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + char* out) { + std::string code = base::StringToLowerASCII(V8ToString(val)); + if (code.length() != 1) + return false; + *out = code[0]; + return true; + } +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + blink::WebInputEvent::Type* out) { + std::string type = base::StringToLowerASCII(V8ToString(val)); + if (type == "mousedown") + *out = blink::WebInputEvent::MouseDown; + else if (type == "mouseup") + *out = blink::WebInputEvent::MouseUp; + else if (type == "mousemove") + *out = blink::WebInputEvent::MouseMove; + else if (type == "mouseenter") + *out = blink::WebInputEvent::MouseEnter; + else if (type == "mouseleave") + *out = blink::WebInputEvent::MouseLeave; + else if (type == "contextmenu") + *out = blink::WebInputEvent::ContextMenu; + else if (type == "mousewheel") + *out = blink::WebInputEvent::MouseWheel; + else if (type == "keydown") + *out = blink::WebInputEvent::KeyDown; + else if (type == "keyup") + *out = blink::WebInputEvent::KeyUp; + else if (type == "char") + *out = blink::WebInputEvent::Char; + else if (type == "touchstart") + *out = blink::WebInputEvent::TouchStart; + else if (type == "touchmove") + *out = blink::WebInputEvent::TouchMove; + else if (type == "touchend") + *out = blink::WebInputEvent::TouchEnd; + else if (type == "touchcancel") + *out = blink::WebInputEvent::TouchCancel; + return false; + } +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + blink::WebInputEvent::Modifiers* out) { + std::string modifier = base::StringToLowerASCII(V8ToString(val)); + if (modifier == "shift") + *out = blink::WebInputEvent::ShiftKey; + else if (modifier == "control" || modifier == "ctrl") + *out = blink::WebInputEvent::ControlKey; + else if (modifier == "alt") + *out = blink::WebInputEvent::AltKey; + else if (modifier == "meta" || modifier == "command" || modifier == "cmd") + *out = blink::WebInputEvent::MetaKey; + else if (modifier == "iskeypad") + *out = blink::WebInputEvent::IsKeyPad; + else if (modifier == "isautorepeat") + *out = blink::WebInputEvent::IsAutoRepeat; + else if (modifier == "leftbuttondown") + *out = blink::WebInputEvent::LeftButtonDown; + else if (modifier == "middlebuttondown") + *out = blink::WebInputEvent::MiddleButtonDown; + else if (modifier == "rightbuttondown") + *out = blink::WebInputEvent::RightButtonDown; + else if (modifier == "capslock") + *out = blink::WebInputEvent::CapsLockOn; + else if (modifier == "numlock") + *out = blink::WebInputEvent::NumLockOn; + else if (modifier == "left") + *out = blink::WebInputEvent::IsLeft; + else if (modifier == "right") + *out = blink::WebInputEvent::IsRight; + return false; + } +}; + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + blink::WebInputEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!dict.Get("type", &out->type)) + return false; + std::vector modifiers; + if (dict.Get("modifiers", &modifiers)) + out->modifiers = VectorToBitArray(modifiers); + out->timeStampSeconds = base::Time::Now().ToDoubleT(); + return true; +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + blink::WebKeyboardEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!ConvertFromV8(isolate, val, static_cast(out))) + return false; + char code; + if (!dict.Get("keyCode", &code)) + return false; + bool shifted = false; + out->windowsKeyCode = atom::KeyboardCodeFromCharCode(code, &shifted); + if (out->windowsKeyCode == ui::VKEY_UNKNOWN) + return false; + if (shifted) + out->modifiers |= blink::WebInputEvent::ShiftKey; + out->setKeyIdentifierFromWindowsKeyCode(); + return false; +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + content::NativeWebKeyboardEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!ConvertFromV8(isolate, val, static_cast(out))) + return false; + dict.Get("skipInBrowser", &out->skip_in_browser); + return false; +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, blink::WebMouseEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!ConvertFromV8(isolate, val, static_cast(out))) + return false; + if (!dict.Get("x", &out->x) || !dict.Get("y", &out->y)) + return false; + dict.Get("globalX", &out->globalX); + dict.Get("globalY", &out->globalY); + dict.Get("movementX", &out->movementX); + dict.Get("movementY", &out->movementY); + dict.Get("clickCount", &out->clickCount); + return false; +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + blink::WebMouseWheelEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!ConvertFromV8(isolate, val, static_cast(out))) + return false; + dict.Get("deltaX", &out->deltaX); + dict.Get("deltaY", &out->deltaY); + dict.Get("wheelTicksX", &out->wheelTicksX); + dict.Get("wheelTicksY", &out->wheelTicksY); + dict.Get("accelerationRatioX", &out->accelerationRatioX); + dict.Get("accelerationRatioY", &out->accelerationRatioY); + dict.Get("hasPreciseScrollingDeltas", &out->hasPreciseScrollingDeltas); + dict.Get("canScroll", &out->canScroll); + return false; +} + bool Converter::FromV8( v8::Isolate* isolate, v8::Local val, blink::WebFloatPoint* out) { mate::Dictionary dict; diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index bbd2af0e67..fd631983d4 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -8,14 +8,52 @@ #include "native_mate/converter.h" namespace blink { +class WebInputEvent; +class WebMouseEvent; +class WebMouseWheelEvent; +class WebKeyboardEvent; struct WebDeviceEmulationParams; struct WebFloatPoint; struct WebPoint; struct WebSize; } +namespace content { +struct NativeWebKeyboardEvent; +} + namespace mate { +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebInputEvent* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebKeyboardEvent* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + content::NativeWebKeyboardEvent* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebMouseEvent* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebMouseWheelEvent* out); +}; + template<> struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, diff --git a/filenames.gypi b/filenames.gypi index 30668f20a7..acdea0c25e 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -283,6 +283,8 @@ 'atom/common/google_api_key.h', 'atom/common/id_weak_map.cc', 'atom/common/id_weak_map.h', + 'atom/common/keyboad_util.cc', + 'atom/common/keyboad_util.h', 'atom/common/linux/application_info.cc', 'atom/common/native_mate_converters/accelerator_converter.cc', 'atom/common/native_mate_converters/accelerator_converter.h', From 5a599cb6ffcbe7469050af36d503a623d85532de Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 13:49:33 +0800 Subject: [PATCH 29/41] Sequence of definitions should follow the declarations --- atom/browser/native_window.cc | 64 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 9121f0cb88..4a78ec85fe 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -207,38 +207,6 @@ bool NativeWindow::IsDocumentEdited() { void NativeWindow::SetMenu(ui::MenuModel* menu) { } -void NativeWindow::ShowDefinitionForSelection() { - NOTIMPLEMENTED(); -} - -void NativeWindow::SetAutoHideMenuBar(bool auto_hide) { -} - -bool NativeWindow::IsMenuBarAutoHide() { - return false; -} - -void NativeWindow::SetMenuBarVisibility(bool visible) { -} - -bool NativeWindow::IsMenuBarVisible() { - return true; -} - -double NativeWindow::GetAspectRatio() { - return aspect_ratio_; -} - -gfx::Size NativeWindow::GetAspectRatioExtraSize() { - return aspect_ratio_extraSize_; -} - -void NativeWindow::SetAspectRatio(double aspect_ratio, - const gfx::Size& extra_size) { - aspect_ratio_ = aspect_ratio; - aspect_ratio_extraSize_ = extra_size; -} - bool NativeWindow::HasModalDialog() { return has_dialog_attached_; } @@ -293,6 +261,38 @@ void NativeWindow::CapturePage(const gfx::Rect& rect, kBGRA_8888_SkColorType); } +void NativeWindow::ShowDefinitionForSelection() { + NOTIMPLEMENTED(); +} + +void NativeWindow::SetAutoHideMenuBar(bool auto_hide) { +} + +bool NativeWindow::IsMenuBarAutoHide() { + return false; +} + +void NativeWindow::SetMenuBarVisibility(bool visible) { +} + +bool NativeWindow::IsMenuBarVisible() { + return true; +} + +double NativeWindow::GetAspectRatio() { + return aspect_ratio_; +} + +gfx::Size NativeWindow::GetAspectRatioExtraSize() { + return aspect_ratio_extraSize_; +} + +void NativeWindow::SetAspectRatio(double aspect_ratio, + const gfx::Size& extra_size) { + aspect_ratio_ = aspect_ratio; + aspect_ratio_extraSize_ = extra_size; +} + void NativeWindow::SetFrameSubscription(bool isOffscreen) { const auto view = web_contents()->GetRenderWidgetHostView(); From c550546ff12038ceee01ee5d79e83d1210295030 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 14:09:31 +0800 Subject: [PATCH 30/41] Do not manually convert Object to WebInputEvent --- atom/browser/api/atom_api_window.cc | 163 ++++-------------- atom/browser/api/atom_api_window.h | 3 +- atom/browser/native_window.cc | 96 ++++------- atom/browser/native_window.h | 21 ++- atom/common/event_types.cc | 118 ------------- atom/common/event_types.h | 52 ------ .../native_mate_converters/blink_converter.cc | 7 + .../native_mate_converters/blink_converter.h | 2 + atom/common/options_switches.cc | 11 -- atom/common/options_switches.h | 11 -- filenames.gypi | 2 - 11 files changed, 90 insertions(+), 396 deletions(-) delete mode 100644 atom/common/event_types.cc delete mode 100644 atom/common/event_types.h diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index b8d2c463eb..a2851415d1 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -9,16 +9,18 @@ #include "atom/browser/browser.h" #include "atom/browser/native_window.h" #include "atom/common/node_includes.h" -#include "atom/common/event_types.h" +#include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/options_switches.h" +#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/render_process_host.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/gfx/geometry/rect.h" #if defined(OS_WIN) @@ -462,14 +464,6 @@ void Window::CapturePage(mate::Arguments* args) { rect, base::Bind(&OnCapturePageDone, args->isolate(), callback)); } -void Window::BeginFrameSubscription() { - window_->SetFrameSubscription(true); -} - -void Window::EndFrameSubscription() { - window_->SetFrameSubscription(false); -} - void Window::SetProgressBar(double progress) { window_->SetProgressBar(progress); } @@ -546,125 +540,39 @@ bool Window::IsVisibleOnAllWorkspaces() { return window_->IsVisibleOnAllWorkspaces(); } -void Window::SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& data){ - auto type = blink::WebInputEvent::Type::Char; - int modifiers = 0; - int keycode = 0; - int native = 0; - std::string type_str = ""; - mate::Dictionary modifier_list = mate::Dictionary::CreateEmpty(isolate); - - data.Get(switches::kEventType, &type_str); - data.Get(switches::kModifiers, &modifier_list); - data.Get(switches::kKeyCode, &keycode); - data.Get(switches::kNativeKeyCode, &native); - - if(type_str.compare(event_types::kKeyDown) == 0){ - type = blink::WebInputEvent::Type::KeyDown; - }else if(type_str.compare(event_types::kKeyUp) == 0){ - type = blink::WebInputEvent::Type::KeyUp; - }else if(type_str.compare(event_types::kChar) == 0){ - type = blink::WebInputEvent::Type::Char; - } - - std::map modifier_types; - modifier_types[event_types::kModifierIsKeyPad] = false; - modifier_types[event_types::kModifierIsAutoRepeat] = false; - modifier_types[event_types::kModifierIsLeft] = false; - modifier_types[event_types::kModifierIsRight] = false; - modifier_types[event_types::kModifierShiftKey] = false; - modifier_types[event_types::kModifierControlKey] = false; - modifier_types[event_types::kModifierAltKey] = false; - modifier_types[event_types::kModifierMetaKey] = false; - modifier_types[event_types::kModifierCapsLockOn] = false; - modifier_types[event_types::kModifierNumLockOn] = false; - - for(std::map::iterator it = modifier_types.begin(); it != modifier_types.end(); ++it){ - modifier_list.Get(it->first,&(it->second)); - - if(it->second) modifiers = modifiers & event_types::modifierStrToWebModifier(it->first); - } - - window_->SendKeyboardEvent(type, modifiers, keycode, native); -} - -void Window::SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data){ - int x, y, movementX, movementY, clickCount; - std::string type_str = ""; - std::string button_str = ""; - mate::Dictionary modifier_list = mate::Dictionary::CreateEmpty(isolate); - - blink::WebInputEvent::Type type = blink::WebInputEvent::Type::MouseMove; - blink::WebMouseEvent::Button button = blink::WebMouseEvent::Button::ButtonNone; - int modifiers = 0; - - data.Get(switches::kEventType, &type_str); - data.Get(switches::kMouseEventButton, &button_str); - data.Get(switches::kModifiers, &modifier_list); - - if(type_str.compare(event_types::kMouseDown) == 0){ - type = blink::WebInputEvent::Type::MouseDown; - }else if(type_str.compare(event_types::kMouseUp) == 0){ - type = blink::WebInputEvent::Type::MouseUp; - }else if(type_str.compare(event_types::kMouseMove) == 0){ - type = blink::WebInputEvent::Type::MouseMove; - }else if(type_str.compare(event_types::kMouseEnter) == 0){ - type = blink::WebInputEvent::Type::MouseEnter; - }else if(type_str.compare(event_types::kMouseLeave) == 0){ - type = blink::WebInputEvent::Type::MouseLeave; - }else if(type_str.compare(event_types::kContextMenu) == 0){ - type = blink::WebInputEvent::Type::ContextMenu; - }else if(type_str.compare(event_types::kMouseWheel) == 0){ - type = blink::WebInputEvent::Type::MouseWheel; - } - - std::map modifier_types; - modifier_types[event_types::kMouseLeftButton] = false; - modifier_types[event_types::kMouseRightButton] = false; - modifier_types[event_types::kMouseMiddleButton] = false; - modifier_types[event_types::kModifierLeftButtonDown] = false; - modifier_types[event_types::kModifierMiddleButtonDown] = false; - modifier_types[event_types::kModifierRightButtonDown] = false; - modifier_types[event_types::kModifierShiftKey] = false; - modifier_types[event_types::kModifierControlKey] = false; - modifier_types[event_types::kModifierAltKey] = false; - modifier_types[event_types::kModifierMetaKey] = false; - modifier_types[event_types::kModifierCapsLockOn] = false; - modifier_types[event_types::kModifierNumLockOn] = false; - - for(std::map::iterator it = modifier_types.begin(); it != modifier_types.end(); ++it){ - modifier_list.Get(it->first,&(it->second)); - - if(it->second) modifiers = modifiers & event_types::modifierStrToWebModifier(it->first); - } - - if(type == blink::WebInputEvent::Type::MouseWheel){ - bool precise = true; - - x = 0; - y = 0; - data.Get(switches::kX, &x); - data.Get(switches::kY, &y); - data.Get(switches::kMouseWheelPrecise, &precise); - - window_->SendMouseWheelEvent(modifiers, x, y, precise); - }else{ - if (data.Get(switches::kX, &x) && data.Get(switches::kY, &y)) { - if(!data.Get(switches::kMovementX, &movementX)){ - movementX = 0; - } - - if(!data.Get(switches::kMovementY, &movementY)){ - movementY = 0; - } - - if(!data.Get(switches::kClickCount, &clickCount)){ - clickCount = 0; - } - - window_->SendMouseEvent(type, modifiers, button, x, y, movementX, movementY, clickCount); +void Window::SendInputEvent(v8::Isolate* isolate, + v8::Local input_event) { + int type = mate::GetWebInputEventType(isolate, input_event); + if (blink::WebInputEvent::isMouseEventType(type)) { + blink::WebMouseEvent mouse_event; + if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) { + window_->SendInputEvent(mouse_event); + return; + } + } else if (blink::WebInputEvent::isKeyboardEventType(type)) { + content::NativeWebKeyboardEvent keyboard_event;; + if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) { + window_->SendInputEvent(keyboard_event); + return; + } + } else if (type == blink::WebInputEvent::MouseWheel) { + blink::WebMouseWheelEvent mouse_wheel_event; + if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) { + window_->SendInputEvent(mouse_wheel_event); + return; } } + + isolate->ThrowException(v8::Exception::Error(mate::StringToV8( + isolate, "Invalid event type"))); +} + +void Window::BeginFrameSubscription() { + window_->SetFrameSubscription(true); +} + +void Window::EndFrameSubscription() { + window_->SetFrameSubscription(false); } int32_t Window::ID() const { @@ -751,8 +659,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, &Window::SetVisibleOnAllWorkspaces) .SetMethod("isVisibleOnAllWorkspaces", &Window::IsVisibleOnAllWorkspaces) - .SetMethod("sendMouseEvent", &Window::SendMouseEvent) - .SetMethod("sendKeyboardEvent", &Window::SendKeyboardEvent) + .SetMethod("sendInputEvent", &Window::SendInputEvent) .SetMethod("beginFrameSubscription", &Window::BeginFrameSubscription) .SetMethod("endFrameSubscription", &Window::EndFrameSubscription) #if defined(OS_MACOSX) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 6dfcbee8bc..507bbb4384 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -142,8 +142,7 @@ class Window : public mate::TrackableObject, bool IsMenuBarVisible(); void SetAspectRatio(double aspect_ratio, mate::Arguments* args); - void SendKeyboardEvent(v8::Isolate* isolate, const mate::Dictionary& data); - void SendMouseEvent(v8::Isolate* isolate, const mate::Dictionary& data); + void SendInputEvent(v8::Isolate* isolate, v8::Local input_event); void BeginFrameSubscription(); void EndFrameSubscription(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 4a78ec85fe..55fe206ff1 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -8,10 +8,6 @@ #include #include -#include "content/public/browser/render_widget_host_view_frame_subscriber.h" -#include "content/public/browser/native_web_keyboard_event.h" -#include "third_party/WebKit/public/web/WebInputEvent.h" -#include "media/base/video_frame.h" #include "media/base/yuv_convert.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" @@ -43,7 +39,6 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/screen.h" #include "ui/gl/gpu_switching_manager.h" -#include "ui/events/event.h" using content::NavigationEntry; using content::RenderWidgetHostView; @@ -312,6 +307,38 @@ void NativeWindow::SetFrameSubscription(bool isOffscreen) { } } +void NativeWindow::SendInputEvent(const blink::WebMouseEvent& mouse_event) { + const auto view = web_contents()->GetRenderWidgetHostView(); + if (!view) + return; + const auto host = view->GetRenderWidgetHost(); + if (!host) + return; + host->ForwardMouseEvent(mouse_event); +} + +void NativeWindow::SendInputEvent( + const blink::WebMouseWheelEvent& mouse_wheel_event) { + const auto view = web_contents()->GetRenderWidgetHostView(); + if (!view) + return; + const auto host = view->GetRenderWidgetHost(); + if (!host) + return; + host->ForwardWheelEvent(mouse_wheel_event); +} + +void NativeWindow::SendInputEvent( + const content::NativeWebKeyboardEvent& keyboard_event) { + const auto view = web_contents()->GetRenderWidgetHostView(); + if (!view) + return; + const auto host = view->GetRenderWidgetHost(); + if (!host) + return; + host->ForwardKeyboardEvent(keyboard_event); +} + void NativeWindow::RequestToClosePage() { bool prevent_default = false; FOR_EACH_OBSERVER(NativeWindowObserver, @@ -454,65 +481,6 @@ void NativeWindow::DevToolsClosed() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed()); } -void NativeWindow::SendKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, int keycode, int nativeKeycode){ - auto keyb_event = new content::NativeWebKeyboardEvent; - - keyb_event->nativeKeyCode = nativeKeycode; - keyb_event->windowsKeyCode = keycode; - keyb_event->setKeyIdentifierFromWindowsKeyCode(); - keyb_event->type = type; - keyb_event->modifiers = modifiers; - keyb_event->isSystemKey = false; - keyb_event->timeStampSeconds = base::Time::Now().ToDoubleT(); - keyb_event->skip_in_browser = false; - - if (type == blink::WebInputEvent::Char || type == blink::WebInputEvent::RawKeyDown) { - keyb_event->text[0] = keycode; - keyb_event->unmodifiedText[0] = keycode; - } - - const auto view = web_contents()->GetRenderWidgetHostView(); - const auto host = view ? view->GetRenderWidgetHost() : nullptr; - - host->ForwardKeyboardEvent(*keyb_event); -} - -void NativeWindow::SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount){ - auto mouse_event = new blink::WebMouseEvent(); - - mouse_event->x = x; - mouse_event->y = y; - mouse_event->windowX = x; - mouse_event->windowY = y; - mouse_event->clickCount = clickCount; - mouse_event->type = type; - mouse_event->modifiers = modifiers; - mouse_event->button = button; - - mouse_event->timeStampSeconds = base::Time::Now().ToDoubleT(); - - const auto view = web_contents()->GetRenderWidgetHostView(); - const auto host = view ? view->GetRenderWidgetHost() : nullptr; - host->ForwardMouseEvent(*mouse_event); -} - -void NativeWindow::SendMouseWheelEvent(int modifiers, int x, int y, bool precise){ - auto wheel_event = new blink::WebMouseWheelEvent(); - - wheel_event->type = blink::WebInputEvent::MouseWheel; - wheel_event->deltaX = x; - wheel_event->deltaY = y; - if(x) wheel_event->wheelTicksX = x > 0.0f ? 1.0f : -1.0f; - if(y) wheel_event->wheelTicksY = y > 0.0f ? 1.0f : -1.0f; - wheel_event->modifiers = modifiers; - wheel_event->hasPreciseScrollingDeltas = precise; - wheel_event->canScroll = true; - - const auto view = web_contents()->GetRenderWidgetHostView(); - const auto host = view ? view->GetRenderWidgetHost() : nullptr; - host->ForwardWheelEvent(*wheel_event); -} - void NativeWindow::RenderViewCreated( content::RenderViewHost* render_view_host) { if (!transparent_) diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 5784743af8..1eabd5e693 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -11,8 +11,6 @@ #include "media/base/video_frame.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" -#include "content/public/browser/native_web_keyboard_event.h" -#include "third_party/WebKit/public/web/WebInputEvent.h" #include "atom/browser/native_window_observer.h" #include "atom/browser/ui/accelerator_util.h" #include "base/cancelable_callback.h" @@ -28,6 +26,11 @@ class SkRegion; +namespace blink { +class WebMouseEvent; +class WebMouseWheelEvent; +} + namespace brightray { class InspectableWebContents; } @@ -173,6 +176,14 @@ class NativeWindow : public content::WebContentsObserver, gfx::Size GetAspectRatioExtraSize(); void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size); + // Subscribe to the frame updates. + void SetFrameSubscription(bool isOffscreen); + + // Send the WebInputEvent to the page. + void SendInputEvent(const blink::WebMouseEvent& mouse_event); + void SendInputEvent(const blink::WebMouseWheelEvent& mouse_wheel_event); + void SendInputEvent(const content::NativeWebKeyboardEvent& keyboard_event); + base::WeakPtr GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -229,12 +240,6 @@ class NativeWindow : public content::WebContentsObserver, void OnFrameReceived(bool result, scoped_refptr frame); - void SendKeyboardEvent(blink::WebInputEvent::Type type, int modifiers, int keycode, int nativeKeycode); - void SendMouseEvent(blink::WebInputEvent::Type type, int modifiers, blink::WebMouseEvent::Button button, int x, int y, int movementX, int movementY, int clickCount); - void SendMouseWheelEvent(int modifiers, int x, int y, bool clickCount); - - void SetFrameSubscription(bool isOffscreen); - protected: NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, const mate::Dictionary& options); diff --git a/atom/common/event_types.cc b/atom/common/event_types.cc deleted file mode 100644 index be08481289..0000000000 --- a/atom/common/event_types.cc +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2013 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/common/event_types.h" -#include "third_party/WebKit/public/web/WebInputEvent.h" - -namespace atom { - -namespace event_types { - -const char kMouseDown[] = "down"; -const char kMouseUp[] = "up"; -const char kMouseMove[] = "move"; -const char kMouseEnter[] = "enter"; -const char kMouseLeave[] = "leave"; -const char kContextMenu[] = "context-menu"; -const char kMouseWheel[] = "wheel"; - -const char kKeyDown[] = "down"; -const char kKeyUp[] = "up"; -const char kChar[] = "char"; - -const char kMouseLeftButton[] = "left"; -const char kMouseRightButton[] = "right"; -const char kMouseMiddleButton[] = "middle"; - -const char kModifierLeftButtonDown[] = "left-button-down"; -const char kModifierMiddleButtonDown[] = "middle-button-down"; -const char kModifierRightButtonDown[] = "right-button-down"; - -const char kModifierShiftKey[] = "shift"; -const char kModifierControlKey[] = "control"; -const char kModifierAltKey[] = "alt"; -const char kModifierMetaKey[] = "meta"; -const char kModifierCapsLockOn[] = "caps-lock"; -const char kModifierNumLockOn[] = "num-lock"; - -const char kModifierIsKeyPad[] = "keypad"; -const char kModifierIsAutoRepeat[] = "auto-repeat"; -const char kModifierIsLeft[] = "left"; -const char kModifierIsRight[] = "right"; - -int modifierStrToWebModifier(std::string modifier){ - if(modifier.compare(event_types::kModifierLeftButtonDown) == 0){ - - return blink::WebInputEvent::Modifiers::LeftButtonDown; - - }else if(modifier.compare(event_types::kModifierMiddleButtonDown) == 0){ - - return blink::WebInputEvent::Modifiers::MiddleButtonDown; - - }else if(modifier.compare(event_types::kModifierRightButtonDown) == 0){ - - return blink::WebInputEvent::Modifiers::RightButtonDown; - - }else if(modifier.compare(event_types::kMouseLeftButton) == 0){ - - return blink::WebInputEvent::Modifiers::LeftButtonDown; - - }else if(modifier.compare(event_types::kMouseRightButton) == 0){ - - return blink::WebInputEvent::Modifiers::RightButtonDown; - - }else if(modifier.compare(event_types::kMouseMiddleButton) == 0){ - - return blink::WebInputEvent::Modifiers::MiddleButtonDown; - - }else if(modifier.compare(event_types::kModifierIsKeyPad) == 0){ - - return blink::WebInputEvent::Modifiers::IsKeyPad; - - }else if(modifier.compare(event_types::kModifierIsAutoRepeat) == 0){ - - return blink::WebInputEvent::Modifiers::IsAutoRepeat; - - }else if(modifier.compare(event_types::kModifierIsLeft) == 0){ - - return blink::WebInputEvent::Modifiers::IsLeft; - - }else if(modifier.compare(event_types::kModifierIsRight) == 0){ - - return blink::WebInputEvent::Modifiers::IsRight; - - }else if(modifier.compare(event_types::kModifierShiftKey) == 0){ - - return blink::WebInputEvent::Modifiers::ShiftKey; - - }else if(modifier.compare(event_types::kModifierControlKey) == 0){ - - return blink::WebInputEvent::Modifiers::ControlKey; - - }else if(modifier.compare(event_types::kModifierAltKey) == 0){ - - return blink::WebInputEvent::Modifiers::AltKey; - - }else if(modifier.compare(event_types::kModifierMetaKey) == 0){ - - return blink::WebInputEvent::Modifiers::MetaKey; - - }else if(modifier.compare(event_types::kModifierCapsLockOn) == 0){ - - return blink::WebInputEvent::Modifiers::CapsLockOn; - - }else if(modifier.compare(event_types::kModifierNumLockOn) == 0){ - - return blink::WebInputEvent::Modifiers::NumLockOn; - - }else{ - - return 0; - - } -} - -} // namespace event_types - -} // namespace atom diff --git a/atom/common/event_types.h b/atom/common/event_types.h deleted file mode 100644 index d4769db2d7..0000000000 --- a/atom/common/event_types.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2013 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef ATOM_COMMON_EVENT_TYPES_H_ -#define ATOM_COMMON_EVENT_TYPES_H_ - -#include "third_party/WebKit/public/web/WebInputEvent.h" - -namespace atom { - -namespace event_types { - -extern const char kMouseDown[]; -extern const char kMouseUp[]; -extern const char kMouseMove[]; -extern const char kMouseEnter[]; -extern const char kMouseLeave[]; -extern const char kContextMenu[]; -extern const char kMouseWheel[]; - -extern const char kKeyDown[]; -extern const char kKeyUp[]; -extern const char kChar[]; - -extern const char kMouseLeftButton[]; -extern const char kMouseRightButton[]; -extern const char kMouseMiddleButton[]; - -extern const char kModifierLeftButtonDown[]; -extern const char kModifierMiddleButtonDown[]; -extern const char kModifierRightButtonDown[]; - -extern const char kModifierShiftKey[]; -extern const char kModifierControlKey[]; -extern const char kModifierAltKey[]; -extern const char kModifierMetaKey[]; -extern const char kModifierCapsLockOn[]; -extern const char kModifierNumLockOn[]; - -extern const char kModifierIsKeyPad[]; -extern const char kModifierIsAutoRepeat[]; -extern const char kModifierIsLeft[]; -extern const char kModifierIsRight[]; - -int modifierStrToWebModifier(std::string modifier); - -} // namespace event_types - -} // namespace atom - -#endif // ATOM_COMMON_EVENT_TYPES_H_ diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index afafa10b11..a406059cf6 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -112,6 +112,13 @@ struct Converter { } }; +int GetWebInputEventType(v8::Isolate* isolate, v8::Local val) { + int type = -1; + mate::Dictionary dict; + ConvertFromV8(isolate, val, &dict) && dict.Get("type", &type); + return type; +} + bool Converter::FromV8( v8::Isolate* isolate, v8::Local val, blink::WebInputEvent* out) { diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index fd631983d4..17bb108d34 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -24,6 +24,8 @@ struct NativeWebKeyboardEvent; namespace mate { +int GetWebInputEventType(v8::Isolate* isolate, v8::Local val); + template<> struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 2268a40395..c70e1ba4af 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -116,17 +116,6 @@ const char kRegisterStandardSchemes[] = "register-standard-schemes"; // The browser process app model ID const char kAppUserModelId[] = "app-user-model-id"; -const char kModifiers[] = "modifiers"; -const char kKeyCode[] = "code"; -const char kNativeKeyCode[] = "native"; - -const char kMovementX[] = "movement-x"; -const char kMovementY[] = "movement-y"; -const char kClickCount[] = "click-count"; -const char kEventType[] = "type"; -const char kMouseEventButton[] = "button"; -const char kMouseWheelPrecise[] = "precise"; - } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index eb7842e787..e62f311666 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -62,17 +62,6 @@ extern const char kRegisterStandardSchemes[]; extern const char kAppUserModelId[]; -extern const char kModifiers[]; -extern const char kKeyCode[]; -extern const char kNativeKeyCode[]; - -extern const char kMovementX[]; -extern const char kMovementY[]; -extern const char kClickCount[]; -extern const char kEventType[]; -extern const char kMouseEventButton[]; -extern const char kMouseWheelPrecise[]; - } // namespace switches } // namespace atom diff --git a/filenames.gypi b/filenames.gypi index acdea0c25e..f25ec4a8a5 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -313,8 +313,6 @@ 'atom/common/node_includes.h', 'atom/common/options_switches.cc', 'atom/common/options_switches.h', - 'atom/common/event_types.cc', - 'atom/common/event_types.h', 'atom/common/platform_util.h', 'atom/common/platform_util_linux.cc', 'atom/common/platform_util_mac.mm', From 9e7de78231e753ceda212c24224dda1ca4d7b689 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 14:12:48 +0800 Subject: [PATCH 31/41] Fix cpplint warnings --- atom/browser/api/atom_api_window.cc | 1 - atom/browser/native_window.cc | 12 ++++-------- atom/browser/native_window.h | 17 +++++++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index a2851415d1..db7b1d5ca1 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -8,7 +8,6 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" #include "atom/browser/native_window.h" -#include "atom/common/node_includes.h" #include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 55fe206ff1..8095452554 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -107,9 +107,8 @@ NativeWindow* NativeWindow::FromWebContents( content::WebContents* web_contents) { WindowList& window_list = *WindowList::GetInstance(); for (NativeWindow* window : window_list) { - if (window->web_contents() == web_contents){ + if (window->web_contents() == web_contents) return window; - } } return nullptr; } @@ -290,16 +289,12 @@ void NativeWindow::SetAspectRatio(double aspect_ratio, void NativeWindow::SetFrameSubscription(bool isOffscreen) { const auto view = web_contents()->GetRenderWidgetHostView(); - if (view) { if (isOffscreen) { scoped_ptr subscriber( new RenderSubscriber( view->GetVisibleViewportSize(), - base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)) - ) - ); - + base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)))); view->BeginFrameSubscription(subscriber.Pass()); } else { view->EndFrameSubscription(); @@ -593,7 +588,8 @@ bool RenderSubscriber::ShouldCaptureFrame( gfx::Rect(size_), size_, base::TimeDelta()); - *callback = base::Bind(&RenderSubscriber::CallbackMethod, callback_, *storage); + *callback = + base::Bind(&RenderSubscriber::CallbackMethod, callback_, *storage); return true; } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 1eabd5e693..3344cfb65c 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -313,10 +313,14 @@ class NativeWindow : public content::WebContentsObserver, DISALLOW_COPY_AND_ASSIGN(NativeWindow); }; -//This class provides a way to listen to frame renders and to use the rendered frames for offscreen rendering +// This class provides a way to listen to frame renders and to use the rendered +// frames for offscreen rendering class RenderSubscriber : public content::RenderWidgetHostViewFrameSubscriber { public: - RenderSubscriber(gfx::Size size, base::Callback)> callback) : size_(size), callback_(callback) {} + RenderSubscriber( + gfx::Size size, + base::Callback)> callback) + : size_(size), callback_(callback) {} bool ShouldCaptureFrame(const gfx::Rect& damage_rect, base::TimeTicks present_time, @@ -325,10 +329,11 @@ class RenderSubscriber : public content::RenderWidgetHostViewFrameSubscriber { base::TimeTicks last_present_time() const { return last_present_time_; } - static void CallbackMethod(base::Callback)> callback, - scoped_refptr frame, - base::TimeTicks present_time, - bool success) { + static void CallbackMethod( + base::Callback)> callback, + scoped_refptr frame, + base::TimeTicks present_time, + bool success) { callback.Run(success, frame); } From 42863e4700a19acd57ed425e91c4054fae40f8e6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 14:20:31 +0800 Subject: [PATCH 32/41] Move SendInputEvent to WebContents --- atom/browser/api/atom_api_web_contents.cc | 40 +++++++++++++++++++++++ atom/browser/api/atom_api_web_contents.h | 5 ++- atom/browser/api/atom_api_window.cc | 31 ------------------ atom/browser/api/atom_api_window.h | 1 - atom/browser/native_window.cc | 36 -------------------- atom/browser/native_window.h | 10 ------ 6 files changed, 44 insertions(+), 79 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index d4cb6cd227..43b20a3d71 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -30,12 +30,14 @@ #include "chrome/browser/printing/print_preview_message_handler.h" #include "content/common/view_messages.h" #include "content/public/browser/favicon_status.h" +#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/resource_request_details.h" #include "content/public/browser/service_worker_context.h" #include "content/public/browser/storage_partition.h" @@ -46,6 +48,7 @@ #include "net/http/http_response_headers.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" #include "atom/common/node_includes.h" @@ -813,6 +816,42 @@ bool WebContents::SendIPCMessage(const base::string16& channel, return Send(new AtomViewMsg_Message(routing_id(), channel, args)); } +void WebContents::SendInputEvent(v8::Isolate* isolate, + v8::Local input_event) { + const auto view = web_contents()->GetRenderWidgetHostView(); + if (!view) + return; + const auto host = view->GetRenderWidgetHost(); + if (!host) + return; + + int type = mate::GetWebInputEventType(isolate, input_event); + if (blink::WebInputEvent::isMouseEventType(type)) { + blink::WebMouseEvent mouse_event; + if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) { + host->ForwardMouseEvent(mouse_event); + return; + } + } else if (blink::WebInputEvent::isKeyboardEventType(type)) { + content::NativeWebKeyboardEvent keyboard_event;; + if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) { + host->ForwardKeyboardEvent(keyboard_event); + return; + } + } else if (type == blink::WebInputEvent::MouseWheel) { + blink::WebMouseWheelEvent mouse_wheel_event; + if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) { + host->ForwardWheelEvent(mouse_wheel_event); + return; + } + } + + isolate->ThrowException(v8::Exception::Error(mate::StringToV8( + isolate, "Invalid event type"))); +} + + + void WebContents::SetSize(const SetSizeParams& params) { if (guest_delegate_) guest_delegate_->SetSize(params); @@ -875,6 +914,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("focus", &WebContents::Focus) .SetMethod("tabTraverse", &WebContents::TabTraverse) .SetMethod("_send", &WebContents::SendIPCMessage, true) + .SetMethod("sendInputEvent", &WebContents::SendInputEvent) .SetMethod("setSize", &WebContents::SetSize) .SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency) .SetMethod("isGuest", &WebContents::IsGuest) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 0ce47237e4..6dc2660532 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -114,10 +114,13 @@ class WebContents : public mate::TrackableObject, void Focus(); void TabTraverse(bool reverse); - // Sending messages to browser. + // Send messages to browser. bool SendIPCMessage(const base::string16& channel, const base::ListValue& args); + // Send WebInputEvent to the page. + void SendInputEvent(v8::Isolate* isolate, v8::Local input_event); + // Methods for creating . void SetSize(const SetSizeParams& params); void SetAllowTransparency(bool allow); diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index db7b1d5ca1..985b6a7543 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -8,18 +8,15 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" #include "atom/browser/native_window.h" -#include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/options_switches.h" -#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/render_process_host.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" -#include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/gfx/geometry/rect.h" #if defined(OS_WIN) @@ -539,33 +536,6 @@ bool Window::IsVisibleOnAllWorkspaces() { return window_->IsVisibleOnAllWorkspaces(); } -void Window::SendInputEvent(v8::Isolate* isolate, - v8::Local input_event) { - int type = mate::GetWebInputEventType(isolate, input_event); - if (blink::WebInputEvent::isMouseEventType(type)) { - blink::WebMouseEvent mouse_event; - if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) { - window_->SendInputEvent(mouse_event); - return; - } - } else if (blink::WebInputEvent::isKeyboardEventType(type)) { - content::NativeWebKeyboardEvent keyboard_event;; - if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) { - window_->SendInputEvent(keyboard_event); - return; - } - } else if (type == blink::WebInputEvent::MouseWheel) { - blink::WebMouseWheelEvent mouse_wheel_event; - if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) { - window_->SendInputEvent(mouse_wheel_event); - return; - } - } - - isolate->ThrowException(v8::Exception::Error(mate::StringToV8( - isolate, "Invalid event type"))); -} - void Window::BeginFrameSubscription() { window_->SetFrameSubscription(true); } @@ -658,7 +628,6 @@ void Window::BuildPrototype(v8::Isolate* isolate, &Window::SetVisibleOnAllWorkspaces) .SetMethod("isVisibleOnAllWorkspaces", &Window::IsVisibleOnAllWorkspaces) - .SetMethod("sendInputEvent", &Window::SendInputEvent) .SetMethod("beginFrameSubscription", &Window::BeginFrameSubscription) .SetMethod("endFrameSubscription", &Window::EndFrameSubscription) #if defined(OS_MACOSX) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 507bbb4384..83322c16cb 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -142,7 +142,6 @@ class Window : public mate::TrackableObject, bool IsMenuBarVisible(); void SetAspectRatio(double aspect_ratio, mate::Arguments* args); - void SendInputEvent(v8::Isolate* isolate, v8::Local input_event); void BeginFrameSubscription(); void EndFrameSubscription(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 8095452554..eee53e352e 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -40,10 +40,6 @@ #include "ui/gfx/screen.h" #include "ui/gl/gpu_switching_manager.h" -using content::NavigationEntry; -using content::RenderWidgetHostView; -using content::RenderWidgetHost; - DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay); namespace atom { @@ -302,38 +298,6 @@ void NativeWindow::SetFrameSubscription(bool isOffscreen) { } } -void NativeWindow::SendInputEvent(const blink::WebMouseEvent& mouse_event) { - const auto view = web_contents()->GetRenderWidgetHostView(); - if (!view) - return; - const auto host = view->GetRenderWidgetHost(); - if (!host) - return; - host->ForwardMouseEvent(mouse_event); -} - -void NativeWindow::SendInputEvent( - const blink::WebMouseWheelEvent& mouse_wheel_event) { - const auto view = web_contents()->GetRenderWidgetHostView(); - if (!view) - return; - const auto host = view->GetRenderWidgetHost(); - if (!host) - return; - host->ForwardWheelEvent(mouse_wheel_event); -} - -void NativeWindow::SendInputEvent( - const content::NativeWebKeyboardEvent& keyboard_event) { - const auto view = web_contents()->GetRenderWidgetHostView(); - if (!view) - return; - const auto host = view->GetRenderWidgetHost(); - if (!host) - return; - host->ForwardKeyboardEvent(keyboard_event); -} - void NativeWindow::RequestToClosePage() { bool prevent_default = false; FOR_EACH_OBSERVER(NativeWindowObserver, diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 3344cfb65c..a593fdc3c2 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -26,11 +26,6 @@ class SkRegion; -namespace blink { -class WebMouseEvent; -class WebMouseWheelEvent; -} - namespace brightray { class InspectableWebContents; } @@ -179,11 +174,6 @@ class NativeWindow : public content::WebContentsObserver, // Subscribe to the frame updates. void SetFrameSubscription(bool isOffscreen); - // Send the WebInputEvent to the page. - void SendInputEvent(const blink::WebMouseEvent& mouse_event); - void SendInputEvent(const blink::WebMouseWheelEvent& mouse_wheel_event); - void SendInputEvent(const content::NativeWebKeyboardEvent& keyboard_event); - base::WeakPtr GetWeakPtr() { return weak_factory_.GetWeakPtr(); } From 86f523d3c13224f0a3dadac919ec25e24d4f8b80 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 15:57:43 +0800 Subject: [PATCH 33/41] Move BeginFrameSubscription to WebContents --- atom/browser/api/atom_api_web_contents.cc | 17 ++++++ atom/browser/api/atom_api_web_contents.h | 6 +++ atom/browser/api/atom_api_window.cc | 23 +------- atom/browser/api/atom_api_window.h | 4 -- atom/browser/api/frame_subscriber.cc | 66 +++++++++++++++++++++++ atom/browser/api/frame_subscriber.h | 45 ++++++++++++++++ atom/browser/native_window.cc | 56 ------------------- atom/browser/native_window.h | 37 ------------- atom/browser/native_window_observer.h | 2 - filenames.gypi | 2 + 10 files changed, 137 insertions(+), 121 deletions(-) create mode 100644 atom/browser/api/frame_subscriber.cc create mode 100644 atom/browser/api/frame_subscriber.h diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 43b20a3d71..1a9ffeb67f 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -850,7 +850,21 @@ void WebContents::SendInputEvent(v8::Isolate* isolate, isolate, "Invalid event type"))); } +void WebContents::BeginFrameSubscription( + const FrameSubscriber::FrameCaptureCallback& callback) { + const auto view = web_contents()->GetRenderWidgetHostView(); + if (view) { + scoped_ptr frame_subscriber(new FrameSubscriber( + isolate(), view->GetVisibleViewportSize(), callback)); + view->BeginFrameSubscription(frame_subscriber.Pass()); + } +} +void WebContents::EndFrameSubscription() { + const auto view = web_contents()->GetRenderWidgetHostView(); + if (view) + view->EndFrameSubscription(); +} void WebContents::SetSize(const SetSizeParams& params) { if (guest_delegate_) @@ -915,6 +929,9 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("tabTraverse", &WebContents::TabTraverse) .SetMethod("_send", &WebContents::SendIPCMessage, true) .SetMethod("sendInputEvent", &WebContents::SendInputEvent) + .SetMethod("beginFrameSubscription", + &WebContents::BeginFrameSubscription) + .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription) .SetMethod("setSize", &WebContents::SetSize) .SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency) .SetMethod("isGuest", &WebContents::IsGuest) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 6dc2660532..c8ea6908bc 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -8,6 +8,7 @@ #include #include +#include "atom/browser/api/frame_subscriber.h" #include "atom/browser/api/trackable_object.h" #include "atom/browser/common_web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" @@ -121,6 +122,11 @@ class WebContents : public mate::TrackableObject, // Send WebInputEvent to the page. void SendInputEvent(v8::Isolate* isolate, v8::Local input_event); + // Subscribe to the frame updates. + void BeginFrameSubscription( + const FrameSubscriber::FrameCaptureCallback& callback); + void EndFrameSubscription(); + // Methods for creating . void SetSize(const SetSizeParams& params); void SetAllowTransparency(bool allow); diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 985b6a7543..3a44115da2 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -13,6 +13,7 @@ #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" +#include "atom/common/node_includes.h" #include "atom/common/options_switches.h" #include "content/public/browser/render_process_host.h" #include "native_mate/constructor.h" @@ -24,8 +25,6 @@ #include "atom/browser/ui/win/taskbar_host.h" #endif -#include "atom/common/node_includes.h" - #if defined(OS_WIN) namespace mate { @@ -105,16 +104,6 @@ void Window::WillCloseWindow(bool* prevent_default) { *prevent_default = Emit("close"); } -void Window::OnFrameRendered(scoped_ptr rgb, const int size) { - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); - v8::MaybeLocal data = node::Buffer::New( - isolate(), - reinterpret_cast(rgb.release()), - static_cast(size)); - Emit("frame-rendered", data.ToLocalChecked(), size); -} - void Window::OnWindowClosed() { if (api_web_contents_) { api_web_contents_->DestroyWebContents(); @@ -536,14 +525,6 @@ bool Window::IsVisibleOnAllWorkspaces() { return window_->IsVisibleOnAllWorkspaces(); } -void Window::BeginFrameSubscription() { - window_->SetFrameSubscription(true); -} - -void Window::EndFrameSubscription() { - window_->SetFrameSubscription(false); -} - int32_t Window::ID() const { return weak_map_id(); } @@ -628,8 +609,6 @@ void Window::BuildPrototype(v8::Isolate* isolate, &Window::SetVisibleOnAllWorkspaces) .SetMethod("isVisibleOnAllWorkspaces", &Window::IsVisibleOnAllWorkspaces) - .SetMethod("beginFrameSubscription", &Window::BeginFrameSubscription) - .SetMethod("endFrameSubscription", &Window::EndFrameSubscription) #if defined(OS_MACOSX) .SetMethod("showDefinitionForSelection", &Window::ShowDefinitionForSelection) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 83322c16cb..d60bf0d87e 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -53,7 +53,6 @@ class Window : public mate::TrackableObject, void OnPageTitleUpdated(bool* prevent_default, const std::string& title) override; void WillCloseWindow(bool* prevent_default) override; - void OnFrameRendered(scoped_ptr rgb, const int size) override; void OnWindowClosed() override; void OnWindowBlur() override; void OnWindowFocus() override; @@ -142,9 +141,6 @@ class Window : public mate::TrackableObject, bool IsMenuBarVisible(); void SetAspectRatio(double aspect_ratio, mate::Arguments* args); - void BeginFrameSubscription(); - void EndFrameSubscription(); - #if defined(OS_MACOSX) void ShowDefinitionForSelection(); #endif diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc new file mode 100644 index 0000000000..526769f9cd --- /dev/null +++ b/atom/browser/api/frame_subscriber.cc @@ -0,0 +1,66 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/api/frame_subscriber.h" + +#include "atom/common/node_includes.h" +#include "base/bind.h" +#include "media/base/video_frame.h" +#include "media/base/yuv_convert.h" + +namespace atom { + +namespace api { + +FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, + const gfx::Size& size, + const FrameCaptureCallback& callback) + : isolate_(isolate), size_(size), callback_(callback) { +} + +bool FrameSubscriber::ShouldCaptureFrame( + const gfx::Rect& damage_rect, + base::TimeTicks present_time, + scoped_refptr* storage, + DeliverFrameCallback* callback) { + *storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_, + gfx::Rect(size_), size_, + base::TimeDelta()); + *callback = base::Bind(&FrameSubscriber::OnFrameDelivered, + base::Unretained(this), + *storage); + return true; +} + +void FrameSubscriber::OnFrameDelivered( + scoped_refptr frame, base::TimeTicks, bool result) { + if (!result) + return; + + gfx::Rect rect = frame->visible_rect(); + size_t rgb_arr_size = rect.width() * rect.height() * 4; + v8::MaybeLocal buffer = node::Buffer::New(isolate_, rgb_arr_size); + if (buffer.IsEmpty()) + return; + + // Convert a frame of YUV to 32 bit ARGB. + media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane), + frame->data(media::VideoFrame::kUPlane), + frame->data(media::VideoFrame::kVPlane), + reinterpret_cast( + node::Buffer::Data(buffer.ToLocalChecked())), + rect.width(), rect.height(), + frame->stride(media::VideoFrame::kYPlane), + frame->stride(media::VideoFrame::kUVPlane), + rect.width() * 4, + media::YV12); + + v8::Locker locker(isolate_); + v8::HandleScope handle_scope(isolate_); + callback_.Run(buffer.ToLocalChecked()); +} + +} // namespace api + +} // namespace atom diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h new file mode 100644 index 0000000000..f7748aa579 --- /dev/null +++ b/atom/browser/api/frame_subscriber.h @@ -0,0 +1,45 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_ +#define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_ + +#include "base/callback.h" +#include "content/public/browser/render_widget_host_view_frame_subscriber.h" +#include "ui/gfx/geometry/size.h" +#include "v8/include/v8.h" + +namespace atom { + +namespace api { + +class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { + public: + using FrameCaptureCallback = base::Callback)>; + + FrameSubscriber(v8::Isolate* isolate, + const gfx::Size& size, + const FrameCaptureCallback& callback); + + bool ShouldCaptureFrame(const gfx::Rect& damage_rect, + base::TimeTicks present_time, + scoped_refptr* storage, + DeliverFrameCallback* callback) override; + + private: + void OnFrameDelivered( + scoped_refptr frame, base::TimeTicks, bool); + + v8::Isolate* isolate_; + gfx::Size size_; + FrameCaptureCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(FrameSubscriber); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_ diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index eee53e352e..4d5f273340 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -8,7 +8,6 @@ #include #include -#include "media/base/yuv_convert.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/window_list.h" @@ -283,21 +282,6 @@ void NativeWindow::SetAspectRatio(double aspect_ratio, aspect_ratio_extraSize_ = extra_size; } -void NativeWindow::SetFrameSubscription(bool isOffscreen) { - const auto view = web_contents()->GetRenderWidgetHostView(); - if (view) { - if (isOffscreen) { - scoped_ptr subscriber( - new RenderSubscriber( - view->GetVisibleViewportSize(), - base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)))); - view->BeginFrameSubscription(subscriber.Pass()); - } else { - view->EndFrameSubscription(); - } - } -} - void NativeWindow::RequestToClosePage() { bool prevent_default = false; FOR_EACH_OBSERVER(NativeWindowObserver, @@ -517,44 +501,4 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, callback.Run(bitmap); } -void NativeWindow::OnFrameReceived(bool result, - scoped_refptr frame) { - if (result) { - gfx::Rect rect = frame->visible_rect(); - - const int rgb_arr_size = rect.width() * rect.height() * 4; - scoped_ptr rgb_bytes(new uint8[rgb_arr_size]); - - // Convert a frame of YUV to 32 bit ARGB. - media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane), - frame->data(media::VideoFrame::kUPlane), - frame->data(media::VideoFrame::kVPlane), - rgb_bytes.get(), - rect.width(), rect.height(), - frame->stride(media::VideoFrame::kYPlane), - frame->stride(media::VideoFrame::kUVPlane), - rect.width() * 4, - media::YV12); - - FOR_EACH_OBSERVER(NativeWindowObserver, - observers_, - OnFrameRendered(rgb_bytes.Pass(), rgb_arr_size)); - } -} - -bool RenderSubscriber::ShouldCaptureFrame( - const gfx::Rect& damage_rect, - base::TimeTicks present_time, - scoped_refptr* storage, - DeliverFrameCallback* callback) { - last_present_time_ = present_time; - *storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_, - gfx::Rect(size_), size_, - base::TimeDelta()); - - *callback = - base::Bind(&RenderSubscriber::CallbackMethod, callback_, *storage); - return true; -} - } // namespace atom diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index a593fdc3c2..e9a2b9433d 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -9,8 +9,6 @@ #include #include -#include "media/base/video_frame.h" -#include "content/public/browser/render_widget_host_view_frame_subscriber.h" #include "atom/browser/native_window_observer.h" #include "atom/browser/ui/accelerator_util.h" #include "base/cancelable_callback.h" @@ -171,9 +169,6 @@ class NativeWindow : public content::WebContentsObserver, gfx::Size GetAspectRatioExtraSize(); void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size); - // Subscribe to the frame updates. - void SetFrameSubscription(bool isOffscreen); - base::WeakPtr GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -228,8 +223,6 @@ class NativeWindow : public content::WebContentsObserver, has_dialog_attached_ = has_dialog_attached; } - void OnFrameReceived(bool result, scoped_refptr frame); - protected: NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, const mate::Dictionary& options); @@ -303,36 +296,6 @@ class NativeWindow : public content::WebContentsObserver, DISALLOW_COPY_AND_ASSIGN(NativeWindow); }; -// This class provides a way to listen to frame renders and to use the rendered -// frames for offscreen rendering -class RenderSubscriber : public content::RenderWidgetHostViewFrameSubscriber { - public: - RenderSubscriber( - gfx::Size size, - base::Callback)> callback) - : size_(size), callback_(callback) {} - - bool ShouldCaptureFrame(const gfx::Rect& damage_rect, - base::TimeTicks present_time, - scoped_refptr* storage, - DeliverFrameCallback* callback) override; - - base::TimeTicks last_present_time() const { return last_present_time_; } - - static void CallbackMethod( - base::Callback)> callback, - scoped_refptr frame, - base::TimeTicks present_time, - bool success) { - callback.Run(success, frame); - } - - private: - gfx::Size size_; - base::Callback)> callback_; - base::TimeTicks last_present_time_; -}; - // This class provides a hook to get a NativeWindow from a WebContents. class NativeWindowRelay : public content::WebContentsUserData { diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index db6587de1f..5b0a0c56b3 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -27,8 +27,6 @@ class NativeWindowObserver { const std::string& partition_id, WindowOpenDisposition disposition) {} - virtual void OnFrameRendered(scoped_ptr rgb, const int size) {} - // Called when user is starting an navigation in web page. virtual void WillNavigate(bool* prevent_default, const GURL& url) {} diff --git a/filenames.gypi b/filenames.gypi index f25ec4a8a5..99d6bc6d50 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -103,6 +103,8 @@ 'atom/browser/api/event_emitter.h', 'atom/browser/api/trackable_object.cc', 'atom/browser/api/trackable_object.h', + 'atom/browser/api/frame_subscriber.cc', + 'atom/browser/api/frame_subscriber.h', 'atom/browser/auto_updater.cc', 'atom/browser/auto_updater.h', 'atom/browser/auto_updater_delegate.h', From 573892c1125e54f1853c0ece03192e265fcab185 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 17:44:11 +0800 Subject: [PATCH 34/41] docs: webContents.sendInputEvent --- docs/api/browser-window.md | 64 -------------------------------------- docs/api/web-contents.md | 40 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 64 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 6a168e9e79..2868209ab2 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -244,15 +244,6 @@ Emitted when DevTools is closed. Emitted when DevTools is focused / opened. -### Event: 'frame-rendered' - -* `event` Event -* `frame` Buffer -* `size` Number - -Emitted when *offscreen render* is enabled, the current frame's pixel data -and size are available. - ### Event: 'app-command': Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx) @@ -791,58 +782,3 @@ fired when the window receives a new frame from the renderer. Enables offscreen rendering, after this call `frame-rendered` events will no longer be fired if offscreen rendering was enabled before. - -### BrowserWindow.sendMouseEvent(options) - -Sends a mouse event to the BrowserWindow. -* `options` Object - * `type` String - The type of the mouse event. - * `down` String - Mouse down event. - * `up` String - Mouse up event. - * `move` String - Mouse move event. - * `enter` String - Mouse enter event. - * `leave` String - Mouse leave event. - * `context-menu` String - Context menu event. - * `wheel` String - Mouse wheel event. - * `x` Integer - The x component of the location of the mouse event. - * `y` Integer - The y component of the location of the mouse event. - * `movement-x` Integer - The x component of the mouse movement since the last event. - * `movement-y` Integer - The y component of the mouse movement since the last event. - * `button` String - The mouse button associated with the mouse event. Also sets the associated modifier values on the event. - * `left` String - The left button was pressed. - * `right` String - The right button was pressed. - * `middle` String - The middle button was pressed. - * `click-count` Integer - The number of clicks associated with the mouse event. - * `precise` Boolean - For the `wheel` event type, this option sets the `hasPreciseScrollingDeltas` option of the event. - * `modifiers` Object - The modifier values associated with the event. - * `left-button-down` Boolean - The left mouse button was pressed. - * `middle-button-down` Boolean - The right mouse button was pressed. - * `right-button-down` Boolean - The middle mouse button was pressed. - * `shift` Boolean - The shift key was pressed. - * `control` Boolean - The control key was pressed. - * `alt` Boolean - The alt key was pressed. - * `meta` Boolean - The meta key was pressed. - * `caps-lock` Boolean - The caps-lock key was on. - * `num-lock` Boolean - The num-lock key was on. - -### BrowserWindow.sendKeyboardEvent(options) - -Sends a keyboard event to the BrowserWindow. -* `options` Object - * `type` String - The type of the keyboard event. - * `down` String - Key down event. - * `up` String - Key up event. - * `char` String - Character event. - * `code` Integer - The key code of the key that generated the event. - * `native` Integer - The native key code of the key that generated the event. - * `modifiers` Object - The modifier values associated with the event. - * `keypad` Boolean - Sets the `IsKeyPad` option of the event. - * `auto-repeat` Boolean - Sets the `IsAutoRepeat` option of the event. - * `left` Boolean - Sets the `IsLeft` option of the event. - * `right` Boolean - Sets the `IsRight` option of the event. - * `shift` Boolean - The shift key was pressed. - * `control` Boolean - The control key was pressed. - * `alt` Boolean - The alt key was pressed. - * `meta` Boolean - The meta key was pressed. - * `caps-lock` Boolean - The caps-lock key was on. - * `num-lock` Boolean - The num-lock key was on. diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 8b4ebcc337..1a9043752f 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -511,3 +511,43 @@ Enable device emulation with the given parameters. ### `webContents.disableDeviceEmulation()` Disable device emulation enabled by `webContents.enableDeviceEmulation`. + +### `webContents.sendInputEvent(event)` + +* `event` Object + * `type` String (**required**) - The type of the event, can be `mouseDown`, + `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, + `keyDown`, `keyUp`, `char`. + * `modifiers` Array - An array of modifiers of the event, can + include `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, + `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`, + `numLock`, `left`, `right`. + +Sends an input `event` to the page. + +For keyboard events, the `event` object also have following properties: + +* `keyCode` String (**required**) - A single character that will be sent as + keyboard event. Can be any ASCII character on the keyboard, like `a`, `1` + and `=`. + +For mouse events, the `event` object also have following properties: + +* `x` Integer (**required**) +* `y` Integer (**required**) +* `globalX` Integer +* `globalY` Integer +* `movementX` Integer +* `movementY` Integer +* `clickCount` Integer + +For the `mouseWheel` event, the `event` object also have following properties: + +* `deltaX` Integer +* `deltaY` Integer +* `wheelTicksX` Integer +* `wheelTicksY` Integer +* `accelerationRatioX` Integer +* `accelerationRatioY` Integer +* `hasPreciseScrollingDeltas` Boolean +* `canScroll` Boolean From 1e918480b44b9cf9b65434ccfd4899dfb199f177 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 17:53:19 +0800 Subject: [PATCH 35/41] docs: webContents.beginFrameSubscription --- docs/api/browser-window.md | 10 ---------- docs/api/web-contents.md | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 2868209ab2..f1705c2917 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -772,13 +772,3 @@ Sets whether the window should be visible on all workspaces. Returns whether the window is visible on all workspaces. **Note:** This API always returns false on Windows. - -### BrowserWindow.beginFrameSubscription() - -Enables offscreen rendering, after this call `frame-rendered` events will be -fired when the window receives a new frame from the renderer. - -### BrowserWindow.endFrameSubscription() - -Enables offscreen rendering, after this call `frame-rendered` events will -no longer be fired if offscreen rendering was enabled before. diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 1a9043752f..e8f72cd24b 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -551,3 +551,17 @@ For the `mouseWheel` event, the `event` object also have following properties: * `accelerationRatioY` Integer * `hasPreciseScrollingDeltas` Boolean * `canScroll` Boolean + +### `webContents.beginFrameSubscription(callback)` + +* `callback` Function + +Begin subscribing for presentation events and captured frames, the `callback` +will be called with `callback(frameBuffer)` when there is a presentation event. + +The `frameBuffer` is a `Buffer` that contains raw pixel data, in the format of +32bit ARGB. + +### `webContents.endFrameSubscription()` + +End subscribing for frame presentation events. From ff0e15bf58c5f090653b88e3be5216cc740622e4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 17:55:42 +0800 Subject: [PATCH 36/41] Expose sendInputEvent in webview --- atom/renderer/lib/web-view/web-view.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index f5bcf0496f..65e4501975 100644 --- a/atom/renderer/lib/web-view/web-view.coffee +++ b/atom/renderer/lib/web-view/web-view.coffee @@ -292,6 +292,7 @@ registerWebViewElement = -> "inspectServiceWorker" "print" "printToPDF" + "sendInputEvent" ] # Forward proto.foo* method calls to WebViewImpl.foo*. From 7b2980434c7970695165deaf47ecaea5ae0f1740 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 18:21:51 +0800 Subject: [PATCH 37/41] Fix wrong return values in a few converters --- atom/browser/api/atom_api_web_contents.cc | 2 +- .../native_mate_converters/blink_converter.cc | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1a9ffeb67f..9791a94bb7 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -847,7 +847,7 @@ void WebContents::SendInputEvent(v8::Isolate* isolate, } isolate->ThrowException(v8::Exception::Error(mate::StringToV8( - isolate, "Invalid event type"))); + isolate, "Invalid event object"))); } void WebContents::BeginFrameSubscription( diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index a406059cf6..67c7e7e95f 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -73,7 +73,7 @@ struct Converter { *out = blink::WebInputEvent::TouchEnd; else if (type == "touchcancel") *out = blink::WebInputEvent::TouchCancel; - return false; + return true; } }; @@ -108,12 +108,12 @@ struct Converter { *out = blink::WebInputEvent::IsLeft; else if (modifier == "right") *out = blink::WebInputEvent::IsRight; - return false; + return true; } }; int GetWebInputEventType(v8::Isolate* isolate, v8::Local val) { - int type = -1; + blink::WebInputEvent::Type type = blink::WebInputEvent::Undefined; mate::Dictionary dict; ConvertFromV8(isolate, val, &dict) && dict.Get("type", &type); return type; @@ -152,7 +152,7 @@ bool Converter::FromV8( if (shifted) out->modifiers |= blink::WebInputEvent::ShiftKey; out->setKeyIdentifierFromWindowsKeyCode(); - return false; + return true; } bool Converter::FromV8( @@ -164,7 +164,7 @@ bool Converter::FromV8( if (!ConvertFromV8(isolate, val, static_cast(out))) return false; dict.Get("skipInBrowser", &out->skip_in_browser); - return false; + return true; } bool Converter::FromV8( @@ -181,7 +181,7 @@ bool Converter::FromV8( dict.Get("movementX", &out->movementX); dict.Get("movementY", &out->movementY); dict.Get("clickCount", &out->clickCount); - return false; + return true; } bool Converter::FromV8( @@ -200,7 +200,7 @@ bool Converter::FromV8( dict.Get("accelerationRatioY", &out->accelerationRatioY); dict.Get("hasPreciseScrollingDeltas", &out->hasPreciseScrollingDeltas); dict.Get("canScroll", &out->canScroll); - return false; + return true; } bool Converter::FromV8( From b8d50f3a3a9acdcbe434eb42901af3083234ec44 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 18:28:34 +0800 Subject: [PATCH 38/41] spec: Add test for sendInputEvent --- spec/fixtures/pages/onkeyup.html | 9 +++++++++ spec/fixtures/pages/onmouseup.html | 9 +++++++++ spec/webview-spec.coffee | 23 +++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 spec/fixtures/pages/onkeyup.html create mode 100644 spec/fixtures/pages/onmouseup.html diff --git a/spec/fixtures/pages/onkeyup.html b/spec/fixtures/pages/onkeyup.html new file mode 100644 index 0000000000..99e6c3e983 --- /dev/null +++ b/spec/fixtures/pages/onkeyup.html @@ -0,0 +1,9 @@ + + + + + diff --git a/spec/fixtures/pages/onmouseup.html b/spec/fixtures/pages/onmouseup.html new file mode 100644 index 0000000000..1fd38bc721 --- /dev/null +++ b/spec/fixtures/pages/onmouseup.html @@ -0,0 +1,9 @@ + + + + + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index e4b40c28eb..b310b7b129 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -336,3 +336,26 @@ describe ' tag', -> webview.addEventListener 'did-finish-load', listener2 webview.src = "file://#{fixtures}/pages/fullscreen.html" document.body.appendChild webview + + describe 'sendInputEvent', -> + it 'can send keyboard event', (done) -> + webview.addEventListener 'ipc-message', (e) -> + assert.equal e.channel, 'keyup' + assert.deepEqual e.args, [67, true, false] + done() + webview.addEventListener 'dom-ready', -> + webview.sendInputEvent type: 'keyup', keyCode: 'c', modifiers: ['shift'] + webview.src = "file://#{fixtures}/pages/onkeyup.html" + webview.setAttribute 'nodeintegration', 'on' + document.body.appendChild webview + + it 'can send mouse event', (done) -> + webview.addEventListener 'ipc-message', (e) -> + assert.equal e.channel, 'mouseup' + assert.deepEqual e.args, [10, 20, false, true] + done() + webview.addEventListener 'dom-ready', -> + webview.sendInputEvent type: 'mouseup', modifiers: ['ctrl'], x: 10, y: 20 + webview.src = "file://#{fixtures}/pages/onmouseup.html" + webview.setAttribute 'nodeintegration', 'on' + document.body.appendChild webview From 32bff05208fd73afa0d9a3381c23f79fe421a05b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 18:32:21 +0800 Subject: [PATCH 39/41] docs: .sendInputEvent --- docs/api/web-view-tag.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 4647413b5a..8eb3857ac9 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -358,6 +358,15 @@ page can handle it by listening to the `channel` event of `ipc` module. See [WebContents.send](web-contents.md#webcontentssendchannel-args) for examples. +### `.sendInputEvent(event)` + +* `event` Object + +Sends an input `event` to the page. + +See [WebContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent) +for detailed description of `event` object. + ## DOM events The following DOM events are available to the `webview` tag: From 353cdd967a430940f131079c0e4a416e3409354b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 18:51:49 +0800 Subject: [PATCH 40/41] spec: Add test for webContents.beginFrameSubscription --- spec/api-browser-window-spec.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 3e4e2d5db5..846b8bdbc9 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -303,3 +303,11 @@ describe 'browser-window module', -> assert.equal url, 'https://www.github.com/' done() w.loadUrl "file://#{fixtures}/pages/will-navigate.html" + + describe 'beginFrameSubscription method', -> + it 'subscribes frame updates', (done) -> + w.loadUrl "file://#{fixtures}/api/blank.html" + w.webContents.beginFrameSubscription (data) -> + assert.notEqual data.length, 0 + w.webContents.endFrameSubscription() + done() From f716d47e546034d6adaf910fd62b0a6dd203caf7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 18 Sep 2015 18:57:48 +0800 Subject: [PATCH 41/41] spec: Make the will-navigate test run faster --- spec/api-browser-window-spec.coffee | 10 +++++----- spec/fixtures/pages/will-navigate.html | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 846b8bdbc9..bb4d782e7f 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -295,14 +295,14 @@ describe 'browser-window module', -> w.minimize() describe 'will-navigate event', -> - return if isCI and process.platform is 'darwin' + @timeout 10000 it 'emits when user starts a navigation', (done) -> - @timeout 10000 - w.webContents.on 'will-navigate', (event, url) -> + url = "file://#{fixtures}/pages/will-navigate.html" + w.webContents.on 'will-navigate', (event, u) -> event.preventDefault() - assert.equal url, 'https://www.github.com/' + assert.equal u, url done() - w.loadUrl "file://#{fixtures}/pages/will-navigate.html" + w.loadUrl url describe 'beginFrameSubscription method', -> it 'subscribes frame updates', (done) -> diff --git a/spec/fixtures/pages/will-navigate.html b/spec/fixtures/pages/will-navigate.html index bd2ebdc1cb..8d0c9b779e 100644 --- a/spec/fixtures/pages/will-navigate.html +++ b/spec/fixtures/pages/will-navigate.html @@ -1,7 +1,7 @@