Merge pull request #12140 from electron/native-window-no-web-contents

Refactor NativeWindow (Part 2):  NativeWindow is no longer WebContentsObserver
This commit is contained in:
Cheng Zhao 2018-03-07 10:12:37 +09:00 committed by GitHub
commit ea9d33374f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 301 additions and 360 deletions

View file

@ -13,6 +13,7 @@
#include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_contents_preferences.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/api/api_messages.h" #include "atom/common/api/api_messages.h"
#include "atom/common/color_util.h"
#include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h"
@ -276,7 +277,6 @@ bool BrowserWindow::OnMessageReceived(const IPC::Message& message,
void BrowserWindow::OnCloseContents() { void BrowserWindow::OnCloseContents() {
if (!web_contents()) if (!web_contents())
return; return;
Observe(nullptr);
// Close all child windows before closing current window. // Close all child windows before closing current window.
v8::Locker locker(isolate()); v8::Locker locker(isolate());
@ -296,6 +296,9 @@ void BrowserWindow::OnCloseContents() {
// Do not sent "unresponsive" event after window is closed. // Do not sent "unresponsive" event after window is closed.
window_unresponsive_closure_.Cancel(); window_unresponsive_closure_.Cancel();
// Clear the web_contents() at last.
Observe(nullptr);
} }
void BrowserWindow::OnRendererResponsive() { void BrowserWindow::OnRendererResponsive() {
@ -307,6 +310,10 @@ void BrowserWindow::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close"); *prevent_default = Emit("close");
} }
void BrowserWindow::RequestPreferredWidth(int* width) {
*width = web_contents()->GetPreferredSize().width();
}
void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) { void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
// When user tries to close the window by clicking the close button, we do // 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 // not close the window immediately, instead we try to close the web page
@ -356,10 +363,27 @@ void BrowserWindow::OnWindowEndSession() {
} }
void BrowserWindow::OnWindowBlur() { void BrowserWindow::OnWindowBlur() {
web_contents()->StoreFocus();
#if defined(OS_MACOSX)
auto* rwhv = web_contents()->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(false);
#endif
Emit("blur"); Emit("blur");
} }
void BrowserWindow::OnWindowFocus() { void BrowserWindow::OnWindowFocus() {
web_contents()->RestoreFocus();
#if defined(OS_MACOSX)
auto* rwhv = web_contents()->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(true);
#else
if (!api_web_contents_->IsDevToolsOpened())
web_contents()->Focus();
#endif
Emit("focus"); Emit("focus");
} }
@ -388,6 +412,10 @@ void BrowserWindow::OnWindowRestore() {
} }
void BrowserWindow::OnWindowResize() { void BrowserWindow::OnWindowResize() {
#if defined(OS_MACOSX)
if (!draggable_regions_.empty())
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
Emit("resize"); Emit("resize");
} }
@ -754,7 +782,11 @@ bool BrowserWindow::IsKiosk() {
} }
void BrowserWindow::SetBackgroundColor(const std::string& color_name) { void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
window_->SetBackgroundColor(color_name); SkColor color = ParseHexColor(color_name);
window_->SetBackgroundColor(color);
auto* view = web_contents()->GetRenderWidgetHostView();
if (view)
view->SetBackgroundColor(color);
} }
void BrowserWindow::SetHasShadow(bool has_shadow) { void BrowserWindow::SetHasShadow(bool has_shadow) {
@ -774,15 +806,16 @@ double BrowserWindow::GetOpacity() {
} }
void BrowserWindow::FocusOnWebView() { void BrowserWindow::FocusOnWebView() {
window_->FocusOnWebView(); web_contents()->GetRenderViewHost()->GetWidget()->Focus();
} }
void BrowserWindow::BlurWebView() { void BrowserWindow::BlurWebView() {
window_->BlurWebView(); web_contents()->GetRenderViewHost()->GetWidget()->Blur();
} }
bool BrowserWindow::IsWebViewFocused() { bool BrowserWindow::IsWebViewFocused() {
return window_->IsWebViewFocused(); auto host_view = web_contents()->GetRenderViewHost()->GetWidget()->GetView();
return host_view && host_view->HasFocus();
} }
void BrowserWindow::SetRepresentedFilename(const std::string& filename) { void BrowserWindow::SetRepresentedFilename(const std::string& filename) {
@ -1091,8 +1124,17 @@ void BrowserWindow::AddTabbedWindow(NativeWindow* window,
void BrowserWindow::SetVibrancy(mate::Arguments* args) { void BrowserWindow::SetVibrancy(mate::Arguments* args) {
std::string type; std::string type;
args->GetNext(&type); args->GetNext(&type);
auto* render_view_host = web_contents()->GetRenderViewHost();
if (render_view_host) {
auto* impl = content::RenderWidgetHostImpl::FromID(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (impl)
impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false);
}
window_->SetVibrancy(type); window_->SetVibrancy(type);
} }
@ -1135,10 +1177,19 @@ void BrowserWindow::RemoveFromParentChildWindows() {
parent->child_windows_.Remove(ID()); parent->child_windows_.Remove(ID());
} }
void BrowserWindow::UpdateDraggableRegions( // Convert draggable regions in raw format to SkRegion format.
content::RenderFrameHost* rfh, std::unique_ptr<SkRegion> BrowserWindow::DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions) { const std::vector<DraggableRegion>& regions) {
window_->UpdateDraggableRegions(regions); std::unique_ptr<SkRegion> sk_region(new SkRegion);
for (const DraggableRegion& region : regions) {
sk_region->op(
region.bounds.x(),
region.bounds.y(),
region.bounds.right(),
region.bounds.bottom(),
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
}
return sk_region;
} }
void BrowserWindow::ScheduleUnresponsiveEvent(int ms) { void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {

View file

@ -81,6 +81,7 @@ class BrowserWindow : public mate::TrackableObject<BrowserWindow>,
// NativeWindowObserver: // NativeWindowObserver:
void WillCloseWindow(bool* prevent_default) override; void WillCloseWindow(bool* prevent_default) override;
void RequestPreferredWidth(int* width) override;
void OnCloseButtonClicked(bool* prevent_default) override; void OnCloseButtonClicked(bool* prevent_default) override;
void OnWindowClosed() override; void OnWindowClosed() override;
void OnWindowEndSession() override; void OnWindowEndSession() override;
@ -260,6 +261,10 @@ class BrowserWindow : public mate::TrackableObject<BrowserWindow>,
content::RenderFrameHost* rfh, content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions); const std::vector<DraggableRegion>& regions);
// Convert draggable regions in raw format to SkRegion format.
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions);
// Schedule a notification unresponsive event. // Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms); void ScheduleUnresponsiveEvent(int ms);
@ -271,6 +276,10 @@ class BrowserWindow : public mate::TrackableObject<BrowserWindow>,
MessageCallbackMap messages_callback_map_; MessageCallbackMap messages_callback_map_;
#endif #endif
#if defined(OS_MACOSX)
std::vector<DraggableRegion> draggable_regions_;
#endif
// Closure that would be called when window is unresponsive when closing, // Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive. // it should be cancelled when we can prove that the window is responsive.
base::CancelableClosure window_unresponsive_closure_; base::CancelableClosure window_unresponsive_closure_;

View file

@ -0,0 +1,120 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_browser_window.h"
#import <Cocoa/Cocoa.h>
#include "atom/browser/native_browser_view.h"
#include "atom/common/draggable_region.h"
#include "base/mac/scoped_nsobject.h"
@interface NSView (WebContentsView)
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
@end
@interface ControlRegionView : NSView
@end
@implementation ControlRegionView
- (BOOL)mouseDownCanMoveWindow {
return NO;
}
- (NSView*)hitTest:(NSPoint)aPoint {
return nil;
}
@end
namespace atom {
namespace api {
namespace {
// Return a vector of non-draggable regions that fill a window of size
// |width| by |height|, but leave gaps where the window should be draggable.
std::vector<gfx::Rect> CalculateNonDraggableRegions(
std::unique_ptr<SkRegion> draggable, int width, int height) {
std::vector<gfx::Rect> result;
std::unique_ptr<SkRegion> non_draggable(new SkRegion);
non_draggable->op(0, 0, width, height, SkRegion::kUnion_Op);
non_draggable->op(*draggable, SkRegion::kDifference_Op);
for (SkRegion::Iterator it(*non_draggable); !it.done(); it.next()) {
result.push_back(gfx::SkIRectToRect(it.rect()));
}
return result;
}
} // namespace
void BrowserWindow::UpdateDraggableRegions(
content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions) {
if (window_->has_frame())
return;
// All ControlRegionViews should be added as children of the WebContentsView,
// because WebContentsView will be removed and re-added when entering and
// leaving fullscreen mode.
NSView* webView = web_contents()->GetNativeView();
NSInteger webViewWidth = NSWidth([webView bounds]);
NSInteger webViewHeight = NSHeight([webView bounds]);
if ([webView respondsToSelector:@selector(setMouseDownCanMoveWindow:)]) {
[webView setMouseDownCanMoveWindow:YES];
}
// Remove all ControlRegionViews that are added last time.
// Note that [webView subviews] returns the view's mutable internal array and
// it should be copied to avoid mutating the original array while enumerating
// it.
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
for (NSView* subview in subviews.get())
if ([subview isKindOfClass:[ControlRegionView class]])
[subview removeFromSuperview];
// Draggable regions is implemented by having the whole web view draggable
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
draggable_regions_ = regions;
std::vector<gfx::Rect> system_drag_exclude_areas;
if (regions.empty()) {
system_drag_exclude_areas.push_back(
gfx::Rect(0, 0, webViewWidth, webViewHeight));
} else {
CalculateNonDraggableRegions(
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
}
if (window_->browser_view())
window_->browser_view()->UpdateDraggableRegions(system_drag_exclude_areas);
// Create and add a ControlRegionView for each region that needs to be
// excluded from the dragging.
for (std::vector<gfx::Rect>::const_iterator iter =
system_drag_exclude_areas.begin();
iter != system_drag_exclude_areas.end();
++iter) {
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
[controlRegion setFrame:NSMakeRect(iter->x(),
webViewHeight - iter->bottom(),
iter->width(),
iter->height())];
[webView addSubview:controlRegion];
}
// AppKit will not update its cache of mouseDownCanMoveWindow unless something
// changes. Previously we tried adding an NSView and removing it, but for some
// reason it required reposting the mouse-down event, and didn't always work.
// Calling the below seems to be an effective solution.
[[webView window] setMovableByWindowBackground:NO];
[[webView window] setMovableByWindowBackground:YES];
}
} // namespace api
} // namespace atom

View file

@ -0,0 +1,24 @@
// Copyright (c) 2018 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_browser_window.h"
#include "atom/browser/native_window_views.h"
namespace atom {
namespace api {
void BrowserWindow::UpdateDraggableRegions(
content::RenderFrameHost* rfh,
const std::vector<DraggableRegion>& regions) {
if (window_->has_frame())
return;
static_cast<NativeWindowViews*>(window_.get())->UpdateDraggableRegions(
DraggableRegionsToSkRegion(regions));
}
} // namespace api
} // namespace atom

View file

@ -48,10 +48,7 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
base::Closure callback) { base::Closure callback) {
if (!native_window) if (!native_window)
return; return;
brightray::InspectableWebContents* web_contents = NSWindow* nswindow = native_window->GetNativeWindow();
native_window->inspectable_web_contents();
if (!web_contents)
return;
auto close_callback = base::Bind( auto close_callback = base::Bind(
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback); &MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
@ -59,7 +56,7 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
[[AtomMenuController alloc] initWithModel:model() [[AtomMenuController alloc] initWithModel:model()
useDefaultAccelerator:NO]); useDefaultAccelerator:NO]);
NSMenu* menu = [popup_controllers_[window_id] menu]; NSMenu* menu = [popup_controllers_[window_id] menu];
NSView* view = web_contents->GetView()->GetNativeView(); NSView* view = [nswindow contentView];
// Which menu item to show. // Which menu item to show.
NSMenuItem* item = nil; NSMenuItem* item = nil;
@ -69,7 +66,6 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
// (-1, -1) means showing on mouse location. // (-1, -1) means showing on mouse location.
NSPoint position; NSPoint position;
if (x == -1 || y == -1) { if (x == -1 || y == -1) {
NSWindow* nswindow = native_window->GetNativeWindow();
position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream] position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream]
fromView:nil]; fromView:nil];
} else { } else {

View file

@ -24,19 +24,16 @@ MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
void MenuViews::PopupAt(BrowserWindow* window, void MenuViews::PopupAt(BrowserWindow* window,
int x, int y, int positioning_item, int x, int y, int positioning_item,
const base::Closure& callback) { const base::Closure& callback) {
NativeWindow* native_window = static_cast<NativeWindow*>(window->window()); auto* native_window = static_cast<NativeWindowViews*>(window->window());
if (!native_window) if (!native_window)
return; return;
auto* web_contents = native_window->inspectable_web_contents();
if (!web_contents)
return;
// (-1, -1) means showing on mouse location. // (-1, -1) means showing on mouse location.
gfx::Point location; gfx::Point location;
if (x == -1 || y == -1) { if (x == -1 || y == -1) {
location = display::Screen::GetScreen()->GetCursorScreenPoint(); location = display::Screen::GetScreen()->GetCursorScreenPoint();
} else { } else {
auto* view = web_contents->GetView()->GetWebView(); views::View* view = native_window; // the instance is also its content view
gfx::Point origin = view->bounds().origin(); gfx::Point origin = view->bounds().origin();
location = gfx::Point(origin.x() + x, origin.y() + y); location = gfx::Point(origin.x() + x, origin.y() + y);
} }
@ -53,7 +50,7 @@ void MenuViews::PopupAt(BrowserWindow* window,
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner( menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
model(), flags, close_callback)); model(), flags, close_callback));
menu_runners_[window_id]->RunMenuAt( menu_runners_[window_id]->RunMenuAt(
static_cast<NativeWindowViews*>(window->window())->widget(), native_window->widget(),
NULL, NULL,
gfx::Rect(location, gfx::Size()), gfx::Rect(location, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT, views::MENU_ANCHOR_TOPLEFT,

View file

@ -33,6 +33,7 @@
#include "chrome/browser/speech/tts_message_filter.h" #include "chrome/browser/speech/tts_message_filter.h"
#include "content/public/browser/browser_ppapi_host.h" #include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/resource_dispatcher_host.h"

View file

@ -64,8 +64,10 @@ void AtomJavaScriptDialogManager::RunJavaScriptDialog(
checkbox_string = "Prevent this app from creating additional dialogs"; checkbox_string = "Prevent this app from creating additional dialogs";
} }
} }
auto* relay = NativeWindowRelay::FromWebContents(web_contents);
atom::ShowMessageBox( atom::ShowMessageBox(
NativeWindow::FromWebContents(web_contents), relay ? relay->window.get() : nullptr,
atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE, buttons, -1, 0, atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE, buttons, -1, 0,
atom::MessageBoxOptions::MESSAGE_BOX_NONE, "", atom::MessageBoxOptions::MESSAGE_BOX_NONE, "",
base::UTF16ToUTF8(message_text), "", checkbox_string, base::UTF16ToUTF8(message_text), "", checkbox_string,

View file

@ -17,6 +17,7 @@
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "brightray/common/application_info.h" #include "brightray/common/application_info.h"
#include "net/base/mac/url_conversions.h" #include "net/base/mac/url_conversions.h"
#include "ui/gfx/image/image.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace atom { namespace atom {

View file

@ -8,36 +8,12 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/draggable_region.h" #include "atom/common/color_util.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/options_switches.h" #include "atom/common/options_switches.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_message_macros.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h"
DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay); DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
@ -47,8 +23,7 @@ NativeWindow::NativeWindow(
brightray::InspectableWebContents* inspectable_web_contents, brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options, const mate::Dictionary& options,
NativeWindow* parent) NativeWindow* parent)
: content::WebContentsObserver(inspectable_web_contents->GetWebContents()), : has_frame_(true),
has_frame_(true),
transparent_(false), transparent_(false),
enable_larger_than_screen_(false), enable_larger_than_screen_(false),
is_closed_(false), is_closed_(false),
@ -58,7 +33,7 @@ NativeWindow::NativeWindow(
parent_(parent), parent_(parent),
is_modal_(false), is_modal_(false),
is_osr_dummy_(false), is_osr_dummy_(false),
inspectable_web_contents_(inspectable_web_contents), browser_view_(nullptr),
weak_factory_(this) { weak_factory_(this) {
options.Get(options::kFrame, &has_frame_); options.Get(options::kFrame, &has_frame_);
options.Get(options::kTransparent, &transparent_); options.Get(options::kTransparent, &transparent_);
@ -76,16 +51,6 @@ NativeWindow::~NativeWindow() {
NotifyWindowClosed(); NotifyWindowClosed();
} }
// static
NativeWindow* NativeWindow::FromWebContents(
content::WebContents* web_contents) {
for (const auto& window : WindowList::GetWindows()) {
if (window->web_contents() == web_contents)
return window;
}
return nullptr;
}
void NativeWindow::InitFromOptions(const mate::Dictionary& options) { void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
// Setup window from options. // Setup window from options.
int x = -1, y = -1; int x = -1, y = -1;
@ -172,10 +137,10 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
} }
std::string color; std::string color;
if (options.Get(options::kBackgroundColor, &color)) { if (options.Get(options::kBackgroundColor, &color)) {
SetBackgroundColor(color); SetBackgroundColor(ParseHexColor(color));
} else if (!transparent()) { } else if (!transparent()) {
// For normal window, use white as default background. // For normal window, use white as default background.
SetBackgroundColor("#FFFF"); SetBackgroundColor(SK_ColorWHITE);
} }
std::string title(Browser::Get()->GetName()); std::string title(Browser::Get()->GetName());
options.Get(options::kTitle, &title); options.Get(options::kTitle, &title);
@ -354,19 +319,6 @@ void NativeWindow::SetEscapeTouchBarItem(
const mate::PersistentDictionary& item) { const mate::PersistentDictionary& item) {
} }
void NativeWindow::FocusOnWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
}
void NativeWindow::BlurWebView() {
web_contents()->GetRenderViewHost()->GetWidget()->Blur();
}
bool NativeWindow::IsWebViewFocused() {
auto host_view = web_contents()->GetRenderViewHost()->GetWidget()->GetView();
return host_view && host_view->HasFocus();
}
void NativeWindow::SetAutoHideMenuBar(bool auto_hide) { void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
} }
@ -402,6 +354,11 @@ void NativeWindow::PreviewFile(const std::string& path,
void NativeWindow::CloseFilePreview() { void NativeWindow::CloseFilePreview() {
} }
void NativeWindow::NotifyWindowRequestPreferredWith(int* width) {
for (NativeWindowObserver& observer : observers_)
observer.RequestPreferredWidth(width);
}
void NativeWindow::NotifyWindowCloseButtonClicked() { void NativeWindow::NotifyWindowCloseButtonClicked() {
// First ask the observers whether we want to close. // First ask the observers whether we want to close.
bool prevent_default = false; bool prevent_default = false;
@ -563,18 +520,4 @@ void NativeWindow::NotifyWindowMessage(
} }
#endif #endif
std::unique_ptr<SkRegion> NativeWindow::DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions) {
std::unique_ptr<SkRegion> sk_region(new SkRegion);
for (const DraggableRegion& region : regions) {
sk_region->op(
region.bounds.x(),
region.bounds.y(),
region.bounds.right(),
region.bounds.bottom(),
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
}
return sk_region;
}
} // namespace atom } // namespace atom

View file

@ -11,20 +11,13 @@
#include <vector> #include <vector>
#include "atom/browser/native_window_observer.h" #include "atom/browser/native_window_observer.h"
#include "atom/browser/ui/accelerator_util.h"
#include "atom/browser/ui/atom_menu_model.h" #include "atom/browser/ui/atom_menu_model.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/supports_user_data.h" #include "base/supports_user_data.h"
#include "content/public/browser/readback_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h" #include "content/public/browser/web_contents_user_data.h"
#include "extensions/browser/app_window/size_constraints.h" #include "extensions/browser/app_window/size_constraints.h"
#include "native_mate/persistent_dictionary.h" #include "native_mate/persistent_dictionary.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
class SkRegion; class SkRegion;
@ -37,8 +30,10 @@ struct NativeWebKeyboardEvent;
} }
namespace gfx { namespace gfx {
class Image;
class Point; class Point;
class Rect; class Rect;
class RectF;
class Size; class Size;
} }
@ -52,8 +47,7 @@ class NativeBrowserView;
struct DraggableRegion; struct DraggableRegion;
class NativeWindow : public base::SupportsUserData, class NativeWindow : public base::SupportsUserData {
public content::WebContentsObserver {
public: public:
~NativeWindow() override; ~NativeWindow() override;
@ -64,9 +58,6 @@ class NativeWindow : public base::SupportsUserData,
const mate::Dictionary& options, const mate::Dictionary& options,
NativeWindow* parent = nullptr); NativeWindow* parent = nullptr);
// Find a window from its WebContents
static NativeWindow* FromWebContents(content::WebContents* web_contents);
void InitFromOptions(const mate::Dictionary& options); void InitFromOptions(const mate::Dictionary& options);
virtual void Close() = 0; virtual void Close() = 0;
@ -138,7 +129,7 @@ class NativeWindow : public base::SupportsUserData,
virtual bool IsSimpleFullScreen() = 0; virtual bool IsSimpleFullScreen() = 0;
virtual void SetKiosk(bool kiosk) = 0; virtual void SetKiosk(bool kiosk) = 0;
virtual bool IsKiosk() = 0; virtual bool IsKiosk() = 0;
virtual void SetBackgroundColor(const std::string& color_name) = 0; virtual void SetBackgroundColor(SkColor color) = 0;
virtual void SetHasShadow(bool has_shadow) = 0; virtual void SetHasShadow(bool has_shadow) = 0;
virtual bool HasShadow() = 0; virtual bool HasShadow() = 0;
virtual void SetOpacity(const double opacity) = 0; virtual void SetOpacity(const double opacity) = 0;
@ -194,11 +185,6 @@ class NativeWindow : public base::SupportsUserData,
virtual void ToggleTabBar(); virtual void ToggleTabBar();
virtual bool AddTabbedWindow(NativeWindow* window); virtual bool AddTabbedWindow(NativeWindow* window);
// Webview APIs.
virtual void FocusOnWebView();
virtual void BlurWebView();
virtual bool IsWebViewFocused();
// Toggle the menu bar. // Toggle the menu bar.
virtual void SetAutoHideMenuBar(bool auto_hide); virtual void SetAutoHideMenuBar(bool auto_hide);
virtual bool IsMenuBarAutoHide(); virtual bool IsMenuBarAutoHide();
@ -221,10 +207,6 @@ class NativeWindow : public base::SupportsUserData,
virtual gfx::Rect WindowBoundsToContentBounds( virtual gfx::Rect WindowBoundsToContentBounds(
const gfx::Rect& bounds) const = 0; const gfx::Rect& bounds) const = 0;
// Called when the window needs to update its draggable region.
virtual void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) = 0;
base::WeakPtr<NativeWindow> GetWeakPtr() { base::WeakPtr<NativeWindow> GetWeakPtr() {
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
} }
@ -243,6 +225,7 @@ class NativeWindow : public base::SupportsUserData,
// Public API used by platform-dependent delegates and observers to send UI // Public API used by platform-dependent delegates and observers to send UI
// related notifications. // related notifications.
void NotifyWindowRequestPreferredWith(int* width);
void NotifyWindowCloseButtonClicked(); void NotifyWindowCloseButtonClicked();
void NotifyWindowClosed(); void NotifyWindowClosed();
void NotifyWindowEndSession(); void NotifyWindowEndSession();
@ -282,10 +265,6 @@ class NativeWindow : public base::SupportsUserData,
observers_.RemoveObserver(obs); observers_.RemoveObserver(obs);
} }
brightray::InspectableWebContents* inspectable_web_contents() const {
return inspectable_web_contents_;
}
bool has_frame() const { return has_frame_; } bool has_frame() const { return has_frame_; }
void set_has_frame(bool has_frame) { has_frame_ = has_frame; } void set_has_frame(bool has_frame) { has_frame_ = has_frame; }
@ -295,6 +274,7 @@ class NativeWindow : public base::SupportsUserData,
void set_is_offscreen_dummy(bool is_dummy) { is_osr_dummy_ = is_dummy; } void set_is_offscreen_dummy(bool is_dummy) { is_osr_dummy_ = is_dummy; }
bool is_offscreen_dummy() const { return is_osr_dummy_; } bool is_offscreen_dummy() const { return is_osr_dummy_; }
NativeBrowserView* browser_view() const { return browser_view_; }
NativeWindow* parent() const { return parent_; } NativeWindow* parent() const { return parent_; }
bool is_modal() const { return is_modal_; } bool is_modal() const { return is_modal_; }
@ -303,10 +283,9 @@ class NativeWindow : public base::SupportsUserData,
const mate::Dictionary& options, const mate::Dictionary& options,
NativeWindow* parent); NativeWindow* parent);
// Convert draggable regions in raw format to SkRegion format. Caller is void set_browser_view(NativeBrowserView* browser_view) {
// responsible for deleting the returned SkRegion instance. browser_view_ = browser_view;
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion( }
const std::vector<DraggableRegion>& regions);
private: private:
// Whether window has standard frame. // Whether window has standard frame.
@ -343,8 +322,8 @@ class NativeWindow : public base::SupportsUserData,
// Is this a dummy window for an offscreen WebContents. // Is this a dummy window for an offscreen WebContents.
bool is_osr_dummy_; bool is_osr_dummy_;
// The page this window is viewing. // The browser view layer.
brightray::InspectableWebContents* inspectable_web_contents_; NativeBrowserView* browser_view_;
// Observers of this window. // Observers of this window.
base::ObserverList<NativeWindowObserver> observers_; base::ObserverList<NativeWindowObserver> observers_;

View file

@ -79,7 +79,7 @@ class NativeWindowMac : public NativeWindow {
bool IsSimpleFullScreen() override; bool IsSimpleFullScreen() override;
void SetKiosk(bool kiosk) override; void SetKiosk(bool kiosk) override;
bool IsKiosk() override; bool IsKiosk() override;
void SetBackgroundColor(const std::string& color_name) override; void SetBackgroundColor(SkColor color) override;
void SetHasShadow(bool has_shadow) override; void SetHasShadow(bool has_shadow) override;
bool HasShadow() override; bool HasShadow() override;
void SetOpacity(const double opacity) override; void SetOpacity(const double opacity) override;
@ -119,8 +119,6 @@ class NativeWindowMac : public NativeWindow {
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const; gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const;
gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const; gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const;
void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) override;
// Set the attribute of NSWindow while work around a bug of zoom button. // Set the attribute of NSWindow while work around a bug of zoom button.
void SetStyleMask(bool on, NSUInteger flag); void SetStyleMask(bool on, NSUInteger flag);
@ -137,24 +135,12 @@ class NativeWindowMac : public NativeWindow {
bool zoom_to_page_width() const { return zoom_to_page_width_; } bool zoom_to_page_width() const { return zoom_to_page_width_; }
bool fullscreen_window_title() const { return fullscreen_window_title_; } bool fullscreen_window_title() const { return fullscreen_window_title_; }
bool simple_fullscreen() const { return always_simple_fullscreen_; } bool simple_fullscreen() const { return always_simple_fullscreen_; }
const std::vector<DraggableRegion>& draggable_regions() const {
return draggable_regions_;
}
protected:
// Return a vector of non-draggable regions that fill a window of size
// |width| by |height|, but leave gaps where the window should be draggable.
std::vector<gfx::Rect> CalculateNonDraggableRegions(
const std::vector<DraggableRegion>& regions, int width, int height);
private: private:
void InternalSetParentWindow(NativeWindow* parent, bool attach); void InternalSetParentWindow(NativeWindow* parent, bool attach);
void ShowWindowButton(NSWindowButton button); void ShowWindowButton(NSWindowButton button);
void InstallView(); void InstallView(NSView* view);
void UninstallView();
void SetRenderWidgetHostOpaque(bool opaque);
base::scoped_nsobject<AtomNSWindow> window_; base::scoped_nsobject<AtomNSWindow> window_;
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_; base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
@ -165,10 +151,6 @@ class NativeWindowMac : public NativeWindow {
// The view that will fill the whole frameless window. // The view that will fill the whole frameless window.
base::scoped_nsobject<FullSizeContentView> content_view_; base::scoped_nsobject<FullSizeContentView> content_view_;
NativeBrowserView* browser_view_;
std::vector<DraggableRegion> draggable_regions_;
bool is_kiosk_; bool is_kiosk_;
bool was_fullscreen_; bool was_fullscreen_;

View file

@ -12,8 +12,6 @@
#include "atom/browser/native_browser_view_mac.h" #include "atom/browser/native_browser_view_mac.h"
#include "atom/browser/ui/cocoa/atom_touch_bar.h" #include "atom/browser/ui/cocoa/atom_touch_bar.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/color_util.h"
#include "atom/common/draggable_region.h"
#include "atom/common/options_switches.h" #include "atom/common/options_switches.h"
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_cftyperef.h"
@ -21,15 +19,9 @@
#include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h" #include "brightray/browser/inspectable_web_contents_view.h"
#include "brightray/browser/mac/event_dispatching_window.h" #include "brightray/browser/mac/event_dispatching_window.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_accessibility_state.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/web_contents.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "skia/ext/skia_utils_mac.h" #include "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/gfx/skia_util.h" #include "ui/gfx/skia_util.h"
namespace { namespace {
@ -218,16 +210,14 @@ bool ScopedDisableResize::disable_resize_ = false;
if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask)
return frame; return frame;
content::WebContents* web_contents = shell_->web_contents(); // Get preferred width from observers. Usually the page width.
if (!web_contents) int preferred_width = 0;
return frame; shell_->NotifyWindowRequestPreferredWith(&preferred_width);
CGFloat page_width = static_cast<CGFloat>(
web_contents->GetPreferredSize().width());
NSRect window_frame = [window frame];
// Never shrink from the current size on zoom. // Never shrink from the current size on zoom.
CGFloat zoomed_width = std::max(page_width, NSWidth(window_frame)); NSRect window_frame = [window frame];
CGFloat zoomed_width = std::max(static_cast<CGFloat>(preferred_width),
NSWidth(window_frame));
// |frame| determines our maximum extents. We need to set the origin of the // |frame| determines our maximum extents. We need to set the origin of the
// frame -- and only move it left if necessary. // frame -- and only move it left if necessary.
@ -243,30 +233,10 @@ bool ScopedDisableResize::disable_resize_ = false;
} }
- (void)windowDidBecomeMain:(NSNotification*)notification { - (void)windowDidBecomeMain:(NSNotification*)notification {
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return;
web_contents->RestoreFocus();
content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(true);
shell_->NotifyWindowFocus(); shell_->NotifyWindowFocus();
} }
- (void)windowDidResignMain:(NSNotification*)notification { - (void)windowDidResignMain:(NSNotification*)notification {
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return;
web_contents->StoreFocus();
content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(false);
shell_->NotifyWindowBlur(); shell_->NotifyWindowBlur();
} }
@ -296,7 +266,6 @@ bool ScopedDisableResize::disable_resize_ = false;
} }
- (void)windowDidResize:(NSNotification*)notification { - (void)windowDidResize:(NSNotification*)notification {
shell_->UpdateDraggableRegions(shell_->draggable_regions());
shell_->NotifyWindowResize(); shell_->NotifyWindowResize();
} }
@ -747,25 +716,6 @@ enum {
@end @end
@interface ControlRegionView : NSView
@end
@implementation ControlRegionView
- (BOOL)mouseDownCanMoveWindow {
return NO;
}
- (NSView*)hitTest:(NSPoint)aPoint {
return nil;
}
@end
@interface NSView (WebContentsView)
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
@end
@interface AtomProgressBar : NSProgressIndicator @interface AtomProgressBar : NSProgressIndicator
@end @end
@ -830,7 +780,6 @@ NativeWindowMac::NativeWindowMac(
const mate::Dictionary& options, const mate::Dictionary& options,
NativeWindow* parent) NativeWindow* parent)
: NativeWindow(web_contents, options, parent), : NativeWindow(web_contents, options, parent),
browser_view_(nullptr),
is_kiosk_(false), is_kiosk_(false),
was_fullscreen_(false), was_fullscreen_(false),
zoom_to_page_width_(false), zoom_to_page_width_(false),
@ -1002,7 +951,7 @@ NativeWindowMac::NativeWindowMac(
options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor); options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor);
[window_ setDisableAutoHideCursor:disableAutoHideCursor]; [window_ setDisableAutoHideCursor:disableAutoHideCursor];
NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); NSView* view = web_contents->GetView()->GetNativeView();
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
// Use an NSEvent monitor to listen for the wheel event. // Use an NSEvent monitor to listen for the wheel event.
@ -1013,9 +962,6 @@ NativeWindowMac::NativeWindowMac(
if ([[event window] windowNumber] != [window_ windowNumber]) if ([[event window] windowNumber] != [window_ windowNumber])
return event; return event;
if (!web_contents)
return event;
if (!began && (([event phase] == NSEventPhaseMayBegin) || if (!began && (([event phase] == NSEventPhaseMayBegin) ||
([event phase] == NSEventPhaseBegan))) { ([event phase] == NSEventPhaseBegan))) {
this->NotifyWindowScrollTouchBegin(); this->NotifyWindowScrollTouchBegin();
@ -1028,7 +974,7 @@ NativeWindowMac::NativeWindowMac(
return event; return event;
}]; }];
InstallView(); InstallView(web_contents->GetView()->GetNativeView());
std::string type; std::string type;
if (options.Get(options::kVibrancyType, &type)) { if (options.Get(options::kVibrancyType, &type)) {
@ -1042,7 +988,6 @@ NativeWindowMac::NativeWindowMac(
NativeWindowMac::~NativeWindowMac() { NativeWindowMac::~NativeWindowMac() {
[NSEvent removeMonitor:wheel_event_monitor_]; [NSEvent removeMonitor:wheel_event_monitor_];
Observe(nullptr);
} }
void NativeWindowMac::Close() { void NativeWindowMac::Close() {
@ -1498,15 +1443,10 @@ bool NativeWindowMac::IsKiosk() {
return is_kiosk_; return is_kiosk_;
} }
void NativeWindowMac::SetBackgroundColor(const std::string& color_name) { void NativeWindowMac::SetBackgroundColor(SkColor color) {
SkColor color = ParseHexColor(color_name);
base::ScopedCFTypeRef<CGColorRef> cgcolor( base::ScopedCFTypeRef<CGColorRef> cgcolor(
skia::CGColorCreateFromSkColor(color)); skia::CGColorCreateFromSkColor(color));
[[[window_ contentView] layer] setBackgroundColor:cgcolor]; [[[window_ contentView] layer] setBackgroundColor:cgcolor];
const auto view = web_contents()->GetRenderWidgetHostView();
if (view)
view->SetBackgroundColor(color);
} }
void NativeWindowMac::SetHasShadow(bool has_shadow) { void NativeWindowMac::SetHasShadow(bool has_shadow) {
@ -1550,20 +1490,19 @@ void NativeWindowMac::SetContentProtection(bool enable) {
: NSWindowSharingReadOnly]; : NSWindowSharingReadOnly];
} }
void NativeWindowMac::SetBrowserView(NativeBrowserView* browser_view) { void NativeWindowMac::SetBrowserView(NativeBrowserView* view) {
if (browser_view_) { if (browser_view()) {
[browser_view_->GetInspectableWebContentsView()->GetNativeView() [browser_view()->GetInspectableWebContentsView()->GetNativeView()
removeFromSuperview]; removeFromSuperview];
browser_view_ = nullptr; set_browser_view(nullptr);
} }
if (!browser_view) { if (!view) {
return; return;
} }
browser_view_ = browser_view; set_browser_view(view);
auto* native_view = auto* native_view = view->GetInspectableWebContentsView()->GetNativeView();
browser_view->GetInspectableWebContentsView()->GetNativeView();
[[window_ contentView] addSubview:native_view [[window_ contentView] addSubview:native_view
positioned:NSWindowAbove positioned:NSWindowAbove
relativeTo:nil]; relativeTo:nil];
@ -1575,7 +1514,7 @@ void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
} }
gfx::NativeView NativeWindowMac::GetNativeView() const { gfx::NativeView NativeWindowMac::GetNativeView() const {
return inspectable_web_contents()->GetView()->GetNativeView(); return [window_ contentView];
} }
gfx::NativeWindow NativeWindowMac::GetNativeWindow() const { gfx::NativeWindow NativeWindowMac::GetNativeWindow() const {
@ -1583,7 +1522,7 @@ gfx::NativeWindow NativeWindowMac::GetNativeWindow() const {
} }
gfx::AcceleratedWidget NativeWindowMac::GetAcceleratedWidget() const { gfx::AcceleratedWidget NativeWindowMac::GetAcceleratedWidget() const {
return inspectable_web_contents()->GetView()->GetNativeView(); return [window_ contentView];
} }
void NativeWindowMac::SetProgressBar(double progress, const NativeWindow::ProgressState state) { void NativeWindowMac::SetProgressBar(double progress, const NativeWindow::ProgressState state) {
@ -1681,20 +1620,6 @@ bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
return true; return true;
} }
void NativeWindowMac::SetRenderWidgetHostOpaque(bool opaque) {
if (!web_contents()) return;
auto render_view_host = web_contents()->GetRenderViewHost();
if (!render_view_host) return;
content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (!impl) return;
impl->SetBackgroundOpaque(opaque);
}
void NativeWindowMac::SetVibrancy(const std::string& type) { void NativeWindowMac::SetVibrancy(const std::string& type) {
if (!base::mac::IsAtLeastOS10_10()) return; if (!base::mac::IsAtLeastOS10_10()) return;
@ -1705,7 +1630,6 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
[window_ setBackgroundColor:background_color_before_vibrancy_]; [window_ setBackgroundColor:background_color_before_vibrancy_];
[window_ setTitlebarAppearsTransparent:transparency_before_vibrancy_]; [window_ setTitlebarAppearsTransparent:transparency_before_vibrancy_];
} }
SetRenderWidgetHostOpaque(!transparent());
if (vibrant_view == nil) return; if (vibrant_view == nil) return;
[vibrant_view removeFromSuperview]; [vibrant_view removeFromSuperview];
@ -1714,7 +1638,6 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
return; return;
} }
SetRenderWidgetHostOpaque(false);
background_color_before_vibrancy_.reset([window_ backgroundColor]); background_color_before_vibrancy_.reset([window_ backgroundColor]);
transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent]; transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent];
@ -1813,80 +1736,6 @@ gfx::Rect NativeWindowMac::WindowBoundsToContentBounds(
} }
} }
void NativeWindowMac::UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) {
if (has_frame())
return;
// All ControlRegionViews should be added as children of the WebContentsView,
// because WebContentsView will be removed and re-added when entering and
// leaving fullscreen mode.
NSView* webView = web_contents()->GetNativeView();
NSInteger webViewWidth = NSWidth([webView bounds]);
NSInteger webViewHeight = NSHeight([webView bounds]);
if ([webView respondsToSelector:@selector(setMouseDownCanMoveWindow:)]) {
[webView setMouseDownCanMoveWindow:YES];
}
// Remove all ControlRegionViews that are added last time.
// Note that [webView subviews] returns the view's mutable internal array and
// it should be copied to avoid mutating the original array while enumerating
// it.
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
for (NSView* subview in subviews.get())
if ([subview isKindOfClass:[ControlRegionView class]])
[subview removeFromSuperview];
// Draggable regions is implemented by having the whole web view draggable
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
draggable_regions_ = regions;
std::vector<gfx::Rect> system_drag_exclude_areas =
CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight);
if (browser_view_)
browser_view_->UpdateDraggableRegions(system_drag_exclude_areas);
// Create and add a ControlRegionView for each region that needs to be
// excluded from the dragging.
for (std::vector<gfx::Rect>::const_iterator iter =
system_drag_exclude_areas.begin();
iter != system_drag_exclude_areas.end();
++iter) {
base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
[controlRegion setFrame:NSMakeRect(iter->x(),
webViewHeight - iter->bottom(),
iter->width(),
iter->height())];
[webView addSubview:controlRegion];
}
// AppKit will not update its cache of mouseDownCanMoveWindow unless something
// changes. Previously we tried adding an NSView and removing it, but for some
// reason it required reposting the mouse-down event, and didn't always work.
// Calling the below seems to be an effective solution.
[window_ setMovableByWindowBackground:NO];
[window_ setMovableByWindowBackground:YES];
}
std::vector<gfx::Rect> NativeWindowMac::CalculateNonDraggableRegions(
const std::vector<DraggableRegion>& regions, int width, int height) {
std::vector<gfx::Rect> result;
if (regions.empty()) {
result.push_back(gfx::Rect(0, 0, width, height));
} else {
std::unique_ptr<SkRegion> draggable(DraggableRegionsToSkRegion(regions));
std::unique_ptr<SkRegion> non_draggable(new SkRegion);
non_draggable->op(0, 0, width, height, SkRegion::kUnion_Op);
non_draggable->op(*draggable, SkRegion::kDifference_Op);
for (SkRegion::Iterator it(*non_draggable); !it.done(); it.next()) {
result.push_back(gfx::SkIRectToRect(it.rect()));
}
}
return result;
}
void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent, bool attach) { void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent, bool attach) {
if (is_modal()) if (is_modal())
return; return;
@ -1912,14 +1761,13 @@ void NativeWindowMac::ShowWindowButton(NSWindowButton button) {
[view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil]; [view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil];
} }
void NativeWindowMac::InstallView() { void NativeWindowMac::InstallView(NSView* view) {
// Make sure the bottom corner is rounded for non-modal windows: http://crbug.com/396264. // Make sure the bottom corner is rounded for non-modal windows: http://crbug.com/396264.
// But do not enable it on OS X 10.9 for transparent window, otherwise a // But do not enable it on OS X 10.9 for transparent window, otherwise a
// semi-transparent frame would show. // semi-transparent frame would show.
if (!(transparent() && base::mac::IsOS10_9()) && !is_modal()) if (!(transparent() && base::mac::IsOS10_9()) && !is_modal())
[[window_ contentView] setWantsLayer:YES]; [[window_ contentView] setWantsLayer:YES];
NSView* view = inspectable_web_contents()->GetView()->GetNativeView();
if (has_frame()) { if (has_frame()) {
[view setFrame:[[window_ contentView] bounds]]; [view setFrame:[[window_ contentView] bounds]];
[[window_ contentView] addSubview:view]; [[window_ contentView] addSubview:view];
@ -1967,11 +1815,6 @@ void NativeWindowMac::InstallView() {
} }
} }
void NativeWindowMac::UninstallView() {
NSView* view = inspectable_web_contents()->GetView()->GetNativeView();
[view removeFromSuperview];
}
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) { void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
// Changing the styleMask of a frameless windows causes it to change size so // Changing the styleMask of a frameless windows causes it to change size so
// we explicitly disable resizing while setting it. // we explicitly disable resizing while setting it.

View file

@ -34,6 +34,9 @@ class NativeWindowObserver {
// Called when the window is gonna closed. // Called when the window is gonna closed.
virtual void WillCloseWindow(bool* prevent_default) {} virtual void WillCloseWindow(bool* prevent_default) {}
// Called when the window wants to know the preferred width.
virtual void RequestPreferredWidth(int* width) {}
// Called when closed button is clicked. // Called when closed button is clicked.
virtual void OnCloseButtonClicked(bool* prevent_default) {} virtual void OnCloseButtonClicked(bool* prevent_default) {}

View file

@ -16,7 +16,6 @@
#include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_view_manager.h" #include "atom/browser/web_view_manager.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/color_util.h"
#include "atom/common/draggable_region.h" #include "atom/common/draggable_region.h"
#include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/options_switches.h" #include "atom/common/options_switches.h"
@ -141,8 +140,8 @@ NativeWindowViews::NativeWindowViews(
NativeWindow* parent) NativeWindow* parent)
: NativeWindow(web_contents, options, parent), : NativeWindow(web_contents, options, parent),
window_(new views::Widget), window_(new views::Widget),
web_view_(inspectable_web_contents()->GetView()->GetView()), web_view_(web_contents->GetView()->GetView()),
browser_view_(nullptr), focused_view_(web_contents->GetView()->GetWebView()),
menu_bar_autohide_(false), menu_bar_autohide_(false),
menu_bar_visible_(false), menu_bar_visible_(false),
menu_bar_alt_pressed_(false), menu_bar_alt_pressed_(false),
@ -792,9 +791,8 @@ bool NativeWindowViews::IsKiosk() {
return IsFullscreen(); return IsFullscreen();
} }
void NativeWindowViews::SetBackgroundColor(const std::string& color_name) { void NativeWindowViews::SetBackgroundColor(SkColor background_color) {
// web views' background color. // web views' background color.
SkColor background_color = ParseHexColor(color_name);
SetBackground(views::CreateSolidBackground(background_color)); SetBackground(views::CreateSolidBackground(background_color));
#if defined(OS_WIN) #if defined(OS_WIN)
@ -950,22 +948,21 @@ void NativeWindowViews::SetMenu(AtomMenuModel* menu_model) {
Layout(); Layout();
} }
void NativeWindowViews::SetBrowserView(NativeBrowserView* browser_view) { void NativeWindowViews::SetBrowserView(NativeBrowserView* view) {
if (browser_view_) { if (browser_view()) {
web_view_->RemoveChildView( web_view_->RemoveChildView(
browser_view_->GetInspectableWebContentsView()->GetView()); browser_view()->GetInspectableWebContentsView()->GetView());
browser_view_ = nullptr; set_browser_view(nullptr);
} }
if (!browser_view) { if (!view) {
return; return;
} }
// Add as child of the main web view to avoid (0, 0) origin from overlapping // Add as child of the main web view to avoid (0, 0) origin from overlapping
// with menu bar. // with menu bar.
browser_view_ = browser_view; set_browser_view(view);
web_view_->AddChildView( web_view_->AddChildView(view->GetInspectableWebContentsView()->GetView());
browser_view->GetInspectableWebContentsView()->GetView());
} }
void NativeWindowViews::SetParentWindow(NativeWindow* parent) { void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
@ -1123,11 +1120,8 @@ gfx::Rect NativeWindowViews::WindowBoundsToContentBounds(
} }
void NativeWindowViews::UpdateDraggableRegions( void NativeWindowViews::UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) { std::unique_ptr<SkRegion> region) {
// Draggable region is not supported for non-frameless window. draggable_region_ = std::move(region);
if (has_frame())
return;
draggable_region_ = DraggableRegionsToSkRegion(regions);
} }
#if defined(OS_WIN) #if defined(OS_WIN)
@ -1190,10 +1184,6 @@ void NativeWindowViews::OnWidgetActivationChanged(
&NativeWindow::NotifyWindowBlur, &NativeWindow::NotifyWindowBlur,
GetWeakPtr())); GetWeakPtr()));
if (active && inspectable_web_contents() &&
!inspectable_web_contents()->IsDevToolsViewShowing())
web_contents()->Focus();
// Hide menu bar when window is blured. // Hide menu bar when window is blured.
if (!active && menu_bar_autohide_ && menu_bar_visible_) if (!active && menu_bar_autohide_ && menu_bar_visible_)
SetMenuBarVisibility(false); SetMenuBarVisibility(false);
@ -1208,9 +1198,9 @@ void NativeWindowViews::OnWidgetBoundsChanged(
// handle minimized windows on Windows. // handle minimized windows on Windows.
const auto new_bounds = GetBounds(); const auto new_bounds = GetBounds();
if (widget_size_ != new_bounds.size()) { if (widget_size_ != new_bounds.size()) {
if (browser_view_) { if (browser_view()) {
const auto flags = static_cast<NativeBrowserViewViews*>(browser_view_) const auto flags = static_cast<NativeBrowserViewViews*>(browser_view())->
->GetAutoResizeFlags(); GetAutoResizeFlags();
int width_delta = 0; int width_delta = 0;
int height_delta = 0; int height_delta = 0;
if (flags & kAutoResizeWidth) { if (flags & kAutoResizeWidth) {
@ -1220,7 +1210,7 @@ void NativeWindowViews::OnWidgetBoundsChanged(
height_delta = new_bounds.height() - widget_size_.height(); height_delta = new_bounds.height() - widget_size_.height();
} }
auto* view = browser_view_->GetInspectableWebContentsView()->GetView(); auto* view = browser_view()->GetInspectableWebContentsView()->GetView();
auto new_view_size = view->size(); auto new_view_size = view->size();
new_view_size.set_width(new_view_size.width() + width_delta); new_view_size.set_width(new_view_size.width() + width_delta);
new_view_size.set_height(new_view_size.height() + height_delta); new_view_size.set_height(new_view_size.height() + height_delta);
@ -1246,7 +1236,7 @@ void NativeWindowViews::DeleteDelegate() {
} }
views::View* NativeWindowViews::GetInitiallyFocusedView() { views::View* NativeWindowViews::GetInitiallyFocusedView() {
return inspectable_web_contents()->GetView()->GetWebView(); return focused_view_;
} }
bool NativeWindowViews::CanResize() const { bool NativeWindowViews::CanResize() const {

View file

@ -101,7 +101,7 @@ class NativeWindowViews : public NativeWindow,
bool IsSimpleFullScreen() override; bool IsSimpleFullScreen() override;
void SetKiosk(bool kiosk) override; void SetKiosk(bool kiosk) override;
bool IsKiosk() override; bool IsKiosk() override;
void SetBackgroundColor(const std::string& color_name) override; void SetBackgroundColor(SkColor color) override;
void SetHasShadow(bool has_shadow) override; void SetHasShadow(bool has_shadow) override;
bool HasShadow() override; bool HasShadow() override;
void SetOpacity(const double opacity) override; void SetOpacity(const double opacity) override;
@ -128,8 +128,8 @@ class NativeWindowViews : public NativeWindow,
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override; gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override;
gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override; gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override;
void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) override; void UpdateDraggableRegions(std::unique_ptr<SkRegion> region);
#if defined(OS_WIN) #if defined(OS_WIN)
void SetIcon(HICON small_icon, HICON app_icon); void SetIcon(HICON small_icon, HICON app_icon);
@ -214,8 +214,7 @@ class NativeWindowViews : public NativeWindow,
std::unique_ptr<views::Widget> window_; std::unique_ptr<views::Widget> window_;
views::View* web_view_; // Managed by inspectable_web_contents_. views::View* web_view_; // Managed by inspectable_web_contents_.
views::View* focused_view_; // The view should be focused by default.
NativeBrowserView* browser_view_;
std::unique_ptr<AutofillPopup> autofill_popup_; std::unique_ptr<AutofillPopup> autofill_popup_;

View file

@ -209,7 +209,9 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
if (manager) { if (manager) {
auto embedder = manager->GetEmbedder(guest_instance_id); auto embedder = manager->GetEmbedder(guest_instance_id);
if (embedder) { if (embedder) {
auto window = NativeWindow::FromWebContents(embedder); auto* relay = NativeWindowRelay::FromWebContents(web_contents);
if (relay) {
auto* window = relay->window.get();
if (window) { if (window) {
const bool visible = window->IsVisible() && !window->IsMinimized(); const bool visible = window->IsVisible() && !window->IsMinimized();
if (!visible) { if (!visible) {
@ -219,6 +221,7 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
} }
} }
} }
}
} }
bool WebContentsPreferences::IsPreferenceEnabled( bool WebContentsPreferences::IsPreferenceEnabled(

View file

@ -235,12 +235,8 @@ void WebDialogHelper::RunFileChooser(
NOTREACHED(); NOTREACHED();
} }
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>( auto* browser_context = static_cast<atom::AtomBrowserContext*>(
window_->web_contents()->GetBrowserContext());
if (!browser_context) {
browser_context = static_cast<atom::AtomBrowserContext*>(
render_frame_host->GetProcess()->GetBrowserContext()); render_frame_host->GetProcess()->GetBrowserContext());
}
settings.default_path = browser_context->prefs()->GetFilePath( settings.default_path = browser_context->prefs()->GetFilePath(
prefs::kSelectFileLastDirectory).Append(params.default_file_name); prefs::kSelectFileLastDirectory).Append(params.default_file_name);
settings.properties = flags; settings.properties = flags;

View file

@ -163,6 +163,8 @@
'atom/browser/api/atom_api_web_view_manager.cc', 'atom/browser/api/atom_api_web_view_manager.cc',
'atom/browser/api/atom_api_browser_window.cc', 'atom/browser/api/atom_api_browser_window.cc',
'atom/browser/api/atom_api_browser_window.h', 'atom/browser/api/atom_api_browser_window.h',
'atom/browser/api/atom_api_browser_window_mac.mm',
'atom/browser/api/atom_api_browser_window_views.cc',
'atom/browser/api/event.cc', 'atom/browser/api/event.cc',
'atom/browser/api/event.h', 'atom/browser/api/event.h',
'atom/browser/api/event_emitter.cc', 'atom/browser/api/event_emitter.cc',