mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 22:02:58 -06:00
335 lines
6.7 KiB
C++
335 lines
6.7 KiB
C++
#include "ChromiumBrowser.h"
|
|
#include "ClientApp.h"
|
|
|
|
#include "include/cef_app.h"
|
|
#include "include/cef_version.h"
|
|
|
|
#if defined(GUI_GTK) && defined(GDK_WINDOWING_X11)
|
|
#include <gdk/gdkx.h>
|
|
#endif
|
|
|
|
using namespace Upp;
|
|
|
|
|
|
#ifdef COMPILER_GCC
|
|
const char * const __attribute__((weak)) Upp::ChromiumBrowser::JSFunctions[]={
|
|
/* DO NOT forget about nullptr at the end of the table */
|
|
nullptr
|
|
};
|
|
#endif
|
|
|
|
|
|
#ifdef PLATFORM_POSIX
|
|
static Vector<char*> GetArgs()
|
|
{
|
|
const Vector<String>& cmdline = CommandLine();
|
|
static String app;
|
|
Vector<char*> argv;
|
|
|
|
app = GetExeTitle();
|
|
argv.Clear();
|
|
argv.Add((char *)~app);
|
|
for (unsigned i = 0; i < cmdline.GetCount(); i++){
|
|
argv.Add((char *)~cmdline[i]);
|
|
}
|
|
return argv;
|
|
}
|
|
#endif
|
|
|
|
|
|
void ChromiumBrowser::ChildProcess()
|
|
{
|
|
CefRefPtr<ClientApp> app(new ClientApp);
|
|
|
|
#ifdef PLATFORM_POSIX
|
|
|
|
Vector<char *> args = GetArgs();
|
|
CefMainArgs main_args(args.GetCount(), &args[0]);
|
|
|
|
#elif defined(PLATFORM_WIN32)
|
|
|
|
CefMainArgs main_args(Ctrl::hInstance);
|
|
|
|
#else
|
|
|
|
#error "Unsupported platform"
|
|
|
|
#endif
|
|
|
|
int exit_code = CefExecuteProcess(main_args, app.get(), nullptr);
|
|
if (exit_code >= 0){
|
|
RLOG("CefExecuteProcess error");
|
|
exit(exit_code);
|
|
}
|
|
}
|
|
|
|
|
|
bool ChromiumBrowser::IsChildProcess()
|
|
{
|
|
const Vector<String>& cmdline = CommandLine();
|
|
return (cmdline.GetCount() > 0 && cmdline[0].StartsWith("--type="));
|
|
}
|
|
|
|
|
|
ChromiumBrowser::ChromiumBrowser(): handler(nullptr), start_page("about:blank")
|
|
{
|
|
CefRefPtr<ClientApp> app(new ClientApp);
|
|
|
|
#ifdef PLATFORM_POSIX
|
|
|
|
Vector<char *> args = GetArgs();
|
|
CefMainArgs main_args(args.GetCount(), &args[0]);
|
|
|
|
#elif defined(PLATFORM_WIN32)
|
|
|
|
CefMainArgs main_args(Ctrl::hInstance);
|
|
|
|
#else
|
|
|
|
#error "Unsupported platform"
|
|
|
|
#endif
|
|
|
|
int exit_code = CefExecuteProcess(main_args, app.get(), nullptr);
|
|
if (exit_code >= 0){
|
|
RLOG("CefExecuteProcess error");
|
|
exit(exit_code);
|
|
}
|
|
|
|
CefSettings cef_settings;
|
|
//cef_settings.multi_threaded_message_loop = true;
|
|
#ifdef _DEBUG
|
|
cef_settings.log_severity = LOGSEVERITY_VERBOSE;
|
|
#else
|
|
cef_settings.log_severity = LOGSEVERITY_DISABLE;
|
|
#endif
|
|
tmp_dir = GetTempFileName();
|
|
CefString(&cef_settings.cache_path) = ~tmp_dir;
|
|
CefInitialize(main_args, cef_settings, app.get(), nullptr);
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::MessageLoop()
|
|
{
|
|
CefDoMessageLoopWork();
|
|
SetTimeCallback(30, THISBACK(MessageLoop));
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::State(int reason)
|
|
{
|
|
switch(reason){
|
|
|
|
case FOCUS:
|
|
case ACTIVATE:
|
|
case DEACTIVATE:
|
|
case SHOW:
|
|
case ENABLE:
|
|
break;
|
|
|
|
case OPEN:
|
|
AfterInit();
|
|
break;
|
|
|
|
case CLOSE:
|
|
BeforeTerminate();
|
|
break;
|
|
|
|
case LAYOUTPOS:
|
|
case POSITION:
|
|
Layout();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::AfterInit()
|
|
{
|
|
WhenGotFocus << [this](){ SetFocus(); };
|
|
|
|
handler = new ClientHandler(WhenUrlChange, WhenStatus, WhenMessage, WhenTakeFocus,
|
|
WhenGotFocus, WhenKeyboard, WhenConsoleMessage, WhenCertificateError);
|
|
|
|
CefBrowserSettings br_settings;
|
|
br_settings.file_access_from_file_urls = STATE_DISABLED;
|
|
|
|
Rect r = GetRect();
|
|
CefWindowInfo info;
|
|
|
|
#ifdef GUI_X11
|
|
|
|
info.SetAsChild(GetParentWindow(), CefRect(r.left, r.top, r.Width(), r.Height()));
|
|
|
|
#elif defined(GUI_GTK) && defined(GDK_WINDOWING_X11)
|
|
|
|
info.SetAsChild(gdk_x11_drawable_get_xid(gtk_widget_get_window(GTK_WIDGET(GetTopCtrl()->gtk()))),
|
|
CefRect(r.left, r.top, r.Width(), r.Height()));
|
|
|
|
#elif defined(GUI_WIN32)
|
|
|
|
RECT rect;
|
|
rect.left = r.left;
|
|
rect.top = r.top;
|
|
rect.right = r.Width();
|
|
rect.bottom = r.Height();
|
|
info.SetAsChild(GetTopCtrl()->GetHWND(), rect);
|
|
|
|
#else
|
|
|
|
#error "Unsupported platform"
|
|
|
|
#endif
|
|
|
|
CefBrowserHost::CreateBrowser(info, handler.get(), ~start_page, br_settings, nullptr);
|
|
SetTimeCallback(50, THISBACK(MessageLoop));
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::BeforeTerminate()
|
|
{
|
|
if (handler && handler->GetBrowser()) {
|
|
handler->GetBrowser()->StopLoad();
|
|
Sleep(20);
|
|
handler->GetBrowser()->GetHost()->CloseBrowser(false);
|
|
}
|
|
|
|
CefShutdown();
|
|
DeleteFolderDeep(tmp_dir);
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::Layout()
|
|
{
|
|
if (handler && handler->GetBrowser()){
|
|
|
|
Rect r = GetRect();
|
|
|
|
#ifdef GUI_X11
|
|
|
|
XWindowChanges change = {0};
|
|
change.x = r.left;
|
|
change.y = r.top;
|
|
change.width = r.Width();
|
|
change.height = r.Height();
|
|
XConfigureWindow(Xdisplay, handler->GetBrowser()->GetHost()->GetWindowHandle(), CWHeight | CWWidth | CWY, &change);
|
|
|
|
#elif defined(GUI_GTK) && defined(GDK_WINDOWING_X11)
|
|
|
|
XWindowChanges change = {0};
|
|
change.x = r.left;
|
|
change.y = r.top;
|
|
change.width = r.Width();
|
|
change.height = r.Height();
|
|
XConfigureWindow(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), handler->GetBrowser()->GetHost()->GetWindowHandle(), CWHeight | CWWidth | CWY, &change);
|
|
|
|
#elif defined(GUI_WIN32)
|
|
|
|
CefWindowHandle hwnd = handler->GetBrowser()->GetHost()->GetWindowHandle();
|
|
HDWP hdwp = BeginDeferWindowPos(1);
|
|
hdwp = DeferWindowPos(hdwp, hwnd, nullptr, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER);
|
|
EndDeferWindowPos(hdwp);
|
|
|
|
#else
|
|
|
|
#error "Unsupported platform"
|
|
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
ChromiumBrowser::~ChromiumBrowser()
|
|
{
|
|
BeforeTerminate();
|
|
}
|
|
|
|
|
|
bool ChromiumBrowser::SetFocus()
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
handler->GetBrowser()->GetHost()->SendFocusEvent(true);
|
|
return true;
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::GotFocus()
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
handler->GetBrowser()->GetHost()->SendFocusEvent(true);
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::LostFocus()
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
handler->GetBrowser()->GetHost()->SendFocusEvent(false);
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::Browse(const String & url)
|
|
{
|
|
if (handler && handler->GetBrowser()){
|
|
handler->GetBrowser()->StopLoad();
|
|
handler->GetBrowser()->GetMainFrame()->LoadURL(~url);
|
|
}
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::ShowHTML(const String& html)
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
handler->GetBrowser()->GetMainFrame()->LoadString(~html, "about:blank");
|
|
}
|
|
|
|
|
|
String ChromiumBrowser::GetLocation()
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
return String(handler->GetBrowser()->GetMainFrame()->GetURL());
|
|
|
|
return String::GetVoid();
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::GoBack()
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
handler->GetBrowser()->GoBack();
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::RefreshPage()
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
handler->GetBrowser()->Reload();
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::GoForward()
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
handler->GetBrowser()->GoForward();
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::Stop()
|
|
{
|
|
if (handler && handler->GetBrowser())
|
|
handler->GetBrowser()->StopLoad();
|
|
}
|
|
|
|
|
|
String ChromiumBrowser::GetVersion()
|
|
{
|
|
return Format("CEF %d.%d Chromium %d.%d.%d.%d", cef_version_info(0), cef_version_info(1),
|
|
cef_version_info(2), cef_version_info(3), cef_version_info(4), cef_version_info(5));
|
|
}
|
|
|
|
|
|
void ChromiumBrowser::ExecuteJavaScript(const char * js)
|
|
{
|
|
if (handler && handler->GetBrowser()){
|
|
CefRefPtr<CefFrame> frame = handler->GetBrowser()->GetMainFrame();
|
|
frame->ExecuteJavaScript(js, frame->GetURL(), 0);
|
|
}
|
|
}
|