X Tutup
// Copyright (c) 2016 CEF Python, see the Authors file. // All rights reserved. Licensed under BSD 3-clause license. // Project website: https://github.com/cztomczak/cefpython #include "context_menu_handler.h" #include "include/base/cef_logging.h" #define _MENU_ID_DEVTOOLS MENU_ID_USER_FIRST + 1 #define _MENU_ID_RELOAD_PAGE MENU_ID_USER_FIRST + 2 #define _MENU_ID_OPEN_PAGE_IN_EXTERNAL_BROWSER MENU_ID_USER_FIRST + 3 #define _MENU_ID_OPEN_FRAME_IN_EXTERNAL_BROWSER MENU_ID_USER_FIRST + 4 // Forward declarations void OpenInExternalBrowser(const std::string& url); void ContextMenuHandler::OnBeforeContextMenu( CefRefPtr browser, CefRefPtr frame, CefRefPtr params, CefRefPtr model) { bool enabled = ApplicationSettings_GetBoolFromDict( "context_menu", "enabled"); bool navigation = ApplicationSettings_GetBoolFromDict( "context_menu", "navigation"); bool print = ApplicationSettings_GetBoolFromDict( "context_menu", "print"); bool view_source = ApplicationSettings_GetBoolFromDict( "context_menu", "view_source"); bool external_browser = ApplicationSettings_GetBoolFromDict( "context_menu", "external_browser"); bool devtools = ApplicationSettings_GetBoolFromDict( "context_menu", "devtools"); if (!enabled) { model->Clear(); return; } if (!navigation && model->IsVisible(MENU_ID_BACK) && model->IsVisible(MENU_ID_FORWARD)) { model->Remove(MENU_ID_BACK); model->Remove(MENU_ID_FORWARD); // Remove separator if (model->GetTypeAt(0) == MENUITEMTYPE_SEPARATOR) { model->RemoveAt(0); } } if (!print) { model->Remove(MENU_ID_PRINT); } if (!view_source) { model->Remove(MENU_ID_VIEW_SOURCE); } if (!params->IsEditable() && params->GetSelectionText().empty() && (params->GetPageUrl().length() || params->GetFrameUrl().length())) { if (external_browser) { model->AddItem(_MENU_ID_OPEN_PAGE_IN_EXTERNAL_BROWSER, "Open in external browser"); if (params->GetFrameUrl().length() && params->GetPageUrl() != params->GetFrameUrl()) { model->AddItem(_MENU_ID_OPEN_FRAME_IN_EXTERNAL_BROWSER, "Open frame in external browser"); } } if (navigation) { model->InsertItemAt(2, _MENU_ID_RELOAD_PAGE, "Reload"); } if (devtools) { model->AddSeparator(); model->AddItem(_MENU_ID_DEVTOOLS, "Developer Tools"); } } } bool ContextMenuHandler::OnContextMenuCommand( CefRefPtr browser, CefRefPtr frame, CefRefPtr params, int command_id, EventFlags event_flags) { if (command_id == _MENU_ID_OPEN_PAGE_IN_EXTERNAL_BROWSER) { #if defined(OS_WIN) ShellExecuteA(0, "open", params->GetPageUrl().ToString().c_str(), 0, 0, SW_SHOWNORMAL); #elif defined(OS_LINUX) OpenInExternalBrowser(params->GetPageUrl().ToString()); #endif // OS_WIN return true; } else if (command_id == _MENU_ID_OPEN_FRAME_IN_EXTERNAL_BROWSER) { #if defined(OS_WIN) ShellExecuteA(0, "open", params->GetFrameUrl().ToString().c_str(), 0, 0, SW_SHOWNORMAL); #elif defined(OS_LINUX) OpenInExternalBrowser(params->GetFrameUrl().ToString()); #endif // OS_WIN return true; } else if (command_id == _MENU_ID_RELOAD_PAGE) { browser->ReloadIgnoreCache(); return true; } else if (command_id == _MENU_ID_DEVTOOLS) { PyBrowser_ShowDevTools(browser); return true; } return false; } void ContextMenuHandler::OnContextMenuDismissed(CefRefPtr browser, CefRefPtr frame) { // PASS } // ---------------------------------------------------------------------------- // Context menu utility functions // ---------------------------------------------------------------------------- #if defined(OS_LINUX) void OpenInExternalBrowser(const std::string& url) { // Linux equivalent of ShellExecute if (url.empty()) { LOG(ERROR) << "[Browser process] OpenInExternalBrowser():" " url is empty"; return; } std::string msg = "[Browser process] OpenInExternalBrowser(): url="; msg.append(url.c_str()); LOG(INFO) << msg.c_str(); // xdg-open is a desktop-independent tool for running // default applications. Installed by default on Ubuntu. // xdg-open process is running in the backround until // cefpython app closes. std::string prog = "xdg-open"; // Using system() opens up for bugs and exploits, not // recommended. // Fork yourself and run in parallel, do not block the // current proces. char *args[3]; args[0] = (char*) prog.c_str(); args[1] = (char*) url.c_str(); args[2] = 0; pid_t pid = fork(); if (!pid) { execvp(prog.c_str(), args); } } #endif
X Tutup