feat: replace scroll-touch* with generic input-event (#35531)

This commit is contained in:
Jeremy Rose 2022-09-27 14:47:46 -05:00 committed by GitHub
parent dfb8a2d804
commit f82a863f65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 253 additions and 138 deletions

View file

@ -247,14 +247,6 @@ void BaseWindow::OnWindowLeaveFullScreen() {
Emit("leave-full-screen");
}
void BaseWindow::OnWindowScrollTouchBegin() {
Emit("scroll-touch-begin");
}
void BaseWindow::OnWindowScrollTouchEnd() {
Emit("scroll-touch-end");
}
void BaseWindow::OnWindowSwipe(const std::string& direction) {
Emit("swipe", direction);
}

View file

@ -68,8 +68,6 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
bool* prevent_default) override;
void OnWindowMove() override;
void OnWindowMoved() override;
void OnWindowScrollTouchBegin() override;
void OnWindowScrollTouchEnd() override;
void OnWindowSwipe(const std::string& direction) override;
void OnWindowRotateGesture(float rotation) override;
void OnWindowSheetBegin() override;

View file

@ -106,10 +106,6 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
// Associate with BrowserWindow.
web_contents->SetOwnerWindow(window());
auto* host = web_contents->web_contents()->GetRenderViewHost();
if (host)
host->GetWidget()->AddInputEventObserver(this);
InitWithArgs(args);
// Install the content view after BaseWindow's JS code is initialized.
@ -128,9 +124,6 @@ BrowserWindow::~BrowserWindow() {
if (api_web_contents_) {
// Cleanup the observers if user destroyed this instance directly instead of
// gracefully closing content::WebContents.
auto* host = web_contents()->GetRenderViewHost();
if (host)
host->GetWidget()->RemoveInputEventObserver(this);
api_web_contents_->RemoveObserver(this);
// Destroy the WebContents.
OnCloseContents();
@ -138,26 +131,6 @@ BrowserWindow::~BrowserWindow() {
}
}
void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) {
switch (event.GetType()) {
case blink::WebInputEvent::Type::kGestureScrollBegin:
case blink::WebInputEvent::Type::kGestureScrollUpdate:
case blink::WebInputEvent::Type::kGestureScrollEnd:
Emit("scroll-touch-edge");
break;
default:
break;
}
}
void BrowserWindow::RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) {
if (old_host)
old_host->GetWidget()->RemoveInputEventObserver(this);
if (new_host)
new_host->GetWidget()->AddInputEventObserver(this);
}
void BrowserWindow::BeforeUnloadDialogCancelled() {
WindowList::WindowCloseCancelled(window());
// Cancel unresponsive event when window close is cancelled.

View file

@ -17,7 +17,6 @@
namespace electron::api {
class BrowserWindow : public BaseWindow,
public content::RenderWidgetHost::InputEventObserver,
public content::WebContentsObserver,
public ExtendedWebContentsObserver {
public:
@ -43,12 +42,7 @@ class BrowserWindow : public BaseWindow,
BrowserWindow(gin::Arguments* args, const gin_helper::Dictionary& options);
~BrowserWindow() override;
// content::RenderWidgetHost::InputEventObserver:
void OnInputEvent(const blink::WebInputEvent& event) override;
// content::WebContentsObserver:
void RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) override;
void BeforeUnloadDialogCancelled() override;
void OnRendererUnresponsive(content::RenderProcessHost*) override;
void OnRendererResponsive(

View file

@ -820,6 +820,12 @@ void WebContents::InitZoomController(content::WebContents* web_contents,
double zoom_factor;
if (options.Get(options::kZoomFactor, &zoom_factor))
zoom_controller_->SetDefaultZoomFactor(zoom_factor);
// Nothing to do with ZoomController, but this function gets called in all
// init cases!
content::RenderViewHost* host = web_contents->GetRenderViewHost();
if (host)
host->GetWidget()->AddInputEventObserver(this);
}
void WebContents::InitWithSessionAndOptions(
@ -957,6 +963,12 @@ void WebContents::InitWithWebContents(
}
WebContents::~WebContents() {
if (web_contents()) {
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->GetWidget()->RemoveInputEventObserver(this);
}
if (!inspectable_web_contents_) {
WebContentsDestroyed();
return;
@ -1273,7 +1285,12 @@ content::KeyboardEventProcessingResult WebContents::PreHandleKeyboardEvent(
if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown ||
event.GetType() == blink::WebInputEvent::Type::kKeyUp) {
bool prevent_default = Emit("before-input-event", event);
// For backwards compatibility, pretend that `kRawKeyDown` events are
// actually `kKeyDown`.
content::NativeWebKeyboardEvent tweaked_event(event);
if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown)
tweaked_event.SetType(blink::WebInputEvent::Type::kKeyDown);
bool prevent_default = Emit("before-input-event", tweaked_event);
if (prevent_default) {
return content::KeyboardEventProcessingResult::HANDLED;
}
@ -1684,6 +1701,14 @@ void WebContents::OnWebContentsLostFocus(
Emit("blur");
}
void WebContents::RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) {
if (old_host)
old_host->GetWidget()->RemoveInputEventObserver(this);
if (new_host)
new_host->GetWidget()->AddInputEventObserver(this);
}
void WebContents::DOMContentLoaded(
content::RenderFrameHost* render_frame_host) {
auto* web_frame = WebFrameMain::FromRenderFrameHost(render_frame_host);
@ -3060,6 +3085,9 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
blink::WebKeyboardEvent::Type::kRawKeyDown,
blink::WebInputEvent::Modifiers::kNoModifiers, ui::EventTimeForNow());
if (gin::ConvertFromV8(isolate, input_event, &keyboard_event)) {
// For backwards compatibility, convert `kKeyDown` to `kRawKeyDown`.
if (keyboard_event.GetType() == blink::WebKeyboardEvent::Type::kKeyDown)
keyboard_event.SetType(blink::WebKeyboardEvent::Type::kRawKeyDown);
rwh->ForwardKeyboardEvent(keyboard_event);
return;
}
@ -3466,6 +3494,10 @@ void WebContents::SetImageAnimationPolicy(const std::string& new_policy) {
web_contents()->OnWebPreferencesChanged();
}
void WebContents::OnInputEvent(const blink::WebInputEvent& event) {
Emit("input-event", event);
}
v8::Local<v8::Promise> WebContents::GetProcessMemoryInfo(v8::Isolate* isolate) {
gin_helper::Promise<gin_helper::Dictionary> promise(isolate);
v8::Local<v8::Promise> handle = promise.GetHandle();

View file

@ -103,6 +103,7 @@ class WebContents : public ExclusiveAccessContext,
public gin_helper::CleanedUpAtExit,
public content::WebContentsObserver,
public content::WebContentsDelegate,
public content::RenderWidgetHost::InputEventObserver,
public InspectableWebContentsDelegate,
public InspectableWebContentsViewDelegate {
public:
@ -433,6 +434,9 @@ class WebContents : public ExclusiveAccessContext,
void SetImageAnimationPolicy(const std::string& new_policy);
// content::RenderWidgetHost::InputEventObserver:
void OnInputEvent(const blink::WebInputEvent& event) override;
// disable copy
WebContents(const WebContents&) = delete;
WebContents& operator=(const WebContents&) = delete;
@ -616,6 +620,8 @@ class WebContents : public ExclusiveAccessContext,
content::RenderWidgetHost* render_widget_host) override;
void OnWebContentsLostFocus(
content::RenderWidgetHost* render_widget_host) override;
void RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) override;
// InspectableWebContentsDelegate:
void DevToolsReloadPage() override;

View file

@ -603,16 +603,6 @@ void NativeWindow::NotifyWindowEnterFullScreen() {
observer.OnWindowEnterFullScreen();
}
void NativeWindow::NotifyWindowScrollTouchBegin() {
for (NativeWindowObserver& observer : observers_)
observer.OnWindowScrollTouchBegin();
}
void NativeWindow::NotifyWindowScrollTouchEnd() {
for (NativeWindowObserver& observer : observers_)
observer.OnWindowScrollTouchEnd();
}
void NativeWindow::NotifyWindowSwipe(const std::string& direction) {
for (NativeWindowObserver& observer : observers_)
observer.OnWindowSwipe(direction);

View file

@ -291,8 +291,6 @@ class NativeWindow : public base::SupportsUserData,
void NotifyWindowResized();
void NotifyWindowWillMove(const gfx::Rect& new_bounds, bool* prevent_default);
void NotifyWindowMoved();
void NotifyWindowScrollTouchBegin();
void NotifyWindowScrollTouchEnd();
void NotifyWindowSwipe(const std::string& direction);
void NotifyWindowRotateGesture(float rotation);
void NotifyWindowSheetBegin();

View file

@ -228,9 +228,6 @@ class NativeWindowMac : public NativeWindow,
base::scoped_nsobject<ElectronPreviewItem> preview_item_;
base::scoped_nsobject<ElectronTouchBar> touch_bar_;
// Event monitor for scroll wheel event.
id wheel_event_monitor_;
// The NSView that used as contentView of window.
//
// For frameless window it would fill the whole window.

View file

@ -418,32 +418,6 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor);
[window_ setDisableAutoHideCursor:disableAutoHideCursor];
// Use an NSEvent monitor to listen for the wheel event.
BOOL __block began = NO;
wheel_event_monitor_ = [NSEvent
addLocalMonitorForEventsMatchingMask:NSEventMaskScrollWheel
handler:^(NSEvent* event) {
if ([[event window] windowNumber] !=
[window_ windowNumber])
return event;
if (!began && (([event phase] ==
NSEventPhaseMayBegin) ||
([event phase] ==
NSEventPhaseBegan))) {
this->NotifyWindowScrollTouchBegin();
began = YES;
} else if (began &&
(([event phase] ==
NSEventPhaseEnded) ||
([event phase] ==
NSEventPhaseCancelled))) {
this->NotifyWindowScrollTouchEnd();
began = NO;
}
return event;
}];
// Set maximizable state last to ensure zoom button does not get reset
// by calls to other APIs.
SetMaximizable(maximizable);
@ -1725,10 +1699,6 @@ void NativeWindowMac::Cleanup() {
DCHECK(!IsClosed());
ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
display::Screen::GetScreen()->RemoveObserver(this);
if (wheel_event_monitor_) {
[NSEvent removeMonitor:wheel_event_monitor_];
wheel_event_monitor_ = nil;
}
}
void NativeWindowMac::OverrideNSWindowContentView() {

View file

@ -81,8 +81,6 @@ class NativeWindowObserver : public base::CheckedObserver {
bool* prevent_default) {}
virtual void OnWindowMove() {}
virtual void OnWindowMoved() {}
virtual void OnWindowScrollTouchBegin() {}
virtual void OnWindowScrollTouchEnd() {}
virtual void OnWindowSwipe(const std::string& direction) {}
virtual void OnWindowRotateGesture(float rotation) {}
virtual void OnWindowSheetBegin() {}

View file

@ -11,6 +11,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "gin/converter.h"
#include "gin/data_object_builder.h"
#include "shell/common/gin_converters/gfx_converter.h"
#include "shell/common/gin_converters/gurl_converter.h"
#include "shell/common/gin_converters/value_converter.h"
@ -56,43 +57,73 @@ struct Converter<char16_t> {
}
};
template <>
struct Converter<blink::WebInputEvent::Type> {
static bool FromV8(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
blink::WebInputEvent::Type* out) {
std::string type = base::ToLowerASCII(gin::V8ToString(isolate, val));
if (type == "mousedown")
*out = blink::WebInputEvent::Type::kMouseDown;
else if (type == "mouseup")
*out = blink::WebInputEvent::Type::kMouseUp;
else if (type == "mousemove")
*out = blink::WebInputEvent::Type::kMouseMove;
else if (type == "mouseenter")
*out = blink::WebInputEvent::Type::kMouseEnter;
else if (type == "mouseleave")
*out = blink::WebInputEvent::Type::kMouseLeave;
else if (type == "contextmenu")
*out = blink::WebInputEvent::Type::kContextMenu;
else if (type == "mousewheel")
*out = blink::WebInputEvent::Type::kMouseWheel;
else if (type == "keydown")
*out = blink::WebInputEvent::Type::kRawKeyDown;
else if (type == "keyup")
*out = blink::WebInputEvent::Type::kKeyUp;
else if (type == "char")
*out = blink::WebInputEvent::Type::kChar;
else if (type == "touchstart")
*out = blink::WebInputEvent::Type::kTouchStart;
else if (type == "touchmove")
*out = blink::WebInputEvent::Type::kTouchMove;
else if (type == "touchend")
*out = blink::WebInputEvent::Type::kTouchEnd;
else if (type == "touchcancel")
*out = blink::WebInputEvent::Type::kTouchCancel;
return true;
#define BLINK_EVENT_TYPES() \
CASE_TYPE(kUndefined, "undefined") \
CASE_TYPE(kMouseDown, "mouseDown") \
CASE_TYPE(kMouseUp, "mouseUp") \
CASE_TYPE(kMouseMove, "mouseMove") \
CASE_TYPE(kMouseEnter, "mouseEnter") \
CASE_TYPE(kMouseLeave, "mouseLeave") \
CASE_TYPE(kContextMenu, "contextMenu") \
CASE_TYPE(kMouseWheel, "mouseWheel") \
CASE_TYPE(kRawKeyDown, "rawKeyDown") \
CASE_TYPE(kKeyDown, "keyDown") \
CASE_TYPE(kKeyUp, "keyUp") \
CASE_TYPE(kChar, "char") \
CASE_TYPE(kGestureScrollBegin, "gestureScrollBegin") \
CASE_TYPE(kGestureScrollEnd, "gestureScrollEnd") \
CASE_TYPE(kGestureScrollUpdate, "gestureScrollUpdate") \
CASE_TYPE(kGestureFlingStart, "gestureFlingStart") \
CASE_TYPE(kGestureFlingCancel, "gestureFlingCancel") \
CASE_TYPE(kGesturePinchBegin, "gesturePinchBegin") \
CASE_TYPE(kGesturePinchEnd, "gesturePinchEnd") \
CASE_TYPE(kGesturePinchUpdate, "gesturePinchUpdate") \
CASE_TYPE(kGestureTapDown, "gestureTapDown") \
CASE_TYPE(kGestureShowPress, "gestureShowPress") \
CASE_TYPE(kGestureTap, "gestureTap") \
CASE_TYPE(kGestureTapCancel, "gestureTapCancel") \
CASE_TYPE(kGestureShortPress, "gestureShortPress") \
CASE_TYPE(kGestureLongPress, "gestureLongPress") \
CASE_TYPE(kGestureLongTap, "gestureLongTap") \
CASE_TYPE(kGestureTwoFingerTap, "gestureTwoFingerTap") \
CASE_TYPE(kGestureTapUnconfirmed, "gestureTapUnconfirmed") \
CASE_TYPE(kGestureDoubleTap, "gestureDoubleTap") \
CASE_TYPE(kTouchStart, "touchStart") \
CASE_TYPE(kTouchMove, "touchMove") \
CASE_TYPE(kTouchEnd, "touchEnd") \
CASE_TYPE(kTouchCancel, "touchCancel") \
CASE_TYPE(kTouchScrollStarted, "touchScrollStarted") \
CASE_TYPE(kPointerDown, "pointerDown") \
CASE_TYPE(kPointerUp, "pointerUp") \
CASE_TYPE(kPointerMove, "pointerMove") \
CASE_TYPE(kPointerRawUpdate, "pointerRawUpdate") \
CASE_TYPE(kPointerCancel, "pointerCancel") \
CASE_TYPE(kPointerCausedUaAction, "pointerCausedUaAction")
bool Converter<blink::WebInputEvent::Type>::FromV8(
v8::Isolate* isolate,
v8::Handle<v8::Value> val,
blink::WebInputEvent::Type* out) {
std::string type = gin::V8ToString(isolate, val);
#define CASE_TYPE(event_type, js_name) \
if (base::EqualsCaseInsensitiveASCII(type, js_name)) { \
*out = blink::WebInputEvent::Type::event_type; \
return true; \
}
};
BLINK_EVENT_TYPES()
#undef CASE_TYPE
return false;
}
v8::Local<v8::Value> Converter<blink::WebInputEvent::Type>::ToV8(
v8::Isolate* isolate,
const blink::WebInputEvent::Type& in) {
#define CASE_TYPE(event_type, js_name) \
case blink::WebInputEvent::Type::event_type: \
return StringToV8(isolate, js_name);
switch (in) { BLINK_EVENT_TYPES() }
#undef CASE_TYPE
}
template <>
struct Converter<blink::WebMouseEvent::Button> {
@ -207,6 +238,19 @@ bool Converter<blink::WebInputEvent>::FromV8(v8::Isolate* isolate,
return true;
}
v8::Local<v8::Value> Converter<blink::WebInputEvent>::ToV8(
v8::Isolate* isolate,
const blink::WebInputEvent& in) {
if (blink::WebInputEvent::IsKeyboardEventType(in.GetType()))
return gin::ConvertToV8(isolate,
*static_cast<const blink::WebKeyboardEvent*>(&in));
return gin::DataObjectBuilder(isolate)
.Set("type", in.GetType())
.Set("modifiers", ModifiersToArray(in.GetModifiers()))
.Set("_modifiers", in.GetModifiers())
.Build();
}
bool Converter<blink::WebKeyboardEvent>::FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
blink::WebKeyboardEvent* out) {
@ -276,10 +320,7 @@ v8::Local<v8::Value> Converter<blink::WebKeyboardEvent>::ToV8(
const blink::WebKeyboardEvent& in) {
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
if (in.GetType() == blink::WebInputEvent::Type::kRawKeyDown)
dict.Set("type", "keyDown");
else if (in.GetType() == blink::WebInputEvent::Type::kKeyUp)
dict.Set("type", "keyUp");
dict.Set("type", in.GetType());
dict.Set("key", ui::KeycodeConverter::DomKeyToKeyString(in.dom_key));
dict.Set("code", ui::KeycodeConverter::DomCodeToCodeString(
static_cast<ui::DomCode>(in.dom_code)));

View file

@ -24,11 +24,22 @@ namespace gin {
blink::WebInputEvent::Type GetWebInputEventType(v8::Isolate* isolate,
v8::Local<v8::Value> val);
template <>
struct Converter<blink::WebInputEvent::Type> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
blink::WebInputEvent::Type* out);
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const blink::WebInputEvent::Type& in);
};
template <>
struct Converter<blink::WebInputEvent> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
blink::WebInputEvent* out);
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const blink::WebInputEvent& in);
};
template <>