refactor: use views NonClientHitTest for draggable regions on mac (#35603)
* refactor: use views NonClientHitTest for draggable regions on mac * iwyu * add backport of 9bb5f0316 * chore: update patches * remove some unneeded functions * remove test for triggering when BW is focused * chore: update patches * simplify views/mac split now that the draggable logic is the same * Apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * Update shell/browser/native_window.h Co-authored-by: Charles Kerr <charles@charleskerr.com> * fix build Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: Charles Kerr <charles@charleskerr.com>
This commit is contained in:
parent
7ce94eb0b4
commit
8a926ffde4
15 changed files with 70 additions and 392 deletions
|
@ -124,7 +124,6 @@ filenames = {
|
|||
"shell/app/electron_main_delegate_mac.h",
|
||||
"shell/app/electron_main_delegate_mac.mm",
|
||||
"shell/browser/api/electron_api_app_mac.mm",
|
||||
"shell/browser/api/electron_api_browser_window_mac.mm",
|
||||
"shell/browser/api/electron_api_menu_mac.h",
|
||||
"shell/browser/api/electron_api_menu_mac.mm",
|
||||
"shell/browser/api/electron_api_native_theme_mac.mm",
|
||||
|
@ -211,7 +210,6 @@ filenames = {
|
|||
]
|
||||
|
||||
lib_sources_views = [
|
||||
"shell/browser/api/electron_api_browser_window_views.cc",
|
||||
"shell/browser/api/electron_api_menu_views.cc",
|
||||
"shell/browser/api/electron_api_menu_views.h",
|
||||
"shell/browser/native_browser_view_views.cc",
|
||||
|
|
|
@ -111,11 +111,6 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
|||
// Install the content view after BaseWindow's JS code is initialized.
|
||||
SetContentView(gin::CreateHandle<View>(isolate, web_contents_view.get()));
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
OverrideNSWindowContentView(
|
||||
web_contents->inspectable_web_contents()->GetView());
|
||||
#endif
|
||||
|
||||
// Init window after everything has been setup.
|
||||
window()->InitFromOptions(options);
|
||||
}
|
||||
|
@ -164,7 +159,10 @@ void BrowserWindow::OnRendererResponsive(content::RenderProcessHost*) {
|
|||
|
||||
void BrowserWindow::OnDraggableRegionsUpdated(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
UpdateDraggableRegions(regions);
|
||||
if (window_->has_frame())
|
||||
return;
|
||||
|
||||
window_->UpdateDraggableRegions(regions);
|
||||
}
|
||||
|
||||
void BrowserWindow::OnSetContentBounds(const gfx::Rect& rect) {
|
||||
|
@ -268,19 +266,6 @@ void BrowserWindow::OnWindowIsKeyChanged(bool is_key) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowResize() {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
if (!draggable_regions_.empty()) {
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
} else {
|
||||
for (NativeBrowserView* view : window_->browser_views()) {
|
||||
view->UpdateDraggableRegions(view->GetDraggableRegions());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
BaseWindow::OnWindowResize();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowLeaveFullScreen() {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
if (web_contents()->IsFullscreen())
|
||||
|
@ -349,42 +334,6 @@ void BrowserWindow::SetBrowserView(
|
|||
BaseWindow::ResetBrowserViews();
|
||||
if (browser_view)
|
||||
BaseWindow::AddBrowserView(*browser_view);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
|
||||
BaseWindow::AddBrowserView(browser_view);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
|
||||
BaseWindow::RemoveBrowserView(browser_view);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::SetTopBrowserView(gin::Handle<BrowserView> browser_view,
|
||||
gin_helper::Arguments* args) {
|
||||
BaseWindow::SetTopBrowserView(browser_view, args);
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::ResetBrowserViews() {
|
||||
BaseWindow::ResetBrowserViews();
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::OnDevToolsResized() {
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
}
|
||||
|
||||
void BrowserWindow::FocusOnWebView() {
|
||||
|
|
|
@ -57,7 +57,6 @@ class BrowserWindow : public BaseWindow,
|
|||
void OnActivateContents() override;
|
||||
void OnPageTitleUpdated(const std::u16string& title,
|
||||
bool explicit_set) override;
|
||||
void OnDevToolsResized() override;
|
||||
|
||||
// NativeWindowObserver:
|
||||
void RequestPreferredWidth(int* width) override;
|
||||
|
@ -68,7 +67,6 @@ class BrowserWindow : public BaseWindow,
|
|||
// BaseWindow:
|
||||
void OnWindowBlur() override;
|
||||
void OnWindowFocus() override;
|
||||
void OnWindowResize() override;
|
||||
void OnWindowLeaveFullScreen() override;
|
||||
void CloseImmediately() override;
|
||||
void Focus() override;
|
||||
|
@ -76,11 +74,6 @@ class BrowserWindow : public BaseWindow,
|
|||
void SetBackgroundColor(const std::string& color_name) override;
|
||||
void SetBrowserView(
|
||||
absl::optional<gin::Handle<BrowserView>> browser_view) override;
|
||||
void AddBrowserView(gin::Handle<BrowserView> browser_view) override;
|
||||
void RemoveBrowserView(gin::Handle<BrowserView> browser_view) override;
|
||||
void SetTopBrowserView(gin::Handle<BrowserView> browser_view,
|
||||
gin_helper::Arguments* args) override;
|
||||
void ResetBrowserViews() override;
|
||||
void OnWindowShow() override;
|
||||
void OnWindowHide() override;
|
||||
|
||||
|
@ -95,10 +88,6 @@ class BrowserWindow : public BaseWindow,
|
|||
#endif
|
||||
|
||||
private:
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
void OverrideNSWindowContentView(InspectableWebContentsView* webView);
|
||||
#endif
|
||||
|
||||
// Helpers.
|
||||
|
||||
// Called when the window needs to update its draggable region.
|
||||
|
@ -115,8 +104,6 @@ class BrowserWindow : public BaseWindow,
|
|||
// it should be cancelled when we can prove that the window is responsive.
|
||||
base::CancelableRepeatingClosure window_unresponsive_closure_;
|
||||
|
||||
std::vector<mojom::DraggableRegionPtr> draggable_regions_;
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
// 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 "shell/browser/api/electron_api_browser_window.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "shell/browser/native_browser_view.h"
|
||||
#include "shell/browser/native_window_mac.h"
|
||||
#include "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
|
||||
namespace electron::api {
|
||||
|
||||
void BrowserWindow::OverrideNSWindowContentView(
|
||||
InspectableWebContentsView* view) {
|
||||
// Make NativeWindow use a NSView as content view.
|
||||
static_cast<NativeWindowMac*>(window())->OverrideNSWindowContentView();
|
||||
// Add webview to contentView.
|
||||
NSView* webView = view->GetNativeView().GetNativeNSView();
|
||||
NSView* contentView =
|
||||
[window()->GetNativeWindow().GetNativeNSWindow() contentView];
|
||||
[webView setFrame:[contentView bounds]];
|
||||
|
||||
// ensure that buttons view is floated to top of view hierarchy
|
||||
NSArray* subviews = [contentView subviews];
|
||||
NSView* last = subviews.lastObject;
|
||||
[contentView addSubview:webView positioned:NSWindowBelow relativeTo:last];
|
||||
|
||||
[contentView viewDidMoveToWindow];
|
||||
}
|
||||
|
||||
void BrowserWindow::UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
if (window_->has_frame() || !web_contents())
|
||||
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().GetNativeNSView();
|
||||
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 are implemented by having the whole web view draggable
|
||||
// and overlaying regions that are not draggable.
|
||||
if (&draggable_regions_ != ®ions)
|
||||
draggable_regions_ = mojo::Clone(regions);
|
||||
|
||||
std::vector<gfx::Rect> drag_exclude_rects;
|
||||
if (regions.empty()) {
|
||||
drag_exclude_rects.emplace_back(0, 0, webViewWidth, webViewHeight);
|
||||
} else {
|
||||
drag_exclude_rects = CalculateNonDraggableRegions(
|
||||
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
|
||||
}
|
||||
|
||||
// Draggable regions on BrowserViews are independent from those of
|
||||
// BrowserWindows, so if a BrowserView with different draggable regions than
|
||||
// the BrowserWindow it belongs to is superimposed on top of that window, the
|
||||
// draggable regions of the BrowserView take precedence over those of the
|
||||
// BrowserWindow.
|
||||
for (NativeBrowserView* view : window_->browser_views()) {
|
||||
view->UpdateDraggableRegions(view->GetDraggableRegions());
|
||||
}
|
||||
|
||||
// Create and add a ControlRegionView for each region that needs to be
|
||||
// excluded from the dragging.
|
||||
for (const auto& rect : drag_exclude_rects) {
|
||||
base::scoped_nsobject<NSView> controlRegion(
|
||||
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
|
||||
[controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
|
||||
rect.width(), rect.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 electron::api
|
|
@ -1,37 +0,0 @@
|
|||
// 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 "shell/browser/api/electron_api_browser_window.h"
|
||||
|
||||
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "ui/aura/window.h"
|
||||
|
||||
namespace electron::api {
|
||||
|
||||
void BrowserWindow::UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
if (window_->has_frame())
|
||||
return;
|
||||
|
||||
if (&draggable_regions_ != ®ions && web_contents()) {
|
||||
auto* view =
|
||||
static_cast<content::WebContentsImpl*>(web_contents())->GetView();
|
||||
if (view) {
|
||||
const gfx::NativeView nv = view->GetNativeView();
|
||||
auto const offset = nv->GetBoundsInRootWindow();
|
||||
auto snapped_regions = mojo::Clone(regions);
|
||||
for (auto& snapped_region : snapped_regions) {
|
||||
snapped_region->bounds.Offset(offset.x(), offset.y());
|
||||
}
|
||||
|
||||
draggable_regions_ = mojo::Clone(snapped_regions);
|
||||
}
|
||||
}
|
||||
|
||||
static_cast<NativeWindowViews*>(window_.get())
|
||||
->UpdateDraggableRegions(draggable_regions_);
|
||||
}
|
||||
|
||||
} // namespace electron::api
|
7
shell/browser/native_window.cc
Executable file → Normal file
7
shell/browser/native_window.cc
Executable file → Normal file
|
@ -14,11 +14,13 @@
|
|||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/native_window_features.h"
|
||||
#include "shell/browser/ui/drag_util.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/persistent_dictionary.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
|
@ -683,6 +685,11 @@ void NativeWindow::NotifyWindowMessage(UINT message,
|
|||
}
|
||||
#endif
|
||||
|
||||
void NativeWindow::UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
draggable_region_ = DraggableRegionsToSkRegion(regions);
|
||||
}
|
||||
|
||||
views::Widget* NativeWindow::GetWidget() {
|
||||
return widget();
|
||||
}
|
||||
|
|
|
@ -18,9 +18,12 @@
|
|||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "extensions/browser/app_window/size_constraints.h"
|
||||
#include "shell/browser/native_window_observer.h"
|
||||
#include "shell/common/api/api.mojom.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
||||
class SkRegion;
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
@ -337,6 +340,11 @@ class NativeWindow : public base::SupportsUserData,
|
|||
return fullscreen_transition_type_;
|
||||
}
|
||||
|
||||
SkRegion const* draggable_region() const { return draggable_region_.get(); }
|
||||
|
||||
void UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions);
|
||||
|
||||
views::Widget* widget() const { return widget_.get(); }
|
||||
views::View* content_view() const { return content_view_; }
|
||||
|
||||
|
@ -456,6 +464,10 @@ class NativeWindow : public base::SupportsUserData,
|
|||
|
||||
gfx::Rect overlay_rect_;
|
||||
|
||||
// For custom drag, the whole window is non-draggable and the draggable region
|
||||
// has to been explicitly provided.
|
||||
std::unique_ptr<SkRegion> draggable_region_; // used in custom drag.
|
||||
|
||||
base::WeakPtrFactory<NativeWindow> weak_factory_{this};
|
||||
};
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/common/api/api.mojom.h"
|
||||
#include "ui/display/display_observer.h"
|
||||
#include "ui/native_theme/native_theme_observer.h"
|
||||
#include "ui/views/controls/native/native_view_host.h"
|
||||
|
@ -160,9 +161,6 @@ class NativeWindowMac : public NativeWindow,
|
|||
// cleanup in destructor.
|
||||
void Cleanup();
|
||||
|
||||
// Use a custom content view instead of Chromium's BridgedContentView.
|
||||
void OverrideNSWindowContentView();
|
||||
|
||||
void UpdateVibrancyRadii(bool fullscreen);
|
||||
|
||||
void UpdateWindowOriginalFrame();
|
||||
|
@ -206,6 +204,8 @@ class NativeWindowMac : public NativeWindow,
|
|||
// views::WidgetDelegate:
|
||||
views::View* GetContentsView() override;
|
||||
bool CanMaximize() const override;
|
||||
std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
|
||||
views::Widget* widget) override;
|
||||
|
||||
// ui::NativeThemeObserver:
|
||||
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
|
||||
|
@ -228,11 +228,6 @@ class NativeWindowMac : public NativeWindow,
|
|||
base::scoped_nsobject<ElectronPreviewItem> preview_item_;
|
||||
base::scoped_nsobject<ElectronTouchBar> touch_bar_;
|
||||
|
||||
// The NSView that used as contentView of window.
|
||||
//
|
||||
// For frameless window it would fill the whole window.
|
||||
base::scoped_nsobject<NSView> container_view_;
|
||||
|
||||
// The views::View that fills the client area.
|
||||
std::unique_ptr<RootViewMac> root_view_;
|
||||
|
||||
|
@ -261,6 +256,8 @@ class NativeWindowMac : public NativeWindow,
|
|||
// Controls the position and visibility of window buttons.
|
||||
base::scoped_nsobject<WindowButtonsProxy> buttons_proxy_;
|
||||
|
||||
std::unique_ptr<SkRegion> draggable_region_;
|
||||
|
||||
// Maximizable window state; necessary for persistence through redraws.
|
||||
bool maximizable_ = true;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <objc/objc-runtime.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
@ -31,6 +32,7 @@
|
|||
#include "shell/browser/ui/cocoa/electron_touch_bar.h"
|
||||
#include "shell/browser/ui/cocoa/root_view_mac.h"
|
||||
#include "shell/browser/ui/cocoa/window_buttons_proxy.h"
|
||||
#include "shell/browser/ui/drag_util.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
|
@ -40,88 +42,16 @@
|
|||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/process_util.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/mac/window_list_utils.h"
|
||||
#include "ui/base/hit_test.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/cocoa/native_widget_mac_ns_window_host.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
// This view would inform Chromium to resize the hosted views::View.
|
||||
//
|
||||
// The overridden methods should behave the same with BridgedContentView.
|
||||
@interface ElectronAdaptedContentView : NSView {
|
||||
@private
|
||||
views::NativeWidgetMacNSWindowHost* bridge_host_;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ElectronAdaptedContentView
|
||||
|
||||
- (id)initWithShell:(electron::NativeWindowMac*)shell {
|
||||
if ((self = [self init])) {
|
||||
bridge_host_ = views::NativeWidgetMacNSWindowHost::GetFromNativeWindow(
|
||||
shell->GetNativeWindow());
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow {
|
||||
// When this view is added to a window, AppKit calls setFrameSize before it is
|
||||
// added to the window, so the behavior in setFrameSize is not triggered.
|
||||
NSWindow* window = [self window];
|
||||
if (window)
|
||||
[self setFrameSize:NSZeroSize];
|
||||
}
|
||||
|
||||
- (void)setFrameSize:(NSSize)newSize {
|
||||
// The size passed in here does not always use
|
||||
// -[NSWindow contentRectForFrameRect]. The following ensures that the
|
||||
// contentView for a frameless window can extend over the titlebar of the new
|
||||
// window containing it, since AppKit requires a titlebar to give frameless
|
||||
// windows correct shadows and rounded corners.
|
||||
NSWindow* window = [self window];
|
||||
if (window && [window contentView] == self) {
|
||||
newSize = [window contentRectForFrameRect:[window frame]].size;
|
||||
// Ensure that the window geometry be updated on the host side before the
|
||||
// view size is updated.
|
||||
bridge_host_->GetInProcessNSWindowBridge()->UpdateWindowGeometry();
|
||||
}
|
||||
|
||||
[super setFrameSize:newSize];
|
||||
|
||||
// The OnViewSizeChanged is marked private in derived class.
|
||||
static_cast<remote_cocoa::mojom::NativeWidgetNSWindowHost*>(bridge_host_)
|
||||
->OnViewSizeChanged(gfx::Size(newSize.width, newSize.height));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// This view always takes the size of its superview. It is intended to be used
|
||||
// as a NSWindow's contentView. It is needed because NSWindow's implementation
|
||||
// explicitly resizes the contentView at inopportune times.
|
||||
@interface FullSizeContentView : NSView
|
||||
@end
|
||||
|
||||
@implementation FullSizeContentView
|
||||
|
||||
// This method is directly called by NSWindow during a window resize on OSX
|
||||
// 10.10.0, beta 2. We must override it to prevent the content view from
|
||||
// shrinking.
|
||||
- (void)setFrameSize:(NSSize)size {
|
||||
if ([self superview])
|
||||
size = [[self superview] bounds].size;
|
||||
[super setFrameSize:size];
|
||||
}
|
||||
|
||||
// The contentView gets moved around during certain full-screen operations.
|
||||
// This is less than ideal, and should eventually be removed.
|
||||
- (void)viewDidMoveToSuperview {
|
||||
[self setFrame:[[self superview] bounds]];
|
||||
}
|
||||
|
||||
@end
|
||||
#include "ui/views/window/native_frame_view_mac.h"
|
||||
|
||||
@interface ElectronProgressBar : NSProgressIndicator
|
||||
@end
|
||||
|
@ -1701,22 +1631,42 @@ void NativeWindowMac::Cleanup() {
|
|||
display::Screen::GetScreen()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void NativeWindowMac::OverrideNSWindowContentView() {
|
||||
// When using `views::Widget` to hold WebContents, Chromium would use
|
||||
// `BridgedContentView` as content view, which does not support draggable
|
||||
// regions. In order to make draggable regions work, we have to replace the
|
||||
// content view with a simple NSView.
|
||||
if (has_frame()) {
|
||||
container_view_.reset(
|
||||
[[ElectronAdaptedContentView alloc] initWithShell:this]);
|
||||
} else {
|
||||
container_view_.reset([[FullSizeContentView alloc] init]);
|
||||
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
|
||||
class NativeAppWindowFrameViewMac : public views::NativeFrameViewMac {
|
||||
public:
|
||||
NativeAppWindowFrameViewMac(views::Widget* frame, NativeWindowMac* window)
|
||||
: views::NativeFrameViewMac(frame), native_window_(window) {}
|
||||
|
||||
NativeAppWindowFrameViewMac(const NativeAppWindowFrameViewMac&) = delete;
|
||||
NativeAppWindowFrameViewMac& operator=(const NativeAppWindowFrameViewMac&) =
|
||||
delete;
|
||||
|
||||
~NativeAppWindowFrameViewMac() override = default;
|
||||
|
||||
// NonClientFrameView:
|
||||
int NonClientHitTest(const gfx::Point& point) override {
|
||||
if (!bounds().Contains(point))
|
||||
return HTNOWHERE;
|
||||
|
||||
if (GetWidget()->IsFullscreen())
|
||||
return HTCLIENT;
|
||||
|
||||
// Check for possible draggable region in the client area for the frameless
|
||||
// window.
|
||||
SkRegion const* draggable_region = native_window_->draggable_region();
|
||||
if (draggable_region && draggable_region->contains(point.x(), point.y()))
|
||||
return HTCAPTION;
|
||||
|
||||
return HTCLIENT;
|
||||
}
|
||||
[container_view_
|
||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[window_ setContentView:container_view_];
|
||||
AddContentViewLayers();
|
||||
|
||||
private:
|
||||
// Weak.
|
||||
raw_ptr<NativeWindowMac> const native_window_;
|
||||
};
|
||||
|
||||
std::unique_ptr<views::NonClientFrameView>
|
||||
NativeWindowMac::CreateNonClientFrameView(views::Widget* widget) {
|
||||
return std::make_unique<NativeAppWindowFrameViewMac>(widget, this);
|
||||
}
|
||||
|
||||
bool NativeWindowMac::HasStyleMask(NSUInteger flag) const {
|
||||
|
@ -1779,22 +1729,6 @@ void NativeWindowMac::AddContentViewLayers() {
|
|||
}
|
||||
[[window_ contentView] setWantsLayer:YES];
|
||||
}
|
||||
|
||||
if (!has_frame()) {
|
||||
// In OSX 10.10, adding subviews to the root view for the NSView hierarchy
|
||||
// produces warnings. To eliminate the warnings, we resize the contentView
|
||||
// to fill the window, and add subviews to that.
|
||||
// http://crbug.com/380412
|
||||
if (!original_set_frame_size) {
|
||||
Class cl = [[window_ contentView] class];
|
||||
original_set_frame_size = class_replaceMethod(
|
||||
cl, @selector(setFrameSize:), (IMP)SetFrameSize, "v@:{_NSSize=ff}");
|
||||
original_view_did_move_to_superview =
|
||||
class_replaceMethod(cl, @selector(viewDidMoveToSuperview),
|
||||
(IMP)ViewDidMoveToSuperview, "v@:");
|
||||
[[window_ contentView] viewDidMoveToWindow];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindowMac::InternalSetWindowButtonVisibility(bool visible) {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "content/public/browser/desktop_media_id.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/native_browser_view_views.h"
|
||||
#include "shell/browser/ui/drag_util.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "shell/browser/ui/views/root_view.h"
|
||||
|
@ -1512,11 +1511,6 @@ gfx::Rect NativeWindowViews::WindowBoundsToContentBounds(
|
|||
return content_bounds;
|
||||
}
|
||||
|
||||
void NativeWindowViews::UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
draggable_region_ = DraggableRegionsToSkRegion(regions);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
void NativeWindowViews::SetIcon(HICON window_icon, HICON app_icon) {
|
||||
// We are responsible for storing the images.
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "shell/common/api/api.mojom.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
|
||||
#if defined(USE_OZONE)
|
||||
|
@ -155,9 +153,6 @@ 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<mojom::DraggableRegionPtr>& regions);
|
||||
|
||||
void IncrementChildModals();
|
||||
void DecrementChildModals();
|
||||
|
||||
|
@ -177,8 +172,6 @@ class NativeWindowViews : public NativeWindow,
|
|||
void SetIcon(const gfx::ImageSkia& icon);
|
||||
#endif
|
||||
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
TaskbarHost& taskbar_host() { return taskbar_host_; }
|
||||
#endif
|
||||
|
@ -329,10 +322,6 @@ class NativeWindowViews : public NativeWindow,
|
|||
// Handles unhandled keyboard messages coming back from the renderer process.
|
||||
std::unique_ptr<views::UnhandledKeyboardEventHandler> keyboard_event_handler_;
|
||||
|
||||
// For custom drag, the whole window is non-draggable and the draggable region
|
||||
// has to been explicitly provided.
|
||||
std::unique_ptr<SkRegion> draggable_region_; // used in custom drag.
|
||||
|
||||
// Whether the window should be enabled based on user calls to SetEnabled()
|
||||
bool is_enabled_ = true;
|
||||
// How many modal children this window has;
|
||||
|
|
|
@ -21,16 +21,12 @@ using electron::InspectableWebContentsViewMac;
|
|||
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
|
||||
@end
|
||||
|
||||
@interface ControlRegionView : NSView
|
||||
@end
|
||||
|
||||
@interface ElectronInspectableWebContentsView : BaseView <NSWindowDelegate> {
|
||||
@private
|
||||
electron::InspectableWebContentsViewMac* inspectableWebContentsView_;
|
||||
|
||||
base::scoped_nsobject<NSView> fake_view_;
|
||||
base::scoped_nsobject<NSWindow> devtools_window_;
|
||||
base::scoped_nsobject<ControlRegionView> devtools_mask_;
|
||||
BOOL devtools_visible_;
|
||||
BOOL devtools_docked_;
|
||||
BOOL devtools_is_first_responder_;
|
||||
|
|
|
@ -11,18 +11,6 @@
|
|||
#include "shell/browser/ui/inspectable_web_contents_view_mac.h"
|
||||
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
|
||||
|
||||
@implementation ControlRegionView
|
||||
|
||||
- (BOOL)mouseDownCanMoveWindow {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSView*)hitTest:(NSPoint)aPoint {
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ElectronInspectableWebContentsView
|
||||
|
||||
- (instancetype)initWithInspectableWebContentsViewMac:
|
||||
|
@ -49,9 +37,6 @@
|
|||
[self addSubview:contentsView];
|
||||
}
|
||||
|
||||
// This will float above devtools to exclude it from dragging.
|
||||
devtools_mask_.reset([[ControlRegionView alloc] initWithFrame:NSZeroRect]);
|
||||
|
||||
// See https://code.google.com/p/chromium/issues/detail?id=348490.
|
||||
[self setWantsLayer:YES];
|
||||
|
||||
|
@ -116,12 +101,6 @@
|
|||
devtools_visible_ = visible;
|
||||
if (devtools_docked_) {
|
||||
if (visible) {
|
||||
// The devToolsView is placed under the contentsView, so it has to be
|
||||
// draggable to make draggable region of contentsView work.
|
||||
[devToolsView setMouseDownCanMoveWindow:YES];
|
||||
// This view will exclude the actual devtools part from dragging.
|
||||
[self addSubview:devtools_mask_.get()];
|
||||
|
||||
// Place the devToolsView under contentsView, notice that we didn't set
|
||||
// sizes for them until the setContentsResizingStrategy message.
|
||||
[self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
|
||||
|
@ -132,7 +111,6 @@
|
|||
} else {
|
||||
gfx::ScopedCocoaDisableScreenUpdates disabler;
|
||||
[devToolsView removeFromSuperview];
|
||||
[devtools_mask_ removeFromSuperview];
|
||||
[self adjustSubviews];
|
||||
[self notifyDevToolsResized];
|
||||
}
|
||||
|
@ -225,7 +203,7 @@
|
|||
NSView* devToolsView = [[self subviews] objectAtIndex:0];
|
||||
NSView* contentsView = [[self subviews] objectAtIndex:1];
|
||||
|
||||
DCHECK_EQ(3u, [[self subviews] count]);
|
||||
DCHECK_EQ(2u, [[self subviews] count]);
|
||||
|
||||
gfx::Rect new_devtools_bounds;
|
||||
gfx::Rect new_contents_bounds;
|
||||
|
@ -253,7 +231,6 @@
|
|||
devtools_frame.size.width = sb.size.width - cf.size.width;
|
||||
devtools_frame.size.height = sb.size.height;
|
||||
}
|
||||
[devtools_mask_ setFrame:devtools_frame];
|
||||
|
||||
[self notifyDevToolsResized];
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ int FramelessView::NonClientHitTest(const gfx::Point& cursor) {
|
|||
|
||||
// Check for possible draggable region in the client area for the frameless
|
||||
// window.
|
||||
SkRegion* draggable_region = window_->draggable_region();
|
||||
const SkRegion* draggable_region = window_->draggable_region();
|
||||
if (draggable_region && draggable_region->contains(cursor.x(), cursor.y()))
|
||||
return HTCAPTION;
|
||||
|
||||
|
|
|
@ -897,28 +897,6 @@ describe('webContents module', () => {
|
|||
w.webContents.focus();
|
||||
await expect(focusPromise).to.eventually.be.fulfilled();
|
||||
});
|
||||
|
||||
it('is triggered when BrowserWindow is focused', async () => {
|
||||
const window1 = new BrowserWindow({ show: false });
|
||||
const window2 = new BrowserWindow({ show: false });
|
||||
|
||||
await Promise.all([
|
||||
window1.loadURL('about:blank'),
|
||||
window2.loadURL('about:blank')
|
||||
]);
|
||||
|
||||
const focusPromise1 = emittedOnce(window1.webContents, 'focus');
|
||||
const focusPromise2 = emittedOnce(window2.webContents, 'focus');
|
||||
|
||||
window1.showInactive();
|
||||
window2.showInactive();
|
||||
|
||||
window1.focus();
|
||||
await expect(focusPromise1).to.eventually.be.fulfilled();
|
||||
|
||||
window2.focus();
|
||||
await expect(focusPromise2).to.eventually.be.fulfilled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('blur event', () => {
|
||||
|
|
Loading…
Reference in a new issue