mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Windows: Improvements to off-screen rendering support (issue #518).
- Implement support for transparency. Change the backing store to use Skia instead of GDI and to keep alpha values. - Implement support for select popups. Requires a patch to Chromium (content_popups.patch). - Implicitly disable accelerated compositing when using off-screen rendering. - Introduce a new CefMouseEvent structure for representing mouse event information passed to CefBrowser methods. - Merge cef_key_event_modifiers_t into cef_event_flags_t. - Add a new argument to CefBrowser::Invalidate telling the browser whether to invalidate the select popup or the main view. - Add a new cefclient "transparent-painting-enabled" command-line flag to test transparent off-screen rendering. - Add a new cefclient "Transparency" test. - Fix the cefclient off-screen rendering rotation effect to work even when the underlying web content is not updating. - Add unit tests for transparent painting and select popups. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@979 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
@@ -4,22 +4,79 @@
|
||||
|
||||
#include "libcef/browser/backing_store_osr.h"
|
||||
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/surface/transport_dib.h"
|
||||
|
||||
BackingStoreOSR::BackingStoreOSR(content::RenderWidgetHost* widget,
|
||||
const gfx::Size& size)
|
||||
: content::BackingStore(widget, size) {
|
||||
bitmap_.Allocate(size.width(), size.height(), true);
|
||||
: content::BackingStore(widget, size),
|
||||
device_(SkBitmap::kARGB_8888_Config, size.width(), size.height(), true),
|
||||
canvas_(&device_) {
|
||||
canvas_.drawColor(SK_ColorWHITE);
|
||||
}
|
||||
|
||||
void BackingStoreOSR::PaintToBackingStore(
|
||||
content::RenderProcessHost* process,
|
||||
TransportDIB::Id bitmap,
|
||||
const gfx::Rect& bitmap_rect,
|
||||
const std::vector<gfx::Rect>& copy_rects,
|
||||
float scale_factor,
|
||||
const base::Closure& completion_callback,
|
||||
bool* scheduled_completion_callback) {
|
||||
*scheduled_completion_callback = false;
|
||||
TransportDIB* dib = process->GetTransportDIB(bitmap);
|
||||
if (!dib)
|
||||
return;
|
||||
|
||||
SkBitmap src_bitmap;
|
||||
src_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
|
||||
bitmap_rect.width(),
|
||||
bitmap_rect.height());
|
||||
src_bitmap.setPixels(dib->memory());
|
||||
|
||||
SkPaint copy_paint;
|
||||
copy_paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
|
||||
for (size_t i = 0; i < copy_rects.size(); i++) {
|
||||
SkIRect src_rect = SkIRect::MakeXYWH(copy_rects[i].x() - bitmap_rect.x(),
|
||||
copy_rects[i].y() - bitmap_rect.y(),
|
||||
copy_rects[i].width(),
|
||||
copy_rects[i].height());
|
||||
SkRect paint_rect = SkRect::MakeXYWH(copy_rects[i].x(),
|
||||
copy_rects[i].y(),
|
||||
copy_rects[i].width(),
|
||||
copy_rects[i].height());
|
||||
canvas_.drawBitmapRect(src_bitmap, &src_rect, paint_rect, ©_paint);
|
||||
}
|
||||
src_bitmap.setPixels(0);
|
||||
}
|
||||
|
||||
bool BackingStoreOSR::CopyFromBackingStore(const gfx::Rect& rect,
|
||||
skia::PlatformBitmap* output) {
|
||||
if (!output->Allocate(rect.width(), rect.height(), true))
|
||||
return false;
|
||||
|
||||
SkPaint copy_paint;
|
||||
copy_paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
|
||||
SkCanvas canvas(output->GetBitmap());
|
||||
canvas.drawColor(SK_ColorWHITE);
|
||||
canvas.drawBitmap(device_.accessBitmap(false), 0, 0, ©_paint);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BackingStoreOSR::ScrollBackingStore(const gfx::Vector2d& delta,
|
||||
const gfx::Rect& clip_rect,
|
||||
const gfx::Size& view_size) {
|
||||
SkIRect subset_rect = SkIRect::MakeXYWH(clip_rect.x(), clip_rect.y(),
|
||||
clip_rect.width(), clip_rect.height());
|
||||
bitmap_.GetBitmap().scrollRect(&subset_rect, delta.x(), delta.y());
|
||||
SkIRect subset_rect = SkIRect::MakeXYWH(clip_rect.x(),
|
||||
clip_rect.y(),
|
||||
clip_rect.width(),
|
||||
clip_rect.height());
|
||||
device_.accessBitmap(true).scrollRect(&subset_rect, delta.x(), delta.y());
|
||||
}
|
||||
|
||||
const void* BackingStoreOSR::getPixels() const {
|
||||
return const_cast<BackingStoreOSR*>(this)->bitmap_.GetBitmap().getPixels();
|
||||
return const_cast<BackingStoreOSR*>(this)->device_.
|
||||
accessBitmap(false).getPixels();
|
||||
}
|
||||
|
@@ -42,7 +42,8 @@ class BackingStoreOSR : public content::BackingStore {
|
||||
const gfx::Size& size);
|
||||
virtual ~BackingStoreOSR() {}
|
||||
|
||||
skia::PlatformBitmap bitmap_;
|
||||
SkDevice device_;
|
||||
SkCanvas canvas_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BackingStoreOSR);
|
||||
};
|
||||
|
@@ -1,86 +0,0 @@
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "libcef/browser/backing_store_osr.h"
|
||||
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "ui/gfx/gdi_util.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/surface/transport_dib.h"
|
||||
|
||||
// Portions extracted from content/browser/renderer_host/backing_store_win.cc.
|
||||
|
||||
namespace {
|
||||
|
||||
void CallStretchDIBits(HDC hdc, int dest_x, int dest_y, int dest_w, int dest_h,
|
||||
int src_x, int src_y, int src_w, int src_h, void* pixels,
|
||||
const BITMAPINFO* bitmap_info) {
|
||||
// When blitting a rectangle that touches the bottom left corner of the bitmap
|
||||
// StretchDIBits looks at it top-down! For more details, see
|
||||
// http://wiki.allegro.cc/index.php?title=StretchDIBits.
|
||||
int rv;
|
||||
int bitmap_h = -bitmap_info->bmiHeader.biHeight;
|
||||
int bottom_up_src_y = bitmap_h - src_y - src_h;
|
||||
if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) {
|
||||
rv = StretchDIBits(hdc,
|
||||
dest_x, dest_h + dest_y - 1, dest_w, -dest_h,
|
||||
src_x, bitmap_h - src_y + 1, src_w, -src_h,
|
||||
pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
|
||||
} else {
|
||||
rv = StretchDIBits(hdc,
|
||||
dest_x, dest_y, dest_w, dest_h,
|
||||
src_x, bottom_up_src_y, src_w, src_h,
|
||||
pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
|
||||
}
|
||||
DCHECK(rv != GDI_ERROR);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void BackingStoreOSR::PaintToBackingStore(
|
||||
content::RenderProcessHost* process,
|
||||
TransportDIB::Id bitmap,
|
||||
const gfx::Rect& bitmap_rect,
|
||||
const std::vector<gfx::Rect>& copy_rects,
|
||||
float scale_factor,
|
||||
const base::Closure& completion_callback,
|
||||
bool* scheduled_completion_callback) {
|
||||
*scheduled_completion_callback = false;
|
||||
TransportDIB* dib = process->GetTransportDIB(bitmap);
|
||||
if (!dib)
|
||||
return;
|
||||
|
||||
BITMAPINFOHEADER hdr;
|
||||
gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr);
|
||||
|
||||
// Account for a bitmap_rect that exceeds the bounds of our view.
|
||||
gfx::Rect view_rect(size());
|
||||
HDC temp_dc = bitmap_.GetSurface();
|
||||
for (size_t i = 0; i < copy_rects.size(); i++) {
|
||||
gfx::Rect paint_rect(copy_rects[i]);
|
||||
paint_rect.Intersect(view_rect);
|
||||
CallStretchDIBits(temp_dc,
|
||||
paint_rect.x(),
|
||||
paint_rect.y(),
|
||||
paint_rect.width(),
|
||||
paint_rect.height(),
|
||||
paint_rect.x() - bitmap_rect.x(),
|
||||
paint_rect.y() - bitmap_rect.y(),
|
||||
paint_rect.width(),
|
||||
paint_rect.height(),
|
||||
dib->memory(),
|
||||
reinterpret_cast<BITMAPINFO*>(&hdr));
|
||||
}
|
||||
}
|
||||
|
||||
bool BackingStoreOSR::CopyFromBackingStore(const gfx::Rect& rect,
|
||||
skia::PlatformBitmap* output) {
|
||||
if (!output->Allocate(rect.width(), rect.height(), true))
|
||||
return false;
|
||||
|
||||
HDC src_dc = bitmap_.GetSurface();
|
||||
HDC dst_dc = output->GetSurface();
|
||||
return BitBlt(dst_dc, 0, 0, rect.width(), rect.height(),
|
||||
src_dc, rect.x(), rect.y(), SRCCOPY) ? true : false;
|
||||
}
|
@@ -91,15 +91,15 @@ bool GetCefKeyEvent(const content::NativeWebKeyboardEvent& event,
|
||||
|
||||
cef_event.modifiers = 0;
|
||||
if (event.modifiers & WebKit::WebKeyboardEvent::ShiftKey)
|
||||
cef_event.modifiers |= KEY_SHIFT;
|
||||
cef_event.modifiers |= EVENTFLAG_SHIFT_DOWN;
|
||||
if (event.modifiers & WebKit::WebKeyboardEvent::ControlKey)
|
||||
cef_event.modifiers |= KEY_CTRL;
|
||||
cef_event.modifiers |= EVENTFLAG_CONTROL_DOWN;
|
||||
if (event.modifiers & WebKit::WebKeyboardEvent::AltKey)
|
||||
cef_event.modifiers |= KEY_ALT;
|
||||
cef_event.modifiers |= EVENTFLAG_ALT_DOWN;
|
||||
if (event.modifiers & WebKit::WebKeyboardEvent::MetaKey)
|
||||
cef_event.modifiers |= KEY_META;
|
||||
cef_event.modifiers |= EVENTFLAG_COMMAND_DOWN;
|
||||
if (event.modifiers & WebKit::WebKeyboardEvent::IsKeyPad)
|
||||
cef_event.modifiers |= KEY_KEYPAD;
|
||||
cef_event.modifiers |= EVENTFLAG_IS_KEY_PAD;
|
||||
|
||||
cef_event.windows_key_code = event.windowsKeyCode;
|
||||
cef_event.native_key_code = event.nativeKeyCode;
|
||||
@@ -136,7 +136,6 @@ class CefFileDialogCallbackImpl : public CefFileDialogCallback {
|
||||
std::vector<CefString>::const_iterator it = file_paths.begin();
|
||||
for (; it != file_paths.end(); ++it)
|
||||
vec.push_back(FilePath(*it));
|
||||
|
||||
}
|
||||
callback_.Run(vec);
|
||||
callback_.Reset();
|
||||
@@ -226,16 +225,24 @@ bool CefBrowserHost::CreateBrowser(const CefWindowInfo& windowInfo,
|
||||
return false;
|
||||
}
|
||||
|
||||
CefBrowserSettings new_settings = settings;
|
||||
|
||||
// Verify that render handler is in place for a windowless browser.
|
||||
if (CefBrowserHostImpl::IsWindowRenderingDisabled(windowInfo) &&
|
||||
!client->GetRenderHandler().get()) {
|
||||
NOTREACHED() << "CefRenderHandler implementation is required";
|
||||
return false;
|
||||
if (CefBrowserHostImpl::IsWindowRenderingDisabled(windowInfo)) {
|
||||
if (!client->GetRenderHandler().get()) {
|
||||
NOTREACHED() << "CefRenderHandler implementation is required";
|
||||
return false;
|
||||
}
|
||||
if (!new_settings.accelerated_compositing_disabled) {
|
||||
// Accelerated compositing is not supported when window rendering is
|
||||
// disabled.
|
||||
new_settings.accelerated_compositing_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the browser on the UI thread.
|
||||
CreateBrowserHelper* helper =
|
||||
new CreateBrowserHelper(windowInfo, client, url, settings);
|
||||
new CreateBrowserHelper(windowInfo, client, url, new_settings);
|
||||
CEF_POST_TASK(CEF_UIT, base::Bind(CreateBrowserWithHelper, helper));
|
||||
|
||||
return true;
|
||||
@@ -265,10 +272,19 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (CefBrowserHostImpl::IsWindowRenderingDisabled(windowInfo) &&
|
||||
!client->GetRenderHandler().get()) {
|
||||
NOTREACHED() << "CefRenderHandler implementation is required";
|
||||
return NULL;
|
||||
CefBrowserSettings new_settings = settings;
|
||||
|
||||
// Verify that render handler is in place for a windowless browser.
|
||||
if (CefBrowserHostImpl::IsWindowRenderingDisabled(windowInfo)) {
|
||||
if (!client->GetRenderHandler().get()) {
|
||||
NOTREACHED() << "CefRenderHandler implementation is required";
|
||||
return NULL;
|
||||
}
|
||||
if (!new_settings.accelerated_compositing_disabled) {
|
||||
// Accelerated compositing is not supported when window rendering is
|
||||
// disabled.
|
||||
new_settings.accelerated_compositing_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
_Context->browser_context()->set_use_osr_next_contents_view(
|
||||
@@ -278,7 +294,7 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
||||
CefContentBrowserClient::Get()->CreateBrowserInfo();
|
||||
DCHECK(!info->is_popup());
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::Create(windowInfo, settings, client, NULL, info,
|
||||
CefBrowserHostImpl::Create(windowInfo, new_settings, client, NULL, info,
|
||||
NULL);
|
||||
if (!url.empty())
|
||||
browser->LoadURL(CefFrameHostImpl::kMainFrameId, url);
|
||||
@@ -550,7 +566,7 @@ void CefBrowserHostImpl::WasResized() {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT, base::Bind(&CefBrowserHostImpl::WasResized, this));
|
||||
return;
|
||||
@@ -564,7 +580,8 @@ void CefBrowserHostImpl::WasResized() {
|
||||
widget->WasResized();
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect) {
|
||||
void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect,
|
||||
PaintElementType type) {
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
NOTREACHED() << "Window rendering is not disabled";
|
||||
return;
|
||||
@@ -572,7 +589,7 @@ void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect) {
|
||||
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::Invalidate, this, dirtyRect));
|
||||
base::Bind(&CefBrowserHostImpl::Invalidate, this, dirtyRect, type));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -588,7 +605,7 @@ void CefBrowserHostImpl::Invalidate(const CefRect& dirtyRect) {
|
||||
if (orview) {
|
||||
gfx::Rect rect(dirtyRect.x, dirtyRect.y,
|
||||
dirtyRect.width, dirtyRect.height);
|
||||
orview->Invalidate(rect);
|
||||
orview->Invalidate(rect, type);
|
||||
}
|
||||
#else
|
||||
// TODO(port): Implement this method to work on other platforms as part of
|
||||
@@ -604,74 +621,148 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!web_contents())
|
||||
return;
|
||||
content::NativeWebKeyboardEvent web_event;
|
||||
PlatformTranslateKeyEvent(web_event, event);
|
||||
|
||||
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
|
||||
if (!widget)
|
||||
return;
|
||||
gfx::NativeEvent native_event;
|
||||
if (PlatformTranslateKeyEvent(native_event, event))
|
||||
widget->ForwardKeyboardEvent(content::NativeWebKeyboardEvent(native_event));
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
|
||||
if (widget)
|
||||
widget->ForwardKeyboardEvent(web_event);
|
||||
} else {
|
||||
#if defined(OS_WIN)
|
||||
if (!web_contents())
|
||||
return;
|
||||
content::RenderWidgetHostView* view =
|
||||
web_contents()->GetRenderViewHost()->GetView();
|
||||
CefRenderWidgetHostViewOSR* orview =
|
||||
static_cast<CefRenderWidgetHostViewOSR*>(view);
|
||||
if (orview)
|
||||
orview->SendKeyEvent(web_event);
|
||||
#else
|
||||
// TODO(port): Implement this method to work on other platforms as part of
|
||||
// off-screen rendering support.
|
||||
NOTREACHED();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SendMouseClickEvent(int x, int y,
|
||||
void CefBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event,
|
||||
MouseButtonType type, bool mouseUp, int clickCount) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::SendMouseClickEvent, this, x, y, type,
|
||||
base::Bind(&CefBrowserHostImpl::SendMouseClickEvent, this, event, type,
|
||||
mouseUp, clickCount));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!web_contents())
|
||||
return;
|
||||
WebKit::WebMouseEvent web_event;
|
||||
PlatformTranslateClickEvent(web_event, event, type, mouseUp, clickCount);
|
||||
|
||||
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
|
||||
if (!widget)
|
||||
return;
|
||||
WebKit::WebMouseEvent event;
|
||||
if (PlatformTranslateClickEvent(event, x, y, type, mouseUp, clickCount))
|
||||
widget->ForwardMouseEvent(event);
|
||||
SendMouseEvent(web_event);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SendMouseMoveEvent(int x, int y, bool mouseLeave) {
|
||||
void CefBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event,
|
||||
bool mouseLeave) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::SendMouseMoveEvent, this, x, y,
|
||||
base::Bind(&CefBrowserHostImpl::SendMouseMoveEvent, this, event,
|
||||
mouseLeave));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!web_contents())
|
||||
return;
|
||||
WebKit::WebMouseEvent web_event;
|
||||
PlatformTranslateMoveEvent(web_event, event, mouseLeave);
|
||||
|
||||
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
|
||||
if (!widget)
|
||||
return;
|
||||
WebKit::WebMouseEvent event;
|
||||
if (PlatformTranslateMoveEvent(event, x, y, mouseLeave))
|
||||
widget->ForwardMouseEvent(event);
|
||||
SendMouseEvent(web_event);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SendMouseWheelEvent(int x, int y,
|
||||
void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
|
||||
int deltaX, int deltaY) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::SendMouseWheelEvent, this, x, y,
|
||||
base::Bind(&CefBrowserHostImpl::SendMouseWheelEvent, this, event,
|
||||
deltaX, deltaY));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!web_contents())
|
||||
return;
|
||||
WebKit::WebMouseWheelEvent web_event;
|
||||
PlatformTranslateWheelEvent(web_event, event, deltaX, deltaY);
|
||||
|
||||
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
|
||||
if (!widget)
|
||||
return;
|
||||
WebKit::WebMouseWheelEvent event;
|
||||
if (PlatformTranslateWheelEvent(event, x, y, deltaX, deltaY))
|
||||
widget->ForwardWheelEvent(event);
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
|
||||
if (widget)
|
||||
widget->ForwardWheelEvent(web_event);
|
||||
} else {
|
||||
#if defined(OS_WIN)
|
||||
if (!web_contents())
|
||||
return;
|
||||
content::RenderWidgetHostView* view =
|
||||
web_contents()->GetRenderViewHost()->GetView();
|
||||
CefRenderWidgetHostViewOSR* orview =
|
||||
static_cast<CefRenderWidgetHostViewOSR*>(view);
|
||||
|
||||
if (orview)
|
||||
orview->SendMouseWheelEvent(web_event);
|
||||
#else
|
||||
// TODO(port): Implement this method to work on other platforms as part of
|
||||
// off-screen rendering support.
|
||||
NOTREACHED();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int CefBrowserHostImpl::TranslateModifiers(uint32 cef_modifiers) {
|
||||
int webkit_modifiers = 0;
|
||||
// Set modifiers based on key state.
|
||||
if (cef_modifiers & EVENTFLAG_SHIFT_DOWN)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::ShiftKey;
|
||||
if (cef_modifiers & EVENTFLAG_CONTROL_DOWN)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::ControlKey;
|
||||
if (cef_modifiers & EVENTFLAG_ALT_DOWN)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::AltKey;
|
||||
if (cef_modifiers & EVENTFLAG_COMMAND_DOWN)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::MetaKey;
|
||||
if (cef_modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::LeftButtonDown;
|
||||
if (cef_modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::MiddleButtonDown;
|
||||
if (cef_modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::RightButtonDown;
|
||||
if (cef_modifiers & EVENTFLAG_CAPS_LOCK_ON)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::CapsLockOn;
|
||||
if (cef_modifiers & EVENTFLAG_NUM_LOCK_ON)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::NumLockOn;
|
||||
if (cef_modifiers & EVENTFLAG_IS_LEFT)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::IsLeft;
|
||||
if (cef_modifiers & EVENTFLAG_IS_RIGHT)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::IsRight;
|
||||
if (cef_modifiers & EVENTFLAG_IS_KEY_PAD)
|
||||
webkit_modifiers |= WebKit::WebInputEvent::IsKeyPad;
|
||||
return webkit_modifiers;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SendMouseEvent(const WebKit::WebMouseEvent& event) {
|
||||
if (!IsWindowRenderingDisabled()) {
|
||||
content::RenderWidgetHost* widget = web_contents()->GetRenderViewHost();
|
||||
if (widget)
|
||||
widget->ForwardMouseEvent(event);
|
||||
} else {
|
||||
#if defined(OS_WIN)
|
||||
if (!web_contents())
|
||||
return;
|
||||
content::RenderWidgetHostView* view =
|
||||
web_contents()->GetRenderViewHost()->GetView();
|
||||
CefRenderWidgetHostViewOSR* orview =
|
||||
static_cast<CefRenderWidgetHostViewOSR*>(view);
|
||||
|
||||
if (orview)
|
||||
orview->SendMouseEvent(event);
|
||||
#else
|
||||
// TODO(port): Implement this method to work on other platforms as part of
|
||||
// off-screen rendering support.
|
||||
NOTREACHED();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SendFocusEvent(bool setFocus) {
|
||||
@@ -1440,10 +1531,16 @@ bool CefBrowserHostImpl::ShouldCreateWebContents(
|
||||
}
|
||||
}
|
||||
|
||||
if (IsWindowRenderingDisabled(pending_window_info_) &&
|
||||
!pending_client_->GetRenderHandler().get()) {
|
||||
NOTREACHED() << "CefRenderHandler implementation is required";
|
||||
return false;
|
||||
if (IsWindowRenderingDisabled(pending_window_info_)) {
|
||||
if (!pending_client_->GetRenderHandler().get()) {
|
||||
NOTREACHED() << "CefRenderHandler implementation is required";
|
||||
return false;
|
||||
}
|
||||
if (!pending_settings_.accelerated_compositing_disabled) {
|
||||
// Accelerated compositing is not supported when window rendering is
|
||||
// disabled.
|
||||
pending_settings_.accelerated_compositing_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
_Context->browser_context()->set_use_osr_next_contents_view(
|
||||
|
@@ -35,8 +35,9 @@ struct NativeWebKeyboardEvent;
|
||||
}
|
||||
|
||||
namespace WebKit {
|
||||
class WebMouseEvent;
|
||||
class WebMouseWheelEvent;
|
||||
class WebMouseEvent;
|
||||
class WebMouseWheelEvent;
|
||||
class WebInputEvent;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
@@ -125,12 +126,15 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
CefRefPtr<CefRunFileDialogCallback> callback) OVERRIDE;
|
||||
virtual bool IsWindowRenderingDisabled() OVERRIDE;
|
||||
virtual void WasResized() OVERRIDE;
|
||||
virtual void Invalidate(const CefRect& dirtyRect) OVERRIDE;
|
||||
virtual void Invalidate(const CefRect& dirtyRect,
|
||||
PaintElementType type) OVERRIDE;
|
||||
virtual void SendKeyEvent(const CefKeyEvent& event) OVERRIDE;
|
||||
virtual void SendMouseClickEvent(int x, int y, MouseButtonType type,
|
||||
virtual void SendMouseClickEvent(const CefMouseEvent& event,
|
||||
MouseButtonType type,
|
||||
bool mouseUp, int clickCount) OVERRIDE;
|
||||
virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) OVERRIDE;
|
||||
virtual void SendMouseWheelEvent(int x, int y,
|
||||
virtual void SendMouseMoveEvent(const CefMouseEvent& event,
|
||||
bool mouseLeave) OVERRIDE;
|
||||
virtual void SendMouseWheelEvent(const CefMouseEvent& event,
|
||||
int deltaX, int deltaY) OVERRIDE;
|
||||
virtual void SendFocusEvent(bool setFocus) OVERRIDE;
|
||||
virtual void SendCaptureLostEvent() OVERRIDE;
|
||||
@@ -221,6 +225,8 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
// Returns the URL that is currently loading (or loaded) in the main frame.
|
||||
GURL GetLoadingURL();
|
||||
|
||||
bool IsTransparent();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
static void RegisterWindowClass();
|
||||
#endif
|
||||
@@ -385,16 +391,22 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
void PlatformRunFileChooser(const content::FileChooserParams& params,
|
||||
RunFileChooserCallback callback);
|
||||
|
||||
static bool PlatformTranslateKeyEvent(gfx::NativeEvent& native_event,
|
||||
const CefKeyEvent& key_event);
|
||||
static bool PlatformTranslateClickEvent(WebKit::WebMouseEvent& ev,
|
||||
int x, int y, MouseButtonType type,
|
||||
bool mouseUp, int clickCount);
|
||||
static bool PlatformTranslateMoveEvent(WebKit::WebMouseEvent& ev,
|
||||
int x, int y, bool mouseLeave);
|
||||
static bool PlatformTranslateWheelEvent(WebKit::WebMouseWheelEvent& ev,
|
||||
int x, int y,
|
||||
int deltaX, int deltaY);
|
||||
void PlatformTranslateKeyEvent(content::NativeWebKeyboardEvent& native_event,
|
||||
const CefKeyEvent& key_event);
|
||||
void PlatformTranslateClickEvent(WebKit::WebMouseEvent& web_event,
|
||||
const CefMouseEvent& mouse_event,
|
||||
CefBrowserHost::MouseButtonType type,
|
||||
bool mouseUp, int clickCount);
|
||||
void PlatformTranslateMoveEvent(WebKit::WebMouseEvent& web_event,
|
||||
const CefMouseEvent& mouse_event,
|
||||
bool mouseLeave);
|
||||
void PlatformTranslateWheelEvent(WebKit::WebMouseWheelEvent& web_event,
|
||||
const CefMouseEvent& mouse_event,
|
||||
int deltaX, int deltaY);
|
||||
void PlatformTranslateMouseEvent(WebKit::WebMouseEvent& web_event,
|
||||
const CefMouseEvent& mouse_event);
|
||||
int TranslateModifiers(uint32 cefKeyStates);
|
||||
void SendMouseEvent(const WebKit::WebMouseEvent& web_event);
|
||||
|
||||
void OnAddressChange(CefRefPtr<CefFrame> frame,
|
||||
const GURL& url);
|
||||
|
@@ -334,44 +334,51 @@ void CefBrowserHostImpl::PlatformRunFileChooser(
|
||||
void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
bool CefBrowserHostImpl::IsWindowRenderingDisabled(const CefWindowInfo& info) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateKeyEvent(
|
||||
gfx::NativeEvent& native_event, const CefKeyEvent& event) {
|
||||
bool CefBrowserHostImpl::IsTransparent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
|
||||
content::NativeWebKeyboardEvent& native_event,
|
||||
const CefKeyEvent& event) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateClickEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
int x, int y, MouseButtonType type,
|
||||
bool mouseUp, int clickCount) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateMoveEvent(
|
||||
void CefBrowserHostImpl::PlatformTranslateClickEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
int x, int y, bool mouseLeave) {
|
||||
const CefMouseEvent& mouse_event,
|
||||
MouseButtonType type,
|
||||
bool mouseUp, int clickCount) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateWheelEvent(
|
||||
WebKit::WebMouseWheelEvent& ev,
|
||||
int x, int y, int deltaX, int deltaY) {
|
||||
void CefBrowserHostImpl::PlatformTranslateMoveEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
const CefMouseEvent& mouse_event,
|
||||
bool mouseLeave) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateWheelEvent(
|
||||
WebKit::WebMouseWheelEvent& ev,
|
||||
const CefMouseEvent& mouse_event,
|
||||
int deltaX, int deltaY) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateMouseEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
const CefMouseEvent& mouse_event) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
@@ -319,44 +319,51 @@ void CefBrowserHostImpl::PlatformRunFileChooser(
|
||||
void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
|
||||
}
|
||||
|
||||
//static
|
||||
// static
|
||||
bool CefBrowserHostImpl::IsWindowRenderingDisabled(const CefWindowInfo& info) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateKeyEvent(
|
||||
gfx::NativeEvent& native_event, const CefKeyEvent& event) {
|
||||
bool CefBrowserHostImpl::IsTransparent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
|
||||
content::NativeWebKeyboardEvent& native_event,
|
||||
const CefKeyEvent& event) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateClickEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
int x, int y, MouseButtonType type,
|
||||
bool mouseUp, int clickCount) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateMoveEvent(
|
||||
void CefBrowserHostImpl::PlatformTranslateClickEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
int x, int y, bool mouseLeave) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
const CefMouseEvent& mouse_event,
|
||||
MouseButtonType type,
|
||||
bool mouseUp, int clickCount) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateWheelEvent(
|
||||
WebKit::WebMouseWheelEvent& ev,
|
||||
int x, int y, int deltaX, int deltaY) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
void CefBrowserHostImpl::PlatformTranslateMoveEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
const CefMouseEvent& mouse_event,
|
||||
bool mouseLeave) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateWheelEvent(
|
||||
WebKit::WebMouseWheelEvent& ev,
|
||||
const CefMouseEvent& mouse_event,
|
||||
int deltaX, int deltaY) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateMouseEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
const CefMouseEvent& mouse_event) {
|
||||
// TODO(port): Implement this method as part of off-screen rendering support.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
@@ -687,97 +687,168 @@ bool CefBrowserHostImpl::IsWindowRenderingDisabled(const CefWindowInfo& info) {
|
||||
return info.window_rendering_disabled ? true : false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateKeyEvent(
|
||||
gfx::NativeEvent& native_event, const CefKeyEvent& key_event) {
|
||||
UINT message = 0;
|
||||
WPARAM wparam = key_event.windows_key_code;
|
||||
LPARAM lparam = key_event.native_key_code;
|
||||
bool CefBrowserHostImpl::IsTransparent() {
|
||||
return window_info_.transparent_painting != 0;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
|
||||
content::NativeWebKeyboardEvent& result, const CefKeyEvent& key_event) {
|
||||
result.timeStampSeconds = GetMessageTime() / 1000.0;
|
||||
|
||||
result.windowsKeyCode = key_event.windows_key_code;
|
||||
result.nativeKeyCode = key_event.native_key_code;
|
||||
result.isSystemKey = key_event.is_system_key;
|
||||
switch (key_event.type) {
|
||||
case KEYEVENT_KEYUP:
|
||||
message = key_event.is_system_key ? WM_SYSKEYUP : WM_KEYUP;
|
||||
break;
|
||||
case KEYEVENT_RAWKEYDOWN:
|
||||
case KEYEVENT_KEYDOWN:
|
||||
message = key_event.is_system_key ? WM_SYSKEYDOWN : WM_KEYDOWN;
|
||||
break;
|
||||
case KEYEVENT_CHAR:
|
||||
message = key_event.is_system_key ? WM_SYSCHAR : WM_CHAR;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
gfx::NativeEvent ev = {NULL, message, wparam, lparam};
|
||||
native_event = ev;
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateClickEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
int x, int y, MouseButtonType type,
|
||||
bool mouseUp, int clickCount) {
|
||||
DCHECK(clickCount >=1 && clickCount <= 2);
|
||||
|
||||
UINT message = 0;
|
||||
WPARAM wparam = KeyStatesToWord();
|
||||
LPARAM lparam = MAKELPARAM(x, y);
|
||||
|
||||
if (type == MBT_LEFT) {
|
||||
if (mouseUp)
|
||||
message = (clickCount == 1 ? WM_LBUTTONUP : WM_LBUTTONDBLCLK);
|
||||
else
|
||||
message = WM_LBUTTONDOWN;
|
||||
} else if (type == MBT_MIDDLE) {
|
||||
if (mouseUp)
|
||||
message = (clickCount == 1 ? WM_MBUTTONUP : WM_MBUTTONDBLCLK);
|
||||
else
|
||||
message = WM_MBUTTONDOWN;
|
||||
} else if (type == MBT_RIGHT) {
|
||||
if (mouseUp)
|
||||
message = (clickCount == 1 ? WM_RBUTTONUP : WM_RBUTTONDBLCLK);
|
||||
else
|
||||
message = WM_RBUTTONDOWN;
|
||||
}
|
||||
|
||||
if (message == 0) {
|
||||
case KEYEVENT_RAWKEYDOWN:
|
||||
case KEYEVENT_KEYDOWN:
|
||||
result.type = WebKit::WebInputEvent::RawKeyDown;
|
||||
break;
|
||||
case KEYEVENT_KEYUP:
|
||||
result.type = WebKit::WebInputEvent::KeyUp;
|
||||
break;
|
||||
case KEYEVENT_CHAR:
|
||||
result.type = WebKit::WebInputEvent::Char;
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
ev = WebKit::WebInputEventFactory::mouseEvent(NULL, message, wparam, lparam);
|
||||
return true;
|
||||
if (result.type == WebKit::WebInputEvent::Char ||
|
||||
result.type == WebKit::WebInputEvent::RawKeyDown) {
|
||||
result.text[0] = result.windowsKeyCode;
|
||||
result.unmodifiedText[0] = result.windowsKeyCode;
|
||||
}
|
||||
if (result.type != WebKit::WebInputEvent::Char)
|
||||
result.setKeyIdentifierFromWindowsKeyCode();
|
||||
|
||||
result.modifiers |= TranslateModifiers(key_event.modifiers);
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateMoveEvent(
|
||||
WebKit::WebMouseEvent& ev,
|
||||
int x, int y, bool mouseLeave) {
|
||||
UINT message;
|
||||
WPARAM wparam = KeyStatesToWord();
|
||||
LPARAM lparam = 0;
|
||||
void CefBrowserHostImpl::PlatformTranslateClickEvent(
|
||||
WebKit::WebMouseEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
CefBrowserHost::MouseButtonType type,
|
||||
bool mouseUp, int clickCount) {
|
||||
PlatformTranslateMouseEvent(result, mouse_event);
|
||||
|
||||
if (mouseLeave) {
|
||||
message = WM_MOUSELEAVE;
|
||||
switch (type) {
|
||||
case MBT_LEFT:
|
||||
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
|
||||
WebKit::WebInputEvent::MouseDown;
|
||||
result.button = WebKit::WebMouseEvent::ButtonLeft;
|
||||
break;
|
||||
case MBT_MIDDLE:
|
||||
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
|
||||
WebKit::WebInputEvent::MouseDown;
|
||||
result.button = WebKit::WebMouseEvent::ButtonMiddle;
|
||||
break;
|
||||
case MBT_RIGHT:
|
||||
result.type = mouseUp ? WebKit::WebInputEvent::MouseUp :
|
||||
WebKit::WebInputEvent::MouseDown;
|
||||
result.button = WebKit::WebMouseEvent::ButtonRight;
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
result.clickCount = clickCount;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateMoveEvent(
|
||||
WebKit::WebMouseEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
bool mouseLeave) {
|
||||
PlatformTranslateMouseEvent(result, mouse_event);
|
||||
|
||||
if (!mouseLeave) {
|
||||
result.type = WebKit::WebInputEvent::MouseMove;
|
||||
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
|
||||
result.button = WebKit::WebMouseEvent::ButtonLeft;
|
||||
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
|
||||
result.button = WebKit::WebMouseEvent::ButtonMiddle;
|
||||
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
|
||||
result.button = WebKit::WebMouseEvent::ButtonRight;
|
||||
else
|
||||
result.button = WebKit::WebMouseEvent::ButtonNone;
|
||||
} else {
|
||||
message = WM_MOUSEMOVE;
|
||||
lparam = MAKELPARAM(x, y);
|
||||
result.type = WebKit::WebInputEvent::MouseLeave;
|
||||
result.button = WebKit::WebMouseEvent::ButtonNone;
|
||||
}
|
||||
|
||||
ev = WebKit::WebInputEventFactory::mouseEvent(NULL, message, wparam, lparam);
|
||||
return true;
|
||||
result.clickCount = 0;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserHostImpl::PlatformTranslateWheelEvent(
|
||||
WebKit::WebMouseWheelEvent& ev,
|
||||
int x, int y, int deltaX, int deltaY) {
|
||||
WPARAM wparam = MAKEWPARAM(KeyStatesToWord(), deltaY);
|
||||
LPARAM lparam = MAKELPARAM(x, y);
|
||||
void CefBrowserHostImpl::PlatformTranslateWheelEvent(
|
||||
WebKit::WebMouseWheelEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
int deltaX, int deltaY) {
|
||||
PlatformTranslateMouseEvent(result, mouse_event);
|
||||
|
||||
ev = WebKit::WebInputEventFactory::mouseWheelEvent(NULL, WM_MOUSEWHEEL,
|
||||
wparam, lparam);
|
||||
return true;
|
||||
result.type = WebKit::WebInputEvent::MouseWheel;
|
||||
result.button = WebKit::WebMouseEvent::ButtonNone;
|
||||
|
||||
float wheelDelta;
|
||||
bool horizontalScroll = false;
|
||||
|
||||
wheelDelta = static_cast<float>(deltaY ? deltaY : deltaX);
|
||||
|
||||
horizontalScroll = (deltaY == 0);
|
||||
|
||||
static const ULONG defaultScrollCharsPerWheelDelta = 1;
|
||||
static const FLOAT scrollbarPixelsPerLine = 100.0f / 3.0f;
|
||||
static const ULONG defaultScrollLinesPerWheelDelta = 3;
|
||||
wheelDelta /= WHEEL_DELTA;
|
||||
float scrollDelta = wheelDelta;
|
||||
if (horizontalScroll) {
|
||||
ULONG scrollChars = defaultScrollCharsPerWheelDelta;
|
||||
SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
|
||||
scrollDelta *= static_cast<FLOAT>(scrollChars) * scrollbarPixelsPerLine;
|
||||
} else {
|
||||
ULONG scrollLines = defaultScrollLinesPerWheelDelta;
|
||||
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
|
||||
if (scrollLines == WHEEL_PAGESCROLL)
|
||||
result.scrollByPage = true;
|
||||
if (!result.scrollByPage)
|
||||
scrollDelta *= static_cast<FLOAT>(scrollLines) * scrollbarPixelsPerLine;
|
||||
}
|
||||
|
||||
// Set scroll amount based on above calculations. WebKit expects positive
|
||||
// deltaY to mean "scroll up" and positive deltaX to mean "scroll left".
|
||||
if (horizontalScroll) {
|
||||
result.deltaX = scrollDelta;
|
||||
result.wheelTicksX = wheelDelta;
|
||||
} else {
|
||||
result.deltaY = scrollDelta;
|
||||
result.wheelTicksY = wheelDelta;
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::PlatformTranslateMouseEvent(
|
||||
WebKit::WebMouseEvent& result,
|
||||
const CefMouseEvent& mouse_event) {
|
||||
// position
|
||||
result.x = mouse_event.x;
|
||||
result.y = mouse_event.y;
|
||||
result.windowX = result.x;
|
||||
result.windowY = result.y;
|
||||
result.globalX = result.x;
|
||||
result.globalY = result.y;
|
||||
|
||||
// global position
|
||||
if (IsWindowRenderingDisabled()) {
|
||||
GetClient()->GetRenderHandler()->GetScreenPoint(GetBrowser(),
|
||||
result.x, result.y,
|
||||
result.globalX, result.globalY);
|
||||
} else {
|
||||
POINT globalPoint = { result.x, result.y };
|
||||
ClientToScreen(GetWindowHandle(), &globalPoint);
|
||||
result.globalX = globalPoint.x;
|
||||
result.globalY = globalPoint.y;
|
||||
}
|
||||
|
||||
// modifiers
|
||||
result.modifiers |= TranslateModifiers(mouse_event.modifiers);
|
||||
|
||||
// timestamp
|
||||
result.timeStampSeconds = GetMessageTime() / 1000.0;
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/render_widget_host_view_osr.h"
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
@@ -20,13 +21,18 @@
|
||||
CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
|
||||
content::RenderWidgetHost* widget)
|
||||
: render_widget_host_(content::RenderWidgetHostImpl::From(widget)),
|
||||
about_to_validate_and_paint_(false) {
|
||||
about_to_validate_and_paint_(false),
|
||||
parent_host_view_(NULL),
|
||||
popup_host_view_(NULL),
|
||||
weak_factory_(this) {
|
||||
DCHECK(render_widget_host_);
|
||||
render_widget_host_->SetView(this);
|
||||
|
||||
// CefBrowserHostImpl might not be created at this time for popups.
|
||||
browser_impl_ = CefBrowserHostImpl::GetBrowserForHost(
|
||||
content::RenderViewHost::From(render_widget_host_));
|
||||
if (render_widget_host_->IsRenderView()) {
|
||||
browser_impl_ = CefBrowserHostImpl::GetBrowserForHost(
|
||||
content::RenderViewHost::From(render_widget_host_));
|
||||
}
|
||||
}
|
||||
|
||||
CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
|
||||
@@ -49,7 +55,7 @@ void CefRenderWidgetHostViewOSR::SetBounds(const gfx::Rect& rect) {
|
||||
}
|
||||
|
||||
gfx::NativeView CefRenderWidgetHostViewOSR::GetNativeView() const {
|
||||
return gfx::NativeView();
|
||||
return browser_impl_.get() ? browser_impl_->GetWindowHandle() : NULL;
|
||||
}
|
||||
|
||||
gfx::NativeViewId CefRenderWidgetHostViewOSR::GetNativeViewId() const {
|
||||
@@ -81,12 +87,14 @@ void CefRenderWidgetHostViewOSR::Hide() {
|
||||
WasHidden();
|
||||
}
|
||||
|
||||
|
||||
bool CefRenderWidgetHostViewOSR::IsShowing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
gfx::Rect CefRenderWidgetHostViewOSR::GetViewBounds() const {
|
||||
if (IsPopupWidget())
|
||||
return popup_position_;
|
||||
|
||||
if (!browser_impl_.get())
|
||||
return gfx::Rect();
|
||||
CefRect rc;
|
||||
@@ -99,10 +107,24 @@ gfx::Rect CefRenderWidgetHostViewOSR::GetViewBounds() const {
|
||||
void CefRenderWidgetHostViewOSR::InitAsPopup(
|
||||
RenderWidgetHostView* parent_host_view,
|
||||
const gfx::Rect& pos) {
|
||||
parent_host_view_ = static_cast<CefRenderWidgetHostViewOSR*>(
|
||||
parent_host_view);
|
||||
browser_impl_ = parent_host_view_->get_browser_impl();
|
||||
if (!browser_impl_.get())
|
||||
return;
|
||||
|
||||
parent_host_view_->CancelWidget();
|
||||
|
||||
parent_host_view_->set_popup_host_view(this);
|
||||
NotifyShowWidget();
|
||||
|
||||
popup_position_ = pos;
|
||||
NotifySizeWidget();
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::InitAsFullscreen(
|
||||
RenderWidgetHostView* reference_host_view) {
|
||||
RenderWidgetHostView* reference_host_view) {
|
||||
NOTREACHED() << "Fullscreen widgets are not supported in OSR";
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::WasShown() {
|
||||
@@ -172,6 +194,8 @@ void CefRenderWidgetHostViewOSR::RenderViewGone(
|
||||
base::TerminationStatus status,
|
||||
int error_code) {
|
||||
render_widget_host_ = NULL;
|
||||
parent_host_view_ = NULL;
|
||||
popup_host_view_ = NULL;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN) && !defined(USE_AURA)
|
||||
@@ -185,11 +209,7 @@ gfx::Rect CefRenderWidgetHostViewOSR::GetBoundsInRootWindow() {
|
||||
if (!browser_impl_.get())
|
||||
return gfx::Rect();
|
||||
CefRect rc;
|
||||
// If GetRootScreenRect is not implemented use the view rect as the root
|
||||
// screen rect.
|
||||
if (browser_impl_->GetClient()->GetRenderHandler()->GetRootScreenRect(
|
||||
browser_impl_->GetBrowser(), rc) ||
|
||||
browser_impl_->GetClient()->GetRenderHandler()->GetViewRect(
|
||||
browser_impl_->GetBrowser(), rc)) {
|
||||
return gfx::Rect(rc.x, rc.y, rc.width, rc.height);
|
||||
}
|
||||
@@ -197,6 +217,13 @@ gfx::Rect CefRenderWidgetHostViewOSR::GetBoundsInRootWindow() {
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::Destroy() {
|
||||
if (IsPopupWidget()) {
|
||||
if (parent_host_view_)
|
||||
parent_host_view_->CancelWidget();
|
||||
} else {
|
||||
CancelWidget();
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
@@ -214,13 +241,15 @@ void CefRenderWidgetHostViewOSR::SetTooltipText(const string16& tooltip_text) {
|
||||
|
||||
content::BackingStore* CefRenderWidgetHostViewOSR::AllocBackingStore(
|
||||
const gfx::Size& size) {
|
||||
return new BackingStoreOSR(render_widget_host_, size);
|
||||
return render_widget_host_ ?
|
||||
new BackingStoreOSR(render_widget_host_, size) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::CopyFromCompositingSurface(
|
||||
const gfx::Rect& src_subrect,
|
||||
const gfx::Size& dst_size,
|
||||
const base::Callback<void(bool)>& callback,
|
||||
const base::Callback<void(bool b)>& callback,
|
||||
skia::PlatformBitmap* output) {
|
||||
}
|
||||
|
||||
@@ -269,7 +298,20 @@ void CefRenderWidgetHostViewOSR::SetClickthroughRegion(SkRegion* region) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void CefRenderWidgetHostViewOSR::Invalidate(const gfx::Rect& rect) {
|
||||
void CefRenderWidgetHostViewOSR::SetBackground(const SkBitmap& background) {
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
RenderWidgetHostViewBase::SetBackground(background);
|
||||
render_widget_host_->SetBackground(background);
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::Invalidate(const gfx::Rect& rect,
|
||||
CefBrowserHost::PaintElementType type) {
|
||||
if (!IsPopupWidget() && type == PET_POPUP) {
|
||||
if (popup_host_view_)
|
||||
popup_host_view_->Invalidate(rect, type);
|
||||
return;
|
||||
}
|
||||
std::vector<gfx::Rect> dirtyRects;
|
||||
dirtyRects.push_back(rect);
|
||||
Paint(dirtyRects);
|
||||
@@ -322,9 +364,72 @@ void CefRenderWidgetHostViewOSR::Paint(
|
||||
return;
|
||||
|
||||
browser_impl_->GetClient()->GetRenderHandler()->OnPaint(
|
||||
browser_impl_->GetBrowser(), PET_VIEW, rcList,
|
||||
browser_impl_->GetBrowser(),
|
||||
IsPopupWidget() ? PET_POPUP : PET_VIEW,
|
||||
rcList,
|
||||
backing_store->getPixels(),
|
||||
client_rect.width(), client_rect.height());
|
||||
client_rect.width(),
|
||||
client_rect.height());
|
||||
}
|
||||
}
|
||||
|
||||
bool CefRenderWidgetHostViewOSR::InstallTransparency() {
|
||||
if (browser_impl_.get() && browser_impl_->IsTransparent()) {
|
||||
SkBitmap bg;
|
||||
bg.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); // 1x1 alpha bitmap.
|
||||
bg.allocPixels();
|
||||
bg.eraseARGB(0x00, 0x00, 0x00, 0x00);
|
||||
SetBackground(bg);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::CancelWidget() {
|
||||
if (IsPopupWidget()) {
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->LostCapture();
|
||||
|
||||
if (browser_impl_.get()) {
|
||||
NotifyHideWidget();
|
||||
browser_impl_ = NULL;
|
||||
}
|
||||
|
||||
if (parent_host_view_) {
|
||||
parent_host_view_->set_popup_host_view(NULL);
|
||||
parent_host_view_ = NULL;
|
||||
}
|
||||
|
||||
if (!weak_factory_.HasWeakPtrs()) {
|
||||
MessageLoop::current()->PostTask(FROM_HERE,
|
||||
base::Bind(&CefRenderWidgetHostViewOSR::ShutdownHost,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
} else if (popup_host_view_) {
|
||||
popup_host_view_->CancelWidget();
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::NotifyShowWidget() {
|
||||
if (browser_impl_.get()) {
|
||||
browser_impl_->GetClient()->GetRenderHandler()->OnPopupShow(
|
||||
browser_impl_->GetBrowser(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::NotifyHideWidget() {
|
||||
if (browser_impl_.get()) {
|
||||
browser_impl_->GetClient()->GetRenderHandler()->OnPopupShow(
|
||||
browser_impl_->GetBrowser(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::NotifySizeWidget() {
|
||||
if (browser_impl_.get()) {
|
||||
CefRect widget_pos(popup_position_.x(), popup_position_.y(),
|
||||
popup_position_.width(), popup_position_.height());
|
||||
browser_impl_->GetClient()->GetRenderHandler()->OnPopupSize(
|
||||
browser_impl_->GetBrowser(), widget_pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,3 +442,71 @@ void CefRenderWidgetHostViewOSR::set_browser_impl(
|
||||
CefRefPtr<CefBrowserHostImpl> browser) {
|
||||
browser_impl_ = browser;
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::set_popup_host_view(
|
||||
CefRenderWidgetHostViewOSR* popup_view) {
|
||||
popup_host_view_ = popup_view;
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::ShutdownHost() {
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->Shutdown();
|
||||
// Do not touch any members at this point, |this| has been deleted.
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::set_parent_host_view(
|
||||
CefRenderWidgetHostViewOSR* parent_view) {
|
||||
parent_host_view_ = parent_view;
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SendKeyEvent(
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
if (!IsPopupWidget() && popup_host_view_) {
|
||||
popup_host_view_->SendKeyEvent(event);
|
||||
return;
|
||||
}
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
render_widget_host_->ForwardKeyboardEvent(event);
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SendMouseEvent(
|
||||
const WebKit::WebMouseEvent& event) {
|
||||
if (!IsPopupWidget() && popup_host_view_) {
|
||||
if (popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
WebKit::WebMouseEvent popup_event(event);
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_event.windowX = popup_event.x;
|
||||
popup_event.windowY = popup_event.y;
|
||||
|
||||
popup_host_view_->SendMouseEvent(popup_event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
render_widget_host_->ForwardMouseEvent(event);
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SendMouseWheelEvent(
|
||||
const WebKit::WebMouseWheelEvent& event) {
|
||||
if (!IsPopupWidget() && popup_host_view_) {
|
||||
if (popup_host_view_->popup_position_.Contains(event.x, event.y)) {
|
||||
WebKit::WebMouseWheelEvent popup_event(event);
|
||||
popup_event.x -= popup_host_view_->popup_position_.x();
|
||||
popup_event.y -= popup_host_view_->popup_position_.y();
|
||||
popup_event.windowX = popup_event.x;
|
||||
popup_event.windowY = popup_event.y;
|
||||
popup_host_view_->SendMouseWheelEvent(popup_event);
|
||||
return;
|
||||
} else {
|
||||
// scrolling outside the popup widget, will destroy widget
|
||||
CancelWidget();
|
||||
}
|
||||
}
|
||||
if (!render_widget_host_)
|
||||
return;
|
||||
render_widget_host_->ForwardWheelEvent(event);
|
||||
}
|
||||
|
@@ -10,7 +10,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "include/cef_base.h"
|
||||
#include "include/cef_browser.h"
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_base.h"
|
||||
|
||||
namespace content {
|
||||
@@ -90,7 +92,7 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase {
|
||||
virtual void CopyFromCompositingSurface(
|
||||
const gfx::Rect& src_subrect,
|
||||
const gfx::Size& dst_size,
|
||||
const base::Callback<void(bool)>& callback,
|
||||
const base::Callback<void(bool b)>& callback,
|
||||
skia::PlatformBitmap* output) OVERRIDE;
|
||||
virtual void OnAcceleratedCompositingStateChange() OVERRIDE;
|
||||
virtual void SetHasHorizontalScrollbar(
|
||||
@@ -113,12 +115,31 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase {
|
||||
virtual void SetClickthroughRegion(SkRegion* region) OVERRIDE;
|
||||
#endif
|
||||
|
||||
// CefRenderWidgetHostViewOSR methods
|
||||
void Invalidate(const gfx::Rect& rect);
|
||||
// RenderWidgetHostViewBase methods.
|
||||
virtual void SetBackground(const SkBitmap& background) OVERRIDE;
|
||||
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event);
|
||||
void SendMouseEvent(const WebKit::WebMouseEvent& event);
|
||||
void SendMouseWheelEvent(const WebKit::WebMouseWheelEvent& event);
|
||||
|
||||
void Invalidate(const gfx::Rect& rect,
|
||||
CefBrowserHost::PaintElementType type);
|
||||
void Paint(const std::vector<gfx::Rect>& copy_rects);
|
||||
bool InstallTransparency();
|
||||
|
||||
void CancelWidget();
|
||||
void NotifyShowWidget();
|
||||
void NotifyHideWidget();
|
||||
void NotifySizeWidget();
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> get_browser_impl() const;
|
||||
void set_browser_impl(CefRefPtr<CefBrowserHostImpl> browser);
|
||||
void set_popup_host_view(CefRenderWidgetHostViewOSR* popup_view);
|
||||
void set_parent_host_view(CefRenderWidgetHostViewOSR* parent_view);
|
||||
|
||||
bool IsPopupWidget() const {
|
||||
return popup_type_ != WebKit::WebPopupTypeNone;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class CefWebContentsViewOSR;
|
||||
@@ -126,16 +147,26 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase {
|
||||
explicit CefRenderWidgetHostViewOSR(content::RenderWidgetHost* widget);
|
||||
virtual ~CefRenderWidgetHostViewOSR();
|
||||
|
||||
// After calling this function, object gets deleted
|
||||
void ShutdownHost();
|
||||
|
||||
// Factory used to safely scope delayed calls to ShutdownHost().
|
||||
base::WeakPtrFactory<CefRenderWidgetHostViewOSR> weak_factory_;
|
||||
|
||||
// The associated Model. While |this| is being Destroyed,
|
||||
// |render_widget_host_| is NULL and the Windows message loop is run one last
|
||||
// time. Message handlers must check for a NULL |render_widget_host_|.
|
||||
content::RenderWidgetHostImpl* render_widget_host_;
|
||||
CefRenderWidgetHostViewOSR* parent_host_view_;
|
||||
CefRenderWidgetHostViewOSR* popup_host_view_;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser_impl_;
|
||||
|
||||
bool about_to_validate_and_paint_;
|
||||
std::vector<gfx::Rect> pending_update_rects_;
|
||||
|
||||
gfx::Rect popup_position_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefRenderWidgetHostViewOSR);
|
||||
};
|
||||
|
||||
|
@@ -33,6 +33,13 @@ content::RenderWidgetHostView* CefWebContentsViewOSR::CreateViewForWidget(
|
||||
return view_;
|
||||
}
|
||||
|
||||
content::RenderWidgetHostView* CefWebContentsViewOSR::CreateViewForPopupWidget(
|
||||
content::RenderWidgetHost* render_widget_host) {
|
||||
CefRenderWidgetHostViewOSR* popup_widget =
|
||||
new CefRenderWidgetHostViewOSR(render_widget_host);
|
||||
return popup_widget;
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::SetView(content::RenderWidgetHostView* view) {
|
||||
view_ = view;
|
||||
}
|
||||
@@ -66,6 +73,11 @@ void CefWebContentsViewOSR::SizeContents(const gfx::Size& size) {
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::RenderViewCreated(content::RenderViewHost* host) {
|
||||
if (view_) {
|
||||
CefRenderWidgetHostViewOSR* osr_view =
|
||||
static_cast<CefRenderWidgetHostViewOSR*>(view_);
|
||||
osr_view->InstallTransparency();
|
||||
}
|
||||
}
|
||||
|
||||
void CefWebContentsViewOSR::Focus() {
|
||||
|
@@ -30,6 +30,8 @@ class CefWebContentsViewOSR : public content::WebContentsView,
|
||||
virtual void CreateView(const gfx::Size& initial_size) OVERRIDE;
|
||||
virtual content::RenderWidgetHostView* CreateViewForWidget(
|
||||
content::RenderWidgetHost* render_widget_host) OVERRIDE;
|
||||
virtual content::RenderWidgetHostView* CreateViewForPopupWidget(
|
||||
content::RenderWidgetHost* render_widget_host);
|
||||
virtual void SetView(content::RenderWidgetHostView* view) OVERRIDE;
|
||||
virtual gfx::NativeView GetNativeView() const OVERRIDE;
|
||||
virtual gfx::NativeView GetContentNativeView() const OVERRIDE;
|
||||
|
Reference in New Issue
Block a user