Merge pull request #2051 from atom/detach-web-contents

Decouple WebContents from NativeWindow
This commit is contained in:
Cheng Zhao 2015-06-25 15:11:40 +08:00
commit 1418fdbc02
25 changed files with 694 additions and 659 deletions

View file

@ -22,7 +22,7 @@ void MenuMac::Popup(Window* window) {
NativeWindow* native_window = window->window();
if (!native_window)
return;
content::WebContents* web_contents = native_window->GetWebContents();
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;
@ -54,7 +54,7 @@ void MenuMac::PopupAt(Window* window, int x, int y) {
NativeWindow* native_window = window->window();
if (!native_window)
return;
content::WebContents* web_contents = native_window->GetWebContents();
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;

View file

@ -24,7 +24,7 @@ void MenuViews::PopupAt(Window* window, int x, int y) {
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
if (!native_window)
return;
content::WebContents* web_contents = native_window->GetWebContents();
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();

View file

@ -11,6 +11,7 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_view_guest_delegate.h"
#include "atom/common/api/api_messages.h"
#include "atom/common/event_emitter_caller.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
@ -24,14 +25,12 @@
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "chrome/browser/printing/print_preview_message_handler.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/guest_host.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
@ -57,10 +56,10 @@ struct PrintSettings {
namespace mate {
template<>
struct Converter<atom::api::SetSizeParams> {
struct Converter<atom::SetSizeParams> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
atom::api::SetSizeParams* out) {
atom::SetSizeParams* out) {
mate::Dictionary params;
if (!ConvertFromV8(isolate, val, &params))
return false;
@ -116,9 +115,6 @@ namespace api {
namespace {
const int kDefaultWidth = 300;
const int kDefaultHeight = 300;
v8::Persistent<v8::ObjectTemplate> template_;
// The wrapWebContents funtion which is implemented in JavaScript
@ -142,46 +138,50 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
} // namespace
WebContents::WebContents(brightray::InspectableWebContents* web_contents)
: WebContents(web_contents->GetWebContents()) {
inspectable_web_contents_ = web_contents;
}
WebContents::WebContents(content::WebContents* web_contents)
: CommonWebContentsDelegate(false),
content::WebContentsObserver(web_contents),
guest_opaque_(true),
guest_host_(nullptr),
auto_size_enabled_(false),
is_full_page_plugin_(false),
inspectable_web_contents_(nullptr) {
: content::WebContentsObserver(web_contents),
type_(REMOTE) {
AttachAsUserData(web_contents);
}
WebContents::WebContents(const mate::Dictionary& options)
: CommonWebContentsDelegate(true),
guest_opaque_(true),
guest_host_(nullptr),
auto_size_enabled_(false),
is_full_page_plugin_(false) {
WebContents::WebContents(const mate::Dictionary& options) {
bool is_guest = false;
options.Get("isGuest", &is_guest);
type_ = is_guest ? WEB_VIEW : BROWSER_WINDOW;
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
content::SiteInstance* site_instance = content::SiteInstance::CreateForURL(
browser_context, GURL("chrome-guest://fake-host"));
content::WebContents::CreateParams params(browser_context, site_instance);
params.guest_delegate = this;
auto web_contents = content::WebContents::Create(params);
NativeWindow* owner_window = nullptr;
WebContents* embedder = nullptr;
if (options.Get("embedder", &embedder) && embedder)
owner_window = NativeWindow::FromWebContents(embedder->web_contents());
content::WebContents* web_contents;
if (is_guest) {
content::SiteInstance* site_instance = content::SiteInstance::CreateForURL(
browser_context, GURL("chrome-guest://fake-host"));
content::WebContents::CreateParams params(browser_context, site_instance);
guest_delegate_.reset(new WebViewGuestDelegate);
params.guest_delegate = guest_delegate_.get();
web_contents = content::WebContents::Create(params);
} else {
content::WebContents::CreateParams params(browser_context);
web_contents = content::WebContents::Create(params);
}
Observe(web_contents);
AttachAsUserData(web_contents);
InitWithWebContents(web_contents, owner_window);
inspectable_web_contents_ = managed_web_contents();
InitWithWebContents(web_contents);
Observe(GetWebContents());
if (is_guest) {
guest_delegate_->Initialize(this);
NativeWindow* owner_window = nullptr;
WebContents* embedder = nullptr;
if (options.Get("embedder", &embedder) && embedder) {
// New WebContents's owner_window is the embedder's owner_window.
auto relay = NativeWindowRelay::FromWebContents(embedder->web_contents());
if (relay)
owner_window = relay->window.get();
}
if (owner_window)
SetOwnerWindow(owner_window);
}
}
WebContents::~WebContents() {
@ -193,8 +193,12 @@ bool WebContents::AddMessageToConsole(content::WebContents* source,
const base::string16& message,
int32 line_no,
const base::string16& source_id) {
Emit("console-message", level, message, line_no, source_id);
return true;
if (type_ == BROWSER_WINDOW) {
return false;
} else {
Emit("console-message", level, message, line_no, source_id);
return true;
}
}
bool WebContents::ShouldCreateWebContents(
@ -206,19 +210,21 @@ bool WebContents::ShouldCreateWebContents(
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) {
Emit("new-window", target_url, frame_name, NEW_FOREGROUND_TAB);
if (type_ == BROWSER_WINDOW)
Emit("-new-window", target_url, frame_name, NEW_FOREGROUND_TAB);
else
Emit("new-window", target_url, frame_name, NEW_FOREGROUND_TAB);
return false;
}
void WebContents::CloseContents(content::WebContents* source) {
Emit("close");
}
content::WebContents* WebContents::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
if (params.disposition != CURRENT_TAB) {
Emit("new-window", params.url, "", params.disposition);
if (type_ == BROWSER_WINDOW)
Emit("-new-window", params.url, "", params.disposition);
else
Emit("new-window", params.url, "", params.disposition);
return nullptr;
}
@ -229,15 +235,43 @@ content::WebContents* WebContents::OpenURLFromTab(
return CommonWebContentsDelegate::OpenURLFromTab(source, params);
}
void WebContents::BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) {
if (type_ == BROWSER_WINDOW)
*proceed_to_fire_unload = proceed;
else
*proceed_to_fire_unload = true;
}
void WebContents::MoveContents(content::WebContents* source,
const gfx::Rect& pos) {
Emit("move", pos);
}
void WebContents::CloseContents(content::WebContents* source) {
Emit("closed");
if (type_ == BROWSER_WINDOW)
owner_window()->CloseContents(source);
}
void WebContents::ActivateContents(content::WebContents* source) {
Emit("activate");
}
bool WebContents::IsPopupOrPanel(const content::WebContents* source) const {
return type_ == BROWSER_WINDOW;
}
void WebContents::HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) {
if (!attached())
return;
// Send the unhandled keyboard events back to the embedder to reprocess them.
embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(
web_contents(), event);
if (type_ == BROWSER_WINDOW) {
owner_window()->HandleKeyboardEvent(source, event);
} else if (type_ == WEB_VIEW && guest_delegate_) {
// Send the unhandled keyboard events back to the embedder.
guest_delegate_->HandleKeyboardEvent(source, event);
}
}
void WebContents::EnterFullscreenModeForTab(content::WebContents* source,
@ -251,6 +285,23 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
Emit("leave-html-full-screen");
}
void WebContents::RendererUnresponsive(content::WebContents* source) {
Emit("unresponsive");
if (type_ == BROWSER_WINDOW)
owner_window()->RendererUnresponsive(source);
}
void WebContents::RendererResponsive(content::WebContents* source) {
Emit("responsive");
if (type_ == BROWSER_WINDOW)
owner_window()->RendererResponsive(source);
}
void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
// Do nothing, we override this method just to avoid compilation error since
// there are two virtual functions named BeforeUnloadFired.
}
void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
int process_id = render_view_host->GetProcess()->GetID();
Emit("render-view-deleted", process_id);
@ -405,21 +456,6 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void WebContents::RenderViewReady() {
if (!is_guest())
return;
// We don't want to accidentally set the opacity of an interstitial page.
// WebContents::GetRenderWidgetHostView will return the RWHV of an
// interstitial page if one is showing at this time. We only want opacity
// to apply to web pages.
auto render_view_host_view = web_contents()->GetRenderViewHost()->GetView();
if (guest_opaque_)
render_view_host_view->SetBackgroundColorToDefault();
else
render_view_host_view->SetBackgroundColor(SK_ColorTRANSPARENT);
}
void WebContents::WebContentsDestroyed() {
// The RenderViewDeleted was not called when the WebContents is destroyed.
RenderViewDeleted(web_contents()->GetRenderViewHost());
@ -433,40 +469,12 @@ void WebContents::NavigationEntryCommitted(
details.is_in_page, details.did_replace_entry);
}
void WebContents::DidAttach(int guest_proxy_routing_id) {
Emit("did-attach");
}
content::WebContents* WebContents::GetOwnerWebContents() const {
return embedder_web_contents_;
}
void WebContents::GuestSizeChanged(const gfx::Size& new_size) {
if (!auto_size_enabled_)
return;
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
guest_size_ = new_size;
}
void WebContents::SetGuestHost(content::GuestHost* guest_host) {
guest_host_ = guest_host;
}
void WebContents::WillAttach(content::WebContents* embedder_web_contents,
int element_instance_id,
bool is_full_page_plugin) {
embedder_web_contents_ = embedder_web_contents;
is_full_page_plugin_ = is_full_page_plugin;
}
void WebContents::Destroy() {
if (is_guest() && managed_web_contents()) {
if (type_ == WEB_VIEW && managed_web_contents()) {
// When force destroying the "destroyed" event is not emitted.
WebContentsDestroyed();
// Give the content module an opportunity to perform some cleanup.
guest_host_->WillDestroy();
guest_host_ = nullptr;
guest_delegate_->Destroy();
Observe(nullptr);
DestroyWebContents();
@ -555,29 +563,32 @@ void WebContents::ExecuteJavaScript(const base::string16& code) {
}
void WebContents::OpenDevTools(mate::Arguments* args) {
if (!inspectable_web_contents())
if (type_ == REMOTE)
return;
bool detach = false;
if (is_guest()) {
if (type_ == WEB_VIEW) {
detach = true;
} else if (args && args->Length() == 1) {
mate::Dictionary options;
args->GetNext(&options) && options.Get("detach", &detach);
}
inspectable_web_contents()->SetCanDock(!detach);
inspectable_web_contents()->ShowDevTools();
managed_web_contents()->SetCanDock(!detach);
managed_web_contents()->ShowDevTools();
}
void WebContents::CloseDevTools() {
if (!inspectable_web_contents())
if (type_ == REMOTE)
return;
inspectable_web_contents()->CloseDevTools();
managed_web_contents()->CloseDevTools();
}
bool WebContents::IsDevToolsOpened() {
if (!inspectable_web_contents())
if (type_ == REMOTE)
return false;
return inspectable_web_contents()->IsDevToolsViewShowing();
return managed_web_contents()->IsDevToolsViewShowing();
}
void WebContents::ToggleDevTools() {
@ -588,8 +599,9 @@ void WebContents::ToggleDevTools() {
}
void WebContents::InspectElement(int x, int y) {
if (!inspectable_web_contents())
if (type_ == REMOTE)
return;
OpenDevTools(nullptr);
scoped_refptr<content::DevToolsAgentHost> agent(
content::DevToolsAgentHost::GetOrCreateFor(web_contents()));
@ -597,13 +609,14 @@ void WebContents::InspectElement(int x, int y) {
}
void WebContents::InspectServiceWorker() {
if (!inspectable_web_contents())
if (type_ == REMOTE)
return;
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
if (agent_host->GetType() ==
content::DevToolsAgentHost::TYPE_SERVICE_WORKER) {
OpenDevTools(nullptr);
inspectable_web_contents()->AttachTo(agent_host);
managed_web_contents()->AttachTo(agent_host);
break;
}
}
@ -715,76 +728,17 @@ bool WebContents::SendIPCMessage(const base::string16& channel,
}
void WebContents::SetSize(const SetSizeParams& params) {
bool enable_auto_size =
params.enable_auto_size ? *params.enable_auto_size : auto_size_enabled_;
gfx::Size min_size = params.min_size ? *params.min_size : min_auto_size_;
gfx::Size max_size = params.max_size ? *params.max_size : max_auto_size_;
if (params.normal_size)
normal_size_ = *params.normal_size;
min_auto_size_ = min_size;
min_auto_size_.SetToMin(max_size);
max_auto_size_ = max_size;
max_auto_size_.SetToMax(min_size);
enable_auto_size &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty();
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
if (enable_auto_size) {
// Autosize is being enabled.
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
normal_size_.SetSize(0, 0);
} else {
// Autosize is being disabled.
// Use default width/height if missing from partially defined normal size.
if (normal_size_.width() && !normal_size_.height())
normal_size_.set_height(GetDefaultSize().height());
if (!normal_size_.width() && normal_size_.height())
normal_size_.set_width(GetDefaultSize().width());
gfx::Size new_size;
if (!normal_size_.IsEmpty()) {
new_size = normal_size_;
} else if (!guest_size_.IsEmpty()) {
new_size = guest_size_;
} else {
new_size = GetDefaultSize();
}
if (auto_size_enabled_) {
// Autosize was previously enabled.
rvh->DisableAutoResize(new_size);
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
} else {
// Autosize was already disabled.
guest_host_->SizeContents(new_size);
}
guest_size_ = new_size;
}
auto_size_enabled_ = enable_auto_size;
if (guest_delegate_)
guest_delegate_->SetSize(params);
}
void WebContents::SetAllowTransparency(bool allow) {
if (guest_opaque_ != allow)
return;
auto render_view_host = web_contents()->GetRenderViewHost();
guest_opaque_ = !allow;
if (!render_view_host->GetView())
return;
if (guest_opaque_) {
render_view_host->GetView()->SetBackgroundColorToDefault();
} else {
render_view_host->GetView()->SetBackgroundColor(SK_ColorTRANSPARENT);
}
if (guest_delegate_)
guest_delegate_->SetAllowTransparency(allow);
}
bool WebContents::IsGuest() const {
return is_guest();
return type_ == WEB_VIEW;
}
mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
@ -856,38 +810,6 @@ void WebContents::OnRendererMessageSync(const base::string16& channel,
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
}
void WebContents::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
const gfx::Size& new_size) {
Emit("size-changed",
old_size.width(), old_size.height(),
new_size.width(), new_size.height());
}
gfx::Size WebContents::GetDefaultSize() const {
if (is_full_page_plugin_) {
// Full page plugins default to the size of the owner's viewport.
return embedder_web_contents_->GetRenderWidgetHostView()
->GetVisibleViewportSize();
} else {
return gfx::Size(kDefaultWidth, kDefaultHeight);
}
}
// static
mate::Handle<WebContents> WebContents::CreateFrom(
v8::Isolate* isolate, brightray::InspectableWebContents* web_contents) {
// We have an existing WebContents object in JS.
auto existing = TrackableObject::FromWrappedClass(
isolate, web_contents->GetWebContents());
if (existing)
return mate::CreateHandle(isolate, static_cast<WebContents*>(existing));
// Otherwise create a new WebContents wrapper object.
auto handle = mate::CreateHandle(isolate, new WebContents(web_contents));
g_wrap_web_contents.Run(handle.ToV8());
return handle;
}
// static
mate::Handle<WebContents> WebContents::CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents) {

View file

@ -10,7 +10,6 @@
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/common_web_contents_delegate.h"
#include "content/public/browser/browser_plugin_guest_delegate.h"
#include "content/public/common/favicon_url.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/gpu_data_manager_observer.h"
@ -28,26 +27,12 @@ class Dictionary;
namespace atom {
struct SetSizeParams;
class WebViewGuestDelegate;
namespace api {
// A struct of parameters for SetSize(). The parameters are all declared as
// scoped pointers since they are all optional. Null pointers indicate that the
// parameter has not been provided, and the last used value should be used. Note
// that when |enable_auto_size| is true, providing |normal_size| is not
// meaningful. This is because the normal size of the guestview is overridden
// whenever autosizing occurs.
struct SetSizeParams {
SetSizeParams() {}
~SetSizeParams() {}
scoped_ptr<bool> enable_auto_size;
scoped_ptr<gfx::Size> min_size;
scoped_ptr<gfx::Size> max_size;
scoped_ptr<gfx::Size> normal_size;
};
class WebContents : public mate::TrackableObject<WebContents>,
public content::BrowserPluginGuestDelegate,
public CommonWebContentsDelegate,
public content::WebContentsObserver,
public content::GpuDataManagerObserver {
@ -57,8 +42,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
PrintToPDFCallback;
// Create from an existing WebContents.
static mate::Handle<WebContents> CreateFrom(
v8::Isolate* isolate, brightray::InspectableWebContents* web_contents);
static mate::Handle<WebContents> CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents);
@ -117,26 +100,12 @@ class WebContents : public mate::TrackableObject<WebContents>,
bool SendIPCMessage(const base::string16& channel,
const base::ListValue& args);
// Used to toggle autosize mode for this GuestView, and set both the automatic
// and normal sizes.
// Methods for creating <webview>.
void SetSize(const SetSizeParams& params);
// Sets the transparency of the guest.
void SetAllowTransparency(bool allow);
bool IsGuest() const;
// Returns whether this guest has an associated embedder.
bool attached() const { return !!embedder_web_contents_; }
// Returns the current InspectableWebContents object, nullptr will be returned
// if current WebContents can not beinspected, e.g. it is the devtools.
brightray::InspectableWebContents* inspectable_web_contents() const {
return inspectable_web_contents_;
}
protected:
explicit WebContents(brightray::InspectableWebContents* web_contents);
explicit WebContents(content::WebContents* web_contents);
explicit WebContents(const mate::Dictionary& options);
~WebContents();
@ -160,18 +129,28 @@ class WebContents : public mate::TrackableObject<WebContents>,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override;
void CloseContents(content::WebContents* source) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) override;
void MoveContents(content::WebContents* source,
const gfx::Rect& pos) override;
void CloseContents(content::WebContents* source) override;
void ActivateContents(content::WebContents* contents) override;
bool IsPopupOrPanel(const content::WebContents* source) const override;
void HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
void EnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin) override;
void ExitFullscreenModeForTab(content::WebContents* source) override;
void RendererUnresponsive(content::WebContents* source) override;
void RendererResponsive(content::WebContents* source) override;
// content::WebContentsObserver:
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
void RenderViewDeleted(content::RenderViewHost*) override;
void RenderProcessGone(base::TerminationStatus status) override;
void DocumentLoadedInFrame(
@ -197,7 +176,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) override;
bool OnMessageReceived(const IPC::Message& message) override;
void RenderViewReady() override;
void WebContentsDestroyed() override;
void NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) override;
@ -207,19 +185,16 @@ class WebContents : public mate::TrackableObject<WebContents>,
void PluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid) override;
// content::BrowserPluginGuestDelegate:
void DidAttach(int guest_proxy_routing_id) final;
content::WebContents* GetOwnerWebContents() const final;
void GuestSizeChanged(const gfx::Size& new_size) final;
void SetGuestHost(content::GuestHost* guest_host) final;
void WillAttach(content::WebContents* embedder_web_contents,
int element_instance_id,
bool is_full_page_plugin) final;
// content::GpuDataManagerObserver:
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
private:
enum Type {
BROWSER_WINDOW, // Used by BrowserWindow.
WEB_VIEW, // Used by <webview>.
REMOTE, // Thin wrap around an existing WebContents.
};
// Called when received a message from renderer.
void OnRendererMessage(const base::string16& channel,
const base::ListValue& args);
@ -229,53 +204,12 @@ class WebContents : public mate::TrackableObject<WebContents>,
const base::ListValue& args,
IPC::Message* message);
// This method is invoked when the contents auto-resized to give the container
// an opportunity to match it if it wishes.
//
// This gives the derived class an opportunity to inform its container element
// or perform other actions.
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
const gfx::Size& new_size);
// Returns the default size of the guestview.
gfx::Size GetDefaultSize() const;
v8::Global<v8::Value> session_;
// Stores whether the contents of the guest can be transparent.
bool guest_opaque_;
scoped_ptr<WebViewGuestDelegate> guest_delegate_;
// The WebContents that attaches this guest view.
content::WebContents* embedder_web_contents_;
// The size of the container element.
gfx::Size element_size_;
// The size of the guest content. Note: In autosize mode, the container
// element may not match the size of the guest.
gfx::Size guest_size_;
// A pointer to the guest_host.
content::GuestHost* guest_host_;
// Indicates whether autosize mode is enabled or not.
bool auto_size_enabled_;
// The maximum size constraints of the container element in autosize mode.
gfx::Size max_auto_size_;
// The minimum size constraints of the container element in autosize mode.
gfx::Size min_auto_size_;
// The size that will be used when autosize mode is disabled.
gfx::Size normal_size_;
// Whether the guest view is inside a plugin document.
bool is_full_page_plugin_;
// Current InspectableWebContents object, can be nullptr for WebContents of
// devtools. It is a weak reference.
brightray::InspectableWebContents* inspectable_web_contents_;
// The type of current WebContents.
Type type_;
DISALLOW_COPY_AND_ASSIGN(WebContents);
};

View file

@ -38,8 +38,17 @@ void OnCapturePageDone(
} // namespace
Window::Window(const mate::Dictionary& options)
: window_(NativeWindow::Create(options)) {
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
// Creates the WebContents used by BrowserWindow.
mate::Dictionary web_contents_options(isolate, v8::Object::New(isolate));
auto web_contents = WebContents::Create(isolate, web_contents_options);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
// Creates BrowserWindow.
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
options));
web_contents->SetOwnerWindow(window_.get());
window_->InitFromOptions(options);
window_->AddObserver(this);
}
@ -49,29 +58,11 @@ Window::~Window() {
Destroy();
}
void Window::AfterInit(v8::Isolate* isolate) {
mate::TrackableObject<Window>::AfterInit(isolate);
auto web_contents = window_->managed_web_contents();
auto handle = WebContents::CreateFrom(isolate, web_contents);
web_contents_.Reset(isolate, handle.ToV8());
}
void Window::OnPageTitleUpdated(bool* prevent_default,
const std::string& title) {
*prevent_default = Emit("page-title-updated", title);
}
void Window::WillCreatePopupWindow(const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
WindowOpenDisposition disposition) {
Emit("-new-window", target_url, frame_name);
}
void Window::WillNavigate(bool* prevent_default, const GURL& url) {
*prevent_default = Emit("-will-navigate", url);
}
void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}
@ -79,6 +70,12 @@ void Window::WillCloseWindow(bool* prevent_default) {
void Window::OnWindowClosed() {
Emit("closed");
if (api_web_contents_) {
api_web_contents_->DestroyWebContents();
api_web_contents_ = nullptr;
web_contents_.Reset();
}
RemoveFromWeakMap();
window_->RemoveObserver(this);
}
@ -152,8 +149,8 @@ void Window::OnDevToolsOpened() {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto handle = WebContents::CreateFrom(isolate(),
window_->GetDevToolsWebContents());
auto handle = WebContents::CreateFrom(
isolate(), api_web_contents_->GetDevToolsWebContents());
devtools_web_contents_.Reset(isolate(), handle.ToV8());
}
@ -173,12 +170,11 @@ mate::Wrappable* Window::New(v8::Isolate* isolate,
"Cannot create BrowserWindow before app is ready");
return nullptr;
}
return new Window(options);
return new Window(isolate, options);
}
void Window::Destroy() {
window_->DestroyWebContents();
window_->CloseImmediately();
window_->CloseContents(nullptr);
}
void Window::Close() {

View file

@ -45,20 +45,12 @@ class Window : public mate::TrackableObject<Window>,
NativeWindow* window() const { return window_.get(); }
protected:
explicit Window(const mate::Dictionary& options);
Window(v8::Isolate* isolate, const mate::Dictionary& options);
virtual ~Window();
// mate::Wrappable:
void AfterInit(v8::Isolate* isolate) override;
// NativeWindowObserver:
void OnPageTitleUpdated(bool* prevent_default,
const std::string& title) override;
void WillCreatePopupWindow(const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
WindowOpenDisposition disposition) override;
void WillNavigate(bool* prevent_default, const GURL& url) override;
void WillCloseWindow(bool* prevent_default) override;
void OnWindowClosed() override;
void OnWindowBlur() override;
@ -154,6 +146,8 @@ class Window : public mate::TrackableObject<Window>,
v8::Global<v8::Value> devtools_web_contents_;
v8::Global<v8::Value> menu_;
api::WebContents* api_web_contents_;
scoped_ptr<NativeWindow> window_;
DISALLOW_COPY_AND_ASSIGN(Window);

View file

@ -6,6 +6,7 @@
#include "atom/browser/api/event.h"
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
namespace mate {
@ -15,8 +16,8 @@ namespace {
v8::Persistent<v8::ObjectTemplate> event_template;
void PreventDefault(mate::Arguments* args) {
args->GetThis()->Set(StringToV8(args->isolate(), "defaultPrevented"),
v8::True(args->isolate()));
mate::Dictionary self(args->isolate(), args->GetThis());
self.Set("defaultPrevented", true);
}
// Create a pure JavaScript Event object.
@ -38,7 +39,7 @@ EventEmitter::EventEmitter() {
v8::Local<v8::Object> EventEmitter::CreateEvent(v8::Isolate* isolate,
content::WebContents* sender,
IPC::Message* message) const {
IPC::Message* message) {
v8::Local<v8::Object> event;
bool use_native_event = sender && message;
@ -49,6 +50,7 @@ v8::Local<v8::Object> EventEmitter::CreateEvent(v8::Isolate* isolate,
} else {
event = CreateEventObject(isolate);
}
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
return event;
}

View file

@ -25,9 +25,6 @@ class EventEmitter : public Wrappable {
public:
typedef std::vector<v8::Local<v8::Value>> ValueArray;
protected:
EventEmitter();
// this.emit(name, new Event(), args...);
template<typename... Args>
bool Emit(const base::StringPiece& name, const Args&... args) {
@ -48,10 +45,13 @@ class EventEmitter : public Wrappable {
StringToV8(isolate(), "defaultPrevented"))->BooleanValue();
}
protected:
EventEmitter();
private:
v8::Local<v8::Object> CreateEvent(v8::Isolate* isolate,
content::WebContents* sender,
IPC::Message* message) const;
IPC::Message* message);
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
};

View file

@ -12,14 +12,18 @@ BrowserWindow::_init = ->
@setMenu menu if menu?
# Make new windows requested by links behave like "window.open"
@on '-new-window', (event, url, frameName) =>
event.sender = @webContents
@webContents.on '-new-window', (event, url, frameName) ->
options = show: true, width: 800, height: 600
ipc.emit 'ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options
# Redirect "will-navigate" to webContents.
@on '-will-navigate', (event, url) =>
@webContents.emit 'will-navigate', event, url
# window.move(...)
@webContents.on 'move', (event, size) =>
@setSize size
# Hide the auto-hide menu when webContents is focused.
@webContents.on 'activate', =>
if process.platform isnt 'darwin' and @isMenuBarAutoHide() and @isMenuBarVisible()
@setMenuBarVisibility false
# Redirect focus/blur event to app instance too.
@on 'blur', (event) =>

View file

@ -33,12 +33,10 @@ wrapWebContents = (webContents) ->
# Dispatch IPC messages to the ipc module.
webContents.on 'ipc-message', (event, packed) ->
[channel, args...] = packed
Object.defineProperty event, 'sender', value: webContents
ipc.emit channel, event, args...
webContents.on 'ipc-message-sync', (event, packed) ->
[channel, args...] = packed
Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value)
Object.defineProperty event, 'sender', value: webContents
ipc.emit channel, event, args...
webContents.printToPDF = (options, callback) ->

View file

@ -63,7 +63,7 @@ ProcessOwner GetProcessOwner(int process_id,
// First search for NativeWindow.
for (auto native_window : *WindowList::GetInstance())
if (web_contents == native_window->GetWebContents()) {
if (web_contents == native_window->web_contents()) {
*window = native_window;
return OWNER_NATIVE_WINDOW;
}

View file

@ -65,12 +65,15 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
if (!item)
return;
NativeWindow* window = nullptr;
auto relay = NativeWindowRelay::FromWebContents(item->GetWebContents());
if (relay)
window = relay->window.get();
file_dialog::Filters filters;
base::FilePath path;
auto owner_window_ = NativeWindow::FromWebContents(item->GetWebContents());
if (!file_dialog::ShowSaveDialog(
owner_window_, item->GetURL().spec(),
default_path, filters, &path)) {
if (!file_dialog::ShowSaveDialog(window, item->GetURL().spec(), default_path,
filters, &path)) {
return;
}

View file

@ -107,10 +107,8 @@ void AppendToFile(const base::FilePath& path,
} // namespace
CommonWebContentsDelegate::CommonWebContentsDelegate(bool is_guest)
: is_guest_(is_guest),
owner_window_(nullptr),
html_fullscreen_(false),
CommonWebContentsDelegate::CommonWebContentsDelegate()
: html_fullscreen_(false),
native_fullscreen_(false) {
}
@ -118,9 +116,7 @@ CommonWebContentsDelegate::~CommonWebContentsDelegate() {
}
void CommonWebContentsDelegate::InitWithWebContents(
content::WebContents* web_contents,
NativeWindow* owner_window) {
owner_window_ = owner_window;
content::WebContents* web_contents) {
web_contents->SetDelegate(this);
printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
@ -131,6 +127,13 @@ void CommonWebContentsDelegate::InitWithWebContents(
web_contents_->SetDelegate(this);
}
void CommonWebContentsDelegate::SetOwnerWindow(NativeWindow* owner_window) {
content::WebContents* web_contents = GetWebContents();
owner_window_ = owner_window->GetWeakPtr();
NativeWindowRelay* relay = new NativeWindowRelay(owner_window_);
web_contents->SetUserData(relay->key, relay);
}
void CommonWebContentsDelegate::DestroyWebContents() {
web_contents_.reset();
}
@ -177,11 +180,6 @@ bool CommonWebContentsDelegate::CanOverscrollContent() const {
return false;
}
bool CommonWebContentsDelegate::IsPopupOrPanel(
const content::WebContents* source) const {
return !is_guest_;
}
content::JavaScriptDialogManager*
CommonWebContentsDelegate::GetJavaScriptDialogManager(
content::WebContents* source) {
@ -202,7 +200,7 @@ void CommonWebContentsDelegate::RunFileChooser(
content::WebContents* guest,
const content::FileChooserParams& params) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(owner_window_));
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
web_dialog_helper_->RunFileChooser(guest, params);
}
@ -210,7 +208,7 @@ void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
int request_id,
const base::FilePath& path) {
if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(owner_window_));
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
}
@ -246,7 +244,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile(
} else {
file_dialog::Filters filters;
base::FilePath default_path(base::FilePath::FromUTF8Unsafe(url));
if (!file_dialog::ShowSaveDialog(owner_window_, url, default_path,
if (!file_dialog::ShowSaveDialog(owner_window(), url, default_path,
filters, &path)) {
base::StringValue url_value(url);
web_contents_->CallClientFunction(
@ -281,7 +279,7 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem() {
base::FilePath default_path;
std::vector<base::FilePath> paths;
int flag = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
if (!file_dialog::ShowOpenDialog(owner_window_, "", default_path,
if (!file_dialog::ShowOpenDialog(owner_window(), "", default_path,
filters, flag, &paths))
return;

View file

@ -23,13 +23,15 @@ class CommonWebContentsDelegate
: public brightray::DefaultWebContentsDelegate,
public brightray::InspectableWebContentsDelegate {
public:
explicit CommonWebContentsDelegate(bool is_guest);
CommonWebContentsDelegate();
virtual ~CommonWebContentsDelegate();
// Create a InspectableWebContents object and takes onwership of
// Creates a InspectableWebContents object and takes onwership of
// |web_contents|.
void InitWithWebContents(content::WebContents* web_contents,
NativeWindow* owner_window);
void InitWithWebContents(content::WebContents* web_contents);
// Set the window as owner window.
void SetOwnerWindow(NativeWindow* owner_window);
// Destroy the managed InspectableWebContents object.
void DestroyWebContents();
@ -44,7 +46,7 @@ class CommonWebContentsDelegate
return web_contents_.get();
}
bool is_guest() const { return is_guest_; }
NativeWindow* owner_window() const { return owner_window_.get(); }
protected:
// content::WebContentsDelegate:
@ -55,7 +57,6 @@ class CommonWebContentsDelegate
bool user_gesture,
bool last_unlocked_by_target) override;
bool CanOverscrollContent() const override;
bool IsPopupOrPanel(const content::WebContents* source) const override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
content::ColorChooser* OpenColorChooser(
@ -92,11 +93,8 @@ class CommonWebContentsDelegate
// Set fullscreen mode triggered by html api.
void SetHtmlApiFullscreen(bool enter_fullscreen);
// Whether this is guest WebContents or NativeWindow.
const bool is_guest_;
// The window that this WebContents belongs to.
NativeWindow* owner_window_;
base::WeakPtr<NativeWindow> owner_window_;
// Whether window is fullscreened by HTML5 api.
bool html_fullscreen_;

View file

@ -38,7 +38,7 @@ createGuest = (embedder, params) ->
webViewManager ?= process.atomBinding 'web_view_manager'
id = getNextInstanceId embedder
guest = webContents.create {embedder}
guest = webContents.create {isGuest: true, embedder}
guestInstances[id] = {guest, embedder}
# Destroy guest when the embedder is gone or navigated.

View file

@ -30,9 +30,6 @@
#include "brightray/browser/inspectable_web_contents_view.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
@ -59,6 +56,8 @@ using content::NavigationEntry;
using content::RenderWidgetHostView;
using content::RenderWidgetHost;
DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
namespace atom {
namespace {
@ -84,10 +83,10 @@ std::string RemoveWhitespace(const std::string& str) {
} // namespace
NativeWindow::NativeWindow(content::WebContents* web_contents,
const mate::Dictionary& options)
: CommonWebContentsDelegate(false),
content::WebContentsObserver(web_contents),
NativeWindow::NativeWindow(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options)
: content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
has_frame_(true),
transparent_(false),
enable_larger_than_screen_(false),
@ -95,8 +94,9 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
node_integration_(true),
has_dialog_attached_(false),
zoom_factor_(1.0),
inspectable_web_contents_(inspectable_web_contents),
weak_factory_(this) {
InitWithWebContents(web_contents, this);
inspectable_web_contents->GetView()->SetDelegate(this);
options.Get(switches::kFrame, &has_frame_);
options.Get(switches::kTransparent, &transparent_);
@ -138,12 +138,8 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
RemoveWhitespace(browser->GetName()).c_str(),
browser->GetVersion().c_str(),
CHROME_VERSION_STRING);
web_contents->GetMutableRendererPrefs()->user_agent_override =
web_contents()->GetMutableRendererPrefs()->user_agent_override =
content::BuildUserAgentFromProduct(product_name);
// Get notified of title updated message.
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
content::Source<content::WebContents>(web_contents));
}
NativeWindow::~NativeWindow() {
@ -152,19 +148,12 @@ NativeWindow::~NativeWindow() {
NotifyWindowClosed();
}
// static
NativeWindow* NativeWindow::Create(const mate::Dictionary& options) {
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
content::WebContents::CreateParams create_params(browser_context);
return Create(content::WebContents::Create(create_params), options);
}
// static
NativeWindow* NativeWindow::FromWebContents(
content::WebContents* web_contents) {
WindowList& window_list = *WindowList::GetInstance();
for (NativeWindow* window : window_list) {
if (window->GetWebContents() == web_contents)
if (window->web_contents() == web_contents)
return window;
}
return nullptr;
@ -279,24 +268,22 @@ bool NativeWindow::HasModalDialog() {
}
void NativeWindow::FocusOnWebView() {
GetWebContents()->GetRenderViewHost()->Focus();
web_contents()->GetRenderViewHost()->Focus();
}
void NativeWindow::BlurWebView() {
GetWebContents()->GetRenderViewHost()->Blur();
web_contents()->GetRenderViewHost()->Blur();
}
bool NativeWindow::IsWebViewFocused() {
RenderWidgetHostView* host_view =
GetWebContents()->GetRenderViewHost()->GetView();
auto host_view = web_contents()->GetRenderViewHost()->GetView();
return host_view && host_view->HasFocus();
}
void NativeWindow::CapturePage(const gfx::Rect& rect,
const CapturePageCallback& callback) {
content::WebContents* contents = GetWebContents();
RenderWidgetHostView* const view = contents->GetRenderWidgetHostView();
RenderWidgetHost* const host = view ? view->GetRenderWidgetHost() : nullptr;
const auto view = web_contents()->GetRenderWidgetHostView();
const auto host = view ? view->GetRenderWidgetHost() : nullptr;
if (!view || !host) {
callback.Run(SkBitmap());
return;
@ -326,7 +313,7 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
kBGRA_8888_SkColorType);
}
void NativeWindow::CloseWebContents() {
void NativeWindow::RequestToClosePage() {
bool prevent_default = false;
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
@ -336,12 +323,6 @@ void NativeWindow::CloseWebContents() {
return;
}
content::WebContents* web_contents(GetWebContents());
if (!web_contents) {
CloseImmediately();
return;
}
// Assume the window is not responding if it doesn't cancel the close and is
// not closed in 5s, in this way we can quickly show the unresponsive
// dialog when the window is busy executing some script withouth waiting for
@ -349,10 +330,45 @@ void NativeWindow::CloseWebContents() {
if (window_unresposive_closure_.IsCancelled())
ScheduleUnresponsiveEvent(5000);
if (web_contents->NeedToFireBeforeUnload())
web_contents->DispatchBeforeUnload(false);
if (web_contents()->NeedToFireBeforeUnload())
web_contents()->DispatchBeforeUnload(false);
else
web_contents->Close();
web_contents()->Close();
}
void NativeWindow::CloseContents(content::WebContents* source) {
if (!inspectable_web_contents_)
return;
inspectable_web_contents_->GetView()->SetDelegate(nullptr);
inspectable_web_contents_ = nullptr;
Observe(nullptr);
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
// want to free memory when the window is closed, you can do deleting by
// overriding the OnWindowClosed method in the observer.
CloseImmediately();
// Do not sent "unresponsive" event after window is closed.
window_unresposive_closure_.Cancel();
}
void NativeWindow::RendererUnresponsive(content::WebContents* source) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicity started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
ScheduleUnresponsiveEvent(50);
}
void NativeWindow::RendererResponsive(content::WebContents* source) {
window_unresposive_closure_.Cancel();
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
}
void NativeWindow::AppendExtraCommandLineSwitches(
@ -430,10 +446,6 @@ void NativeWindow::NotifyWindowClosed() {
is_closed_ = true;
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowClosed());
// Do not receive any notification after window has been closed, there is a
// crash that seems to be caused by this: http://git.io/YqMG5g.
registrar_.RemoveAll();
WindowList::RemoveWindow(this);
}
@ -493,50 +505,16 @@ void NativeWindow::NotifyWindowLeaveHtmlFullScreen() {
OnWindowLeaveHtmlFullScreen());
}
bool NativeWindow::ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) {
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillCreatePopupWindow(frame_name,
target_url,
partition_id,
NEW_FOREGROUND_TAB));
return false;
void NativeWindow::DevToolsFocused() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus());
}
// In atom-shell all reloads and navigations started by renderer process would
// be redirected to this method, so we can have precise control of how we
// would open the url (in our case, is to restart the renderer process). See
// AtomRendererClient::ShouldFork for how this is done.
content::WebContents* NativeWindow::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
if (params.disposition != CURRENT_TAB) {
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillCreatePopupWindow(base::string16(),
params.url,
"",
params.disposition));
return nullptr;
}
void NativeWindow::DevToolsOpened() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsOpened());
}
// Give user a chance to prevent navigation.
bool prevent_default = false;
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
WillNavigate(&prevent_default, params.url));
if (prevent_default)
return nullptr;
return CommonWebContentsDelegate::OpenURLFromTab(source, params);
void NativeWindow::DevToolsClosed() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed());
}
void NativeWindow::RenderViewCreated(
@ -551,66 +529,22 @@ void NativeWindow::RenderViewCreated(
impl->SetBackgroundOpaque(false);
}
void NativeWindow::BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) {
*proceed_to_fire_unload = proceed;
void NativeWindow::BeforeUnloadDialogCancelled() {
WindowList::WindowCloseCancelled(this);
if (!proceed) {
WindowList::WindowCloseCancelled(this);
// Cancel unresponsive event when window close is cancelled.
window_unresposive_closure_.Cancel();
}
}
void NativeWindow::ActivateContents(content::WebContents* contents) {
FocusOnWebView();
}
void NativeWindow::DeactivateContents(content::WebContents* contents) {
BlurWebView();
}
void NativeWindow::MoveContents(content::WebContents* source,
const gfx::Rect& pos) {
SetBounds(pos);
}
void NativeWindow::CloseContents(content::WebContents* source) {
// Destroy the WebContents before we close the window.
DestroyWebContents();
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.
// In this way, it would be safe to manage windows via smart pointers. If you
// want to free memory when the window is closed, you can do deleting by
// overriding the OnWindowClosed method in the observer.
CloseImmediately();
// Do not sent "unresponsive" event after window is closed.
// Cancel unresponsive event when window close is cancelled.
window_unresposive_closure_.Cancel();
}
void NativeWindow::RendererUnresponsive(content::WebContents* source) {
// Schedule the unresponsive shortly later, since we may receive the
// responsive event soon. This could happen after the whole application had
// blocked for a while.
// Also notice that when closing this event would be ignored because we have
// explicity started a close timeout counter. This is on purpose because we
// don't want the unresponsive event to be sent too early when user is closing
// the window.
ScheduleUnresponsiveEvent(50);
}
void NativeWindow::RendererResponsive(content::WebContents* source) {
window_unresposive_closure_.Cancel();
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnRendererResponsive());
}
void NativeWindow::BeforeUnloadFired(const base::TimeTicks& proceed_time) {
// Do nothing, we override this method just to avoid compilation error since
// there are two virtual functions named BeforeUnloadFired.
void NativeWindow::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) {
bool prevent_default = false;
std::string text = base::UTF16ToUTF8(entry->GetTitle());
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
if (!prevent_default)
SetTitle(text);
}
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
@ -624,38 +558,6 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
return handled;
}
void NativeWindow::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
std::pair<NavigationEntry*, bool>* title =
content::Details<std::pair<NavigationEntry*, bool>>(details).ptr();
if (title->first) {
bool prevent_default = false;
std::string text = base::UTF16ToUTF8(title->first->GetTitle());
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnPageTitleUpdated(&prevent_default, text));
if (!prevent_default)
SetTitle(text);
}
}
}
void NativeWindow::DevToolsFocused() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsFocus());
}
void NativeWindow::DevToolsOpened() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsOpened());
}
void NativeWindow::DevToolsClosed() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed());
}
void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
if (!window_unresposive_closure_.IsCancelled())
return;

View file

@ -9,26 +9,30 @@
#include <string>
#include <vector>
#include "atom/browser/common_web_contents_delegate.h"
#include "atom/browser/native_window_observer.h"
#include "atom/browser/ui/accelerator_util.h"
#include "base/cancelable_callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_observer.h"
#include "brightray/browser/inspectable_web_contents_view_delegate.h"
#include "content/public/browser/readback_types.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "native_mate/persistent_dictionary.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
namespace base {
class CommandLine;
}
namespace brightray {
class InspectableWebContents;
}
namespace content {
class BrowserContext;
class WebContents;
struct NativeWebKeyboardEvent;
struct WebPreferences;
}
@ -50,9 +54,8 @@ namespace atom {
struct DraggableRegion;
class NativeWindow : public CommonWebContentsDelegate,
public content::WebContentsObserver,
public content::NotificationObserver {
class NativeWindow : public content::WebContentsObserver,
public brightray::InspectableWebContentsViewDelegate {
public:
typedef base::Callback<void(const SkBitmap& bitmap)> CapturePageCallback;
@ -79,12 +82,9 @@ class NativeWindow : public CommonWebContentsDelegate,
// Create window with existing WebContents, the caller is responsible for
// managing the window's live.
static NativeWindow* Create(content::WebContents* web_contents,
const mate::Dictionary& options);
// Create window with new WebContents, the caller is responsible for
// managing the window's live.
static NativeWindow* Create(const mate::Dictionary& options);
static NativeWindow* Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
// Find a window from its WebContents
static NativeWindow* FromWebContents(content::WebContents* web_contents);
@ -163,15 +163,21 @@ class NativeWindow : public CommonWebContentsDelegate,
virtual void SetMenuBarVisibility(bool visible);
virtual bool IsMenuBarVisible();
// The same with closing a tab in a real browser.
//
// Should be called by platform code when user want to close the window.
virtual void CloseWebContents();
base::WeakPtr<NativeWindow> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// Requests the WebContents to close, can be cancelled by the page.
virtual void RequestToClosePage();
// Methods called by the WebContents.
virtual void CloseContents(content::WebContents* source);
virtual void RendererUnresponsive(content::WebContents* source);
virtual void RendererResponsive(content::WebContents* source);
virtual void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {}
// Called when renderer process is going to be started.
void AppendExtraCommandLineSwitches(base::CommandLine* command_line);
void OverrideWebkitPrefs(content::WebPreferences* prefs);
@ -202,7 +208,7 @@ class NativeWindow : public CommonWebContentsDelegate,
}
brightray::InspectableWebContents* inspectable_web_contents() const {
return managed_web_contents();
return inspectable_web_contents_;
}
bool has_frame() const { return has_frame_; }
@ -212,52 +218,24 @@ class NativeWindow : public CommonWebContentsDelegate,
}
protected:
explicit NativeWindow(content::WebContents* web_contents,
const mate::Dictionary& options);
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
// Called when the window needs to update its draggable region.
virtual void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) = 0;
// Implementations of content::WebContentsDelegate.
bool ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const base::string16& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) override;
void ActivateContents(content::WebContents* contents) override;
void DeactivateContents(content::WebContents* contents) override;
void MoveContents(content::WebContents* source,
const gfx::Rect& pos) override;
void CloseContents(content::WebContents* source) override;
void RendererUnresponsive(content::WebContents* source) override;
void RendererResponsive(content::WebContents* source) override;
// Implementations of content::WebContentsObserver.
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
bool OnMessageReceived(const IPC::Message& message) override;
// Implementations of content::NotificationObserver.
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// Implementations of brightray::InspectableWebContentsDelegate.
// brightray::InspectableWebContentsViewDelegate:
void DevToolsFocused() override;
void DevToolsOpened() override;
void DevToolsClosed() override;
// content::WebContentsObserver:
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadDialogCancelled() override;
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
bool OnMessageReceived(const IPC::Message& message) override;
// Whether window has standard frame.
bool has_frame_;
@ -282,9 +260,6 @@ class NativeWindow : public CommonWebContentsDelegate,
const SkBitmap& bitmap,
content::ReadbackResponse response);
// Notification manager.
content::NotificationRegistrar registrar_;
// Observers of this window.
ObserverList<NativeWindowObserver> observers_;
@ -310,11 +285,29 @@ class NativeWindow : public CommonWebContentsDelegate,
// Page's default zoom factor.
double zoom_factor_;
// The page this window is viewing.
brightray::InspectableWebContents* inspectable_web_contents_;
base::WeakPtrFactory<NativeWindow> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
};
// This class provides a hook to get a NativeWindow from a WebContents.
class NativeWindowRelay :
public content::WebContentsUserData<NativeWindowRelay> {
public:
explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window)
: key(UserDataKey()), window(window) {}
void* key;
base::WeakPtr<NativeWindow> window;
private:
friend class content::WebContentsUserData<NativeWindow>;
};
} // namespace atom
#endif // ATOM_BROWSER_NATIVE_WINDOW_H_

View file

@ -23,11 +23,11 @@ namespace atom {
class NativeWindowMac : public NativeWindow {
public:
explicit NativeWindowMac(content::WebContents* web_contents,
const mate::Dictionary& options);
virtual ~NativeWindowMac();
NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
~NativeWindowMac() override;
// NativeWindow implementation.
// NativeWindow:
void Close() override;
void CloseImmediately() override;
void Focus(bool focus) override;
@ -91,7 +91,7 @@ class NativeWindowMac : public NativeWindow {
void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) override;
// Implementations of content::WebContentsDelegate.
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent&) override;

View file

@ -68,7 +68,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
}
- (void)windowDidBecomeMain:(NSNotification*)notification {
content::WebContents* web_contents = shell_->GetWebContents();
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return;
@ -82,7 +82,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
}
- (void)windowDidResignMain:(NSNotification*)notification {
content::WebContents* web_contents = shell_->GetWebContents();
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return;
@ -104,7 +104,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
- (void)windowDidMove:(NSNotification*)notification {
// TODO(zcbenz): Remove the alias after figuring out a proper
// way to disptach move.
// way to disptach move.
shell_->NotifyWindowMove();
shell_->NotifyWindowMoved();
}
@ -149,7 +149,7 @@ static const CGFloat kAtomWindowCornerRadius = 4.0;
// When user tries to close the window by clicking the close button, we do
// not close the window immediately, instead we try to close the web page
// fisrt, and when the web page is closed the window will also be closed.
shell_->CloseWebContents();
shell_->RequestToClosePage();
return NO;
}
@ -303,8 +303,9 @@ SkRegion* DraggableRegionsToSkRegion(
} // namespace
NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
const mate::Dictionary& options)
NativeWindowMac::NativeWindowMac(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
is_kiosk_(false),
attention_request_id_(0) {
@ -385,9 +386,7 @@ NativeWindowMac::NativeWindowMac(content::WebContents* web_contents,
}
NativeWindowMac::~NativeWindowMac() {
// Force InspectableWebContents to be destroyed before we destroy window,
// because it may still be observing the window at this time.
DestroyWebContents();
Observe(nullptr);
}
void NativeWindowMac::Close() {
@ -678,10 +677,9 @@ void NativeWindowMac::SetOverlayIcon(const gfx::Image& overlay,
}
void NativeWindowMac::ShowDefinitionForSelection() {
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
if (!web_contents())
return;
content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
auto rwhv = web_contents()->GetRenderWidgetHostView();
if (!rwhv)
return;
rwhv->ShowDefinitionForSelection();
@ -705,10 +703,9 @@ bool NativeWindowMac::IsVisibleOnAllWorkspaces() {
bool NativeWindowMac::IsWithinDraggableRegion(NSPoint point) const {
if (!draggable_region_)
return false;
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
if (!web_contents())
return false;
NSView* webView = web_contents->GetNativeView();
NSView* webView = web_contents()->GetNativeView();
NSInteger webViewHeight = NSHeight([webView bounds]);
// |draggable_region_| is stored in local platform-indepdent coordiate system
// while |point| is in local Cocoa coordinate system. Do the conversion
@ -815,16 +812,15 @@ void NativeWindowMac::UninstallView() {
}
void NativeWindowMac::ClipWebView() {
content::WebContents* web_contents = GetWebContents();
if (!web_contents)
if (!web_contents())
return;
NSView* webView = web_contents->GetNativeView();
NSView* webView = web_contents()->GetNativeView();
webView.layer.masksToBounds = YES;
webView.layer.cornerRadius = kAtomWindowCornerRadius;
}
void NativeWindowMac::InstallDraggableRegionView() {
NSView* webView = GetWebContents()->GetNativeView();
NSView* webView = web_contents()->GetNativeView();
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithShellWindow:this]);
[controlRegion setFrame:NSMakeRect(0, 0,
@ -834,9 +830,10 @@ void NativeWindowMac::InstallDraggableRegionView() {
}
// static
NativeWindow* NativeWindow::Create(content::WebContents* web_contents,
const mate::Dictionary& options) {
return new NativeWindowMac(web_contents, options);
NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) {
return new NativeWindowMac(inspectable_web_contents, options);
}
} // namespace atom

View file

@ -16,7 +16,8 @@
#include "atom/common/draggable_region.h"
#include "atom/common/options_switches.h"
#include "base/strings/utf_string_conversions.h"
#include "browser/inspectable_web_contents_view.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "native_mate/dictionary.h"
#include "ui/aura/window.h"
@ -132,7 +133,7 @@ class NativeWindowClientView : public views::ClientView {
virtual ~NativeWindowClientView() {}
bool CanClose() override {
static_cast<NativeWindowViews*>(contents_view())->CloseWebContents();
static_cast<NativeWindowViews*>(contents_view())->RequestToClosePage();
return false;
}
@ -142,8 +143,9 @@ class NativeWindowClientView : public views::ClientView {
} // namespace
NativeWindowViews::NativeWindowViews(content::WebContents* web_contents,
const mate::Dictionary& options)
NativeWindowViews::NativeWindowViews(
brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options)
: NativeWindow(web_contents, options),
window_(new views::Widget),
web_view_(inspectable_web_contents()->GetView()->GetView()),
@ -726,9 +728,9 @@ void NativeWindowViews::OnWidgetActivationChanged(
else
NotifyWindowBlur();
if (active && GetWebContents() &&
if (active && inspectable_web_contents() &&
!inspectable_web_contents()->IsDevToolsViewShowing())
GetWebContents()->Focus();
web_contents()->Focus();
// Hide menu bar when window is blured.
if (!active && menu_bar_autohide_ && menu_bar_visible_)
@ -870,13 +872,6 @@ void NativeWindowViews::GetDevToolsWindowWMClass(
}
#endif
void NativeWindowViews::ActivateContents(content::WebContents* contents) {
NativeWindow::ActivateContents(contents);
// Hide menu bar when web view is clicked.
if (menu_bar_autohide_ && menu_bar_visible_)
SetMenuBarVisibility(false);
}
void NativeWindowViews::HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) {
@ -973,9 +968,10 @@ ui::WindowShowState NativeWindowViews::GetRestoredState() {
}
// static
NativeWindow* NativeWindow::Create(content::WebContents* web_contents,
const mate::Dictionary& options) {
return new NativeWindowViews(web_contents, options);
NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) {
return new NativeWindowViews(inspectable_web_contents, options);
}
} // namespace atom

View file

@ -28,9 +28,9 @@ class NativeWindowViews : public NativeWindow,
public views::WidgetDelegateView,
public views::WidgetObserver {
public:
explicit NativeWindowViews(content::WebContents* web_contents,
const mate::Dictionary& options);
virtual ~NativeWindowViews();
NativeWindowViews(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
~NativeWindowViews() override;
// NativeWindow:
void Close() override;
@ -120,15 +120,14 @@ class NativeWindowViews : public NativeWindow,
bool ExecuteWindowsCommand(int command_id) override;
#endif
// brightray::InspectableWebContentsDelegate:
// brightray::InspectableWebContentsViewDelegate:
gfx::ImageSkia GetDevToolsWindowIcon() override;
#if defined(USE_X11)
void GetDevToolsWindowWMClass(
std::string* name, std::string* class_name) override;
#endif
// content::WebContentsDelegate:
void ActivateContents(content::WebContents* contents) override;
// NativeWindow:
void HandleKeyboardEvent(
content::WebContents*,
const content::NativeWebKeyboardEvent& event) override;

View file

@ -0,0 +1,175 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/web_view_guest_delegate.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "content/public/browser/guest_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
namespace atom {
namespace {
const int kDefaultWidth = 300;
const int kDefaultHeight = 300;
} // namespace
WebViewGuestDelegate::WebViewGuestDelegate()
: guest_opaque_(true),
guest_host_(nullptr),
auto_size_enabled_(false),
is_full_page_plugin_(false),
api_web_contents_(nullptr) {
}
WebViewGuestDelegate::~WebViewGuestDelegate() {
}
void WebViewGuestDelegate::Initialize(api::WebContents* api_web_contents) {
api_web_contents_ = api_web_contents;
Observe(api_web_contents->GetWebContents());
}
void WebViewGuestDelegate::Destroy() {
// Give the content module an opportunity to perform some cleanup.
guest_host_->WillDestroy();
guest_host_ = nullptr;
}
void WebViewGuestDelegate::SetSize(const SetSizeParams& params) {
bool enable_auto_size =
params.enable_auto_size ? *params.enable_auto_size : auto_size_enabled_;
gfx::Size min_size = params.min_size ? *params.min_size : min_auto_size_;
gfx::Size max_size = params.max_size ? *params.max_size : max_auto_size_;
if (params.normal_size)
normal_size_ = *params.normal_size;
min_auto_size_ = min_size;
min_auto_size_.SetToMin(max_size);
max_auto_size_ = max_size;
max_auto_size_.SetToMax(min_size);
enable_auto_size &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty();
auto rvh = web_contents()->GetRenderViewHost();
if (enable_auto_size) {
// Autosize is being enabled.
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
normal_size_.SetSize(0, 0);
} else {
// Autosize is being disabled.
// Use default width/height if missing from partially defined normal size.
if (normal_size_.width() && !normal_size_.height())
normal_size_.set_height(GetDefaultSize().height());
if (!normal_size_.width() && normal_size_.height())
normal_size_.set_width(GetDefaultSize().width());
gfx::Size new_size;
if (!normal_size_.IsEmpty()) {
new_size = normal_size_;
} else if (!guest_size_.IsEmpty()) {
new_size = guest_size_;
} else {
new_size = GetDefaultSize();
}
if (auto_size_enabled_) {
// Autosize was previously enabled.
rvh->DisableAutoResize(new_size);
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
} else {
// Autosize was already disabled.
guest_host_->SizeContents(new_size);
}
guest_size_ = new_size;
}
auto_size_enabled_ = enable_auto_size;
}
void WebViewGuestDelegate::SetAllowTransparency(bool allow) {
if (guest_opaque_ != allow)
return;
auto render_view_host = web_contents()->GetRenderViewHost();
guest_opaque_ = !allow;
if (!render_view_host->GetView())
return;
if (guest_opaque_) {
render_view_host->GetView()->SetBackgroundColorToDefault();
} else {
render_view_host->GetView()->SetBackgroundColor(SK_ColorTRANSPARENT);
}
}
void WebViewGuestDelegate::HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) {
if (embedder_web_contents_)
embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(source, event);
}
void WebViewGuestDelegate::RenderViewReady() {
// We don't want to accidentally set the opacity of an interstitial page.
// WebContents::GetRenderWidgetHostView will return the RWHV of an
// interstitial page if one is showing at this time. We only want opacity
// to apply to web pages.
auto render_view_host_view = web_contents()->GetRenderViewHost()->GetView();
if (guest_opaque_)
render_view_host_view->SetBackgroundColorToDefault();
else
render_view_host_view->SetBackgroundColor(SK_ColorTRANSPARENT);
}
void WebViewGuestDelegate::DidAttach(int guest_proxy_routing_id) {
api_web_contents_->Emit("did-attach");
}
content::WebContents* WebViewGuestDelegate::GetOwnerWebContents() const {
return embedder_web_contents_;
}
void WebViewGuestDelegate::GuestSizeChanged(const gfx::Size& new_size) {
if (!auto_size_enabled_)
return;
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
guest_size_ = new_size;
}
void WebViewGuestDelegate::SetGuestHost(content::GuestHost* guest_host) {
guest_host_ = guest_host;
}
void WebViewGuestDelegate::WillAttach(
content::WebContents* embedder_web_contents,
int element_instance_id,
bool is_full_page_plugin) {
embedder_web_contents_ = embedder_web_contents;
is_full_page_plugin_ = is_full_page_plugin;
}
void WebViewGuestDelegate::GuestSizeChangedDueToAutoSize(
const gfx::Size& old_size, const gfx::Size& new_size) {
api_web_contents_->Emit("size-changed",
old_size.width(), old_size.height(),
new_size.width(), new_size.height());
}
gfx::Size WebViewGuestDelegate::GetDefaultSize() const {
if (is_full_page_plugin_) {
// Full page plugins default to the size of the owner's viewport.
return embedder_web_contents_->GetRenderWidgetHostView()
->GetVisibleViewportSize();
} else {
return gfx::Size(kDefaultWidth, kDefaultHeight);
}
}
} // namespace atom

View file

@ -0,0 +1,122 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_WEB_VIEW_GUEST_DELEGATE_H_
#define ATOM_BROWSER_WEB_VIEW_GUEST_DELEGATE_H_
#include "content/public/browser/browser_plugin_guest_delegate.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
struct NativeWebKeyboardEvent;
}
namespace atom {
namespace api {
class WebContents;
}
// A struct of parameters for SetSize(). The parameters are all declared as
// scoped pointers since they are all optional. Null pointers indicate that the
// parameter has not been provided, and the last used value should be used. Note
// that when |enable_auto_size| is true, providing |normal_size| is not
// meaningful. This is because the normal size of the guestview is overridden
// whenever autosizing occurs.
struct SetSizeParams {
SetSizeParams() {}
~SetSizeParams() {}
scoped_ptr<bool> enable_auto_size;
scoped_ptr<gfx::Size> min_size;
scoped_ptr<gfx::Size> max_size;
scoped_ptr<gfx::Size> normal_size;
};
class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate,
public content::WebContentsObserver {
public:
WebViewGuestDelegate();
~WebViewGuestDelegate() override;
void Initialize(api::WebContents* api_web_contents);
// Called when the WebContents is going to be destroyed.
void Destroy();
// Used to toggle autosize mode for this GuestView, and set both the automatic
// and normal sizes.
void SetSize(const SetSizeParams& params);
// Sets the transparency of the guest.
void SetAllowTransparency(bool allow);
// Transfer the keyboard event to embedder.
void HandleKeyboardEvent(content::WebContents* source,
const content::NativeWebKeyboardEvent& event);
protected:
// content::WebContentsObserver:
void RenderViewReady() override;
// content::BrowserPluginGuestDelegate:
void DidAttach(int guest_proxy_routing_id) final;
content::WebContents* GetOwnerWebContents() const final;
void GuestSizeChanged(const gfx::Size& new_size) final;
void SetGuestHost(content::GuestHost* guest_host) final;
void WillAttach(content::WebContents* embedder_web_contents,
int element_instance_id,
bool is_full_page_plugin) final;
private:
// This method is invoked when the contents auto-resized to give the container
// an opportunity to match it if it wishes.
//
// This gives the derived class an opportunity to inform its container element
// or perform other actions.
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
const gfx::Size& new_size);
// Returns the default size of the guestview.
gfx::Size GetDefaultSize() const;
// Stores whether the contents of the guest can be transparent.
bool guest_opaque_;
// The WebContents that attaches this guest view.
content::WebContents* embedder_web_contents_;
// The size of the container element.
gfx::Size element_size_;
// The size of the guest content. Note: In autosize mode, the container
// element may not match the size of the guest.
gfx::Size guest_size_;
// A pointer to the guest_host.
content::GuestHost* guest_host_;
// Indicates whether autosize mode is enabled or not.
bool auto_size_enabled_;
// The maximum size constraints of the container element in autosize mode.
gfx::Size max_auto_size_;
// The minimum size constraints of the container element in autosize mode.
gfx::Size min_auto_size_;
// The size that will be used when autosize mode is disabled.
gfx::Size normal_size_;
// Whether the guest view is inside a plugin document.
bool is_full_page_plugin_;
api::WebContents* api_web_contents_;
DISALLOW_COPY_AND_ASSIGN(WebViewGuestDelegate);
};
} // namespace atom
#endif // ATOM_BROWSER_WEB_VIEW_GUEST_DELEGATE_H_

View file

@ -207,6 +207,8 @@
'atom/browser/ui/x/window_state_watcher.h',
'atom/browser/ui/x/x_window_utils.cc',
'atom/browser/ui/x/x_window_utils.h',
'atom/browser/web_view_guest_delegate.cc',
'atom/browser/web_view_guest_delegate.h',
'atom/browser/web_view_manager.cc',
'atom/browser/web_view_manager.h',
'atom/browser/web_dialog_helper.cc',

2
vendor/brightray vendored

@ -1 +1 @@
Subproject commit 20871355cb590e009d7ee394a7d9da0e4666ea0b
Subproject commit b05e019d2f66023fad1ae2f16cc765e3d62ffd5e