Linux: Remove GTK+ dependency and add initial Aura/X11 implementation (issue #1258)

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1708 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2014-05-22 21:01:22 +00:00
parent 921c25f0af
commit 3859457eef
46 changed files with 1196 additions and 1178 deletions

92
cef.gyp
View File

@ -98,11 +98,6 @@
'<@(cefclient_sources_win)',
],
}],
[ 'toolkit_uses_gtk == 1', {
'dependencies': [
'<(DEPTH)/sandbox/sandbox.gyp:sandbox',
],
}],
[ 'OS=="mac"', {
'product_name': 'cefclient',
'dependencies': [
@ -188,9 +183,13 @@
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies': [
'gtk',
'gtkglext',
'libcef',
],
'link_settings': {
'libraries': [
'-lX11',
],
},
'sources': [
'<@(includes_linux)',
'<@(cefclient_sources_linux)',
@ -281,11 +280,6 @@
'<@(cefsimple_sources_win)',
],
}],
[ 'toolkit_uses_gtk == 1', {
'dependencies': [
'<(DEPTH)/sandbox/sandbox.gyp:sandbox',
],
}],
[ 'OS=="mac"', {
'product_name': 'cefsimple',
'dependencies': [
@ -369,9 +363,13 @@
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies': [
'gtk',
'libcef',
],
'link_settings': {
'libraries': [
'-lX11',
],
},
'sources': [
'<@(includes_linux)',
'<@(cefsimple_sources_linux)',
@ -477,11 +475,6 @@
},
},
}],
[ 'toolkit_uses_gtk == 1', {
'dependencies': [
'<(DEPTH)/sandbox/sandbox.gyp:sandbox',
],
}],
[ 'OS=="mac"', {
'product_name': 'cef_unittests',
'dependencies': [
@ -565,8 +558,6 @@
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies': [
'<(DEPTH)/build/linux/system.gyp:gtk',
'<(DEPTH)/build/linux/system.gyp:gtkprint',
'libcef',
],
}],
@ -598,12 +589,6 @@
'libcef',
],
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies': [
'<(DEPTH)/build/linux/system.gyp:gtk',
'<(DEPTH)/build/linux/system.gyp:gtkprint',
],
}],
],
},
{
@ -1101,29 +1086,14 @@
],
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies':[
'<(DEPTH)/build/linux/system.gyp:gtkprint',
],
'sources': [
'<@(includes_linux)',
'libcef/browser/browser_host_impl_gtk.cc',
'libcef/browser/browser_main_gtk.cc',
'libcef/browser/gtk_util_stub.cc',
'libcef/browser/javascript_dialog_gtk.cc',
'libcef/browser/menu_creator_runner_gtk.cc',
'libcef/browser/menu_creator_runner_gtk.h',
# Include sources for context menu implementation.
'<(DEPTH)/chrome/browser/ui/gtk/gtk_custom_menu.cc',
'<(DEPTH)/chrome/browser/ui/gtk/gtk_custom_menu.h',
'<(DEPTH)/chrome/browser/ui/gtk/gtk_custom_menu_item.cc',
'<(DEPTH)/chrome/browser/ui/gtk/gtk_custom_menu_item.h',
'<(DEPTH)/chrome/browser/ui/gtk/menu_gtk.cc',
'<(DEPTH)/chrome/browser/ui/gtk/menu_gtk.h',
'<(DEPTH)/chrome/browser/ui/views/event_utils.cc',
'<(DEPTH)/chrome/browser/ui/views/event_utils.h',
'libcef/browser/browser_host_impl_linux.cc',
'libcef/browser/browser_main_linux.cc',
'libcef/browser/javascript_dialog_linux.cc',
'libcef/browser/menu_creator_runner_linux.cc',
'libcef/browser/menu_creator_runner_linux.h',
#Include sources for printing.
'<(DEPTH)/chrome/browser/printing/print_dialog_gtk.cc',
'<(DEPTH)/chrome/browser/printing/print_dialog_gtk.h',
'<(DEPTH)/chrome/renderer/printing/print_web_view_helper_linux.cc',
],
}],
@ -1136,7 +1106,14 @@
'dependencies': [
'<(DEPTH)/ui/views/controls/webview/webview.gyp:webview',
'<(DEPTH)/ui/views/views.gyp:views',
'<(DEPTH)/ui/views/views.gyp:views_test_support',
],
'sources': [
'libcef/browser/window_delegate_view.cc',
'libcef/browser/window_delegate_view.h',
'<(DEPTH)/ui/views/test/desktop_test_views_delegate.cc',
'<(DEPTH)/ui/views/test/desktop_test_views_delegate.h',
'<(DEPTH)/ui/views/test/test_views_delegate.cc',
'<(DEPTH)/ui/views/test/test_views_delegate.h',
],
}],
],
@ -1617,8 +1594,6 @@
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies':[
'<(DEPTH)/base/allocator/allocator.gyp:allocator',
'<(DEPTH)/build/linux/system.gyp:gtk',
'<(DEPTH)/build/linux/system.gyp:gtkprint',
],
}],
],
@ -1648,27 +1623,6 @@
],
},
},
{
'target_name': 'gtkglext',
'type': 'none',
'variables': {
# gtkglext is required by the cefclient OSR example.
'gtk_packages': 'gtkglext-1.0',
},
'direct_dependent_settings': {
'cflags': [
'<!@(pkg-config --cflags <(gtk_packages))',
],
},
'link_settings': {
'ldflags': [
'<!@(pkg-config --libs-only-L --libs-only-other <(gtk_packages))',
],
'libraries': [
'<!@(pkg-config --libs-only-l <(gtk_packages))',
],
},
},
],
}], # OS=="linux" or OS=="freebsd" or OS=="openbsd"
[ 'OS=="win"', {

View File

@ -16,9 +16,6 @@
'disable_debugallocation': 1,
}, { # OS!="win"
'cef_directory' : '<!(echo $CEF_DIRECTORY)',
# Aura is not yet supported on non-Windows platforms.
'use_ash': 0,
'use_aura': 0,
}],
[ 'OS=="mac"', {
# Strip symbols and create dSYM files for the Release target.

View File

@ -229,8 +229,8 @@
'tests/cefsimple/mac/Info.plist',
],
'cefsimple_sources_linux': [
'tests/cefsimple/cefsimple_gtk.cpp',
'tests/cefsimple/simple_handler_gtk.cpp',
'tests/cefsimple/cefsimple_linux.cpp',
'tests/cefsimple/simple_handler_linux.cpp',
],
},
}

View File

@ -31,6 +31,8 @@
#ifndef CEF_INCLUDE_CAPI_CEF_BASE_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_BASE_CAPI_H_
#include <stdint.h>
#include "include/internal/cef_export.h"
#include "include/internal/cef_string.h"
#include "include/internal/cef_string_list.h"

View File

@ -108,8 +108,12 @@ struct CefWindowInfoTraits {
static inline void set(const struct_type* src, struct_type* target,
bool copy) {
target->parent_widget = src->parent_widget;
target->widget = src->widget;
target->x = src->x;
target->y = src->y;
target->width = src->width;
target->height = src->height;
target->parent_window = src->parent_window;
target->window = src->window;
}
};
@ -123,10 +127,15 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {}
///
// Create the browser as a child widget.
// Create the browser as a child window.
///
void SetAsChild(CefWindowHandle parent) {
parent_widget = parent;
void SetAsChild(CefWindowHandle parent,
const CefRect& windowRect) {
parent_window = parent;
x = windowRect.x;
y = windowRect.y;
width = windowRect.width;
height = windowRect.height;
}
};

View File

@ -35,17 +35,31 @@
#include "include/internal/cef_build.h"
#if defined(OS_LINUX)
#include <gtk/gtk.h>
typedef union _XEvent XEvent;
typedef struct _XDisplay XDisplay;
#include "include/internal/cef_export.h"
#include "include/internal/cef_string.h"
// Handle types.
#define cef_cursor_handle_t unsigned long
#define cef_event_handle_t XEvent*
#define cef_window_handle_t unsigned long
#define kNullCursorHandle 0
#define kNullEventHandle NULL
#define kNullWindowHandle 0
#ifdef __cplusplus
extern "C" {
#endif
// Handle types.
#define cef_cursor_handle_t GdkCursor*
#define cef_event_handle_t GdkEvent*
#define cef_window_handle_t GtkWidget*
///
// Return the singleton X11 display shared with Chromium. The display is not
// thread-safe and must only be accessed on the browser process UI thread.
///
CEF_EXPORT XDisplay* cef_get_xdisplay();
///
// Structure representing CefExecuteProcess arguments.
@ -59,15 +73,20 @@ typedef struct _cef_main_args_t {
// Class representing window information.
///
typedef struct _cef_window_info_t {
///
// Pointer for the parent widget.
///
cef_window_handle_t parent_widget;
unsigned int x;
unsigned int y;
unsigned int width;
unsigned int height;
///
// Pointer for the new browser widget. Only used with windowed rendering.
// Pointer for the parent window.
///
cef_window_handle_t widget;
cef_window_handle_t parent_window;
///
// Pointer for the new browser window. Only used with windowed rendering.
///
cef_window_handle_t window;
} cef_window_info_t;
#ifdef __cplusplus

View File

@ -57,6 +57,10 @@ struct NSView;
#define cef_window_handle_t void*
#endif
#define kNullCursorHandle NULL
#define kNullEventHandle NULL
#define kNullWindowHandle NULL
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -38,15 +38,19 @@
#include <windows.h>
#include "include/internal/cef_string.h"
#ifdef __cplusplus
extern "C" {
#endif
// Handle types.
#define cef_cursor_handle_t HCURSOR
#define cef_event_handle_t MSG*
#define cef_window_handle_t HWND
#define kNullCursorHandle NULL
#define kNullEventHandle NULL
#define kNullWindowHandle NULL
#ifdef __cplusplus
extern "C" {
#endif
///
// Structure representing CefExecuteProcess arguments.
///

View File

@ -319,8 +319,8 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
}
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::Create(windowInfo, client, url, settings, NULL, false,
request_context);
CefBrowserHostImpl::Create(windowInfo, client, url, settings,
kNullWindowHandle, false, request_context);
return browser.get();
}
@ -362,7 +362,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
DCHECK(browser_info.get());
// If |opener| is non-NULL it must be a popup window.
DCHECK(opener == NULL || browser_info->is_popup());
DCHECK(opener == kNullWindowHandle || browser_info->is_popup());
if (!web_contents) {
CefBrowserContext* browser_context = NULL;
@ -1738,7 +1738,7 @@ void CefBrowserHostImpl::WebContentsCreated(
content::RenderViewHost* view_host = new_contents->GetRenderViewHost();
content::RenderFrameHost* main_frame_host = new_contents->GetMainFrame();
CefWindowHandle opener = NULL;
CefWindowHandle opener = kNullWindowHandle;
scoped_refptr<CefBrowserInfo> info =
CefContentBrowserClient::Get()->GetOrCreateBrowserInfo(
view_host->GetProcess()->GetID(),
@ -2161,6 +2161,9 @@ CefBrowserHostImpl::CefBrowserHostImpl(
#if defined(USE_AURA)
window_widget_ = NULL;
#endif
#if defined(USE_X11)
window_x11_ = NULL;
#endif
DCHECK(!browser_info_->browser().get());
browser_info_->set_browser(this);

View File

@ -55,6 +55,10 @@ class Widget;
}
#endif
#if defined(USE_X11)
class CefWindowX11;
#endif
struct Cef_Request_Params;
struct Cef_Response_Params;
class CefBrowserInfo;
@ -589,6 +593,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
// associated root window is destroyed.
views::Widget* window_widget_;
#endif // defined(USE_AURA)
#if defined(USE_X11)
CefWindowX11* window_x11_;
#endif // defined(USE_X11)
IMPLEMENT_REFCOUNTING(CefBrowserHostImpl);
DISALLOW_EVIL_CONSTRUCTORS(CefBrowserHostImpl);

View File

@ -1,557 +0,0 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions 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/browser/browser_host_impl.h"
#include <gtk/gtk.h>
#include <sys/sysinfo.h>
#include "libcef/browser/thread_util.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/common/renderer_preferences.h"
#include "grit/cef_strings.h"
#include "grit/ui_strings.h"
#include "net/base/mime_util.h"
#include "third_party/WebKit/public/web/gtk/WebInputEventFactory.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
void DestroyBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
// Force the browser to be destroyed and release the reference added in
// PlatformCreateWindow().
browser->WindowDestroyed();
}
void browser_destroy(GtkWidget* widget, CefBrowserHostImpl* browser) {
// Destroy the browser host after window destruction is complete.
CEF_POST_TASK(CEF_UIT, base::Bind(DestroyBrowser, browser));
}
void window_destroy(GtkWidget* widget, gpointer data) {
}
gboolean window_delete_event(GtkWidget* widget, GdkEvent* event,
CefBrowserHostImpl* browser) {
// Protect against multiple requests to close while the close is pending.
if (browser && browser->destruction_state() <=
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
if (browser->destruction_state() ==
CefBrowserHostImpl::DESTRUCTION_STATE_NONE) {
// Request that the browser close.
browser->CloseBrowser(false);
}
// Cancel the close.
return TRUE;
}
// Allow the close.
return FALSE;
}
std::string GetDescriptionFromMimeType(const std::string& mime_type) {
// Check for wild card mime types and return an appropriate description.
static const struct {
const char* mime_type;
int string_id;
} kWildCardMimeTypes[] = {
{ "audio", IDS_APP_AUDIO_FILES },
{ "image", IDS_APP_IMAGE_FILES },
{ "text", IDS_APP_TEXT_FILES },
{ "video", IDS_APP_VIDEO_FILES },
};
for (size_t i = 0;
i < sizeof(kWildCardMimeTypes) / sizeof(kWildCardMimeTypes[0]); ++i) {
if (mime_type == std::string(kWildCardMimeTypes[i].mime_type) + "/*")
return l10n_util::GetStringUTF8(kWildCardMimeTypes[i].string_id);
}
return std::string();
}
void AddFiltersForAcceptTypes(GtkFileChooser* chooser,
const std::vector<base::string16>& accept_types,
bool include_all_files) {
bool has_filter = false;
for (size_t i = 0; i < accept_types.size(); ++i) {
std::string ascii_type = base::UTF16ToASCII(accept_types[i]);
if (ascii_type.length()) {
// Just treat as extension if contains '.' as the first character.
if (ascii_type[0] == '.') {
GtkFileFilter* filter = gtk_file_filter_new();
std::string pattern = "*" + ascii_type;
gtk_file_filter_add_pattern(filter, pattern.c_str());
gtk_file_filter_set_name(filter, pattern.c_str());
gtk_file_chooser_add_filter(chooser, filter);
if (!has_filter)
has_filter = true;
} else {
// Otherwise convert mime type to one or more extensions.
GtkFileFilter* filter = NULL;
std::string description = GetDescriptionFromMimeType(ascii_type);
bool description_from_ext = description.empty();
std::vector<base::FilePath::StringType> ext;
net::GetExtensionsForMimeType(ascii_type, &ext);
for (size_t x = 0; x < ext.size(); ++x) {
if (!filter)
filter = gtk_file_filter_new();
std::string pattern = "*." + ext[x];
gtk_file_filter_add_pattern(filter, pattern.c_str());
if (description_from_ext) {
if (x != 0)
description += ";";
description += pattern;
}
}
if (filter) {
gtk_file_filter_set_name(filter, description.c_str());
gtk_file_chooser_add_filter(chooser, filter);
if (!has_filter)
has_filter = true;
}
}
}
}
// Add the *.* filter, but only if we have added other filters (otherwise it
// is implied).
if (include_all_files && has_filter) {
GtkFileFilter* filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*");
gtk_file_filter_set_name(filter,
l10n_util::GetStringUTF8(IDS_SAVEAS_ALL_FILES).c_str());
gtk_file_chooser_add_filter(chooser, filter);
}
}
bool RunFileDialog(const content::FileChooserParams& params,
CefWindowHandle widget,
std::vector<base::FilePath>* files) {
GtkFileChooserAction action;
const gchar* accept_button;
if (params.mode == content::FileChooserParams::Open ||
params.mode == content::FileChooserParams::OpenMultiple) {
action = GTK_FILE_CHOOSER_ACTION_OPEN;
accept_button = GTK_STOCK_OPEN;
} else if (params.mode == content::FileChooserParams::Save) {
action = GTK_FILE_CHOOSER_ACTION_SAVE;
accept_button = GTK_STOCK_SAVE;
} else {
NOTREACHED();
return false;
}
// Consider default file name if any.
base::FilePath default_file_name(params.default_file_name);
std::string base_name;
if (!default_file_name.empty())
base_name = default_file_name.BaseName().value();
std::string title;
if (!params.title.empty()) {
title = base::UTF16ToUTF8(params.title);
} else {
int string_id = 0;
switch (params.mode) {
case content::FileChooserParams::Open:
string_id = IDS_OPEN_FILE_DIALOG_TITLE;
break;
case content::FileChooserParams::OpenMultiple:
string_id = IDS_OPEN_FILES_DIALOG_TITLE;
break;
case content::FileChooserParams::Save:
string_id = IDS_SAVE_AS_DIALOG_TITLE;
break;
default:
break;
}
title = l10n_util::GetStringUTF8(string_id);
}
GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(widget));
GtkWidget* dialog = gtk_file_chooser_dialog_new(
title.c_str(),
GTK_WINDOW(window),
action,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
accept_button, GTK_RESPONSE_ACCEPT,
NULL);
if (params.mode == content::FileChooserParams::OpenMultiple) {
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
} else if (params.mode == content::FileChooserParams::Save) {
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog),
TRUE);
}
if (params.mode == content::FileChooserParams::Save && !base_name.empty()) {
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
base_name.c_str());
}
AddFiltersForAcceptTypes(GTK_FILE_CHOOSER(dialog), params.accept_types, true);
bool success = false;
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
if (params.mode == content::FileChooserParams::Open ||
params.mode == content::FileChooserParams::Save) {
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
files->push_back(base::FilePath(filename));
success = true;
} else if (params.mode == content::FileChooserParams::OpenMultiple) {
GSList* filenames =
gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
if (filenames) {
for (GSList* iter = filenames; iter != NULL;
iter = g_slist_next(iter)) {
base::FilePath path(static_cast<char*>(iter->data));
g_free(iter->data);
files->push_back(path);
}
g_slist_free(filenames);
success = true;
}
}
}
gtk_widget_destroy(dialog);
return success;
}
// Returns the number of seconds since system boot.
long GetSystemUptime() {
struct sysinfo info;
if (sysinfo(&info) == 0)
return info.uptime;
return 0;
}
} // namespace
bool CefBrowserHostImpl::PlatformCreateWindow() {
GtkWidget* window;
GtkWidget* parentView = window_info_.parent_widget;
if (parentView == NULL) {
// Create a new window.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
parentView = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), parentView);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_show_all(GTK_WIDGET(window));
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(window_destroy), NULL);
g_signal_connect(G_OBJECT(window), "delete_event",
G_CALLBACK(window_delete_event), this);
window_info_.parent_widget = parentView;
}
// Add a reference that will be released in the destroy handler.
AddRef();
// Parent the TabContents to the browser window.
window_info_.widget = web_contents_->GetView()->GetNativeView();
gtk_container_add(GTK_CONTAINER(window_info_.parent_widget),
window_info_.widget);
g_signal_connect(G_OBJECT(window_info_.widget), "destroy",
G_CALLBACK(browser_destroy), this);
// As an additional requirement on Linux, we must set the colors for the
// render widgets in webkit.
content::RendererPreferences* prefs =
web_contents_->GetMutableRendererPrefs();
prefs->focus_ring_color = SkColorSetARGB(255, 229, 151, 0);
prefs->thumb_active_color = SkColorSetRGB(244, 244, 244);
prefs->thumb_inactive_color = SkColorSetRGB(234, 234, 234);
prefs->track_color = SkColorSetRGB(211, 211, 211);
prefs->active_selection_bg_color = SkColorSetRGB(30, 144, 255);
prefs->active_selection_fg_color = SK_ColorWHITE;
prefs->inactive_selection_bg_color = SkColorSetRGB(200, 200, 200);
prefs->inactive_selection_fg_color = SkColorSetRGB(50, 50, 50);
return true;
}
void CefBrowserHostImpl::PlatformCloseWindow() {
if (window_info_.widget != NULL) {
GtkWidget* window =
gtk_widget_get_toplevel(GTK_WIDGET(window_info_.widget));
// Send the "delete_event" signal.
GdkEvent event;
memset(&event, 0, sizeof(GdkEvent));
event.any.type = GDK_DELETE;
event.any.send_event = TRUE;
event.any.window = window->window;
gtk_main_do_event(&event);
}
}
void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
if (window_info_.widget != NULL) {
GtkWidget* window =
gtk_widget_get_toplevel(GTK_WIDGET(window_info_.widget));
gtk_widget_set_size_request(window, width, height);
}
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.widget;
}
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
CEF_REQUIRE_UIT();
char buff[] = "/tmp/CEFSourceXXXXXX";
int fd = mkstemp(buff);
if (fd == -1)
return false;
FILE* srcOutput = fdopen(fd, "w+");
if (!srcOutput)
return false;
if (fputs(text.c_str(), srcOutput) < 0) {
fclose(srcOutput);
return false;
}
fclose(srcOutput);
std::string newName(buff);
newName.append(".txt");
if (rename(buff, newName.c_str()) != 0)
return false;
std::string openCommand("xdg-open ");
openCommand += newName;
if (system(openCommand.c_str()) != 0)
return false;
return true;
}
void CefBrowserHostImpl::PlatformHandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) {
// TODO(cef): Is something required here to handle shortcut keys?
}
void CefBrowserHostImpl::PlatformRunFileChooser(
const content::FileChooserParams& params,
RunFileChooserCallback callback) {
std::vector<base::FilePath> files;
if (params.mode == content::FileChooserParams::Open ||
params.mode == content::FileChooserParams::OpenMultiple ||
params.mode == content::FileChooserParams::Save) {
::RunFileDialog(params, PlatformGetWindowHandle(), &files);
} else {
NOTIMPLEMENTED();
}
callback.Run(files);
}
void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
}
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) {
// Use a synthetic GdkEventKey in order to obtain the windowsKeyCode member
// from the NativeWebKeyboardEvent constructor. This is the only member
// which cannot be easily translated (without hardcoding keyCodes).
guint state = 0;
if (key_event.modifiers & EVENTFLAG_SHIFT_DOWN)
state |= GDK_SHIFT_MASK;
if (key_event.modifiers & EVENTFLAG_CAPS_LOCK_ON)
state |= GDK_LOCK_MASK;
if (key_event.modifiers & EVENTFLAG_CONTROL_DOWN)
state |= GDK_CONTROL_MASK;
if (key_event.modifiers & EVENTFLAG_ALT_DOWN)
state |= GDK_MOD1_MASK;
if (key_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
state |= GDK_BUTTON1_MASK;
if (key_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
state |= GDK_BUTTON2_MASK;
if (key_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
state |= GDK_BUTTON3_MASK;
GdkKeymap* keymap = gdk_keymap_get_for_display(gdk_display_get_default());
GdkKeymapKey *keys = NULL;
gint n_keys = 0;
if (gdk_keymap_get_entries_for_keyval(keymap, key_event.native_key_code,
&keys, &n_keys)) {
GdkEventKey event;
event.type = GDK_KEY_PRESS;
event.window = NULL;
event.send_event = 0;
event.time = 0;
event.state = state;
event.keyval = key_event.native_key_code;
event.length = 0;
event.string = NULL;
event.hardware_keycode = keys[0].keycode;
event.group = keys[0].group;
event.is_modifier = 0;
g_free(keys);
result = content::NativeWebKeyboardEvent(
reinterpret_cast<GdkEvent*>(&event));
}
result.timeStampSeconds = GetSystemUptime();
switch (key_event.type) {
case KEYEVENT_RAWKEYDOWN:
case KEYEVENT_KEYDOWN:
result.type = blink::WebInputEvent::RawKeyDown;
break;
case KEYEVENT_KEYUP:
result.type = blink::WebInputEvent::KeyUp;
break;
case KEYEVENT_CHAR:
result.type = blink::WebInputEvent::Char;
break;
default:
NOTREACHED();
}
}
void CefBrowserHostImpl::PlatformTranslateClickEvent(
blink::WebMouseEvent& result,
const CefMouseEvent& mouse_event,
MouseButtonType type,
bool mouseUp, int clickCount) {
PlatformTranslateMouseEvent(result, mouse_event);
switch (type) {
case MBT_LEFT:
result.type = mouseUp ? blink::WebInputEvent::MouseUp :
blink::WebInputEvent::MouseDown;
result.button = blink::WebMouseEvent::ButtonLeft;
break;
case MBT_MIDDLE:
result.type = mouseUp ? blink::WebInputEvent::MouseUp :
blink::WebInputEvent::MouseDown;
result.button = blink::WebMouseEvent::ButtonMiddle;
break;
case MBT_RIGHT:
result.type = mouseUp ? blink::WebInputEvent::MouseUp :
blink::WebInputEvent::MouseDown;
result.button = blink::WebMouseEvent::ButtonRight;
break;
default:
NOTREACHED();
}
result.clickCount = clickCount;
}
void CefBrowserHostImpl::PlatformTranslateMoveEvent(
blink::WebMouseEvent& result,
const CefMouseEvent& mouse_event,
bool mouseLeave) {
PlatformTranslateMouseEvent(result, mouse_event);
if (!mouseLeave) {
result.type = blink::WebInputEvent::MouseMove;
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonLeft;
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonMiddle;
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonRight;
else
result.button = blink::WebMouseEvent::ButtonNone;
} else {
result.type = blink::WebInputEvent::MouseLeave;
result.button = blink::WebMouseEvent::ButtonNone;
}
result.clickCount = 0;
}
void CefBrowserHostImpl::PlatformTranslateWheelEvent(
blink::WebMouseWheelEvent& result,
const CefMouseEvent& mouse_event,
int deltaX, int deltaY) {
result = blink::WebMouseWheelEvent();
PlatformTranslateMouseEvent(result, mouse_event);
result.type = blink::WebInputEvent::MouseWheel;
static const double scrollbarPixelsPerGtkTick = 40.0;
result.deltaX = deltaX;
result.deltaY = deltaY;
result.wheelTicksX = result.deltaX / scrollbarPixelsPerGtkTick;
result.wheelTicksY = result.deltaY / scrollbarPixelsPerGtkTick;
result.hasPreciseScrollingDeltas = true;
// Unless the phase and momentumPhase are passed in as parameters to this
// function, there is no way to know them
result.phase = blink::WebMouseWheelEvent::PhaseNone;
result.momentumPhase = blink::WebMouseWheelEvent::PhaseNone;
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonLeft;
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonMiddle;
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonRight;
else
result.button = blink::WebMouseEvent::ButtonNone;
}
void CefBrowserHostImpl::PlatformTranslateMouseEvent(
blink::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
GtkWidget* window = gtk_widget_get_toplevel(GetWindowHandle());
GdkWindow* gdk_window = gtk_widget_get_window(window);
gint xorigin, yorigin;
gdk_window_get_root_origin(gdk_window, &xorigin, &yorigin);
result.globalX = xorigin + result.x;
result.globalY = yorigin + result.y;
// modifiers
result.modifiers |= TranslateModifiers(mouse_event.modifiers);
// timestamp
result.timeStampSeconds = GetSystemUptime();
}

View File

@ -0,0 +1,562 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors.
// Portions 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/browser/browser_host_impl.h"
#include <sys/sysinfo.h>
#include <X11/extensions/XInput2.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "libcef/browser/context.h"
#include "libcef/browser/window_delegate_view.h"
#include "libcef/browser/thread_util.h"
#include "base/bind.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/common/renderer_preferences.h"
#include "third_party/WebKit/public/web/gtk/WebInputEventFactory.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/views/widget/widget.h"
namespace {
// Returns the number of seconds since system boot.
long GetSystemUptime() {
struct sysinfo info;
if (sysinfo(&info) == 0)
return info.uptime;
return 0;
}
const char* kAtomsToCache[] = {
"WM_DELETE_WINDOW",
"WM_PROTOCOLS",
"_NET_WM_PING",
"_NET_WM_PID",
NULL
};
::Window FindEventTarget(const base::NativeEvent& xev) {
::Window target = xev->xany.window;
if (xev->type == GenericEvent)
target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event;
return target;
}
::Window FindChild(::Display* display, ::Window window) {
::Window root;
::Window parent;
::Window* children;
unsigned int nchildren;
if (XQueryTree(display, window, &root, &parent, &children, &nchildren)) {
DCHECK_EQ(1U, nchildren);
return children[0];
}
return None;
}
} // namespace
#if defined(USE_X11)
CEF_EXPORT XDisplay* cef_get_xdisplay() {
if (!CEF_CURRENTLY_ON(CEF_UIT))
return NULL;
return gfx::GetXDisplay();
}
#endif
// Object wrapper for an X11 Window.
// Based on WindowTreeHostX11 and DesktopWindowTreeHostX11.
class CefWindowX11 : public ui::PlatformEventDispatcher {
public:
CefWindowX11(CefRefPtr<CefBrowserHostImpl> browser,
::Window parent_xwindow,
const gfx::Rect& bounds)
: browser_(browser),
xdisplay_(gfx::GetXDisplay()),
parent_xwindow_(parent_xwindow),
xwindow_(0),
window_mapped_(false),
bounds_(bounds),
atom_cache_(xdisplay_, kAtomsToCache) {
if (parent_xwindow_ == None)
parent_xwindow_ = DefaultRootWindow(xdisplay_);
XSetWindowAttributes swa;
memset(&swa, 0, sizeof(swa));
swa.background_pixmap = None;
swa.override_redirect = false;
xwindow_ = XCreateWindow(
xdisplay_, parent_xwindow_,
bounds.x(), bounds.y(), bounds.width(), bounds.height(),
0, // border width
CopyFromParent, // depth
InputOutput,
CopyFromParent, // visual
CWBackPixmap | CWOverrideRedirect,
&swa);
if (ui::PlatformEventSource::GetInstance())
ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
long event_mask = FocusChangeMask | StructureNotifyMask | PropertyChangeMask;
XSelectInput(xdisplay_, xwindow_, event_mask);
XFlush(xdisplay_);
// TODO(erg): We currently only request window deletion events. We also
// should listen for activation events and anything else that GTK+ listens
// for, and do something useful.
::Atom protocols[2];
protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
// We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
// the desktop environment.
XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
// Likewise, the X server needs to know this window's pid so it knows which
// program to kill if the window hangs.
// XChangeProperty() expects "pid" to be long.
COMPILE_ASSERT(sizeof(long) >= sizeof(pid_t), pid_t_bigger_than_long);
long pid = getpid();
XChangeProperty(xdisplay_,
xwindow_,
atom_cache_.GetAtom("_NET_WM_PID"),
XA_CARDINAL,
32,
PropModeReplace,
reinterpret_cast<unsigned char*>(&pid), 1);
// Allow subclasses to create and cache additional atoms.
atom_cache_.allow_uncached_atoms();
}
virtual ~CefWindowX11() {
DCHECK(!xwindow_);
if (ui::PlatformEventSource::GetInstance())
ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
}
void Close() {
XEvent ev = {0};
ev.xclient.type = ClientMessage;
ev.xclient.window = xwindow_;
ev.xclient.message_type = atom_cache_.GetAtom("WM_PROTOCOLS");
ev.xclient.format = 32;
ev.xclient.data.l[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(xdisplay_, xwindow_, False, NoEventMask, &ev);
}
void Show() {
if (xwindow_ == None)
return;
if (!window_mapped_) {
// Before we map the window, set size hints. Otherwise, some window managers
// will ignore toplevel XMoveWindow commands.
XSizeHints size_hints;
size_hints.flags = PPosition | PWinGravity;
size_hints.x = bounds_.x();
size_hints.y = bounds_.y();
// Set StaticGravity so that the window position is not affected by the
// frame width when running with window manager.
size_hints.win_gravity = StaticGravity;
XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
XMapWindow(xdisplay_, xwindow_);
// We now block until our window is mapped. Some X11 APIs will crash and
// burn if passed |xwindow_| before the window is mapped, and XMapWindow is
// asynchronous.
if (ui::X11EventSource::GetInstance())
ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_);
window_mapped_ = true;
}
}
void Hide() {
if (xwindow_ == None)
return;
if (window_mapped_) {
XWithdrawWindow(xdisplay_, xwindow_, 0);
window_mapped_ = false;
}
}
void SetBounds(const gfx::Rect& bounds) {
if (xwindow_ == None)
return;
bool origin_changed = bounds_.origin() != bounds.origin();
bool size_changed = bounds_.size() != bounds.size();
XWindowChanges changes = {0};
unsigned value_mask = 0;
if (size_changed) {
changes.width = bounds.width();
changes.height = bounds.height();
value_mask = CWHeight | CWWidth;
}
if (origin_changed) {
changes.x = bounds.x();
changes.y = bounds.y();
value_mask |= CWX | CWY;
}
if (value_mask)
XConfigureWindow(xdisplay_, xwindow_, value_mask, &changes);
}
// ui::PlatformEventDispatcher methods:
virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE {
::Window target = FindEventTarget(event);
return target == xwindow_;
}
virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE {
XEvent* xev = event;
switch (xev->type) {
case ConfigureNotify: {
DCHECK_EQ(xwindow_, xev->xconfigure.event);
DCHECK_EQ(xwindow_, xev->xconfigure.window);
// It's possible that the X window may be resized by some other means
// than from within Aura (e.g. the X window manager can change the
// size). Make sure the root window size is maintained properly.
gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
xev->xconfigure.width, xev->xconfigure.height);
bounds_ = bounds;
::Window child = FindChild(xdisplay_, xwindow_);
if (child) {
// Resize the child DesktopWindowTreeHostX11 to match this window.
XWindowChanges changes = {0};
changes.width = bounds.width();
changes.height = bounds.height();
XConfigureWindow(xdisplay_, child, CWHeight | CWWidth, &changes);
}
break;
}
case ClientMessage: {
Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
// We have received a close message from the window manager.
if (browser_->destruction_state() <=
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
if (browser_->destruction_state() ==
CefBrowserHostImpl::DESTRUCTION_STATE_NONE) {
// Request that the browser close.
browser_->CloseBrowser(false);
}
// Cancel the close.
} else {
// Allow the close.
XDestroyWindow(xdisplay_, xwindow_);
}
} else if (message_type == atom_cache_.GetAtom("_NET_WM_PING")) {
XEvent reply_event = *xev;
reply_event.xclient.window = parent_xwindow_;
XSendEvent(xdisplay_,
reply_event.xclient.window,
False,
SubstructureRedirectMask | SubstructureNotifyMask,
&reply_event);
XFlush(xdisplay_);
}
break;
}
case DestroyNotify:
xwindow_ = None;
// Force the browser to be destroyed and release the reference added
// in PlatformCreateWindow().
browser_->WindowDestroyed();
delete this;
break;
case FocusIn:
// This message is recieved first followed by a "_NET_ACTIVE_WINDOW"
// message sent to the root window. When X11DesktopHandler handles the
// "_NET_ACTIVE_WINDOW" message it will erroneously mark the WebView
// (hosted in a DesktopWindowTreeHostX11) as unfocused. Use a delayed
// task here to restore the WebView's focus state.
CEF_POST_DELAYED_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::OnSetFocus, browser_,
FOCUS_SOURCE_SYSTEM),
100);
break;
}
return ui::POST_DISPATCH_STOP_PROPAGATION;
}
::Window xwindow() const { return xwindow_; }
gfx::Rect bounds() const { return bounds_; }
private:
CefRefPtr<CefBrowserHostImpl> browser_;
// The display and the native X window hosting the root window.
XDisplay* xdisplay_;
::Window parent_xwindow_;
::Window xwindow_;
// Is the window mapped to the screen?
bool window_mapped_;
// The bounds of |xwindow_|.
gfx::Rect bounds_;
ui::X11AtomCache atom_cache_;
DISALLOW_COPY_AND_ASSIGN(CefWindowX11);
};
bool CefBrowserHostImpl::PlatformCreateWindow() {
DCHECK(!window_x11_);
DCHECK(!window_widget_);
if (window_info_.width == 0)
window_info_.width = 800;
if (window_info_.height == 0)
window_info_.height = 600;
gfx::Rect rect(window_info_.x, window_info_.y,
window_info_.width, window_info_.height);
// Create a new window object. It will delete itself when the associated X11
// window is destroyed.
window_x11_ = new CefWindowX11(this, window_info_.parent_window, rect);
window_info_.window = window_x11_->xwindow();
// Add a reference that will be released in the destroy handler.
AddRef();
SkColor background_color = SK_ColorWHITE;
const CefSettings& settings = CefContext::Get()->settings();
if (CefColorGetA(settings.background_color) > 0) {
background_color = SkColorSetRGB(
CefColorGetR(settings.background_color),
CefColorGetG(settings.background_color),
CefColorGetB(settings.background_color));
}
CefWindowDelegateView* delegate_view =
new CefWindowDelegateView(background_color);
delegate_view->Init(window_info_.window,
web_contents(),
gfx::Rect(gfx::Point(), rect.size()));
window_widget_ = delegate_view->GetWidget();
window_widget_->Show();
window_x11_->Show();
// As an additional requirement on Linux, we must set the colors for the
// render widgets in webkit.
content::RendererPreferences* prefs =
web_contents_->GetMutableRendererPrefs();
prefs->focus_ring_color = SkColorSetARGB(255, 229, 151, 0);
prefs->thumb_active_color = SkColorSetRGB(244, 244, 244);
prefs->thumb_inactive_color = SkColorSetRGB(234, 234, 234);
prefs->track_color = SkColorSetRGB(211, 211, 211);
prefs->active_selection_bg_color = SkColorSetRGB(30, 144, 255);
prefs->active_selection_fg_color = SK_ColorWHITE;
prefs->inactive_selection_bg_color = SkColorSetRGB(200, 200, 200);
prefs->inactive_selection_fg_color = SkColorSetRGB(50, 50, 50);
return true;
}
void CefBrowserHostImpl::PlatformCloseWindow() {
if (window_x11_)
window_x11_->Close();
}
void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
if (window_x11_) {
window_x11_->SetBounds(
gfx::Rect(window_x11_->bounds().origin(), gfx::Size(width, height)));
}
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.window;
}
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
CEF_REQUIRE_UIT();
char buff[] = "/tmp/CEFSourceXXXXXX";
int fd = mkstemp(buff);
if (fd == -1)
return false;
FILE* srcOutput = fdopen(fd, "w+");
if (!srcOutput)
return false;
if (fputs(text.c_str(), srcOutput) < 0) {
fclose(srcOutput);
return false;
}
fclose(srcOutput);
std::string newName(buff);
newName.append(".txt");
if (rename(buff, newName.c_str()) != 0)
return false;
std::string openCommand("xdg-open ");
openCommand += newName;
if (system(openCommand.c_str()) != 0)
return false;
return true;
}
void CefBrowserHostImpl::PlatformHandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) {
// TODO(cef): Is something required here to handle shortcut keys?
}
void CefBrowserHostImpl::PlatformRunFileChooser(
const content::FileChooserParams& params,
RunFileChooserCallback callback) {
NOTIMPLEMENTED();
std::vector<base::FilePath> files;
callback.Run(files);
}
void CefBrowserHostImpl::PlatformHandleExternalProtocol(const GURL& url) {
}
void CefBrowserHostImpl::PlatformTranslateKeyEvent(
content::NativeWebKeyboardEvent& result,
const CefKeyEvent& key_event) {
NOTIMPLEMENTED();
}
void CefBrowserHostImpl::PlatformTranslateClickEvent(
blink::WebMouseEvent& result,
const CefMouseEvent& mouse_event,
MouseButtonType type,
bool mouseUp, int clickCount) {
PlatformTranslateMouseEvent(result, mouse_event);
switch (type) {
case MBT_LEFT:
result.type = mouseUp ? blink::WebInputEvent::MouseUp :
blink::WebInputEvent::MouseDown;
result.button = blink::WebMouseEvent::ButtonLeft;
break;
case MBT_MIDDLE:
result.type = mouseUp ? blink::WebInputEvent::MouseUp :
blink::WebInputEvent::MouseDown;
result.button = blink::WebMouseEvent::ButtonMiddle;
break;
case MBT_RIGHT:
result.type = mouseUp ? blink::WebInputEvent::MouseUp :
blink::WebInputEvent::MouseDown;
result.button = blink::WebMouseEvent::ButtonRight;
break;
default:
NOTREACHED();
}
result.clickCount = clickCount;
}
void CefBrowserHostImpl::PlatformTranslateMoveEvent(
blink::WebMouseEvent& result,
const CefMouseEvent& mouse_event,
bool mouseLeave) {
PlatformTranslateMouseEvent(result, mouse_event);
if (!mouseLeave) {
result.type = blink::WebInputEvent::MouseMove;
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonLeft;
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonMiddle;
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonRight;
else
result.button = blink::WebMouseEvent::ButtonNone;
} else {
result.type = blink::WebInputEvent::MouseLeave;
result.button = blink::WebMouseEvent::ButtonNone;
}
result.clickCount = 0;
}
void CefBrowserHostImpl::PlatformTranslateWheelEvent(
blink::WebMouseWheelEvent& result,
const CefMouseEvent& mouse_event,
int deltaX, int deltaY) {
result = blink::WebMouseWheelEvent();
PlatformTranslateMouseEvent(result, mouse_event);
result.type = blink::WebInputEvent::MouseWheel;
static const double scrollbarPixelsPerGtkTick = 40.0;
result.deltaX = deltaX;
result.deltaY = deltaY;
result.wheelTicksX = result.deltaX / scrollbarPixelsPerGtkTick;
result.wheelTicksY = result.deltaY / scrollbarPixelsPerGtkTick;
result.hasPreciseScrollingDeltas = true;
// Unless the phase and momentumPhase are passed in as parameters to this
// function, there is no way to know them
result.phase = blink::WebMouseWheelEvent::PhaseNone;
result.momentumPhase = blink::WebMouseWheelEvent::PhaseNone;
if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonLeft;
else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonMiddle;
else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON)
result.button = blink::WebMouseEvent::ButtonRight;
else
result.button = blink::WebMouseEvent::ButtonNone;
}
void CefBrowserHostImpl::PlatformTranslateMouseEvent(
blink::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;
// TODO(linux): Convert global{X,Y} to screen coordinates.
// modifiers
result.modifiers |= TranslateModifiers(mouse_event.modifiers);
// timestamp
result.timeStampSeconds = GetSystemUptime();
}

View File

@ -35,12 +35,8 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/win/shell.h"
#include "ui/gfx/win/hwnd_util.h"
#include "ui/views/background.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#pragma comment(lib, "dwmapi.lib")
@ -548,76 +544,6 @@ bool IsSystemCursorID(LPCWSTR cursor_id) {
return cursor_id >= IDC_ARROW; // See WinUser.h
}
// Manages the views-based root window that hosts the web contents. This object
// will be deleted automatically when the associated root window is destroyed.
class CefWindowDelegateView : public views::WidgetDelegateView {
public:
explicit CefWindowDelegateView(SkColor background_color)
: background_color_(background_color),
web_view_(NULL) {
}
// Create the Widget and associated root window.
void Init(gfx::AcceleratedWidget parent_widget,
content::WebContents* web_contents,
const gfx::Rect& bounds) {
DCHECK(!web_view_);
web_view_ = new views::WebView(web_contents->GetBrowserContext());
web_view_->SetWebContents(web_contents);
web_view_->SetPreferredSize(bounds.size());
views::Widget* widget = new views::Widget;
// See CalculateWindowStylesFromInitParams in
// ui/views/widget/widget_hwnd_utils.cc for the conversion of |params| to
// Windows style flags.
views::Widget::InitParams params;
params.parent_widget = parent_widget;
params.bounds = bounds;
params.delegate = this;
params.top_level = true;
// Set the WS_CHILD flag.
params.child = true;
// Set the WS_VISIBLE flag.
params.type = views::Widget::InitParams::TYPE_CONTROL;
// Don't set the WS_EX_COMPOSITED flag.
params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
// Results in a call to InitContent().
widget->Init(params);
// |widget| should now be associated with |this|.
DCHECK_EQ(widget, GetWidget());
}
private:
// Initialize the Widget's content.
void InitContent() {
set_background(views::Background::CreateSolidBackground(background_color_));
SetLayoutManager(new views::FillLayout());
AddChildView(web_view_);
}
// WidgetDelegateView methods:
virtual bool CanResize() const OVERRIDE { return true; }
virtual bool CanMaximize() const OVERRIDE { return true; }
virtual View* GetContentsView() OVERRIDE { return this; }
// View methods:
virtual void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) OVERRIDE {
if (details.is_add && details.child == this)
InitContent();
}
private:
SkColor background_color_;
views::WebView* web_view_;
DISALLOW_COPY_AND_ASSIGN(CefWindowDelegateView);
};
} // namespace
// static

View File

@ -26,10 +26,6 @@
#include "ui/base/resource/resource_bundle.h"
#include "v8/include/v8.h"
#if defined(OS_LINUX)
#include "chrome/browser/printing/print_dialog_gtk.h"
#endif
#if defined(USE_AURA)
#include "ui/aura/env.h"
#include "ui/gfx/screen.h"
@ -41,6 +37,10 @@
#endif
#endif // defined(USE_AURA)
#if defined(USE_AURA) && defined(USE_X11)
#include "ui/base/ime/input_method_initializer.h"
#endif
CefBrowserMainParts::CefBrowserMainParts(
const content::MainFunctionParams& parameters)
: BrowserMainParts(),
@ -58,6 +58,14 @@ void CefBrowserMainParts::PreMainMessageLoopStart() {
}
}
void CefBrowserMainParts::PreEarlyInitialization() {
#if defined(USE_AURA) && defined(USE_X11)
// TODO(linux): Consider using a real input method or
// views::LinuxUI::SetInstance.
ui::InitializeInputMethodForTesting();
#endif
}
void CefBrowserMainParts::ToolkitInitialized() {
#if defined(USE_AURA)
aura::Env::CreateInstance();
@ -77,11 +85,6 @@ void CefBrowserMainParts::PostMainMessageLoopStart() {
// CEF's internal handling of "chrome://tracing".
content::WebUIControllerFactory::UnregisterFactoryForTesting(
content::ContentWebUIControllerFactory::GetInstance());
#if defined(OS_LINUX)
printing::PrintingContextLinux::SetCreatePrintDialogFunction(
&PrintDialogGtk::CreatePrintDialog);
#endif
}
int CefBrowserMainParts::PreCreateThreads() {

View File

@ -41,6 +41,7 @@ class CefBrowserMainParts : public content::BrowserMainParts {
virtual void PreMainMessageLoopStart() OVERRIDE;
virtual void PostMainMessageLoopStart() OVERRIDE;
virtual void PreEarlyInitialization() OVERRIDE;
virtual void ToolkitInitialized() OVERRIDE;
virtual int PreCreateThreads() OVERRIDE;
virtual void PreMainMessageLoopRun() OVERRIDE;

View File

@ -2,8 +2,6 @@
// 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 "libcef/browser/browser_main.h"
void CefBrowserMainParts::PlatformInitialize() {

View File

@ -1,36 +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 <gtk/gtk.h>
#include "ui/events/event.h"
// This file includes a selection of methods copied from
// chrome/browser/ui/gtk/gtk_util.cc.
namespace gtk_util {
void SetAlwaysShowImage(GtkWidget* image_menu_item) {
gtk_image_menu_item_set_always_show_image(
GTK_IMAGE_MENU_ITEM(image_menu_item), TRUE);
}
} // namespace gtk_util
namespace event_utils {
int EventFlagsFromGdkState(guint state) {
int flags = 0;
flags |= (state & GDK_LOCK_MASK) ? ui::EF_CAPS_LOCK_DOWN : 0;
flags |= (state & GDK_CONTROL_MASK) ? ui::EF_CONTROL_DOWN : 0;
flags |= (state & GDK_SHIFT_MASK) ? ui::EF_SHIFT_DOWN : 0;
flags |= (state & GDK_MOD1_MASK) ? ui::EF_ALT_DOWN : 0;
flags |= (state & GDK_BUTTON1_MASK) ? ui::EF_LEFT_MOUSE_BUTTON : 0;
flags |= (state & GDK_BUTTON2_MASK) ? ui::EF_MIDDLE_MOUSE_BUTTON : 0;
flags |= (state & GDK_BUTTON3_MASK) ? ui::EF_RIGHT_MOUSE_BUTTON : 0;
return flags;
}
} // namespace event_utils

View File

@ -9,10 +9,6 @@
#include "content/public/browser/javascript_dialog_manager.h"
#if defined(TOOLKIT_GTK)
#include "ui/base/gtk/gtk_signal.h"
#endif
#if defined(OS_MACOSX)
#if __OBJC__
@class CefJavaScriptDialogHelper;
@ -63,9 +59,6 @@ class CefJavaScriptDialog {
static LRESULT CALLBACK GetMsgProc(int code, WPARAM wparam, LPARAM lparam);
static HHOOK msg_hook_;
static int msg_hook_user_count_;
#elif defined(TOOLKIT_GTK)
GtkWidget* gtk_dialog_;
CHROMEGTK_CALLBACK_1(CefJavaScriptDialog, void, OnResponse, int);
#endif
DISALLOW_COPY_AND_ASSIGN(CefJavaScriptDialog);

View File

@ -1,135 +0,0 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions 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/javascript_dialog.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/javascript_dialog_manager.h"
#include <gtk/gtk.h>
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
namespace {
const char kPromptTextId[] = "cef_prompt_text";
// If there's a text entry in the dialog, get the text from the first one and
// return it.
base::string16 GetPromptText(GtkDialog* dialog) {
GtkWidget* widget = static_cast<GtkWidget*>(
g_object_get_data(G_OBJECT(dialog), kPromptTextId));
if (widget)
return base::UTF8ToUTF16(gtk_entry_get_text(GTK_ENTRY(widget)));
return base::string16();
}
} // namespace
CefJavaScriptDialog::CefJavaScriptDialog(
CefJavaScriptDialogManager* creator,
content::JavaScriptMessageType message_type,
const base::string16& display_url,
const base::string16& message_text,
const base::string16& default_prompt_text,
const content::JavaScriptDialogManager::DialogClosedCallback& callback)
: creator_(creator),
callback_(callback) {
GtkButtonsType buttons = GTK_BUTTONS_NONE;
GtkMessageType gtk_message_type = GTK_MESSAGE_OTHER;
std::string title;
switch (message_type) {
case content::JAVASCRIPT_MESSAGE_TYPE_ALERT:
buttons = GTK_BUTTONS_NONE;
gtk_message_type = GTK_MESSAGE_WARNING;
title = "JavaScript Alert";
break;
case content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM:
buttons = GTK_BUTTONS_CANCEL;
gtk_message_type = GTK_MESSAGE_QUESTION;
title = "JavaScript Confirm";
break;
case content::JAVASCRIPT_MESSAGE_TYPE_PROMPT:
buttons = GTK_BUTTONS_CANCEL;
gtk_message_type = GTK_MESSAGE_QUESTION;
title = "JavaScript Prompt";
break;
default:
NOTREACHED();
}
if (!display_url.empty()) {
title += " - ";
title += base::UTF16ToUTF8(display_url).c_str();
}
GtkWidget* window =
gtk_widget_get_ancestor(
GTK_WIDGET(creator->browser()->GetWindowHandle()),
GTK_TYPE_WINDOW);
gtk_dialog_ = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_MODAL,
gtk_message_type,
buttons,
"%s",
base::UTF16ToUTF8(message_text).c_str());
g_signal_connect(gtk_dialog_,
"delete-event",
G_CALLBACK(gtk_widget_hide_on_delete),
NULL);
gtk_window_set_title(GTK_WINDOW(gtk_dialog_), title.c_str());
GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_),
GTK_STOCK_OK,
GTK_RESPONSE_OK);
if (message_type != content::JAVASCRIPT_MESSAGE_TYPE_PROMPT)
gtk_widget_grab_focus(ok_button);
if (message_type == content::JAVASCRIPT_MESSAGE_TYPE_PROMPT) {
GtkWidget* content_area =
gtk_dialog_get_content_area(GTK_DIALOG(gtk_dialog_));
GtkWidget* text_box = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(text_box),
base::UTF16ToUTF8(default_prompt_text).c_str());
gtk_box_pack_start(GTK_BOX(content_area), text_box, TRUE, TRUE, 0);
g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box);
gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE);
}
gtk_dialog_set_default_response(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK);
g_signal_connect(gtk_dialog_, "response", G_CALLBACK(OnResponseThunk), this);
gtk_widget_show_all(GTK_WIDGET(gtk_dialog_));
}
CefJavaScriptDialog::~CefJavaScriptDialog() {
}
void CefJavaScriptDialog::Cancel() {
}
void CefJavaScriptDialog::OnResponse(GtkWidget* dialog, int response_id) {
switch (response_id) {
case GTK_RESPONSE_OK:
callback_.Run(true, GetPromptText(GTK_DIALOG(dialog)));
break;
case GTK_RESPONSE_CANCEL:
case GTK_RESPONSE_DELETE_EVENT:
callback_.Run(false, base::string16());
break;
default:
NOTREACHED();
}
gtk_widget_destroy(dialog);
creator_->DialogClosed(this);
}

View File

@ -0,0 +1,28 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions 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/javascript_dialog.h"
#include "libcef/browser/javascript_dialog_manager.h"
CefJavaScriptDialog::CefJavaScriptDialog(
CefJavaScriptDialogManager* creator,
content::JavaScriptMessageType message_type,
const base::string16& display_url,
const base::string16& message_text,
const base::string16& default_prompt_text,
const content::JavaScriptDialogManager::DialogClosedCallback& callback)
: creator_(creator),
callback_(callback) {
NOTIMPLEMENTED();
callback_.Run(false, base::string16());
creator_->DialogClosed(this);
}
CefJavaScriptDialog::~CefJavaScriptDialog() {
}
void CefJavaScriptDialog::Cancel() {
}

View File

@ -18,8 +18,8 @@
#include "libcef/browser/menu_creator_runner_win.h"
#elif defined(OS_MACOSX)
#include "libcef/browser/menu_creator_runner_mac.h"
#elif defined(TOOLKIT_GTK)
#include "libcef/browser/menu_creator_runner_gtk.h"
#elif defined(OS_LINUX)
#include "libcef/browser/menu_creator_runner_linux.h"
#endif
namespace {
@ -110,8 +110,8 @@ bool CefMenuCreator::CreateRunner() {
runner_.reset(new CefMenuCreatorRunnerWin);
#elif defined(OS_MACOSX)
runner_.reset(new CefMenuCreatorRunnerMac);
#elif defined(TOOLKIT_GTK)
runner_.reset(new CefMenuCreatorRunnerGtk);
#elif defined(OS_LINUX)
runner_.reset(new CefMenuCreatorRunnerLinux);
#else
// Need an implementation.
NOTREACHED();

View File

@ -1,55 +0,0 @@
// Copyright (c) 2012 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 "libcef/browser/menu_creator_runner_gtk.h"
#include "libcef/browser/browser_host_impl.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents_view.h"
#include "ui/gfx/point.h"
namespace {
class CefMenuDelegate : public MenuGtk::Delegate {
public:
CefMenuDelegate() {}
};
} // namespace
CefMenuCreatorRunnerGtk::CefMenuCreatorRunnerGtk() {
}
CefMenuCreatorRunnerGtk::~CefMenuCreatorRunnerGtk() {
if (menu_.get())
menu_->Cancel();
}
bool CefMenuCreatorRunnerGtk::RunContextMenu(CefMenuCreator* manager) {
gfx::Point screen_point;
GdkEventButton* event = NULL;
gfx::Rect bounds;
manager->browser()->GetWebContents()->GetView()->GetContainerBounds(&bounds);
screen_point = bounds.origin();
screen_point.Offset(manager->params().x, manager->params().y);
content::RenderWidgetHostView* view =
manager->browser()->GetWebContents()->GetRenderWidgetHostView();
event = view->GetLastMouseDown();
if (!menu_delegate_.get())
menu_delegate_.reset(new CefMenuDelegate);
// Create a menu based on the model.
menu_.reset(new MenuGtk(menu_delegate_.get(), manager->model()));
uint32_t triggering_event_time = event ? event->time : GDK_CURRENT_TIME;
// Show the menu. Execution will continue asynchronously.
menu_->PopupAsContext(screen_point, triggering_event_time);
return true;
}

View File

@ -1,27 +0,0 @@
// Copyright (c) 2012 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.
#ifndef CEF_LIBCEF_BROWSER_MENU_MANAGER_RUNNER_GTK_H_
#define CEF_LIBCEF_BROWSER_MENU_MANAGER_RUNNER_GTK_H_
#pragma once
#include "libcef/browser/menu_creator.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/gtk/menu_gtk.h"
class CefMenuCreatorRunnerGtk: public CefMenuCreator::Runner {
public:
CefMenuCreatorRunnerGtk();
virtual ~CefMenuCreatorRunnerGtk();
// CefMemoryManager::Runner methods.
virtual bool RunContextMenu(CefMenuCreator* manager) OVERRIDE;
private:
scoped_ptr<MenuGtk> menu_;
scoped_ptr<MenuGtk::Delegate> menu_delegate_;
};
#endif // CEF_LIBCEF_BROWSER_MENU_MANAGER_RUNNER_GTK_H_

View File

@ -0,0 +1,16 @@
// Copyright (c) 2012 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 "libcef/browser/menu_creator_runner_linux.h"
CefMenuCreatorRunnerLinux::CefMenuCreatorRunnerLinux() {
}
CefMenuCreatorRunnerLinux::~CefMenuCreatorRunnerLinux() {
}
bool CefMenuCreatorRunnerLinux::RunContextMenu(CefMenuCreator* manager) {
NOTIMPLEMENTED();
return false;
}

View File

@ -0,0 +1,20 @@
// Copyright (c) 2012 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.
#ifndef CEF_LIBCEF_BROWSER_MENU_MANAGER_RUNNER_LINUX_H_
#define CEF_LIBCEF_BROWSER_MENU_MANAGER_RUNNER_LINUX_H_
#pragma once
#include "libcef/browser/menu_creator.h"
class CefMenuCreatorRunnerLinux: public CefMenuCreator::Runner {
public:
CefMenuCreatorRunnerLinux();
virtual ~CefMenuCreatorRunnerLinux();
// CefMemoryManager::Runner methods.
virtual bool RunContextMenu(CefMenuCreator* manager) OVERRIDE;
};
#endif // CEF_LIBCEF_BROWSER_MENU_MANAGER_RUNNER_LINUX_H_

View File

@ -43,6 +43,7 @@
#define CEF_POST_TASK(id, task) \
content::BrowserThread::PostTask(id, FROM_HERE, task)
#define CEF_POST_DELAYED_TASK(id, task, delay_ms) \
content::BrowserThread::PostDelayedTask(id, FROM_HERE, task, delay_ms)
content::BrowserThread::PostDelayedTask(id, FROM_HERE, task, \
base::TimeDelta::FromMilliseconds(delay_ms))
#endif // CEF_LIBCEF_BROWSER_THREAD_UTIL_H_

View File

@ -0,0 +1,62 @@
// Copyright 2014 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 "libcef/browser/window_delegate_view.h"
#include "content/public/browser/web_contents.h"
#include "ui/views/background.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
CefWindowDelegateView::CefWindowDelegateView(SkColor background_color)
: background_color_(background_color),
web_view_(NULL) {
}
void CefWindowDelegateView::Init(
gfx::AcceleratedWidget parent_widget,
content::WebContents* web_contents,
const gfx::Rect& bounds) {
DCHECK(!web_view_);
web_view_ = new views::WebView(web_contents->GetBrowserContext());
web_view_->SetWebContents(web_contents);
web_view_->SetPreferredSize(bounds.size());
views::Widget* widget = new views::Widget;
// See CalculateWindowStylesFromInitParams in
// ui/views/widget/widget_hwnd_utils.cc for the conversion of |params| to
// Windows style flags.
views::Widget::InitParams params;
params.parent_widget = parent_widget;
params.bounds = bounds;
params.delegate = this;
params.top_level = true;
// Set the WS_CHILD flag.
params.child = true;
// Set the WS_VISIBLE flag.
params.type = views::Widget::InitParams::TYPE_CONTROL;
// Don't set the WS_EX_COMPOSITED flag.
params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
// Results in a call to InitContent().
widget->Init(params);
// |widget| should now be associated with |this|.
DCHECK_EQ(widget, GetWidget());
}
void CefWindowDelegateView::InitContent() {
set_background(views::Background::CreateSolidBackground(background_color_));
SetLayoutManager(new views::FillLayout());
AddChildView(web_view_);
}
void CefWindowDelegateView::ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) {
if (details.is_add && details.child == this)
InitContent();
}

View File

@ -0,0 +1,50 @@
// Copyright 2014 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.
#ifndef CEF_LIBCEF_BROWSER_WINDOW_DELEGATE_VIEW_H_
#define CEF_LIBCEF_BROWSER_WINDOW_DELEGATE_VIEW_H_
#pragma once
#include "ui/views/widget/widget_delegate.h"
namespace content {
class WebContents;
}
namespace views {
class WebView;
}
// Manages the views-based root window that hosts the web contents. This object
// will be deleted automatically when the associated root window is destroyed.
class CefWindowDelegateView : public views::WidgetDelegateView {
public:
explicit CefWindowDelegateView(SkColor background_color);
// Create the Widget and associated root window.
void Init(gfx::AcceleratedWidget parent_widget,
content::WebContents* web_contents,
const gfx::Rect& bounds);
private:
// Initialize the Widget's content.
void InitContent();
// WidgetDelegateView methods:
virtual bool CanResize() const OVERRIDE { return true; }
virtual bool CanMaximize() const OVERRIDE { return true; }
virtual View* GetContentsView() OVERRIDE { return this; }
// View methods:
virtual void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) OVERRIDE;
private:
SkColor background_color_;
views::WebView* web_view_;
DISALLOW_COPY_AND_ASSIGN(CefWindowDelegateView);
};
#endif // CEF_LIBCEF_BROWSER_WINDOW_DELEGATE_VIEW_H_

View File

@ -34,7 +34,8 @@
#define CEF_POST_TASK_RT(task) \
CEF_RENDER_LOOP()->PostTask(FROM_HERE, task)
#define CEF_POST_DELAYED_TASK_RT(task, delay_ms) \
CEF_RENDER_LOOP()->PostDelayedTask(FROM_HERE, task, delay_ms)
CEF_RENDER_LOOP()->PostDelayedTask(FROM_HERE, task, \
base::TimeDelta::FromMilliseconds(delay_ms))
// Use this template in conjuction with RefCountedThreadSafe when you want to
// ensure that an object is deleted on the render thread.

View File

@ -144,7 +144,7 @@ cef_window_handle_t CEF_CALLBACK browser_host_get_window_handle(
DCHECK(self);
if (!self)
return NULL;
return kNullWindowHandle;
// Execute
cef_window_handle_t _retval = CefBrowserHostCppToC::Get(
@ -160,7 +160,7 @@ cef_window_handle_t CEF_CALLBACK browser_host_get_opener_window_handle(
DCHECK(self);
if (!self)
return NULL;
return kNullWindowHandle;
// Execute
cef_window_handle_t _retval = CefBrowserHostCppToC::Get(

View File

@ -100,7 +100,7 @@ void CefBrowserHostCToCpp::SetFocus(bool enable) {
CefWindowHandle CefBrowserHostCToCpp::GetWindowHandle() {
if (CEF_MEMBER_MISSING(struct_, get_window_handle))
return NULL;
return kNullWindowHandle;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -113,7 +113,7 @@ CefWindowHandle CefBrowserHostCToCpp::GetWindowHandle() {
CefWindowHandle CefBrowserHostCToCpp::GetOpenerWindowHandle() {
if (CEF_MEMBER_MISSING(struct_, get_opener_window_handle))
return NULL;
return kNullWindowHandle;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

View File

@ -4,6 +4,7 @@
#include "include/wrapper/cef_byte_read_handler.h"
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include "libcef_dll/cef_logging.h"

View File

@ -1,7 +1,7 @@
Index: common.gypi
===================================================================
--- common.gypi (revision 263053)
+++ common.gypi (working copy)
diff --git common.gypi common.gypi
index c87ec63..45bb14e 100644
--- common.gypi
+++ common.gypi
@@ -9,6 +9,9 @@
# Variables expected to be overriden on the GYP command line (-D) or by
# ~/.gyp/include.gypi.
@ -12,24 +12,11 @@ Index: common.gypi
# Putting a variables dict inside another variables dict looks kind of
# weird. This is done so that 'host_arch', 'chromeos', etc are defined as
# variables within the outer variables dict here. This is necessary
@@ -101,9 +104,9 @@
#
# TODO(erg): Merge this into the previous block once compiling with
# aura safely implies including ash capabilities.
- ['OS=="linux"', {
- 'use_aura%': 1,
- }],
+ #['OS=="linux"', {
+ # 'use_aura%': 1,
+ #}],
# Whether we're a traditional desktop unix.
['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and chromeos==0', {
Index: mac/strip_save_dsym
===================================================================
--- mac/strip_save_dsym (revision 263053)
+++ mac/strip_save_dsym (working copy)
@@ -48,7 +48,7 @@
diff --git mac/strip_save_dsym mac/strip_save_dsym
index c9cf226..0dedbe3 100755
--- mac/strip_save_dsym
+++ mac/strip_save_dsym
@@ -48,7 +48,7 @@ def macho_archs(macho):
"bundle"]
macho_types_re = "Mach-O (?:64-bit )?(?:" + "|".join(macho_types) + ")"

View File

@ -1,8 +1,8 @@
Index: desktop_aura/desktop_screen_win.cc
===================================================================
--- desktop_aura/desktop_screen_win.cc (revision 263053)
+++ desktop_aura/desktop_screen_win.cc (working copy)
@@ -54,6 +54,8 @@
diff --git desktop_aura/desktop_screen_win.cc desktop_aura/desktop_screen_win.cc
index c5edf76..9389662 100644
--- desktop_aura/desktop_screen_win.cc
+++ desktop_aura/desktop_screen_win.cc
@@ -54,6 +54,8 @@ gfx::Display DesktopScreenWin::GetDisplayMatching(
}
HWND DesktopScreenWin::GetHWNDFromNativeView(gfx::NativeView window) const {
@ -11,11 +11,11 @@ Index: desktop_aura/desktop_screen_win.cc
aura::WindowTreeHost* host = window->GetHost();
return host ? host->GetAcceleratedWidget() : NULL;
}
Index: desktop_aura/desktop_window_tree_host_win.cc
===================================================================
--- desktop_aura/desktop_window_tree_host_win.cc (revision 263053)
+++ desktop_aura/desktop_window_tree_host_win.cc (working copy)
@@ -130,7 +130,9 @@
diff --git desktop_aura/desktop_window_tree_host_win.cc desktop_aura/desktop_window_tree_host_win.cc
index 2fc499b..6fa63b5 100644
--- desktop_aura/desktop_window_tree_host_win.cc
+++ desktop_aura/desktop_window_tree_host_win.cc
@@ -130,7 +130,9 @@ void DesktopWindowTreeHostWin::Init(aura::Window* content_window,
native_widget_delegate_);
HWND parent_hwnd = NULL;
@ -26,11 +26,11 @@ Index: desktop_aura/desktop_window_tree_host_win.cc
parent_hwnd = params.parent->GetHost()->GetAcceleratedWidget();
message_handler_->set_remove_standard_frame(params.remove_standard_frame);
Index: desktop_aura/desktop_window_tree_host_win.h
===================================================================
--- desktop_aura/desktop_window_tree_host_win.h (revision 263053)
+++ desktop_aura/desktop_window_tree_host_win.h (working copy)
@@ -214,6 +214,7 @@
diff --git desktop_aura/desktop_window_tree_host_win.h desktop_aura/desktop_window_tree_host_win.h
index dc8a218..84680cf 100644
--- desktop_aura/desktop_window_tree_host_win.h
+++ desktop_aura/desktop_window_tree_host_win.h
@@ -214,6 +214,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
LPARAM l_param) OVERRIDE;
virtual bool HandleScrollEvent(const ui::ScrollEvent& event) OVERRIDE;
@ -38,27 +38,91 @@ Index: desktop_aura/desktop_window_tree_host_win.h
Widget* GetWidget();
const Widget* GetWidget() const;
HWND GetHWND() const;
Index: widget.cc
===================================================================
--- widget.cc (revision 263053)
+++ widget.cc (working copy)
@@ -122,6 +122,7 @@
diff --git desktop_aura/desktop_window_tree_host_x11.cc desktop_aura/desktop_window_tree_host_x11.cc
index 028b6f5..e8b4bd2 100644
--- desktop_aura/desktop_window_tree_host_x11.cc
+++ desktop_aura/desktop_window_tree_host_x11.cc
@@ -138,7 +138,8 @@ DesktopWindowTreeHostX11::DesktopWindowTreeHostX11(
content_window_(NULL),
window_parent_(NULL),
custom_window_shape_(NULL),
- urgency_hint_set_(false) {
+ urgency_hint_set_(false),
+ xwindow_destroyed_(false) {
}
DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() {
@@ -315,7 +316,8 @@ void DesktopWindowTreeHostX11::CloseNow() {
// Actually free our native resources.
if (ui::PlatformEventSource::GetInstance())
ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
- XDestroyWindow(xdisplay_, xwindow_);
+ if (!xwindow_destroyed_)
+ XDestroyWindow(xdisplay_, xwindow_);
xwindow_ = None;
desktop_native_widget_aura_->OnHostClosed();
@@ -968,9 +970,13 @@ void DesktopWindowTreeHostX11::InitX11Window(
if (swa.override_redirect)
attribute_mask |= CWOverrideRedirect;
+ gfx::AcceleratedWidget parent_widget = params.parent_widget;
+ if (parent_widget == gfx::kNullAcceleratedWidget)
+ parent_widget = x_root_window_;
+
bounds_ = params.bounds;
xwindow_ = XCreateWindow(
- xdisplay_, x_root_window_,
+ xdisplay_, parent_widget,
bounds_.x(), bounds_.y(),
bounds_.width(), bounds_.height(),
0, // border width
@@ -1378,6 +1384,10 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
}
break;
}
+ case DestroyNotify:
+ xwindow_destroyed_ = true;
+ CloseNow();
+ break;
case FocusOut:
if (xev->xfocus.mode != NotifyGrab) {
ReleaseCapture();
diff --git desktop_aura/desktop_window_tree_host_x11.h desktop_aura/desktop_window_tree_host_x11.h
index bc20464..63527ae 100644
--- desktop_aura/desktop_window_tree_host_x11.h
+++ desktop_aura/desktop_window_tree_host_x11.h
@@ -299,6 +299,9 @@ private:
// the frame when |xwindow_| gains focus or handles a mouse button event.
bool urgency_hint_set_;
+ // True if the xwindow has already been destroyed.
+ bool xwindow_destroyed_;
+
DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11);
};
diff --git widget.cc widget.cc
index e05db49..a936235 100644
--- widget.cc
+++ widget.cc
@@ -122,6 +122,7 @@ Widget::InitParams::InitParams()
show_state(ui::SHOW_STATE_DEFAULT),
double_buffer(false),
parent(NULL),
+ parent_widget(NULL),
+ parent_widget(gfx::kNullAcceleratedWidget),
native_widget(NULL),
desktop_window_tree_host(NULL),
top_level(false),
@@ -148,6 +149,7 @@
@@ -148,6 +149,7 @@ Widget::InitParams::InitParams(Type type)
show_state(ui::SHOW_STATE_DEFAULT),
double_buffer(false),
parent(NULL),
+ parent_widget(NULL),
+ parent_widget(gfx::kNullAcceleratedWidget),
native_widget(NULL),
desktop_window_tree_host(NULL),
top_level(false),
@@ -386,7 +388,12 @@
@@ -386,7 +388,12 @@ void Widget::Init(const InitParams& in_params) {
Minimize();
} else if (params.delegate) {
SetContentsView(params.delegate->GetContentsView());
@ -72,11 +136,11 @@ Index: widget.cc
}
native_widget_initialized_ = true;
}
Index: widget.h
===================================================================
--- widget.h (revision 263053)
+++ widget.h (working copy)
@@ -200,6 +200,7 @@
diff --git widget.h widget.h
index 640b140..43feff7 100644
--- widget.h
+++ widget.h
@@ -200,6 +200,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Should the widget be double buffered? Default is false.
bool double_buffer;
gfx::NativeView parent;

View File

@ -27,9 +27,9 @@ CefRefPtr<CefBrowser> AppGetBrowser() {
return g_handler->GetBrowser();
}
CefWindowHandle AppGetMainHwnd() {
ClientWindowHandle AppGetMainHwnd() {
if (!g_handler.get())
return NULL;
return kNullWindowHandle;
return g_handler->GetMainHwnd();
}

View File

@ -9,6 +9,7 @@
#include <string>
#include "include/cef_base.h"
#include "cefclient/client_app.h"
#include "cefclient/client_handler.h"
class CefApp;
class CefBrowser;
@ -18,7 +19,7 @@ class CefCommandLine;
CefRefPtr<CefBrowser> AppGetBrowser();
// Returns the main application window handle.
CefWindowHandle AppGetMainHwnd();
ClientWindowHandle AppGetMainHwnd();
// Returns the application working directory.
std::string AppGetWorkingDirectory();

View File

@ -6,11 +6,17 @@
// in order for gtkglext to compile.
#undef GTK_DISABLE_SINGLE_INCLUDES
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <X11/Xlib.h>
#undef Success // Definition conflicts with cef_message_router.h
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include "cefclient/cefclient.h"
#include "include/cef_app.h"
#include "include/cef_browser.h"
@ -21,11 +27,16 @@
#include "cefclient/scheme_test.h"
#include "cefclient/string_util.h"
char szWorkingDir[512]; // The current working directory
// The global ClientHandler reference.
extern CefRefPtr<ClientHandler> g_handler;
namespace {
char szWorkingDir[512]; // The current working directory
// Height of the buttons at the top of the GTK window.
int g_toolbar_height = 0;
void destroy(GtkWidget* widget, gpointer data) {
// Quitting CEF is handled in ClientHandler::OnBeforeClose().
}
@ -53,6 +64,46 @@ void TerminationSignalHandler(int signatl) {
AppQuitMessageLoop();
}
void VboxSizeAllocated(GtkWidget *widget,
GtkAllocation *allocation,
void *data) {
if (g_handler) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser) {
// Size the browser window to match the GTK widget.
::Display* xdisplay = cef_get_xdisplay();
::Window xwindow = browser->GetHost()->GetWindowHandle();
XWindowChanges changes = {0};
changes.width = allocation->width;
changes.height = allocation->height - g_toolbar_height;
XConfigureWindow(xdisplay, xwindow, CWHeight | CWWidth, &changes);
}
}
}
void ToolbarSizeAllocated(GtkWidget *widget,
GtkAllocation *allocation,
void *data) {
g_toolbar_height = allocation->height;
}
gboolean WindowFocusIn(GtkWidget* widget,
GdkEventFocus* event,
gpointer user_data) {
if (g_handler && event->in) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser) {
// Give focus to the browser window.
::Display* xdisplay = cef_get_xdisplay();
::Window xwindow = browser->GetHost()->GetWindowHandle();
XSetInputFocus(xdisplay, xwindow, RevertToParent, CurrentTime);
return TRUE;
}
}
return FALSE;
}
// Callback for Tests > Get Source... menu item.
gboolean GetSourceActivated(GtkWidget* widget) {
if (g_handler.get() && g_handler->GetBrowserId())
@ -188,6 +239,20 @@ void URLEntryActivate(GtkEntry* entry) {
g_handler->GetBrowser()->GetMainFrame()->LoadURL(std::string(url).c_str());
}
gboolean URLEntryButtonPress(GtkWidget* widget,
GdkEventButton* event,
gpointer user_data) {
// Give focus to the GTK window.
GtkWidget* window = gtk_widget_get_ancestor(widget,
GTK_TYPE_WINDOW);
GdkWindow* gdk_window = gtk_widget_get_window(window);
::Display* xdisplay = GDK_WINDOW_XDISPLAY(gdk_window);
::Window xwindow = GDK_WINDOW_XID(gdk_window);
XSetInputFocus(xdisplay, xwindow, RevertToParent, CurrentTime);
return FALSE;
}
// GTK utility functions ----------------------------------------------
GtkWidget* AddMenuEntry(GtkWidget* menu_widget, const char* text,
@ -237,16 +302,7 @@ GtkWidget* CreateMenuBar() {
return menu_bar;
}
// WebViewDelegate::TakeFocus in the test webview delegate.
static gboolean HandleFocus(GtkWidget* widget,
GdkEventFocus* focus) {
if (g_handler.get() && g_handler->GetBrowserId()) {
// Give focus to the browser window.
g_handler->GetBrowser()->GetHost()->SetFocus(true);
}
return TRUE;
}
} // namespace
int main(int argc, char* argv[]) {
CefMainArgs main_args(argc, argv);
@ -260,13 +316,6 @@ int main(int argc, char* argv[]) {
if (!getcwd(szWorkingDir, sizeof (szWorkingDir)))
return -1;
GtkWidget* window;
gtk_init(&argc, &argv);
// Perform gtkglext initialization required by the OSR example.
gtk_gl_init(&argc, &argv);
// Parse command line arguments.
AppInitCommandLine(argc, argv);
@ -278,15 +327,22 @@ int main(int argc, char* argv[]) {
// Initialize CEF.
CefInitialize(main_args, settings, app.get(), NULL);
// The Chromium sandbox requires that there only be a single thread during
// initialization. Therefore initialize GTK after CEF.
gtk_init(&argc, &argv);
// Register the scheme handler.
scheme_test::InitTest();
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
g_signal_connect(window, "focus", G_CALLBACK(&HandleFocus), NULL);
g_signal_connect(window, "focus-in-event",
G_CALLBACK(WindowFocusIn), NULL);
GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
g_signal_connect(vbox, "size-allocate",
G_CALLBACK(VboxSizeAllocated), NULL);
gtk_container_add(GTK_CONTAINER(window), vbox);
GtkWidget* menu_bar = CreateMenuBar();
@ -295,6 +351,8 @@ int main(int argc, char* argv[]) {
GtkWidget* toolbar = gtk_toolbar_new();
// Turn off the labels on the toolbar buttons.
gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
g_signal_connect(toolbar, "size-allocate",
G_CALLBACK(ToolbarSizeAllocated), NULL);
GtkToolItem* back = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
g_signal_connect(back, "clicked",
@ -316,12 +374,14 @@ int main(int argc, char* argv[]) {
G_CALLBACK(StopButtonClicked), NULL);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), stop, -1 /* append */);
GtkWidget* m_editWnd = gtk_entry_new();
g_signal_connect(G_OBJECT(m_editWnd), "activate",
GtkWidget* entry = gtk_entry_new();
g_signal_connect(entry, "activate",
G_CALLBACK(URLEntryActivate), NULL);
g_signal_connect(entry, "button-press-event",
G_CALLBACK(URLEntryButtonPress), NULL);
GtkToolItem* tool_item = gtk_tool_item_new();
gtk_container_add(GTK_CONTAINER(tool_item), m_editWnd);
gtk_container_add(GTK_CONTAINER(tool_item), entry);
gtk_tool_item_set_expand(tool_item, TRUE);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool_item, -1); // append
@ -335,24 +395,27 @@ int main(int argc, char* argv[]) {
// Create the handler.
g_handler = new ClientHandler();
g_handler->SetMainHwnd(vbox);
g_handler->SetEditHwnd(m_editWnd);
g_handler->SetEditHwnd(entry);
g_handler->SetButtonHwnds(GTK_WIDGET(back), GTK_WIDGET(forward),
GTK_WIDGET(reload), GTK_WIDGET(stop));
// Create the browser view.
// Show the GTK window.
gtk_widget_show_all(GTK_WIDGET(window));
CefWindowInfo window_info;
CefBrowserSettings browserSettings;
window_info.SetAsChild(vbox);
// The GTK window must be visible before we can retrieve the XID.
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(window));
window_info.SetAsChild(xwindow,
CefRect(0, g_toolbar_height, 800, 600 - g_toolbar_height));
// Create the browser window.
CefBrowserHost::CreateBrowserSync(
window_info, g_handler.get(),
g_handler->GetStartupURL(), browserSettings, NULL);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show_all(GTK_WIDGET(window));
// Install an signal handler so we clean up after ourselves.
// Install a signal handler so we clean up after ourselves.
signal(SIGINT, TerminationSignalHandler);
signal(SIGTERM, TerminationSignalHandler);

View File

@ -485,20 +485,20 @@ void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
}
}
void ClientHandler::SetMainHwnd(CefWindowHandle hwnd) {
void ClientHandler::SetMainHwnd(ClientWindowHandle hwnd) {
AutoLock lock_scope(this);
m_MainHwnd = hwnd;
}
void ClientHandler::SetEditHwnd(CefWindowHandle hwnd) {
void ClientHandler::SetEditHwnd(ClientWindowHandle hwnd) {
AutoLock lock_scope(this);
m_EditHwnd = hwnd;
}
void ClientHandler::SetButtonHwnds(CefWindowHandle backHwnd,
CefWindowHandle forwardHwnd,
CefWindowHandle reloadHwnd,
CefWindowHandle stopHwnd) {
void ClientHandler::SetButtonHwnds(ClientWindowHandle backHwnd,
ClientWindowHandle forwardHwnd,
ClientWindowHandle reloadHwnd,
ClientWindowHandle stopHwnd) {
AutoLock lock_scope(this);
m_BackHwnd = backHwnd;
m_ForwardHwnd = forwardHwnd;

View File

@ -14,12 +14,18 @@
#include "include/wrapper/cef_message_router.h"
#include "cefclient/util.h"
#if defined(OS_LINUX)
// The Linux client uses GTK instead of the underlying platform type (X11).
#include <gtk/gtk.h>
#define ClientWindowHandle GtkWidget*
#else
#define ClientWindowHandle CefWindowHandle
#endif
// Define this value to redirect all popup URLs to the main application browser
// window.
// #define TEST_REDIRECT_POPUP_URLS
// ClientHandler implementation.
class ClientHandler : public CefClient,
public CefContextMenuHandler,
@ -156,13 +162,13 @@ class ClientHandler : public CefClient,
virtual void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
TerminationStatus status) OVERRIDE;
void SetMainHwnd(CefWindowHandle hwnd);
CefWindowHandle GetMainHwnd() { return m_MainHwnd; }
void SetEditHwnd(CefWindowHandle hwnd);
void SetButtonHwnds(CefWindowHandle backHwnd,
CefWindowHandle forwardHwnd,
CefWindowHandle reloadHwnd,
CefWindowHandle stopHwnd);
void SetMainHwnd(ClientWindowHandle hwnd);
ClientWindowHandle GetMainHwnd() { return m_MainHwnd; }
void SetEditHwnd(ClientWindowHandle hwnd);
void SetButtonHwnds(ClientWindowHandle backHwnd,
ClientWindowHandle forwardHwnd,
ClientWindowHandle reloadHwnd,
ClientWindowHandle stopHwnd);
CefRefPtr<CefBrowser> GetBrowser() { return m_Browser; }
int GetBrowserId() { return m_BrowserId; }
@ -229,7 +235,7 @@ class ClientHandler : public CefClient,
BrowserList m_PopupBrowsers;
// The main frame window handle
CefWindowHandle m_MainHwnd;
ClientWindowHandle m_MainHwnd;
// The child browser id
int m_BrowserId;
@ -238,13 +244,13 @@ class ClientHandler : public CefClient,
bool m_bIsClosing;
// The edit window handle
CefWindowHandle m_EditHwnd;
ClientWindowHandle m_EditHwnd;
// The button window handles
CefWindowHandle m_BackHwnd;
CefWindowHandle m_ForwardHwnd;
CefWindowHandle m_StopHwnd;
CefWindowHandle m_ReloadHwnd;
ClientWindowHandle m_BackHwnd;
ClientWindowHandle m_ForwardHwnd;
ClientWindowHandle m_StopHwnd;
ClientWindowHandle m_ReloadHwnd;
// Support for logging.
std::string m_LogFile;

View File

@ -1,9 +1,14 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// Copyright (c) 2014 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 <gtk/gtk.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#undef Success // Definition conflicts with cef_message_router.h
#include <string>
#include "cefclient/client_handler.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
@ -24,11 +29,49 @@ void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
REQUIRE_UI_THREAD();
GtkWidget* window = gtk_widget_get_ancestor(
GTK_WIDGET(browser->GetHost()->GetWindowHandle()),
GTK_TYPE_WINDOW);
std::string titleStr(title);
gtk_window_set_title(GTK_WINDOW(window), titleStr.c_str());
if (!browser->IsPopup()) {
// Set the GTK parent window title.
GtkWidget* window = gtk_widget_get_ancestor(m_MainHwnd,
GTK_TYPE_WINDOW);
gtk_window_set_title(GTK_WINDOW(window), titleStr.c_str());
} else {
// Retrieve the X11 display shared with Chromium.
::Display* display = cef_get_xdisplay();
ASSERT(display);
// Retrieve the X11 window handle for the browser.
::Window window = browser->GetHost()->GetWindowHandle();
ASSERT(window != kNullWindowHandle);
// Retrieve the atoms required by the below XChangeProperty call.
const char* kAtoms[] = {
"_NET_WM_NAME",
"UTF8_STRING"
};
Atom atoms[2];
int result = XInternAtoms(display, const_cast<char**>(kAtoms), 2, false,
atoms);
ASSERT(result);
// Set the window title.
XChangeProperty(display,
window,
atoms[0],
atoms[1],
8,
PropModeReplace,
reinterpret_cast<const unsigned char*>(titleStr.c_str()),
titleStr.size());
// TODO(erg): This is technically wrong. So XStoreName and friends expect
// this in Host Portable Character Encoding instead of UTF-8, which I
// believe is Compound Text. This shouldn't matter 90% of the time since
// this is the fallback to the UTF8 property above.
XStoreName(display, browser->GetHost()->GetWindowHandle(),
titleStr.c_str());
}
}
void ClientHandler::SendNotification(NotificationType type) {
@ -57,3 +100,4 @@ void ClientHandler::SetNavState(bool canGoBack, bool canGoForward) {
std::string ClientHandler::GetDownloadPath(const std::string& file_name) {
return std::string();
}

View File

@ -6,6 +6,7 @@
#include "cefclient/resource_util.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
bool GetResourceDir(std::string& dir) {
char buff[1024];

View File

@ -2,8 +2,6 @@
// 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 "cefsimple/simple_app.h"
// Entry point function for all processes.
@ -24,9 +22,6 @@ int main(int argc, char* argv[]) {
return exit_code;
}
// Initialize GTK.
gtk_init(&argc, &argv);
// Specify CEF global settings here.
CefSettings settings;

View File

@ -1,22 +0,0 @@
// Copyright (c) 2013 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 "cefsimple/simple_handler.h"
#include <gtk/gtk.h>
#include <string>
#include "cefsimple/util.h"
#include "include/cef_browser.h"
void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
REQUIRE_UI_THREAD();
GtkWidget* window = gtk_widget_get_ancestor(
GTK_WIDGET(browser->GetHost()->GetWindowHandle()),
GTK_TYPE_WINDOW);
std::string titleStr(title);
gtk_window_set_title(GTK_WINDOW(window), titleStr.c_str());
}

View File

@ -0,0 +1,52 @@
// Copyright (c) 2014 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 "cefsimple/simple_handler.h"
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <string>
#include "cefsimple/util.h"
#include "include/cef_browser.h"
void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
REQUIRE_UI_THREAD();
std::string titleStr(title);
// Retrieve the X11 display shared with Chromium.
::Display* display = cef_get_xdisplay();
ASSERT(display);
// Retrieve the X11 window handle for the browser.
::Window window = browser->GetHost()->GetWindowHandle();
ASSERT(window != kNullWindowHandle);
// Retrieve the atoms required by the below XChangeProperty call.
const char* kAtoms[] = {
"_NET_WM_NAME",
"UTF8_STRING"
};
Atom atoms[2];
int result = XInternAtoms(display, const_cast<char**>(kAtoms), 2, false, atoms);
ASSERT(result);
// Set the window title.
XChangeProperty(display,
window,
atoms[0],
atoms[1],
8,
PropModeReplace,
reinterpret_cast<const unsigned char*>(titleStr.c_str()),
titleStr.size());
// TODO(erg): This is technically wrong. So XStoreName and friends expect
// this in Host Portable Character Encoding instead of UTF-8, which I believe
// is Compound Text. This shouldn't matter 90% of the time since this is the
// fallback to the UTF8 property above.
XStoreName(display, browser->GetHost()->GetWindowHandle(), titleStr.c_str());
}

View File

@ -377,10 +377,9 @@ _simpletypes = {
'bool' : ['int', '0'],
'char': ['char', '0'],
'char* const': ['char* const', 'NULL'],
'CefCursorHandle' : ['cef_cursor_handle_t', 'NULL'],
'CefEventHandle' : ['cef_event_handle_t', 'NULL'],
'CefWindowHandle' : ['cef_window_handle_t', 'NULL'],
'CefTextInputContext' : ['cef_text_input_context_t' ,'NULL'],
'CefCursorHandle' : ['cef_cursor_handle_t', 'kNullCursorHandle'],
'CefEventHandle' : ['cef_event_handle_t', 'kNullEventHandle'],
'CefWindowHandle' : ['cef_window_handle_t', 'kNullWindowHandle'],
'CefRect' : ['cef_rect_t', 'CefRect()'],
'CefThreadId' : ['cef_thread_id_t', 'TID_UI'],
'CefTime' : ['cef_time_t', 'CefTime()'],

View File

@ -231,7 +231,6 @@
],
'dependencies': [
'gtk',
'gtkglext',
],
'link_settings': {
'ldflags': [
@ -241,6 +240,7 @@
],
'libraries': [
"$(BUILDTYPE)/libcef.so",
"-lX11",
],
},
'sources': [
@ -442,9 +442,6 @@
],
},
],
'dependencies': [
'gtk',
],
'link_settings': {
'ldflags': [
# Look for libcef.so in the current directory. Path can also be
@ -453,6 +450,7 @@
],
'libraries': [
"$(BUILDTYPE)/libcef.so",
"-lX11",
],
},
'sources': [
@ -652,27 +650,6 @@
],
},
},
{
'target_name': 'gtkglext',
'type': 'none',
'variables': {
# gtkglext is required by the cefclient OSR example.
'gtk_packages': 'gtkglext-1.0',
},
'direct_dependent_settings': {
'cflags': [
'$(shell <(pkg-config) --cflags <(gtk_packages))',
],
},
'link_settings': {
'ldflags': [
'$(shell <(pkg-config) --libs-only-L --libs-only-other <(gtk_packages))',
],
'libraries': [
'$(shell <(pkg-config) --libs-only-l <(gtk_packages))',
],
},
},
],
}], # OS=="linux" or OS=="freebsd" or OS=="openbsd"
],