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/window_list.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/file_path_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() {
if (!web_contents())
return;
Observe(nullptr);
// Close all child windows before closing current window.
v8::Locker locker(isolate());
@ -296,6 +296,9 @@ void BrowserWindow::OnCloseContents() {
// Do not sent "unresponsive" event after window is closed.
window_unresponsive_closure_.Cancel();
// Clear the web_contents() at last.
Observe(nullptr);
}
void BrowserWindow::OnRendererResponsive() {
@ -307,6 +310,10 @@ void BrowserWindow::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}
void BrowserWindow::RequestPreferredWidth(int* width) {
*width = web_contents()->GetPreferredSize().width();
}
void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
// 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
@ -356,10 +363,27 @@ void BrowserWindow::OnWindowEndSession() {
}
void BrowserWindow::OnWindowBlur() {
web_contents()->StoreFocus();
#if defined(OS_MACOSX)
auto* rwhv = web_contents()->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetActive(false);
#endif
Emit("blur");
}
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");
}
@ -388,6 +412,10 @@ void BrowserWindow::OnWindowRestore() {
}
void BrowserWindow::OnWindowResize() {
#if defined(OS_MACOSX)
if (!draggable_regions_.empty())
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
Emit("resize");
}
@ -754,7 +782,11 @@ bool BrowserWindow::IsKiosk() {
}
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) {
@ -774,15 +806,16 @@ double BrowserWindow::GetOpacity() {
}
void BrowserWindow::FocusOnWebView() {
window_->FocusOnWebView();
web_contents()->GetRenderViewHost()->GetWidget()->Focus();
}
void BrowserWindow::BlurWebView() {
window_->BlurWebView();
web_contents()->GetRenderViewHost()->GetWidget()->Blur();
}
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) {
@ -1091,8 +1124,17 @@ void BrowserWindow::AddTabbedWindow(NativeWindow* window,
void BrowserWindow::SetVibrancy(mate::Arguments* args) {
std::string 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);
}
@ -1135,10 +1177,19 @@ void BrowserWindow::RemoveFromParentChildWindows() {
parent->child_windows_.Remove(ID());
}
void BrowserWindow::UpdateDraggableRegions(
content::RenderFrameHost* rfh,
// Convert draggable regions in raw format to SkRegion format.
std::unique_ptr<SkRegion> BrowserWindow::DraggableRegionsToSkRegion(
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) {

View file

@ -81,6 +81,7 @@ class BrowserWindow : public mate::TrackableObject<BrowserWindow>,
// NativeWindowObserver:
void WillCloseWindow(bool* prevent_default) override;
void RequestPreferredWidth(int* width) override;
void OnCloseButtonClicked(bool* prevent_default) override;
void OnWindowClosed() override;
void OnWindowEndSession() override;
@ -260,6 +261,10 @@ class BrowserWindow : public mate::TrackableObject<BrowserWindow>,
content::RenderFrameHost* rfh,
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.
void ScheduleUnresponsiveEvent(int ms);
@ -271,6 +276,10 @@ class BrowserWindow : public mate::TrackableObject<BrowserWindow>,
MessageCallbackMap messages_callback_map_;
#endif
#if defined(OS_MACOSX)
std::vector<DraggableRegion> draggable_regions_;
#endif
// Closure that would be called when window is unresponsive when closing,
// it should be cancelled when we can prove that the window is responsive.
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) {
if (!native_window)
return;
brightray::InspectableWebContents* web_contents =
native_window->inspectable_web_contents();
if (!web_contents)
return;
NSWindow* nswindow = native_window->GetNativeWindow();
auto close_callback = base::Bind(
&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()
useDefaultAccelerator:NO]);
NSMenu* menu = [popup_controllers_[window_id] menu];
NSView* view = web_contents->GetView()->GetNativeView();
NSView* view = [nswindow contentView];
// Which menu item to show.
NSMenuItem* item = nil;
@ -69,7 +66,6 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
// (-1, -1) means showing on mouse location.
NSPoint position;
if (x == -1 || y == -1) {
NSWindow* nswindow = native_window->GetNativeWindow();
position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream]
fromView:nil];
} else {

View file

@ -24,19 +24,16 @@ MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
void MenuViews::PopupAt(BrowserWindow* window,
int x, int y, int positioning_item,
const base::Closure& callback) {
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
auto* native_window = static_cast<NativeWindowViews*>(window->window());
if (!native_window)
return;
auto* web_contents = native_window->inspectable_web_contents();
if (!web_contents)
return;
// (-1, -1) means showing on mouse location.
gfx::Point location;
if (x == -1 || y == -1) {
location = display::Screen::GetScreen()->GetCursorScreenPoint();
} 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();
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(
model(), flags, close_callback));
menu_runners_[window_id]->RunMenuAt(
static_cast<NativeWindowViews*>(window->window())->widget(),
native_window->widget(),
NULL,
gfx::Rect(location, gfx::Size()),
views::MENU_ANCHOR_TOPLEFT,

View file

@ -33,6 +33,7 @@
#include "chrome/browser/speech/tts_message_filter.h"
#include "content/public/browser/browser_ppapi_host.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_view_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";
}
}
auto* relay = NativeWindowRelay::FromWebContents(web_contents);
atom::ShowMessageBox(
NativeWindow::FromWebContents(web_contents),
relay ? relay->window.get() : nullptr,
atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE, buttons, -1, 0,
atom::MessageBoxOptions::MESSAGE_BOX_NONE, "",
base::UTF16ToUTF8(message_text), "", checkbox_string,

View file

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

View file

@ -8,36 +8,12 @@
#include <utility>
#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/window_list.h"
#include "atom/common/draggable_region.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/color_util.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_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 "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);
@ -47,8 +23,7 @@ NativeWindow::NativeWindow(
brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options,
NativeWindow* parent)
: content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
has_frame_(true),
: has_frame_(true),
transparent_(false),
enable_larger_than_screen_(false),
is_closed_(false),
@ -58,7 +33,7 @@ NativeWindow::NativeWindow(
parent_(parent),
is_modal_(false),
is_osr_dummy_(false),
inspectable_web_contents_(inspectable_web_contents),
browser_view_(nullptr),
weak_factory_(this) {
options.Get(options::kFrame, &has_frame_);
options.Get(options::kTransparent, &transparent_);
@ -76,16 +51,6 @@ NativeWindow::~NativeWindow() {
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) {
// Setup window from options.
int x = -1, y = -1;
@ -172,10 +137,10 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
}
std::string color;
if (options.Get(options::kBackgroundColor, &color)) {
SetBackgroundColor(color);
SetBackgroundColor(ParseHexColor(color));
} else if (!transparent()) {
// For normal window, use white as default background.
SetBackgroundColor("#FFFF");
SetBackgroundColor(SK_ColorWHITE);
}
std::string title(Browser::Get()->GetName());
options.Get(options::kTitle, &title);
@ -354,19 +319,6 @@ void NativeWindow::SetEscapeTouchBarItem(
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) {
}
@ -402,6 +354,11 @@ void NativeWindow::PreviewFile(const std::string& path,
void NativeWindow::CloseFilePreview() {
}
void NativeWindow::NotifyWindowRequestPreferredWith(int* width) {
for (NativeWindowObserver& observer : observers_)
observer.RequestPreferredWidth(width);
}
void NativeWindow::NotifyWindowCloseButtonClicked() {
// First ask the observers whether we want to close.
bool prevent_default = false;
@ -563,18 +520,4 @@ void NativeWindow::NotifyWindowMessage(
}
#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

View file

@ -11,20 +11,13 @@
#include <vector>
#include "atom/browser/native_window_observer.h"
#include "atom/browser/ui/accelerator_util.h"
#include "atom/browser/ui/atom_menu_model.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.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 "extensions/browser/app_window/size_constraints.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;
@ -37,8 +30,10 @@ struct NativeWebKeyboardEvent;
}
namespace gfx {
class Image;
class Point;
class Rect;
class RectF;
class Size;
}
@ -52,8 +47,7 @@ class NativeBrowserView;
struct DraggableRegion;
class NativeWindow : public base::SupportsUserData,
public content::WebContentsObserver {
class NativeWindow : public base::SupportsUserData {
public:
~NativeWindow() override;
@ -64,9 +58,6 @@ class NativeWindow : public base::SupportsUserData,
const mate::Dictionary& options,
NativeWindow* parent = nullptr);
// Find a window from its WebContents
static NativeWindow* FromWebContents(content::WebContents* web_contents);
void InitFromOptions(const mate::Dictionary& options);
virtual void Close() = 0;
@ -138,7 +129,7 @@ class NativeWindow : public base::SupportsUserData,
virtual bool IsSimpleFullScreen() = 0;
virtual void SetKiosk(bool kiosk) = 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 bool HasShadow() = 0;
virtual void SetOpacity(const double opacity) = 0;
@ -194,11 +185,6 @@ class NativeWindow : public base::SupportsUserData,
virtual void ToggleTabBar();
virtual bool AddTabbedWindow(NativeWindow* window);
// Webview APIs.
virtual void FocusOnWebView();
virtual void BlurWebView();
virtual bool IsWebViewFocused();
// Toggle the menu bar.
virtual void SetAutoHideMenuBar(bool auto_hide);
virtual bool IsMenuBarAutoHide();
@ -221,10 +207,6 @@ class NativeWindow : public base::SupportsUserData,
virtual gfx::Rect WindowBoundsToContentBounds(
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() {
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
// related notifications.
void NotifyWindowRequestPreferredWith(int* width);
void NotifyWindowCloseButtonClicked();
void NotifyWindowClosed();
void NotifyWindowEndSession();
@ -282,10 +265,6 @@ class NativeWindow : public base::SupportsUserData,
observers_.RemoveObserver(obs);
}
brightray::InspectableWebContents* inspectable_web_contents() const {
return inspectable_web_contents_;
}
bool has_frame() const { return 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; }
bool is_offscreen_dummy() const { return is_osr_dummy_; }
NativeBrowserView* browser_view() const { return browser_view_; }
NativeWindow* parent() const { return parent_; }
bool is_modal() const { return is_modal_; }
@ -303,10 +283,9 @@ class NativeWindow : public base::SupportsUserData,
const mate::Dictionary& options,
NativeWindow* parent);
// Convert draggable regions in raw format to SkRegion format. Caller is
// responsible for deleting the returned SkRegion instance.
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions);
void set_browser_view(NativeBrowserView* browser_view) {
browser_view_ = browser_view;
}
private:
// Whether window has standard frame.
@ -343,8 +322,8 @@ class NativeWindow : public base::SupportsUserData,
// Is this a dummy window for an offscreen WebContents.
bool is_osr_dummy_;
// The page this window is viewing.
brightray::InspectableWebContents* inspectable_web_contents_;
// The browser view layer.
NativeBrowserView* browser_view_;
// Observers of this window.
base::ObserverList<NativeWindowObserver> observers_;

View file

@ -79,7 +79,7 @@ class NativeWindowMac : public NativeWindow {
bool IsSimpleFullScreen() override;
void SetKiosk(bool kiosk) override;
bool IsKiosk() override;
void SetBackgroundColor(const std::string& color_name) override;
void SetBackgroundColor(SkColor color) override;
void SetHasShadow(bool has_shadow) override;
bool HasShadow() 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 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.
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 fullscreen_window_title() const { return fullscreen_window_title_; }
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:
void InternalSetParentWindow(NativeWindow* parent, bool attach);
void ShowWindowButton(NSWindowButton button);
void InstallView();
void UninstallView();
void SetRenderWidgetHostOpaque(bool opaque);
void InstallView(NSView* view);
base::scoped_nsobject<AtomNSWindow> window_;
base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
@ -165,10 +151,6 @@ class NativeWindowMac : public NativeWindow {
// The view that will fill the whole frameless window.
base::scoped_nsobject<FullSizeContentView> content_view_;
NativeBrowserView* browser_view_;
std::vector<DraggableRegion> draggable_regions_;
bool is_kiosk_;
bool was_fullscreen_;

View file

@ -12,8 +12,6 @@
#include "atom/browser/native_browser_view_mac.h"
#include "atom/browser/ui/cocoa/atom_touch_bar.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 "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
@ -21,15 +19,9 @@
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.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/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 "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/gfx/skia_util.h"
namespace {
@ -218,16 +210,14 @@ bool ScopedDisableResize::disable_resize_ = false;
if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask)
return frame;
content::WebContents* web_contents = shell_->web_contents();
if (!web_contents)
return frame;
CGFloat page_width = static_cast<CGFloat>(
web_contents->GetPreferredSize().width());
NSRect window_frame = [window frame];
// Get preferred width from observers. Usually the page width.
int preferred_width = 0;
shell_->NotifyWindowRequestPreferredWith(&preferred_width);
// 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 -- and only move it left if necessary.
@ -243,30 +233,10 @@ bool ScopedDisableResize::disable_resize_ = false;
}
- (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();
}
- (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();
}
@ -296,7 +266,6 @@ bool ScopedDisableResize::disable_resize_ = false;
}
- (void)windowDidResize:(NSNotification*)notification {
shell_->UpdateDraggableRegions(shell_->draggable_regions());
shell_->NotifyWindowResize();
}
@ -747,25 +716,6 @@ enum {
@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
@end
@ -830,7 +780,6 @@ NativeWindowMac::NativeWindowMac(
const mate::Dictionary& options,
NativeWindow* parent)
: NativeWindow(web_contents, options, parent),
browser_view_(nullptr),
is_kiosk_(false),
was_fullscreen_(false),
zoom_to_page_width_(false),
@ -1002,7 +951,7 @@ NativeWindowMac::NativeWindowMac(
options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor);
[window_ setDisableAutoHideCursor:disableAutoHideCursor];
NSView* view = inspectable_web_contents()->GetView()->GetNativeView();
NSView* view = web_contents->GetView()->GetNativeView();
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
// Use an NSEvent monitor to listen for the wheel event.
@ -1013,9 +962,6 @@ NativeWindowMac::NativeWindowMac(
if ([[event window] windowNumber] != [window_ windowNumber])
return event;
if (!web_contents)
return event;
if (!began && (([event phase] == NSEventPhaseMayBegin) ||
([event phase] == NSEventPhaseBegan))) {
this->NotifyWindowScrollTouchBegin();
@ -1028,7 +974,7 @@ NativeWindowMac::NativeWindowMac(
return event;
}];
InstallView();
InstallView(web_contents->GetView()->GetNativeView());
std::string type;
if (options.Get(options::kVibrancyType, &type)) {
@ -1042,7 +988,6 @@ NativeWindowMac::NativeWindowMac(
NativeWindowMac::~NativeWindowMac() {
[NSEvent removeMonitor:wheel_event_monitor_];
Observe(nullptr);
}
void NativeWindowMac::Close() {
@ -1498,15 +1443,10 @@ bool NativeWindowMac::IsKiosk() {
return is_kiosk_;
}
void NativeWindowMac::SetBackgroundColor(const std::string& color_name) {
SkColor color = ParseHexColor(color_name);
void NativeWindowMac::SetBackgroundColor(SkColor color) {
base::ScopedCFTypeRef<CGColorRef> cgcolor(
skia::CGColorCreateFromSkColor(color));
[[[window_ contentView] layer] setBackgroundColor:cgcolor];
const auto view = web_contents()->GetRenderWidgetHostView();
if (view)
view->SetBackgroundColor(color);
}
void NativeWindowMac::SetHasShadow(bool has_shadow) {
@ -1550,20 +1490,19 @@ void NativeWindowMac::SetContentProtection(bool enable) {
: NSWindowSharingReadOnly];
}
void NativeWindowMac::SetBrowserView(NativeBrowserView* browser_view) {
if (browser_view_) {
[browser_view_->GetInspectableWebContentsView()->GetNativeView()
void NativeWindowMac::SetBrowserView(NativeBrowserView* view) {
if (browser_view()) {
[browser_view()->GetInspectableWebContentsView()->GetNativeView()
removeFromSuperview];
browser_view_ = nullptr;
set_browser_view(nullptr);
}
if (!browser_view) {
if (!view) {
return;
}
browser_view_ = browser_view;
auto* native_view =
browser_view->GetInspectableWebContentsView()->GetNativeView();
set_browser_view(view);
auto* native_view = view->GetInspectableWebContentsView()->GetNativeView();
[[window_ contentView] addSubview:native_view
positioned:NSWindowAbove
relativeTo:nil];
@ -1575,7 +1514,7 @@ void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
}
gfx::NativeView NativeWindowMac::GetNativeView() const {
return inspectable_web_contents()->GetView()->GetNativeView();
return [window_ contentView];
}
gfx::NativeWindow NativeWindowMac::GetNativeWindow() const {
@ -1583,7 +1522,7 @@ gfx::NativeWindow NativeWindowMac::GetNativeWindow() const {
}
gfx::AcceleratedWidget NativeWindowMac::GetAcceleratedWidget() const {
return inspectable_web_contents()->GetView()->GetNativeView();
return [window_ contentView];
}
void NativeWindowMac::SetProgressBar(double progress, const NativeWindow::ProgressState state) {
@ -1681,20 +1620,6 @@ bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
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) {
if (!base::mac::IsAtLeastOS10_10()) return;
@ -1705,7 +1630,6 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
[window_ setBackgroundColor:background_color_before_vibrancy_];
[window_ setTitlebarAppearsTransparent:transparency_before_vibrancy_];
}
SetRenderWidgetHostOpaque(!transparent());
if (vibrant_view == nil) return;
[vibrant_view removeFromSuperview];
@ -1714,7 +1638,6 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
return;
}
SetRenderWidgetHostOpaque(false);
background_color_before_vibrancy_.reset([window_ backgroundColor]);
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) {
if (is_modal())
return;
@ -1912,14 +1761,13 @@ void NativeWindowMac::ShowWindowButton(NSWindowButton button) {
[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.
// But do not enable it on OS X 10.9 for transparent window, otherwise a
// semi-transparent frame would show.
if (!(transparent() && base::mac::IsOS10_9()) && !is_modal())
[[window_ contentView] setWantsLayer:YES];
NSView* view = inspectable_web_contents()->GetView()->GetNativeView();
if (has_frame()) {
[view setFrame:[[window_ contentView] bounds]];
[[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) {
// Changing the styleMask of a frameless windows causes it to change size so
// we explicitly disable resizing while setting it.

View file

@ -34,6 +34,9 @@ class NativeWindowObserver {
// Called when the window is gonna closed.
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.
virtual void OnCloseButtonClicked(bool* prevent_default) {}

View file

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

View file

@ -101,7 +101,7 @@ class NativeWindowViews : public NativeWindow,
bool IsSimpleFullScreen() override;
void SetKiosk(bool kiosk) override;
bool IsKiosk() override;
void SetBackgroundColor(const std::string& color_name) override;
void SetBackgroundColor(SkColor color) override;
void SetHasShadow(bool has_shadow) override;
bool HasShadow() 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 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)
void SetIcon(HICON small_icon, HICON app_icon);
@ -214,8 +214,7 @@ class NativeWindowViews : public NativeWindow,
std::unique_ptr<views::Widget> window_;
views::View* web_view_; // Managed by inspectable_web_contents_.
NativeBrowserView* browser_view_;
views::View* focused_view_; // The view should be focused by default.
std::unique_ptr<AutofillPopup> autofill_popup_;

View file

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

View file

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

View file

@ -163,6 +163,8 @@
'atom/browser/api/atom_api_web_view_manager.cc',
'atom/browser/api/atom_api_browser_window.cc',
'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.h',
'atom/browser/api/event_emitter.cc',