#include #include #include #include #include #include #include #include #include #include #include #include #include "WebBrowserHost.h" #include "WebClient.h" namespace Atomic { #ifdef ATOMIC_PLATFORM_OSX void* GetNSWindowContentView(void* window); #endif class WebClientPrivate : public CefClient, public CefLifeSpanHandler { friend class WebClient; public: WebClientPrivate(WebClient* client) { webClient_ = client; webBrowserHost_ = webClient_->GetSubsystem(); } CefRefPtr GetRenderHandler() OVERRIDE { if (webClient_->renderHandler_.Null()) return nullptr; return webClient_->renderHandler_->GetCEFRenderHandler(); } virtual CefRefPtr GetLifeSpanHandler() OVERRIDE { return this; } bool OnProcessMessageReceived(CefRefPtr browser, CefProcessId source_process, CefRefPtr message) OVERRIDE { return false; } bool CreateBrowser() { CefWindowInfo windowInfo; CefBrowserSettings browserSettings; Graphics* graphics = webClient_->GetSubsystem(); SDL_Window* sdlWindow = static_cast(graphics->GetSDLWindow()); SDL_SysWMinfo info; SDL_VERSION(&info.version); if(SDL_GetWindowWMInfo(sdlWindow, &info)) { NSView* view = (NSView*) GetNSWindowContentView(info.info.cocoa.window); windowInfo.SetAsWindowless(view, false); CefRefPtr browser = CefBrowserHost::CreateBrowserSync(windowInfo, this, "https://html5test.com/", browserSettings, nullptr); if (!browser.get()) return false; browsers_.Push(browser); return true; } return false; } // CefLifeSpanHandler methods: virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE { CEF_REQUIRE_UI_THREAD(); } virtual bool DoClose(CefRefPtr browser) OVERRIDE { return false; } virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE { CEF_REQUIRE_UI_THREAD(); // Remove from the list of existing browsers. Vector>::Iterator itr = browsers_.Begin(); while (itr != browsers_.End()) { if ((*itr)->IsSame(browser)) { browsers_.Erase(itr); break; } itr++; } } void CloseAllBrowsers(bool force_close) { if (!CefCurrentlyOn(TID_UI)) { // Execute on the UI thread. CefPostTask(TID_UI, base::Bind(&WebClientPrivate::CloseAllBrowsers, this, force_close)); return; } if (!browsers_.Size()) return; // make a copy of vector, as we'll be erasing as we go Vector> browsers = browsers_; Vector>::Iterator itr = browsers.Begin(); while (itr != browsers.End()) { (*itr)->GetHost()->CloseBrowser(force_close); itr++; } browsers_.Clear(); } IMPLEMENT_REFCOUNTING(WebClientPrivate); private: Vector> browsers_; WeakPtr webBrowserHost_; WeakPtr webClient_; }; WebClient::WebClient(Context* context) : Object(context) { d_ = new WebClientPrivate(this); } WebClient::~WebClient() { renderHandler_ = 0; //d_->Release(); } void WebClient::SendMouseClickEvent(int x, int y, unsigned button, bool mouseUp, unsigned modifier) const { if (!d_->browsers_.Size()) return; CefRefPtr browser = d_->browsers_[0]; CefRefPtr host = browser->GetHost(); CefMouseEvent mevent; mevent.x = x; mevent.y = y; mevent.modifiers = 0; //MBT_LEFT = 0, //MBT_MIDDLE, //MBT_RIGHT, host->SendMouseClickEvent(mevent, (CefBrowserHost::MouseButtonType) button, mouseUp, 1); } void WebClient::SendMouseMoveEvent(int x, int y, unsigned modifier, bool mouseLeave) const { if (!d_->browsers_.Size()) return; CefRefPtr browser = d_->browsers_[0]; CefRefPtr host = browser->GetHost(); CefMouseEvent mevent; mevent.x = x; mevent.y = y; mevent.modifiers = 0; //MBT_LEFT = 0, //MBT_MIDDLE, //MBT_RIGHT, host->SendMouseMoveEvent(mevent, mouseLeave); } void WebClient::WasResized() { if (!d_->browsers_.Size()) return; d_->browsers_[0]->GetHost()->WasResized();; } bool WebClient::CreateBrowser() { return d_->CreateBrowser(); } void WebClient::SetWebRenderHandler(WebRenderHandler* handler) { handler->SetWebClient(this); renderHandler_ = handler; } CefClient* WebClient::GetCefClient() { return d_; } }