- Add initial Linux implementation files.
- Fix copyright years. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@161 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
7b91ff9266
commit
b8385a7649
|
@ -73,6 +73,9 @@ public:
|
||||||
pthread_mutexattr_t attr_;
|
pthread_mutexattr_t attr_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Window handle.
|
||||||
|
#define CefWindowHandle cef_window_handle_t
|
||||||
|
|
||||||
// Class representing window information.
|
// Class representing window information.
|
||||||
class CefWindowInfo : public cef_window_info_t
|
class CefWindowInfo : public cef_window_info_t
|
||||||
{
|
{
|
||||||
|
@ -99,7 +102,6 @@ public:
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
cef_string_clear(&m_windowName);
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,17 +116,19 @@ public:
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetAsChild(CefWindowHandle ParentWidget)
|
||||||
|
{
|
||||||
|
m_ParentWidget = ParentWidget;
|
||||||
|
}
|
||||||
|
|
||||||
CefWindowInfo& operator=(const CefWindowInfo& r)
|
CefWindowInfo& operator=(const CefWindowInfo& r)
|
||||||
{
|
{
|
||||||
return operator=(static_cast<const cef_window_info_t&>(r));
|
return operator=(static_cast<const cef_window_info_t&>(r));
|
||||||
}
|
}
|
||||||
CefWindowInfo& operator=(const cef_window_info_t& r)
|
CefWindowInfo& operator=(const cef_window_info_t& r)
|
||||||
{
|
{
|
||||||
cef_string_copy(r.m_windowName.str, r.m_windowName.length, &m_windowName);
|
m_Widget = r.m_Widget;
|
||||||
m_x = r.m_x;
|
m_ParentWidget = r.m_ParentWidget;
|
||||||
m_y = r.m_y;
|
|
||||||
m_nWidth = r.m_nWidth;
|
|
||||||
m_nHeight = r.m_nHeight;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,8 +179,6 @@ protected:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Window handle.
|
|
||||||
#define CefWindowHandle cef_window_handle_t
|
|
||||||
#endif // defined(__linux__)
|
#endif // defined(__linux__)
|
||||||
|
|
||||||
#endif // _CEF_LINUX_H
|
#endif // _CEF_LINUX_H
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#define _CEF_TYPES_LINUX_H
|
#define _CEF_TYPES_LINUX_H
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
#include <gtk/gtk.h>
|
||||||
#include "cef_string.h"
|
#include "cef_string.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -39,17 +40,16 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Window handle.
|
// Window handle.
|
||||||
#define cef_window_handle_t void*
|
#define cef_window_handle_t GtkWidget*
|
||||||
|
|
||||||
// Class representing window information.
|
// Class representing window information.
|
||||||
typedef struct _cef_window_info_t
|
typedef struct _cef_window_info_t
|
||||||
{
|
{
|
||||||
// Standard parameters required by CreateWindowEx()
|
// Pointer for the parent GtkBox widget.
|
||||||
cef_string_t m_windowName;
|
cef_window_handle_t m_ParentWidget;
|
||||||
int m_x;
|
|
||||||
int m_y;
|
// Pointer for the new browser widget.
|
||||||
int m_nWidth;
|
cef_window_handle_t m_Widget;
|
||||||
int m_nHeight;
|
|
||||||
} cef_window_info_t;
|
} cef_window_info_t;
|
||||||
|
|
||||||
// Class representing print context information.
|
// Class representing print context information.
|
||||||
|
|
|
@ -44,7 +44,6 @@ extern "C" {
|
||||||
// Class representing window information.
|
// Class representing window information.
|
||||||
typedef struct _cef_window_info_t
|
typedef struct _cef_window_info_t
|
||||||
{
|
{
|
||||||
// Standard parameters required by CreateWindowEx()
|
|
||||||
cef_string_t m_windowName;
|
cef_string_t m_windowName;
|
||||||
int m_x;
|
int m_x;
|
||||||
int m_y;
|
int m_y;
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
// Copyright (c) 2011 The Chromium Embedded Framework Authors.
|
||||||
|
// Portions copyright (c) 2006-2008 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 "cef_context.h"
|
||||||
|
#include "browser_impl.h"
|
||||||
|
#include "browser_settings.h"
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
|
||||||
|
#include "webkit/glue/webpreferences.h"
|
||||||
|
|
||||||
|
using WebKit::WebRect;
|
||||||
|
using WebKit::WebSize;
|
||||||
|
|
||||||
|
CefWindowHandle CefBrowserImpl::GetWindowHandle()
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
CefWindowHandle handle = window_info_.m_Widget;
|
||||||
|
Unlock();
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::NativeWindow CefBrowserImpl::GetMainWndHandle() const {
|
||||||
|
GtkWidget* toplevel = gtk_widget_get_ancestor(window_info_.m_Widget,
|
||||||
|
GTK_TYPE_WINDOW);
|
||||||
|
return GTK_IS_WINDOW(toplevel) ? GTK_WINDOW(toplevel) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefBrowserImpl::UIT_CreateBrowser(const CefString& url)
|
||||||
|
{
|
||||||
|
REQUIRE_UIT();
|
||||||
|
|
||||||
|
// Add a reference that will be released in UIT_DestroyBrowser().
|
||||||
|
AddRef();
|
||||||
|
|
||||||
|
// Add the new browser to the list maintained by the context
|
||||||
|
_Context->AddBrowser(this);
|
||||||
|
|
||||||
|
WebPreferences prefs;
|
||||||
|
BrowserToWebSettings(settings_, prefs);
|
||||||
|
|
||||||
|
// Create the webview host object
|
||||||
|
webviewhost_.reset(
|
||||||
|
WebViewHost::Create(window_info_.m_ParentWidget, gfx::Rect(),
|
||||||
|
delegate_.get(), NULL, prefs));
|
||||||
|
delegate_->RegisterDragDrop();
|
||||||
|
|
||||||
|
window_info_.m_Widget = webviewhost_->view_handle();
|
||||||
|
|
||||||
|
if(handler_.get()) {
|
||||||
|
// Notify the handler that we're done creating the new window
|
||||||
|
handler_->HandleAfterCreated(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(url.size() > 0) {
|
||||||
|
CefRefPtr<CefFrame> frame = GetMainFrame();
|
||||||
|
frame->AddRef();
|
||||||
|
UIT_LoadURL(frame, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefBrowserImpl::UIT_SetFocus(WebWidgetHost* host, bool enable)
|
||||||
|
{
|
||||||
|
REQUIRE_UIT();
|
||||||
|
if (!host)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(enable)
|
||||||
|
gtk_widget_grab_focus(host->view_handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
WebKit::WebWidget* CefBrowserImpl::UIT_CreatePopupWidget()
|
||||||
|
{
|
||||||
|
REQUIRE_UIT();
|
||||||
|
|
||||||
|
DCHECK(!popuphost_);
|
||||||
|
popuphost_ = WebWidgetHost::Create(NULL, popup_delegate_.get());
|
||||||
|
|
||||||
|
// TODO(port): Show window.
|
||||||
|
|
||||||
|
return popuphost_->webwidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefBrowserImpl::UIT_ClosePopupWidget()
|
||||||
|
{
|
||||||
|
REQUIRE_UIT();
|
||||||
|
|
||||||
|
// TODO(port): Close window.
|
||||||
|
popuphost_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CefBrowserImpl::UIT_ViewDocumentString(WebKit::WebFrame *frame)
|
||||||
|
{
|
||||||
|
REQUIRE_UIT();
|
||||||
|
|
||||||
|
// TODO(port): Add implementation.
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
|
||||||
|
const gfx::Size& canvas_size,
|
||||||
|
WebKit::WebFrame* frame) {
|
||||||
|
REQUIRE_UIT();
|
||||||
|
|
||||||
|
// TODO(port): Add implementation.
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefBrowserImpl::UIT_PrintPages(WebKit::WebFrame* frame) {
|
||||||
|
REQUIRE_UIT();
|
||||||
|
|
||||||
|
// TODO(port): Add implementation.
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CefBrowserImpl::UIT_GetPagesCount(WebKit::WebFrame* frame)
|
||||||
|
{
|
||||||
|
REQUIRE_UIT();
|
||||||
|
|
||||||
|
// TODO(port): Add implementation.
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,252 @@
|
||||||
|
// Copyright (c) 2011 The Chromium Embedded Framework Authors.
|
||||||
|
// Portions copyright (c) 2006-2008 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 "browser_webview_delegate.h"
|
||||||
|
#include "browser_impl.h"
|
||||||
|
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "base/message_loop.h"
|
||||||
|
#include "gfx/gtk_util.h"
|
||||||
|
#include "gfx/point.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
|
||||||
|
#include "webkit/glue/webcursor.h"
|
||||||
|
#include "webkit/glue/webdropdata.h"
|
||||||
|
#include "webkit/glue/webpreferences.h"
|
||||||
|
#include "webkit/glue/window_open_disposition.h"
|
||||||
|
#include "webkit/plugins/npapi/gtk_plugin_container_manager.h"
|
||||||
|
#include "webkit/plugins/npapi/plugin_list.h"
|
||||||
|
#include "webkit/plugins/npapi/webplugin.h"
|
||||||
|
#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
|
||||||
|
|
||||||
|
using WebKit::WebCursorInfo;
|
||||||
|
using WebKit::WebFrame;
|
||||||
|
using WebKit::WebNavigationPolicy;
|
||||||
|
using WebKit::WebPopupMenuInfo;
|
||||||
|
using WebKit::WebRect;
|
||||||
|
using WebKit::WebWidget;
|
||||||
|
using WebKit::WebView;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
enum SelectionClipboardType {
|
||||||
|
TEXT_HTML,
|
||||||
|
PLAIN_TEXT,
|
||||||
|
};
|
||||||
|
|
||||||
|
GdkAtom GetTextHtmlAtom() {
|
||||||
|
GdkAtom kTextHtmlGdkAtom = gdk_atom_intern_static_string("text/html");
|
||||||
|
return kTextHtmlGdkAtom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectionClipboardGetContents(GtkClipboard* clipboard,
|
||||||
|
GtkSelectionData* selection_data, guint info, gpointer data) {
|
||||||
|
// Ignore formats that we don't know about.
|
||||||
|
if (info != TEXT_HTML && info != PLAIN_TEXT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WebView* webview = static_cast<WebView*>(data);
|
||||||
|
WebFrame* frame = webview->focusedFrame();
|
||||||
|
if (!frame)
|
||||||
|
frame = webview->mainFrame();
|
||||||
|
DCHECK(frame);
|
||||||
|
|
||||||
|
std::string selection;
|
||||||
|
if (TEXT_HTML == info) {
|
||||||
|
selection = frame->selectionAsMarkup().utf8();
|
||||||
|
} else {
|
||||||
|
selection = frame->selectionAsText().utf8();
|
||||||
|
}
|
||||||
|
if (TEXT_HTML == info) {
|
||||||
|
gtk_selection_data_set(selection_data,
|
||||||
|
GetTextHtmlAtom(),
|
||||||
|
8 /* bits per data unit, ie, char */,
|
||||||
|
reinterpret_cast<const guchar*>(selection.data()),
|
||||||
|
selection.length());
|
||||||
|
} else {
|
||||||
|
gtk_selection_data_set_text(selection_data, selection.data(),
|
||||||
|
selection.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// WebViewClient --------------------------------------------------------------
|
||||||
|
|
||||||
|
WebWidget* BrowserWebViewDelegate::createPopupMenu(
|
||||||
|
const WebPopupMenuInfo& info) {
|
||||||
|
NOTREACHED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::showContextMenu(
|
||||||
|
WebKit::WebFrame* frame, const WebKit::WebContextMenuData& data) {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebWidgetClient ------------------------------------------------------------
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::show(WebNavigationPolicy policy) {
|
||||||
|
WebWidgetHost* host = GetWidgetHost();
|
||||||
|
GtkWidget* drawing_area = host->view_handle();
|
||||||
|
GtkWidget* window =
|
||||||
|
gtk_widget_get_parent(gtk_widget_get_parent(drawing_area));
|
||||||
|
gtk_widget_show_all(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::closeWidgetSoon() {
|
||||||
|
if (this == browser_->GetWebViewDelegate()) {
|
||||||
|
MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(
|
||||||
|
>k_widget_destroy, GTK_WIDGET(browser_->GetMainWndHandle())));
|
||||||
|
} else if (this == browser_->GetPopupDelegate()) {
|
||||||
|
browser_->UIT_ClosePopupWidget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::didChangeCursor(const WebCursorInfo& cursor_info) {
|
||||||
|
current_cursor_.InitFromCursorInfo(cursor_info);
|
||||||
|
GdkCursorType cursor_type =
|
||||||
|
static_cast<GdkCursorType>(current_cursor_.GetCursorType());
|
||||||
|
GdkCursor* gdk_cursor;
|
||||||
|
if (cursor_type == GDK_CURSOR_IS_PIXMAP) {
|
||||||
|
// TODO(port): WebKit bug https://bugs.webkit.org/show_bug.cgi?id=16388 is
|
||||||
|
// that calling gdk_window_set_cursor repeatedly is expensive. We should
|
||||||
|
// avoid it here where possible.
|
||||||
|
gdk_cursor = current_cursor_.GetCustomCursor();
|
||||||
|
} else {
|
||||||
|
// Optimize the common case, where the cursor hasn't changed.
|
||||||
|
// However, we can switch between different pixmaps, so only on the
|
||||||
|
// non-pixmap branch.
|
||||||
|
if (cursor_type_ == cursor_type)
|
||||||
|
return;
|
||||||
|
if (cursor_type == GDK_LAST_CURSOR)
|
||||||
|
gdk_cursor = NULL;
|
||||||
|
else
|
||||||
|
gdk_cursor = gfx::GetCursor(cursor_type);
|
||||||
|
}
|
||||||
|
cursor_type_ = cursor_type;
|
||||||
|
gdk_window_set_cursor(browser_->GetWebViewWndHandle()->window, gdk_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRect BrowserWebViewDelegate::windowRect() {
|
||||||
|
WebWidgetHost* host = GetWidgetHost();
|
||||||
|
GtkWidget* drawing_area = host->view_handle();
|
||||||
|
GtkWidget* vbox = gtk_widget_get_parent(drawing_area);
|
||||||
|
GtkWidget* window = gtk_widget_get_parent(vbox);
|
||||||
|
|
||||||
|
gint x, y;
|
||||||
|
gtk_window_get_position(GTK_WINDOW(window), &x, &y);
|
||||||
|
x += vbox->allocation.x + drawing_area->allocation.x;
|
||||||
|
y += vbox->allocation.y + drawing_area->allocation.y;
|
||||||
|
|
||||||
|
return WebRect(x, y,
|
||||||
|
drawing_area->allocation.width,
|
||||||
|
drawing_area->allocation.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::setWindowRect(const WebRect& rect) {
|
||||||
|
if (this == browser_->GetWebViewDelegate()) {
|
||||||
|
// TODO(port): Set the window rectangle.
|
||||||
|
} else if (this == browser_->GetPopupDelegate()) {
|
||||||
|
WebWidgetHost* host = GetWidgetHost();
|
||||||
|
GtkWidget* drawing_area = host->view_handle();
|
||||||
|
GtkWidget* window =
|
||||||
|
gtk_widget_get_parent(gtk_widget_get_parent(drawing_area));
|
||||||
|
gtk_window_resize(GTK_WINDOW(window), rect.width, rect.height);
|
||||||
|
gtk_window_move(GTK_WINDOW(window), rect.x, rect.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRect BrowserWebViewDelegate::rootWindowRect() {
|
||||||
|
if (WebWidgetHost* host = GetWidgetHost()) {
|
||||||
|
// We are being asked for the x/y and width/height of the entire browser
|
||||||
|
// window. This means the x/y is the distance from the corner of the
|
||||||
|
// screen, and the width/height is the size of the entire browser window.
|
||||||
|
// For example, this is used to implement window.screenX and window.screenY.
|
||||||
|
GtkWidget* drawing_area = host->view_handle();
|
||||||
|
GtkWidget* window =
|
||||||
|
gtk_widget_get_parent(gtk_widget_get_parent(drawing_area));
|
||||||
|
gint x, y, width, height;
|
||||||
|
gtk_window_get_position(GTK_WINDOW(window), &x, &y);
|
||||||
|
gtk_window_get_size(GTK_WINDOW(window), &width, &height);
|
||||||
|
return WebRect(x, y, width, height);
|
||||||
|
}
|
||||||
|
return WebRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRect BrowserWebViewDelegate::windowResizerRect() {
|
||||||
|
// Not necessary on Linux.
|
||||||
|
return WebRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::runModal() {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebPluginPageDelegate ------------------------------------------------------
|
||||||
|
|
||||||
|
webkit::npapi::WebPluginDelegate* BrowserWebViewDelegate::CreatePluginDelegate(
|
||||||
|
const FilePath& path,
|
||||||
|
const std::string& mime_type) {
|
||||||
|
// TODO(evanm): we probably shouldn't be doing this mapping to X ids at
|
||||||
|
// this level.
|
||||||
|
GdkNativeWindow plugin_parent =
|
||||||
|
GDK_WINDOW_XWINDOW(browser_->GetWebViewHost()->view_handle()->window);
|
||||||
|
|
||||||
|
return webkit::npapi::WebPluginDelegateImpl::Create(path, mime_type,
|
||||||
|
plugin_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::CreatedPluginWindow(
|
||||||
|
gfx::PluginWindowHandle id) {
|
||||||
|
browser_->GetWebViewHost()->CreatePluginContainer(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::WillDestroyPluginWindow(
|
||||||
|
gfx::PluginWindowHandle id) {
|
||||||
|
browser_->GetWebViewHost()->DestroyPluginContainer(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::DidMovePlugin(
|
||||||
|
const webkit::npapi::WebPluginGeometry& move) {
|
||||||
|
WebWidgetHost* host = GetWidgetHost();
|
||||||
|
webkit::npapi::GtkPluginContainerManager* plugin_container_manager =
|
||||||
|
static_cast<WebViewHost*>(host)->plugin_container_manager();
|
||||||
|
plugin_container_manager->MovePluginContainer(move);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protected methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
void BrowserWebViewDelegate::ShowJavaScriptAlert(
|
||||||
|
WebKit::WebFrame* webframe, const CefString& message) {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BrowserWebViewDelegate::ShowJavaScriptConfirm(
|
||||||
|
WebKit::WebFrame* webframe, const CefString& message) {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BrowserWebViewDelegate::ShowJavaScriptPrompt(
|
||||||
|
WebKit::WebFrame* webframe, const CefString& message,
|
||||||
|
const CefString& default_value, CefString* result) {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called to show the file chooser dialog.
|
||||||
|
bool BrowserWebViewDelegate::ShowFileChooser(std::vector<FilePath>& file_names,
|
||||||
|
const bool multi_select,
|
||||||
|
const WebKit::WebString& title,
|
||||||
|
const FilePath& default_file) {
|
||||||
|
NOTIMPLEMENTED();
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright (c) 2011 The Chromium Embedded Framework 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 "cef_process_ui_thread.h"
|
||||||
|
#include "browser_impl.h"
|
||||||
|
|
||||||
|
void CefProcessUIThread::PlatformInit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefProcessUIThread::PlatformCleanUp() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright (c) 2006-2008 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 <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "webview_host.h"
|
||||||
|
#include "browser_webview_delegate.h"
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "gfx/rect.h"
|
||||||
|
#include "gfx/size.h"
|
||||||
|
#include "skia/ext/platform_canvas.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
|
||||||
|
#include "webkit/glue/webpreferences.h"
|
||||||
|
#include "webkit/plugins/npapi/gtk_plugin_container.h"
|
||||||
|
|
||||||
|
using WebKit::WebDevToolsAgentClient;
|
||||||
|
using WebKit::WebView;
|
||||||
|
|
||||||
|
// static
|
||||||
|
WebViewHost* WebViewHost::Create(GtkWidget* parent_view,
|
||||||
|
const gfx::Rect& rect,
|
||||||
|
BrowserWebViewDelegate* delegate,
|
||||||
|
WebDevToolsAgentClient* dev_tools_client,
|
||||||
|
const WebPreferences& prefs) {
|
||||||
|
WebViewHost* host = new WebViewHost();
|
||||||
|
|
||||||
|
host->view_ = WebWidgetHost::CreateWidget(parent_view, host);
|
||||||
|
host->plugin_container_manager_.set_host_widget(host->view_);
|
||||||
|
|
||||||
|
host->webwidget_ = WebView::create(delegate, dev_tools_client);
|
||||||
|
prefs.Apply(host->webview());
|
||||||
|
host->webview()->initializeMainFrame(delegate);
|
||||||
|
host->webwidget_->layout();
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebView* WebViewHost::webview() const {
|
||||||
|
return static_cast<WebView*>(webwidget_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebViewHost::CreatePluginContainer(gfx::PluginWindowHandle id) {
|
||||||
|
plugin_container_manager_.CreatePluginContainer(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebViewHost::DestroyPluginContainer(gfx::PluginWindowHandle id) {
|
||||||
|
plugin_container_manager_.DestroyPluginContainer(id);
|
||||||
|
}
|
|
@ -0,0 +1,437 @@
|
||||||
|
// Copyright (c) 2006-2008 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 "webwidget_host.h"
|
||||||
|
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "base/basictypes.h"
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "skia/ext/bitmap_platform_device.h"
|
||||||
|
#include "skia/ext/platform_canvas.h"
|
||||||
|
#include "skia/ext/platform_device.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/x11/WebScreenInfoFactory.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebPopupMenu.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebScreenInfo.h"
|
||||||
|
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
|
||||||
|
|
||||||
|
using WebKit::WebInputEventFactory;
|
||||||
|
using WebKit::WebKeyboardEvent;
|
||||||
|
using WebKit::WebMouseEvent;
|
||||||
|
using WebKit::WebMouseWheelEvent;
|
||||||
|
using WebKit::WebPopupMenu;
|
||||||
|
using WebKit::WebScreenInfo;
|
||||||
|
using WebKit::WebScreenInfoFactory;
|
||||||
|
using WebKit::WebSize;
|
||||||
|
using WebKit::WebWidgetClient;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Used to store a backpointer to WebWidgetHost from our GtkWidget.
|
||||||
|
const char kWebWidgetHostKey[] = "webwidgethost";
|
||||||
|
|
||||||
|
// In response to an invalidation, we call into WebKit to do layout. On
|
||||||
|
// Windows, WM_PAINT is a virtual message so any extra invalidates that come up
|
||||||
|
// while it's doing layout are implicitly swallowed as soon as we actually do
|
||||||
|
// drawing via BeginPaint.
|
||||||
|
//
|
||||||
|
// Though GTK does know how to collapse multiple paint requests, it won't erase
|
||||||
|
// paint requests from the future when we start drawing. To avoid an infinite
|
||||||
|
// cycle of repaints, we track whether we're currently handling a redraw, and
|
||||||
|
// during that if we get told by WebKit that a region has become invalid, we
|
||||||
|
// still add that region to the local dirty rect but *don't* enqueue yet
|
||||||
|
// another "do a paint" message.
|
||||||
|
bool g_handling_expose = false;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Callback functions to proxy to host...
|
||||||
|
|
||||||
|
// The web contents are completely drawn and handled by WebKit, except that
|
||||||
|
// windowed plugins are GtkSockets on top of it. We need to place the
|
||||||
|
// GtkSockets inside a GtkContainer. We use a GtkFixed container, and the
|
||||||
|
// GtkSocket objects override a little bit to manage their size (see the code
|
||||||
|
// in webplugin_delegate_impl_gtk.cc). We listen on a the events we're
|
||||||
|
// interested in and forward them on to the WebWidgetHost. This class is a
|
||||||
|
// collection of static methods, implementing the widget related code.
|
||||||
|
class WebWidgetHostGtkWidget {
|
||||||
|
public:
|
||||||
|
// This will create a new widget used for hosting the web contents. We use
|
||||||
|
// our GtkDrawingAreaContainer here, for the reasons mentioned above.
|
||||||
|
static GtkWidget* CreateNewWidget(GtkWidget* parent_view,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
GtkWidget* widget = gtk_fixed_new();
|
||||||
|
gtk_fixed_set_has_window(GTK_FIXED(widget), true);
|
||||||
|
|
||||||
|
gtk_box_pack_start(GTK_BOX(parent_view), widget, TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
gtk_widget_add_events(widget, GDK_EXPOSURE_MASK |
|
||||||
|
GDK_POINTER_MOTION_MASK |
|
||||||
|
GDK_BUTTON_PRESS_MASK |
|
||||||
|
GDK_BUTTON_RELEASE_MASK |
|
||||||
|
GDK_KEY_PRESS_MASK |
|
||||||
|
GDK_KEY_RELEASE_MASK);
|
||||||
|
GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS);
|
||||||
|
g_signal_connect(widget, "size-request",
|
||||||
|
G_CALLBACK(&HandleSizeRequest), host);
|
||||||
|
g_signal_connect(widget, "size-allocate",
|
||||||
|
G_CALLBACK(&HandleSizeAllocate), host);
|
||||||
|
g_signal_connect(widget, "configure-event",
|
||||||
|
G_CALLBACK(&HandleConfigure), host);
|
||||||
|
g_signal_connect(widget, "expose-event",
|
||||||
|
G_CALLBACK(&HandleExpose), host);
|
||||||
|
g_signal_connect(widget, "destroy",
|
||||||
|
G_CALLBACK(&HandleDestroy), host);
|
||||||
|
g_signal_connect(widget, "key-press-event",
|
||||||
|
G_CALLBACK(&HandleKeyPress), host);
|
||||||
|
g_signal_connect(widget, "key-release-event",
|
||||||
|
G_CALLBACK(&HandleKeyRelease), host);
|
||||||
|
g_signal_connect(widget, "focus",
|
||||||
|
G_CALLBACK(&HandleFocus), host);
|
||||||
|
g_signal_connect(widget, "focus-in-event",
|
||||||
|
G_CALLBACK(&HandleFocusIn), host);
|
||||||
|
g_signal_connect(widget, "focus-out-event",
|
||||||
|
G_CALLBACK(&HandleFocusOut), host);
|
||||||
|
g_signal_connect(widget, "button-press-event",
|
||||||
|
G_CALLBACK(&HandleButtonPress), host);
|
||||||
|
g_signal_connect(widget, "button-release-event",
|
||||||
|
G_CALLBACK(&HandleButtonRelease), host);
|
||||||
|
g_signal_connect(widget, "motion-notify-event",
|
||||||
|
G_CALLBACK(&HandleMotionNotify), host);
|
||||||
|
g_signal_connect(widget, "scroll-event",
|
||||||
|
G_CALLBACK(&HandleScroll), host);
|
||||||
|
|
||||||
|
g_object_set_data(G_OBJECT(widget), kWebWidgetHostKey, host);
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Our size was requested. We let the GtkFixed do its normal calculation,
|
||||||
|
// after which this callback is called. The GtkFixed will come up with a
|
||||||
|
// requisition based on its children, which include plugin windows. Since
|
||||||
|
// we don't want to prevent resizing smaller than a plugin window, we need to
|
||||||
|
// control the size ourself.
|
||||||
|
static void HandleSizeRequest(GtkWidget* widget,
|
||||||
|
GtkRequisition* req,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
// This is arbitrary, but the WebKit scrollbars try to shrink themselves
|
||||||
|
// if the browser window is too small. Give them some space.
|
||||||
|
static const int kMinWidthHeight = 64;
|
||||||
|
|
||||||
|
req->width = kMinWidthHeight;
|
||||||
|
req->height = kMinWidthHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our size has changed.
|
||||||
|
static void HandleSizeAllocate(GtkWidget* widget,
|
||||||
|
GtkAllocation* allocation,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
host->Resize(WebSize(allocation->width, allocation->height));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size, position, or stacking of the GdkWindow changed.
|
||||||
|
static gboolean HandleConfigure(GtkWidget* widget,
|
||||||
|
GdkEventConfigure* config,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
host->Resize(WebSize(config->width, config->height));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A portion of the GdkWindow needs to be redraw.
|
||||||
|
static gboolean HandleExpose(GtkWidget* widget,
|
||||||
|
GdkEventExpose* expose,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
// See comments above about what g_handling_expose is for.
|
||||||
|
g_handling_expose = true;
|
||||||
|
gfx::Rect rect(expose->area);
|
||||||
|
host->UpdatePaintRect(rect);
|
||||||
|
host->Paint();
|
||||||
|
g_handling_expose = false;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The GdkWindow was destroyed.
|
||||||
|
static gboolean HandleDestroy(GtkWidget* widget, void* unused) {
|
||||||
|
// The associated WebWidgetHost instance may have already been destroyed.
|
||||||
|
WebWidgetHost* host = static_cast<WebWidgetHost*>(
|
||||||
|
g_object_get_data(G_OBJECT(widget), kWebWidgetHostKey));
|
||||||
|
if (host)
|
||||||
|
host->WindowDestroyed();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard key pressed.
|
||||||
|
static gboolean HandleKeyPress(GtkWidget* widget,
|
||||||
|
GdkEventKey* event,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
host->webwidget()->handleInputEvent(
|
||||||
|
WebInputEventFactory::keyboardEvent(event));
|
||||||
|
|
||||||
|
// In the browser we do a ton of work with IMEs. This is some minimal
|
||||||
|
// code to make basic text work in test_shell, but doesn't cover IME.
|
||||||
|
// This is a copy of the logic in ProcessUnfilteredKeyPressEvent in
|
||||||
|
// render_widget_host_view_gtk.cc .
|
||||||
|
if (event->type == GDK_KEY_PRESS) {
|
||||||
|
WebKeyboardEvent wke = WebInputEventFactory::keyboardEvent(event);
|
||||||
|
if (wke.text[0]) {
|
||||||
|
wke.type = WebKit::WebInputEvent::Char;
|
||||||
|
host->webwidget()->handleInputEvent(wke);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard key released.
|
||||||
|
static gboolean HandleKeyRelease(GtkWidget* widget,
|
||||||
|
GdkEventKey* event,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
return HandleKeyPress(widget, event, host);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This signal is called when arrow keys or tab is pressed. If we return
|
||||||
|
// true, we prevent focus from being moved to another widget. If we want to
|
||||||
|
// allow focus to be moved outside of web contents, we need to implement
|
||||||
|
// WebViewDelegate::TakeFocus in the test webview delegate.
|
||||||
|
static gboolean HandleFocus(GtkWidget* widget,
|
||||||
|
GdkEventFocus* focus,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard focus entered.
|
||||||
|
static gboolean HandleFocusIn(GtkWidget* widget,
|
||||||
|
GdkEventFocus* focus,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
host->webwidget()->setFocus(true);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard focus left.
|
||||||
|
static gboolean HandleFocusOut(GtkWidget* widget,
|
||||||
|
GdkEventFocus* focus,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
host->webwidget()->setFocus(false);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mouse button down.
|
||||||
|
static gboolean HandleButtonPress(GtkWidget* widget,
|
||||||
|
GdkEventButton* event,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
if (!(event->button == 1 || event->button == 2 || event->button == 3))
|
||||||
|
return FALSE; // We do not forward any other buttons to the renderer.
|
||||||
|
if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
|
||||||
|
return FALSE;
|
||||||
|
host->webwidget()->handleInputEvent(
|
||||||
|
WebInputEventFactory::mouseEvent(event));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mouse button up.
|
||||||
|
static gboolean HandleButtonRelease(GtkWidget* widget,
|
||||||
|
GdkEventButton* event,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
return HandleButtonPress(widget, event, host);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mouse pointer movements.
|
||||||
|
static gboolean HandleMotionNotify(GtkWidget* widget,
|
||||||
|
GdkEventMotion* event,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
host->webwidget()->handleInputEvent(
|
||||||
|
WebInputEventFactory::mouseEvent(event));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mouse scroll wheel.
|
||||||
|
static gboolean HandleScroll(GtkWidget* widget,
|
||||||
|
GdkEventScroll* event,
|
||||||
|
WebWidgetHost* host) {
|
||||||
|
host->webwidget()->handleInputEvent(
|
||||||
|
WebInputEventFactory::mouseWheelEvent(event));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DISALLOW_IMPLICIT_CONSTRUCTORS(WebWidgetHostGtkWidget);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return an Xlib Display pointer for the given widget.
|
||||||
|
Display* GtkWidgetGetDisplay(GtkWidget* widget) {
|
||||||
|
GdkDisplay* gdk_display = gtk_widget_get_display(widget);
|
||||||
|
return gdk_x11_display_get_xdisplay(gdk_display);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the screen number for the given widget.
|
||||||
|
int GtkWidgetGetScreenNum(GtkWidget* widget) {
|
||||||
|
GdkDisplay* gdk_display = gtk_widget_get_display(widget);
|
||||||
|
GdkScreen* gdk_screen = gdk_display_get_default_screen(gdk_display);
|
||||||
|
return gdk_x11_screen_get_screen_number(gdk_screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// This is provided so that the webview can reuse the custom GTK window code.
|
||||||
|
// static
|
||||||
|
gfx::NativeView WebWidgetHost::CreateWidget(
|
||||||
|
gfx::NativeView parent_view, WebWidgetHost* host) {
|
||||||
|
return WebWidgetHostGtkWidget::CreateNewWidget(parent_view, host);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
WebWidgetHost* WebWidgetHost::Create(GtkWidget* parent_view,
|
||||||
|
WebWidgetClient* client) {
|
||||||
|
WebWidgetHost* host = new WebWidgetHost();
|
||||||
|
host->view_ = CreateWidget(parent_view, host);
|
||||||
|
host->webwidget_ = WebPopupMenu::create(client);
|
||||||
|
// We manage our own double buffering because we need to be able to update
|
||||||
|
// the expose area in an ExposeEvent within the lifetime of the event handler.
|
||||||
|
gtk_widget_set_double_buffered(GTK_WIDGET(host->view_), false);
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
|
||||||
|
paint_rect_ = paint_rect_.Union(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
|
||||||
|
DLOG_IF(WARNING, painting_) << "unexpected invalidation while painting";
|
||||||
|
|
||||||
|
UpdatePaintRect(damaged_rect);
|
||||||
|
|
||||||
|
if (!g_handling_expose) {
|
||||||
|
gtk_widget_queue_draw_area(GTK_WIDGET(view_), damaged_rect.x(),
|
||||||
|
damaged_rect.y(), damaged_rect.width(), damaged_rect.height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
|
||||||
|
// This is used for optimizing painting when the renderer is scrolled. We're
|
||||||
|
// currently not doing any optimizations so just invalidate the region.
|
||||||
|
DidInvalidateRect(clip_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::ScheduleComposite() {
|
||||||
|
int width = logical_size_.width();
|
||||||
|
int height = logical_size_.height();
|
||||||
|
GdkRectangle grect = {
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
};
|
||||||
|
GdkWindow* window = view_->window;
|
||||||
|
gdk_window_invalidate_rect(window, &grect, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebWidgetHost::WebWidgetHost()
|
||||||
|
: view_(NULL),
|
||||||
|
webwidget_(NULL),
|
||||||
|
scroll_dx_(0),
|
||||||
|
scroll_dy_(0) {
|
||||||
|
set_painting(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebWidgetHost::~WebWidgetHost() {
|
||||||
|
// We may be deleted before the view_. Clear out the signals so that we don't
|
||||||
|
// attempt to invoke something on a deleted object.
|
||||||
|
g_object_set_data(G_OBJECT(view_), kWebWidgetHostKey, NULL);
|
||||||
|
g_signal_handlers_disconnect_matched(view_,
|
||||||
|
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, this);
|
||||||
|
webwidget_->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::Resize(const gfx::Size &newsize) {
|
||||||
|
// The pixel buffer backing us is now the wrong size
|
||||||
|
canvas_.reset();
|
||||||
|
logical_size_ = newsize;
|
||||||
|
webwidget_->resize(newsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::Paint() {
|
||||||
|
int width = logical_size_.width();
|
||||||
|
int height = logical_size_.height();
|
||||||
|
gfx::Rect client_rect(width, height);
|
||||||
|
|
||||||
|
// Allocate a canvas if necessary
|
||||||
|
if (!canvas_.get()) {
|
||||||
|
ResetScrollRect();
|
||||||
|
paint_rect_ = client_rect;
|
||||||
|
canvas_.reset(new skia::PlatformCanvas(width, height, true));
|
||||||
|
if (!canvas_.get()) {
|
||||||
|
// memory allocation failed, we can't paint.
|
||||||
|
LOG(ERROR) << "Failed to allocate memory for " << width << "x" << height;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This may result in more invalidation
|
||||||
|
webwidget_->layout();
|
||||||
|
|
||||||
|
// Paint the canvas if necessary. Allow painting to generate extra rects the
|
||||||
|
// first time we call it. This is necessary because some WebCore rendering
|
||||||
|
// objects update their layout only when painted.
|
||||||
|
// Store the total area painted in total_paint. Then tell the gdk window
|
||||||
|
// to update that area after we're done painting it.
|
||||||
|
gfx::Rect total_paint;
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
paint_rect_ = client_rect.Intersect(paint_rect_);
|
||||||
|
if (!paint_rect_.IsEmpty()) {
|
||||||
|
gfx::Rect rect(paint_rect_);
|
||||||
|
paint_rect_ = gfx::Rect();
|
||||||
|
|
||||||
|
DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations";
|
||||||
|
PaintRect(rect);
|
||||||
|
total_paint = total_paint.Union(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//DCHECK(paint_rect_.IsEmpty());
|
||||||
|
|
||||||
|
// Invalidate the paint region on the widget's underlying gdk window. Note
|
||||||
|
// that gdk_window_invalidate_* will generate extra expose events, which
|
||||||
|
// we wish to avoid. So instead we use calls to begin_paint/end_paint.
|
||||||
|
GdkRectangle grect = {
|
||||||
|
total_paint.x(),
|
||||||
|
total_paint.y(),
|
||||||
|
total_paint.width(),
|
||||||
|
total_paint.height(),
|
||||||
|
};
|
||||||
|
GdkWindow* window = view_->window;
|
||||||
|
gdk_window_begin_paint_rect(window, &grect);
|
||||||
|
|
||||||
|
// BitBlit to the gdk window.
|
||||||
|
cairo_t* source_surface = canvas_->beginPlatformPaint();
|
||||||
|
cairo_t* cairo_drawable = gdk_cairo_create(window);
|
||||||
|
cairo_set_source_surface(cairo_drawable, cairo_get_target(source_surface),
|
||||||
|
0, 0);
|
||||||
|
cairo_paint(cairo_drawable);
|
||||||
|
cairo_destroy(cairo_drawable);
|
||||||
|
|
||||||
|
gdk_window_end_paint(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebScreenInfo WebWidgetHost::GetScreenInfo() {
|
||||||
|
Display* display = GtkWidgetGetDisplay(view_);
|
||||||
|
int screen_num = GtkWidgetGetScreenNum(view_);
|
||||||
|
return WebScreenInfoFactory::screenInfo(display, screen_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::ResetScrollRect() {
|
||||||
|
// This method is only needed for optimized scroll painting, which we don't
|
||||||
|
// care about in the test shell, yet.
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::PaintRect(const gfx::Rect& rect) {
|
||||||
|
set_painting(true);
|
||||||
|
webwidget_->paint(canvas_.get(), rect);
|
||||||
|
set_painting(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebWidgetHost::WindowDestroyed() {
|
||||||
|
delete this;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 20010 The Chromium Embedded Framework Authors. All rights
|
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 20010 The Chromium Embedded Framework Authors. All rights
|
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 20010 The Chromium Embedded Framework Authors. All rights
|
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 20010 The Chromium Embedded Framework Authors. All rights
|
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
|
||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue