cef/libcef/webwidget_host.cc

127 lines
3.8 KiB
C++

// Copyright (c) 2011 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/webwidget_host.h"
#include "libcef/cef_thread.h"
#include "base/bind.h"
#include "base/message_loop.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebWidget.h"
using webkit::npapi::WebPluginGeometry;
using WebKit::WebSize;
void WebWidgetHost::ScheduleComposite() {
if (has_invalidate_task_)
return;
has_invalidate_task_ = true;
// Try to paint at 60fps.
static int64 kDesiredRate = 16;
base::TimeDelta delta = base::TimeTicks::Now() - paint_last_call_;
int64 actualRate = delta.InMilliseconds();
if (actualRate >= kDesiredRate) {
// Can't keep up so run as fast as possible.
MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&WebWidgetHost::Invalidate, weak_factory_.GetWeakPtr()));
} else {
// Maintain the desired rate.
MessageLoop::current()->PostDelayedTask(FROM_HERE,
base::Bind(&WebWidgetHost::Invalidate, weak_factory_.GetWeakPtr()),
kDesiredRate - actualRate);
}
}
void WebWidgetHost::ScheduleAnimation() {
ScheduleComposite();
}
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
#if defined(OS_WIN) || defined(OS_MACOSX)
paint_rgn_.op(rect.x(), rect.y(), rect.right(), rect.bottom(),
SkRegion::kUnion_Op);
#else
// TODO(cef): Update all ports to use regions instead of rectangles.
paint_rect_ = paint_rect_.Union(rect);
#endif
}
void WebWidgetHost::UpdateRedrawRect(const gfx::Rect& rect) {
if (!view_)
redraw_rect_ = redraw_rect_.Union(rect);
}
void WebWidgetHost::SetSize(int width, int height) {
webwidget_->resize(WebSize(width, height));
DidInvalidateRect(gfx::Rect(0, 0, width, height));
EnsureTooltip();
}
void WebWidgetHost::GetSize(int& width, int& height) {
const WebSize& size = webwidget_->size();
width = size.width;
height = size.height;
}
void WebWidgetHost::AddWindowedPlugin(gfx::PluginWindowHandle handle) {
WebPluginGeometry geometry;
plugin_map_.insert(std::make_pair(handle, geometry));
}
void WebWidgetHost::RemoveWindowedPlugin(gfx::PluginWindowHandle handle) {
PluginMap::iterator it = plugin_map_.find(handle);
DCHECK(it != plugin_map_.end());
plugin_map_.erase(it);
}
void WebWidgetHost::MoveWindowedPlugin(const WebPluginGeometry& move) {
PluginMap::iterator it = plugin_map_.find(move.window);
DCHECK(it != plugin_map_.end());
it->second.window = move.window;
if (move.rects_valid) {
it->second.window_rect = move.window_rect;
it->second.clip_rect = move.clip_rect;
it->second.cutout_rects = move.cutout_rects;
it->second.rects_valid = true;
}
it->second.visible = move.visible;
}
gfx::PluginWindowHandle WebWidgetHost::GetWindowedPluginAt(int x, int y) {
if (!plugin_map_.empty()) {
PluginMap::const_iterator it = plugin_map_.begin();
for (; it != plugin_map_.end(); ++it) {
if (it->second.visible && it->second.window_rect.Contains(x, y))
return it->second.window;
}
}
return gfx::kNullPluginWindow;
}
void WebWidgetHost::DoPaint() {
// TODO(cef): The below code is cross-platform but the IsIdle() method
// currently requires patches to Chromium. Since this code is only executed
// on Windows it's been stuck behind an #ifdef for now to avoid having to
// patch Chromium code on other platforms.
#if defined(OS_WIN)
if (MessageLoop::current()->IsIdle()) {
has_update_task_ = false;
// Paint to the delegate.
Paint();
} else {
// Try again later.
CefThread::PostTask(CefThread::UI, FROM_HERE,
base::Bind(&WebWidgetHost::DoPaint, weak_factory_.GetWeakPtr()));
}
#else
NOTIMPLEMENTED();
#endif
}