mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-24 07:58:11 +01:00
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:
parent
921c25f0af
commit
3859457eef
92
cef.gyp
92
cef.gyp
@ -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"', {
|
||||
|
3
cef.gypi
3
cef.gypi
@ -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.
|
||||
|
@ -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',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
562
libcef/browser/browser_host_impl_linux.cc
Normal file
562
libcef/browser/browser_host_impl_linux.cc
Normal 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();
|
||||
}
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
@ -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
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
28
libcef/browser/javascript_dialog_linux.cc
Normal file
28
libcef/browser/javascript_dialog_linux.cc
Normal 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() {
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
@ -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_
|
16
libcef/browser/menu_creator_runner_linux.cc
Normal file
16
libcef/browser/menu_creator_runner_linux.cc
Normal 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;
|
||||
}
|
20
libcef/browser/menu_creator_runner_linux.h
Normal file
20
libcef/browser/menu_creator_runner_linux.h
Normal 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_
|
@ -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_
|
||||
|
62
libcef/browser/window_delegate_view.cc
Normal file
62
libcef/browser/window_delegate_view.cc
Normal 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();
|
||||
}
|
||||
|
50
libcef/browser/window_delegate_view.h
Normal file
50
libcef/browser/window_delegate_view.h
Normal 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_
|
@ -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.
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "include/wrapper/cef_byte_read_handler.h"
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "libcef_dll/cef_logging.h"
|
||||
|
||||
|
@ -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) + ")"
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
52
tests/cefsimple/simple_handler_linux.cpp
Normal file
52
tests/cefsimple/simple_handler_linux.cpp
Normal 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());
|
||||
}
|
||||
|
@ -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()'],
|
||||
|
@ -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"
|
||||
],
|
||||
|
Loading…
x
Reference in New Issue
Block a user