Compare commits

...

30 Commits
6422 ... 3538

Author SHA1 Message Date
Marshall Greenblatt
cb937fc9cd Windows: Fix sandbox link error with binary distribution (issue #2546) 2018-11-13 13:46:51 -05:00
Marshall Greenblatt
56227877aa Update to Chromium version 70.0.3538.102 2018-11-12 16:57:34 -05:00
Marshall Greenblatt
e710be4f64 cefclient: Fix new window always on top (issue #1468) 2018-11-05 13:47:17 -05:00
Marshall Greenblatt
458cc98590 Fix incorrect quota size (issue #2452) 2018-10-26 15:47:35 -04:00
Marshall Greenblatt
1d1fe01a48 Update to Chromium version 70.0.3538.77 2018-10-25 18:36:05 -04:00
Marshall Greenblatt
5e6699b223 Fix substitution of localized strings for directory listings (issue #2412) 2018-10-19 14:41:34 -04:00
Marshall Greenblatt
678fa78c28 Fix ArrayBuffer crashes and add performance test (issue #2521) 2018-10-10 16:14:26 +03:00
Marshall Greenblatt
924c2e339e Windows: Fix crashes when dragging an image with OSR enabled (issue #2525) 2018-10-10 14:46:14 +03:00
Marshall Greenblatt
c8ac6c879d Linux: cefclient: Fix crash when creating popup window (issue #2512) 2018-10-10 13:49:22 +03:00
Isaac Devine
5969b2bbb8 Windows: Fix hidden dropdowns when the window is topmost (issue #1468)
Also add a --always-on-top flag to cefclient to allow easier testing of this
behavior on Windows and Linux.
2018-10-10 12:12:29 +03:00
Marshall Greenblatt
fbc59483b9 Fix crash using CefCookieManager::SetStoragePath (issue #2522) 2018-10-08 19:12:47 +03:00
Marshall Greenblatt
dcdb070ecd macOS: Fix crash when showing a select popup with CefDoMessageLoopWork (issue #2495) 2018-09-28 16:30:38 +02:00
Marshall Greenblatt
b69a4a2e3d Add missing include for DISALLOW_COPY_AND_ASSIGN 2018-09-28 15:50:01 +02:00
Marshall Greenblatt
df6fb4f06e Update to Chromium version 70.0.3538.35 2018-09-28 15:40:26 +02:00
Marshall Greenblatt
b8ca094aca Fix redraw of OSR PDF viewer (issue #2507) 2018-09-27 16:02:55 +02:00
Marshall Greenblatt
01ef24d928 Fix DCHECK when mouse wheel deltas are 0 (issue #2515) 2018-09-27 14:24:45 +02:00
Marshall Greenblatt
ce3a5d5a7b Linux: Add missing return statement (issue #2014) 2018-09-25 13:25:08 +02:00
Marshall Greenblatt
36bc0371bf Linux: Add missing use_gtk check (issue #2014) 2018-09-24 16:12:16 +02:00
Marshall Greenblatt
391685c279 Add TS_PROCESS_OOM termination status (issue #2510) 2018-09-24 10:52:22 +02:00
Marshall Greenblatt
7016b2def6 Fix crash when high contrast themes are enabled (issue #2508) 2018-09-21 16:37:00 +02:00
Marshall Greenblatt
f9b6257652 Windows: cmake: Add VS2017 15.8 build support 2018-09-21 11:13:46 +02:00
Marshall Greenblatt
6d61f0c90f Linux: Add multi-threaded message loop support (issue #2512) 2018-09-20 15:26:54 +02:00
Marshall Greenblatt
006d0629a0 Fix crash when hovering buttons in OSR PDF viewer (issue #2488) 2018-09-14 11:19:44 +02:00
Marshall Greenblatt
8f5df4027b Remove Singleton patches which are no longer required (issue #2362) 2018-09-06 21:54:33 +02:00
Marshall Greenblatt
1489b9dde4 Windows: Fix DCHECKs during shutdown with multi-threaded message loop mode (issue #2362) 2018-09-06 17:35:58 +02:00
Marshall Greenblatt
e858849615 Fix external message pump (issue #2493) 2018-09-06 14:43:20 +02:00
Marshall Greenblatt
876e82f444 Linux: Zero initialize MwmHints (issue #2492) 2018-09-06 13:49:39 +02:00
Marshall Greenblatt
74b4a5fe27 macOS: Fix crash when closing full-screen window (issue #2491) 2018-09-06 13:49:33 +02:00
Marshall Greenblatt
b3f2995808 Linux: Remove GTK build dependency (issue #2014) 2018-09-06 11:34:40 +02:00
Marshall Greenblatt
5fa11acf79 Update to Chromium version 70.0.3538.7 2018-09-05 22:22:57 +02:00
103 changed files with 1855 additions and 722 deletions

View File

@@ -405,6 +405,8 @@ static_library("libcef_static") {
"libcef/browser/net/chrome_scheme_handler.h", "libcef/browser/net/chrome_scheme_handler.h",
"libcef/browser/net/cookie_store_proxy.cc", "libcef/browser/net/cookie_store_proxy.cc",
"libcef/browser/net/cookie_store_proxy.h", "libcef/browser/net/cookie_store_proxy.h",
"libcef/browser/net/cookie_store_source.cc",
"libcef/browser/net/cookie_store_source.h",
"libcef/browser/net/crlset_file_util_impl.cc", "libcef/browser/net/crlset_file_util_impl.cc",
"libcef/browser/net/devtools_scheme_handler.cc", "libcef/browser/net/devtools_scheme_handler.cc",
"libcef/browser/net/devtools_scheme_handler.h", "libcef/browser/net/devtools_scheme_handler.h",

View File

@@ -7,5 +7,5 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding # https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
{ {
'chromium_checkout': 'refs/tags/70.0.3538.0', 'chromium_checkout': 'refs/tags/70.0.3538.102',
} }

View File

@@ -376,6 +376,8 @@
'tests/cefclient/browser/dialog_handler_gtk.cc', 'tests/cefclient/browser/dialog_handler_gtk.cc',
'tests/cefclient/browser/dialog_handler_gtk.h', 'tests/cefclient/browser/dialog_handler_gtk.h',
'tests/cefclient/browser/main_context_impl_posix.cc', 'tests/cefclient/browser/main_context_impl_posix.cc',
'tests/cefclient/browser/main_message_loop_multithreaded_gtk.cc',
'tests/cefclient/browser/main_message_loop_multithreaded_gtk.h',
'tests/cefclient/browser/print_handler_gtk.cc', 'tests/cefclient/browser/print_handler_gtk.cc',
'tests/cefclient/browser/print_handler_gtk.h', 'tests/cefclient/browser/print_handler_gtk.h',
'tests/cefclient/browser/resource_util_linux.cc', 'tests/cefclient/browser/resource_util_linux.cc',
@@ -385,6 +387,8 @@
'tests/cefclient/browser/root_window_views.h', 'tests/cefclient/browser/root_window_views.h',
'tests/cefclient/browser/temp_window_x11.cc', 'tests/cefclient/browser/temp_window_x11.cc',
'tests/cefclient/browser/temp_window_x11.h', 'tests/cefclient/browser/temp_window_x11.h',
'tests/cefclient/browser/util_gtk.cc',
'tests/cefclient/browser/util_gtk.h',
'tests/cefclient/browser/views_menu_bar.cc', 'tests/cefclient/browser/views_menu_bar.cc',
'tests/cefclient/browser/views_menu_bar.h', 'tests/cefclient/browser/views_menu_bar.h',
'tests/cefclient/browser/views_style.cc', 'tests/cefclient/browser/views_style.cc',

View File

@@ -360,6 +360,7 @@ if(OS_WINDOWS)
1912 # VS2017 version 15.5 1912 # VS2017 version 15.5
1913 # VS2017 version 15.6 1913 # VS2017 version 15.6
1914 # VS2017 version 15.7 1914 # VS2017 version 15.7
1915 # VS2017 version 15.8
) )
list(FIND supported_msvc_versions ${MSVC_VERSION} _index) list(FIND supported_msvc_versions ${MSVC_VERSION} _index)
if (${_index} EQUAL -1) if (${_index} EQUAL -1)
@@ -478,6 +479,7 @@ if(OS_WINDOWS)
dbghelp.lib dbghelp.lib
psapi.lib psapi.lib
version.lib version.lib
wbemuuid.lib
winmm.lib winmm.lib
) )

View File

@@ -51,6 +51,7 @@
#include "include/base/cef_atomic_ref_count.h" #include "include/base/cef_atomic_ref_count.h"
#include "include/base/cef_build.h" #include "include/base/cef_build.h"
#include "include/base/cef_logging.h" #include "include/base/cef_logging.h"
#include "include/base/cef_macros.h"
namespace base { namespace base {

View File

@@ -181,7 +181,7 @@ typedef struct _cef_settings_t {
// Set to true (1) to have the browser process message loop run in a separate // Set to true (1) to have the browser process message loop run in a separate
// thread. If false (0) than the CefDoMessageLoopWork() function must be // thread. If false (0) than the CefDoMessageLoopWork() function must be
// called from your application message loop. This option is only supported on // called from your application message loop. This option is only supported on
// Windows. // Windows and Linux.
/// ///
int multi_threaded_message_loop; int multi_threaded_message_loop;
@@ -789,6 +789,11 @@ typedef enum {
// Segmentation fault. // Segmentation fault.
/// ///
TS_PROCESS_CRASHED, TS_PROCESS_CRASHED,
///
// Out of memory. Some platforms may use TS_PROCESS_CRASHED instead.
///
TS_PROCESS_OOM,
} cef_termination_status_t; } cef_termination_status_t;
/// ///

View File

@@ -1213,6 +1213,11 @@ void CefBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event,
void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event, void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
int deltaX, int deltaX,
int deltaY) { int deltaY) {
if (deltaX == 0 && deltaY == 0) {
// Nothing to do.
return;
}
if (!CEF_CURRENTLY_ON_UIT()) { if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefBrowserHostImpl::SendMouseWheelEvent, this, base::BindOnce(&CefBrowserHostImpl::SendMouseWheelEvent, this,
@@ -2781,6 +2786,8 @@ void CefBrowserHostImpl::RenderProcessGone(base::TerminationStatus status) {
ts = TS_PROCESS_WAS_KILLED; ts = TS_PROCESS_WAS_KILLED;
else if (status == base::TERMINATION_STATUS_PROCESS_CRASHED) else if (status == base::TERMINATION_STATUS_PROCESS_CRASHED)
ts = TS_PROCESS_CRASHED; ts = TS_PROCESS_CRASHED;
else if (status == base::TERMINATION_STATUS_OOM)
ts = TS_PROCESS_OOM;
else if (status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION) else if (status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION)
return; return;

View File

@@ -10,7 +10,6 @@
#include "libcef/browser/browser_context_impl.h" #include "libcef/browser/browser_context_impl.h"
#include "libcef/browser/browser_context_keyed_service_factories.h" #include "libcef/browser/browser_context_keyed_service_factories.h"
#include "libcef/browser/browser_message_loop.h"
#include "libcef/browser/content_browser_client.h" #include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h" #include "libcef/browser/context.h"
#include "libcef/browser/devtools_manager_delegate.h" #include "libcef/browser/devtools_manager_delegate.h"
@@ -34,6 +33,7 @@
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
#include "net/base/net_module.h" #include "net/base/net_module.h"
#include "services/service_manager/embedder/result_codes.h" #include "services/service_manager/embedder/result_codes.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#if defined(USE_AURA) #if defined(USE_AURA)
@@ -107,11 +107,6 @@ void CefBrowserMainParts::ToolkitInitialized() {
} }
void CefBrowserMainParts::PreMainMessageLoopStart() { void CefBrowserMainParts::PreMainMessageLoopStart() {
if (!base::MessageLoop::current()) {
// Create the browser message loop.
message_loop_.reset(new CefBrowserMessageLoop());
}
for (size_t i = 0; i < chrome_extra_parts_.size(); ++i) for (size_t i = 0; i < chrome_extra_parts_.size(); ++i)
chrome_extra_parts_[i]->PreMainMessageLoopStart(); chrome_extra_parts_[i]->PreMainMessageLoopStart();
} }
@@ -156,6 +151,8 @@ void CefBrowserMainParts::PreMainMessageLoopRun() {
display::Screen::SetScreenInstance(views::CreateDesktopScreen()); display::Screen::SetScreenInstance(views::CreateDesktopScreen());
#endif #endif
ui::MaterialDesignController::Initialize();
// CEF's profile is a BrowserContext. // CEF's profile is a BrowserContext.
PreProfileInit(); PreProfileInit();

View File

@@ -16,11 +16,6 @@
#include "content/public/browser/browser_main_parts.h" #include "content/public/browser/browser_main_parts.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
namespace base {
class MessageLoop;
class Thread;
} // namespace base
namespace content { namespace content {
struct MainFunctionParams; struct MainFunctionParams;
} }
@@ -89,7 +84,6 @@ class CefBrowserMainParts : public content::BrowserMainParts {
CefRefPtr<CefRequestContextImpl> global_request_context_; CefRefPtr<CefRequestContextImpl> global_request_context_;
CefDevToolsDelegate* devtools_delegate_; // Deletes itself. CefDevToolsDelegate* devtools_delegate_; // Deletes itself.
std::unique_ptr<base::MessageLoop> message_loop_;
std::unique_ptr<extensions::ExtensionsClient> extensions_client_; std::unique_ptr<extensions::ExtensionsClient> extensions_client_;
std::unique_ptr<extensions::ExtensionsBrowserClient> std::unique_ptr<extensions::ExtensionsBrowserClient>

View File

@@ -53,7 +53,6 @@ bool ChromeProfileStub::IsChild() const {
} }
bool ChromeProfileStub::IsLegacySupervised() const { bool ChromeProfileStub::IsLegacySupervised() const {
NOTREACHED();
return false; return false;
} }

View File

@@ -797,8 +797,8 @@ void CefContentBrowserClient::GetQuotaSettings(
content::StoragePartition* partition, content::StoragePartition* partition,
storage::OptionalQuotaSettingsCallback callback) { storage::OptionalQuotaSettingsCallback callback) {
const base::FilePath& cache_path = partition->GetPath(); const base::FilePath& cache_path = partition->GetPath();
storage::GetNominalDynamicSettings(cache_path, !cache_path.empty(), storage::GetNominalDynamicSettings(
std::move(callback)); cache_path, cache_path.empty() /* is_incognito */, std::move(callback));
} }
content::MediaObserver* CefContentBrowserClient::GetMediaObserver() { content::MediaObserver* CefContentBrowserClient::GetMediaObserver() {

View File

@@ -29,6 +29,7 @@
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "services/service_manager/embedder/main.h" #include "services/service_manager/embedder/main.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
#if defined(OS_WIN) #if defined(OS_WIN)
@@ -356,7 +357,7 @@ bool CefContext::Initialize(const CefMainArgs& args,
init_thread_id_ = base::PlatformThread::CurrentId(); init_thread_id_ = base::PlatformThread::CurrentId();
settings_ = settings; settings_ = settings;
#if !defined(OS_WIN) #if !(defined(OS_WIN) || defined(OS_LINUX))
if (settings.multi_threaded_message_loop) { if (settings.multi_threaded_message_loop) {
NOTIMPLEMENTED() << "multi_threaded_message_loop is not supported."; NOTIMPLEMENTED() << "multi_threaded_message_loop is not supported.";
return false; return false;
@@ -539,6 +540,8 @@ void CefContext::FinishShutdownOnUIThread(
static_cast<ChromeBrowserProcessStub*>(g_browser_process)->Shutdown(); static_cast<ChromeBrowserProcessStub*>(g_browser_process)->Shutdown();
ui::ResourceBundle::GetSharedInstance().CleanupOnUIThread();
if (uithread_shutdown_event) if (uithread_shutdown_event)
uithread_shutdown_event->Signal(); uithread_shutdown_event->Signal();
} }

View File

@@ -10,12 +10,12 @@
#include "libcef/browser/content_browser_client.h" #include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h" #include "libcef/browser/context.h"
#include "libcef/browser/net/cookie_store_source.h"
#include "libcef/browser/net/network_delegate.h" #include "libcef/browser/net/network_delegate.h"
#include "libcef/common/task_runner_impl.h" #include "libcef/common/task_runner_impl.h"
#include "libcef/common/time_util.h" #include "libcef/common/time_util.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/files/file_util.h"
#include "base/format_macros.h" #include "base/format_macros.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
@@ -24,7 +24,6 @@
#include "content/browser/storage_partition_impl.h" #include "content/browser/storage_partition_impl.h"
#include "net/cookies/cookie_util.h" #include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h" #include "net/cookies/parsed_cookie.h"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
#include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context.h"
#include "url/gurl.h" #include "url/gurl.h"
@@ -164,7 +163,7 @@ void CefCookieManagerImpl::GetCookieStore(
return; return;
} }
DCHECK(is_blocking_ || cookie_store_.get()); DCHECK(is_blocking_ || cookie_source_);
// Binding ref-counted |this| to CookieStoreGetter may result in // Binding ref-counted |this| to CookieStoreGetter may result in
// heap-use-after-free if (a) the CookieStoreGetter contains the last // heap-use-after-free if (a) the CookieStoreGetter contains the last
@@ -187,8 +186,8 @@ void CefCookieManagerImpl::GetCookieStore(
net::CookieStore* CefCookieManagerImpl::GetExistingCookieStore() { net::CookieStore* CefCookieManagerImpl::GetExistingCookieStore() {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
if (cookie_store_.get()) { if (cookie_source_) {
return cookie_store_.get(); return cookie_source_->GetCookieStore();
} else if (request_context_impl_.get()) { } else if (request_context_impl_.get()) {
net::CookieStore* cookie_store = net::CookieStore* cookie_store =
request_context_impl_->GetExistingCookieStore(); request_context_impl_->GetExistingCookieStore();
@@ -289,45 +288,14 @@ bool CefCookieManagerImpl::SetStoragePath(
if (!path.empty()) if (!path.empty())
new_path = base::FilePath(path); new_path = base::FilePath(path);
if (cookie_store_.get() && if (!cookie_source_) {
((storage_path_.empty() && path.empty()) || storage_path_ == new_path)) { cookie_source_.reset(new CefCookieStoreOwnerSource());
// The path has not changed so don't do anything.
RunAsyncCompletionOnIOThread(callback);
return true;
} }
scoped_refptr<net::SQLitePersistentCookieStore> persistent_store; cookie_source_->SetCookieStoragePath(new_path, persist_session_cookies,
if (!new_path.empty()) { g_browser_process->net_log());
// TODO(cef): Move directory creation to the blocking pool instead of
// allowing file IO on this thread.
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (base::DirectoryExists(new_path) || base::CreateDirectory(new_path)) {
const base::FilePath& cookie_path = new_path.AppendASCII("Cookies");
persistent_store = new net::SQLitePersistentCookieStore(
cookie_path, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
// Intentionally using the background task runner exposed by CEF to
// facilitate unit test expectations. This task runner MUST be
// configured with BLOCK_SHUTDOWN.
CefContentBrowserClient::Get()->background_task_runner(),
persist_session_cookies, nullptr);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
storage_path_.clear();
}
}
// Set the new cookie store that will be used for all new requests. The old
// cookie store, if any, will be automatically flushed and closed when no
// longer referenced.
cookie_store_.reset(new net::CookieMonster(persistent_store.get(), nullptr,
g_browser_process->net_log()));
if (persistent_store.get() && persist_session_cookies)
cookie_store_->SetPersistSessionCookies(true);
storage_path_ = new_path;
// Restore the previously supported schemes.
SetSupportedSchemesInternal(supported_schemes_, callback);
RunAsyncCompletionOnIOThread(callback);
return true; return true;
} }
@@ -505,10 +473,9 @@ void CefCookieManagerImpl::SetSupportedSchemesInternal(
return; return;
} }
DCHECK(is_blocking_ || cookie_store_.get()); DCHECK(is_blocking_ || cookie_source_);
if (cookie_store_) { if (cookie_source_) {
supported_schemes_ = schemes; cookie_source_->SetCookieSupportedSchemes(schemes);
SetCookieMonsterSchemes(cookie_store_.get(), supported_schemes_);
} }
RunAsyncCompletionOnIOThread(callback); RunAsyncCompletionOnIOThread(callback);

View File

@@ -15,6 +15,8 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "net/cookies/cookie_monster.h" #include "net/cookies/cookie_monster.h"
class CefCookieStoreOwnerSource;
// Implementation of the CefCookieManager interface. // Implementation of the CefCookieManager interface.
class CefCookieManagerImpl : public CefCookieManager { class CefCookieManagerImpl : public CefCookieManager {
public: public:
@@ -122,9 +124,7 @@ class CefCookieManagerImpl : public CefCookieManager {
scoped_refptr<CefURLRequestContextGetterImpl> request_context_impl_; scoped_refptr<CefURLRequestContextGetterImpl> request_context_impl_;
// Used for cookie monsters owned by this object. // Used for cookie monsters owned by this object.
base::FilePath storage_path_; std::unique_ptr<CefCookieStoreOwnerSource> cookie_source_;
std::vector<std::string> supported_schemes_;
std::unique_ptr<net::CookieMonster> cookie_store_;
// Must be the last member. // Must be the last member.
base::WeakPtrFactory<CefCookieManagerImpl> weak_ptr_factory_; base::WeakPtrFactory<CefCookieManagerImpl> weak_ptr_factory_;

View File

@@ -259,6 +259,11 @@ bool CefExtensionsBrowserClient::IsInDemoMode() {
return false; return false;
} }
bool CefExtensionsBrowserClient::IsScreensaverInDemoMode(
const std::string& app_id) {
return false;
}
bool CefExtensionsBrowserClient::IsRunningInForcedAppMode() { bool CefExtensionsBrowserClient::IsRunningInForcedAppMode() {
return false; return false;
} }

View File

@@ -85,6 +85,7 @@ class CefExtensionsBrowserClient : public ExtensionsBrowserClient {
bool DidVersionUpdate(content::BrowserContext* context) override; bool DidVersionUpdate(content::BrowserContext* context) override;
void PermitExternalProtocolHandler() override; void PermitExternalProtocolHandler() override;
bool IsInDemoMode() override; bool IsInDemoMode() override;
bool IsScreensaverInDemoMode(const std::string& app_id) override;
bool IsRunningInForcedAppMode() override; bool IsRunningInForcedAppMode() override;
bool IsAppModeForcedForApp(const ExtensionId& extension_id) override; bool IsAppModeForcedForApp(const ExtensionId& extension_id) override;
bool IsLoggedInAsPublicAccount() override; bool IsLoggedInAsPublicAccount() override;

View File

@@ -78,8 +78,8 @@ bool CefBrowserPlatformDelegateNativeLinux::CreateHostWindow() {
// Add a reference that will be released in BrowserDestroyed(). // Add a reference that will be released in BrowserDestroyed().
browser_->AddRef(); browser_->AddRef();
CefWindowDelegateView* delegate_view = CefWindowDelegateView* delegate_view = new CefWindowDelegateView(
new CefWindowDelegateView(GetBackgroundColor()); GetBackgroundColor(), window_x11_->TopLevelAlwaysOnTop());
delegate_view->Init(window_info_.window, browser_->web_contents(), delegate_view->Init(window_info_.window, browser_->web_contents(),
gfx::Rect(gfx::Point(), rect.size())); gfx::Rect(gfx::Point(), rect.size()));

View File

@@ -99,6 +99,7 @@
} }
- (void)cleanup:(id)window { - (void)cleanup:(id)window {
[window_ setDelegate:nil];
[self release]; [self release];
} }

View File

@@ -189,8 +189,15 @@ bool CefBrowserPlatformDelegateNativeWin::CreateHostWindow() {
point = point =
gfx::ToFlooredPoint(gfx::ScalePoint(gfx::PointF(point), 1.0f / scale)); gfx::ToFlooredPoint(gfx::ScalePoint(gfx::PointF(point), 1.0f / scale));
// Stay on top if top-most window hosting the web view is topmost.
HWND top_level_window = GetAncestor(window_info_.window, GA_ROOT);
DWORD top_level_window_ex_styles =
GetWindowLongPtr(top_level_window, GWL_EXSTYLE);
bool always_on_top =
(top_level_window_ex_styles & WS_EX_TOPMOST) == WS_EX_TOPMOST;
CefWindowDelegateView* delegate_view = CefWindowDelegateView* delegate_view =
new CefWindowDelegateView(GetBackgroundColor()); new CefWindowDelegateView(GetBackgroundColor(), always_on_top);
delegate_view->Init(window_info_.window, browser_->web_contents(), delegate_view->Init(window_info_.window, browser_->web_contents(),
gfx::Rect(0, 0, point.x(), point.y())); gfx::Rect(0, 0, point.x(), point.y()));

View File

@@ -12,8 +12,11 @@
#include "ui/views/layout/fill_layout.h" #include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
CefWindowDelegateView::CefWindowDelegateView(SkColor background_color) CefWindowDelegateView::CefWindowDelegateView(SkColor background_color,
: background_color_(background_color), web_view_(NULL) {} bool always_on_top)
: background_color_(background_color),
web_view_(NULL),
always_on_top_(always_on_top) {}
void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget, void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget,
content::WebContents* web_contents, content::WebContents* web_contents,
@@ -44,6 +47,8 @@ void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget,
// CefBrowserHostImpl::PlatformSetFocus. // CefBrowserHostImpl::PlatformSetFocus.
params.activatable = views::Widget::InitParams::ACTIVATABLE_YES; params.activatable = views::Widget::InitParams::ACTIVATABLE_YES;
params.keep_on_top = always_on_top_;
// Results in a call to InitContent(). // Results in a call to InitContent().
widget->Init(params); widget->Init(params);

View File

@@ -20,7 +20,7 @@ class WebView;
// will be deleted automatically when the associated root window is destroyed. // will be deleted automatically when the associated root window is destroyed.
class CefWindowDelegateView : public views::WidgetDelegateView { class CefWindowDelegateView : public views::WidgetDelegateView {
public: public:
explicit CefWindowDelegateView(SkColor background_color); CefWindowDelegateView(SkColor background_color, bool always_on_top);
// Create the Widget and associated root window. // Create the Widget and associated root window.
void Init(gfx::AcceleratedWidget parent_widget, void Init(gfx::AcceleratedWidget parent_widget,
@@ -43,6 +43,7 @@ class CefWindowDelegateView : public views::WidgetDelegateView {
private: private:
SkColor background_color_; SkColor background_color_;
views::WebView* web_view_; views::WebView* web_view_;
bool always_on_top_;
DISALLOW_COPY_AND_ASSIGN(CefWindowDelegateView); DISALLOW_COPY_AND_ASSIGN(CefWindowDelegateView);
}; };

View File

@@ -104,6 +104,7 @@ CefWindowX11::CefWindowX11(CefRefPtr<CefBrowserHostImpl> browser,
InputOutput, InputOutput,
CopyFromParent, // visual CopyFromParent, // visual
CWBackPixmap | CWOverrideRedirect, &swa); CWBackPixmap | CWOverrideRedirect, &swa);
CHECK(xwindow_);
if (ui::PlatformEventSource::GetInstance()) if (ui::PlatformEventSource::GetInstance())
ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
@@ -395,3 +396,34 @@ void CefWindowX11::ContinueFocus() {
browser_->SetFocus(true); browser_->SetFocus(true);
focus_pending_ = false; focus_pending_ = false;
} }
bool CefWindowX11::TopLevelAlwaysOnTop() const {
::Window toplevel_window = FindToplevelParent(xdisplay_, xwindow_);
Atom state_atom = gfx::GetAtom("_NET_WM_STATE");
Atom state_keep_above = gfx::GetAtom("_NET_WM_STATE_KEEP_ABOVE");
Atom* states;
Atom actual_type;
int actual_format;
unsigned long num_items;
unsigned long bytes_after;
XGetWindowProperty(xdisplay_, toplevel_window, state_atom, 0, 1024,
x11::False, XA_ATOM, &actual_type, &actual_format,
&num_items, &bytes_after,
reinterpret_cast<unsigned char**>(&states));
bool always_on_top = false;
for (unsigned long i = 0; i < num_items; ++i) {
if (states[i] == state_keep_above) {
always_on_top = true;
break;
}
}
XFree(states);
return always_on_top;
}

View File

@@ -52,6 +52,8 @@ class CefWindowX11 : public ui::PlatformEventDispatcher {
::Window xwindow() const { return xwindow_; } ::Window xwindow() const { return xwindow_; }
gfx::Rect bounds() const { return bounds_; } gfx::Rect bounds() const { return bounds_; }
bool TopLevelAlwaysOnTop() const;
private: private:
void ContinueFocus(); void ContinueFocus();

View File

@@ -4,12 +4,12 @@
#include "libcef/browser/net/cookie_store_proxy.h" #include "libcef/browser/net/cookie_store_proxy.h"
#include "libcef/browser/cookie_manager_impl.h" #include "include/cef_request_context.h"
#include "libcef/browser/net/url_request_context_impl.h" #include "libcef/browser/net/cookie_store_source.h"
#include "libcef/browser/thread_util.h" #include "libcef/browser/thread_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "net/url_request/url_request_context.h" #include "net/cookies/cookie_change_dispatcher.h"
namespace { namespace {
@@ -44,12 +44,10 @@ class NullCookieChangeDispatcher : public net::CookieChangeDispatcher {
} // namespace } // namespace
CefCookieStoreProxy::CefCookieStoreProxy( CefCookieStoreProxy::CefCookieStoreProxy(
CefURLRequestContextImpl* parent, std::unique_ptr<CefCookieStoreSource> source)
CefRefPtr<CefRequestContextHandler> handler) : source_(std::move(source)) {
: parent_(parent), handler_(handler) {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
DCHECK(parent_); DCHECK(source_);
DCHECK(handler_.get());
} }
CefCookieStoreProxy::~CefCookieStoreProxy() { CefCookieStoreProxy::~CefCookieStoreProxy() {
@@ -189,24 +187,5 @@ bool CefCookieStoreProxy::IsEphemeral() {
net::CookieStore* CefCookieStoreProxy::GetCookieStore() { net::CookieStore* CefCookieStoreProxy::GetCookieStore() {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
return source_->GetCookieStore();
CefRefPtr<CefCookieManager> manager = handler_->GetCookieManager();
if (manager.get()) {
// Use the cookie store provided by the manager. May be nullptr if the
// cookie manager is blocking.
return reinterpret_cast<CefCookieManagerImpl*>(manager.get())
->GetExistingCookieStore();
}
DCHECK(parent_);
if (parent_) {
// Use the cookie store from the parent.
net::CookieStore* cookie_store = parent_->cookie_store();
DCHECK(cookie_store);
if (!cookie_store)
LOG(ERROR) << "Cookie store does not exist";
return cookie_store;
}
return nullptr;
} }

View File

@@ -6,19 +6,15 @@
#define CEF_LIBCEF_BROWSER_COOKIE_STORE_PROXY_H_ #define CEF_LIBCEF_BROWSER_COOKIE_STORE_PROXY_H_
#pragma once #pragma once
#include "include/cef_request_context_handler.h"
#include "net/cookies/cookie_store.h" #include "net/cookies/cookie_store.h"
class CefURLRequestContextImpl; class CefCookieStoreSource;
// Proxies cookie requests to the CefRequestContextHandler or global cookie // Proxies cookie requests to a CefCookieStoreSource (see comments on the
// store. Life span is controlled by CefURLRequestContextProxy. Only accessed on // implementation classes for details). Only accessed on the IO thread.
// the IO thread. See browser_context.h for an object relationship diagram.
class CefCookieStoreProxy : public net::CookieStore { class CefCookieStoreProxy : public net::CookieStore {
public: public:
CefCookieStoreProxy(CefURLRequestContextImpl* parent, explicit CefCookieStoreProxy(std::unique_ptr<CefCookieStoreSource> source);
CefRefPtr<CefRequestContextHandler> handler);
~CefCookieStoreProxy() override; ~CefCookieStoreProxy() override;
// net::CookieStore methods. // net::CookieStore methods.
@@ -52,11 +48,7 @@ class CefCookieStoreProxy : public net::CookieStore {
private: private:
net::CookieStore* GetCookieStore(); net::CookieStore* GetCookieStore();
// The |parent_| pointer is kept alive by CefURLRequestContextGetterProxy std::unique_ptr<CefCookieStoreSource> const source_;
// which has a ref to the owning CefURLRequestContextGetterImpl.
CefURLRequestContextImpl* parent_;
CefRefPtr<CefRequestContextHandler> handler_;
std::unique_ptr<net::CookieChangeDispatcher> null_dispatcher_; std::unique_ptr<net::CookieChangeDispatcher> null_dispatcher_;
DISALLOW_COPY_AND_ASSIGN(CefCookieStoreProxy); DISALLOW_COPY_AND_ASSIGN(CefCookieStoreProxy);

View File

@@ -0,0 +1,111 @@
// Copyright (c) 2018 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/net/cookie_store_source.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/cookie_manager_impl.h"
#include "libcef/browser/net/url_request_context_impl.h"
#include "libcef/browser/thread_util.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
CefCookieStoreHandlerSource::CefCookieStoreHandlerSource(
CefURLRequestContextImpl* parent,
CefRefPtr<CefRequestContextHandler> handler)
: parent_(parent), handler_(handler) {
DCHECK(parent_);
DCHECK(handler_);
}
net::CookieStore* CefCookieStoreHandlerSource::GetCookieStore() {
CEF_REQUIRE_IOT();
CefRefPtr<CefCookieManager> manager = handler_->GetCookieManager();
if (manager) {
// Use the cookie store provided by the manager. May be nullptr if the
// cookie manager is blocking.
return reinterpret_cast<CefCookieManagerImpl*>(manager.get())
->GetExistingCookieStore();
}
DCHECK(parent_);
if (parent_) {
// Use the cookie store from the parent.
net::CookieStore* cookie_store = parent_->cookie_store();
DCHECK(cookie_store);
if (!cookie_store)
LOG(ERROR) << "Cookie store does not exist";
return cookie_store;
}
return nullptr;
}
CefCookieStoreOwnerSource::CefCookieStoreOwnerSource() {}
void CefCookieStoreOwnerSource::SetCookieStoragePath(
const base::FilePath& path,
bool persist_session_cookies,
net::NetLog* net_log) {
CEF_REQUIRE_IOT();
if (cookie_store_ && ((path_.empty() && path.empty()) || path_ == path)) {
// The path has not changed so don't do anything.
return;
}
scoped_refptr<net::SQLitePersistentCookieStore> persistent_store;
if (!path.empty()) {
// TODO(cef): Move directory creation to the blocking pool instead of
// allowing file IO on this thread.
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (base::DirectoryExists(path) || base::CreateDirectory(path)) {
const base::FilePath& cookie_path = path.AppendASCII("Cookies");
persistent_store = new net::SQLitePersistentCookieStore(
cookie_path,
content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::IO),
// Intentionally using the background task runner exposed by CEF to
// facilitate unit test expectations. This task runner MUST be
// configured with BLOCK_SHUTDOWN.
CefContentBrowserClient::Get()->background_task_runner(),
persist_session_cookies, NULL);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
}
}
// Set the new cookie store that will be used for all new requests. The old
// cookie store, if any, will be automatically flushed and closed when no
// longer referenced.
std::unique_ptr<net::CookieMonster> cookie_monster(
new net::CookieMonster(persistent_store.get(), nullptr, net_log));
if (persistent_store.get() && persist_session_cookies)
cookie_monster->SetPersistSessionCookies(true);
path_ = path;
// Restore the previously supported schemes.
CefCookieManagerImpl::SetCookieMonsterSchemes(cookie_monster.get(),
supported_schemes_);
cookie_store_ = std::move(cookie_monster);
}
void CefCookieStoreOwnerSource::SetCookieSupportedSchemes(
const std::vector<std::string>& schemes) {
CEF_REQUIRE_IOT();
supported_schemes_ = schemes;
CefCookieManagerImpl::SetCookieMonsterSchemes(
static_cast<net::CookieMonster*>(cookie_store_.get()),
supported_schemes_);
}
net::CookieStore* CefCookieStoreOwnerSource::GetCookieStore() {
CEF_REQUIRE_IOT();
return cookie_store_.get();
}

View File

@@ -0,0 +1,75 @@
// Copyright (c) 2018 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_COOKIE_STORE_SOURCE_H_
#define CEF_LIBCEF_BROWSER_COOKIE_STORE_SOURCE_H_
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "include/cef_request_context_handler.h"
#include "base/macros.h"
namespace base {
class FilePath;
}
namespace net {
class CookieStore;
class NetLog;
} // namespace net
class CefURLRequestContextImpl;
// Abstract base class for CookieStore sources. Only accessed on the IO thread.
class CefCookieStoreSource {
public:
virtual net::CookieStore* GetCookieStore() = 0;
virtual ~CefCookieStoreSource() {}
};
// Sources a cookie store that is created/owned by a CefCookieManager or the
// parent context. Life span is controlled by CefURLRequestContextProxy. See
// browser_context.h for an object relationship diagram.
class CefCookieStoreHandlerSource : public CefCookieStoreSource {
public:
CefCookieStoreHandlerSource(CefURLRequestContextImpl* parent,
CefRefPtr<CefRequestContextHandler> handler);
net::CookieStore* GetCookieStore() override;
private:
// The |parent_| pointer is kept alive by CefURLRequestContextGetterProxy
// which has a ref to the owning CefURLRequestContextGetterImpl.
CefURLRequestContextImpl* parent_;
CefRefPtr<CefRequestContextHandler> handler_;
DISALLOW_COPY_AND_ASSIGN(CefCookieStoreHandlerSource);
};
// Sources a cookie store that is created/owned by this object. Life span is
// controlled by the owning URLRequestContext.
class CefCookieStoreOwnerSource : public CefCookieStoreSource {
public:
CefCookieStoreOwnerSource();
void SetCookieStoragePath(const base::FilePath& path,
bool persist_session_cookies,
net::NetLog* net_log);
void SetCookieSupportedSchemes(const std::vector<std::string>& schemes);
net::CookieStore* GetCookieStore() override;
private:
std::unique_ptr<net::CookieStore> cookie_store_;
base::FilePath path_;
std::vector<std::string> supported_schemes_;
DISALLOW_COPY_AND_ASSIGN(CefCookieStoreOwnerSource);
};
#endif // CEF_LIBCEF_BROWSER_COOKIE_STORE_SOURCE_H_

View File

@@ -10,6 +10,8 @@
#include "libcef/browser/content_browser_client.h" #include "libcef/browser/content_browser_client.h"
#include "libcef/browser/cookie_manager_impl.h" #include "libcef/browser/cookie_manager_impl.h"
#include "libcef/browser/net/cookie_store_proxy.h"
#include "libcef/browser/net/cookie_store_source.h"
#include "libcef/browser/net/network_delegate.h" #include "libcef/browser/net/network_delegate.h"
#include "libcef/browser/net/scheme_handler.h" #include "libcef/browser/net/scheme_handler.h"
#include "libcef/browser/net/url_request_interceptor.h" #include "libcef/browser/net/url_request_interceptor.h"
@@ -18,7 +20,6 @@
#include "libcef/common/content_client.h" #include "libcef/common/content_client.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/stl_util.h" #include "base/stl_util.h"
@@ -43,7 +44,6 @@
#include "net/cert/multi_log_ct_verifier.h" #include "net/cert/multi_log_ct_verifier.h"
#include "net/cookies/cookie_monster.h" #include "net/cookies/cookie_monster.h"
#include "net/dns/host_resolver.h" #include "net/dns/host_resolver.h"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
#include "net/ftp/ftp_network_layer.h" #include "net/ftp/ftp_network_layer.h"
#include "net/http/http_auth_handler_factory.h" #include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h" #include "net/http/http_auth_preferences.h"
@@ -473,57 +473,21 @@ void CefURLRequestContextGetterImpl::SetCookieStoragePath(
const base::FilePath& path, const base::FilePath& path,
bool persist_session_cookies) { bool persist_session_cookies) {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
if (!io_state_->cookie_source_) {
if (io_state_->url_request_context_->cookie_store() && // Use a proxy because we can't change the URLRequestContext's CookieStore
((io_state_->cookie_store_path_.empty() && path.empty()) || // during runtime.
io_state_->cookie_store_path_ == path)) { io_state_->cookie_source_ = new CefCookieStoreOwnerSource();
// The path has not changed so don't do anything. io_state_->storage_->set_cookie_store(std::make_unique<CefCookieStoreProxy>(
return; base::WrapUnique(io_state_->cookie_source_)));
} }
io_state_->cookie_source_->SetCookieStoragePath(path, persist_session_cookies,
scoped_refptr<net::SQLitePersistentCookieStore> persistent_store; io_state_->net_log_);
if (!path.empty()) {
// TODO(cef): Move directory creation to the blocking pool instead of
// allowing file IO on this thread.
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (base::DirectoryExists(path) || base::CreateDirectory(path)) {
const base::FilePath& cookie_path = path.AppendASCII("Cookies");
persistent_store = new net::SQLitePersistentCookieStore(
cookie_path, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
// Intentionally using the background task runner exposed by CEF to
// facilitate unit test expectations. This task runner MUST be
// configured with BLOCK_SHUTDOWN.
CefContentBrowserClient::Get()->background_task_runner(),
persist_session_cookies, NULL);
} else {
NOTREACHED() << "The cookie storage directory could not be created";
}
}
// Set the new cookie store that will be used for all new requests. The old
// cookie store, if any, will be automatically flushed and closed when no
// longer referenced.
std::unique_ptr<net::CookieMonster> cookie_monster(new net::CookieMonster(
persistent_store.get(), nullptr, io_state_->net_log_));
if (persistent_store.get() && persist_session_cookies)
cookie_monster->SetPersistSessionCookies(true);
io_state_->cookie_store_path_ = path;
// Restore the previously supported schemes.
CefCookieManagerImpl::SetCookieMonsterSchemes(
cookie_monster.get(), io_state_->cookie_supported_schemes_);
io_state_->storage_->set_cookie_store(std::move(cookie_monster));
} }
void CefURLRequestContextGetterImpl::SetCookieSupportedSchemes( void CefURLRequestContextGetterImpl::SetCookieSupportedSchemes(
const std::vector<std::string>& schemes) { const std::vector<std::string>& schemes) {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
io_state_->cookie_source_->SetCookieSupportedSchemes(schemes);
io_state_->cookie_supported_schemes_ = schemes;
CefCookieManagerImpl::SetCookieMonsterSchemes(
static_cast<net::CookieMonster*>(GetExistingCookieStore()),
io_state_->cookie_supported_schemes_);
} }
void CefURLRequestContextGetterImpl::AddHandler( void CefURLRequestContextGetterImpl::AddHandler(
@@ -540,9 +504,8 @@ void CefURLRequestContextGetterImpl::AddHandler(
net::CookieStore* CefURLRequestContextGetterImpl::GetExistingCookieStore() net::CookieStore* CefURLRequestContextGetterImpl::GetExistingCookieStore()
const { const {
CEF_REQUIRE_IOT(); CEF_REQUIRE_IOT();
if (io_state_->url_request_context_ && if (io_state_->cookie_source_) {
io_state_->url_request_context_->cookie_store()) { return io_state_->cookie_source_->GetCookieStore();
return io_state_->url_request_context_->cookie_store();
} }
LOG(ERROR) << "Cookie store does not exist"; LOG(ERROR) << "Cookie store does not exist";

View File

@@ -22,6 +22,7 @@
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_job_factory.h"
class CefCookieStoreOwnerSource;
class PrefRegistrySimple; class PrefRegistrySimple;
class PrefService; class PrefService;
@@ -113,8 +114,8 @@ class CefURLRequestContextGetterImpl : public CefURLRequestContextGetter {
content::ProtocolHandlerMap protocol_handlers_; content::ProtocolHandlerMap protocol_handlers_;
content::URLRequestInterceptorScopedVector request_interceptors_; content::URLRequestInterceptorScopedVector request_interceptors_;
base::FilePath cookie_store_path_; // Owned by the URLRequestContextStorage.
std::vector<std::string> cookie_supported_schemes_; CefCookieStoreOwnerSource* cookie_source_ = nullptr;
std::vector<CefRefPtr<CefRequestContextHandler>> handler_list_; std::vector<CefRefPtr<CefRequestContextHandler>> handler_list_;

View File

@@ -5,6 +5,7 @@
#include "libcef/browser/net/url_request_context_proxy.h" #include "libcef/browser/net/url_request_context_proxy.h"
#include "libcef/browser/net/cookie_store_proxy.h" #include "libcef/browser/net/cookie_store_proxy.h"
#include "libcef/browser/net/cookie_store_source.h"
#include "libcef/browser/net/url_request_context_impl.h" #include "libcef/browser/net/url_request_context_impl.h"
#include "libcef/browser/thread_util.h" #include "libcef/browser/thread_util.h"
@@ -16,7 +17,8 @@ CefURLRequestContextProxy::CefURLRequestContextProxy(
DCHECK(handler.get()); DCHECK(handler.get());
// Cookie store that proxies to the browser implementation. // Cookie store that proxies to the browser implementation.
cookie_store_proxy_.reset(new CefCookieStoreProxy(parent, handler)); cookie_store_proxy_.reset(new CefCookieStoreProxy(
std::make_unique<CefCookieStoreHandlerSource>(parent, handler)));
set_cookie_store(cookie_store_proxy_.get()); set_cookie_store(cookie_store_proxy_.get());
// All other values refer to the parent request context. // All other values refer to the parent request context.

View File

@@ -27,6 +27,7 @@
#include "content/browser/bad_message.h" #include "content/browser/bad_message.h"
#include "content/browser/compositor/image_transport_factory.h" #include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h" #include "content/browser/frame_host/render_widget_host_view_guest.h"
#include "content/browser/renderer_host/cursor_manager.h"
#include "content/browser/renderer_host/dip_util.h" #include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -277,6 +278,8 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
if (browser_impl_.get()) if (browser_impl_.get())
ResizeRootLayer(false); ResizeRootLayer(false);
cursor_manager_.reset(new content::CursorManager(this));
// Do this last because it may result in a call to SetNeedsBeginFrames. // Do this last because it may result in a call to SetNeedsBeginFrames.
render_widget_host_->SetView(this); render_widget_host_->SetView(this);
} }
@@ -636,6 +639,10 @@ void CefRenderWidgetHostViewOSR::UpdateCursor(
#endif #endif
} }
content::CursorManager* CefRenderWidgetHostViewOSR::GetCursorManager() {
return cursor_manager_.get();
}
void CefRenderWidgetHostViewOSR::SetIsLoading(bool is_loading) {} void CefRenderWidgetHostViewOSR::SetIsLoading(bool is_loading) {}
void CefRenderWidgetHostViewOSR::RenderProcessGone( void CefRenderWidgetHostViewOSR::RenderProcessGone(

View File

@@ -44,6 +44,7 @@ class RenderWidgetHost;
class RenderWidgetHostImpl; class RenderWidgetHostImpl;
class RenderWidgetHostViewGuest; class RenderWidgetHostViewGuest;
class BackingStore; class BackingStore;
class CursorManager;
} // namespace content } // namespace content
class CefBeginFrameTimer; class CefBeginFrameTimer;
@@ -153,6 +154,7 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
int error_code) override; int error_code) override;
void Destroy() override; void Destroy() override;
void SetTooltipText(const base::string16& tooltip_text) override; void SetTooltipText(const base::string16& tooltip_text) override;
content::CursorManager* GetCursorManager() override;
gfx::Size GetCompositorViewportPixelSize() const override; gfx::Size GetCompositorViewportPixelSize() const override;
void CopyFromSurface( void CopyFromSurface(
@@ -346,6 +348,8 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
std::unique_ptr<ui::XScopedCursor> invisible_cursor_; std::unique_ptr<ui::XScopedCursor> invisible_cursor_;
#endif #endif
std::unique_ptr<content::CursorManager> cursor_manager_;
// Used to control the VSync rate in subprocesses when BeginFrame scheduling // Used to control the VSync rate in subprocesses when BeginFrame scheduling
// is enabled. // is enabled.
std::unique_ptr<CefBeginFrameTimer> begin_frame_timer_; std::unique_ptr<CefBeginFrameTimer> begin_frame_timer_;

View File

@@ -323,7 +323,7 @@ void CefWindowView::CreateWidget() {
}; };
Atom mwmHintsProperty = XInternAtom(display, "_MOTIF_WM_HINTS", 0); Atom mwmHintsProperty = XInternAtom(display, "_MOTIF_WM_HINTS", 0);
struct MwmHints hints; struct MwmHints hints = {};
hints.flags = MWM_HINTS_DECORATIONS; hints.flags = MWM_HINTS_DECORATIONS;
hints.decorations = 0; hints.decorations = 0;
XChangeProperty(display, window, mwmHintsProperty, mwmHintsProperty, 32, XChangeProperty(display, window, mwmHintsProperty, mwmHintsProperty, 32,

View File

@@ -96,9 +96,6 @@ CefString CefDragDataImpl::GetFragmentBaseURL() {
CefString CefDragDataImpl::GetFileName() { CefString CefDragDataImpl::GetFileName() {
base::AutoLock lock_scope(lock_); base::AutoLock lock_scope(lock_);
if (data_.file_contents_content_disposition.empty())
return CefString();
base::Optional<base::FilePath> filename = base::Optional<base::FilePath> filename =
data_.GetSafeFilenameForImageFileContents(); data_.GetSafeFilenameForImageFileContents();
return filename ? CefString(filename->value()) : CefString(); return filename ? CefString(filename->value()) : CefString();

View File

@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "libcef/common/main_delegate.h" #include "libcef/common/main_delegate.h"
#include "libcef/browser/browser_message_loop.h"
#include "libcef/browser/content_browser_client.h" #include "libcef/browser/content_browser_client.h"
#include "libcef/browser/context.h" #include "libcef/browser/context.h"
#include "libcef/common/cef_switches.h" #include "libcef/common/cef_switches.h"
@@ -12,6 +13,7 @@
#include "libcef/renderer/content_renderer_client.h" #include "libcef/renderer/content_renderer_client.h"
#include "libcef/utility/content_utility_client.h" #include "libcef/utility/content_utility_client.h"
#include "base/at_exit.h"
#include "base/base_switches.h" #include "base/base_switches.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
@@ -39,7 +41,6 @@
#include "pdf/pdf_ppapi.h" #include "pdf/pdf_ppapi.h"
#include "services/service_manager/sandbox/switches.h" #include "services/service_manager/sandbox/switches.h"
#include "ui/base/layout.h" #include "ui/base/layout.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h" #include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
@@ -280,6 +281,14 @@ class CefUIThread : public base::Thread {
browser_runner_->Shutdown(); browser_runner_->Shutdown();
browser_runner_.reset(NULL); browser_runner_.reset(NULL);
// Release MessagePump resources registered with the AtExitManager.
base::MessageLoop* ml = const_cast<base::MessageLoop*>(message_loop());
base::MessageLoopCurrent::UnbindFromCurrentThreadInternal(ml);
ml->ReleasePump();
// Run exit callbacks on the UI thread to avoid sequence check failures.
base::AtExitManager::ProcessCallbacksNow();
#if defined(OS_WIN) #if defined(OS_WIN)
// Closes the COM library on the current thread. CoInitialize must // Closes the COM library on the current thread. CoInitialize must
// be balanced by a corresponding call to CoUninitialize. // be balanced by a corresponding call to CoUninitialize.
@@ -304,6 +313,11 @@ CefMainDelegate::CefMainDelegate(CefRefPtr<CefApp> application)
CefMainDelegate::~CefMainDelegate() {} CefMainDelegate::~CefMainDelegate() {}
void CefMainDelegate::PreCreateMainMessageLoop() {
// Create the main message loop.
message_loop_.reset(new CefBrowserMessageLoop());
}
bool CefMainDelegate::BasicStartupComplete(int* exit_code) { bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::string process_type = std::string process_type =
@@ -629,6 +643,9 @@ void CefMainDelegate::ShutdownBrowser() {
browser_runner_->Shutdown(); browser_runner_->Shutdown();
browser_runner_.reset(NULL); browser_runner_.reset(NULL);
} }
message_loop_.reset();
if (ui_thread_.get()) { if (ui_thread_.get()) {
// Blocks until the thread has stopped. // Blocks until the thread has stopped.
ui_thread_->Stop(); ui_thread_->Stop();

View File

@@ -16,6 +16,7 @@
namespace base { namespace base {
class CommandLine; class CommandLine;
class MessageLoop;
class Thread; class Thread;
} // namespace base } // namespace base
@@ -32,6 +33,7 @@ class CefMainDelegate : public content::ContentMainDelegate {
explicit CefMainDelegate(CefRefPtr<CefApp> application); explicit CefMainDelegate(CefRefPtr<CefApp> application);
~CefMainDelegate() override; ~CefMainDelegate() override;
void PreCreateMainMessageLoop() override;
bool BasicStartupComplete(int* exit_code) override; bool BasicStartupComplete(int* exit_code) override;
void PreSandboxStartup() override; void PreSandboxStartup() override;
void SandboxInitialized(const std::string& process_type) override; void SandboxInitialized(const std::string& process_type) override;
@@ -55,6 +57,7 @@ class CefMainDelegate : public content::ContentMainDelegate {
private: private:
void InitializeResourceBundle(); void InitializeResourceBundle();
std::unique_ptr<base::MessageLoop> message_loop_;
std::unique_ptr<content::BrowserMainRunner> browser_runner_; std::unique_ptr<content::BrowserMainRunner> browser_runner_;
std::unique_ptr<base::Thread> ui_thread_; std::unique_ptr<base::Thread> ui_thread_;

View File

@@ -3,8 +3,13 @@
// can be found in the LICENSE file. // can be found in the LICENSE file.
#include "libcef/common/net/net_resource_provider.h" #include "libcef/common/net/net_resource_provider.h"
#include "libcef/common/content_client.h"
#include "chrome/common/net/net_resource_provider.h"
base::StringPiece NetResourceProvider(int key) { base::StringPiece NetResourceProvider(int key) {
return CefContentClient::Get()->GetDataResource(key, ui::SCALE_FACTOR_NONE); // Chrome performs substitution of localized strings for directory listings.
base::StringPiece value = chrome_common_net::NetResourceProvider(key);
if (value.empty())
LOG(ERROR) << "No data resource available for id " << key;
return value;
} }

View File

@@ -314,6 +314,8 @@ class V8TrackArrayBuffer : public CefTrackNode {
buffer_(buffer), buffer_(buffer),
release_callback_(release_callback) { release_callback_(release_callback) {
DCHECK(isolate_); DCHECK(isolate_);
isolate_->AdjustAmountOfExternalAllocatedMemory(
static_cast<int>(sizeof(V8TrackArrayBuffer)));
} }
~V8TrackArrayBuffer() { ~V8TrackArrayBuffer() {
@@ -330,6 +332,13 @@ class V8TrackArrayBuffer : public CefTrackNode {
void Neuter() { buffer_ = nullptr; } void Neuter() { buffer_ = nullptr; }
// Attach this track object to the specified V8 object.
void AttachTo(v8::Local<v8::Context> context,
v8::Local<v8::ArrayBuffer> arrayBuffer) {
SetPrivate(context, arrayBuffer, kCefTrackObject,
v8::External::New(isolate_, this));
}
// Retrieve the track object for the specified V8 object. // Retrieve the track object for the specified V8 object.
static V8TrackArrayBuffer* Unwrap(v8::Local<v8::Context> context, static V8TrackArrayBuffer* Unwrap(v8::Local<v8::Context> context,
v8::Local<v8::Object> object) { v8::Local<v8::Object> object) {
@@ -341,35 +350,10 @@ class V8TrackArrayBuffer : public CefTrackNode {
return nullptr; return nullptr;
} }
// Attach this track object to the specified V8 object.
void AttachTo(v8::Local<v8::Context> context,
v8::Local<v8::ArrayBuffer> arrayBuffer) {
isolate_->AdjustAmountOfExternalAllocatedMemory(
static_cast<int>(sizeof(V8TrackArrayBuffer)));
SetPrivate(context, arrayBuffer, kCefTrackObject,
v8::External::New(isolate_, this));
handle_.Reset(isolate_, arrayBuffer);
handle_.SetWeak(this, FirstWeakCallback, v8::WeakCallbackType::kParameter);
handle_.MarkIndependent();
}
private: private:
static void FirstWeakCallback(
const v8::WeakCallbackInfo<V8TrackArrayBuffer>& data) {
V8TrackArrayBuffer* wrapper = data.GetParameter();
if (wrapper->buffer_ != nullptr) {
wrapper->release_callback_->ReleaseBuffer(wrapper->buffer_);
wrapper->buffer_ = nullptr;
}
wrapper->handle_.Reset();
}
v8::Isolate* isolate_; v8::Isolate* isolate_;
void* buffer_; void* buffer_;
CefRefPtr<CefV8ArrayBufferReleaseCallback> release_callback_; CefRefPtr<CefV8ArrayBufferReleaseCallback> release_callback_;
v8::Persistent<v8::ArrayBuffer> handle_;
}; };
// Object wrapped in a v8::External and passed as the Data argument to // Object wrapped in a v8::External and passed as the Data argument to

View File

@@ -47,6 +47,10 @@ patches = [
# #
# Revert change that removes MessageLoopForUI constructor. # Revert change that removes MessageLoopForUI constructor.
# https://chromium-review.googlesource.com/751322 # https://chromium-review.googlesource.com/751322
#
# Add MessageLoop::ReleasePump to fix crashes during shutdown with multi-
# threaded message loop mode.
# https://bitbucket.org/chromiumembedded/cef/issues/2362
'name': 'message_loop', 'name': 'message_loop',
}, },
{ {
@@ -120,12 +124,6 @@ patches = [
# https://codereview.chromium.org/208313009 # https://codereview.chromium.org/208313009
'name': 'ui_dragdrop_355390', 'name': 'ui_dragdrop_355390',
}, },
{
# Windows: Fix AtExitManager assertion on *ServiceFactory destruction during
# multi-threaded message loop shutdown.
# https://bitbucket.org/chromiumembedded/cef/issues/1680
'name': 'service_factory_1680',
},
{ {
# Make URLRequest::set_is_pending() public so that it can be called from # Make URLRequest::set_is_pending() public so that it can be called from
# CefRequestInterceptor::MaybeInterceptResponse(). # CefRequestInterceptor::MaybeInterceptResponse().
@@ -329,6 +327,11 @@ patches = [
# https://bitbucket.org/chromiumembedded/cef/issues/2256 # https://bitbucket.org/chromiumembedded/cef/issues/2256
'name': 'linux_build', 'name': 'linux_build',
}, },
{
# Linux: Remove GTK build dependency.
# https://bitbucket.org/chromiumembedded/cef/issues/2014
'name': 'linux_gtk_2014',
},
{ {
# Changes necessary to support for chrome extensions: # Changes necessary to support for chrome extensions:
# (a) Add a new ExtensionHost constructor that allows CEF to create the # (a) Add a new ExtensionHost constructor that allows CEF to create the
@@ -372,9 +375,25 @@ patches = [
# https://bitbucket.org/chromiumembedded/cef/issues/2466 # https://bitbucket.org/chromiumembedded/cef/issues/2466
'name': 'linux_poll_2466', 'name': 'linux_poll_2466',
}, },
{
# Allow ResourceBundle creation/destruction on the main thread and usage on
# the UI thread.
# https://bitbucket.org/chromiumembedded/cef/issues/2398
'name': 'resource_bundle_2512',
},
{ {
# Fix VR target dependencies. # Fix VR target dependencies.
# https://bugs.chromium.org/p/chromium/issues/detail?id=873170 # https://bugs.chromium.org/p/chromium/issues/detail?id=873170
'name': 'vr_build_873170', 'name': 'vr_build_873170',
},
{
# Fix redraw of OSR PDF viewer.
# https://bitbucket.org/chromiumembedded/cef/issues/2507
'name': 'browser_child_frame_2507',
},
{
# macOS: Fix crash when showing a select popup with CefDoMessageLoopWork.
# https://bitbucket.org/chromiumembedded/cef/issues/2495
'name': 'message_pump_mac_2495',
} }
] ]

View File

@@ -0,0 +1,20 @@
diff --git content/browser/renderer_host/render_widget_host_view_child_frame.cc content/browser/renderer_host/render_widget_host_view_child_frame.cc
index ef607a087cdf..1320a4d274f6 100644
--- content/browser/renderer_host/render_widget_host_view_child_frame.cc
+++ content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -662,6 +662,7 @@ void RenderWidgetHostViewChildFrame::SubmitCompositorFrame(
"RenderWidgetHostViewChildFrame::OnSwapCompositorFrame");
support_->SubmitCompositorFrame(local_surface_id, std::move(frame),
std::move(hit_test_region_list));
+ ProcessFrameSwappedCallbacks();
}
void RenderWidgetHostViewChildFrame::OnDidNotProduceFrame(
@@ -945,7 +946,6 @@ void RenderWidgetHostViewChildFrame::OnFirstSurfaceActivation(
last_activated_surface_info_ = surface_info;
has_frame_ = true;
FirstSurfaceActivation(surface_info);
- ProcessFrameSwappedCallbacks();
}
void RenderWidgetHostViewChildFrame::OnFrameTokenChanged(uint32_t frame_token) {

View File

@@ -37,7 +37,7 @@ index e5f885ab4bc0..4573329ad26a 100644
attached_ = true; attached_ = true;
diff --git content/browser/frame_host/interstitial_page_impl.cc content/browser/frame_host/interstitial_page_impl.cc diff --git content/browser/frame_host/interstitial_page_impl.cc content/browser/frame_host/interstitial_page_impl.cc
index 26debf62bf01..973b88ff4752 100644 index 6a26f13d2466..af4a8f378d5e 100644
--- content/browser/frame_host/interstitial_page_impl.cc --- content/browser/frame_host/interstitial_page_impl.cc
+++ content/browser/frame_host/interstitial_page_impl.cc +++ content/browser/frame_host/interstitial_page_impl.cc
@@ -634,7 +634,7 @@ WebContentsView* InterstitialPageImpl::CreateWebContentsView() { @@ -634,7 +634,7 @@ WebContentsView* InterstitialPageImpl::CreateWebContentsView() {
@@ -79,10 +79,10 @@ index 41e44d5d658a..047c935d8ca2 100644
// Creates a new View that holds a popup and receives messages for it. // Creates a new View that holds a popup and receives messages for it.
virtual RenderWidgetHostViewBase* CreateViewForPopupWidget( virtual RenderWidgetHostViewBase* CreateViewForPopupWidget(
diff --git content/browser/web_contents/web_contents_view_aura.cc content/browser/web_contents/web_contents_view_aura.cc diff --git content/browser/web_contents/web_contents_view_aura.cc content/browser/web_contents/web_contents_view_aura.cc
index f3b19570771b..fe1df8339576 100644 index e471459007af..2edd94c79b4d 100644
--- content/browser/web_contents/web_contents_view_aura.cc --- content/browser/web_contents/web_contents_view_aura.cc
+++ content/browser/web_contents/web_contents_view_aura.cc +++ content/browser/web_contents/web_contents_view_aura.cc
@@ -796,7 +796,8 @@ void WebContentsViewAura::CreateView(const gfx::Size& initial_size, @@ -811,7 +811,8 @@ void WebContentsViewAura::CreateView(const gfx::Size& initial_size,
} }
RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget( RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
@@ -92,7 +92,7 @@ index f3b19570771b..fe1df8339576 100644
if (render_widget_host->GetView()) { if (render_widget_host->GetView()) {
// During testing, the view will already be set up in most cases to the // During testing, the view will already be set up in most cases to the
// test view, so we don't want to clobber it with a real one. To verify that // test view, so we don't want to clobber it with a real one. To verify that
@@ -808,6 +809,7 @@ RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget( @@ -823,6 +824,7 @@ RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
render_widget_host->GetView()); render_widget_host->GetView());
} }

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn
index ae76265b33a6..a3b7580d0046 100644 index f37afc63467b..eb99c80f0516 100644
--- chrome/browser/BUILD.gn --- chrome/browser/BUILD.gn
+++ chrome/browser/BUILD.gn +++ chrome/browser/BUILD.gn
@@ -8,6 +8,7 @@ import("//build/config/features.gni") @@ -8,6 +8,7 @@ import("//build/config/features.gni")
@@ -10,7 +10,7 @@ index ae76265b33a6..a3b7580d0046 100644
import("//chrome/common/features.gni") import("//chrome/common/features.gni")
import("//components/feature_engagement/features.gni") import("//components/feature_engagement/features.gni")
import("//components/feed/features.gni") import("//components/feed/features.gni")
@@ -1689,6 +1690,7 @@ jumbo_split_static_library("browser") { @@ -1691,6 +1692,7 @@ jumbo_split_static_library("browser") {
"//base:i18n", "//base:i18n",
"//base/allocator:buildflags", "//base/allocator:buildflags",
"//cc", "//cc",
@@ -18,7 +18,7 @@ index ae76265b33a6..a3b7580d0046 100644
"//chrome:extra_resources", "//chrome:extra_resources",
"//chrome:resources", "//chrome:resources",
"//chrome:strings", "//chrome:strings",
@@ -1963,6 +1965,10 @@ jumbo_split_static_library("browser") { @@ -1965,6 +1967,10 @@ jumbo_split_static_library("browser") {
] ]
} }
@@ -29,3 +29,12 @@ index ae76265b33a6..a3b7580d0046 100644
if (is_android) { if (is_android) {
sources += [ sources += [
"after_startup_task_utils_android.cc", "after_startup_task_utils_android.cc",
@@ -3508,7 +3514,7 @@ jumbo_split_static_library("browser") {
]
}
- if (use_aura && !use_ozone && is_desktop_linux) {
+ if (use_aura && !use_ozone && is_desktop_linux && use_gtk) {
deps += [ "//chrome/browser/ui/libgtkui" ]
}

View File

@@ -71,10 +71,10 @@ index e8e76ce5b954..1dd338dd0142 100644
content::BrowserContext* GetBrowserContextRedirectedInIncognito( content::BrowserContext* GetBrowserContextRedirectedInIncognito(
content::BrowserContext* context); content::BrowserContext* context);
diff --git chrome/browser/profiles/profile_manager.cc chrome/browser/profiles/profile_manager.cc diff --git chrome/browser/profiles/profile_manager.cc chrome/browser/profiles/profile_manager.cc
index acd7501aef4a..b53fe5e32289 100644 index 351207fb8b55..97962af699b3 100644
--- chrome/browser/profiles/profile_manager.cc --- chrome/browser/profiles/profile_manager.cc
+++ chrome/browser/profiles/profile_manager.cc +++ chrome/browser/profiles/profile_manager.cc
@@ -382,7 +382,7 @@ ProfileManager::ProfileManager(const base::FilePath& user_data_dir) @@ -386,7 +386,7 @@ ProfileManager::ProfileManager(const base::FilePath& user_data_dir)
chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
content::NotificationService::AllSources()); content::NotificationService::AllSources());

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/plugins/plugin_info_host_impl.cc chrome/browser/plugins/plugin_info_host_impl.cc diff --git chrome/browser/plugins/plugin_info_host_impl.cc chrome/browser/plugins/plugin_info_host_impl.cc
index 52d374d1fe4e..1ac12af269c9 100644 index 52d374d1fe4e..c113ae8634e0 100644
--- chrome/browser/plugins/plugin_info_host_impl.cc --- chrome/browser/plugins/plugin_info_host_impl.cc
+++ chrome/browser/plugins/plugin_info_host_impl.cc +++ chrome/browser/plugins/plugin_info_host_impl.cc
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
@@ -22,39 +22,7 @@ index 52d374d1fe4e..1ac12af269c9 100644
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
#include "components/guest_view/browser/guest_view_base.h" #include "components/guest_view/browser/guest_view_base.h"
#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry.h"
@@ -74,12 +80,10 @@ namespace { @@ -99,6 +105,9 @@ bool IsPluginLoadingAccessibleResourceInWebView(
class PluginInfoHostImplShutdownNotifierFactory
: public BrowserContextKeyedServiceShutdownNotifierFactory {
public:
- static PluginInfoHostImplShutdownNotifierFactory* GetInstance() {
- return base::Singleton<PluginInfoHostImplShutdownNotifierFactory>::get();
- }
+ static PluginInfoHostImplShutdownNotifierFactory* GetInstance();
private:
- friend struct base::DefaultSingletonTraits<
+ friend struct base::LazyInstanceTraitsBase<
PluginInfoHostImplShutdownNotifierFactory>;
PluginInfoHostImplShutdownNotifierFactory()
@@ -91,6 +95,16 @@ class PluginInfoHostImplShutdownNotifierFactory
DISALLOW_COPY_AND_ASSIGN(PluginInfoHostImplShutdownNotifierFactory);
};
+base::LazyInstance<PluginInfoHostImplShutdownNotifierFactory>::Leaky
+ g_plugin_info_host_impl_shutdown_notifier_factory =
+ LAZY_INSTANCE_INITIALIZER;
+
+// static
+PluginInfoHostImplShutdownNotifierFactory*
+PluginInfoHostImplShutdownNotifierFactory::GetInstance() {
+ return g_plugin_info_host_impl_shutdown_notifier_factory.Pointer();
+}
+
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Returns whether a request from a plugin to load |resource| from a renderer
// with process id |process_id| is a request for an internal resource by an app
@@ -99,6 +113,9 @@ bool IsPluginLoadingAccessibleResourceInWebView(
extensions::ExtensionRegistry* extension_registry, extensions::ExtensionRegistry* extension_registry,
int process_id, int process_id,
const GURL& resource) { const GURL& resource) {
@@ -64,7 +32,7 @@ index 52d374d1fe4e..1ac12af269c9 100644
extensions::WebViewRendererState* renderer_state = extensions::WebViewRendererState* renderer_state =
extensions::WebViewRendererState::GetInstance(); extensions::WebViewRendererState::GetInstance();
std::string partition_id; std::string partition_id;
@@ -128,12 +145,16 @@ bool IsPluginLoadingAccessibleResourceInWebView( @@ -128,12 +137,16 @@ bool IsPluginLoadingAccessibleResourceInWebView(
PluginInfoHostImpl::Context::Context(int render_process_id, Profile* profile) PluginInfoHostImpl::Context::Context(int render_process_id, Profile* profile)
: render_process_id_(render_process_id), : render_process_id_(render_process_id),
resource_context_(profile->GetResourceContext()), resource_context_(profile->GetResourceContext()),
@@ -84,7 +52,7 @@ index 52d374d1fe4e..1ac12af269c9 100644
allow_outdated_plugins_.Init(prefs::kPluginsAllowOutdated, allow_outdated_plugins_.Init(prefs::kPluginsAllowOutdated,
profile->GetPrefs()); profile->GetPrefs());
allow_outdated_plugins_.MoveToThread( allow_outdated_plugins_.MoveToThread(
@@ -232,6 +253,7 @@ void PluginInfoHostImpl::PluginsLoaded( @@ -232,6 +245,7 @@ void PluginInfoHostImpl::PluginsLoaded(
plugin_metadata->identifier(), &output->status); plugin_metadata->identifier(), &output->status);
} }
@@ -92,7 +60,7 @@ index 52d374d1fe4e..1ac12af269c9 100644
if (output->status == chrome::mojom::PluginStatus::kNotFound) { if (output->status == chrome::mojom::PluginStatus::kNotFound) {
// Check to see if the component updater can fetch an implementation. // Check to see if the component updater can fetch an implementation.
base::PostTaskAndReplyWithResult( base::PostTaskAndReplyWithResult(
@@ -243,7 +265,9 @@ void PluginInfoHostImpl::PluginsLoaded( @@ -243,7 +257,9 @@ void PluginInfoHostImpl::PluginsLoaded(
base::BindOnce(&PluginInfoHostImpl::ComponentPluginLookupDone, this, base::BindOnce(&PluginInfoHostImpl::ComponentPluginLookupDone, this,
params, std::move(output), std::move(callback), params, std::move(output), std::move(callback),
std::move(plugin_metadata))); std::move(plugin_metadata)));
@@ -103,7 +71,7 @@ index 52d374d1fe4e..1ac12af269c9 100644
GetPluginInfoFinish(params, std::move(output), std::move(callback), GetPluginInfoFinish(params, std::move(output), std::move(callback),
std::move(plugin_metadata)); std::move(plugin_metadata));
} }
@@ -256,6 +280,14 @@ void PluginInfoHostImpl::Context::DecidePluginStatus( @@ -256,6 +272,14 @@ void PluginInfoHostImpl::Context::DecidePluginStatus(
PluginMetadata::SecurityStatus security_status, PluginMetadata::SecurityStatus security_status,
const std::string& plugin_identifier, const std::string& plugin_identifier,
chrome::mojom::PluginStatus* status) const { chrome::mojom::PluginStatus* status) const {
@@ -118,7 +86,7 @@ index 52d374d1fe4e..1ac12af269c9 100644
if (security_status == PluginMetadata::SECURITY_STATUS_FULLY_TRUSTED) { if (security_status == PluginMetadata::SECURITY_STATUS_FULLY_TRUSTED) {
*status = chrome::mojom::PluginStatus::kAllowed; *status = chrome::mojom::PluginStatus::kAllowed;
return; return;
@@ -379,16 +411,36 @@ bool PluginInfoHostImpl::Context::FindEnabledPlugin( @@ -379,16 +403,36 @@ bool PluginInfoHostImpl::Context::FindEnabledPlugin(
return false; return false;
} }
@@ -157,7 +125,7 @@ index 52d374d1fe4e..1ac12af269c9 100644
// If we broke out of the loop, we have found an enabled plugin. // If we broke out of the loop, we have found an enabled plugin.
bool enabled = i < matching_plugins.size(); bool enabled = i < matching_plugins.size();
diff --git chrome/renderer/chrome_content_renderer_client.cc chrome/renderer/chrome_content_renderer_client.cc diff --git chrome/renderer/chrome_content_renderer_client.cc chrome/renderer/chrome_content_renderer_client.cc
index 78925a9dc0f0..30ef27e50bf7 100644 index d3f9d5ebe197..f3f1ef7750d5 100644
--- chrome/renderer/chrome_content_renderer_client.cc --- chrome/renderer/chrome_content_renderer_client.cc
+++ chrome/renderer/chrome_content_renderer_client.cc +++ chrome/renderer/chrome_content_renderer_client.cc
@@ -796,6 +796,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( @@ -796,6 +796,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(

View File

@@ -26,7 +26,7 @@ index 642fff3b4367..45faeed249c0 100644
} else { } else {
DCHECK(context_provider); DCHECK(context_provider);
diff --git ui/compositor/compositor.h ui/compositor/compositor.h diff --git ui/compositor/compositor.h ui/compositor/compositor.h
index a974ea654834..cfb3ff7f8a0c 100644 index a1b6716fc79f..6ec79ea0fab4 100644
--- ui/compositor/compositor.h --- ui/compositor/compositor.h
+++ ui/compositor/compositor.h +++ ui/compositor/compositor.h
@@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@

View File

@@ -64,10 +64,10 @@ index 569e6112d86b..41599944688a 100644
} }
diff --git chrome/browser/ui/views/frame/browser_root_view.cc chrome/browser/ui/views/frame/browser_root_view.cc diff --git chrome/browser/ui/views/frame/browser_root_view.cc chrome/browser/ui/views/frame/browser_root_view.cc
index d4d56c7c6a96..1ec4de7d5fd3 100644 index 77738cb5bec9..a8fbabe4b10f 100644
--- chrome/browser/ui/views/frame/browser_root_view.cc --- chrome/browser/ui/views/frame/browser_root_view.cc
+++ chrome/browser/ui/views/frame/browser_root_view.cc +++ chrome/browser/ui/views/frame/browser_root_view.cc
@@ -66,7 +66,7 @@ void OnFindURLMimeType(const GURL& url, @@ -69,7 +69,7 @@ void OnFindURLMimeType(const GURL& url,
content::PluginService::GetInstance()->GetPluginInfo( content::PluginService::GetInstance()->GetPluginInfo(
-1, // process ID -1, // process ID
MSG_ROUTING_NONE, // routing ID MSG_ROUTING_NONE, // routing ID
@@ -77,7 +77,7 @@ index d4d56c7c6a96..1ec4de7d5fd3 100644
} }
diff --git content/browser/frame_host/navigation_handle_impl.cc content/browser/frame_host/navigation_handle_impl.cc diff --git content/browser/frame_host/navigation_handle_impl.cc content/browser/frame_host/navigation_handle_impl.cc
index 72e60fdbe27c..8906cc6a598a 100644 index 6bc8930b7d82..76197c5dbe12 100644
--- content/browser/frame_host/navigation_handle_impl.cc --- content/browser/frame_host/navigation_handle_impl.cc
+++ content/browser/frame_host/navigation_handle_impl.cc +++ content/browser/frame_host/navigation_handle_impl.cc
@@ -401,12 +401,6 @@ net::Error NavigationHandleImpl::GetNetErrorCode() { @@ -401,12 +401,6 @@ net::Error NavigationHandleImpl::GetNetErrorCode() {
@@ -94,10 +94,10 @@ index 72e60fdbe27c..8906cc6a598a 100644
"WillFailRequest state should come before WillProcessResponse"); "WillFailRequest state should come before WillProcessResponse");
return render_frame_host_; return render_frame_host_;
diff --git content/browser/frame_host/render_frame_host_impl.cc content/browser/frame_host/render_frame_host_impl.cc diff --git content/browser/frame_host/render_frame_host_impl.cc content/browser/frame_host/render_frame_host_impl.cc
index 60b610202e7d..b14da4aba2f0 100644 index e67018e0f809..acfb47dd16bd 100644
--- content/browser/frame_host/render_frame_host_impl.cc --- content/browser/frame_host/render_frame_host_impl.cc
+++ content/browser/frame_host/render_frame_host_impl.cc +++ content/browser/frame_host/render_frame_host_impl.cc
@@ -1671,6 +1671,7 @@ void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError( @@ -1685,6 +1685,7 @@ void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError(
if (GetNavigationHandle()) { if (GetNavigationHandle()) {
GetNavigationHandle()->set_net_error_code( GetNavigationHandle()->set_net_error_code(
static_cast<net::Error>(params.error_code)); static_cast<net::Error>(params.error_code));
@@ -105,7 +105,7 @@ index 60b610202e7d..b14da4aba2f0 100644
} }
frame_tree_node_->navigator()->DidFailProvisionalLoadWithError(this, params); frame_tree_node_->navigator()->DidFailProvisionalLoadWithError(this, params);
@@ -4115,9 +4116,9 @@ void RenderFrameHostImpl::CommitNavigation( @@ -4132,9 +4133,9 @@ void RenderFrameHostImpl::CommitNavigation(
// is used. Currently we have this here to make sure we have non-racy // is used. Currently we have this here to make sure we have non-racy
// situation (https://crbug.com/849929). // situation (https://crbug.com/849929).
DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService)); DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
@@ -117,7 +117,7 @@ index 60b610202e7d..b14da4aba2f0 100644
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE, BrowserThread::IO, FROM_HERE,
base::BindOnce(&PrefetchURLLoaderService::GetFactory, base::BindOnce(&PrefetchURLLoaderService::GetFactory,
@@ -4811,8 +4812,8 @@ bool RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryInternal( @@ -4828,8 +4829,8 @@ bool RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryInternal(
RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory( RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory(
this, false /* is_navigation */, false /* is_download */, this, false /* is_navigation */, false /* is_download */,
&default_factory_request); &default_factory_request);
@@ -129,10 +129,10 @@ index 60b610202e7d..b14da4aba2f0 100644
storage_partition->GetNetworkContext()->CreateURLLoaderFactory( storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
std::move(default_factory_request), std::move(params)); std::move(default_factory_request), std::move(params));
diff --git content/browser/frame_host/render_frame_message_filter.cc content/browser/frame_host/render_frame_message_filter.cc diff --git content/browser/frame_host/render_frame_message_filter.cc content/browser/frame_host/render_frame_message_filter.cc
index 2f32390f0b45..6324f0f738e8 100644 index dfd9bb1aa8c9..1b8d91f88541 100644
--- content/browser/frame_host/render_frame_message_filter.cc --- content/browser/frame_host/render_frame_message_filter.cc
+++ content/browser/frame_host/render_frame_message_filter.cc +++ content/browser/frame_host/render_frame_message_filter.cc
@@ -629,6 +629,7 @@ void RenderFrameMessageFilter::GetCookies(int render_frame_id, @@ -635,6 +635,7 @@ void RenderFrameMessageFilter::GetCookies(int render_frame_id,
void RenderFrameMessageFilter::OnGetPluginInfo( void RenderFrameMessageFilter::OnGetPluginInfo(
int render_frame_id, int render_frame_id,
const GURL& url, const GURL& url,
@@ -140,7 +140,7 @@ index 2f32390f0b45..6324f0f738e8 100644
const url::Origin& main_frame_origin, const url::Origin& main_frame_origin,
const std::string& mime_type, const std::string& mime_type,
bool* found, bool* found,
@@ -637,8 +638,8 @@ void RenderFrameMessageFilter::OnGetPluginInfo( @@ -643,8 +644,8 @@ void RenderFrameMessageFilter::OnGetPluginInfo(
bool allow_wildcard = true; bool allow_wildcard = true;
*found = plugin_service_->GetPluginInfo( *found = plugin_service_->GetPluginInfo(
render_process_id_, render_frame_id, resource_context_, url, render_process_id_, render_frame_id, resource_context_, url,
@@ -152,10 +152,10 @@ index 2f32390f0b45..6324f0f738e8 100644
void RenderFrameMessageFilter::OnOpenChannelToPepperPlugin( void RenderFrameMessageFilter::OnOpenChannelToPepperPlugin(
diff --git content/browser/frame_host/render_frame_message_filter.h content/browser/frame_host/render_frame_message_filter.h diff --git content/browser/frame_host/render_frame_message_filter.h content/browser/frame_host/render_frame_message_filter.h
index 9716b2008062..362990246f97 100644 index a661ac526652..73c3a7077ddf 100644
--- content/browser/frame_host/render_frame_message_filter.h --- content/browser/frame_host/render_frame_message_filter.h
+++ content/browser/frame_host/render_frame_message_filter.h +++ content/browser/frame_host/render_frame_message_filter.h
@@ -144,6 +144,7 @@ class CONTENT_EXPORT RenderFrameMessageFilter @@ -147,6 +147,7 @@ class CONTENT_EXPORT RenderFrameMessageFilter
#if BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS)
void OnGetPluginInfo(int render_frame_id, void OnGetPluginInfo(int render_frame_id,
const GURL& url, const GURL& url,
@@ -364,10 +364,10 @@ index 88efca34d574..565f24148f7b 100644
virtual void FocusedNodeChanged(const blink::WebNode& node) {} virtual void FocusedNodeChanged(const blink::WebNode& node) {}
diff --git content/renderer/render_frame_impl.cc content/renderer/render_frame_impl.cc diff --git content/renderer/render_frame_impl.cc content/renderer/render_frame_impl.cc
index 81bd5faff7f4..f3bbf5f124de 100644 index 52270733e645..30d04dfab50d 100644
--- content/renderer/render_frame_impl.cc --- content/renderer/render_frame_impl.cc
+++ content/renderer/render_frame_impl.cc +++ content/renderer/render_frame_impl.cc
@@ -3577,7 +3577,8 @@ blink::WebPlugin* RenderFrameImpl::CreatePlugin( @@ -3585,7 +3585,8 @@ blink::WebPlugin* RenderFrameImpl::CreatePlugin(
std::string mime_type; std::string mime_type;
bool found = false; bool found = false;
Send(new FrameHostMsg_GetPluginInfo( Send(new FrameHostMsg_GetPluginInfo(
@@ -377,7 +377,7 @@ index 81bd5faff7f4..f3bbf5f124de 100644
params.mime_type.Utf8(), &found, &info, &mime_type)); params.mime_type.Utf8(), &found, &info, &mime_type));
if (!found) if (!found)
return nullptr; return nullptr;
@@ -3948,6 +3949,8 @@ void RenderFrameImpl::FrameDetached(DetachType type) { @@ -3965,6 +3966,8 @@ void RenderFrameImpl::FrameDetached(DetachType type) {
void RenderFrameImpl::FrameFocused() { void RenderFrameImpl::FrameFocused() {
Send(new FrameHostMsg_FrameFocused(routing_id_)); Send(new FrameHostMsg_FrameFocused(routing_id_));
@@ -387,10 +387,10 @@ index 81bd5faff7f4..f3bbf5f124de 100644
void RenderFrameImpl::WillCommitProvisionalLoad() { void RenderFrameImpl::WillCommitProvisionalLoad() {
diff --git content/renderer/render_thread_impl.cc content/renderer/render_thread_impl.cc diff --git content/renderer/render_thread_impl.cc content/renderer/render_thread_impl.cc
index e0208d440f55..77ea92adb54d 100644 index b36daaee097a..3d2163ea2853 100644
--- content/renderer/render_thread_impl.cc --- content/renderer/render_thread_impl.cc
+++ content/renderer/render_thread_impl.cc +++ content/renderer/render_thread_impl.cc
@@ -829,6 +829,8 @@ void RenderThreadImpl::Init() { @@ -828,6 +828,8 @@ void RenderThreadImpl::Init() {
StartServiceManagerConnection(); StartServiceManagerConnection();
@@ -400,10 +400,10 @@ index e0208d440f55..77ea92adb54d 100644
base::Bind(&RenderThreadImpl::OnRendererInterfaceRequest, base::Bind(&RenderThreadImpl::OnRendererInterfaceRequest,
base::Unretained(this))); base::Unretained(this)));
diff --git content/renderer/renderer_blink_platform_impl.cc content/renderer/renderer_blink_platform_impl.cc diff --git content/renderer/renderer_blink_platform_impl.cc content/renderer/renderer_blink_platform_impl.cc
index 8d7631fb756f..5239dde4a1c9 100644 index 4a594bd98bcd..79d3fdd29271 100644
--- content/renderer/renderer_blink_platform_impl.cc --- content/renderer/renderer_blink_platform_impl.cc
+++ content/renderer/renderer_blink_platform_impl.cc +++ content/renderer/renderer_blink_platform_impl.cc
@@ -1192,6 +1192,14 @@ void RendererBlinkPlatformImpl::RequestPurgeMemory() { @@ -1200,6 +1200,14 @@ void RendererBlinkPlatformImpl::RequestPurgeMemory() {
base::MemoryCoordinatorClientRegistry::GetInstance()->PurgeMemory(); base::MemoryCoordinatorClientRegistry::GetInstance()->PurgeMemory();
} }

View File

@@ -180,7 +180,7 @@ index ad1ef1bd0b8f..8014a61c5083 100644
// A weak pointer to the current or pending RenderViewHost. We don't access // A weak pointer to the current or pending RenderViewHost. We don't access
// this through the host_contents because we want to deal with the pending // this through the host_contents because we want to deal with the pending
diff --git extensions/browser/extensions_browser_client.h extensions/browser/extensions_browser_client.h diff --git extensions/browser/extensions_browser_client.h extensions/browser/extensions_browser_client.h
index 7e0c178e1e36..98066c8437a1 100644 index 5a2533dc788f..b21e25a9af25 100644
--- extensions/browser/extensions_browser_client.h --- extensions/browser/extensions_browser_client.h
+++ extensions/browser/extensions_browser_client.h +++ extensions/browser/extensions_browser_client.h
@@ -61,6 +61,7 @@ class ComponentExtensionResourceManager; @@ -61,6 +61,7 @@ class ComponentExtensionResourceManager;
@@ -191,7 +191,7 @@ index 7e0c178e1e36..98066c8437a1 100644
class ExtensionHostDelegate; class ExtensionHostDelegate;
class ExtensionPrefsObserver; class ExtensionPrefsObserver;
class ExtensionApiFrameIdMap; class ExtensionApiFrameIdMap;
@@ -132,6 +133,11 @@ class ExtensionsBrowserClient { @@ -133,6 +134,11 @@ class ExtensionsBrowserClient {
virtual content::BrowserContext* GetOriginalContext( virtual content::BrowserContext* GetOriginalContext(
content::BrowserContext* context) = 0; content::BrowserContext* context) = 0;
@@ -203,7 +203,7 @@ index 7e0c178e1e36..98066c8437a1 100644
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// Returns a user id hash from |context| or an empty string if no hash could // Returns a user id hash from |context| or an empty string if no hash could
// be extracted. // be extracted.
@@ -214,6 +220,14 @@ class ExtensionsBrowserClient { @@ -215,6 +221,14 @@ class ExtensionsBrowserClient {
virtual std::unique_ptr<ExtensionHostDelegate> virtual std::unique_ptr<ExtensionHostDelegate>
CreateExtensionHostDelegate() = 0; CreateExtensionHostDelegate() = 0;

View File

@@ -12,7 +12,7 @@ index 6fd17634ee87..0563b730a180 100644
# https://crbug.com/474506. # https://crbug.com/474506.
"//clank/java/BUILD.gn", "//clank/java/BUILD.gn",
diff --git BUILD.gn BUILD.gn diff --git BUILD.gn BUILD.gn
index fd7e05257f9a..89d9e6c53d06 100644 index abc4f97ce994..addd29dff7fb 100644
--- BUILD.gn --- BUILD.gn
+++ BUILD.gn +++ BUILD.gn
@@ -187,6 +187,7 @@ group("gn_all") { @@ -187,6 +187,7 @@ group("gn_all") {

View File

@@ -0,0 +1,170 @@
diff --git build/config/linux/gtk/BUILD.gn build/config/linux/gtk/BUILD.gn
index a2b40d82674e..fac0c1900ce8 100644
--- build/config/linux/gtk/BUILD.gn
+++ build/config/linux/gtk/BUILD.gn
@@ -4,8 +4,10 @@
import("//build/config/linux/gtk/gtk.gni")
import("//build/config/linux/pkg_config.gni")
+import("//build/config/ui.gni")
assert(is_linux, "This file should only be referenced on Linux")
+assert(use_gtk, "This file should only be referenced when GTK is enabled")
# GN doesn't check visibility for configs so we give this an obviously internal
# name to discourage random targets from accidentally depending on this and
diff --git build/config/ui.gni build/config/ui.gni
index 547b42fb5c66..0eae3470e1bb 100644
--- build/config/ui.gni
+++ build/config/ui.gni
@@ -37,6 +37,9 @@ declare_args() {
# True means the UI is built using the "views" framework.
toolkit_views = (is_mac || is_win || is_chromeos || use_aura) &&
!is_chromecast && !is_fuchsia
+
+ # Whether we should use GTK.
+ use_gtk = use_aura && is_linux
}
# Additional dependent variables -----------------------------------------------
diff --git chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
index d44c7feaabec..5f1992335a38 100644
--- chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
+++ chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.h"
#include "base/run_loop.h"
+#include "cef/libcef/features/features.h"
#include "chrome/browser/chrome_browser_main.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_service.h"
@@ -30,6 +31,7 @@
namespace {
+#if !BUILDFLAG(ENABLE_CEF)
ui::NativeTheme* GetNativeThemeForWindow(aura::Window* window) {
if (!window)
return nullptr;
@@ -54,6 +56,7 @@ ui::NativeTheme* GetNativeThemeForWindow(aura::Window* window) {
return ui::NativeTheme::GetInstanceForNativeUi();
}
+#endif // !BUILDFLAG(ENABLE_CEF)
} // namespace
@@ -67,9 +70,11 @@ ChromeBrowserMainExtraPartsViewsLinux::
}
void ChromeBrowserMainExtraPartsViewsLinux::PreEarlyInitialization() {
+#if !BUILDFLAG(ENABLE_CEF)
views::LinuxUI* gtk_ui = BuildGtkUi();
gtk_ui->SetNativeThemeOverride(base::Bind(&GetNativeThemeForWindow));
views::LinuxUI::SetInstance(gtk_ui);
+#endif
}
void ChromeBrowserMainExtraPartsViewsLinux::ToolkitInitialized() {
diff --git chrome/test/BUILD.gn chrome/test/BUILD.gn
index b0b7066b6b08..f9511166e283 100644
--- chrome/test/BUILD.gn
+++ chrome/test/BUILD.gn
@@ -3835,7 +3835,7 @@ test("unit_tests") {
"../browser/ui/input_method/input_method_engine_unittest.cc",
]
}
- if (!is_chromeos && !is_chromecast && is_linux) {
+ if (!is_chromeos && !is_chromecast && is_linux && use_gtk) {
sources +=
[ "../browser/ui/libgtkui/select_file_dialog_impl_gtk_unittest.cc" ]
deps += [ "//build/config/linux/gtk" ]
@@ -3856,7 +3856,7 @@ test("unit_tests") {
if (use_gio) {
configs += [ "//build/linux:gio_config" ]
}
- if (!is_chromeos && !use_ozone && is_linux) {
+ if (!is_chromeos && !use_ozone && is_linux && use_gtk) {
deps += [ "//chrome/browser/ui/libgtkui" ]
}
@@ -4978,7 +4978,7 @@ if (!is_android) {
# suites, it seems like one or another starts timing out too.
"../browser/ui/views/keyboard_access_browsertest.cc",
]
- if (!use_ozone) {
+ if (!use_ozone && use_gtk) {
sources += [
"../browser/ui/libgtkui/select_file_dialog_interactive_uitest.cc",
]
diff --git remoting/host/BUILD.gn remoting/host/BUILD.gn
index 563d8318c231..4795186b594c 100644
--- remoting/host/BUILD.gn
+++ remoting/host/BUILD.gn
@@ -336,7 +336,7 @@ static_library("host") {
"//build/config/linux:xrandr",
]
deps += [ "//remoting/host/linux:x11" ]
- if (is_desktop_linux) {
+ if (is_desktop_linux && use_gtk) {
deps += [ "//build/config/linux/gtk" ]
}
} else {
@@ -717,7 +717,7 @@ if (enable_me2me_host) {
deps += [ "//components/policy:generated" ]
}
- if (is_desktop_linux) {
+ if (is_desktop_linux && use_gtk) {
deps += [ "//build/config/linux/gtk" ]
}
if ((is_linux && !is_chromeos) || is_mac) {
diff --git remoting/host/it2me/BUILD.gn remoting/host/it2me/BUILD.gn
index 1d8b50d2320e..f72d8a1f3ba3 100644
--- remoting/host/it2me/BUILD.gn
+++ remoting/host/it2me/BUILD.gn
@@ -53,7 +53,7 @@ source_set("common") {
"//remoting/resources",
"//remoting/signaling",
]
- if (is_desktop_linux) {
+ if (is_desktop_linux && use_gtk) {
deps += [
"//build/config/linux/gtk",
@@ -247,7 +247,7 @@ if (!is_chromeos && enable_remoting_host) {
}
}
- if (is_desktop_linux) {
+ if (is_desktop_linux && use_gtk) {
deps += [ "//build/config/linux/gtk" ]
}
}
diff --git remoting/host/linux/BUILD.gn remoting/host/linux/BUILD.gn
index fa24d0b9b4ab..3ca8743bb4c7 100644
--- remoting/host/linux/BUILD.gn
+++ remoting/host/linux/BUILD.gn
@@ -98,7 +98,7 @@ source_set("linux") {
if (use_x11) {
deps += [ ":x11" ]
}
- if (is_desktop_linux) {
+ if (is_desktop_linux && use_gtk) {
deps += [ "//build/config/linux/gtk" ]
}
}
diff --git remoting/test/BUILD.gn remoting/test/BUILD.gn
index 267049123534..3672603366df 100644
--- remoting/test/BUILD.gn
+++ remoting/test/BUILD.gn
@@ -197,7 +197,7 @@ if (enable_remoting_host && !is_android && !is_chromeos) {
":it2me_standalone_host",
]
- if (is_desktop_linux) {
+ if (is_desktop_linux && use_gtk) {
deps += [ "//build/config/linux/gtk" ]
}

View File

@@ -13,10 +13,20 @@ index ff55a15ce0f0..30a903dffcdc 100644
MessageLoopCurrentForUI MessageLoopForUI::current() { MessageLoopCurrentForUI MessageLoopForUI::current() {
return MessageLoopCurrentForUI::Get(); return MessageLoopCurrentForUI::Get();
diff --git base/message_loop/message_loop.h base/message_loop/message_loop.h diff --git base/message_loop/message_loop.h base/message_loop/message_loop.h
index dae6c35eab00..adbd6e72c7a3 100644 index dae6c35eab00..f1b59fccd4c0 100644
--- base/message_loop/message_loop.h --- base/message_loop/message_loop.h
+++ base/message_loop/message_loop.h +++ base/message_loop/message_loop.h
@@ -366,6 +366,7 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate, @@ -197,6 +197,9 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate,
// Runs the specified PendingTask.
void RunTask(PendingTask* pending_task);
+ // Called from Thread::CleanUp() to release resources.
+ void ReleasePump() { pump_ = nullptr; }
+
//----------------------------------------------------------------------------
protected:
std::unique_ptr<MessagePump> pump_;
@@ -366,6 +369,7 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate,
class BASE_EXPORT MessageLoopForUI : public MessageLoop { class BASE_EXPORT MessageLoopForUI : public MessageLoop {
public: public:
explicit MessageLoopForUI(Type type = TYPE_UI); explicit MessageLoopForUI(Type type = TYPE_UI);
@@ -24,6 +34,19 @@ index dae6c35eab00..adbd6e72c7a3 100644
// TODO(gab): Mass migrate callers to MessageLoopCurrentForUI::Get()/IsSet(). // TODO(gab): Mass migrate callers to MessageLoopCurrentForUI::Get()/IsSet().
static MessageLoopCurrentForUI current(); static MessageLoopCurrentForUI current();
diff --git base/message_loop/message_loop_current.cc base/message_loop/message_loop_current.cc
index ece6b92ca3a3..3925cdd3ad7f 100644
--- base/message_loop/message_loop_current.cc
+++ base/message_loop/message_loop_current.cc
@@ -43,6 +43,8 @@ void MessageLoopCurrent::AddDestructionObserver(
void MessageLoopCurrent::RemoveDestructionObserver(
DestructionObserver* destruction_observer) {
+ if (!current_)
+ return;
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
current_->destruction_observers_.RemoveObserver(destruction_observer);
}
diff --git base/message_loop/message_loop_current.h base/message_loop/message_loop_current.h diff --git base/message_loop/message_loop_current.h base/message_loop/message_loop_current.h
index d623cbc7f7b2..04d83792f98d 100644 index d623cbc7f7b2..04d83792f98d 100644
--- base/message_loop/message_loop_current.h --- base/message_loop/message_loop_current.h

View File

@@ -0,0 +1,24 @@
diff --git base/message_loop/message_pump_mac.mm base/message_loop/message_pump_mac.mm
index fb2520179995..165a8d4b4b29 100644
--- base/message_loop/message_pump_mac.mm
+++ base/message_loop/message_pump_mac.mm
@@ -761,7 +761,8 @@ explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) :
#else
ScopedPumpMessagesInPrivateModes::ScopedPumpMessagesInPrivateModes() {
- DCHECK(g_app_pump);
+ if (!g_app_pump)
+ return;
DCHECK_EQ(kNSApplicationModalSafeModeMask, g_app_pump->GetModeMask());
// Pumping events in private runloop modes is known to interact badly with
// app modal windows like NSAlert.
@@ -770,7 +771,8 @@ explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) :
}
ScopedPumpMessagesInPrivateModes::~ScopedPumpMessagesInPrivateModes() {
- DCHECK(g_app_pump);
+ if (!g_app_pump)
+ return;
g_app_pump->SetModeMask(kNSApplicationModalSafeModeMask);
}

View File

@@ -23,10 +23,10 @@ index bd8facb2d850..fba8020aa90e 100644
record_whole_document(false), record_whole_document(false),
save_previous_document_resources(SavePreviousDocumentResources::NEVER), save_previous_document_resources(SavePreviousDocumentResources::NEVER),
diff --git content/public/common/web_preferences.h content/public/common/web_preferences.h diff --git content/public/common/web_preferences.h content/public/common/web_preferences.h
index e21f52c4dde5..b7da33f1b9a3 100644 index eba70c162af1..59247078aa81 100644
--- content/public/common/web_preferences.h --- content/public/common/web_preferences.h
+++ content/public/common/web_preferences.h +++ content/public/common/web_preferences.h
@@ -198,6 +198,7 @@ struct CONTENT_EXPORT WebPreferences { @@ -203,6 +203,7 @@ struct CONTENT_EXPORT WebPreferences {
bool spatial_navigation_enabled; bool spatial_navigation_enabled;
bool use_solid_color_scrollbars; bool use_solid_color_scrollbars;
bool navigate_on_drag_drop; bool navigate_on_drag_drop;
@@ -35,10 +35,10 @@ index e21f52c4dde5..b7da33f1b9a3 100644
bool record_whole_document; bool record_whole_document;
SavePreviousDocumentResources save_previous_document_resources; SavePreviousDocumentResources save_previous_document_resources;
diff --git content/renderer/render_view_impl.cc content/renderer/render_view_impl.cc diff --git content/renderer/render_view_impl.cc content/renderer/render_view_impl.cc
index 059aaa640ef3..e2e0e58726b8 100644 index 215c4a750f04..6d82965a631d 100644
--- content/renderer/render_view_impl.cc --- content/renderer/render_view_impl.cc
+++ content/renderer/render_view_impl.cc +++ content/renderer/render_view_impl.cc
@@ -1308,6 +1308,7 @@ void RenderViewImpl::SendFrameStateUpdates() { @@ -1312,6 +1312,7 @@ void RenderViewImpl::SendFrameStateUpdates() {
void RenderViewImpl::ApplyWebPreferencesInternal(const WebPreferences& prefs, void RenderViewImpl::ApplyWebPreferencesInternal(const WebPreferences& prefs,
blink::WebView* web_view) { blink::WebView* web_view) {
ApplyWebPreferences(prefs, web_view); ApplyWebPreferences(prefs, web_view);

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
index 58bfe0e13733..371653fc39e8 100644 index ea8b1a687eb5..a154b1e3fd71 100644
--- chrome/browser/ui/BUILD.gn --- chrome/browser/ui/BUILD.gn
+++ chrome/browser/ui/BUILD.gn +++ chrome/browser/ui/BUILD.gn
@@ -828,6 +828,7 @@ jumbo_split_static_library("ui") { @@ -828,6 +828,7 @@ jumbo_split_static_library("ui") {
@@ -10,6 +10,15 @@ index 58bfe0e13733..371653fc39e8 100644
"//chrome:extra_resources", "//chrome:extra_resources",
"//chrome:resources", "//chrome:resources",
"//chrome:strings", "//chrome:strings",
@@ -2714,7 +2715,7 @@ jumbo_split_static_library("ui") {
"views/frame/native_browser_frame_factory_ozone.cc",
]
} else {
- if (use_aura) {
+ if (use_aura && use_gtk) {
# This is the only component that can interact with gtk.
deps += [ "//chrome/browser/ui/libgtkui" ]
}
diff --git chrome/browser/ui/cocoa/applescript/tab_applescript.mm chrome/browser/ui/cocoa/applescript/tab_applescript.mm diff --git chrome/browser/ui/cocoa/applescript/tab_applescript.mm chrome/browser/ui/cocoa/applescript/tab_applescript.mm
index f0a489a0c3af..1bd1259e47e3 100644 index f0a489a0c3af..1bd1259e47e3 100644
--- chrome/browser/ui/cocoa/applescript/tab_applescript.mm --- chrome/browser/ui/cocoa/applescript/tab_applescript.mm

View File

@@ -0,0 +1,45 @@
diff --git ui/base/resource/resource_bundle.cc ui/base/resource/resource_bundle.cc
index 2a00d4e..d2328b7 100644
--- ui/base/resource/resource_bundle.cc
+++ ui/base/resource/resource_bundle.cc
@@ -737,6 +737,12 @@ ResourceBundle::ResourceBundle(Delegate* delegate)
: delegate_(delegate),
locale_resources_data_lock_(new base::Lock),
max_scale_factor_(SCALE_FACTOR_100P) {
+ // With CEF's multi-threaded mode the ResourceBundle may be created on the
+ // main thread and then accessed on the UI thread. Allow the SequenceChecker
+ // to re-bind on the UI thread when CalledOnValidSequence() is called for the
+ // first time.
+ DETACH_FROM_SEQUENCE(sequence_checker_);
+
mangle_localized_strings_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kMangleLocalizedStrings);
}
@@ -746,6 +752,11 @@ ResourceBundle::~ResourceBundle() {
UnloadLocaleResources();
}
+void ResourceBundle::CleanupOnUIThread() {
+ FreeImages();
+ font_cache_.clear();
+}
+
// static
void ResourceBundle::InitSharedInstance(Delegate* delegate) {
DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice";
diff --git ui/base/resource/resource_bundle.h ui/base/resource/resource_bundle.h
index 422d84b..669522fd 100644
--- ui/base/resource/resource_bundle.h
+++ ui/base/resource/resource_bundle.h
@@ -150,6 +150,11 @@ class UI_BASE_EXPORT ResourceBundle {
// Return the global resource loader instance.
static ResourceBundle& GetSharedInstance();
+ // With CEF's multi-threaded mode the ResourceBundle may be created/destroyed
+ // on the main thread but accessed on the UI thread. Call this method on the
+ // UI thread to clean up resources before destruction.
+ void CleanupOnUIThread();
+
// Loads a secondary locale data pack using the given file region.
void LoadSecondaryLocaleDataWithPakFileRegion(
base::File pak_file,

View File

@@ -1,5 +1,5 @@
diff --git content/browser/renderer_host/render_widget_host_view_aura.cc content/browser/renderer_host/render_widget_host_view_aura.cc diff --git content/browser/renderer_host/render_widget_host_view_aura.cc content/browser/renderer_host/render_widget_host_view_aura.cc
index 126b857e541b..86dccf223b0a 100644 index b01698c81116..8196bc8f2e52 100644
--- content/browser/renderer_host/render_widget_host_view_aura.cc --- content/browser/renderer_host/render_widget_host_view_aura.cc
+++ content/browser/renderer_host/render_widget_host_view_aura.cc +++ content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -718,10 +718,12 @@ gfx::Rect RenderWidgetHostViewAura::GetViewBounds() const { @@ -718,10 +718,12 @@ gfx::Rect RenderWidgetHostViewAura::GetViewBounds() const {
@@ -19,7 +19,7 @@ index 126b857e541b..86dccf223b0a 100644
} }
void RenderWidgetHostViewAura::WindowTitleChanged() { void RenderWidgetHostViewAura::WindowTitleChanged() {
@@ -1932,6 +1934,15 @@ void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) { @@ -1936,6 +1938,15 @@ void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
if (frame_sink_id_.is_valid()) if (frame_sink_id_.is_valid())
window_->SetEmbedFrameSinkId(frame_sink_id_); window_->SetEmbedFrameSinkId(frame_sink_id_);

View File

@@ -1,143 +0,0 @@
diff --git chrome/browser/spellchecker/spellcheck_factory.cc chrome/browser/spellchecker/spellcheck_factory.cc
index 64b5243d510a..8ae3001f85fc 100644
--- chrome/browser/spellchecker/spellcheck_factory.cc
+++ chrome/browser/spellchecker/spellcheck_factory.cc
@@ -17,6 +17,13 @@
#include "services/service_manager/public/cpp/identity.h"
#include "ui/base/l10n/l10n_util.h"
+namespace {
+
+static base::LazyInstance<SpellcheckServiceFactory>::Leaky
+ g_spellcheck_service_factory = LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
// static
SpellcheckService* SpellcheckServiceFactory::GetForContext(
content::BrowserContext* context) {
@@ -37,7 +44,7 @@ SpellcheckService* SpellcheckServiceFactory::GetForRenderer(
// static
SpellcheckServiceFactory* SpellcheckServiceFactory::GetInstance() {
- return base::Singleton<SpellcheckServiceFactory>::get();
+ return g_spellcheck_service_factory.Pointer();
}
SpellcheckServiceFactory::SpellcheckServiceFactory()
diff --git chrome/browser/spellchecker/spellcheck_factory.h chrome/browser/spellchecker/spellcheck_factory.h
index fd4e6643725c..fcdbb8e4db88 100644
--- chrome/browser/spellchecker/spellcheck_factory.h
+++ chrome/browser/spellchecker/spellcheck_factory.h
@@ -7,7 +7,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/memory/singleton.h"
+#include "base/lazy_instance.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
class SpellcheckService;
@@ -31,7 +31,7 @@ class SpellcheckServiceFactory : public BrowserContextKeyedServiceFactory {
static SpellcheckServiceFactory* GetInstance();
private:
- friend struct base::DefaultSingletonTraits<SpellcheckServiceFactory>;
+ friend struct base::LazyInstanceTraitsBase<SpellcheckServiceFactory>;
SpellcheckServiceFactory();
~SpellcheckServiceFactory() override;
diff --git chrome/browser/supervised_user/supervised_user_settings_service_factory.cc chrome/browser/supervised_user/supervised_user_settings_service_factory.cc
index 173ac3132161..473e56161cca 100644
--- chrome/browser/supervised_user/supervised_user_settings_service_factory.cc
+++ chrome/browser/supervised_user/supervised_user_settings_service_factory.cc
@@ -9,6 +9,13 @@
#include "chrome/browser/supervised_user/supervised_user_settings_service.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
+namespace {
+
+base::LazyInstance<SupervisedUserSettingsServiceFactory>::Leaky
+ g_service_factory = LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
// static
SupervisedUserSettingsService*
SupervisedUserSettingsServiceFactory::GetForProfile(Profile* profile) {
@@ -19,7 +26,7 @@ SupervisedUserSettingsServiceFactory::GetForProfile(Profile* profile) {
// static
SupervisedUserSettingsServiceFactory*
SupervisedUserSettingsServiceFactory::GetInstance() {
- return base::Singleton<SupervisedUserSettingsServiceFactory>::get();
+ return g_service_factory.Pointer();
}
SupervisedUserSettingsServiceFactory::SupervisedUserSettingsServiceFactory()
diff --git chrome/browser/supervised_user/supervised_user_settings_service_factory.h chrome/browser/supervised_user/supervised_user_settings_service_factory.h
index 2907619549ba..f941fba363b5 100644
--- chrome/browser/supervised_user/supervised_user_settings_service_factory.h
+++ chrome/browser/supervised_user/supervised_user_settings_service_factory.h
@@ -5,7 +5,7 @@
#ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SETTINGS_SERVICE_FACTORY_H_
#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SETTINGS_SERVICE_FACTORY_H_
-#include "base/memory/singleton.h"
+#include "base/lazy_instance.h"
#include "chrome/browser/supervised_user/supervised_users.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
@@ -20,7 +20,7 @@ class SupervisedUserSettingsServiceFactory
static SupervisedUserSettingsServiceFactory* GetInstance();
private:
- friend struct base::DefaultSingletonTraits<
+ friend struct base::LazyInstanceTraitsBase<
SupervisedUserSettingsServiceFactory>;
SupervisedUserSettingsServiceFactory();
diff --git chrome/browser/ui/prefs/pref_watcher.cc chrome/browser/ui/prefs/pref_watcher.cc
index e38f8c50b10f..3b486f3b8daf 100644
--- chrome/browser/ui/prefs/pref_watcher.cc
+++ chrome/browser/ui/prefs/pref_watcher.cc
@@ -46,6 +46,9 @@ const char* const kWebPrefsToObserve[] = {
const int kWebPrefsToObserveLength = base::size(kWebPrefsToObserve);
+base::LazyInstance<PrefWatcherFactory>::Leaky g_pref_watcher_factory =
+ LAZY_INSTANCE_INITIALIZER;
+
} // namespace
// Watching all these settings per tab is slow when a user has a lot of tabs and
@@ -124,7 +127,7 @@ PrefWatcher* PrefWatcherFactory::GetForProfile(Profile* profile) {
// static
PrefWatcherFactory* PrefWatcherFactory::GetInstance() {
- return base::Singleton<PrefWatcherFactory>::get();
+ return g_pref_watcher_factory.Pointer();
}
PrefWatcherFactory::PrefWatcherFactory()
diff --git chrome/browser/ui/prefs/pref_watcher.h chrome/browser/ui/prefs/pref_watcher.h
index 061ca27681fa..0538f62f3f25 100644
--- chrome/browser/ui/prefs/pref_watcher.h
+++ chrome/browser/ui/prefs/pref_watcher.h
@@ -5,7 +5,7 @@
#ifndef CHROME_BROWSER_UI_PREFS_PREF_WATCHER_H_
#define CHROME_BROWSER_UI_PREFS_PREF_WATCHER_H_
-#include "base/memory/singleton.h"
+#include "base/lazy_instance.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
@@ -58,7 +58,7 @@ class PrefWatcherFactory : public BrowserContextKeyedServiceFactory {
static PrefWatcherFactory* GetInstance();
private:
- friend struct base::DefaultSingletonTraits<PrefWatcherFactory>;
+ friend struct base::LazyInstanceTraitsBase<PrefWatcherFactory>;
PrefWatcherFactory();
~PrefWatcherFactory() override;

View File

@@ -251,10 +251,10 @@ index 37cabf2c9ffa..a5165fdbfdf6 100644
CreateDownloadURLLoaderFactoryGetter(storage_partition, rfh, true); CreateDownloadURLLoaderFactoryGetter(storage_partition, rfh, true);
} }
diff --git content/browser/loader/navigation_url_loader_impl.cc content/browser/loader/navigation_url_loader_impl.cc diff --git content/browser/loader/navigation_url_loader_impl.cc content/browser/loader/navigation_url_loader_impl.cc
index d9034953e7f8..0e7c34daa4f8 100644 index 2c8e4c488be4..be77d11bf2ba 100644
--- content/browser/loader/navigation_url_loader_impl.cc --- content/browser/loader/navigation_url_loader_impl.cc
+++ content/browser/loader/navigation_url_loader_impl.cc +++ content/browser/loader/navigation_url_loader_impl.cc
@@ -1131,7 +1131,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController @@ -1173,7 +1173,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// path does as well for navigations. // path does as well for navigations.
bool has_plugin = PluginService::GetInstance()->GetPluginInfo( bool has_plugin = PluginService::GetInstance()->GetPluginInfo(
-1 /* render_process_id */, -1 /* render_frame_id */, resource_context_, -1 /* render_process_id */, -1 /* render_frame_id */, resource_context_,
@@ -263,7 +263,7 @@ index d9034953e7f8..0e7c34daa4f8 100644
false /* allow_wildcard */, &stale, &plugin, nullptr); false /* allow_wildcard */, &stale, &plugin, nullptr);
if (stale) { if (stale) {
@@ -1495,7 +1495,7 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl( @@ -1536,7 +1536,7 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
network::mojom::URLLoaderFactoryPtrInfo proxied_factory_info; network::mojom::URLLoaderFactoryPtrInfo proxied_factory_info;
network::mojom::URLLoaderFactoryRequest proxied_factory_request; network::mojom::URLLoaderFactoryRequest proxied_factory_request;
bool bypass_redirect_checks = false; bool bypass_redirect_checks = false;
@@ -599,10 +599,10 @@ index 51f91bdd7e2f..a67745058ed3 100644
std::move(subresource_loader_factories), service_worker_context_, std::move(subresource_loader_factories), service_worker_context_,
appcache_handle_core, appcache_handle_core,
diff --git content/browser/storage_partition_impl.h content/browser/storage_partition_impl.h diff --git content/browser/storage_partition_impl.h content/browser/storage_partition_impl.h
index 6f6c5c1e504a..097095a613dd 100644 index 78110a30b23a..f387d99af595 100644
--- content/browser/storage_partition_impl.h --- content/browser/storage_partition_impl.h
+++ content/browser/storage_partition_impl.h +++ content/browser/storage_partition_impl.h
@@ -95,7 +95,7 @@ class CONTENT_EXPORT StoragePartitionImpl @@ -97,7 +97,7 @@ class CONTENT_EXPORT StoragePartitionImpl
storage::FileSystemContext* GetFileSystemContext() override; storage::FileSystemContext* GetFileSystemContext() override;
storage::DatabaseTracker* GetDatabaseTracker() override; storage::DatabaseTracker* GetDatabaseTracker() override;
DOMStorageContextWrapper* GetDOMStorageContext() override; DOMStorageContextWrapper* GetDOMStorageContext() override;
@@ -611,7 +611,7 @@ index 6f6c5c1e504a..097095a613dd 100644
IndexedDBContextImpl* GetIndexedDBContext() override; IndexedDBContextImpl* GetIndexedDBContext() override;
CacheStorageContextImpl* GetCacheStorageContext() override; CacheStorageContextImpl* GetCacheStorageContext() override;
ServiceWorkerContextWrapper* GetServiceWorkerContext() override; ServiceWorkerContextWrapper* GetServiceWorkerContext() override;
@@ -136,14 +136,14 @@ class CONTENT_EXPORT StoragePartitionImpl @@ -138,14 +138,14 @@ class CONTENT_EXPORT StoragePartitionImpl
void FlushNetworkInterfaceForTesting() override; void FlushNetworkInterfaceForTesting() override;
void WaitForDeletionTasksForTesting() override; void WaitForDeletionTasksForTesting() override;
@@ -634,9 +634,9 @@ index 6f6c5c1e504a..097095a613dd 100644
// blink::mojom::StoragePartitionService interface. // blink::mojom::StoragePartitionService interface.
void OpenLocalStorage(const url::Origin& origin, void OpenLocalStorage(const url::Origin& origin,
@@ -152,18 +152,19 @@ class CONTENT_EXPORT StoragePartitionImpl @@ -159,18 +159,19 @@ class CONTENT_EXPORT StoragePartitionImpl
const std::string& namespace_id, const std::vector<url::Origin>& origins,
blink::mojom::SessionStorageNamespaceRequest request) override; OnCanSendReportingReportsCallback callback) override;
- scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter() { - scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter() {
- return url_loader_factory_getter_; - return url_loader_factory_getter_;
@@ -658,7 +658,7 @@ index 6f6c5c1e504a..097095a613dd 100644
auto& bindings_for_testing() { return bindings_; } auto& bindings_for_testing() { return bindings_; }
@@ -174,10 +175,11 @@ class CONTENT_EXPORT StoragePartitionImpl @@ -181,10 +182,11 @@ class CONTENT_EXPORT StoragePartitionImpl
// one must use the "chrome-guest://blahblah" site URL to ensure that the // one must use the "chrome-guest://blahblah" site URL to ensure that the
// service worker stays in this StoragePartition. This is an empty GURL if // service worker stays in this StoragePartition. This is an empty GURL if
// this StoragePartition is not for guests. // this StoragePartition is not for guests.

View File

@@ -295,10 +295,10 @@ index 9c78b30ab3a0..999eb4048f5c 100644
std::unique_ptr<SelectionController> selection_controller_; std::unique_ptr<SelectionController> selection_controller_;
diff --git ui/views/controls/menu/menu_controller.cc ui/views/controls/menu/menu_controller.cc diff --git ui/views/controls/menu/menu_controller.cc ui/views/controls/menu/menu_controller.cc
index b4da2b5128c8..d030d6e81c19 100644 index d68060616527..005a8c412c5e 100644
--- ui/views/controls/menu/menu_controller.cc --- ui/views/controls/menu/menu_controller.cc
+++ ui/views/controls/menu/menu_controller.cc +++ ui/views/controls/menu/menu_controller.cc
@@ -2441,8 +2441,13 @@ MenuItemView* MenuController::FindNextSelectableMenuItem( @@ -2449,8 +2449,13 @@ MenuItemView* MenuController::FindNextSelectableMenuItem(
void MenuController::OpenSubmenuChangeSelectionIfCan() { void MenuController::OpenSubmenuChangeSelectionIfCan() {
MenuItemView* item = pending_state_.item; MenuItemView* item = pending_state_.item;
@@ -313,7 +313,7 @@ index b4da2b5128c8..d030d6e81c19 100644
MenuItemView* to_select = NULL; MenuItemView* to_select = NULL;
if (item->GetSubmenu()->GetMenuItemCount() > 0) if (item->GetSubmenu()->GetMenuItemCount() > 0)
to_select = FindInitialSelectableMenuItem(item, INCREMENT_SELECTION_DOWN); to_select = FindInitialSelectableMenuItem(item, INCREMENT_SELECTION_DOWN);
@@ -2457,8 +2462,10 @@ void MenuController::OpenSubmenuChangeSelectionIfCan() { @@ -2465,8 +2470,10 @@ void MenuController::OpenSubmenuChangeSelectionIfCan() {
void MenuController::CloseSubmenu() { void MenuController::CloseSubmenu() {
MenuItemView* item = state_.item; MenuItemView* item = state_.item;
DCHECK(item); DCHECK(item);

View File

@@ -194,7 +194,7 @@ index 364d6df184c5..0d32a4579c87 100644
// a reference. // a reference.
corewm::TooltipWin* tooltip_; corewm::TooltipWin* tooltip_;
diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 590de782aca3..e87ee9935760 100644 index 4e04197810d8..82d3e87b55d4 100644
--- ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc --- ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -145,6 +145,7 @@ DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( @@ -145,6 +145,7 @@ DesktopWindowTreeHostX11::DesktopWindowTreeHostX11(
@@ -241,7 +241,7 @@ index 590de782aca3..e87ee9935760 100644
return ToDIPRect(bounds_in_pixels_); return ToDIPRect(bounds_in_pixels_);
} }
@@ -1271,6 +1278,8 @@ void DesktopWindowTreeHostX11::SetBoundsInPixels( @@ -1274,6 +1281,8 @@ void DesktopWindowTreeHostX11::SetBoundsInPixels(
} }
gfx::Point DesktopWindowTreeHostX11::GetLocationOnScreenInPixels() const { gfx::Point DesktopWindowTreeHostX11::GetLocationOnScreenInPixels() const {
@@ -250,15 +250,15 @@ index 590de782aca3..e87ee9935760 100644
return bounds_in_pixels_.origin(); return bounds_in_pixels_.origin();
} }
@@ -1415,7 +1424,6 @@ void DesktopWindowTreeHostX11::InitX11Window( @@ -1418,7 +1427,6 @@ void DesktopWindowTreeHostX11::InitX11Window(
::Atom window_type; XAtom window_type;
switch (params.type) { switch (params.type) {
case Widget::InitParams::TYPE_MENU: case Widget::InitParams::TYPE_MENU:
- swa.override_redirect = x11::True; - swa.override_redirect = x11::True;
window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU"); window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU");
break; break;
case Widget::InitParams::TYPE_TOOLTIP: case Widget::InitParams::TYPE_TOOLTIP:
@@ -1471,9 +1479,15 @@ void DesktopWindowTreeHostX11::InitX11Window( @@ -1474,9 +1482,15 @@ void DesktopWindowTreeHostX11::InitX11Window(
attribute_mask |= CWBorderPixel; attribute_mask |= CWBorderPixel;
swa.border_pixel = 0; swa.border_pixel = 0;
@@ -275,7 +275,7 @@ index 590de782aca3..e87ee9935760 100644
bounds_in_pixels_.y(), bounds_in_pixels_.width(), bounds_in_pixels_.y(), bounds_in_pixels_.width(),
bounds_in_pixels_.height(), bounds_in_pixels_.height(),
0, // border width 0, // border width
@@ -2089,6 +2103,10 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent( @@ -2094,6 +2108,10 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
} }
break; break;
} }
@@ -287,7 +287,7 @@ index 590de782aca3..e87ee9935760 100644
case x11::FocusOut: case x11::FocusOut:
OnFocusEvent(xev->type == x11::FocusIn, event->xfocus.mode, OnFocusEvent(xev->type == x11::FocusIn, event->xfocus.mode,
diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index 5a0a3086545a..531619b16213 100644 index cc9d5fb48234..f8daf495d5d9 100644
--- ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h --- ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h +++ ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -91,6 +91,12 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 @@ -91,6 +91,12 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
@@ -303,7 +303,7 @@ index 5a0a3086545a..531619b16213 100644
protected: protected:
// Overridden from DesktopWindowTreeHost: // Overridden from DesktopWindowTreeHost:
void Init(const Widget::InitParams& params) override; void Init(const Widget::InitParams& params) override;
@@ -321,6 +327,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 @@ -330,6 +336,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
// The bounds of |xwindow_|. // The bounds of |xwindow_|.
gfx::Rect bounds_in_pixels_; gfx::Rect bounds_in_pixels_;
@@ -313,7 +313,7 @@ index 5a0a3086545a..531619b16213 100644
// Whenever the bounds are set, we keep the previous set of bounds around so // Whenever the bounds are set, we keep the previous set of bounds around so
// we can have a better chance of getting the real // we can have a better chance of getting the real
// |restored_bounds_in_pixels_|. Window managers tend to send a Configure // |restored_bounds_in_pixels_|. Window managers tend to send a Configure
@@ -365,6 +374,10 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 @@ -370,6 +379,10 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
// Whether we used an ARGB visual for our window. // Whether we used an ARGB visual for our window.
bool use_argb_visual_; bool use_argb_visual_;
@@ -324,7 +324,7 @@ index 5a0a3086545a..531619b16213 100644
DesktopDragDropClientAuraX11* drag_drop_client_; DesktopDragDropClientAuraX11* drag_drop_client_;
std::unique_ptr<ui::EventHandler> x11_non_client_event_filter_; std::unique_ptr<ui::EventHandler> x11_non_client_event_filter_;
@@ -454,6 +467,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 @@ -459,6 +472,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
uint32_t modal_dialog_counter_; uint32_t modal_dialog_counter_;

View File

@@ -1,5 +1,5 @@
diff --git content/browser/web_contents/web_contents_impl.cc content/browser/web_contents/web_contents_impl.cc diff --git content/browser/web_contents/web_contents_impl.cc content/browser/web_contents/web_contents_impl.cc
index 36dab1bdee1d..27a1c1cbe0c8 100644 index 499c8c0a2e89..0dbf4cecdade 100644
--- content/browser/web_contents/web_contents_impl.cc --- content/browser/web_contents/web_contents_impl.cc
+++ content/browser/web_contents/web_contents_impl.cc +++ content/browser/web_contents/web_contents_impl.cc
@@ -1940,21 +1940,30 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) { @@ -1940,21 +1940,30 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
@@ -70,7 +70,7 @@ index 36dab1bdee1d..27a1c1cbe0c8 100644
} }
// Save the created window associated with the route so we can show it // Save the created window associated with the route so we can show it
// later. // later.
@@ -6042,7 +6060,7 @@ InterstitialPageImpl* WebContentsImpl::GetInterstitialForRenderManager() { @@ -6043,7 +6061,7 @@ InterstitialPageImpl* WebContentsImpl::GetInterstitialForRenderManager() {
void WebContentsImpl::CreateRenderWidgetHostViewForRenderManager( void WebContentsImpl::CreateRenderWidgetHostViewForRenderManager(
RenderViewHost* render_view_host) { RenderViewHost* render_view_host) {
RenderWidgetHostViewBase* rwh_view = RenderWidgetHostViewBase* rwh_view =

View File

@@ -78,7 +78,7 @@ index a7ddc156c2b1..e31496827664 100644
} }
diff --git third_party/blink/renderer/core/page/page.cc third_party/blink/renderer/core/page/page.cc diff --git third_party/blink/renderer/core/page/page.cc third_party/blink/renderer/core/page/page.cc
index af94b52a5b6e..f5b91fefcda0 100644 index fc45eecaba60..253acc51e9b5 100644
--- third_party/blink/renderer/core/page/page.cc --- third_party/blink/renderer/core/page/page.cc
+++ third_party/blink/renderer/core/page/page.cc +++ third_party/blink/renderer/core/page/page.cc
@@ -171,7 +171,8 @@ Page::Page(PageClients& page_clients) @@ -171,7 +171,8 @@ Page::Page(PageClients& page_clients)
@@ -141,7 +141,7 @@ index af94b52a5b6e..f5b91fefcda0 100644
page->NotifyPluginsChanged(); page->NotifyPluginsChanged();
} }
} }
@@ -736,7 +756,8 @@ void Page::Trace(blink::Visitor* visitor) { @@ -737,7 +757,8 @@ void Page::Trace(blink::Visitor* visitor) {
visitor->Trace(overscroll_controller_); visitor->Trace(overscroll_controller_);
visitor->Trace(link_highlights_); visitor->Trace(link_highlights_);
visitor->Trace(main_frame_); visitor->Trace(main_frame_);
@@ -152,7 +152,7 @@ index af94b52a5b6e..f5b91fefcda0 100644
visitor->Trace(plugins_changed_observers_); visitor->Trace(plugins_changed_observers_);
visitor->Trace(next_related_page_); visitor->Trace(next_related_page_);
diff --git third_party/blink/renderer/core/page/page.h third_party/blink/renderer/core/page/page.h diff --git third_party/blink/renderer/core/page/page.h third_party/blink/renderer/core/page/page.h
index c9ecb33e153f..6ff8e8dc6b67 100644 index 8036e8ad5e03..597924d40ade 100644
--- third_party/blink/renderer/core/page/page.h --- third_party/blink/renderer/core/page/page.h
+++ third_party/blink/renderer/core/page/page.h +++ third_party/blink/renderer/core/page/page.h
@@ -136,7 +136,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>, @@ -136,7 +136,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,

View File

@@ -1,8 +1,8 @@
diff --git third_party/blink/renderer/core/input/pointer_event_manager.cc third_party/blink/renderer/core/input/pointer_event_manager.cc diff --git third_party/blink/renderer/core/input/pointer_event_manager.cc third_party/blink/renderer/core/input/pointer_event_manager.cc
index 2e4954ba8deb..f5f50ea77be8 100644 index b2af030b97d3..016d1ea8039d 100644
--- third_party/blink/renderer/core/input/pointer_event_manager.cc --- third_party/blink/renderer/core/input/pointer_event_manager.cc
+++ third_party/blink/renderer/core/input/pointer_event_manager.cc +++ third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -272,7 +272,7 @@ void PointerEventManager::HandlePointerInterruption( @@ -281,7 +281,7 @@ void PointerEventManager::HandlePointerInterruption(
for (auto pointer_event : canceled_pointer_events) { for (auto pointer_event : canceled_pointer_events) {
// If we are sending a pointercancel we have sent the pointerevent to some // If we are sending a pointercancel we have sent the pointerevent to some
// target before. // target before.

View File

@@ -1,8 +1,8 @@
diff --git third_party/blink/public/web/web_view.h third_party/blink/public/web/web_view.h diff --git third_party/blink/public/web/web_view.h third_party/blink/public/web/web_view.h
index 380ca3f69a26..fe841b6f25bd 100644 index bafddd241354..1f66e731b111 100644
--- third_party/blink/public/web/web_view.h --- third_party/blink/public/web/web_view.h
+++ third_party/blink/public/web/web_view.h +++ third_party/blink/public/web/web_view.h
@@ -351,6 +351,7 @@ class WebView : protected WebWidget { @@ -356,6 +356,7 @@ class WebView : protected WebWidget {
// Sets whether select popup menus should be rendered by the browser. // Sets whether select popup menus should be rendered by the browser.
BLINK_EXPORT static void SetUseExternalPopupMenus(bool); BLINK_EXPORT static void SetUseExternalPopupMenus(bool);
@@ -10,7 +10,7 @@ index 380ca3f69a26..fe841b6f25bd 100644
// Hides any popup (suggestions, selects...) that might be showing. // Hides any popup (suggestions, selects...) that might be showing.
virtual void HidePopups() = 0; virtual void HidePopups() = 0;
@@ -375,6 +376,8 @@ class WebView : protected WebWidget { @@ -380,6 +381,8 @@ class WebView : protected WebWidget {
unsigned inactive_background_color, unsigned inactive_background_color,
unsigned inactive_foreground_color) = 0; unsigned inactive_foreground_color) = 0;
@@ -20,7 +20,7 @@ index 380ca3f69a26..fe841b6f25bd 100644
// Call these methods before and after running a nested, modal event loop // Call these methods before and after running a nested, modal event loop
diff --git third_party/blink/renderer/core/exported/web_view_impl.cc third_party/blink/renderer/core/exported/web_view_impl.cc diff --git third_party/blink/renderer/core/exported/web_view_impl.cc third_party/blink/renderer/core/exported/web_view_impl.cc
index 1a1e2cfb4fd2..9251b9a09504 100644 index 1dfa732a6a79..e997d738c9e2 100644
--- third_party/blink/renderer/core/exported/web_view_impl.cc --- third_party/blink/renderer/core/exported/web_view_impl.cc
+++ third_party/blink/renderer/core/exported/web_view_impl.cc +++ third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -234,8 +234,13 @@ void WebView::SetUseExternalPopupMenus(bool use_external_popup_menus) { @@ -234,8 +234,13 @@ void WebView::SetUseExternalPopupMenus(bool use_external_popup_menus) {
@@ -48,7 +48,7 @@ index 1a1e2cfb4fd2..9251b9a09504 100644
suppress_next_keypress_event_(false), suppress_next_keypress_event_(false),
ime_accept_events_(true), ime_accept_events_(true),
diff --git third_party/blink/renderer/core/exported/web_view_impl.h third_party/blink/renderer/core/exported/web_view_impl.h diff --git third_party/blink/renderer/core/exported/web_view_impl.h third_party/blink/renderer/core/exported/web_view_impl.h
index 66a3b5c16769..ac7331a50353 100644 index ca44078fa4cf..4148ab31a8e9 100644
--- third_party/blink/renderer/core/exported/web_view_impl.h --- third_party/blink/renderer/core/exported/web_view_impl.h
+++ third_party/blink/renderer/core/exported/web_view_impl.h +++ third_party/blink/renderer/core/exported/web_view_impl.h
@@ -103,7 +103,8 @@ class CORE_EXPORT WebViewImpl final : public WebView, @@ -103,7 +103,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,

View File

@@ -1,8 +1,8 @@
diff --git chrome/app/generated_resources.grd chrome/app/generated_resources.grd diff --git chrome/app/generated_resources.grd chrome/app/generated_resources.grd
index c700d8b74bcb..9a01101ba673 100644 index bd1f38bd147d..8fe0439a6b16 100644
--- chrome/app/generated_resources.grd --- chrome/app/generated_resources.grd
+++ chrome/app/generated_resources.grd +++ chrome/app/generated_resources.grd
@@ -4478,7 +4478,7 @@ Keep your key file in a safe place. You will need it to create new versions of y @@ -4505,7 +4505,7 @@ Keep your key file in a safe place. You will need it to create new versions of y
</message> </message>
</if> </if>
<message name="IDS_PLUGIN_BLOCKED_BY_POLICY" desc="The placeholder text for a plugin blocked by enterprise policy."> <message name="IDS_PLUGIN_BLOCKED_BY_POLICY" desc="The placeholder text for a plugin blocked by enterprise policy.">

View File

@@ -42,6 +42,8 @@ void BrowserWindow::OnBrowserClosing(CefRefPtr<CefBrowser> browser) {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier()); DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
is_closing_ = true; is_closing_ = true;
delegate_->OnBrowserWindowClosing();
} }
void BrowserWindow::OnBrowserClosed(CefRefPtr<CefBrowser> browser) { void BrowserWindow::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {

View File

@@ -25,6 +25,9 @@ class BrowserWindow : public ClientHandler::Delegate {
// Called when the browser has been created. // Called when the browser has been created.
virtual void OnBrowserCreated(CefRefPtr<CefBrowser> browser) = 0; virtual void OnBrowserCreated(CefRefPtr<CefBrowser> browser) = 0;
// Called when the BrowserWindow is closing.
virtual void OnBrowserWindowClosing() {}
// Called when the BrowserWindow has been destroyed. // Called when the BrowserWindow has been destroyed.
virtual void OnBrowserWindowDestroyed() = 0; virtual void OnBrowserWindowDestroyed() = 0;

View File

@@ -19,6 +19,7 @@
#include "include/base/cef_logging.h" #include "include/base/cef_logging.h"
#include "include/wrapper/cef_closure_task.h" #include "include/wrapper/cef_closure_task.h"
#include "tests/cefclient/browser/util_gtk.h"
#include "tests/shared/browser/geometry_util.h" #include "tests/shared/browser/geometry_util.h"
#include "tests/shared/browser/main_message_loop.h" #include "tests/shared/browser/main_message_loop.h"
@@ -922,6 +923,7 @@ class ScopedGLContext {
bool swap_buffers_; bool swap_buffers_;
GdkGLDrawable* gldrawable_; GdkGLDrawable* gldrawable_;
bool is_valid_; bool is_valid_;
ScopedGdkThreadsEnter scoped_gdk_threads_;
}; };
} // namespace } // namespace
@@ -930,23 +932,26 @@ BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate,
const std::string& startup_url, const std::string& startup_url,
const OsrRenderer::Settings& settings) const OsrRenderer::Settings& settings)
: BrowserWindow(delegate), : BrowserWindow(delegate),
xdisplay_(nullptr),
renderer_(settings), renderer_(settings),
glarea_(NULL),
hidden_(false),
gl_enabled_(false), gl_enabled_(false),
painting_popup_(false), painting_popup_(false),
device_scale_factor_(1.0f), hidden_(false),
glarea_(NULL),
drag_trigger_event_(NULL), drag_trigger_event_(NULL),
drag_data_(NULL), drag_data_(NULL),
drag_operation_(DRAG_OPERATION_NONE), drag_operation_(DRAG_OPERATION_NONE),
drag_context_(NULL), drag_context_(NULL),
drag_targets_(gtk_target_list_new(NULL, 0)), drag_targets_(gtk_target_list_new(NULL, 0)),
drag_leave_(false), drag_leave_(false),
drag_drop_(false) { drag_drop_(false),
device_scale_factor_(1.0f) {
client_handler_ = new ClientHandlerOsr(this, this, startup_url); client_handler_ = new ClientHandlerOsr(this, this, startup_url);
} }
BrowserWindowOsrGtk::~BrowserWindowOsrGtk() { BrowserWindowOsrGtk::~BrowserWindowOsrGtk() {
ScopedGdkThreadsEnter scoped_gdk_threads;
if (drag_trigger_event_) { if (drag_trigger_event_) {
gdk_event_free(drag_trigger_event_); gdk_event_free(drag_trigger_event_);
} }
@@ -956,6 +961,12 @@ BrowserWindowOsrGtk::~BrowserWindowOsrGtk() {
gtk_target_list_unref(drag_targets_); gtk_target_list_unref(drag_targets_);
} }
void BrowserWindowOsrGtk::set_xdisplay(XDisplay* xdisplay) {
REQUIRE_MAIN_THREAD();
DCHECK(!xdisplay_);
xdisplay_ = xdisplay;
}
void BrowserWindowOsrGtk::CreateBrowser( void BrowserWindowOsrGtk::CreateBrowser(
ClientWindowHandle parent_handle, ClientWindowHandle parent_handle,
const CefRect& rect, const CefRect& rect,
@@ -966,6 +977,8 @@ void BrowserWindowOsrGtk::CreateBrowser(
// Create the native window. // Create the native window.
Create(parent_handle); Create(parent_handle);
ScopedGdkThreadsEnter scoped_gdk_threads;
// Retrieve the X11 Window ID for the GTK parent window. // Retrieve the X11 Window ID for the GTK parent window.
GtkWidget* window = GtkWidget* window =
gtk_widget_get_ancestor(GTK_WIDGET(parent_handle), GTK_TYPE_WINDOW); gtk_widget_get_ancestor(GTK_WIDGET(parent_handle), GTK_TYPE_WINDOW);
@@ -1045,20 +1058,25 @@ void BrowserWindowOsrGtk::SetBounds(int x, int y, size_t width, size_t height) {
void BrowserWindowOsrGtk::SetFocus(bool focus) { void BrowserWindowOsrGtk::SetFocus(bool focus) {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
if (glarea_ && focus) ScopedGdkThreadsEnter scoped_gdk_threads;
if (glarea_ && focus) {
gtk_widget_grab_focus(glarea_); gtk_widget_grab_focus(glarea_);
}
} }
void BrowserWindowOsrGtk::SetDeviceScaleFactor(float device_scale_factor) { void BrowserWindowOsrGtk::SetDeviceScaleFactor(float device_scale_factor) {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
if (device_scale_factor == device_scale_factor_) {
return; base::AutoLock lock_scope(lock_);
if (device_scale_factor == device_scale_factor_)
return;
// Apply some sanity checks. // Apply some sanity checks.
if (device_scale_factor < 1.0f || device_scale_factor > 4.0f) if (device_scale_factor < 1.0f || device_scale_factor > 4.0f)
return; return;
device_scale_factor_ = device_scale_factor; device_scale_factor_ = device_scale_factor;
}
if (browser_) { if (browser_) {
browser_->GetHost()->NotifyScreenInfoChanged(); browser_->GetHost()->NotifyScreenInfoChanged();
@@ -1068,6 +1086,7 @@ void BrowserWindowOsrGtk::SetDeviceScaleFactor(float device_scale_factor) {
float BrowserWindowOsrGtk::GetDeviceScaleFactor() const { float BrowserWindowOsrGtk::GetDeviceScaleFactor() const {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
base::AutoLock lock_scope(lock_);
return device_scale_factor_; return device_scale_factor_;
} }
@@ -1082,11 +1101,12 @@ void BrowserWindowOsrGtk::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
void BrowserWindowOsrGtk::OnBeforeClose(CefRefPtr<CefBrowser> browser) { void BrowserWindowOsrGtk::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
// Detach |this| from the ClientHandlerOsr. // Detach |this| from the ClientHandlerOsr.
static_cast<ClientHandlerOsr*>(client_handler_.get())->DetachOsrDelegate(); static_cast<ClientHandlerOsr*>(client_handler_.get())->DetachOsrDelegate();
ScopedGdkThreadsEnter scoped_gdk_threads;
UnregisterDragDrop(); UnregisterDragDrop();
// Disconnect all signal handlers that reference |this|. // Disconnect all signal handlers that reference |this|.
@@ -1105,17 +1125,22 @@ bool BrowserWindowOsrGtk::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
bool BrowserWindowOsrGtk::GetViewRect(CefRefPtr<CefBrowser> browser, bool BrowserWindowOsrGtk::GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) { CefRect& rect) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
if (!glarea_) if (!glarea_)
return false; return false;
float device_scale_factor;
{
base::AutoLock lock_scope(lock_);
device_scale_factor = device_scale_factor_;
}
// The simulated screen and view rectangle are the same. This is necessary // The simulated screen and view rectangle are the same. This is necessary
// for popup menus to be located and sized inside the view. // for popup menus to be located and sized inside the view.
rect.x = rect.y = 0; rect.x = rect.y = 0;
rect.width = DeviceToLogical(glarea_->allocation.width, device_scale_factor_); rect.width = DeviceToLogical(glarea_->allocation.width, device_scale_factor);
rect.height = rect.height =
DeviceToLogical(glarea_->allocation.height, device_scale_factor_); DeviceToLogical(glarea_->allocation.height, device_scale_factor);
return true; return true;
} }
@@ -1125,12 +1150,17 @@ bool BrowserWindowOsrGtk::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int& screenX, int& screenX,
int& screenY) { int& screenY) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
float device_scale_factor;
{
base::AutoLock lock_scope(lock_);
device_scale_factor = device_scale_factor_;
}
GdkRectangle screen_rect; GdkRectangle screen_rect;
GetWidgetRectInScreen(glarea_, &screen_rect); GetWidgetRectInScreen(glarea_, &screen_rect);
screenX = screen_rect.x + LogicalToDevice(viewX, device_scale_factor_); screenX = screen_rect.x + LogicalToDevice(viewX, device_scale_factor);
screenY = screen_rect.y + LogicalToDevice(viewY, device_scale_factor_); screenY = screen_rect.y + LogicalToDevice(viewY, device_scale_factor);
return true; return true;
} }
@@ -1141,7 +1171,13 @@ bool BrowserWindowOsrGtk::GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefRect view_rect; CefRect view_rect;
GetViewRect(browser, view_rect); GetViewRect(browser, view_rect);
screen_info.device_scale_factor = device_scale_factor_; float device_scale_factor;
{
base::AutoLock lock_scope(lock_);
device_scale_factor = device_scale_factor_;
}
screen_info.device_scale_factor = device_scale_factor;
// The screen info rectangles are used by the renderer to create and position // The screen info rectangles are used by the renderer to create and position
// popups. Keep popups inside the view rectangle. // popups. Keep popups inside the view rectangle.
@@ -1153,7 +1189,6 @@ bool BrowserWindowOsrGtk::GetScreenInfo(CefRefPtr<CefBrowser> browser,
void BrowserWindowOsrGtk::OnPopupShow(CefRefPtr<CefBrowser> browser, void BrowserWindowOsrGtk::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) { bool show) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
if (!show) { if (!show) {
renderer_.ClearPopupRects(); renderer_.ClearPopupRects();
@@ -1165,9 +1200,14 @@ void BrowserWindowOsrGtk::OnPopupShow(CefRefPtr<CefBrowser> browser,
void BrowserWindowOsrGtk::OnPopupSize(CefRefPtr<CefBrowser> browser, void BrowserWindowOsrGtk::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) { const CefRect& rect) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
renderer_.OnPopupSize(browser, LogicalToDevice(rect, device_scale_factor_)); float device_scale_factor;
{
base::AutoLock lock_scope(lock_);
device_scale_factor = device_scale_factor_;
}
renderer_.OnPopupSize(browser, LogicalToDevice(rect, device_scale_factor));
} }
void BrowserWindowOsrGtk::OnPaint(CefRefPtr<CefBrowser> browser, void BrowserWindowOsrGtk::OnPaint(CefRefPtr<CefBrowser> browser,
@@ -1177,7 +1217,6 @@ void BrowserWindowOsrGtk::OnPaint(CefRefPtr<CefBrowser> browser,
int width, int width,
int height) { int height) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
if (width <= 2 && height <= 2) { if (width <= 2 && height <= 2) {
// Ignore really small buffer sizes while the widget is starting up. // Ignore really small buffer sizes while the widget is starting up.
@@ -1211,17 +1250,17 @@ void BrowserWindowOsrGtk::OnCursorChange(
CefRenderHandler::CursorType type, CefRenderHandler::CursorType type,
const CefCursorInfo& custom_cursor_info) { const CefCursorInfo& custom_cursor_info) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
// Retrieve the X11 display shared with Chromium. // Retrieve the X11 display shared with Chromium.
::Display* xdisplay = cef_get_xdisplay(); CHECK(xdisplay_ != 0);
DCHECK(xdisplay);
ScopedGdkThreadsEnter scoped_gdk_threads;
// Retrieve the X11 window handle for the GTK widget. // Retrieve the X11 window handle for the GTK widget.
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(glarea_)); ::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(glarea_));
// Set the cursor. // Set the cursor.
XDefineCursor(xdisplay, xwindow, cursor); XDefineCursor(xdisplay_, xwindow, cursor);
} }
bool BrowserWindowOsrGtk::StartDragging( bool BrowserWindowOsrGtk::StartDragging(
@@ -1231,7 +1270,6 @@ bool BrowserWindowOsrGtk::StartDragging(
int x, int x,
int y) { int y) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
if (!drag_data->HasImage()) { if (!drag_data->HasImage()) {
LOG(ERROR) << "Drag image representation not available"; LOG(ERROR) << "Drag image representation not available";
@@ -1241,6 +1279,8 @@ bool BrowserWindowOsrGtk::StartDragging(
DragReset(); DragReset();
drag_data_ = drag_data; drag_data_ = drag_data;
ScopedGdkThreadsEnter scoped_gdk_threads;
// Begin drag. // Begin drag.
if (drag_trigger_event_) { if (drag_trigger_event_) {
LOG(ERROR) << "Dragging started, but last mouse event is missing"; LOG(ERROR) << "Dragging started, but last mouse event is missing";
@@ -1271,7 +1311,6 @@ void BrowserWindowOsrGtk::UpdateDragCursor(
CefRefPtr<CefBrowser> browser, CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) { CefRenderHandler::DragOperation operation) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD();
drag_operation_ = operation; drag_operation_ = operation;
} }
@@ -1290,6 +1329,8 @@ void BrowserWindowOsrGtk::Create(ClientWindowHandle parent_handle) {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
DCHECK(!glarea_); DCHECK(!glarea_);
ScopedGdkThreadsEnter scoped_gdk_threads;
glarea_ = gtk_drawing_area_new(); glarea_ = gtk_drawing_area_new();
DCHECK(glarea_); DCHECK(glarea_);
@@ -1344,8 +1385,7 @@ void BrowserWindowOsrGtk::Create(ClientWindowHandle parent_handle) {
gint BrowserWindowOsrGtk::SizeAllocation(GtkWidget* widget, gint BrowserWindowOsrGtk::SizeAllocation(GtkWidget* widget,
GtkAllocation* allocation, GtkAllocation* allocation,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (self->browser_.get()) { if (self->browser_.get()) {
// Results in a call to GetViewRect(). // Results in a call to GetViewRect().
self->browser_->GetHost()->WasResized(); self->browser_->GetHost()->WasResized();
@@ -1357,7 +1397,7 @@ gint BrowserWindowOsrGtk::SizeAllocation(GtkWidget* widget,
gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget, gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget,
GdkEventButton* event, GdkEventButton* event,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (!self->browser_.get()) if (!self->browser_.get())
return TRUE; return TRUE;
@@ -1379,16 +1419,23 @@ gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget,
return FALSE; return FALSE;
} }
float device_scale_factor;
{
base::AutoLock lock_scope(self->lock_);
device_scale_factor = self->device_scale_factor_;
}
CefMouseEvent mouse_event; CefMouseEvent mouse_event;
mouse_event.x = event->x; mouse_event.x = event->x;
mouse_event.y = event->y; mouse_event.y = event->y;
self->ApplyPopupOffset(mouse_event.x, mouse_event.y); self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
DeviceToLogical(mouse_event, self->device_scale_factor_); DeviceToLogical(mouse_event, device_scale_factor);
mouse_event.modifiers = GetCefStateModifiers(event->state); mouse_event.modifiers = GetCefStateModifiers(event->state);
bool mouse_up = (event->type == GDK_BUTTON_RELEASE); bool mouse_up = (event->type == GDK_BUTTON_RELEASE);
if (!mouse_up) if (!mouse_up) {
gtk_widget_grab_focus(widget); gtk_widget_grab_focus(widget);
}
int click_count = 1; int click_count = 1;
switch (event->type) { switch (event->type) {
@@ -1420,7 +1467,7 @@ gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget,
gint BrowserWindowOsrGtk::KeyEvent(GtkWidget* widget, gint BrowserWindowOsrGtk::KeyEvent(GtkWidget* widget,
GdkEventKey* event, GdkEventKey* event,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (!self->browser_.get()) if (!self->browser_.get())
return TRUE; return TRUE;
@@ -1476,7 +1523,7 @@ gint BrowserWindowOsrGtk::KeyEvent(GtkWidget* widget,
gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget, gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget,
GdkEventMotion* event, GdkEventMotion* event,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (!self->browser_.get()) if (!self->browser_.get())
return TRUE; return TRUE;
@@ -1500,11 +1547,17 @@ gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget,
} }
} }
float device_scale_factor;
{
base::AutoLock lock_scope(self->lock_);
device_scale_factor = self->device_scale_factor_;
}
CefMouseEvent mouse_event; CefMouseEvent mouse_event;
mouse_event.x = x; mouse_event.x = x;
mouse_event.y = y; mouse_event.y = y;
self->ApplyPopupOffset(mouse_event.x, mouse_event.y); self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
DeviceToLogical(mouse_event, self->device_scale_factor_); DeviceToLogical(mouse_event, device_scale_factor);
mouse_event.modifiers = GetCefStateModifiers(state); mouse_event.modifiers = GetCefStateModifiers(state);
bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY); bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY);
@@ -1527,18 +1580,24 @@ gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget,
gint BrowserWindowOsrGtk::ScrollEvent(GtkWidget* widget, gint BrowserWindowOsrGtk::ScrollEvent(GtkWidget* widget,
GdkEventScroll* event, GdkEventScroll* event,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (!self->browser_.get()) if (!self->browser_.get())
return TRUE; return TRUE;
CefRefPtr<CefBrowserHost> host = self->browser_->GetHost(); CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();
float device_scale_factor;
{
base::AutoLock lock_scope(self->lock_);
device_scale_factor = self->device_scale_factor_;
}
CefMouseEvent mouse_event; CefMouseEvent mouse_event;
mouse_event.x = event->x; mouse_event.x = event->x;
mouse_event.y = event->y; mouse_event.y = event->y;
self->ApplyPopupOffset(mouse_event.x, mouse_event.y); self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
DeviceToLogical(mouse_event, self->device_scale_factor_); DeviceToLogical(mouse_event, device_scale_factor);
mouse_event.modifiers = GetCefStateModifiers(event->state); mouse_event.modifiers = GetCefStateModifiers(event->state);
static const int scrollbarPixelsPerGtkTick = 40; static const int scrollbarPixelsPerGtkTick = 40;
@@ -1567,8 +1626,7 @@ gint BrowserWindowOsrGtk::ScrollEvent(GtkWidget* widget,
gint BrowserWindowOsrGtk::FocusEvent(GtkWidget* widget, gint BrowserWindowOsrGtk::FocusEvent(GtkWidget* widget,
GdkEventFocus* event, GdkEventFocus* event,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); // May be called on the main thread and the UI thread.
if (self->browser_.get()) if (self->browser_.get())
self->browser_->GetHost()->SendFocusEvent(event->in == TRUE); self->browser_->GetHost()->SendFocusEvent(event->in == TRUE);
return TRUE; return TRUE;
@@ -1597,7 +1655,7 @@ void BrowserWindowOsrGtk::ApplyPopupOffset(int& x, int& y) const {
} }
void BrowserWindowOsrGtk::EnableGL() { void BrowserWindowOsrGtk::EnableGL() {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (gl_enabled_) if (gl_enabled_)
return; return;
@@ -1612,7 +1670,7 @@ void BrowserWindowOsrGtk::EnableGL() {
} }
void BrowserWindowOsrGtk::DisableGL() { void BrowserWindowOsrGtk::DisableGL() {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (!gl_enabled_) if (!gl_enabled_)
return; return;
@@ -1629,6 +1687,8 @@ void BrowserWindowOsrGtk::DisableGL() {
void BrowserWindowOsrGtk::RegisterDragDrop() { void BrowserWindowOsrGtk::RegisterDragDrop() {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
// Succession of CEF d&d calls: // Succession of CEF d&d calls:
// 1. DragTargetDragEnter // 1. DragTargetDragEnter
// 2. DragTargetDragOver // 2. DragTargetDragOver
@@ -1679,14 +1739,15 @@ void BrowserWindowOsrGtk::RegisterDragDrop() {
} }
void BrowserWindowOsrGtk::UnregisterDragDrop() { void BrowserWindowOsrGtk::UnregisterDragDrop() {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
gtk_drag_dest_unset(glarea_); gtk_drag_dest_unset(glarea_);
// Drag events are unregistered in OnBeforeClose by calling // Drag events are unregistered in OnBeforeClose by calling
// g_signal_handlers_disconnect_matched. // g_signal_handlers_disconnect_matched.
} }
void BrowserWindowOsrGtk::DragReset() { void BrowserWindowOsrGtk::DragReset() {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (drag_trigger_event_) { if (drag_trigger_event_) {
gdk_event_free(drag_trigger_event_); gdk_event_free(drag_trigger_event_);
drag_trigger_event_ = NULL; drag_trigger_event_ = NULL;
@@ -1705,22 +1766,30 @@ void BrowserWindowOsrGtk::DragReset() {
void BrowserWindowOsrGtk::DragBegin(GtkWidget* widget, void BrowserWindowOsrGtk::DragBegin(GtkWidget* widget,
GdkDragContext* drag_context, GdkDragContext* drag_context,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
// Load drag icon. // Load drag icon.
if (!self->drag_data_->HasImage()) { if (!self->drag_data_->HasImage()) {
LOG(ERROR) << "Failed to set drag icon, drag image not available"; LOG(ERROR) << "Failed to set drag icon, drag image not available";
return; return;
} }
float device_scale_factor;
{
base::AutoLock lock_scope(self->lock_);
device_scale_factor = self->device_scale_factor_;
}
int pixel_width = 0; int pixel_width = 0;
int pixel_height = 0; int pixel_height = 0;
CefRefPtr<CefBinaryValue> image_binary = CefRefPtr<CefBinaryValue> image_binary =
self->drag_data_->GetImage()->GetAsPNG(self->device_scale_factor_, true, self->drag_data_->GetImage()->GetAsPNG(device_scale_factor, true,
pixel_width, pixel_height); pixel_width, pixel_height);
if (!image_binary) { if (!image_binary) {
LOG(ERROR) << "Failed to set drag icon, drag image error"; LOG(ERROR) << "Failed to set drag icon, drag image error";
return; return;
} }
size_t image_size = image_binary->GetSize(); size_t image_size = image_binary->GetSize();
guint8* image_buffer = (guint8*)malloc(image_size); // must free guint8* image_buffer = (guint8*)malloc(image_size); // must free
image_binary->GetData((void*)image_buffer, image_size, 0); image_binary->GetData((void*)image_buffer, image_size, 0);
@@ -1768,7 +1837,7 @@ void BrowserWindowOsrGtk::DragDataGet(GtkWidget* widget,
guint info, guint info,
guint time, guint time,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
// No drag targets are set so this callback is never called. // No drag targets are set so this callback is never called.
} }
@@ -1776,7 +1845,7 @@ void BrowserWindowOsrGtk::DragDataGet(GtkWidget* widget,
void BrowserWindowOsrGtk::DragEnd(GtkWidget* widget, void BrowserWindowOsrGtk::DragEnd(GtkWidget* widget,
GdkDragContext* drag_context, GdkDragContext* drag_context,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
if (self->browser_) { if (self->browser_) {
// Sometimes there is DragEnd event generated without prior DragDrop. // Sometimes there is DragEnd event generated without prior DragDrop.
@@ -1799,7 +1868,13 @@ gboolean BrowserWindowOsrGtk::DragMotion(GtkWidget* widget,
gint y, gint y,
guint time, guint time,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
float device_scale_factor;
{
base::AutoLock lock_scope(self->lock_);
device_scale_factor = self->device_scale_factor_;
}
// MoveEvent is never called during drag & drop, so must call // MoveEvent is never called during drag & drop, so must call
// SendMouseMoveEvent here. // SendMouseMoveEvent here.
@@ -1808,7 +1883,7 @@ gboolean BrowserWindowOsrGtk::DragMotion(GtkWidget* widget,
mouse_event.y = y; mouse_event.y = y;
mouse_event.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON; mouse_event.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
self->ApplyPopupOffset(mouse_event.x, mouse_event.y); self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
DeviceToLogical(mouse_event, self->device_scale_factor_); DeviceToLogical(mouse_event, device_scale_factor);
if (self->browser_) { if (self->browser_) {
bool mouse_leave = self->drag_leave_; bool mouse_leave = self->drag_leave_;
self->browser_->GetHost()->SendMouseMoveEvent(mouse_event, mouse_leave); self->browser_->GetHost()->SendMouseMoveEvent(mouse_event, mouse_leave);
@@ -1853,7 +1928,7 @@ void BrowserWindowOsrGtk::DragLeave(GtkWidget* widget,
GdkDragContext* drag_context, GdkDragContext* drag_context,
guint time, guint time,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
// There is no drag-enter event in GTK. The first drag-motion event // There is no drag-enter event in GTK. The first drag-motion event
// after drag-leave will be a drag-enter event. // after drag-leave will be a drag-enter event.
@@ -1875,7 +1950,7 @@ gboolean BrowserWindowOsrGtk::DragFailed(GtkWidget* widget,
GdkDragContext* drag_context, GdkDragContext* drag_context,
GtkDragResult result, GtkDragResult result,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
// Send drag end coordinates and system drag ended event. // Send drag end coordinates and system drag ended event.
if (self->browser_) { if (self->browser_) {
@@ -1895,7 +1970,7 @@ gboolean BrowserWindowOsrGtk::DragDrop(GtkWidget* widget,
gint y, gint y,
guint time, guint time,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
// Finish GTK drag. // Finish GTK drag.
gtk_drag_finish(drag_context, TRUE, FALSE, time); gtk_drag_finish(drag_context, TRUE, FALSE, time);
@@ -1939,7 +2014,7 @@ void BrowserWindowOsrGtk::DragDataReceived(GtkWidget* widget,
guint info, guint info,
guint time, guint time,
BrowserWindowOsrGtk* self) { BrowserWindowOsrGtk* self) {
REQUIRE_MAIN_THREAD(); CEF_REQUIRE_UI_THREAD();
// This callback is never called because DragDrop does not call // This callback is never called because DragDrop does not call
// gtk_drag_get_data, as only dragging inside web view is supported. // gtk_drag_get_data, as only dragging inside web view is supported.
} }

View File

@@ -6,6 +6,8 @@
#define CEF_TESTS_CEFCLIENT_BROWSER_BROWSER_WINDOW_OSR_GTK_H_ #define CEF_TESTS_CEFCLIENT_BROWSER_BROWSER_WINDOW_OSR_GTK_H_
#pragma once #pragma once
#include "include/base/cef_lock.h"
#include "tests/cefclient/browser/browser_window.h" #include "tests/cefclient/browser/browser_window.h"
#include "tests/cefclient/browser/client_handler_osr.h" #include "tests/cefclient/browser/client_handler_osr.h"
#include "tests/cefclient/browser/osr_renderer.h" #include "tests/cefclient/browser/osr_renderer.h"
@@ -24,6 +26,9 @@ class BrowserWindowOsrGtk : public BrowserWindow,
const std::string& startup_url, const std::string& startup_url,
const OsrRenderer::Settings& settings); const OsrRenderer::Settings& settings);
// Called from RootWindowGtk::CreateRootWindow before CreateBrowser.
void set_xdisplay(XDisplay* xdisplay);
// BrowserWindow methods. // BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle, void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect, const CefRect& rect,
@@ -162,15 +167,18 @@ class BrowserWindowOsrGtk : public BrowserWindow,
guint time, guint time,
BrowserWindowOsrGtk* self); BrowserWindowOsrGtk* self);
// The below members will only be accessed on the main thread which should be XDisplay* xdisplay_;
// the same as the CEF UI thread.
// Members only accessed on the UI thread.
OsrRenderer renderer_; OsrRenderer renderer_;
ClientWindowHandle glarea_;
bool hidden_;
bool gl_enabled_; bool gl_enabled_;
bool painting_popup_; bool painting_popup_;
float device_scale_factor_; // Members only accessed on the main thread.
bool hidden_;
// Members protected by the GDK global lock.
ClientWindowHandle glarea_;
// Drag & drop // Drag & drop
GdkEvent* drag_trigger_event_; // mouse event, a possible trigger for drag GdkEvent* drag_trigger_event_; // mouse event, a possible trigger for drag
@@ -181,6 +189,11 @@ class BrowserWindowOsrGtk : public BrowserWindow,
bool drag_leave_; bool drag_leave_;
bool drag_drop_; bool drag_drop_;
mutable base::Lock lock_;
// Access to these members must be protected by |lock_|.
float device_scale_factor_;
DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrGtk); DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrGtk);
}; };

View File

@@ -14,6 +14,7 @@
#include "include/base/cef_logging.h" #include "include/base/cef_logging.h"
#include "tests/cefclient/browser/client_handler_std.h" #include "tests/cefclient/browser/client_handler_std.h"
#include "tests/cefclient/browser/util_gtk.h"
#include "tests/shared/browser/main_message_loop.h" #include "tests/shared/browser/main_message_loop.h"
namespace client { namespace client {
@@ -21,14 +22,16 @@ namespace client {
namespace { namespace {
::Window GetXWindowForWidget(GtkWidget* widget) { ::Window GetXWindowForWidget(GtkWidget* widget) {
ScopedGdkThreadsEnter scoped_gdk_threads;
// The GTK window must be visible before we can retrieve the XID. // The GTK window must be visible before we can retrieve the XID.
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(widget)); ::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(widget));
DCHECK(xwindow); DCHECK(xwindow);
return xwindow; return xwindow;
} }
void SetXWindowVisible(::Window xwindow, bool visible) { void SetXWindowVisible(XDisplay* xdisplay, ::Window xwindow, bool visible) {
::Display* xdisplay = cef_get_xdisplay(); CHECK(xdisplay != 0);
// Retrieve the atoms required by the below XChangeProperty call. // Retrieve the atoms required by the below XChangeProperty call.
const char* kAtoms[] = {"_NET_WM_STATE", "ATOM", "_NET_WM_STATE_HIDDEN"}; const char* kAtoms[] = {"_NET_WM_STATE", "ATOM", "_NET_WM_STATE_HIDDEN"};
@@ -61,12 +64,13 @@ void SetXWindowVisible(::Window xwindow, bool visible) {
} }
} }
void SetXWindowBounds(::Window xwindow, void SetXWindowBounds(XDisplay* xdisplay,
::Window xwindow,
int x, int x,
int y, int y,
size_t width, size_t width,
size_t height) { size_t height) {
::Display* xdisplay = cef_get_xdisplay(); CHECK(xdisplay != 0);
XWindowChanges changes = {0}; XWindowChanges changes = {0};
changes.x = x; changes.x = x;
changes.y = y; changes.y = y;
@@ -79,10 +83,16 @@ void SetXWindowBounds(::Window xwindow,
BrowserWindowStdGtk::BrowserWindowStdGtk(Delegate* delegate, BrowserWindowStdGtk::BrowserWindowStdGtk(Delegate* delegate,
const std::string& startup_url) const std::string& startup_url)
: BrowserWindow(delegate) { : BrowserWindow(delegate), xdisplay_(nullptr) {
client_handler_ = new ClientHandlerStd(this, startup_url); client_handler_ = new ClientHandlerStd(this, startup_url);
} }
void BrowserWindowStdGtk::set_xdisplay(XDisplay* xdisplay) {
REQUIRE_MAIN_THREAD();
DCHECK(!xdisplay_);
xdisplay_ = xdisplay;
}
void BrowserWindowStdGtk::CreateBrowser( void BrowserWindowStdGtk::CreateBrowser(
ClientWindowHandle parent_handle, ClientWindowHandle parent_handle,
const CefRect& rect, const CefRect& rect,
@@ -118,14 +128,14 @@ void BrowserWindowStdGtk::ShowPopup(ClientWindowHandle parent_handle,
if (browser_) { if (browser_) {
::Window parent_xwindow = GetXWindowForWidget(parent_handle); ::Window parent_xwindow = GetXWindowForWidget(parent_handle);
::Display* xdisplay = cef_get_xdisplay(); CHECK(xdisplay_ != 0);
::Window xwindow = browser_->GetHost()->GetWindowHandle(); ::Window xwindow = browser_->GetHost()->GetWindowHandle();
DCHECK(xwindow); DCHECK(xwindow);
XReparentWindow(xdisplay, xwindow, parent_xwindow, x, y); XReparentWindow(xdisplay_, xwindow, parent_xwindow, x, y);
SetXWindowBounds(xwindow, x, y, width, height); SetXWindowBounds(xdisplay_, xwindow, x, y, width, height);
SetXWindowVisible(xwindow, true); SetXWindowVisible(xdisplay_, xwindow, true);
} }
} }
@@ -135,7 +145,7 @@ void BrowserWindowStdGtk::Show() {
if (browser_) { if (browser_) {
::Window xwindow = browser_->GetHost()->GetWindowHandle(); ::Window xwindow = browser_->GetHost()->GetWindowHandle();
DCHECK(xwindow); DCHECK(xwindow);
SetXWindowVisible(xwindow, true); SetXWindowVisible(xdisplay_, xwindow, true);
} }
} }
@@ -145,17 +155,17 @@ void BrowserWindowStdGtk::Hide() {
if (browser_) { if (browser_) {
::Window xwindow = browser_->GetHost()->GetWindowHandle(); ::Window xwindow = browser_->GetHost()->GetWindowHandle();
DCHECK(xwindow); DCHECK(xwindow);
SetXWindowVisible(xwindow, false); SetXWindowVisible(xdisplay_, xwindow, false);
} }
} }
void BrowserWindowStdGtk::SetBounds(int x, int y, size_t width, size_t height) { void BrowserWindowStdGtk::SetBounds(int x, int y, size_t width, size_t height) {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
if (browser_) { if (xdisplay_ && browser_) {
::Window xwindow = browser_->GetHost()->GetWindowHandle(); ::Window xwindow = browser_->GetHost()->GetWindowHandle();
DCHECK(xwindow); DCHECK(xwindow);
SetXWindowBounds(xwindow, x, y, width, height); SetXWindowBounds(xdisplay_, xwindow, x, y, width, height);
} }
} }

View File

@@ -19,6 +19,9 @@ class BrowserWindowStdGtk : public BrowserWindow {
// |delegate| must outlive this object. // |delegate| must outlive this object.
BrowserWindowStdGtk(Delegate* delegate, const std::string& startup_url); BrowserWindowStdGtk(Delegate* delegate, const std::string& startup_url);
// Called from RootWindowGtk::CreateRootWindow before CreateBrowser.
void set_xdisplay(XDisplay* xdisplay);
// BrowserWindow methods. // BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle, void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect, const CefRect& rect,
@@ -40,6 +43,8 @@ class BrowserWindowStdGtk : public BrowserWindow {
ClientWindowHandle GetWindowHandle() const OVERRIDE; ClientWindowHandle GetWindowHandle() const OVERRIDE;
private: private:
XDisplay* xdisplay_;
DISALLOW_COPY_AND_ASSIGN(BrowserWindowStdGtk); DISALLOW_COPY_AND_ASSIGN(BrowserWindowStdGtk);
}; };

View File

@@ -77,7 +77,7 @@ int BytesWriteHandler::Flush() {
} }
size_t BytesWriteHandler::Grow(size_t size) { size_t BytesWriteHandler::Grow(size_t size) {
base::AutoLock lock_scope(lock_); lock_.AssertAcquired();
size_t rv; size_t rv;
size_t s = (size > grow_ ? size : grow_); size_t s = (size > grow_ ? size : grow_);
void* tmp = realloc(data_, datasize_ + s); void* tmp = realloc(data_, datasize_ + s);

View File

@@ -11,6 +11,7 @@
#include "include/cef_parser.h" #include "include/cef_parser.h"
#include "include/wrapper/cef_helpers.h" #include "include/wrapper/cef_helpers.h"
#include "tests/cefclient/browser/root_window.h" #include "tests/cefclient/browser/root_window.h"
#include "tests/cefclient/browser/util_gtk.h"
namespace client { namespace client {
@@ -130,6 +131,7 @@ void AddFilters(GtkFileChooser* chooser,
} }
GtkWindow* GetWindow(CefRefPtr<CefBrowser> browser) { GtkWindow* GetWindow(CefRefPtr<CefBrowser> browser) {
REQUIRE_MAIN_THREAD();
scoped_refptr<RootWindow> root_window = scoped_refptr<RootWindow> root_window =
RootWindow::GetForBrowser(browser->GetIdentifier()); RootWindow::GetForBrowser(browser->GetIdentifier());
if (root_window) { if (root_window) {
@@ -141,6 +143,10 @@ GtkWindow* GetWindow(CefRefPtr<CefBrowser> browser) {
return NULL; return NULL;
} }
void RunCallback(base::Callback<void(GtkWindow*)> callback, GtkWindow* window) {
callback.Run(window);
}
} // namespace } // namespace
ClientDialogHandlerGtk::ClientDialogHandlerGtk() : gtk_dialog_(NULL) {} ClientDialogHandlerGtk::ClientDialogHandlerGtk() : gtk_dialog_(NULL) {}
@@ -153,6 +159,78 @@ bool ClientDialogHandlerGtk::OnFileDialog(
const std::vector<CefString>& accept_filters, const std::vector<CefString>& accept_filters,
int selected_accept_filter, int selected_accept_filter,
CefRefPtr<CefFileDialogCallback> callback) { CefRefPtr<CefFileDialogCallback> callback) {
CEF_REQUIRE_UI_THREAD();
OnFileDialogParams params;
params.browser = browser;
params.mode = mode;
params.title = title;
params.default_file_path = default_file_path;
params.accept_filters = accept_filters;
params.selected_accept_filter = selected_accept_filter;
params.callback = callback;
GetWindowAndContinue(
browser,
base::Bind(&ClientDialogHandlerGtk::OnFileDialogContinue, this, params));
return true;
}
bool ClientDialogHandlerGtk::OnJSDialog(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
JSDialogType dialog_type,
const CefString& message_text,
const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback,
bool& suppress_message) {
CEF_REQUIRE_UI_THREAD();
OnJSDialogParams params;
params.browser = browser;
params.origin_url = origin_url;
params.dialog_type = dialog_type;
params.message_text = message_text;
params.default_prompt_text = default_prompt_text;
params.callback = callback;
GetWindowAndContinue(
browser,
base::Bind(&ClientDialogHandlerGtk::OnJSDialogContinue, this, params));
return true;
}
bool ClientDialogHandlerGtk::OnBeforeUnloadDialog(
CefRefPtr<CefBrowser> browser,
const CefString& message_text,
bool is_reload,
CefRefPtr<CefJSDialogCallback> callback) {
CEF_REQUIRE_UI_THREAD();
const std::string& new_message_text =
message_text.ToString() + "\n\nIs it OK to leave/reload this page?";
bool suppress_message = false;
return OnJSDialog(browser, CefString(), JSDIALOGTYPE_CONFIRM,
new_message_text, CefString(), callback, suppress_message);
}
void ClientDialogHandlerGtk::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
if (!gtk_dialog_)
return;
gtk_widget_destroy(gtk_dialog_);
gtk_dialog_ = NULL;
js_dialog_callback_ = NULL;
}
void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
GtkWindow* window) {
CEF_REQUIRE_UI_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
std::vector<CefString> files; std::vector<CefString> files;
GtkFileChooserAction action; GtkFileChooserAction action;
@@ -160,7 +238,7 @@ bool ClientDialogHandlerGtk::OnFileDialog(
// Remove any modifier flags. // Remove any modifier flags.
FileDialogMode mode_type = FileDialogMode mode_type =
static_cast<FileDialogMode>(mode & FILE_DIALOG_TYPE_MASK); static_cast<FileDialogMode>(params.mode & FILE_DIALOG_TYPE_MASK);
if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_MULTIPLE) { if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_MULTIPLE) {
action = GTK_FILE_CHOOSER_ACTION_OPEN; action = GTK_FILE_CHOOSER_ACTION_OPEN;
@@ -173,12 +251,13 @@ bool ClientDialogHandlerGtk::OnFileDialog(
accept_button = GTK_STOCK_SAVE; accept_button = GTK_STOCK_SAVE;
} else { } else {
NOTREACHED(); NOTREACHED();
return false; params.callback->Cancel();
return;
} }
std::string title_str; std::string title_str;
if (!title.empty()) { if (!params.title.empty()) {
title_str = title; title_str = params.title;
} else { } else {
switch (mode_type) { switch (mode_type) {
case FILE_DIALOG_OPEN: case FILE_DIALOG_OPEN:
@@ -198,10 +277,6 @@ bool ClientDialogHandlerGtk::OnFileDialog(
} }
} }
GtkWindow* window = GetWindow(browser);
if (!window)
return false;
GtkWidget* dialog = gtk_file_chooser_dialog_new( GtkWidget* dialog = gtk_file_chooser_dialog_new(
title_str.c_str(), GTK_WINDOW(window), action, GTK_STOCK_CANCEL, title_str.c_str(), GTK_WINDOW(window), action, GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL, accept_button, GTK_RESPONSE_ACCEPT, NULL); GTK_RESPONSE_CANCEL, accept_button, GTK_RESPONSE_ACCEPT, NULL);
@@ -211,14 +286,15 @@ bool ClientDialogHandlerGtk::OnFileDialog(
if (mode_type == FILE_DIALOG_SAVE) { if (mode_type == FILE_DIALOG_SAVE) {
gtk_file_chooser_set_do_overwrite_confirmation( gtk_file_chooser_set_do_overwrite_confirmation(
GTK_FILE_CHOOSER(dialog), !!(mode & FILE_DIALOG_OVERWRITEPROMPT_FLAG)); GTK_FILE_CHOOSER(dialog),
!!(params.mode & FILE_DIALOG_OVERWRITEPROMPT_FLAG));
} }
gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), gtk_file_chooser_set_show_hidden(
!(mode & FILE_DIALOG_HIDEREADONLY_FLAG)); GTK_FILE_CHOOSER(dialog), !(params.mode & FILE_DIALOG_HIDEREADONLY_FLAG));
if (!default_file_path.empty() && mode_type == FILE_DIALOG_SAVE) { if (!params.default_file_path.empty() && mode_type == FILE_DIALOG_SAVE) {
const std::string& file_path = default_file_path; const std::string& file_path = params.default_file_path;
bool exists = false; bool exists = false;
struct stat sb; struct stat sb;
@@ -237,10 +313,10 @@ bool ClientDialogHandlerGtk::OnFileDialog(
} }
std::vector<GtkFileFilter*> filters; std::vector<GtkFileFilter*> filters;
AddFilters(GTK_FILE_CHOOSER(dialog), accept_filters, true, &filters); AddFilters(GTK_FILE_CHOOSER(dialog), params.accept_filters, true, &filters);
if (selected_accept_filter < static_cast<int>(filters.size())) { if (params.selected_accept_filter < static_cast<int>(filters.size())) {
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog),
filters[selected_accept_filter]); filters[params.selected_accept_filter]);
} }
bool success = false; bool success = false;
@@ -267,7 +343,7 @@ bool ClientDialogHandlerGtk::OnFileDialog(
} }
} }
int filter_index = selected_accept_filter; int filter_index = params.selected_accept_filter;
if (success) { if (success) {
GtkFileFilter* selected_filter = GtkFileFilter* selected_filter =
gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog)); gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
@@ -284,27 +360,22 @@ bool ClientDialogHandlerGtk::OnFileDialog(
gtk_widget_destroy(dialog); gtk_widget_destroy(dialog);
if (success) if (success)
callback->Continue(filter_index, files); params.callback->Continue(filter_index, files);
else else
callback->Cancel(); params.callback->Cancel();
return true;
} }
bool ClientDialogHandlerGtk::OnJSDialog(CefRefPtr<CefBrowser> browser, void ClientDialogHandlerGtk::OnJSDialogContinue(OnJSDialogParams params,
const CefString& origin_url, GtkWindow* window) {
JSDialogType dialog_type,
const CefString& message_text,
const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback,
bool& suppress_message) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
GtkButtonsType buttons = GTK_BUTTONS_NONE; GtkButtonsType buttons = GTK_BUTTONS_NONE;
GtkMessageType gtk_message_type = GTK_MESSAGE_OTHER; GtkMessageType gtk_message_type = GTK_MESSAGE_OTHER;
std::string title; std::string title;
switch (dialog_type) { switch (params.dialog_type) {
case JSDIALOGTYPE_ALERT: case JSDIALOGTYPE_ALERT:
buttons = GTK_BUTTONS_NONE; buttons = GTK_BUTTONS_NONE;
gtk_message_type = GTK_MESSAGE_WARNING; gtk_message_type = GTK_MESSAGE_WARNING;
@@ -324,20 +395,16 @@ bool ClientDialogHandlerGtk::OnJSDialog(CefRefPtr<CefBrowser> browser,
break; break;
} }
js_dialog_callback_ = callback; js_dialog_callback_ = params.callback;
if (!origin_url.empty()) { if (!params.origin_url.empty()) {
title += " - "; title += " - ";
title += CefFormatUrlForSecurityDisplay(origin_url).ToString(); title += CefFormatUrlForSecurityDisplay(params.origin_url).ToString();
} }
GtkWindow* window = GetWindow(browser);
if (!window)
return false;
gtk_dialog_ = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, gtk_dialog_ = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL,
gtk_message_type, buttons, "%s", gtk_message_type, buttons, "%s",
message_text.ToString().c_str()); params.message_text.ToString().c_str());
g_signal_connect(gtk_dialog_, "delete-event", g_signal_connect(gtk_dialog_, "delete-event",
G_CALLBACK(gtk_widget_hide_on_delete), NULL); G_CALLBACK(gtk_widget_hide_on_delete), NULL);
@@ -346,15 +413,15 @@ bool ClientDialogHandlerGtk::OnJSDialog(CefRefPtr<CefBrowser> browser,
GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_), GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_),
GTK_STOCK_OK, GTK_RESPONSE_OK); GTK_STOCK_OK, GTK_RESPONSE_OK);
if (dialog_type != JSDIALOGTYPE_PROMPT) if (params.dialog_type != JSDIALOGTYPE_PROMPT)
gtk_widget_grab_focus(ok_button); gtk_widget_grab_focus(ok_button);
if (dialog_type == JSDIALOGTYPE_PROMPT) { if (params.dialog_type == JSDIALOGTYPE_PROMPT) {
GtkWidget* content_area = GtkWidget* content_area =
gtk_dialog_get_content_area(GTK_DIALOG(gtk_dialog_)); gtk_dialog_get_content_area(GTK_DIALOG(gtk_dialog_));
GtkWidget* text_box = gtk_entry_new(); GtkWidget* text_box = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(text_box), gtk_entry_set_text(GTK_ENTRY(text_box),
default_prompt_text.ToString().c_str()); params.default_prompt_text.ToString().c_str());
gtk_box_pack_start(GTK_BOX(content_area), text_box, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(content_area), text_box, TRUE, TRUE, 0);
g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box); g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box);
gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE); gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE);
@@ -363,33 +430,21 @@ bool ClientDialogHandlerGtk::OnJSDialog(CefRefPtr<CefBrowser> browser,
gtk_dialog_set_default_response(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK); gtk_dialog_set_default_response(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK);
g_signal_connect(gtk_dialog_, "response", G_CALLBACK(OnDialogResponse), this); g_signal_connect(gtk_dialog_, "response", G_CALLBACK(OnDialogResponse), this);
gtk_widget_show_all(GTK_WIDGET(gtk_dialog_)); gtk_widget_show_all(GTK_WIDGET(gtk_dialog_));
return true;
} }
bool ClientDialogHandlerGtk::OnBeforeUnloadDialog( void ClientDialogHandlerGtk::GetWindowAndContinue(
CefRefPtr<CefBrowser> browser, CefRefPtr<CefBrowser> browser,
const CefString& message_text, base::Callback<void(GtkWindow*)> callback) {
bool is_reload, if (!CURRENTLY_ON_MAIN_THREAD()) {
CefRefPtr<CefJSDialogCallback> callback) { MAIN_POST_CLOSURE(base::Bind(&ClientDialogHandlerGtk::GetWindowAndContinue,
CEF_REQUIRE_UI_THREAD(); this, browser, callback));
const std::string& new_message_text =
message_text.ToString() + "\n\nIs it OK to leave/reload this page?";
bool suppress_message = false;
return OnJSDialog(browser, CefString(), JSDIALOGTYPE_CONFIRM,
new_message_text, CefString(), callback, suppress_message);
}
void ClientDialogHandlerGtk::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
if (!gtk_dialog_)
return; return;
gtk_widget_destroy(gtk_dialog_); }
gtk_dialog_ = NULL;
js_dialog_callback_ = NULL; GtkWindow* window = GetWindow(browser);
if (window) {
CefPostTask(TID_UI, base::Bind(RunCallback, callback, window));
}
} }
// static // static

View File

@@ -8,6 +8,7 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "include/base/cef_callback_forward.h"
#include "include/cef_dialog_handler.h" #include "include/cef_dialog_handler.h"
#include "include/cef_jsdialog_handler.h" #include "include/cef_jsdialog_handler.h"
@@ -42,6 +43,30 @@ class ClientDialogHandlerGtk : public CefDialogHandler,
void OnResetDialogState(CefRefPtr<CefBrowser> browser) OVERRIDE; void OnResetDialogState(CefRefPtr<CefBrowser> browser) OVERRIDE;
private: private:
struct OnFileDialogParams {
CefRefPtr<CefBrowser> browser;
FileDialogMode mode;
CefString title;
CefString default_file_path;
std::vector<CefString> accept_filters;
int selected_accept_filter;
CefRefPtr<CefFileDialogCallback> callback;
};
void OnFileDialogContinue(OnFileDialogParams params, GtkWindow* window);
struct OnJSDialogParams {
CefRefPtr<CefBrowser> browser;
CefString origin_url;
JSDialogType dialog_type;
CefString message_text;
CefString default_prompt_text;
CefRefPtr<CefJSDialogCallback> callback;
};
void OnJSDialogContinue(OnJSDialogParams params, GtkWindow* window);
void GetWindowAndContinue(CefRefPtr<CefBrowser> browser,
base::Callback<void(GtkWindow*)> callback);
static void OnDialogResponse(GtkDialog* dialog, static void OnDialogResponse(GtkDialog* dialog,
gint response_id, gint response_id,
ClientDialogHandlerGtk* handler); ClientDialogHandlerGtk* handler);

View File

@@ -135,7 +135,7 @@ bool MainContextImpl::UseWindowlessRendering() {
} }
void MainContextImpl::PopulateSettings(CefSettings* settings) { void MainContextImpl::PopulateSettings(CefSettings* settings) {
#if defined(OS_WIN) #if defined(OS_WIN) || defined(OS_LINUX)
settings->multi_threaded_message_loop = settings->multi_threaded_message_loop =
command_line_->HasSwitch(switches::kMultiThreadedMessageLoop); command_line_->HasSwitch(switches::kMultiThreadedMessageLoop);
#endif #endif

View File

@@ -0,0 +1,155 @@
// Copyright (c) 2018 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 "tests/cefclient/browser/main_message_loop_multithreaded_gtk.h"
#include <X11/Xlib.h>
#include <gtk/gtkmain.h>
#include "include/base/cef_bind.h"
#include "include/base/cef_logging.h"
#include "include/wrapper/cef_closure_task.h"
namespace client {
namespace {
base::Lock g_global_lock;
base::PlatformThreadId g_global_lock_thread = kInvalidPlatformThreadId;
void lock_enter() {
// The GDK lock is not reentrant, so check that we're using it correctly.
// See comments on ScopedGdkThreadsEnter.
base::PlatformThreadId current_thread = base::PlatformThread::CurrentId();
CHECK(current_thread != g_global_lock_thread);
g_global_lock.Acquire();
g_global_lock_thread = current_thread;
}
void lock_leave() {
g_global_lock_thread = kInvalidPlatformThreadId;
g_global_lock.Release();
}
// Same as g_idle_add() but specifying the GMainContext.
guint idle_add(GMainContext* main_context,
GSourceFunc function,
gpointer data) {
GSource* source = g_idle_source_new();
g_source_set_callback(source, function, data, nullptr);
guint id = g_source_attach(source, main_context);
g_source_unref(source);
return id;
}
// Same as g_timeout_add() but specifying the GMainContext.
guint timeout_add(GMainContext* main_context,
guint interval,
GSourceFunc function,
gpointer data) {
GSource* source = g_timeout_source_new(interval);
g_source_set_callback(source, function, data, nullptr);
guint id = g_source_attach(source, main_context);
g_source_unref(source);
return id;
}
} // namespace
MainMessageLoopMultithreadedGtk::MainMessageLoopMultithreadedGtk()
: thread_id_(base::PlatformThread::CurrentId()) {
// Initialize Xlib support for concurrent threads. This function must be the
// first Xlib function a multi-threaded program calls, and it must complete
// before any other Xlib call is made.
CHECK(XInitThreads() != 0);
// Initialize GDK thread support. See comments on ScopedGdkThreadsEnter.
gdk_threads_set_lock_functions(lock_enter, lock_leave);
gdk_threads_init();
}
MainMessageLoopMultithreadedGtk::~MainMessageLoopMultithreadedGtk() {
DCHECK(RunsTasksOnCurrentThread());
DCHECK(queued_tasks_.empty());
}
int MainMessageLoopMultithreadedGtk::Run() {
DCHECK(RunsTasksOnCurrentThread());
// Chromium uses the default GLib context so we create our own context and
// make it the default for this thread.
main_context_ = g_main_context_new();
g_main_context_push_thread_default(main_context_);
main_loop_ = g_main_loop_new(main_context_, TRUE);
// Check the queue when GTK is idle, or at least every 100ms.
// TODO(cef): It might be more efficient to use input functions
// (gdk_input_add) and trigger by writing to an fd.
idle_add(main_context_, MainMessageLoopMultithreadedGtk::TriggerRunTasks,
this);
timeout_add(main_context_, 100,
MainMessageLoopMultithreadedGtk::TriggerRunTasks, this);
// Block until g_main_loop_quit().
g_main_loop_run(main_loop_);
// Release GLib resources.
g_main_loop_unref(main_loop_);
main_loop_ = nullptr;
g_main_context_pop_thread_default(main_context_);
g_main_context_unref(main_context_);
main_context_ = nullptr;
return 0;
}
void MainMessageLoopMultithreadedGtk::Quit() {
PostTask(CefCreateClosureTask(base::Bind(
&MainMessageLoopMultithreadedGtk::DoQuit, base::Unretained(this))));
}
void MainMessageLoopMultithreadedGtk::PostTask(CefRefPtr<CefTask> task) {
base::AutoLock lock_scope(lock_);
// Queue the task.
queued_tasks_.push(task);
}
bool MainMessageLoopMultithreadedGtk::RunsTasksOnCurrentThread() const {
return (thread_id_ == base::PlatformThread::CurrentId());
}
// static
int MainMessageLoopMultithreadedGtk::TriggerRunTasks(void* self) {
static_cast<MainMessageLoopMultithreadedGtk*>(self)->RunTasks();
return G_SOURCE_CONTINUE;
}
void MainMessageLoopMultithreadedGtk::RunTasks() {
DCHECK(RunsTasksOnCurrentThread());
std::queue<CefRefPtr<CefTask>> tasks;
{
base::AutoLock lock_scope(lock_);
tasks.swap(queued_tasks_);
}
// Execute all queued tasks.
while (!tasks.empty()) {
CefRefPtr<CefTask> task = tasks.front();
tasks.pop();
task->Execute();
}
}
void MainMessageLoopMultithreadedGtk::DoQuit() {
DCHECK(RunsTasksOnCurrentThread());
g_main_loop_quit(main_loop_);
}
} // namespace client

View File

@@ -0,0 +1,54 @@
// Copyright (c) 2018 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_TESTS_CEFCLIENT_BROWSER_MAIN_MESSAGE_LOOP_MULTITHREADED_GTK_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_MAIN_MESSAGE_LOOP_MULTITHREADED_GTK_H_
#pragma once
#include <queue>
#include <gdk/gdk.h>
#include "include/base/cef_lock.h"
#include "include/base/cef_platform_thread.h"
#include "tests/shared/browser/main_message_loop.h"
namespace client {
// Represents the main message loop in the browser process when using multi-
// threaded message loop mode on Linux. In this mode there is no Chromium
// message loop running on the main application thread. Instead, this
// implementation utilizes a Glib context for running tasks.
class MainMessageLoopMultithreadedGtk : public MainMessageLoop {
public:
MainMessageLoopMultithreadedGtk();
~MainMessageLoopMultithreadedGtk();
// MainMessageLoop methods.
int Run() OVERRIDE;
void Quit() OVERRIDE;
void PostTask(CefRefPtr<CefTask> task) OVERRIDE;
bool RunsTasksOnCurrentThread() const OVERRIDE;
private:
static int TriggerRunTasks(void* self);
void RunTasks();
void DoQuit();
base::PlatformThreadId thread_id_;
GMainContext* main_context_;
GMainLoop* main_loop_;
base::Lock lock_;
// Must be protected by |lock_|.
std::queue<CefRefPtr<CefTask>> queued_tasks_;
DISALLOW_COPY_AND_ASSIGN(MainMessageLoopMultithreadedGtk);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_MAIN_MESSAGE_LOOP_MULTITHREADED_GTK_H_

View File

@@ -10,11 +10,13 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gtk/gtkunixprint.h> #include <gtk/gtkunixprint.h>
#include "include/base/cef_bind.h"
#include "include/base/cef_logging.h" #include "include/base/cef_logging.h"
#include "include/base/cef_macros.h" #include "include/base/cef_macros.h"
#include "include/wrapper/cef_helpers.h" #include "include/wrapper/cef_helpers.h"
#include "tests/cefclient/browser/root_window.h" #include "tests/cefclient/browser/root_window.h"
#include "tests/cefclient/browser/util_gtk.h"
namespace client { namespace client {
@@ -270,6 +272,33 @@ void InitPrintSettings(GtkPrintSettings* settings,
printable_area_device_units, true); printable_area_device_units, true);
} }
// Returns the GtkWindow* for the browser. Will return NULL when using the Views
// framework.
GtkWindow* GetWindow(CefRefPtr<CefBrowser> browser) {
scoped_refptr<RootWindow> root_window =
RootWindow::GetForBrowser(browser->GetIdentifier());
if (root_window)
return GTK_WINDOW(root_window->GetWindowHandle());
return NULL;
}
void RunCallback(base::Callback<void(GtkWindow*)> callback, GtkWindow* window) {
callback.Run(window);
}
void GetWindowAndContinue(CefRefPtr<CefBrowser> browser,
base::Callback<void(GtkWindow*)> callback) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(base::Bind(GetWindowAndContinue, browser, callback));
return;
}
GtkWindow* window = GetWindow(browser);
if (window) {
CefPostTask(TID_UI, base::Bind(RunCallback, callback, window));
}
}
} // namespace } // namespace
struct ClientPrintHandlerGtk::PrintHandler { struct ClientPrintHandlerGtk::PrintHandler {
@@ -281,6 +310,8 @@ struct ClientPrintHandlerGtk::PrintHandler {
printer_(NULL) {} printer_(NULL) {}
~PrintHandler() { ~PrintHandler() {
ScopedGdkThreadsEnter scoped_gdk_threads;
if (dialog_) { if (dialog_) {
gtk_widget_destroy(dialog_); gtk_widget_destroy(dialog_);
dialog_ = NULL; dialog_ = NULL;
@@ -301,6 +332,8 @@ struct ClientPrintHandlerGtk::PrintHandler {
void OnPrintSettings(CefRefPtr<CefPrintSettings> settings, void OnPrintSettings(CefRefPtr<CefPrintSettings> settings,
bool get_defaults) { bool get_defaults) {
ScopedGdkThreadsEnter scoped_gdk_threads;
if (get_defaults) { if (get_defaults) {
DCHECK(!page_setup_); DCHECK(!page_setup_);
DCHECK(!printer_); DCHECK(!printer_);
@@ -369,11 +402,13 @@ struct ClientPrintHandlerGtk::PrintHandler {
InitPrintSettings(gtk_settings_, page_setup_, settings); InitPrintSettings(gtk_settings_, page_setup_, settings);
} }
bool OnPrintDialog(bool has_selection, void OnPrintDialog(bool has_selection,
CefRefPtr<CefPrintDialogCallback> callback) { CefRefPtr<CefPrintDialogCallback> callback,
GtkWindow* parent) {
dialog_callback_ = callback; dialog_callback_ = callback;
GtkWindow* parent = GetWindow(); ScopedGdkThreadsEnter scoped_gdk_threads;
// TODO(estade): We need a window title here. // TODO(estade): We need a window title here.
dialog_ = gtk_print_unix_dialog_new(NULL, parent); dialog_ = gtk_print_unix_dialog_new(NULL, parent);
g_signal_connect(dialog_, "delete-event", g_signal_connect(dialog_, "delete-event",
@@ -401,8 +436,6 @@ struct ClientPrintHandlerGtk::PrintHandler {
g_signal_connect(dialog_, "response", G_CALLBACK(OnDialogResponseThunk), g_signal_connect(dialog_, "response", G_CALLBACK(OnDialogResponseThunk),
this); this);
gtk_widget_show(dialog_); gtk_widget_show(dialog_);
return true;
} }
bool OnPrintJob(const CefString& document_name, bool OnPrintJob(const CefString& document_name,
@@ -413,6 +446,8 @@ struct ClientPrintHandlerGtk::PrintHandler {
if (!printer_) if (!printer_)
return false; return false;
ScopedGdkThreadsEnter scoped_gdk_threads;
job_callback_ = callback; job_callback_ = callback;
// Save the settings for next time. // Save the settings for next time.
@@ -428,16 +463,6 @@ struct ClientPrintHandlerGtk::PrintHandler {
} }
private: private:
// Returns the GtkWindow* for the browser. Will return NULL when using the
// Views framework.
GtkWindow* GetWindow() {
scoped_refptr<RootWindow> root_window =
RootWindow::GetForBrowser(browser_->GetIdentifier());
if (root_window)
return GTK_WINDOW(root_window->GetWindowHandle());
return NULL;
}
void OnDialogResponse(GtkDialog* dialog, gint response_id) { void OnDialogResponse(GtkDialog* dialog, gint response_id) {
int num_matched_handlers = g_signal_handlers_disconnect_by_func( int num_matched_handlers = g_signal_handlers_disconnect_by_func(
dialog_, reinterpret_cast<gpointer>(&OnDialogResponseThunk), this); dialog_, reinterpret_cast<gpointer>(&OnDialogResponseThunk), this);
@@ -581,7 +606,11 @@ bool ClientPrintHandlerGtk::OnPrintDialog(
CefRefPtr<CefPrintDialogCallback> callback) { CefRefPtr<CefPrintDialogCallback> callback) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
return GetPrintHandler(browser)->OnPrintDialog(has_selection, callback); PrintHandler* print_handler = GetPrintHandler(browser);
GetWindowAndContinue(browser, base::Bind(&PrintHandler::OnPrintDialog,
base::Unretained(print_handler),
has_selection, callback));
return true;
} }
bool ClientPrintHandlerGtk::OnPrintJob( bool ClientPrintHandlerGtk::OnPrintJob(
@@ -609,6 +638,8 @@ void ClientPrintHandlerGtk::OnPrintReset(CefRefPtr<CefBrowser> browser) {
CefSize ClientPrintHandlerGtk::GetPdfPaperSize(int device_units_per_inch) { CefSize ClientPrintHandlerGtk::GetPdfPaperSize(int device_units_per_inch) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
GtkPageSetup* page_setup = gtk_page_setup_new(); GtkPageSetup* page_setup = gtk_page_setup_new();
float width = gtk_page_setup_get_paper_width(page_setup, GTK_UNIT_INCH); float width = gtk_page_setup_get_paper_width(page_setup, GTK_UNIT_INCH);

View File

@@ -10,7 +10,8 @@
namespace client { namespace client {
RootWindowConfig::RootWindowConfig() RootWindowConfig::RootWindowConfig()
: with_controls(true), : always_on_top(false),
with_controls(true),
with_osr(false), with_osr(false),
with_extension(false), with_extension(false),
initially_hidden(false), initially_hidden(false),

View File

@@ -23,6 +23,9 @@ namespace client {
struct RootWindowConfig { struct RootWindowConfig {
RootWindowConfig(); RootWindowConfig();
// If true the window will always display above other windows.
bool always_on_top;
// If true the window will show controls. // If true the window will show controls.
bool with_controls; bool with_controls;

View File

@@ -18,6 +18,7 @@
#include "tests/cefclient/browser/main_context.h" #include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/resource.h" #include "tests/cefclient/browser/resource.h"
#include "tests/cefclient/browser/temp_window.h" #include "tests/cefclient/browser/temp_window.h"
#include "tests/cefclient/browser/util_gtk.h"
#include "tests/cefclient/browser/window_test_runner_gtk.h" #include "tests/cefclient/browser/window_test_runner_gtk.h"
#include "tests/shared/browser/main_message_loop.h" #include "tests/shared/browser/main_message_loop.h"
#include "tests/shared/common/client_switches.h" #include "tests/shared/common/client_switches.h"
@@ -50,6 +51,7 @@ void MaximizeWindow(GtkWindow* window) {
RootWindowGtk::RootWindowGtk() RootWindowGtk::RootWindowGtk()
: with_controls_(false), : with_controls_(false),
always_on_top_(false),
with_osr_(false), with_osr_(false),
with_extension_(false), with_extension_(false),
is_popup_(false), is_popup_(false),
@@ -62,9 +64,10 @@ RootWindowGtk::RootWindowGtk()
url_entry_(NULL), url_entry_(NULL),
toolbar_height_(0), toolbar_height_(0),
menubar_height_(0), menubar_height_(0),
force_close_(false),
window_destroyed_(false), window_destroyed_(false),
browser_destroyed_(false) {} browser_destroyed_(false),
force_close_(false),
is_closing_(false) {}
RootWindowGtk::~RootWindowGtk() { RootWindowGtk::~RootWindowGtk() {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
@@ -82,6 +85,7 @@ void RootWindowGtk::Init(RootWindow::Delegate* delegate,
delegate_ = delegate; delegate_ = delegate;
with_controls_ = config.with_controls; with_controls_ = config.with_controls;
always_on_top_ = config.always_on_top;
with_osr_ = config.with_osr; with_osr_ = config.with_osr;
with_extension_ = config.with_extension; with_extension_ = config.with_extension;
start_rect_ = config.bounds; start_rect_ = config.bounds;
@@ -140,6 +144,8 @@ void RootWindowGtk::Show(ShowMode mode) {
if (!window_) if (!window_)
return; return;
ScopedGdkThreadsEnter scoped_gdk_threads;
// Show the GTK window. // Show the GTK window.
gtk_widget_show_all(window_); gtk_widget_show_all(window_);
@@ -158,6 +164,8 @@ void RootWindowGtk::Show(ShowMode mode) {
void RootWindowGtk::Hide() { void RootWindowGtk::Hide() {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
if (window_) if (window_)
gtk_widget_hide(window_); gtk_widget_hide(window_);
} }
@@ -168,6 +176,8 @@ void RootWindowGtk::SetBounds(int x, int y, size_t width, size_t height) {
if (!window_) if (!window_)
return; return;
ScopedGdkThreadsEnter scoped_gdk_threads;
GtkWindow* window = GTK_WINDOW(window_); GtkWindow* window = GTK_WINDOW(window_);
GdkWindow* gdk_window = gtk_widget_get_window(window_); GdkWindow* gdk_window = gtk_widget_get_window(window_);
@@ -184,7 +194,11 @@ void RootWindowGtk::Close(bool force) {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
if (window_) { if (window_) {
force_close_ = force; ScopedGdkThreadsEnter scoped_gdk_threads;
if (force) {
NotifyForceClose();
}
gtk_widget_destroy(window_); gtk_widget_destroy(window_);
} }
} }
@@ -258,7 +272,15 @@ void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings,
height = start_rect_.height; height = start_rect_.height;
} }
ScopedGdkThreadsEnter scoped_gdk_threads;
window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
CHECK(window_);
if (always_on_top_) {
gtk_window_set_keep_above(GTK_WINDOW(window_), TRUE);
}
gtk_window_set_default_size(GTK_WINDOW(window_), width, height); gtk_window_set_default_size(GTK_WINDOW(window_), width, height);
g_signal_connect(G_OBJECT(window_), "focus-in-event", g_signal_connect(G_OBJECT(window_), "focus-in-event",
G_CALLBACK(&RootWindowGtk::WindowFocusIn), this); G_CALLBACK(&RootWindowGtk::WindowFocusIn), this);
@@ -345,6 +367,17 @@ void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings,
// added to the Vbox container for automatic layout-based sizing. // added to the Vbox container for automatic layout-based sizing.
GtkWidget* parent = with_osr_ ? vbox : window_; GtkWidget* parent = with_osr_ ? vbox : window_;
// Set the Display associated with the browser.
::Display* xdisplay = GDK_WINDOW_XDISPLAY(gtk_widget_get_window(window_));
CHECK(xdisplay);
if (with_osr_) {
static_cast<BrowserWindowOsrGtk*>(browser_window_.get())
->set_xdisplay(xdisplay);
} else {
static_cast<BrowserWindowStdGtk*>(browser_window_.get())
->set_xdisplay(xdisplay);
}
if (!is_popup_) { if (!is_popup_) {
// Create the browser window. // Create the browser window.
browser_window_->CreateBrowser(parent, browser_bounds_, settings, browser_window_->CreateBrowser(parent, browser_bounds_, settings,
@@ -368,6 +401,16 @@ void RootWindowGtk::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
delegate_->OnBrowserCreated(this, browser); delegate_->OnBrowserCreated(this, browser);
} }
void RootWindowGtk::OnBrowserWindowClosing() {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI,
base::Bind(&RootWindowGtk::OnBrowserWindowClosing, this));
return;
}
is_closing_ = true;
}
void RootWindowGtk::OnBrowserWindowDestroyed() { void RootWindowGtk::OnBrowserWindowDestroyed() {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
@@ -380,14 +423,15 @@ void RootWindowGtk::OnBrowserWindowDestroyed() {
Close(true); Close(true);
} }
browser_destroyed_ = true; NotifyDestroyedIfDone(false, true);
NotifyDestroyedIfDone();
} }
void RootWindowGtk::OnSetAddress(const std::string& url) { void RootWindowGtk::OnSetAddress(const std::string& url) {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
if (url_entry_) { if (url_entry_) {
ScopedGdkThreadsEnter scoped_gdk_threads;
std::string urlStr(url); std::string urlStr(url);
gtk_entry_set_text(GTK_ENTRY(url_entry_), urlStr.c_str()); gtk_entry_set_text(GTK_ENTRY(url_entry_), urlStr.c_str());
} }
@@ -397,6 +441,8 @@ void RootWindowGtk::OnSetTitle(const std::string& title) {
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
if (window_) { if (window_) {
ScopedGdkThreadsEnter scoped_gdk_threads;
std::string titleStr(title); std::string titleStr(title);
gtk_window_set_title(GTK_WINDOW(window_), titleStr.c_str()); gtk_window_set_title(GTK_WINDOW(window_), titleStr.c_str());
} }
@@ -422,6 +468,8 @@ void RootWindowGtk::OnAutoResize(const CefSize& new_size) {
if (!window_) if (!window_)
return; return;
ScopedGdkThreadsEnter scoped_gdk_threads;
GtkWindow* window = GTK_WINDOW(window_); GtkWindow* window = GTK_WINDOW(window_);
GdkWindow* gdk_window = gtk_widget_get_window(window_); GdkWindow* gdk_window = gtk_widget_get_window(window_);
@@ -440,6 +488,8 @@ void RootWindowGtk::OnSetLoadingState(bool isLoading,
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
if (with_controls_) { if (with_controls_) {
ScopedGdkThreadsEnter scoped_gdk_threads;
gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), isLoading); gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), isLoading);
gtk_widget_set_sensitive(GTK_WIDGET(reload_button_), !isLoading); gtk_widget_set_sensitive(GTK_WIDGET(reload_button_), !isLoading);
gtk_widget_set_sensitive(GTK_WIDGET(back_button_), canGoBack); gtk_widget_set_sensitive(GTK_WIDGET(back_button_), canGoBack);
@@ -453,7 +503,176 @@ void RootWindowGtk::OnSetDraggableRegions(
// TODO(cef): Implement support for draggable regions on this platform. // TODO(cef): Implement support for draggable regions on this platform.
} }
void RootWindowGtk::NotifyDestroyedIfDone() { void RootWindowGtk::NotifyMoveOrResizeStarted() {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(
base::Bind(&RootWindowGtk::NotifyMoveOrResizeStarted, this));
return;
}
// Called when size, position or stack order changes.
CefRefPtr<CefBrowser> browser = GetBrowser();
if (browser.get()) {
// Notify the browser of move/resize events so that:
// - Popup windows are displayed in the correct location and dismissed
// when the window moves.
// - Drag&drop areas are updated accordingly.
browser->GetHost()->NotifyMoveOrResizeStarted();
}
}
void RootWindowGtk::NotifySetFocus() {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(base::Bind(&RootWindowGtk::NotifySetFocus, this));
return;
}
if (!browser_window_.get())
return;
browser_window_->SetFocus(true);
delegate_->OnRootWindowActivated(this);
}
void RootWindowGtk::NotifyVisibilityChange(bool show) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(
base::Bind(&RootWindowGtk::NotifyVisibilityChange, this, show));
return;
}
if (!browser_window_.get())
return;
if (show)
browser_window_->Show();
else
browser_window_->Hide();
}
void RootWindowGtk::NotifyMenuBarHeight(int height) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(
base::Bind(&RootWindowGtk::NotifyMenuBarHeight, this, height));
return;
}
menubar_height_ = height;
}
void RootWindowGtk::NotifyContentBounds(int x, int y, int width, int height) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(base::Bind(&RootWindowGtk::NotifyContentBounds, this, x,
y, width, height));
return;
}
// Offset browser positioning by any controls that will appear in the client
// area.
const int ux_height = toolbar_height_ + menubar_height_;
const int browser_x = x;
const int browser_y = y + ux_height;
const int browser_width = width;
const int browser_height = height - ux_height;
// Size the browser window to match the GTK widget.
browser_bounds_ =
CefRect(browser_x, browser_y, browser_width, browser_height);
if (browser_window_.get()) {
browser_window_->SetBounds(browser_x, browser_y, browser_width,
browser_height);
}
}
void RootWindowGtk::NotifyLoadURL(const std::string& url) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(base::Bind(&RootWindowGtk::NotifyLoadURL, this, url));
return;
}
CefRefPtr<CefBrowser> browser = GetBrowser();
if (browser.get()) {
browser->GetMainFrame()->LoadURL(url);
}
}
void RootWindowGtk::NotifyButtonClicked(int id) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(
base::Bind(&RootWindowGtk::NotifyButtonClicked, this, id));
return;
}
CefRefPtr<CefBrowser> browser = GetBrowser();
if (!browser.get())
return;
switch (id) {
case IDC_NAV_BACK:
browser->GoBack();
break;
case IDC_NAV_FORWARD:
browser->GoForward();
break;
case IDC_NAV_RELOAD:
browser->Reload();
break;
case IDC_NAV_STOP:
browser->StopLoad();
break;
default:
NOTREACHED() << "id=" << id;
}
}
void RootWindowGtk::NotifyMenuItem(int id) {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(base::Bind(&RootWindowGtk::NotifyMenuItem, this, id));
return;
}
// Run the test.
if (delegate_)
delegate_->OnTest(this, id);
}
void RootWindowGtk::NotifyForceClose() {
if (!CefCurrentlyOn(TID_UI)) {
CefPostTask(TID_UI, base::Bind(&RootWindowGtk::NotifyForceClose, this));
return;
}
force_close_ = true;
}
void RootWindowGtk::NotifyCloseBrowser() {
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(base::Bind(&RootWindowGtk::NotifyCloseBrowser, this));
return;
}
CefRefPtr<CefBrowser> browser = GetBrowser();
if (browser) {
browser->GetHost()->CloseBrowser(false);
}
}
void RootWindowGtk::NotifyDestroyedIfDone(bool window_destroyed,
bool browser_destroyed) {
// Each call will to this method will set only one state flag.
DCHECK_EQ(1, window_destroyed + browser_destroyed);
if (!CURRENTLY_ON_MAIN_THREAD()) {
MAIN_POST_CLOSURE(base::Bind(&RootWindowGtk::NotifyDestroyedIfDone, this,
window_destroyed, browser_destroyed));
return;
}
if (window_destroyed)
window_destroyed_ = true;
if (browser_destroyed)
browser_destroyed_ = true;
// Notify once both the window and the browser have been destroyed. // Notify once both the window and the browser have been destroyed.
if (window_destroyed_ && browser_destroyed_) if (window_destroyed_ && browser_destroyed_)
delegate_->OnRootWindowDestroyed(this); delegate_->OnRootWindowDestroyed(this);
@@ -463,9 +682,11 @@ void RootWindowGtk::NotifyDestroyedIfDone() {
gboolean RootWindowGtk::WindowFocusIn(GtkWidget* widget, gboolean RootWindowGtk::WindowFocusIn(GtkWidget* widget,
GdkEventFocus* event, GdkEventFocus* event,
RootWindowGtk* self) { RootWindowGtk* self) {
if (event->in && self->browser_window_.get()) { CEF_REQUIRE_UI_THREAD();
self->browser_window_->SetFocus(true);
self->delegate_->OnRootWindowActivated(self); if (event->in) {
self->NotifySetFocus();
// Return true for a windowed browser so that focus is not passed to GTK. // Return true for a windowed browser so that focus is not passed to GTK.
return self->with_osr_ ? FALSE : TRUE; return self->with_osr_ ? FALSE : TRUE;
} }
@@ -477,14 +698,13 @@ gboolean RootWindowGtk::WindowFocusIn(GtkWidget* widget,
gboolean RootWindowGtk::WindowState(GtkWidget* widget, gboolean RootWindowGtk::WindowState(GtkWidget* widget,
GdkEventWindowState* event, GdkEventWindowState* event,
RootWindowGtk* self) { RootWindowGtk* self) {
CEF_REQUIRE_UI_THREAD();
// Called when the root window is iconified or restored. Hide the browser // Called when the root window is iconified or restored. Hide the browser
// window when the root window is iconified to reduce resource usage. // window when the root window is iconified to reduce resource usage.
if ((event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) && if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) {
self->browser_window_.get()) { self->NotifyVisibilityChange(
if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED));
self->browser_window_->Hide();
else
self->browser_window_->Show();
} }
return TRUE; return TRUE;
@@ -494,45 +714,35 @@ gboolean RootWindowGtk::WindowState(GtkWidget* widget,
gboolean RootWindowGtk::WindowConfigure(GtkWindow* window, gboolean RootWindowGtk::WindowConfigure(GtkWindow* window,
GdkEvent* event, GdkEvent* event,
RootWindowGtk* self) { RootWindowGtk* self) {
// Called when size, position or stack order changes. CEF_REQUIRE_UI_THREAD();
CefRefPtr<CefBrowser> browser = self->GetBrowser(); self->NotifyMoveOrResizeStarted();
if (browser.get()) {
// Notify the browser of move/resize events so that:
// - Popup windows are displayed in the correct location and dismissed
// when the window moves.
// - Drag&drop areas are updated accordingly.
browser->GetHost()->NotifyMoveOrResizeStarted();
}
return FALSE; // Don't stop this message. return FALSE; // Don't stop this message.
} }
// static // static
void RootWindowGtk::WindowDestroy(GtkWidget* widget, RootWindowGtk* self) { void RootWindowGtk::WindowDestroy(GtkWidget* widget, RootWindowGtk* self) {
// Called when the root window is destroyed. // May be called on the main thread or the UI thread.
self->window_destroyed_ = true; self->NotifyDestroyedIfDone(true, false);
self->NotifyDestroyedIfDone();
} }
// static // static
gboolean RootWindowGtk::WindowDelete(GtkWidget* widget, gboolean RootWindowGtk::WindowDelete(GtkWidget* widget,
GdkEvent* event, GdkEvent* event,
RootWindowGtk* self) { RootWindowGtk* self) {
CEF_REQUIRE_UI_THREAD();
// Called to query whether the root window should be closed. // Called to query whether the root window should be closed.
if (self->force_close_) if (self->force_close_)
return FALSE; // Allow the close. return FALSE; // Allow the close.
if (self->browser_window_.get() && !self->browser_window_->IsClosing()) { if (!self->is_closing_) {
CefRefPtr<CefBrowser> browser = self->GetBrowser(); // Notify the browser window that we would like to close it. This
if (browser) { // will result in a call to ClientHandler::DoClose() if the
// Notify the browser window that we would like to close it. This // JavaScript 'onbeforeunload' event handler allows it.
// will result in a call to ClientHandler::DoClose() if the self->NotifyCloseBrowser();
// JavaScript 'onbeforeunload' event handler allows it.
browser->GetHost()->CloseBrowser(false);
// Cancel the close. // Cancel the close.
return TRUE; return TRUE;
}
} }
// Allow the close. // Allow the close.
@@ -543,35 +753,27 @@ gboolean RootWindowGtk::WindowDelete(GtkWidget* widget,
void RootWindowGtk::VboxSizeAllocated(GtkWidget* widget, void RootWindowGtk::VboxSizeAllocated(GtkWidget* widget,
GtkAllocation* allocation, GtkAllocation* allocation,
RootWindowGtk* self) { RootWindowGtk* self) {
// Offset browser positioning by any controls that will appear in the client // May be called on the main thread and the UI thread.
// area. self->NotifyContentBounds(allocation->x, allocation->y, allocation->width,
const int ux_height = self->toolbar_height_ + self->menubar_height_; allocation->height);
const int x = allocation->x;
const int y = allocation->y + ux_height;
const int width = allocation->width;
const int height = allocation->height - ux_height;
// Size the browser window to match the GTK widget.
self->browser_bounds_ = CefRect(x, y, width, height);
if (self->browser_window_.get())
self->browser_window_->SetBounds(x, y, width, height);
} }
// static // static
void RootWindowGtk::MenubarSizeAllocated(GtkWidget* widget, void RootWindowGtk::MenubarSizeAllocated(GtkWidget* widget,
GtkAllocation* allocation, GtkAllocation* allocation,
RootWindowGtk* self) { RootWindowGtk* self) {
self->menubar_height_ = allocation->height; // May be called on the main thread and the UI thread.
self->NotifyMenuBarHeight(allocation->height);
} }
// static // static
gboolean RootWindowGtk::MenuItemActivated(GtkWidget* widget, gboolean RootWindowGtk::MenuItemActivated(GtkWidget* widget,
RootWindowGtk* self) { RootWindowGtk* self) {
CEF_REQUIRE_UI_THREAD();
// Retrieve the menu ID set in AddMenuEntry. // Retrieve the menu ID set in AddMenuEntry.
int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), kMenuIdKey)); int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), kMenuIdKey));
// Run the test. self->NotifyMenuItem(id);
if (self->delegate_)
self->delegate_->OnTest(self, id);
return FALSE; // Don't stop this message. return FALSE; // Don't stop this message.
} }
@@ -585,47 +787,43 @@ void RootWindowGtk::ToolbarSizeAllocated(GtkWidget* widget,
// static // static
void RootWindowGtk::BackButtonClicked(GtkButton* button, RootWindowGtk* self) { void RootWindowGtk::BackButtonClicked(GtkButton* button, RootWindowGtk* self) {
CefRefPtr<CefBrowser> browser = self->GetBrowser(); CEF_REQUIRE_UI_THREAD();
if (browser.get()) self->NotifyButtonClicked(IDC_NAV_BACK);
browser->GoBack();
} }
// static // static
void RootWindowGtk::ForwardButtonClicked(GtkButton* button, void RootWindowGtk::ForwardButtonClicked(GtkButton* button,
RootWindowGtk* self) { RootWindowGtk* self) {
CefRefPtr<CefBrowser> browser = self->GetBrowser(); CEF_REQUIRE_UI_THREAD();
if (browser.get()) self->NotifyButtonClicked(IDC_NAV_FORWARD);
browser->GoForward();
} }
// static // static
void RootWindowGtk::StopButtonClicked(GtkButton* button, RootWindowGtk* self) { void RootWindowGtk::StopButtonClicked(GtkButton* button, RootWindowGtk* self) {
CefRefPtr<CefBrowser> browser = self->GetBrowser(); CEF_REQUIRE_UI_THREAD();
if (browser.get()) self->NotifyButtonClicked(IDC_NAV_STOP);
browser->StopLoad();
} }
// static // static
void RootWindowGtk::ReloadButtonClicked(GtkButton* button, void RootWindowGtk::ReloadButtonClicked(GtkButton* button,
RootWindowGtk* self) { RootWindowGtk* self) {
CefRefPtr<CefBrowser> browser = self->GetBrowser(); CEF_REQUIRE_UI_THREAD();
if (browser.get()) self->NotifyButtonClicked(IDC_NAV_RELOAD);
browser->Reload();
} }
// static // static
void RootWindowGtk::URLEntryActivate(GtkEntry* entry, RootWindowGtk* self) { void RootWindowGtk::URLEntryActivate(GtkEntry* entry, RootWindowGtk* self) {
CefRefPtr<CefBrowser> browser = self->GetBrowser(); CEF_REQUIRE_UI_THREAD();
if (browser.get()) { const gchar* url = gtk_entry_get_text(entry);
const gchar* url = gtk_entry_get_text(entry); self->NotifyLoadURL(std::string(url));
browser->GetMainFrame()->LoadURL(std::string(url).c_str());
}
} }
// static // static
gboolean RootWindowGtk::URLEntryButtonPress(GtkWidget* widget, gboolean RootWindowGtk::URLEntryButtonPress(GtkWidget* widget,
GdkEventButton* event, GdkEventButton* event,
RootWindowGtk* self) { RootWindowGtk* self) {
CEF_REQUIRE_UI_THREAD();
// Give focus to the GTK window. This is a work-around for bad focus-related // Give focus to the GTK window. This is a work-around for bad focus-related
// interaction between the root window managed by GTK and the browser managed // interaction between the root window managed by GTK and the browser managed
// by X11. // by X11.

View File

@@ -53,6 +53,7 @@ class RootWindowGtk : public RootWindow, public BrowserWindow::Delegate {
// BrowserWindow::Delegate methods. // BrowserWindow::Delegate methods.
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE; void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
void OnBrowserWindowClosing() OVERRIDE;
void OnBrowserWindowDestroyed() OVERRIDE; void OnBrowserWindowDestroyed() OVERRIDE;
void OnSetAddress(const std::string& url) OVERRIDE; void OnSetAddress(const std::string& url) OVERRIDE;
void OnSetTitle(const std::string& title) OVERRIDE; void OnSetTitle(const std::string& title) OVERRIDE;
@@ -64,7 +65,17 @@ class RootWindowGtk : public RootWindow, public BrowserWindow::Delegate {
void OnSetDraggableRegions( void OnSetDraggableRegions(
const std::vector<CefDraggableRegion>& regions) OVERRIDE; const std::vector<CefDraggableRegion>& regions) OVERRIDE;
void NotifyDestroyedIfDone(); void NotifyMoveOrResizeStarted();
void NotifySetFocus();
void NotifyVisibilityChange(bool show);
void NotifyMenuBarHeight(int height);
void NotifyContentBounds(int x, int y, int width, int height);
void NotifyLoadURL(const std::string& url);
void NotifyButtonClicked(int id);
void NotifyMenuItem(int id);
void NotifyForceClose();
void NotifyCloseBrowser();
void NotifyDestroyedIfDone(bool window_destroyed, bool browser_destroyed);
GtkWidget* CreateMenuBar(); GtkWidget* CreateMenuBar();
GtkWidget* CreateMenu(GtkWidget* menu_bar, const char* text); GtkWidget* CreateMenu(GtkWidget* menu_bar, const char* text);
@@ -114,6 +125,7 @@ class RootWindowGtk : public RootWindow, public BrowserWindow::Delegate {
// After initialization all members are only accessed on the main thread. // After initialization all members are only accessed on the main thread.
// Members set during initialization. // Members set during initialization.
bool with_controls_; bool with_controls_;
bool always_on_top_;
bool with_osr_; bool with_osr_;
bool with_extension_; bool with_extension_;
bool is_popup_; bool is_popup_;
@@ -139,10 +151,14 @@ class RootWindowGtk : public RootWindow, public BrowserWindow::Delegate {
CefRect browser_bounds_; CefRect browser_bounds_;
bool force_close_;
bool window_destroyed_; bool window_destroyed_;
bool browser_destroyed_; bool browser_destroyed_;
// Members only accessed on the UI thread because they're needed for
// WindowDelete.
bool force_close_;
bool is_closing_;
DISALLOW_COPY_AND_ASSIGN(RootWindowGtk); DISALLOW_COPY_AND_ASSIGN(RootWindowGtk);
}; };

View File

@@ -159,6 +159,11 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
CefBrowserSettings& settings) { CefBrowserSettings& settings) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
if (!temp_window_) {
// TempWindow must be created on the UI thread.
temp_window_.reset(new TempWindow());
}
MainContext::Get()->PopulateBrowserSettings(&settings); MainContext::Get()->PopulateBrowserSettings(&settings);
scoped_refptr<RootWindow> root_window = scoped_refptr<RootWindow> root_window =
@@ -390,8 +395,9 @@ void RootWindowManager::OnRootWindowDestroyed(RootWindow* root_window) {
} }
if (terminate_when_all_windows_closed_ && root_windows_.empty()) { if (terminate_when_all_windows_closed_ && root_windows_.empty()) {
// Quit the main message loop after all windows have closed. // All windows have closed. Clean up on the UI thread.
MainMessageLoop::Get()->Quit(); CefPostTask(TID_UI, base::Bind(&RootWindowManager::CleanupOnUIThread,
base::Unretained(this)));
} }
} }
@@ -440,4 +446,16 @@ void RootWindowManager::CreateExtensionWindow(
} }
} }
void RootWindowManager::CleanupOnUIThread() {
CEF_REQUIRE_UI_THREAD();
if (temp_window_) {
// TempWindow must be destroyed on the UI thread.
temp_window_.reset(nullptr);
}
// Quit the main message loop.
MainMessageLoop::Get()->Quit();
}
} // namespace client } // namespace client

View File

@@ -106,6 +106,8 @@ class RootWindowManager : public RootWindow::Delegate {
const base::Closure& close_callback, const base::Closure& close_callback,
bool with_osr) OVERRIDE; bool with_osr) OVERRIDE;
void CleanupOnUIThread();
const bool terminate_when_all_windows_closed_; const bool terminate_when_all_windows_closed_;
bool request_context_per_browser_; bool request_context_per_browser_;
bool request_context_shared_cache_; bool request_context_shared_cache_;
@@ -124,7 +126,7 @@ class RootWindowManager : public RootWindow::Delegate {
CefRefPtr<CefBrowser> active_browser_; CefRefPtr<CefBrowser> active_browser_;
// Singleton window used as the temporary parent for popup browsers. // Singleton window used as the temporary parent for popup browsers.
TempWindow temp_window_; scoped_ptr<TempWindow> temp_window_;
CefRefPtr<CefRequestContext> shared_request_context_; CefRefPtr<CefRequestContext> shared_request_context_;

View File

@@ -21,6 +21,7 @@ static const char* kDefaultImageCache[] = {"menu_icon", "window_icon"};
RootWindowViews::RootWindowViews() RootWindowViews::RootWindowViews()
: with_controls_(false), : with_controls_(false),
always_on_top_(false),
with_extension_(false), with_extension_(false),
initially_hidden_(false), initially_hidden_(false),
is_popup_(false), is_popup_(false),
@@ -42,6 +43,7 @@ void RootWindowViews::Init(RootWindow::Delegate* delegate,
delegate_ = delegate; delegate_ = delegate;
with_controls_ = config.with_controls; with_controls_ = config.with_controls;
always_on_top_ = config.always_on_top;
with_extension_ = config.with_extension; with_extension_ = config.with_extension;
initially_hidden_ = config.initially_hidden; initially_hidden_ = config.initially_hidden;
if (initially_hidden_ && !config.source_bounds.IsEmpty()) { if (initially_hidden_ && !config.source_bounds.IsEmpty()) {
@@ -239,6 +241,7 @@ void RootWindowViews::OnViewsWindowCreated(CefRefPtr<ViewsWindow> window) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
DCHECK(!window_); DCHECK(!window_);
window_ = window; window_ = window;
window_->SetAlwaysOnTop(always_on_top_);
if (!pending_extensions_.empty()) { if (!pending_extensions_.empty()) {
window_->OnExtensionsChanged(pending_extensions_); window_->OnExtensionsChanged(pending_extensions_);

View File

@@ -104,6 +104,7 @@ class RootWindowViews : public RootWindow,
// unless otherwise indicated. // unless otherwise indicated.
// Members set during initialization. // Members set during initialization.
bool with_controls_; bool with_controls_;
bool always_on_top_;
bool with_extension_; bool with_extension_;
bool initially_hidden_; bool initially_hidden_;
CefRefPtr<CefWindow> parent_window_; CefRefPtr<CefWindow> parent_window_;

View File

@@ -103,6 +103,7 @@ int GetURLBarHeight(HWND hwnd) {
RootWindowWin::RootWindowWin() RootWindowWin::RootWindowWin()
: with_controls_(false), : with_controls_(false),
always_on_top_(false),
with_osr_(false), with_osr_(false),
with_extension_(false), with_extension_(false),
is_popup_(false), is_popup_(false),
@@ -152,6 +153,7 @@ void RootWindowWin::Init(RootWindow::Delegate* delegate,
delegate_ = delegate; delegate_ = delegate;
with_controls_ = config.with_controls; with_controls_ = config.with_controls;
always_on_top_ = config.always_on_top;
with_osr_ = config.with_osr; with_osr_ = config.with_osr;
with_extension_ = config.with_extension; with_extension_ = config.with_extension;
@@ -333,6 +335,7 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings,
CHECK(find_message_id_); CHECK(find_message_id_);
const DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; const DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
const DWORD dwExStyle = always_on_top_ ? WS_EX_TOPMOST : 0;
int x, y, width, height; int x, y, width, height;
if (::IsRectEmpty(&start_rect_)) { if (::IsRectEmpty(&start_rect_)) {
@@ -341,7 +344,7 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings,
} else { } else {
// Adjust the window size to account for window frame and controls. // Adjust the window size to account for window frame and controls.
RECT window_rect = start_rect_; RECT window_rect = start_rect_;
::AdjustWindowRectEx(&window_rect, dwStyle, with_controls_, 0); ::AdjustWindowRectEx(&window_rect, dwStyle, with_controls_, dwExStyle);
x = start_rect_.left; x = start_rect_.left;
y = start_rect_.top; y = start_rect_.top;
@@ -352,8 +355,8 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings,
browser_settings_ = settings; browser_settings_ = settings;
// Create the main window initially hidden. // Create the main window initially hidden.
CreateWindow(window_class.c_str(), window_title.c_str(), dwStyle, x, y, width, CreateWindowEx(dwExStyle, window_class.c_str(), window_title.c_str(), dwStyle,
height, NULL, NULL, hInstance, this); x, y, width, height, NULL, NULL, hInstance, this);
CHECK(hwnd_); CHECK(hwnd_);
if (!called_enable_non_client_dpi_scaling_ && IsProcessPerMonitorDpiAware()) { if (!called_enable_non_client_dpi_scaling_ && IsProcessPerMonitorDpiAware()) {

View File

@@ -112,6 +112,7 @@ class RootWindowWin : public RootWindow, public BrowserWindow::Delegate {
// After initialization all members are only accessed on the main thread. // After initialization all members are only accessed on the main thread.
// Members set during initialization. // Members set during initialization.
bool with_controls_; bool with_controls_;
bool always_on_top_;
bool with_osr_; bool with_osr_;
bool with_extension_; bool with_extension_;
bool is_popup_; bool is_popup_;

View File

@@ -11,7 +11,7 @@
namespace client { namespace client {
// Represents a singleton hidden window that acts as a temporary parent for // Represents a singleton hidden window that acts as a temporary parent for
// popup browsers. // popup browsers. Only accessed on the UI thread.
class TempWindowMac { class TempWindowMac {
public: public:
// Returns the singleton window handle. // Returns the singleton window handle.
@@ -20,6 +20,8 @@ class TempWindowMac {
private: private:
// A single instance will be created/owned by RootWindowManager. // A single instance will be created/owned by RootWindowManager.
friend class RootWindowManager; friend class RootWindowManager;
// Allow deletion via scoped_ptr only.
friend struct base::DefaultDeleter<TempWindowMac>;
TempWindowMac(); TempWindowMac();
~TempWindowMac(); ~TempWindowMac();

View File

@@ -11,7 +11,7 @@
namespace client { namespace client {
// Represents a singleton hidden window that acts as a temporary parent for // Represents a singleton hidden window that acts as a temporary parent for
// popup browsers. // popup browsers. Only accessed on the UI thread.
class TempWindowWin { class TempWindowWin {
public: public:
// Returns the singleton window handle. // Returns the singleton window handle.
@@ -20,6 +20,8 @@ class TempWindowWin {
private: private:
// A single instance will be created/owned by RootWindowManager. // A single instance will be created/owned by RootWindowManager.
friend class RootWindowManager; friend class RootWindowManager;
// Allow deletion via scoped_ptr only.
friend struct base::DefaultDeleter<TempWindowWin>;
TempWindowWin(); TempWindowWin();
~TempWindowWin(); ~TempWindowWin();

View File

@@ -16,6 +16,7 @@ namespace {
// Create the temp window. // Create the temp window.
::Window CreateTempWindow() { ::Window CreateTempWindow() {
::Display* xdisplay = cef_get_xdisplay(); ::Display* xdisplay = cef_get_xdisplay();
CHECK(xdisplay != 0);
::Window parent_xwindow = DefaultRootWindow(xdisplay); ::Window parent_xwindow = DefaultRootWindow(xdisplay);
XSetWindowAttributes swa; XSetWindowAttributes swa;
@@ -33,6 +34,7 @@ namespace {
// Close the temp window. // Close the temp window.
void CloseTempWindow(::Window xwindow) { void CloseTempWindow(::Window xwindow) {
::Display* xdisplay = cef_get_xdisplay(); ::Display* xdisplay = cef_get_xdisplay();
CHECK(xdisplay != 0);
XDestroyWindow(xdisplay, xwindow); XDestroyWindow(xdisplay, xwindow);
} }

View File

@@ -11,7 +11,7 @@
namespace client { namespace client {
// Represents a singleton hidden window that acts as a temporary parent for // Represents a singleton hidden window that acts as a temporary parent for
// popup browsers. // popup browsers. Only accessed on the UI thread.
class TempWindowX11 { class TempWindowX11 {
public: public:
// Returns the singleton window handle. // Returns the singleton window handle.
@@ -20,6 +20,8 @@ class TempWindowX11 {
private: private:
// A single instance will be created/owned by RootWindowManager. // A single instance will be created/owned by RootWindowManager.
friend class RootWindowManager; friend class RootWindowManager;
// Allow deletion via scoped_ptr only.
friend struct base::DefaultDeleter<TempWindowX11>;
TempWindowX11(); TempWindowX11();
~TempWindowX11(); ~TempWindowX11();

View File

@@ -0,0 +1,33 @@
// Copyright (c) 2018 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 "tests/cefclient/browser/util_gtk.h"
#include <gdk/gdk.h>
namespace client {
base::PlatformThreadId ScopedGdkThreadsEnter::locked_thread_ =
kInvalidPlatformThreadId;
ScopedGdkThreadsEnter::ScopedGdkThreadsEnter() {
// The GDK lock is not reentrant, so don't try to lock again if the current
// thread already holds it.
base::PlatformThreadId current_thread = base::PlatformThread::CurrentId();
take_lock_ = current_thread != locked_thread_;
if (take_lock_) {
gdk_threads_enter();
locked_thread_ = current_thread;
}
}
ScopedGdkThreadsEnter::~ScopedGdkThreadsEnter() {
if (take_lock_) {
locked_thread_ = kInvalidPlatformThreadId;
gdk_threads_leave();
}
}
} // namespace client

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2018 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_TESTS_CEFCLIENT_BROWSER_UTIL_GTK_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_UTIL_GTK_H_
#pragma once
#include "include/base/cef_macros.h"
#include "include/base/cef_platform_thread.h"
namespace client {
// Scoped helper that manages the global GDK lock by calling gdk_threads_enter()
// and gdk_threads_leave(). The lock is not reentrant so this helper implements
// additional checking to avoid deadlocks.
//
// When using GTK in multi-threaded mode you must do the following:
// 1. Call gdk_threads_init() before making any other GTK/GDK/GLib calls.
// 2. Acquire the global lock before making any GTK/GDK calls, and release the
// lock afterwards. This should only be done with callbacks that do not
// originate from GTK signals (because those callbacks already hold the
// lock).
//
// See https://www.geany.org/manual/gtk/gtk-faq/x482.html for more information.
class ScopedGdkThreadsEnter {
public:
ScopedGdkThreadsEnter();
~ScopedGdkThreadsEnter();
private:
bool take_lock_;
static base::PlatformThreadId locked_thread_;
DISALLOW_COPY_AND_ASSIGN(ScopedGdkThreadsEnter);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_UTIL_GTK_H_

View File

@@ -222,6 +222,13 @@ void ViewsWindow::SetFullscreen(bool fullscreen) {
} }
} }
void ViewsWindow::SetAlwaysOnTop(bool on_top) {
CEF_REQUIRE_UI_THREAD();
if (window_) {
window_->SetAlwaysOnTop(on_top);
}
}
void ViewsWindow::SetLoadingState(bool isLoading, void ViewsWindow::SetLoadingState(bool isLoading,
bool canGoBack, bool canGoBack,
bool canGoForward) { bool canGoForward) {

View File

@@ -112,6 +112,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
void SetTitle(const std::string& title); void SetTitle(const std::string& title);
void SetFavicon(CefRefPtr<CefImage> image); void SetFavicon(CefRefPtr<CefImage> image);
void SetFullscreen(bool fullscreen); void SetFullscreen(bool fullscreen);
void SetAlwaysOnTop(bool on_top);
void SetLoadingState(bool isLoading, bool canGoBack, bool canGoForward); void SetLoadingState(bool isLoading, bool canGoBack, bool canGoForward);
void SetDraggableRegions(const std::vector<CefDraggableRegion>& regions); void SetDraggableRegions(const std::vector<CefDraggableRegion>& regions);
void TakeFocus(bool next); void TakeFocus(bool next);

View File

@@ -8,6 +8,7 @@
#include "include/wrapper/cef_helpers.h" #include "include/wrapper/cef_helpers.h"
#include "tests/cefclient/browser/root_window.h" #include "tests/cefclient/browser/root_window.h"
#include "tests/cefclient/browser/util_gtk.h"
#include "tests/shared/browser/main_message_loop.h" #include "tests/shared/browser/main_message_loop.h"
namespace client { namespace client {
@@ -33,17 +34,13 @@ bool IsMaximized(GtkWindow* window) {
return (state & GDK_WINDOW_STATE_MAXIMIZED) ? true : false; return (state & GDK_WINDOW_STATE_MAXIMIZED) ? true : false;
} }
} // namespace void SetPosImpl(CefRefPtr<CefBrowser> browser,
int x,
WindowTestRunnerGtk::WindowTestRunnerGtk() {} int y,
int width,
void WindowTestRunnerGtk::SetPos(CefRefPtr<CefBrowser> browser, int height) {
int x,
int y,
int width,
int height) {
CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
GtkWindow* window = GetWindow(browser); GtkWindow* window = GetWindow(browser);
if (!window) if (!window)
@@ -65,15 +62,15 @@ void WindowTestRunnerGtk::SetPos(CefRefPtr<CefBrowser> browser,
// Make sure the window is inside the display. // Make sure the window is inside the display.
CefRect display_rect(rect.x, rect.y, rect.width, rect.height); CefRect display_rect(rect.x, rect.y, rect.width, rect.height);
CefRect window_rect(x, y, width, height); CefRect window_rect(x, y, width, height);
ModifyBounds(display_rect, window_rect); WindowTestRunner::ModifyBounds(display_rect, window_rect);
gdk_window_move_resize(gdk_window, window_rect.x, window_rect.y, gdk_window_move_resize(gdk_window, window_rect.x, window_rect.y,
window_rect.width, window_rect.height); window_rect.width, window_rect.height);
} }
void WindowTestRunnerGtk::Minimize(CefRefPtr<CefBrowser> browser) { void MinimizeImpl(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
GtkWindow* window = GetWindow(browser); GtkWindow* window = GetWindow(browser);
if (!window) if (!window)
@@ -86,9 +83,9 @@ void WindowTestRunnerGtk::Minimize(CefRefPtr<CefBrowser> browser) {
gtk_window_iconify(window); gtk_window_iconify(window);
} }
void WindowTestRunnerGtk::Maximize(CefRefPtr<CefBrowser> browser) { void MaximizeImpl(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
GtkWindow* window = GetWindow(browser); GtkWindow* window = GetWindow(browser);
if (!window) if (!window)
@@ -96,9 +93,9 @@ void WindowTestRunnerGtk::Maximize(CefRefPtr<CefBrowser> browser) {
gtk_window_maximize(window); gtk_window_maximize(window);
} }
void WindowTestRunnerGtk::Restore(CefRefPtr<CefBrowser> browser) { void RestoreImpl(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
REQUIRE_MAIN_THREAD(); REQUIRE_MAIN_THREAD();
ScopedGdkThreadsEnter scoped_gdk_threads;
GtkWindow* window = GetWindow(browser); GtkWindow* window = GetWindow(browser);
if (!window) if (!window)
@@ -109,5 +106,29 @@ void WindowTestRunnerGtk::Restore(CefRefPtr<CefBrowser> browser) {
gtk_window_present(window); gtk_window_present(window);
} }
} // namespace
WindowTestRunnerGtk::WindowTestRunnerGtk() {}
void WindowTestRunnerGtk::SetPos(CefRefPtr<CefBrowser> browser,
int x,
int y,
int width,
int height) {
MAIN_POST_CLOSURE(base::Bind(SetPosImpl, browser, x, y, width, height));
}
void WindowTestRunnerGtk::Minimize(CefRefPtr<CefBrowser> browser) {
MAIN_POST_CLOSURE(base::Bind(MinimizeImpl, browser));
}
void WindowTestRunnerGtk::Maximize(CefRefPtr<CefBrowser> browser) {
MAIN_POST_CLOSURE(base::Bind(MaximizeImpl, browser));
}
void WindowTestRunnerGtk::Restore(CefRefPtr<CefBrowser> browser) {
MAIN_POST_CLOSURE(base::Bind(RestoreImpl, browser));
}
} // namespace window_test } // namespace window_test
} // namespace client } // namespace client

View File

@@ -19,6 +19,7 @@
#include "include/cef_command_line.h" #include "include/cef_command_line.h"
#include "include/wrapper/cef_helpers.h" #include "include/wrapper/cef_helpers.h"
#include "tests/cefclient/browser/main_context_impl.h" #include "tests/cefclient/browser/main_context_impl.h"
#include "tests/cefclient/browser/main_message_loop_multithreaded_gtk.h"
#include "tests/cefclient/browser/test_runner.h" #include "tests/cefclient/browser/test_runner.h"
#include "tests/shared/browser/client_app_browser.h" #include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/browser/main_message_loop_external_pump.h" #include "tests/shared/browser/main_message_loop_external_pump.h"
@@ -99,7 +100,9 @@ int RunMain(int argc, char* argv[]) {
// Create the main message loop object. // Create the main message loop object.
scoped_ptr<MainMessageLoop> message_loop; scoped_ptr<MainMessageLoop> message_loop;
if (settings.external_message_pump) if (settings.multi_threaded_message_loop)
message_loop.reset(new MainMessageLoopMultithreadedGtk);
else if (settings.external_message_pump)
message_loop = MainMessageLoopExternalPump::Create(); message_loop = MainMessageLoopExternalPump::Create();
else else
message_loop.reset(new MainMessageLoopStd); message_loop.reset(new MainMessageLoopStd);
@@ -127,6 +130,7 @@ int RunMain(int argc, char* argv[]) {
test_runner::RegisterSchemeHandlers(); test_runner::RegisterSchemeHandlers();
RootWindowConfig window_config; RootWindowConfig window_config;
window_config.always_on_top = command_line->HasSwitch(switches::kAlwaysOnTop);
window_config.with_controls = window_config.with_controls =
!command_line->HasSwitch(switches::kHideControls); !command_line->HasSwitch(switches::kHideControls);
window_config.with_osr = settings.windowless_rendering_enabled ? true : false; window_config.with_osr = settings.windowless_rendering_enabled ? true : false;

View File

@@ -95,6 +95,7 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
test_runner::RegisterSchemeHandlers(); test_runner::RegisterSchemeHandlers();
RootWindowConfig window_config; RootWindowConfig window_config;
window_config.always_on_top = command_line->HasSwitch(switches::kAlwaysOnTop);
window_config.with_controls = window_config.with_controls =
!command_line->HasSwitch(switches::kHideControls); !command_line->HasSwitch(switches::kHideControls);
window_config.with_osr = settings.windowless_rendering_enabled ? true : false; window_config.with_osr = settings.windowless_rendering_enabled ? true : false;

View File

@@ -318,6 +318,24 @@ PERF_TEST_FUNC(V8ObjectGetValueWithAccessor) {
PERF_ITERATIONS_END() PERF_ITERATIONS_END()
} }
PERF_TEST_FUNC(V8ArrayBufferCreate) {
class ReleaseCallback : public CefV8ArrayBufferReleaseCallback {
public:
void ReleaseBuffer(void* buffer) override { std::free(buffer); }
IMPLEMENT_REFCOUNTING(ReleaseCallback);
};
size_t len = 1;
size_t byte_len = len * sizeof(float);
CefRefPtr<CefV8ArrayBufferReleaseCallback> callback = new ReleaseCallback();
PERF_ITERATIONS_START()
float* buffer = (float*)std::malloc(byte_len);
CefRefPtr<CefV8Value> ret =
CefV8Value::CreateArrayBuffer(buffer, byte_len, callback);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8ContextEnterExit) { PERF_TEST_FUNC(V8ContextEnterExit) {
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext(); CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
@@ -363,6 +381,7 @@ const PerfTestEntry kPerfTests[] = {
PERF_TEST_ENTRY(V8ObjectGetValue), PERF_TEST_ENTRY(V8ObjectGetValue),
PERF_TEST_ENTRY(V8ObjectSetValueWithAccessor), PERF_TEST_ENTRY(V8ObjectSetValueWithAccessor),
PERF_TEST_ENTRY(V8ObjectGetValueWithAccessor), PERF_TEST_ENTRY(V8ObjectGetValueWithAccessor),
PERF_TEST_ENTRY(V8ArrayBufferCreate),
PERF_TEST_ENTRY(V8ContextEnterExit), PERF_TEST_ENTRY(V8ContextEnterExit),
PERF_TEST_ENTRY(V8ContextEval), PERF_TEST_ENTRY(V8ContextEval),
}; };

View File

@@ -119,7 +119,7 @@ int CefTestSuite::Run() {
} }
void CefTestSuite::GetSettings(CefSettings& settings) const { void CefTestSuite::GetSettings(CefSettings& settings) const {
#if defined(OS_WIN) #if (defined(OS_WIN) || defined(OS_LINUX))
settings.multi_threaded_message_loop = settings.multi_threaded_message_loop =
command_line_->HasSwitch(client::switches::kMultiThreadedMessageLoop); command_line_->HasSwitch(client::switches::kMultiThreadedMessageLoop);
#endif #endif

Some files were not shown because too many files have changed in this diff Show More