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
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue