diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index d4cb6cd227d5..9791a94bb77b 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,56 @@ 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 object"))); +} + +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_) guest_delegate_->SetSize(params); @@ -875,6 +928,10 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("focus", &WebContents::Focus) .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 0ce47237e494..c8ea6908bc5b 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" @@ -114,10 +115,18 @@ 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); + + // 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 6d6316d91312..3a44115da264 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -8,28 +8,23 @@ #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" #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/node_includes.h" #include "atom/common/options_switches.h" #include "content/public/browser/render_process_host.h" #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" #include "atom/browser/ui/win/taskbar_host.h" #endif -#include "atom/common/node_includes.h" - #if defined(OS_WIN) namespace mate { @@ -109,15 +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()); - - auto data = node::Buffer::New(isolate(), reinterpret_cast(rgb.get()), static_cast(size)); - - Emit("frame-rendered", data, size); -} - void Window::OnWindowClosed() { if (api_web_contents_) { api_web_contents_->DestroyWebContents(); @@ -463,14 +449,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); } @@ -547,127 +525,6 @@ 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); - } - } -} - int32_t Window::ID() const { return weak_map_id(); } @@ -752,10 +609,6 @@ void Window::BuildPrototype(v8::Isolate* isolate, &Window::SetVisibleOnAllWorkspaces) .SetMethod("isVisibleOnAllWorkspaces", &Window::IsVisibleOnAllWorkspaces) - .SetMethod("sendMouseEvent", &Window::SendMouseEvent) - .SetMethod("sendKeyboardEvent", &Window::SendKeyboardEvent) - .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 6dfcbee8bc88..d60bf0d87ea0 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,11 +141,6 @@ 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 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 000000000000..526769f9cd6c --- /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 000000000000..f7748aa5790d --- /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 b88c37576d08..4d5f273340ab 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -8,11 +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" #include "atom/browser/window_list.h" @@ -43,11 +38,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; -using content::RenderWidgetHost; DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay); @@ -112,9 +102,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; } @@ -167,9 +156,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); @@ -210,38 +196,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_; } @@ -296,27 +250,36 @@ void NativeWindow::CapturePage(const gfx::Rect& rect, kBGRA_8888_SkColorType); } -void NativeWindow::SetFrameSubscription(bool isOffscreen) { - if (!isOffscreen && !offscreen_) return; +void NativeWindow::ShowDefinitionForSelection() { + NOTIMPLEMENTED(); +} - const auto view = web_contents()->GetRenderWidgetHostView(); +void NativeWindow::SetAutoHideMenuBar(bool auto_hide) { +} - if (view) { - if (isOffscreen) { - scoped_ptr subscriber( - new RenderSubscriber( - view->GetVisibleViewportSize(), - base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this)) - ) - ); +bool NativeWindow::IsMenuBarAutoHide() { + return false; +} - view->BeginFrameSubscription(subscriber.Pass()); - } else { - view->EndFrameSubscription(); - } +void NativeWindow::SetMenuBarVisibility(bool visible) { +} - offscreen_ = isOffscreen; - } +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::RequestToClosePage() { @@ -461,69 +424,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::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { - SetFrameSubscription(offscreen_); -} - void NativeWindow::RenderViewCreated( content::RenderViewHost* render_view_host) { if (!transparent_) @@ -601,43 +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 e7de4ebc6556..e9a2b9433d13 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -9,10 +9,6 @@ #include #include -#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" @@ -227,14 +223,6 @@ class NativeWindow : public content::WebContentsObserver, has_dialog_attached_ = has_dialog_attached; } - 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); @@ -246,7 +234,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 +254,6 @@ class NativeWindow : public content::WebContentsObserver, const SkBitmap& bitmap, content::ReadbackResponse response); - bool offscreen_; - // Whether window has standard frame. bool has_frame_; @@ -311,31 +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 db6587de1f44..5b0a0c56b3de 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/atom/browser/ui/accelerator_util.cc b/atom/browser/ui/accelerator_util.cc index 41dde7acf732..e25e14b7968c 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/event_types.cc b/atom/common/event_types.cc deleted file mode 100644 index be0848128980..000000000000 --- 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 d4769db2d78b..000000000000 --- 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/keyboad_util.cc b/atom/common/keyboad_util.cc new file mode 100644 index 000000000000..1baa829ff74a --- /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 000000000000..0496886e40bd --- /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 5d3ff62086ca..67c7e7e95fd8 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -5,13 +5,204 @@ #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 true; + } +}; + +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 true; + } +}; + +int GetWebInputEventType(v8::Isolate* isolate, v8::Local val) { + blink::WebInputEvent::Type type = blink::WebInputEvent::Undefined; + 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) { + 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 true; +} + +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 true; +} + +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 true; +} + +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 true; +} + 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 bbd2af0e679f..17bb108d349e 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -8,14 +8,54 @@ #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 { +int GetWebInputEventType(v8::Isolate* isolate, v8::Local val); + +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/atom/common/options_switches.cc b/atom/common/options_switches.cc index 75688ec45bf7..c70e1ba4afa6 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -116,19 +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"; - -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 6ce6d7f4eddc..e62f3116661a 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -62,19 +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[]; - -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/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index f5bcf0496f8c..65e4501975fe 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*. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 6a168e9e79ec..f1705c291756 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) @@ -781,68 +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. - -### 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 8b4ebcc33784..e8f72cd24bf2 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -511,3 +511,57 @@ 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 + +### `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. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 4647413b5a43..8eb3857ac970 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: diff --git a/filenames.gypi b/filenames.gypi index 30668f20a720..99d6bc6d50d3 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', @@ -283,6 +285,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', @@ -311,8 +315,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', diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 3e4e2d5db5e2..bb4d782e7ffb 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -295,11 +295,19 @@ 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 url + + 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() - w.loadUrl "file://#{fixtures}/pages/will-navigate.html" diff --git a/spec/fixtures/pages/onkeyup.html b/spec/fixtures/pages/onkeyup.html new file mode 100644 index 000000000000..99e6c3e98382 --- /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 000000000000..1fd38bc7211f --- /dev/null +++ b/spec/fixtures/pages/onmouseup.html @@ -0,0 +1,9 @@ + + + + + diff --git a/spec/fixtures/pages/will-navigate.html b/spec/fixtures/pages/will-navigate.html index bd2ebdc1cb43..8d0c9b779e2d 100644 --- a/spec/fixtures/pages/will-navigate.html +++ b/spec/fixtures/pages/will-navigate.html @@ -1,7 +1,7 @@ diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index e4b40c28ebeb..b310b7b129f8 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