pulsar/native/atom_cef_client.cpp
Kevin Sawicki c69e217192 Ignore title changes from dev tools client
Previously the generic developer tools message
would be set as the window title when opened
and only removed once the active edit session was
changed.
2013-02-06 15:58:39 -08:00

249 lines
7.6 KiB
C++

#include <sstream>
#include <iostream>
#include <assert.h>
#include "include/cef_path_util.h"
#include "include/cef_process_util.h"
#include "include/cef_task.h"
#include "include/cef_runnable.h"
#include "include/cef_trace.h"
#include "cef_types.h"
#include "native/atom_cef_client.h"
#include "cef_v8.h"
#define REQUIRE_UI_THREAD() assert(CefCurrentlyOn(TID_UI));
#define REQUIRE_IO_THREAD() assert(CefCurrentlyOn(TID_IO));
#define REQUIRE_FILE_THREAD() assert(CefCurrentlyOn(TID_FILE));
AtomCefClient::AtomCefClient(){
}
AtomCefClient::AtomCefClient(bool handlePasteboardCommands, bool ignoreTitleChanges) {
m_HandlePasteboardCommands = handlePasteboardCommands;
m_IgnoreTitleChanges = ignoreTitleChanges;
}
AtomCefClient::~AtomCefClient() {
}
bool AtomCefClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) {
std::string name = message->GetName().ToString();
CefRefPtr<CefListValue> argumentList = message->GetArgumentList();
int messageId = argumentList->GetInt(0);
if (name == "open") {
bool hasArguments = argumentList->GetSize() > 1;
hasArguments ? Open(argumentList->GetString(1)) : Open();
}
if (name == "openUnstable") {
bool hasArguments = argumentList->GetSize() > 1;
hasArguments ? OpenUnstable(argumentList->GetString(1)) : OpenUnstable();
}
else if (name == "newWindow") {
NewWindow();
}
else if (name == "toggleDevTools") {
ToggleDevTools(browser);
}
else if (name == "showDevTools") {
ShowDevTools(browser);
}
else if (name == "confirm") {
std::string message = argumentList->GetString(1).ToString();
std::string detailedMessage = argumentList->GetString(2).ToString();
std::vector<std::string> buttonLabels(argumentList->GetSize() - 3);
for (int i = 3; i < argumentList->GetSize(); i++) {
buttonLabels[i - 3] = argumentList->GetString(i).ToString();
}
Confirm(messageId, message, detailedMessage, buttonLabels, browser);
}
else if (name == "showSaveDialog") {
ShowSaveDialog(messageId, browser);
}
else if (name == "focus") {
GetBrowser()->GetHost()->SetFocus(true);
}
else if (name == "exit") {
Exit(argumentList->GetInt(1));
}
else if (name == "log") {
std::string message = argumentList->GetString(1).ToString();
Log(message.c_str());
}
else if (name == "beginTracing") {
BeginTracing();
}
else if (name == "endTracing") {
EndTracing();
}
else if (name == "show") {
Show(browser);
}
else if (name == "toggleFullScreen") {
ToggleFullScreen(browser);
}
else {
return false;
}
return true;
}
void AtomCefClient::OnBeforeContextMenu(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params,
CefRefPtr<CefMenuModel> model) {
model->Clear();
model->AddItem(MENU_ID_USER_FIRST, "&Toggle DevTools");
}
bool AtomCefClient::OnContextMenuCommand(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params,
int command_id,
EventFlags event_flags) {
if (command_id == MENU_ID_USER_FIRST) {
ToggleDevTools(browser);
return true;
}
else {
return false;
}
}
bool AtomCefClient::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
const CefString& message,
const CefString& source,
int line) {
REQUIRE_UI_THREAD();
Log(message.ToString().c_str());
return true;
}
bool AtomCefClient::OnKeyEvent(CefRefPtr<CefBrowser> browser,
const CefKeyEvent& event,
CefEventHandle os_event) {
if (event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == 'r') {
browser->SendProcessMessage(PID_RENDERER, CefProcessMessage::Create("reload"));
}
if (m_HandlePasteboardCommands && event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == 'x') {
browser->GetFocusedFrame()->Cut();
}
if (m_HandlePasteboardCommands && event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == 'c') {
browser->GetFocusedFrame()->Copy();
}
if (m_HandlePasteboardCommands && event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == 'v') {
browser->GetFocusedFrame()->Paste();
}
else if (event.modifiers == (EVENTFLAG_COMMAND_DOWN | EVENTFLAG_ALT_DOWN) && event.unmodified_character == 'i') {
ToggleDevTools(browser);
} else if (event.modifiers == EVENTFLAG_COMMAND_DOWN && event.unmodified_character == '`') {
FocusNextWindow();
} else if (event.modifiers == (EVENTFLAG_COMMAND_DOWN | EVENTFLAG_SHIFT_DOWN) && event.unmodified_character == '~') {
FocusPreviousWindow();
}
else {
return false;
}
return true;
}
void AtomCefClient::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
// REQUIRE_UI_THREAD(); // When uncommented this fails when app is terminated
m_Browser = NULL;
}
void AtomCefClient::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
REQUIRE_UI_THREAD();
AutoLock lock_scope(this);
if (!m_Browser.get()) {
m_Browser = browser;
}
GetBrowser()->GetHost()->SetFocus(true);
}
void AtomCefClient::OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& errorText,
const CefString& failedUrl) {
REQUIRE_UI_THREAD();
frame->LoadString(std::string(errorText) + "<br />" + std::string(failedUrl), failedUrl);
}
void AtomCefClient::BeginTracing() {
if (CefCurrentlyOn(TID_UI)) {
class Client : public CefTraceClient,
public CefRunFileDialogCallback {
public:
explicit Client(CefRefPtr<AtomCefClient> handler)
: handler_(handler),
trace_data_("{\"traceEvents\":["),
first_(true) {
}
virtual void OnTraceDataCollected(const char* fragment,
size_t fragment_size) OVERRIDE {
if (first_)
first_ = false;
else
trace_data_.append(",");
trace_data_.append(fragment, fragment_size);
}
virtual void OnEndTracingComplete() OVERRIDE {
REQUIRE_UI_THREAD();
trace_data_.append("]}");
handler_->GetBrowser()->GetHost()->RunFileDialog(
FILE_DIALOG_SAVE, CefString(), "/tmp/atom-trace.txt", std::vector<CefString>(),
this);
}
virtual void OnFileDialogDismissed(
CefRefPtr<CefBrowserHost> browser_host,
const std::vector<CefString>& file_paths) OVERRIDE {
if (!file_paths.empty())
handler_->Save(file_paths.front(), trace_data_);
}
private:
CefRefPtr<AtomCefClient> handler_;
std::string trace_data_;
bool first_;
IMPLEMENT_REFCOUNTING(Callback);
};
CefBeginTracing(new Client(this), CefString());
} else {
CefPostTask(TID_UI, NewCefRunnableMethod(this, &AtomCefClient::BeginTracing));
}
}
void AtomCefClient::EndTracing() {
if (CefCurrentlyOn(TID_UI)) {
CefEndTracingAsync();
} else {
CefPostTask(TID_UI, NewCefRunnableMethod(this, &AtomCefClient::BeginTracing));
}
}
bool AtomCefClient::Save(const std::string& path, const std::string& data) {
FILE* f = fopen(path.c_str(), "w");
if (!f)
return false;
fwrite(data.c_str(), data.size(), 1, f);
fclose(f);
return true;
}