Mouse event handling and keyboard event handling (not totally working yet)

This commit is contained in:
Heilig Benedek 2015-08-31 18:32:33 +02:00
parent e4c01f3187
commit c59c0bd5b3
9 changed files with 330 additions and 3 deletions

View file

@ -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<std::string> 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<std::string>::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<std::string> 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<std::string>::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)

View file

@ -138,6 +138,8 @@ class Window : public mate::TrackableObject<Window>,
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();

View file

@ -9,6 +9,8 @@
#include <vector>
#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<content::RenderWidgetHostViewFrameSubscriber> subscriber(new RenderSubscriber(
view->GetVisibleViewportSize(), base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this))
));

View file

@ -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<media::VideoFrame> 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;

View file

@ -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

48
atom/common/event_types.h Normal file
View file

@ -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_

View file

@ -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

View file

@ -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

View file

@ -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',