- cefclient: Split ClientHandler into an abstract base class and a concrete implementation for shared usage (issue #1500).

- cefclient: Show an alert box when selecting Tests > Popup Window while running in off-screen rendering mode.
- cefclient: Mac: Enable/disable UX buttons to match loading state.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1999 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2015-01-26 19:34:26 +00:00
parent 3f4c5acbe7
commit a66c401687
18 changed files with 721 additions and 620 deletions

View File

@ -156,6 +156,8 @@
'tests/cefclient/client_app_delegates.cc',
'tests/cefclient/client_handler.cc',
'tests/cefclient/client_handler.h',
'tests/cefclient/client_handler_shared.cc',
'tests/cefclient/client_handler_shared.h',
'tests/cefclient/client_renderer.cc',
'tests/cefclient/client_renderer.h',
'tests/cefclient/client_switches.cc',
@ -190,7 +192,7 @@
'tests/cefclient/cefclient.exe.manifest',
'tests/cefclient/cefclient.rc',
'tests/cefclient/cefclient_win.cc',
'tests/cefclient/client_handler_win.cc',
'tests/cefclient/client_handler_shared_win.cc',
'tests/cefclient/main_context_impl_win.cc',
'tests/cefclient/main_message_loop_multithreaded_win.h',
'tests/cefclient/main_message_loop_multithreaded_win.cc',
@ -208,7 +210,7 @@
],
'cefclient_sources_mac': [
'tests/cefclient/cefclient_mac.mm',
'tests/cefclient/client_handler_mac.mm',
'tests/cefclient/client_handler_shared_mac.mm',
'tests/cefclient/main_context_impl_posix.cc',
'tests/cefclient/osr_widget_mac.h',
'tests/cefclient/osr_widget_mac.mm',
@ -224,7 +226,6 @@
'tests/cefclient/client_app_delegates.cc',
'tests/cefclient/client_handler.cc',
'tests/cefclient/client_handler.h',
'tests/cefclient/client_handler_mac.mm',
'tests/cefclient/client_renderer.cc',
'tests/cefclient/client_renderer.h',
'tests/cefclient/client_switches.cc',
@ -260,7 +261,7 @@
],
'cefclient_sources_linux': [
'tests/cefclient/cefclient_gtk.cc',
'tests/cefclient/client_handler_gtk.cc',
'tests/cefclient/client_handler_shared_gtk.cc',
'tests/cefclient/dialog_handler_gtk.cc',
'tests/cefclient/dialog_handler_gtk.h',
'tests/cefclient/main_context_impl_posix.cc',

View File

@ -22,7 +22,7 @@
#include "include/cef_frame.h"
#include "include/wrapper/cef_helpers.h"
#include "cefclient/client_app.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_handler_shared.h"
#include "cefclient/client_switches.h"
#include "cefclient/main_context_impl.h"
#include "cefclient/main_message_loop_std.h"
@ -33,8 +33,8 @@
namespace client {
namespace {
// The global ClientHandler reference.
CefRefPtr<ClientHandler> g_handler;
// The global ClientHandlerShared reference.
CefRefPtr<ClientHandlerShared> g_handler;
// Height of the buttons at the top of the GTK window.
int g_toolbar_height = 0;
@ -427,11 +427,10 @@ int RunMain(int argc, char* argv[]) {
G_CALLBACK(delete_event), window);
// Create the handler.
g_handler = new ClientHandler();
g_handler = new ClientHandlerShared();
g_handler->SetMainWindowHandle(vbox);
g_handler->SetEditWindowHandle(entry);
g_handler->SetButtonWindowHandles(GTK_WIDGET(back), GTK_WIDGET(forward),
GTK_WIDGET(reload), GTK_WIDGET(stop));
g_handler->SetUXWindowHandles(entry, GTK_WIDGET(back), GTK_WIDGET(forward),
GTK_WIDGET(reload), GTK_WIDGET(stop));
CefWindowInfo window_info;
CefBrowserSettings browserSettings;
@ -439,9 +438,9 @@ int RunMain(int argc, char* argv[]) {
// Populate the browser settings based on command line arguments.
context->PopulateBrowserSettings(&browserSettings);
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
if (command_line->HasSwitch(switches::kOffScreenRenderingEnabled)) {
if (g_handler->is_osr()) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
const bool transparent =
command_line->HasSwitch(switches::kTransparentPaintingEnabled);
const bool show_update_rect =
@ -473,7 +472,7 @@ int RunMain(int argc, char* argv[]) {
// Create the browser window.
CefBrowserHost::CreateBrowserSync(
window_info, g_handler.get(),
g_handler->GetStartupURL(), browserSettings, NULL);
g_handler->startup_url(), browserSettings, NULL);
// Install a signal handler so we clean up after ourselves.
signal(SIGINT, TerminationSignalHandler);

View File

@ -21,8 +21,8 @@
namespace {
// The global ClientHandler reference.
CefRefPtr<client::ClientHandler> g_handler;
// The global ClientHandlerShared reference.
CefRefPtr<client::ClientHandlerShared> g_handler;
// Used by off-screen rendering to find the associated CefBrowser.
class MainBrowserProvider : public client::OSRBrowserProvider {
@ -232,8 +232,7 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get()) {
if (CefCommandLine::GetGlobalCommandLine()->HasSwitch(
client::switches::kOffScreenRenderingEnabled)) {
if (g_handler->is_osr())) {
browser->GetHost()->SendFocusEvent(true);
} else {
browser->GetHost()->SetFocus(true);
@ -247,8 +246,7 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get()) {
if (CefCommandLine::GetGlobalCommandLine()->HasSwitch(
client::switches::kOffScreenRenderingEnabled)) {
if (g_handler->is_osr()) {
browser->GetHost()->SendFocusEvent(false);
} else {
browser->GetHost()->SetFocus(false);
@ -402,21 +400,25 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
button_rect.origin.x += BUTTON_MARGIN;
button_rect.size.width = BUTTON_WIDTH;
NSButton* button = MakeButton(&button_rect, @"Back", contentView);
[button setTarget:delegate];
[button setAction:@selector(goBack:)];
NSButton* backButton = MakeButton(&button_rect, @"Back", contentView);
[backButton setTarget:delegate];
[backButton setAction:@selector(goBack:)];
[backButton setEnabled:NO];
button = MakeButton(&button_rect, @"Forward", contentView);
[button setTarget:delegate];
[button setAction:@selector(goForward:)];
NSButton* forwardButton = MakeButton(&button_rect, @"Forward", contentView);
[forwardButton setTarget:delegate];
[forwardButton setAction:@selector(goForward:)];
[forwardButton setEnabled:NO];
button = MakeButton(&button_rect, @"Reload", contentView);
[button setTarget:delegate];
[button setAction:@selector(reload:)];
NSButton* reloadButton = MakeButton(&button_rect, @"Reload", contentView);
[reloadButton setTarget:delegate];
[reloadButton setAction:@selector(reload:)];
[reloadButton setEnabled:NO];
button = MakeButton(&button_rect, @"Stop", contentView);
[button setTarget:delegate];
[button setAction:@selector(stopLoading:)];
NSButton* stopButton = MakeButton(&button_rect, @"Stop", contentView);
[stopButton setTarget:delegate];
[stopButton setAction:@selector(stopLoading:)];
[stopButton setEnabled:NO];
// Create the URL text field.
button_rect.origin.x += BUTTON_MARGIN;
@ -427,13 +429,15 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
[editWnd setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)];
[editWnd setTarget:delegate];
[editWnd setAction:@selector(takeURLStringValueFrom:)];
[editWnd setEnabled:NO];
[[editWnd cell] setWraps:NO];
[[editWnd cell] setScrollable:YES];
// Create the handler.
g_handler = new client::ClientHandler();
g_handler = new client::ClientHandlerShared();
g_handler->SetMainWindowHandle(contentView);
g_handler->SetEditWindowHandle(editWnd);
g_handler->SetUXWindowHandles(editWnd, backButton, forwardButton,
reloadButton, stopButton);
// Create the browser view.
CefWindowInfo window_info;
@ -442,9 +446,9 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
// Populate the browser settings based on command line arguments.
client::MainContext::Get()->PopulateBrowserSettings(&settings);
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
if (command_line->HasSwitch(client::switches::kOffScreenRenderingEnabled)) {
if (g_handler->is_osr()) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
const bool transparent =
command_line->HasSwitch(client::switches::kTransparentPaintingEnabled);
const bool show_update_rect =
@ -462,7 +466,7 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
}
CefBrowserHost::CreateBrowser(window_info, g_handler.get(),
g_handler->GetStartupURL(), settings, NULL);
g_handler->startup_url(), settings, NULL);
// Show the window.
[mainWnd makeKeyAndOrderFront: nil];

View File

@ -17,7 +17,7 @@
#include "include/cef_sandbox_win.h"
#include "include/wrapper/cef_closure_task.h"
#include "cefclient/client_app.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_handler_shared.h"
#include "cefclient/client_switches.h"
#include "cefclient/main_context_impl.h"
#include "cefclient/main_message_loop_multithreaded_win.h"
@ -63,8 +63,8 @@ LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK FindWndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK AboutWndProc(HWND, UINT, WPARAM, LPARAM);
// The global ClientHandler reference.
CefRefPtr<ClientHandler> g_handler;
// The global ClientHandlerShared reference.
CefRefPtr<ClientHandlerShared> g_handler;
// Used by off-screen rendering to find the associated CefBrowser.
class MainBrowserProvider : public OSRBrowserProvider {
@ -197,11 +197,10 @@ static void SetFocusToBrowser(CefRefPtr<CefBrowser> browser) {
if (!g_handler)
return;
if (CefCommandLine::GetGlobalCommandLine()->HasSwitch(
switches::kOffScreenRenderingEnabled)) {
if (g_handler->is_osr()) {
// Give focus to the OSR window.
CefRefPtr<OSRWindow> osr_window =
static_cast<OSRWindow*>(g_handler->GetOSRHandler().get());
OSRWindow::From(g_handler->GetOSRHandler());
if (osr_window)
::SetFocus(osr_window->hwnd());
} else {
@ -295,7 +294,7 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
switch (message) {
case WM_CREATE: {
// Create the single static handler class instance
g_handler = new ClientHandler();
g_handler = new ClientHandlerShared();
g_handler->SetMainWindowHandle(hWnd);
// Create the child windows used for navigation
@ -342,9 +341,8 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
reinterpret_cast<WNDPROC>(GetWindowLongPtr(editWnd, GWLP_WNDPROC));
SetWindowLongPtr(editWnd, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(MainWndProc));
g_handler->SetEditWindowHandle(editWnd);
g_handler->SetButtonWindowHandles(
backWnd, forwardWnd, reloadWnd, stopWnd);
g_handler->SetUXWindowHandles(
editWnd, backWnd, forwardWnd, reloadWnd, stopWnd);
rect.top += URLBAR_HEIGHT;
@ -354,9 +352,9 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
// Populate the browser settings based on command line arguments.
MainContext::Get()->PopulateBrowserSettings(&settings);
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
if (command_line->HasSwitch(switches::kOffScreenRenderingEnabled)) {
if (g_handler->is_osr()) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
const bool transparent =
command_line->HasSwitch(switches::kTransparentPaintingEnabled);
const bool show_update_rect =
@ -375,7 +373,7 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
// Creat the new child browser window
CefBrowserHost::CreateBrowser(info, g_handler.get(),
g_handler->GetStartupURL(), settings, NULL);
g_handler->startup_url(), settings, NULL);
return 0;
}
@ -463,11 +461,10 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam,
// For off-screen browsers when the frame window is minimized set the
// browser as hidden to reduce resource usage.
const bool offscreen = CefCommandLine::GetGlobalCommandLine()->HasSwitch(
switches::kOffScreenRenderingEnabled);
const bool offscreen = g_handler->is_osr();
if (offscreen) {
CefRefPtr<OSRWindow> osr_window =
static_cast<OSRWindow*>(g_handler->GetOSRHandler().get());
OSRWindow::From(g_handler->GetOSRHandler());
if (osr_window)
osr_window->WasHidden(wParam == SIZE_MINIMIZED);
}

View File

@ -3,33 +3,22 @@
// can be found in the LICENSE file.
#include "cefclient/client_handler.h"
#include <stdio.h>
#include <algorithm>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "include/base/cef_bind.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_path_util.h"
#include "include/cef_process_util.h"
#include "include/cef_trace.h"
#include "include/cef_url.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "cefclient/client_renderer.h"
#include "cefclient/client_switches.h"
#include "cefclient/main_context.h"
#include "cefclient/main_message_loop.h"
#include "cefclient/resource_util.h"
#include "cefclient/test_runner.h"
#if defined(OS_LINUX)
#include "cefclient/dialog_handler_gtk.h"
#endif
namespace client {
#if defined(OS_WIN)
@ -54,18 +43,12 @@ enum client_menu_ids {
} // namespace
int ClientHandler::browser_count_ = 0;
ClientHandler::ClientHandler()
: startup_url_(MainContext::Get()->GetMainURL()),
browser_id_(0),
is_closing_(false),
ClientHandler::ClientHandler(const std::string& startup_url,
bool is_osr)
: startup_url_(startup_url),
is_osr_(is_osr),
browser_count_(0),
main_handle_(NULL),
edit_handle_(NULL),
back_handle_(NULL),
forward_handle_(NULL),
stop_handle_(NULL),
reload_handle_(NULL),
console_log_file_(MainContext::Get()->GetConsoleLogPath()),
first_console_message_(true),
focus_on_editable_field_(false) {
@ -73,10 +56,7 @@ ClientHandler::ClientHandler()
#if defined(OS_LINUX)
// Provide the GTK-based dialog implementation on Linux.
CefRefPtr<ClientDialogHandlerGtk> dialog_handler =
new ClientDialogHandlerGtk();
dialog_handler_ = dialog_handler.get();
jsdialog_handler_ = dialog_handler.get();
dialog_handler_ = new ClientDialogHandlerGtk();
#endif
// Read command line settings.
@ -160,6 +140,23 @@ bool ClientHandler::OnContextMenuCommand(
}
}
void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& url) {
CEF_REQUIRE_UI_THREAD();
// Only update the address for the main (top-level) frame.
if (frame->IsMain())
SetAddress(browser, url);
}
void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
SetTitle(browser, title);
}
bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
const CefString& message,
const CefString& source,
@ -247,10 +244,8 @@ bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
// being processed in the renderer. If we instead handled the event in the
// OnKeyEvent() method the space key would cause the window to scroll in
// addition to showing the alert box.
if (event.type == KEYEVENT_RAWKEYDOWN) {
browser->GetMainFrame()->ExecuteJavaScript(
"alert('You pressed the space bar!');", "", 0);
}
if (event.type == KEYEVENT_RAWKEYDOWN)
test_runner::Alert(browser, "You pressed the space bar!");
return true;
}
@ -268,16 +263,15 @@ bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> browser,
bool* no_javascript_access) {
CEF_REQUIRE_IO_THREAD();
if (browser->GetHost()->IsWindowRenderingDisabled()) {
// Cancel popups in off-screen rendering mode.
return true;
}
return false;
// Return true to cancel the popup window.
return !CreatePopupWindow(false, popupFeatures, windowInfo, client, settings);
}
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
browser_count_++;
if (!message_router_) {
// Create the browser-side router for query handling.
CefMessageRouterConfig config;
@ -294,35 +288,13 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
if (mouse_cursor_change_disabled_)
browser->GetHost()->SetMouseCursorChangeDisabled(true);
if (!GetBrowser()) {
base::AutoLock lock_scope(lock_);
// We need to keep the main child window, but not popup windows
browser_ = browser;
browser_id_ = browser->GetIdentifier();
} else if (browser->IsPopup()) {
// Add to the list of popup browsers.
popup_browsers_.push_back(browser);
// Give focus to the popup browser. Perform asynchronously because the
// parent window may attempt to keep focus after launching the popup.
CefPostTask(TID_UI,
base::Bind(&CefBrowserHost::SetFocus, browser->GetHost().get(), true));
}
browser_count_++;
BrowserCreated(browser);
}
bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
// Closing the main window requires special handling. See the DoClose()
// documentation in the CEF header for a detailed destription of this
// process.
if (GetBrowserId() == browser->GetIdentifier()) {
base::AutoLock lock_scope(lock_);
// Set a flag to indicate that the window close should be allowed.
is_closing_ = true;
}
BrowserClosing(browser);
// Allow the close. For windowed browsers this will result in the OS close
// event being sent.
@ -332,44 +304,19 @@ bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
message_router_->OnBeforeClose(browser);
if (GetBrowserId() == browser->GetIdentifier()) {
{
base::AutoLock lock_scope(lock_);
// Free the browser pointer so that the browser can be destroyed
browser_ = NULL;
}
if (osr_handler_.get()) {
osr_handler_->OnBeforeClose(browser);
osr_handler_ = NULL;
}
} else if (browser->IsPopup()) {
// Remove from the browser popup list.
BrowserList::iterator bit = popup_browsers_.begin();
for (; bit != popup_browsers_.end(); ++bit) {
if ((*bit)->IsSame(browser)) {
popup_browsers_.erase(bit);
break;
}
}
}
if (--browser_count_ == 0) {
// All browser windows have closed.
// Remove and delete message router handlers.
MessageHandlerSet::const_iterator it = message_handler_set_.begin();
MessageHandlerSet::const_iterator it =
message_handler_set_.begin();
for (; it != message_handler_set_.end(); ++it) {
message_router_->RemoveHandler(*(it));
delete *(it);
}
message_handler_set_.clear();
message_router_ = NULL;
// Quit the application message loop.
MainMessageLoop::Get()->Quit();
}
BrowserClosed(browser);
}
void ClientHandler::OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
@ -378,8 +325,7 @@ void ClientHandler::OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool canGoForward) {
CEF_REQUIRE_UI_THREAD();
SetLoading(isLoading);
SetNavState(canGoBack, canGoForward);
SetLoadingState(browser, isLoading, canGoBack, canGoForward);
}
void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
@ -425,6 +371,7 @@ CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) {
CEF_REQUIRE_IO_THREAD();
return test_runner::GetResourceHandler(browser, frame, request);
}
@ -459,106 +406,30 @@ void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
message_router_->OnRenderProcessTerminated(browser);
// Load the startup URL if that's not the website that we terminated on.
// Don't reload if there's no start URL, or if the crash URL was specified.
if (startup_url_.empty() || startup_url_ == "chrome://crash")
return;
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
std::string url = frame->GetURL();
// Don't reload if the termination occurred before any URL had successfully
// loaded.
if (url.empty())
return;
std::string start_url = startup_url_;
// Convert URLs to lowercase for easier comparison.
std::transform(url.begin(), url.end(), url.begin(), tolower);
std::transform(start_url.begin(), start_url.end(), start_url.begin(),
tolower);
std::string startupURL = GetStartupURL();
if (startupURL != "chrome://crash" && !url.empty() &&
url.find(startupURL) != 0) {
frame->LoadURL(startupURL);
}
}
bool ClientHandler::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->GetRootScreenRect(browser, rect);
}
bool ClientHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->GetViewRect(browser, rect);
}
bool ClientHandler::GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->GetScreenPoint(browser, viewX, viewY, screenX, screenY);
}
bool ClientHandler::GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->GetScreenInfo(browser, screen_info);
}
void ClientHandler::OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
// Don't reload the URL that just resulted in termination.
if (url.find(start_url) == 0)
return;
return osr_handler_->OnPopupShow(browser, show);
}
void ClientHandler::OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
return osr_handler_->OnPopupSize(browser, rect);
}
void ClientHandler::OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
osr_handler_->OnPaint(browser, type, dirtyRects, buffer, width, height);
}
void ClientHandler::OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor,
CursorType type,
const CefCursorInfo& custom_cursor_info) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
osr_handler_->OnCursorChange(browser, cursor, type, custom_cursor_info);
}
bool ClientHandler::StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return false;
return osr_handler_->StartDragging(browser, drag_data, allowed_ops, x, y);
}
void ClientHandler::UpdateDragCursor(CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) {
CEF_REQUIRE_UI_THREAD();
if (!osr_handler_.get())
return;
osr_handler_->UpdateDragCursor(browser, operation);
frame->LoadURL(startup_url_);
}
void ClientHandler::SetMainWindowHandle(ClientWindowHandle handle) {
@ -573,8 +444,7 @@ void ClientHandler::SetMainWindowHandle(ClientWindowHandle handle) {
#if defined(OS_LINUX)
// Associate |handle| with the GTK dialog handler.
static_cast<ClientDialogHandlerGtk*>(dialog_handler_.get())->set_parent(
handle);
dialog_handler_->set_parent(handle);
#endif
}
@ -583,122 +453,28 @@ ClientWindowHandle ClientHandler::GetMainWindowHandle() const {
return main_handle_;
}
void ClientHandler::SetEditWindowHandle(ClientWindowHandle handle) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandler::SetEditWindowHandle, this, handle));
return;
}
edit_handle_ = handle;
}
void ClientHandler::SetButtonWindowHandles(ClientWindowHandle backHandle,
ClientWindowHandle forwardHandle,
ClientWindowHandle reloadHandle,
ClientWindowHandle stopHandle) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandler::SetButtonWindowHandles, this,
backHandle, forwardHandle, reloadHandle, stopHandle));
return;
}
back_handle_ = backHandle;
forward_handle_ = forwardHandle;
reload_handle_ = reloadHandle;
stop_handle_ = stopHandle;
}
void ClientHandler::SetOSRHandler(CefRefPtr<RenderHandler> handler) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandler::SetOSRHandler, this, handler));
return;
}
osr_handler_ = handler;
}
CefRefPtr<ClientHandler::RenderHandler> ClientHandler::GetOSRHandler() const {
return osr_handler_;
}
CefRefPtr<CefBrowser> ClientHandler::GetBrowser() const {
base::AutoLock lock_scope(lock_);
return browser_;
}
int ClientHandler::GetBrowserId() const {
base::AutoLock lock_scope(lock_);
return browser_id_;
}
void ClientHandler::CloseAllBrowsers(bool force_close) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandler::CloseAllBrowsers, this, force_close));
return;
}
if (!popup_browsers_.empty()) {
// Request that any popup browsers close.
BrowserList::const_iterator it = popup_browsers_.begin();
for (; it != popup_browsers_.end(); ++it)
(*it)->GetHost()->CloseBrowser(force_close);
}
if (browser_.get()) {
// Request that the main browser close.
browser_->GetHost()->CloseBrowser(force_close);
}
}
bool ClientHandler::IsClosing() const {
base::AutoLock lock_scope(lock_);
return is_closing_;
int ClientHandler::GetBrowserCount() const {
CEF_REQUIRE_UI_THREAD();
return browser_count_;
}
void ClientHandler::ShowDevTools(CefRefPtr<CefBrowser> browser,
const CefPoint& inspect_element_at) {
CefWindowInfo windowInfo;
CefRefPtr<CefClient> client;
CefBrowserSettings settings;
#if defined(OS_WIN)
windowInfo.SetAsPopup(browser->GetHost()->GetWindowHandle(), "DevTools");
#endif
browser->GetHost()->ShowDevTools(windowInfo, this, settings,
inspect_element_at);
if (CreatePopupWindow(true, CefPopupFeatures(), windowInfo, client,
settings)) {
browser->GetHost()->ShowDevTools(windowInfo, client, settings,
inspect_element_at);
}
}
void ClientHandler::CloseDevTools(CefRefPtr<CefBrowser> browser) {
browser->GetHost()->CloseDevTools();
}
std::string ClientHandler::GetStartupURL() const {
return startup_url_;
}
bool ClientHandler::Save(const std::string& path, const std::string& data) {
FILE* f = fopen(path.c_str(), "w");
if (!f)
return false;
size_t total = 0;
do {
size_t write = fwrite(data.c_str() + total, 1, data.size() - total, f);
if (write == 0)
break;
total += write;
} while (total < data.size());
fclose(f);
return true;
}
void ClientHandler::BuildTestMenu(CefRefPtr<CefMenuModel> model) {
if (model->GetCount() > 0)
model->AddSeparator();

View File

@ -6,31 +6,27 @@
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_H_
#pragma once
#include <list>
#include <map>
#include <set>
#include <string>
#include "include/base/cef_lock.h"
#include "include/cef_client.h"
#include "include/wrapper/cef_helpers.h"
#include "include/wrapper/cef_message_router.h"
#if defined(OS_LINUX)
// The Linux client uses GTK instead of the underlying platform type (X11).
#include <gtk/gtk.h>
#include "cefclient/dialog_handler_gtk.h"
// The Linux client uses GTK instead of the underlying platform type (X11).
#define ClientWindowHandle GtkWidget*
#else
#define ClientWindowHandle CefWindowHandle
#endif
// Define this value to redirect all popup URLs to the main application browser
// window.
// #define TEST_REDIRECT_POPUP_URLS
namespace client {
// ClientHandler implementation.
// Client handler abstract base class. Provides common functionality shared by
// all concrete client handler implementations.
class ClientHandler : public CefClient,
public CefContextMenuHandler,
public CefDisplayHandler,
@ -40,27 +36,18 @@ class ClientHandler : public CefClient,
public CefKeyboardHandler,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRenderHandler,
public CefRequestHandler {
public:
// Interface implemented to handle off-screen rendering.
class RenderHandler : public CefRenderHandler {
public:
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) =0;
};
typedef std::set<CefMessageRouterBrowserSide::Handler*> MessageHandlerSet;
ClientHandler();
ClientHandler(const std::string& startup_url,
bool is_osr);
~ClientHandler();
// CefClient methods
CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() OVERRIDE {
return this;
}
CefRefPtr<CefDialogHandler> GetDialogHandler() OVERRIDE {
return dialog_handler_;
}
CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
return this;
}
@ -73,9 +60,6 @@ class ClientHandler : public CefClient,
CefRefPtr<CefGeolocationHandler> GetGeolocationHandler() OVERRIDE {
return this;
}
CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() OVERRIDE {
return jsdialog_handler_;
}
CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE {
return this;
}
@ -85,9 +69,6 @@ class ClientHandler : public CefClient,
CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE {
return this;
}
CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
return this;
}
CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE {
return this;
}
@ -95,6 +76,15 @@ class ClientHandler : public CefClient,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) OVERRIDE;
#if defined(OS_LINUX)
CefRefPtr<CefDialogHandler> GetDialogHandler() OVERRIDE {
return dialog_handler_;
}
CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() OVERRIDE {
return dialog_handler_;
}
#endif
// CefContextMenuHandler methods
void OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
@ -190,158 +180,120 @@ class ClientHandler : public CefClient,
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
TerminationStatus status) OVERRIDE;
// CefRenderHandler methods
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) OVERRIDE;
void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) OVERRIDE;
void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor,
CursorType type,
const CefCursorInfo& custom_cursor_info) OVERRIDE;
bool StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) OVERRIDE;
void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) OVERRIDE;
// Set the main frame window handle.
void SetMainWindowHandle(ClientWindowHandle handle);
// Get the main frame window handle. Can only be called on the CEF UI thread.
ClientWindowHandle GetMainWindowHandle() const;
void SetEditWindowHandle(ClientWindowHandle handle);
void SetButtonWindowHandles(ClientWindowHandle backHandle,
ClientWindowHandle forwardHandle,
ClientWindowHandle reloadHandle,
ClientWindowHandle stopHandle);
void SetOSRHandler(CefRefPtr<RenderHandler> handler);
CefRefPtr<RenderHandler> GetOSRHandler() const;
CefRefPtr<CefBrowser> GetBrowser() const;
int GetBrowserId() const;
// Request that all existing browser windows close.
void CloseAllBrowsers(bool force_close);
// Returns true if the main browser window is currently closing. Used in
// combination with DoClose() and the OS close notification to properly handle
// 'onbeforeunload' JavaScript events during window close.
bool IsClosing() const;
// Returns the number of browsers currently using this handler. Can only be
// called on the CEF UI thread.
int GetBrowserCount() const;
// Show a new DevTools popup window.
void ShowDevTools(CefRefPtr<CefBrowser> browser,
const CefPoint& inspect_element_at);
// Close the existing DevTools popup window, if any.
void CloseDevTools(CefRefPtr<CefBrowser> browser);
// Returns the startup URL.
std::string GetStartupURL() const;
std::string startup_url() const { return startup_url_; }
bool Save(const std::string& path, const std::string& data);
// Returns true if this handler uses off-screen rendering.
bool is_osr() const { return is_osr_; }
protected:
// The following virtual methods are called on the CEF UI thread unless
// otherwise indicated.
// A browser has been created.
virtual void BrowserCreated(CefRefPtr<CefBrowser> browser) = 0;
// A browser is closing.
virtual void BrowserClosing(CefRefPtr<CefBrowser> browser) = 0;
// A browser has been closed.
virtual void BrowserClosed(CefRefPtr<CefBrowser> browser) = 0;
// Set the window URL address.
virtual void SetAddress(CefRefPtr<CefBrowser> browser,
const CefString& url) = 0;
// Set the window title.
virtual void SetTitle(CefRefPtr<CefBrowser> browser,
const CefString& title) = 0;
// Set the loading state.
virtual void SetLoadingState(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) = 0;
// Create a new popup window using the specified information. |is_devtools|
// will be true if the window will be used for DevTools. Return true to
// proceed with popup browser creation or false to cancel the popup browser.
// May be called on any thead.
virtual bool CreatePopupWindow(
bool is_devtools,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) = 0;
private:
void SetLoading(bool isLoading);
void SetNavState(bool canGoBack, bool canGoForward);
// Test context menu creation.
void BuildTestMenu(CefRefPtr<CefMenuModel> model);
bool ExecuteTestMenu(int command_id);
// THREAD SAFE MEMBERS
// The following members may be accessed from any thread.
// The startup URL.
const std::string startup_url_;
// True if this handler uses off-screen rendering.
const bool is_osr_;
// True if mouse cursor change is disabled.
bool mouse_cursor_change_disabled_;
#if defined(OS_LINUX)
// Custom dialog handler for GTK.
CefRefPtr<ClientDialogHandlerGtk> dialog_handler_;
#endif
// Handles the browser side of query routing. The renderer side is handled
// in client_renderer.cc.
CefRefPtr<CefMessageRouterBrowserSide> message_router_;
// UI THREAD MEMBERS
// The following members will only be accessed on the CEF UI thread.
// Track state information for the text context menu.
struct TestMenuState {
TestMenuState() : check_item(true), radio_item(0) {}
bool check_item;
int radio_item;
} test_menu_state_;
// START THREAD SAFE MEMBERS
// The following members are thread-safe because they're initialized during
// object construction and not changed thereafter.
// The startup URL.
std::string startup_url_;
// True if mouse cursor change is disabled.
bool mouse_cursor_change_disabled_;
CefRefPtr<CefDialogHandler> dialog_handler_;
CefRefPtr<CefJSDialogHandler> jsdialog_handler_;
// END THREAD SAFE MEMBERS
// Lock used to protect members accessed on multiple threads. Make it mutable
// so that it can be used from const methods.
mutable base::Lock lock_;
// START LOCK PROTECTED MEMBERS
// The following members are accessed on multiple threads and must be
// protected by |lock_|.
// The child browser window.
CefRefPtr<CefBrowser> browser_;
// The child browser id.
int browser_id_;
// True if the main browser window is currently closing.
bool is_closing_;
// END LOCK PROTECTED MEMBERS
// START UI THREAD ACCESS ONLY MEMBERS
// The following members will only be accessed on the CEF UI thread.
// List of any popup browser windows.
typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
BrowserList popup_browsers_;
// The current number of browsers using this handler.
int browser_count_;
// The main frame window handle.
ClientWindowHandle main_handle_;
// The edit window handle.
ClientWindowHandle edit_handle_;
// The button window handles.
ClientWindowHandle back_handle_;
ClientWindowHandle forward_handle_;
ClientWindowHandle stop_handle_;
ClientWindowHandle reload_handle_;
// The handler for off-screen rendering, if any.
CefRefPtr<RenderHandler> osr_handler_;
// Used for console logging purposes.
// Console logging state.
const std::string console_log_file_;
bool first_console_message_;
// True if an editable field currently has focus.
bool focus_on_editable_field_;
// Handles the browser side of query routing. The renderer side is handled
// in client_renderer.cc.
CefRefPtr<CefMessageRouterBrowserSide> message_router_;
// Set of Handlers registered with the message router.
MessageHandlerSet message_handler_set_;
// Number of currently existing browser windows. The application will exit
// when the number of windows reaches 0.
static int browser_count_;
// END UI THREAD ACCESS ONLY MEMBERS
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientHandler);
DISALLOW_COPY_AND_ASSIGN(ClientHandler);
};
} // namespace client

View File

@ -1,47 +0,0 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#import <Cocoa/Cocoa.h>
#include "cefclient/client_handler.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
namespace client {
void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& url) {
CEF_REQUIRE_UI_THREAD();
if (GetBrowserId() == browser->GetIdentifier() && frame->IsMain()) {
// Set the edit window text
NSTextField* textField = (NSTextField*)edit_handle_;
std::string urlStr(url);
NSString* str = [NSString stringWithUTF8String:urlStr.c_str()];
[textField setStringValue:str];
}
}
void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
// Set the frame window title bar
NSView* view = (NSView*)browser->GetHost()->GetWindowHandle();
NSWindow* window = [view window];
std::string titleStr(title);
NSString* str = [NSString stringWithUTF8String:titleStr.c_str()];
[window setTitle:str];
}
void ClientHandler::SetLoading(bool isLoading) {
// TODO(port): Change button status.
}
void ClientHandler::SetNavState(bool canGoBack, bool canGoForward) {
// TODO(port): Change button status.
}
} // namespace client

View File

@ -0,0 +1,235 @@
// Copyright (c) 2015 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 "cefclient/client_handler_shared.h"
#include <stdio.h>
#include <algorithm>
#include <string>
#include "include/base/cef_bind.h"
#include "include/cef_command_line.h"
#include "include/wrapper/cef_closure_task.h"
#include "cefclient/client_switches.h"
#include "cefclient/main_context.h"
#include "cefclient/main_message_loop.h"
#include "cefclient/test_runner.h"
namespace client {
ClientHandlerShared::ClientHandlerShared()
: ClientHandler(MainContext::Get()->GetMainURL(),
CefCommandLine::GetGlobalCommandLine()->HasSwitch(
switches::kOffScreenRenderingEnabled)),
is_closing_(false),
browser_id_(0),
edit_handle_(NULL),
back_handle_(NULL),
forward_handle_(NULL),
stop_handle_(NULL),
reload_handle_(NULL) {
}
ClientHandlerShared::~ClientHandlerShared() {
}
void ClientHandlerShared::BrowserCreated(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == 0) {
// Keep references to the browser hosted in the main window.
browser_id_ = browser->GetIdentifier();
{
// Protect modification of |browser_| with a lock because it may be
// accessed from different threads.
base::AutoLock lock_scope(lock_);
browser_ = browser;
}
} else if (browser->IsPopup()) {
// Add to the list of popup browsers.
popup_browsers_.push_back(browser);
// Give focus to the popup browser. Perform asynchronously because the
// parent window may attempt to keep focus after launching the popup.
CefPostTask(TID_UI,
base::Bind(&CefBrowserHost::SetFocus, browser->GetHost().get(), true));
}
}
void ClientHandlerShared::BrowserClosing(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
// Closing the main window requires special handling. See the DoClose()
// documentation in the CEF header for a detailed destription of this
// process.
if (browser_id_ == browser->GetIdentifier()) {
// Protect modification of |is_closing_| with a lock because it may be
// accessed from different threads.
base::AutoLock lock_scope(lock_);
// Set a flag to indicate that the window close should be allowed.
is_closing_ = true;
}
}
void ClientHandlerShared::BrowserClosed(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
{
// Protect modification of |browser_| with a lock because it may be
// accessed from different threads.
base::AutoLock lock_scope(lock_);
// Free the browser pointer so that the browser can be destroyed.
browser_ = NULL;
}
if (osr_handler_.get()) {
osr_handler_->OnBeforeClose(browser);
// Protect modification of |osr_handler_| with a lock because it may be
// accessed from different threads.
base::AutoLock lock_scope(lock_);
osr_handler_ = NULL;
}
browser_id_ = 0;
} else if (browser->IsPopup()) {
// Remove from the browser popup list.
BrowserList::iterator bit = popup_browsers_.begin();
for (; bit != popup_browsers_.end(); ++bit) {
if ((*bit)->IsSame(browser)) {
popup_browsers_.erase(bit);
break;
}
}
}
if (GetBrowserCount() == 0) {
// Quit the main message loop.
MainMessageLoop::Get()->Quit();
}
}
bool ClientHandlerShared::CreatePopupWindow(
bool is_devtools,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) {
// Note: This method will be called on multiple threads.
if (is_devtools) {
// Create DevTools as a windowed popup browser using the same client.
#if defined(OS_WIN)
windowInfo.SetAsPopup(GetMainWindowHandle(), "DevTools");
#endif
client = this;
} else if (is_osr()) {
CefPostTask(TID_UI,
base::Bind(test_runner::Alert, GetBrowser(),
"Popup windows are disabled with off-screen rendering."));
// Cancel popups in off-screen rendering mode.
return false;
}
return true;
}
void ClientHandlerShared::SetUXWindowHandles(
ClientWindowHandle editHandle,
ClientWindowHandle backHandle,
ClientWindowHandle forwardHandle,
ClientWindowHandle reloadHandle,
ClientWindowHandle stopHandle) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandlerShared::SetUXWindowHandles, this,
editHandle, backHandle, forwardHandle, reloadHandle,
stopHandle));
return;
}
edit_handle_ = editHandle;
back_handle_ = backHandle;
forward_handle_ = forwardHandle;
reload_handle_ = reloadHandle;
stop_handle_ = stopHandle;
}
CefRefPtr<ClientHandlerShared::RenderHandler>
ClientHandlerShared::GetOSRHandler() const {
if (CefCurrentlyOn(TID_UI)) {
// No need for locking because |osr_handler_| will only be modified on this
// thread.
return osr_handler_;
} else {
// Use a lock to protect |osr_handler_| from being modified while we're
// accessing it from a different thread.
base::AutoLock lock_scope(lock_);
return osr_handler_;
}
}
void ClientHandlerShared::SetOSRHandler(CefRefPtr<RenderHandler> handler) {
// Protect modification of |osr_handler_| with a lock because it may be
// accessed from different threads.
base::AutoLock lock_scope(lock_);
osr_handler_ = handler;
}
CefRefPtr<CefBrowser> ClientHandlerShared::GetBrowser() const {
if (CefCurrentlyOn(TID_UI)) {
// No need for locking because |browser_| will only be modified on this
// thread.
return browser_;
} else {
// Use a lock to protect |browser_| from being modified while we're
// accessing it from a different thread.
base::AutoLock lock_scope(lock_);
return browser_;
}
}
int ClientHandlerShared::GetBrowserId() const {
CEF_REQUIRE_UI_THREAD();
return browser_id_;
}
void ClientHandlerShared::CloseAllBrowsers(bool force_close) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
base::Bind(&ClientHandlerShared::CloseAllBrowsers, this, force_close));
return;
}
if (!popup_browsers_.empty()) {
// Request that any popup browsers close.
BrowserList::const_iterator it = popup_browsers_.begin();
for (; it != popup_browsers_.end(); ++it)
(*it)->GetHost()->CloseBrowser(force_close);
}
if (browser_.get()) {
// Request that the main browser close.
browser_->GetHost()->CloseBrowser(force_close);
}
}
bool ClientHandlerShared::IsClosing() const {
if (CefCurrentlyOn(TID_UI)) {
// No need for locking because |is_closing_| will only be modified on this
// thread.
return is_closing_;
} else {
// Use a lock to protect |is_closing_| from being modified while we're
// accessing it from a different thread.
base::AutoLock lock_scope(lock_);
return is_closing_;
}
}
} // namespace client

View File

@ -0,0 +1,126 @@
// Copyright (c) 2015 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_CLIENT_HANDLER_SHARED_H_
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_SHARED_H_
#pragma once
#include <list>
#include <string>
#include "include/base/cef_lock.h"
#include "cefclient/client_handler.h"
namespace client {
// Client handler implementation that is shared by all existing browsers.
class ClientHandlerShared : public ClientHandler {
public:
// Interface implemented to handle off-screen rendering.
class RenderHandler : public CefRenderHandler {
public:
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) =0;
};
ClientHandlerShared();
~ClientHandlerShared();
// CefClient methods
CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
return osr_handler_;
}
// ClientHandler methods
void BrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
void BrowserClosing(CefRefPtr<CefBrowser> browser) OVERRIDE;
void BrowserClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
void SetAddress(CefRefPtr<CefBrowser> browser,
const CefString& url) OVERRIDE;
void SetTitle(CefRefPtr<CefBrowser> browser,
const CefString& title) OVERRIDE;
void SetLoadingState(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) OVERRIDE;
bool CreatePopupWindow(
bool is_devtools,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE;
void SetUXWindowHandles(ClientWindowHandle editHandle,
ClientWindowHandle backHandle,
ClientWindowHandle forwardHandle,
ClientWindowHandle reloadHandle,
ClientWindowHandle stopHandle);
CefRefPtr<RenderHandler> GetOSRHandler() const;
void SetOSRHandler(CefRefPtr<RenderHandler> handler);
// Get the main (non-popup) browser associated with this client. Safe to call
// on any thread.
CefRefPtr<CefBrowser> GetBrowser() const;
// Get the main (non-popup) browser ID. Will return non-0 if the main browser
// currently exists. Should only be called on the CEF UI thread.
int GetBrowserId() const;
// Request that all existing browser windows close.
void CloseAllBrowsers(bool force_close);
// Returns true if the main browser window is currently closing. Used in
// combination with DoClose() and the OS close notification to properly handle
// 'onbeforeunload' JavaScript events during window close. Safe to call on any
// thread.
bool IsClosing() const;
private:
// Lock used to protect members accessed on multiple threads. Make it mutable
// so that it can be used from const methods.
mutable base::Lock lock_;
// LOCK PROTECTED MEMBERS
// Setting the following members or accessing them from a thread other than
// the CEF UI thread must be protected by |lock_|. Most platforms will only
// access them from the UI thread but on Windows they will be accessed from
// the main application thread when using using multi-threaded message loop
// mode.
// The handler for off-screen rendering, if any.
CefRefPtr<RenderHandler> osr_handler_;
// The child browser window.
CefRefPtr<CefBrowser> browser_;
// True if the main browser window is currently closing.
bool is_closing_;
// UI THREAD MEMBERS
// The following members will only be accessed on the CEF UI thread.
// The child browser id.
int browser_id_;
// List of any popup browser windows.
typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
BrowserList popup_browsers_;
// The edit window handle.
ClientWindowHandle edit_handle_;
// The button window handles.
ClientWindowHandle back_handle_;
ClientWindowHandle forward_handle_;
ClientWindowHandle stop_handle_;
ClientWindowHandle reload_handle_;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientHandlerShared);
DISALLOW_COPY_AND_ASSIGN(ClientHandlerShared);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_SHARED_H_

View File

@ -10,33 +10,31 @@
#include <string>
#include "cefclient/client_handler.h"
#include "cefclient/client_handler_shared.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
namespace client {
void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& url) {
void ClientHandlerShared::SetAddress(CefRefPtr<CefBrowser> browser,
const CefString& url) {
CEF_REQUIRE_UI_THREAD();
if (GetBrowserId() == browser->GetIdentifier() && frame->IsMain()) {
// Set the edit window text
if (browser_id_ == browser->GetIdentifier()) {
// Set the edit window text.
std::string urlStr(url);
gtk_entry_set_text(GTK_ENTRY(edit_handle_), urlStr.c_str());
}
}
void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
void ClientHandlerShared::SetTitle(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
std::string titleStr(title);
if (!browser->IsPopup()) {
// Set the GTK parent window title.
GtkWidget* window = gtk_widget_get_ancestor(main_handle_,
GtkWidget* window = gtk_widget_get_ancestor(GetMainWindowHandle(),
GTK_TYPE_WINDOW);
gtk_window_set_title(GTK_WINDOW(window), titleStr.c_str());
} else {
@ -78,17 +76,20 @@ void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
}
}
void ClientHandler::SetLoading(bool isLoading) {
void ClientHandlerShared::SetLoadingState(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) {
CEF_REQUIRE_UI_THREAD();
// Nothing to do for popup windows.
if (browser_id_ != browser->GetIdentifier())
return;
if (isLoading)
gtk_widget_set_sensitive(GTK_WIDGET(stop_handle_), true);
else
gtk_widget_set_sensitive(GTK_WIDGET(stop_handle_), false);
}
void ClientHandler::SetNavState(bool canGoBack, bool canGoForward) {
CEF_REQUIRE_UI_THREAD();
if (canGoBack)
gtk_widget_set_sensitive(GTK_WIDGET(back_handle_), true);

View File

@ -0,0 +1,53 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#import <Cocoa/Cocoa.h>
#include "cefclient/client_handler_shared.h"
#include "include/cef_browser.h"
namespace client {
void ClientHandlerShared::SetAddress(CefRefPtr<CefBrowser> browser,
const CefString& url) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
// Set edit window text for the main window.
NSTextField* textField = (NSTextField*)edit_handle_;
std::string urlStr(url);
NSString* str = [NSString stringWithUTF8String:urlStr.c_str()];
[textField setStringValue:str];
}
}
void ClientHandlerShared::SetTitle(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
// Set the frame window title bar.
NSView* view = (NSView*)browser->GetHost()->GetWindowHandle();
NSWindow* window = [view window];
std::string titleStr(title);
NSString* str = [NSString stringWithUTF8String:titleStr.c_str()];
[window setTitle:str];
}
void ClientHandlerShared::SetLoadingState(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
// Set UX control state for the main window.
[(NSTextField*)edit_handle_ setEnabled:YES];
[(NSButton*)reload_handle_ setEnabled:!isLoading];
[(NSButton*)stop_handle_ setEnabled:isLoading];
[(NSButton*)back_handle_ setEnabled:canGoBack];
[(NSButton*)forward_handle_ setEnabled:canGoForward];
}
}
} // namespace client

View File

@ -0,0 +1,55 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "cefclient/client_handler_shared.h"
#include <string>
#include <windows.h>
#include "include/cef_browser.h"
#include "cefclient/resource.h"
namespace client {
void ClientHandlerShared::SetAddress(CefRefPtr<CefBrowser> browser,
const CefString& url) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
// Set the edit window text for the main (top-level) browser.
SetWindowText(edit_handle_, std::wstring(url).c_str());
}
}
void ClientHandlerShared::SetTitle(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
// Set the frame window title bar.
CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
if (browser_id_ == browser->GetIdentifier()) {
// For the main (top-level) browser the frame window will be the parent of
// the browser window.
hwnd = GetParent(hwnd);
}
SetWindowText(hwnd, std::wstring(title).c_str());
}
void ClientHandlerShared::SetLoadingState(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
// Set UX control state for the main (top-level) browser.
EnableWindow(edit_handle_, TRUE);
EnableWindow(reload_handle_, !isLoading);
EnableWindow(stop_handle_, isLoading);
EnableWindow(back_handle_, canGoBack);
EnableWindow(forward_handle_, canGoForward);
}
}
} // namespace client

View File

@ -1,54 +0,0 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "cefclient/client_handler.h"
#include <string>
#include <windows.h>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "cefclient/resource.h"
namespace client {
void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& url) {
CEF_REQUIRE_UI_THREAD();
if (GetBrowserId() == browser->GetIdentifier() && frame->IsMain()) {
// Set the edit window text
SetWindowText(edit_handle_, std::wstring(url).c_str());
}
}
void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
// Set the frame window title bar
CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
if (GetBrowserId() == browser->GetIdentifier()) {
// The frame window will be the parent of the browser window
hwnd = GetParent(hwnd);
}
SetWindowText(hwnd, std::wstring(title).c_str());
}
void ClientHandler::SetLoading(bool isLoading) {
DCHECK(edit_handle_ != NULL && reload_handle_ != NULL &&
stop_handle_ != NULL);
EnableWindow(edit_handle_, TRUE);
EnableWindow(reload_handle_, !isLoading);
EnableWindow(stop_handle_, isLoading);
}
void ClientHandler::SetNavState(bool canGoBack, bool canGoForward) {
DCHECK(back_handle_ != NULL && forward_handle_ != NULL);
EnableWindow(back_handle_, canGoBack);
EnableWindow(forward_handle_, canGoForward);
}
} // namespace client

View File

@ -1110,7 +1110,7 @@ CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
// static
CefRefPtr<OSRWindow> OSRWindow::From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler) {
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler) {
return static_cast<OSRWindow*>(renderHandler.get());
}

View File

@ -7,7 +7,7 @@
#pragma once
#include "include/cef_render_handler.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_handler_shared.h"
#include "cefclient/osr_renderer.h"
namespace client {
@ -20,7 +20,7 @@ class OSRBrowserProvider {
virtual ~OSRBrowserProvider() {}
};
class OSRWindow : public ClientHandler::RenderHandler {
class OSRWindow : public ClientHandlerShared::RenderHandler {
public:
// Create a new OSRWindow instance. |browser_provider| must outlive this
// object.
@ -30,7 +30,7 @@ class OSRWindow : public ClientHandler::RenderHandler {
ClientWindowHandle parentView);
static CefRefPtr<OSRWindow> From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler);
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler);
ClientWindowHandle GetWindowHandle() const {
return glarea_;
@ -41,7 +41,7 @@ class OSRWindow : public ClientHandler::RenderHandler {
return NULL;
}
// ClientHandler::RenderHandler methods
// ClientHandlerShared::RenderHandler methods
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods
@ -93,6 +93,7 @@ class OSRWindow : public ClientHandler::RenderHandler {
bool render_task_pending_;
IMPLEMENT_REFCOUNTING(OSRWindow);
DISALLOW_COPY_AND_ASSIGN(OSRWindow);
};
} // namespace client

View File

@ -6,7 +6,7 @@
#define CEF_TESTS_CEFCLIENT_OSR_WIDGET_MAC_H_
#include "include/cef_client.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_handler_shared.h"
namespace client {
class OSRBrowserProvider;
@ -61,7 +61,7 @@ class OSRBrowserProvider {
};
// Handler for off-screen rendering windows.
class ClientOSRHandler : public ClientHandler::RenderHandler {
class ClientOSRHandler : public ClientHandlerShared::RenderHandler {
public:
explicit ClientOSRHandler(ClientOpenGLView* view,
OSRBrowserProvider* browser_provider);
@ -69,7 +69,7 @@ class ClientOSRHandler : public ClientHandler::RenderHandler {
void Disconnect();
// ClientHandler::RenderHandler
// ClientHandlerShared::RenderHandler methods
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods
@ -124,7 +124,7 @@ class OSRWindow {
CefWindowHandle parentView,
const CefRect& frame);
CefRefPtr<ClientHandler::RenderHandler> GetRenderHandler() {
CefRefPtr<ClientHandlerShared::RenderHandler> GetRenderHandler() {
return render_client.get();
}
@ -142,6 +142,7 @@ class OSRWindow {
CefWindowHandle view_;
IMPLEMENT_REFCOUNTING(OSRWindow);
DISALLOW_COPY_AND_ASSIGN(OSRWindow);
};
} // namespace client

View File

@ -55,7 +55,7 @@ CefRefPtr<OSRWindow> OSRWindow::Create(
// static
CefRefPtr<OSRWindow> OSRWindow::From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler) {
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler) {
return static_cast<OSRWindow*>(renderHandler.get());
}

View File

@ -7,7 +7,7 @@
#pragma once
#include "include/cef_render_handler.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_handler_shared.h"
#include "cefclient/osr_dragdrop_win.h"
#include "cefclient/osr_renderer.h"
@ -21,7 +21,7 @@ class OSRBrowserProvider {
virtual ~OSRBrowserProvider() {}
};
class OSRWindow : public ClientHandler::RenderHandler
class OSRWindow : public ClientHandlerShared::RenderHandler
#if defined(CEF_USE_ATL)
, public OsrDragEvents
#endif
@ -34,7 +34,7 @@ class OSRWindow : public ClientHandler::RenderHandler
bool show_update_rect);
static CefRefPtr<OSRWindow> From(
CefRefPtr<ClientHandler::RenderHandler> renderHandler);
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler);
// Create the underlying window.
bool CreateWidget(HWND hWndParent, const RECT& rect,
@ -47,7 +47,7 @@ class OSRWindow : public ClientHandler::RenderHandler
return hWnd_;
}
// ClientHandler::RenderHandler methods
// ClientHandlerShared::RenderHandler methods
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods
@ -132,6 +132,7 @@ class OSRWindow : public ClientHandler::RenderHandler
bool hidden_;
IMPLEMENT_REFCOUNTING(OSRWindow);
DISALLOW_COPY_AND_ASSIGN(OSRWindow);
};
} // namespace client