minor fixes and enable datalist elements in OSR
This commit is contained in:
parent
a95d6b997b
commit
218e28b136
12 changed files with 402 additions and 58 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "atom/browser/osr/osr_render_widget_host_view.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback_helpers.h"
|
||||
|
@ -22,9 +23,12 @@
|
|||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/context_factory.h"
|
||||
#include "media/base/video_frame.h"
|
||||
#include "third_party/WebKit/public/platform/WebInputEvent.h"
|
||||
#include "ui/compositor/compositor.h"
|
||||
#include "ui/compositor/layer.h"
|
||||
#include "ui/compositor/layer_type.h"
|
||||
#include "ui/events/base_event_utils.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
#include "ui/events/latency_info.h"
|
||||
#include "ui/gfx/geometry/dip_util.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
|
@ -37,6 +41,70 @@ namespace {
|
|||
const float kDefaultScaleFactor = 1.0;
|
||||
const int kFrameRetryLimit = 2;
|
||||
|
||||
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
ui::EventType type = ui::EventType::ET_UNKNOWN;
|
||||
switch (event.type()) {
|
||||
case blink::WebInputEvent::MouseDown:
|
||||
type = ui::EventType::ET_MOUSE_PRESSED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseUp:
|
||||
type = ui::EventType::ET_MOUSE_RELEASED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseMove:
|
||||
type = ui::EventType::ET_MOUSE_MOVED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseEnter:
|
||||
type = ui::EventType::ET_MOUSE_ENTERED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseLeave:
|
||||
type = ui::EventType::ET_MOUSE_EXITED;
|
||||
break;
|
||||
case blink::WebInputEvent::MouseWheel:
|
||||
type = ui::EventType::ET_MOUSEWHEEL;
|
||||
break;
|
||||
default:
|
||||
type = ui::EventType::ET_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
int button_flags = 0;
|
||||
switch (event.button) {
|
||||
case blink::WebMouseEvent::Button::X1:
|
||||
button_flags |= ui::EventFlags::EF_BACK_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::X2:
|
||||
button_flags |= ui::EventFlags::EF_FORWARD_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::Left:
|
||||
button_flags |= ui::EventFlags::EF_LEFT_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::Middle:
|
||||
button_flags |= ui::EventFlags::EF_MIDDLE_MOUSE_BUTTON;
|
||||
break;
|
||||
case blink::WebMouseEvent::Button::Right:
|
||||
button_flags |= ui::EventFlags::EF_RIGHT_MOUSE_BUTTON;
|
||||
break;
|
||||
default:
|
||||
button_flags = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ui::MouseEvent ui_event(type,
|
||||
gfx::Point(std::floor(event.x), std::floor(event.y)),
|
||||
gfx::Point(std::floor(event.x), std::floor(event.y)),
|
||||
ui::EventTimeForNow(),
|
||||
button_flags, button_flags);
|
||||
ui_event.SetClickCount(event.clickCount);
|
||||
|
||||
return ui_event;
|
||||
}
|
||||
|
||||
ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
|
||||
blink::WebMouseWheelEvent event) {
|
||||
return ui::MouseWheelEvent(UiMouseEventFromWebMouseEvent(event),
|
||||
std::floor(event.deltaX), std::floor(event.deltaY));
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
||||
const int kResizeLockTimeoutMs = 67;
|
||||
|
@ -619,6 +687,8 @@ void OffScreenRenderWidgetHostView::Destroy() {
|
|||
child_host_view_->CancelWidget();
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->CancelWidget();
|
||||
for (auto proxy_view : proxy_views_)
|
||||
proxy_view->RemoveObserver();
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
|
@ -835,6 +905,22 @@ void OffScreenRenderWidgetHostView::RemoveGuestHostView(
|
|||
guest_host_views_.erase(guest_host);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::AddViewProxy(OffscreenViewProxy* proxy) {
|
||||
proxy->SetObserver(this);
|
||||
proxy_views_.insert(proxy);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::RemoveViewProxy(OffscreenViewProxy* proxy) {
|
||||
proxy->RemoveObserver();
|
||||
proxy_views_.erase(proxy);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ProxyViewDestroyed(
|
||||
OffscreenViewProxy* proxy) {
|
||||
proxy_views_.erase(proxy);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::RegisterGuestViewFrameSwappedCallback(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view) {
|
||||
guest_host_view->RegisterFrameSwappedCallback(base::MakeUnique<base::Closure>(
|
||||
|
@ -906,12 +992,16 @@ void CopyBitmapTo(
|
|||
char* dest = static_cast<char*>(destination.getPixels());
|
||||
int pixelsize = source.bytesPerPixel();
|
||||
|
||||
if (pos.x() + pos.width() <= destination.width() &&
|
||||
pos.y() + pos.height() <= destination.height()) {
|
||||
for (int i = 0; i < pos.height(); i++) {
|
||||
int width = pos.x() + pos.width() <= destination.width() ? pos.width()
|
||||
: pos.width() - ((pos.x() + pos.width()) - destination.width());
|
||||
int height = pos.y() + pos.height() <= destination.height() ? pos.height()
|
||||
: pos.height() - ((pos.y() + pos.height()) - destination.height());
|
||||
|
||||
if (width > 0 && height > 0) {
|
||||
for (int i = 0; i < height; i++) {
|
||||
memcpy(dest + ((pos.y() + i) * destination.width() + pos.x()) * pixelsize,
|
||||
src + (i * source.width()) * pixelsize,
|
||||
pos.width() * pixelsize);
|
||||
width * pixelsize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -926,19 +1016,41 @@ void OffScreenRenderWidgetHostView::OnPaint(
|
|||
|
||||
if (parent_callback_) {
|
||||
parent_callback_.Run(damage_rect, bitmap);
|
||||
} else if (popup_host_view_ && popup_bitmap_.get()) {
|
||||
gfx::Rect pos = popup_host_view_->popup_position_;
|
||||
gfx::Rect damage(damage_rect);
|
||||
damage.Union(pos);
|
||||
|
||||
SkBitmap copy = SkBitmapOperations::CreateTiledBitmap(bitmap,
|
||||
pos.x(), pos.y(), pos.width(), pos.height());
|
||||
|
||||
CopyBitmapTo(bitmap, *popup_bitmap_, pos);
|
||||
callback_.Run(damage, bitmap);
|
||||
CopyBitmapTo(bitmap, copy, pos);
|
||||
} else {
|
||||
callback_.Run(damage_rect, bitmap);
|
||||
gfx::Rect damage(damage_rect);
|
||||
|
||||
std::vector<gfx::Rect> damages;
|
||||
std::vector<const SkBitmap*> bitmaps;
|
||||
std::vector<SkBitmap> originals;
|
||||
|
||||
if (popup_host_view_ && popup_bitmap_.get()) {
|
||||
gfx::Rect pos = popup_host_view_->popup_position_;
|
||||
damage.Union(pos);
|
||||
damages.push_back(pos);
|
||||
bitmaps.push_back(popup_bitmap_.get());
|
||||
originals.push_back(SkBitmapOperations::CreateTiledBitmap(bitmap,
|
||||
pos.x(), pos.y(), pos.width(), pos.height()));
|
||||
}
|
||||
|
||||
for (auto proxy_view : proxy_views_) {
|
||||
gfx::Rect pos = proxy_view->GetBounds();
|
||||
damage.Union(pos);
|
||||
damages.push_back(pos);
|
||||
bitmaps.push_back(proxy_view->GetBitmap());
|
||||
originals.push_back(SkBitmapOperations::CreateTiledBitmap(bitmap,
|
||||
pos.x(), pos.y(), pos.width(), pos.height()));
|
||||
}
|
||||
|
||||
for (int i = 0; i < damages.size(); i++) {
|
||||
CopyBitmapTo(bitmap, *(bitmaps[i]), damages[i]);
|
||||
}
|
||||
|
||||
damage.Intersect(GetViewBounds());
|
||||
callback_.Run(damage, bitmap);
|
||||
|
||||
for (int i = 0; i < damages.size(); i++) {
|
||||
CopyBitmapTo(bitmap, originals[i], damages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseResize();
|
||||
|
@ -951,6 +1063,11 @@ void OffScreenRenderWidgetHostView::OnPopupPaint(
|
|||
InvalidateBounds(popup_host_view_->popup_position_);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnProxyViewPaint(
|
||||
const gfx::Rect& damage_rect) {
|
||||
InvalidateBounds(damage_rect);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::HoldResize() {
|
||||
if (!hold_resize_)
|
||||
hold_resize_ = true;
|
||||
|
@ -992,6 +1109,21 @@ void OffScreenRenderWidgetHostView::ProcessKeyboardEvent(
|
|||
void OffScreenRenderWidgetHostView::ProcessMouseEvent(
|
||||
const blink::WebMouseEvent& event,
|
||||
const ui::LatencyInfo& latency) {
|
||||
for (auto proxy_view : proxy_views_) {
|
||||
gfx::Rect bounds = proxy_view->GetBounds();
|
||||
if (bounds.Contains(event.x, event.y)) {
|
||||
blink::WebMouseEvent proxy_event(event);
|
||||
proxy_event.x -= bounds.x();
|
||||
proxy_event.y -= bounds.y();
|
||||
proxy_event.windowX = proxy_event.x;
|
||||
proxy_event.windowY = proxy_event.y;
|
||||
|
||||
ui::MouseEvent ui_event = UiMouseEventFromWebMouseEvent(proxy_event);
|
||||
proxy_view->OnEvent(&ui_event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsPopupWidget()) {
|
||||
if (popup_host_view_ &&
|
||||
popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
|
@ -1005,6 +1137,7 @@ void OffScreenRenderWidgetHostView::ProcessMouseEvent(
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
render_widget_host_->ForwardMouseEvent(event);
|
||||
|
@ -1013,6 +1146,21 @@ void OffScreenRenderWidgetHostView::ProcessMouseEvent(
|
|||
void OffScreenRenderWidgetHostView::ProcessMouseWheelEvent(
|
||||
const blink::WebMouseWheelEvent& event,
|
||||
const ui::LatencyInfo& latency) {
|
||||
for (auto proxy_view : proxy_views_) {
|
||||
gfx::Rect bounds = proxy_view->GetBounds();
|
||||
if (bounds.Contains(event.x, event.y)) {
|
||||
blink::WebMouseWheelEvent proxy_event(event);
|
||||
proxy_event.x -= bounds.x();
|
||||
proxy_event.y -= bounds.y();
|
||||
proxy_event.windowX = proxy_event.x;
|
||||
proxy_event.windowY = proxy_event.y;
|
||||
|
||||
ui::MouseWheelEvent ui_event =
|
||||
UiMouseWheelEventFromWebMouseEvent(proxy_event);
|
||||
proxy_view->OnEvent(&ui_event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!IsPopupWidget()) {
|
||||
if (popup_host_view_) {
|
||||
if (popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
#include "atom/browser/osr/osr_output_device.h"
|
||||
#include "atom/browser/osr/osr_view_proxy.h"
|
||||
#include "base/process/kill.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "base/time/time.h"
|
||||
|
@ -68,7 +69,8 @@ class OffScreenRenderWidgetHostView
|
|||
#if !defined(OS_MACOSX)
|
||||
public content::DelegatedFrameHostClient,
|
||||
#endif
|
||||
public NativeWindowObserver {
|
||||
public NativeWindowObserver,
|
||||
public OffscreenViewProxyObserver {
|
||||
public:
|
||||
OffScreenRenderWidgetHostView(bool transparent,
|
||||
const OnPaintCallback& callback,
|
||||
|
@ -208,6 +210,9 @@ class OffScreenRenderWidgetHostView
|
|||
void CancelWidget();
|
||||
void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
||||
void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host);
|
||||
void AddViewProxy(OffscreenViewProxy* proxy);
|
||||
void RemoveViewProxy(OffscreenViewProxy* proxy);
|
||||
void ProxyViewDestroyed(OffscreenViewProxy* proxy);
|
||||
|
||||
void RegisterGuestViewFrameSwappedCallback(
|
||||
content::RenderWidgetHostViewGuest* guest_host_view);
|
||||
|
@ -216,6 +221,7 @@ class OffScreenRenderWidgetHostView
|
|||
|
||||
void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||
void OnPopupPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
|
||||
void OnProxyViewPaint(const gfx::Rect& damage_rect);
|
||||
|
||||
bool IsPopupWidget() const {
|
||||
return popup_type_ != blink::WebPopupTypeNone;
|
||||
|
@ -273,6 +279,7 @@ class OffScreenRenderWidgetHostView
|
|||
std::unique_ptr<SkBitmap> popup_bitmap_;
|
||||
OffScreenRenderWidgetHostView* child_host_view_;
|
||||
std::set<OffScreenRenderWidgetHostView*> guest_host_views_;
|
||||
std::set<OffscreenViewProxy*> proxy_views_;
|
||||
|
||||
NativeWindow* native_window_;
|
||||
OffScreenOutputDevice* software_output_device_;
|
||||
|
|
58
atom/browser/osr/osr_view_proxy.cc
Normal file
58
atom/browser/osr/osr_view_proxy.cc
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/osr/osr_view_proxy.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
OffscreenViewProxy::OffscreenViewProxy(views::View* view)
|
||||
: view_(view), observer_(nullptr) {
|
||||
view_bitmap_.reset(new SkBitmap);
|
||||
}
|
||||
|
||||
OffscreenViewProxy::~OffscreenViewProxy() {
|
||||
if (observer_) {
|
||||
observer_->ProxyViewDestroyed(this);
|
||||
}
|
||||
}
|
||||
|
||||
void OffscreenViewProxy::SetObserver(OffscreenViewProxyObserver* observer) {
|
||||
if (observer_) {
|
||||
observer_->ProxyViewDestroyed(this);
|
||||
}
|
||||
observer_ = observer;
|
||||
}
|
||||
|
||||
void OffscreenViewProxy::RemoveObserver() {
|
||||
observer_ = nullptr;
|
||||
}
|
||||
|
||||
const SkBitmap* OffscreenViewProxy::GetBitmap() const {
|
||||
return view_bitmap_.get();
|
||||
}
|
||||
|
||||
void OffscreenViewProxy::SetBitmap(const SkBitmap& bitmap) {
|
||||
if (view_bounds_.width() == bitmap.width() &&
|
||||
view_bounds_.height() == bitmap.height() &&
|
||||
observer_) {
|
||||
view_bitmap_.reset(new SkBitmap(bitmap));
|
||||
observer_->OnProxyViewPaint(view_bounds_);
|
||||
}
|
||||
}
|
||||
|
||||
const gfx::Rect& OffscreenViewProxy::GetBounds() {
|
||||
return view_bounds_;
|
||||
}
|
||||
|
||||
void OffscreenViewProxy::SetBounds(const gfx::Rect& bounds) {
|
||||
view_bounds_ = bounds;
|
||||
}
|
||||
|
||||
void OffscreenViewProxy::OnEvent(ui::Event* event) {
|
||||
if (view_) {
|
||||
view_->OnEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
53
atom/browser/osr/osr_view_proxy.h
Normal file
53
atom/browser/osr/osr_view_proxy.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_OSR_OSR_VIEW_PROXY_H_
|
||||
#define ATOM_BROWSER_OSR_OSR_VIEW_PROXY_H_
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/events/event.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class OffscreenViewProxy;
|
||||
|
||||
class OffscreenViewProxyObserver {
|
||||
public:
|
||||
virtual void OnProxyViewPaint(const gfx::Rect& damage_rect) = 0;
|
||||
virtual void ProxyViewDestroyed(OffscreenViewProxy* proxy) = 0;
|
||||
};
|
||||
|
||||
class OffscreenViewProxy {
|
||||
public:
|
||||
explicit OffscreenViewProxy(views::View* view);
|
||||
~OffscreenViewProxy();
|
||||
|
||||
void SetObserver(OffscreenViewProxyObserver* observer);
|
||||
void RemoveObserver();
|
||||
|
||||
const SkBitmap* GetBitmap() const;
|
||||
void SetBitmap(const SkBitmap& bitmap);
|
||||
|
||||
const gfx::Rect& GetBounds();
|
||||
void SetBounds(const gfx::Rect& bounds);
|
||||
|
||||
void OnEvent(ui::Event* event);
|
||||
|
||||
void ResetView() { view_ = nullptr; }
|
||||
private:
|
||||
views::View* view_;
|
||||
|
||||
gfx::Rect view_bounds_;
|
||||
std::unique_ptr<SkBitmap> view_bitmap_;
|
||||
|
||||
OffscreenViewProxyObserver* observer_;
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_OSR_OSR_VIEW_PROXY_H_
|
Loading…
Add table
Add a link
Reference in a new issue