// 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 #include #include "base/message_loop.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" #include "ui/gfx/gtk_util.h" #include "ui/gfx/point.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(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(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::didChangeCursor(const WebCursorInfo& cursor_info) { current_cursor_.InitFromCursorInfo(cursor_info); GdkCursorType cursor_type = static_cast(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_->UIT_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_->UIT_GetWebViewDelegate()) { // TODO(port): Set the window rectangle. } else if (this == browser_->UIT_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::startDragging( const WebDragData& data, WebDragOperationsMask mask, const WebImage& image, const WebPoint& image_offset) { // TODO(port): Support drag and drop. browser_->UIT_GetWebView()->dragSourceSystemDragEnded(); } 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_->UIT_GetWebViewHost()->view_handle()->window); return webkit::npapi::WebPluginDelegateImpl::Create(path, mime_type, plugin_parent); } void BrowserWebViewDelegate::CreatedPluginWindow( gfx::PluginWindowHandle id) { browser_->UIT_GetWebViewHost()->CreatePluginContainer(id); } void BrowserWebViewDelegate::WillDestroyPluginWindow( gfx::PluginWindowHandle id) { browser_->UIT_GetWebViewHost()->DestroyPluginContainer(id); } void BrowserWebViewDelegate::DidMovePlugin( const webkit::npapi::WebPluginGeometry& move) { WebWidgetHost* host = GetWidgetHost(); webkit::npapi::GtkPluginContainerManager* plugin_container_manager = static_cast(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& file_names, const bool multi_select, const WebKit::WebString& title, const FilePath& default_file) { NOTIMPLEMENTED(); return false; }