Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 17 commits into from Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 21 additions & 3 deletions docs/api/browser-window.md
Expand Up @@ -652,18 +652,36 @@ The following app commands are explicitly supported on Linux:
* `browser-backward`
* `browser-forward`

#### Event: 'scroll-touch-begin' _macOS_
#### Event: 'scroll-touch-begin' _macOS_ _Deprecated_
nornagon marked this conversation as resolved.
Show resolved Hide resolved

Emitted when scroll wheel event phase has begun.

#### Event: 'scroll-touch-end' _macOS_
> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.

#### Event: 'scroll-touch-end' _macOS_ _Deprecated_

Emitted when scroll wheel event phase has ended.

#### Event: 'scroll-touch-edge' _macOS_
> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.

#### Event: 'scroll-touch-edge' _macOS_ _Deprecated_

Emitted when scroll wheel event phase filed upon reaching the edge of element.

> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.

#### Event: 'swipe' _macOS_

Returns:
Expand Down
11 changes: 11 additions & 0 deletions docs/api/structures/input-event.md
@@ -1,5 +1,16 @@
# InputEvent Object

* `type` string - Can be `undefined`, `mouseDown`, `mouseUp`, `mouseMove`,
`mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, `rawKeyDown`,
`keyDown`, `keyUp`, `char`, `gestureScrollBegin`, `gestureScrollEnd`,
`gestureScrollUpdate`, `gestureFlingStart`, `gestureFlingCancel`,
`gesturePinchBegin`, `gesturePinchEnd`, `gesturePinchUpdate`,
`gestureTapDown`, `gestureShowPress`, `gestureTap`, `gestureTapCancel`,
`gestureShortPress`, `gestureLongPress`, `gestureLongTap`,
`gestureTwoFingerTap`, `gestureTapUnconfirmed`, `gestureDoubleTap`,
`touchStart`, `touchMove`, `touchEnd`, `touchCancel`, `touchScrollStarted`,
`pointerDown`, `pointerUp`, `pointerMove`, `pointerRawUpdate`,
`pointerCancel` or `pointerCausedUaAction`.
* `modifiers` string[] (optional) - An array of modifiers of the event, can
be `shift`, `control`, `ctrl`, `alt`, `meta`, `command`, `cmd`, `isKeypad`,
`isAutoRepeat`, `leftButtonDown`, `middleButtonDown`, `rightButtonDown`,
Expand Down
2 changes: 1 addition & 1 deletion docs/api/structures/keyboard-input-event.md
@@ -1,6 +1,6 @@
# KeyboardInputEvent Object extends `InputEvent`

* `type` string - The type of the event, can be `keyDown`, `keyUp` or `char`.
* `type` string - The type of the event, can be `rawKeyDown`, `keyDown`, `keyUp` or `char`.
* `keyCode` string - The character that will be sent
as the keyboard event. Should only use the valid key codes in
[Accelerator](../accelerator.md).
10 changes: 10 additions & 0 deletions docs/api/web-contents.md
Expand Up @@ -396,6 +396,16 @@ Emitted when a plugin process has crashed.

Emitted when `webContents` is destroyed.

#### Event: 'input-event'

Returns:

* `event` Event
* `inputEvent` [InputEvent](structures/input-event.md)

Emitted when an input event is sent to the WebContents. See
[InputEvent](structures/input-event.md) for details.

#### Event: 'before-input-event'

Returns:
Expand Down
50 changes: 50 additions & 0 deletions docs/breaking-changes.md
Expand Up @@ -12,6 +12,32 @@ This document uses the following convention to categorize breaking changes:
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
* **Removed:** An API or feature was removed, and is no longer supported by Electron.

## Planned Breaking API Changes (23.0)

### Removed: BrowserWindow `scroll-touch-*` events

The deprecated `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge`
events on BrowserWindow have been removed. Instead, use the newly available
[`input-event` event](api/web-contents.md#event-input-event) on WebContents.

```js
// Removed in Electron 22.0
nornagon marked this conversation as resolved.
Show resolved Hide resolved
win.on('scroll-touch-begin', scrollTouchBegin)
win.on('scroll-touch-edge', scrollTouchEdge)
win.on('scroll-touch-end', scrollTouchEnd)

// Replace with
win.webContents.on('input-event', (_, event) => {
nornagon marked this conversation as resolved.
Show resolved Hide resolved
if (event.type === 'gestureScrollBegin') {
scrollTouchBegin()
} else if (event.type === 'gestureScrollUpdate') {
scrollTouchEdge()
} else if (event.type === 'gestureScrollEnd') {
scrollTouchEnd()
}
})
```

## Planned Breaking API Changes (22.0)

### Removed: WebContents `new-window` event
Expand All @@ -30,6 +56,30 @@ webContents.setWindowOpenHandler((details) => {
})
```

### Deprecated: BrowserWindow `scroll-touch-*` events

The `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` events on
BrowserWindow are deprecated. Instead, use the newly available [`input-event`
event](api/web-contents.md#event-input-event) on WebContents.

```js
// Deprecated
win.on('scroll-touch-begin', scrollTouchBegin)
win.on('scroll-touch-edge', scrollTouchEdge)
win.on('scroll-touch-end', scrollTouchEnd)

// Replace with
win.webContents.on('input-event', (_, event) => {
nornagon marked this conversation as resolved.
Show resolved Hide resolved
if (event.type === 'gestureScrollBegin') {
scrollTouchBegin()
} else if (event.type === 'gestureScrollUpdate') {
scrollTouchEdge()
} else if (event.type === 'gestureScrollEnd') {
scrollTouchEnd()
}
})
```

## Planned Breaking API Changes (20.0)

### Behavior Changed: V8 Memory Cage enabled
Expand Down
23 changes: 23 additions & 0 deletions lib/browser/api/browser-window.ts
@@ -1,5 +1,6 @@
import { BaseWindow, WebContents, Event, BrowserView, TouchBar } from 'electron/main';
import type { BrowserWindow as BWT } from 'electron/main';
import * as deprecate from '@electron/internal/common/deprecate';
const { BrowserWindow } = process._linkedBinding('electron_browser_window') as { BrowserWindow: typeof BWT };

Object.setPrototypeOf(BrowserWindow.prototype, BaseWindow.prototype);
Expand Down Expand Up @@ -44,6 +45,28 @@ BrowserWindow.prototype._init = function (this: BWT) {
this.on(event as any, visibilityChanged);
}

const warn = deprecate.warnOnceMessage('\'scroll-touch-{begin,end,edge}\' are deprecated and will be removed. Please use the WebContents \'input-event\' event instead.');
this.webContents.on('input-event', (_, e) => {
if (e.type === 'gestureScrollBegin') {
if (this.listenerCount('scroll-touch-begin') !== 0) {
warn();
this.emit('scroll-touch-edge');
this.emit('scroll-touch-begin');
}
} else if (e.type === 'gestureScrollUpdate') {
if (this.listenerCount('scroll-touch-edge') !== 0) {
warn();
this.emit('scroll-touch-edge');
nornagon marked this conversation as resolved.
Show resolved Hide resolved
}
} else if (e.type === 'gestureScrollEnd') {
if (this.listenerCount('scroll-touch-end') !== 0) {
warn();
this.emit('scroll-touch-edge');
this.emit('scroll-touch-end');
}
}
});

// Notify the creation of the window.
const event = process._linkedBinding('electron_browser_event').createEmpty();
app.emit('browser-window-created', event, this);
Expand Down
9 changes: 6 additions & 3 deletions lib/common/deprecate.ts
Expand Up @@ -3,10 +3,13 @@ type DeprecationHandler = (message: string) => void;
let deprecationHandler: DeprecationHandler | null = null;

export function warnOnce (oldName: string, newName?: string) {
let warned = false;
const msg = newName
return warnOnceMessage(newName
? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.`
: `'${oldName}' is deprecated and will be removed.`;
: `'${oldName}' is deprecated and will be removed.`);
}

export function warnOnceMessage (msg: string) {
let warned = false;
return () => {
if (!warned && !process.noDeprecation) {
warned = true;
Expand Down
8 changes: 0 additions & 8 deletions shell/browser/api/electron_api_base_window.cc
Expand Up @@ -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);
}
Expand Down
2 changes: 0 additions & 2 deletions shell/browser/api/electron_api_base_window.h
Expand Up @@ -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;
Expand Down
27 changes: 0 additions & 27 deletions shell/browser/api/electron_api_browser_window.cc
Expand Up @@ -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.
Expand All @@ -128,35 +124,12 @@ 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();
}
}

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.
Expand Down
6 changes: 0 additions & 6 deletions shell/browser/api/electron_api_browser_window.h
Expand Up @@ -17,7 +17,6 @@
namespace electron::api {

class BrowserWindow : public BaseWindow,
public content::RenderWidgetHost::InputEventObserver,
public content::WebContentsObserver,
public ExtendedWebContentsObserver {
public:
Expand All @@ -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(
Expand Down
34 changes: 33 additions & 1 deletion shell/browser/api/electron_api_web_contents.cc
Expand Up @@ -817,6 +817,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(
Expand Down Expand Up @@ -954,6 +960,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;
Expand Down Expand Up @@ -1254,7 +1266,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;
}
Expand Down Expand Up @@ -1670,6 +1687,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);
Expand Down Expand Up @@ -3045,6 +3070,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;
}
Expand Down Expand Up @@ -3447,6 +3475,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();
Expand Down
6 changes: 6 additions & 0 deletions shell/browser/api/electron_api_web_contents.h
Expand Up @@ -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:
Expand Down Expand Up @@ -431,6 +432,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;
Expand Down Expand Up @@ -615,6 +619,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;
Expand Down