#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
#include "common/api/api_messages.h"
#include "common/options_switches.h"
#include "ipc/ipc_message_macros.h"
base::DictionaryValue* options)
: content::WebContentsObserver(web_contents),
inspectable_web_contents_(
- brightray::InspectableWebContents::Create(web_contents)) {
+ brightray::InspectableWebContents::Create(web_contents)),
+ window_going_to_destroy_(false),
+ can_destroy_window_(false) {
web_contents->SetDelegate(this);
windows_.push_back(this);
inspectable_web_contents()->GetView()->CloseDevTools();
}
+void NativeWindow::RequestToDestroyWindow() {
+ if (window_going_to_destroy_)
+ return;
+
+ window_going_to_destroy_ = true;
+
+ content::WebContents* web_contents(GetWebContents());
+
+ web_contents->OnCloseStarted();
+
+ if (web_contents->NeedToFireBeforeUnload())
+ web_contents->GetRenderViewHost()->FirePageBeforeUnload(false);
+ else
+ web_contents->Close();
+}
+
+bool NativeWindow::CanClose() {
+ return !GetWebContents()->NeedToFireBeforeUnload() || can_destroy_window_;
+}
+
content::WebContents* NativeWindow::GetWebContents() const {
return inspectable_web_contents_->GetWebContents();
}
return dialog_manager_.get();
}
+void NativeWindow::BeforeUnloadFired(content::WebContents* source,
+ bool proceed,
+ bool* proceed_to_fire_unload) {
+ *proceed_to_fire_unload = proceed;
+
+ if (proceed && window_going_to_destroy_) {
+ can_destroy_window_ = true;
+ } else {
+ window_going_to_destroy_ = false;
+ can_destroy_window_ = false;
+ }
+}
+
+void NativeWindow::CloseContents(content::WebContents* source) {
+ // When the web contents is gone, close the window immediately, but the
+ // wrapper itself will not get destroyed until you call delete.
+ // In this way, it would be safe to manage windows via smart pointers.
+ Close();
+}
+
bool NativeWindow::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NativeWindow, message)
virtual void FlashFrame(bool flash) = 0;
virtual void SetKiosk(bool kiosk) = 0;
virtual bool IsKiosk() = 0;
+
virtual void ShowDevTools();
virtual void CloseDevTools();
+ // Close the web page in this window and then desctruct.
+ virtual void RequestToDestroyWindow();
+
+ // Used by platform dependent code to determine whether the window can be
+ // closed. A window can only be closed when the beforeunload handler
+ // doesn't prevent it.
+ bool CanClose();
+
content::WebContents* GetWebContents() const;
void AddObserver(NativeWindowObserver* obs) {
content::WebContents* new_contents) OVERRIDE;
virtual content::JavaScriptDialogManager*
GetJavaScriptDialogManager() OVERRIDE;
+ virtual void CloseContents(content::WebContents* source) OVERRIDE;
+ virtual void BeforeUnloadFired(content::WebContents* source,
+ bool proceed,
+ bool* proceed_to_fire_unload) OVERRIDE;
// Implementations of content::WebContentsObserver.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
scoped_ptr<brightray::InspectableWebContents> inspectable_web_contents_;
+ bool window_going_to_destroy_;
+ bool can_destroy_window_;
+
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
};
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
+@interface AtomNSWindowDelegate : NSObject<NSWindowDelegate> {
+ @private
+ atom::NativeWindowMac* shell_;
+}
+- (id)initWithShell:(atom::NativeWindowMac*)shell;
+@end
+
+@implementation AtomNSWindowDelegate
+
+- (id)initWithShell:(atom::NativeWindowMac*)shell {
+ if ((self = [super init]))
+ shell_ = shell;
+ return self;
+}
+
+- (BOOL)windowShouldClose:(id)window {
+ if (!shell_->CanClose()) {
+ shell_->RequestToDestroyWindow();
+ return NO;
+ }
+
+ [self release];
+
+ return YES;
+}
+
+@end
+
@interface AtomNSWindow : AtomEventProcessingWindow {
@private
atom::NativeWindowMac* shell_;
[atom_window setShell:this];
window_ = atom_window;
+ [window() setReleasedWhenClosed:NO];
+ [window() setDelegate:[[AtomNSWindowDelegate alloc] initWithShell:this]];
// Disable fullscreen button when 'fullscreen' is specified to false.
bool fullscreen;
}
NativeWindowMac::~NativeWindowMac() {
- Close();
[window() release];
}