refactor: move draggable regions to WebContents (#36230)
This commit is contained in:
parent
2008c9a5d0
commit
184ac2b382
22 changed files with 96 additions and 202 deletions
|
@ -358,6 +358,7 @@ filenames = {
|
||||||
"shell/browser/child_web_contents_tracker.h",
|
"shell/browser/child_web_contents_tracker.h",
|
||||||
"shell/browser/cookie_change_notifier.cc",
|
"shell/browser/cookie_change_notifier.cc",
|
||||||
"shell/browser/cookie_change_notifier.h",
|
"shell/browser/cookie_change_notifier.h",
|
||||||
|
"shell/browser/draggable_region_provider.h",
|
||||||
"shell/browser/electron_api_ipc_handler_impl.cc",
|
"shell/browser/electron_api_ipc_handler_impl.cc",
|
||||||
"shell/browser/electron_api_ipc_handler_impl.h",
|
"shell/browser/electron_api_ipc_handler_impl.h",
|
||||||
"shell/browser/electron_autofill_driver.cc",
|
"shell/browser/electron_autofill_driver.cc",
|
||||||
|
|
|
@ -766,6 +766,7 @@ void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
window_->AddBrowserView(browser_view->view());
|
window_->AddBrowserView(browser_view->view());
|
||||||
|
window_->AddDraggableRegionProvider(browser_view.get());
|
||||||
browser_view->SetOwnerWindow(this);
|
browser_view->SetOwnerWindow(this);
|
||||||
browser_views_[browser_view->ID()].Reset(isolate(), browser_view.ToV8());
|
browser_views_[browser_view->ID()].Reset(isolate(), browser_view.ToV8());
|
||||||
}
|
}
|
||||||
|
@ -775,6 +776,7 @@ void BaseWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
|
||||||
auto iter = browser_views_.find(browser_view->ID());
|
auto iter = browser_views_.find(browser_view->ID());
|
||||||
if (iter != browser_views_.end()) {
|
if (iter != browser_views_.end()) {
|
||||||
window_->RemoveBrowserView(browser_view->view());
|
window_->RemoveBrowserView(browser_view->view());
|
||||||
|
window_->RemoveDraggableRegionProvider(browser_view.get());
|
||||||
browser_view->SetOwnerWindow(nullptr);
|
browser_view->SetOwnerWindow(nullptr);
|
||||||
iter->second.Reset();
|
iter->second.Reset();
|
||||||
browser_views_.erase(iter);
|
browser_views_.erase(iter);
|
||||||
|
@ -1124,6 +1126,7 @@ void BaseWindow::ResetBrowserViews() {
|
||||||
DCHECK_EQ(owner_window, this);
|
DCHECK_EQ(owner_window, this);
|
||||||
browser_view->SetOwnerWindow(nullptr);
|
browser_view->SetOwnerWindow(nullptr);
|
||||||
window_->RemoveBrowserView(browser_view->view());
|
window_->RemoveBrowserView(browser_view->view());
|
||||||
|
window_->RemoveDraggableRegionProvider(browser_view.get());
|
||||||
browser_view->SetOwnerWindow(nullptr);
|
browser_view->SetOwnerWindow(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "shell/common/gin_helper/object_template_builder.h"
|
#include "shell/common/gin_helper/object_template_builder.h"
|
||||||
#include "shell/common/node_includes.h"
|
#include "shell/common/node_includes.h"
|
||||||
#include "shell/common/options_switches.h"
|
#include "shell/common/options_switches.h"
|
||||||
|
#include "ui/base/hit_test.h"
|
||||||
#include "ui/gfx/geometry/rect.h"
|
#include "ui/gfx/geometry/rect.h"
|
||||||
|
|
||||||
namespace gin {
|
namespace gin {
|
||||||
|
@ -105,16 +106,16 @@ void BrowserView::SetOwnerWindow(BaseWindow* window) {
|
||||||
if (web_contents())
|
if (web_contents())
|
||||||
web_contents()->SetOwnerWindow(window ? window->window() : nullptr);
|
web_contents()->SetOwnerWindow(window ? window->window() : nullptr);
|
||||||
|
|
||||||
if (owner_window_.get()) {
|
owner_window_ = window ? window->GetWeakPtr() : nullptr;
|
||||||
owner_window_->window()->remove_inspectable_view(
|
|
||||||
view_->GetInspectableWebContentsView());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
owner_window_ = window ? window->GetWeakPtr() : nullptr;
|
int BrowserView::NonClientHitTest(const gfx::Point& point) {
|
||||||
|
gfx::Rect bounds = GetBounds();
|
||||||
if (owner_window_.get() && view_->GetInspectableWebContentsView())
|
gfx::Point local_point(point.x() - bounds.x(), point.y() - bounds.y());
|
||||||
owner_window_->window()->add_inspectable_view(
|
SkRegion* region = api_web_contents_->draggable_region();
|
||||||
view_->GetInspectableWebContentsView());
|
if (region && region->contains(local_point.x(), local_point.y()))
|
||||||
|
return HTCAPTION;
|
||||||
|
return HTNOWHERE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowserView::~BrowserView() {
|
BrowserView::~BrowserView() {
|
||||||
|
@ -130,14 +131,6 @@ void BrowserView::WebContentsDestroyed() {
|
||||||
Unpin();
|
Unpin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserView::OnDraggableRegionsUpdated(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
|
||||||
InspectableWebContentsView* iwc_view = view_->GetInspectableWebContentsView();
|
|
||||||
if (!iwc_view)
|
|
||||||
return;
|
|
||||||
iwc_view->UpdateDraggableRegions(regions);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
gin::Handle<BrowserView> BrowserView::New(gin_helper::ErrorThrower thrower,
|
gin::Handle<BrowserView> BrowserView::New(gin_helper::ErrorThrower thrower,
|
||||||
gin::Arguments* args) {
|
gin::Arguments* args) {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
#include "content/public/browser/web_contents_observer.h"
|
||||||
#include "gin/handle.h"
|
#include "gin/handle.h"
|
||||||
#include "gin/wrappable.h"
|
#include "gin/wrappable.h"
|
||||||
|
#include "shell/browser/draggable_region_provider.h"
|
||||||
#include "shell/browser/extended_web_contents_observer.h"
|
#include "shell/browser/extended_web_contents_observer.h"
|
||||||
#include "shell/browser/native_browser_view.h"
|
#include "shell/browser/native_browser_view.h"
|
||||||
#include "shell/browser/native_window.h"
|
#include "shell/browser/native_window.h"
|
||||||
|
@ -37,7 +38,8 @@ class BrowserView : public gin::Wrappable<BrowserView>,
|
||||||
public gin_helper::Constructible<BrowserView>,
|
public gin_helper::Constructible<BrowserView>,
|
||||||
public gin_helper::Pinnable<BrowserView>,
|
public gin_helper::Pinnable<BrowserView>,
|
||||||
public content::WebContentsObserver,
|
public content::WebContentsObserver,
|
||||||
public ExtendedWebContentsObserver {
|
public ExtendedWebContentsObserver,
|
||||||
|
public DraggableRegionProvider {
|
||||||
public:
|
public:
|
||||||
// gin_helper::Constructible
|
// gin_helper::Constructible
|
||||||
static gin::Handle<BrowserView> New(gin_helper::ErrorThrower thrower,
|
static gin::Handle<BrowserView> New(gin_helper::ErrorThrower thrower,
|
||||||
|
@ -58,6 +60,8 @@ class BrowserView : public gin::Wrappable<BrowserView>,
|
||||||
|
|
||||||
int32_t ID() const { return id_; }
|
int32_t ID() const { return id_; }
|
||||||
|
|
||||||
|
int NonClientHitTest(const gfx::Point& point) override;
|
||||||
|
|
||||||
// disable copy
|
// disable copy
|
||||||
BrowserView(const BrowserView&) = delete;
|
BrowserView(const BrowserView&) = delete;
|
||||||
BrowserView& operator=(const BrowserView&) = delete;
|
BrowserView& operator=(const BrowserView&) = delete;
|
||||||
|
@ -69,10 +73,6 @@ class BrowserView : public gin::Wrappable<BrowserView>,
|
||||||
// content::WebContentsObserver:
|
// content::WebContentsObserver:
|
||||||
void WebContentsDestroyed() override;
|
void WebContentsDestroyed() override;
|
||||||
|
|
||||||
// ExtendedWebContentsObserver:
|
|
||||||
void OnDraggableRegionsUpdated(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetAutoResize(AutoResizeFlags flags);
|
void SetAutoResize(AutoResizeFlags flags);
|
||||||
void SetBounds(const gfx::Rect& bounds);
|
void SetBounds(const gfx::Rect& bounds);
|
||||||
|
|
|
@ -83,6 +83,7 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||||
gin::Handle<WebContentsView> web_contents_view =
|
gin::Handle<WebContentsView> web_contents_view =
|
||||||
WebContentsView::Create(isolate, web_preferences);
|
WebContentsView::Create(isolate, web_preferences);
|
||||||
DCHECK(web_contents_view.get());
|
DCHECK(web_contents_view.get());
|
||||||
|
window_->AddDraggableRegionProvider(web_contents_view.get());
|
||||||
|
|
||||||
// Save a reference of the WebContents.
|
// Save a reference of the WebContents.
|
||||||
gin::Handle<WebContents> web_contents =
|
gin::Handle<WebContents> web_contents =
|
||||||
|
@ -146,14 +147,6 @@ void BrowserWindow::OnRendererResponsive(content::RenderProcessHost*) {
|
||||||
Emit("responsive");
|
Emit("responsive");
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindow::OnDraggableRegionsUpdated(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
|
||||||
if (window_->has_frame())
|
|
||||||
return;
|
|
||||||
|
|
||||||
window_->UpdateDraggableRegions(regions);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowserWindow::OnSetContentBounds(const gfx::Rect& rect) {
|
void BrowserWindow::OnSetContentBounds(const gfx::Rect& rect) {
|
||||||
// window.resizeTo(...)
|
// window.resizeTo(...)
|
||||||
// window.moveTo(...)
|
// window.moveTo(...)
|
||||||
|
@ -204,8 +197,8 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
|
||||||
api_web_contents_->NotifyUserActivation();
|
api_web_contents_->NotifyUserActivation();
|
||||||
|
|
||||||
// Trigger beforeunload events for associated BrowserViews.
|
// Trigger beforeunload events for associated BrowserViews.
|
||||||
for (InspectableWebContentsView* view : window_->inspectable_views()) {
|
for (NativeBrowserView* view : window_->browser_views()) {
|
||||||
auto* vwc = view->inspectable_web_contents()->GetWebContents();
|
auto* vwc = view->GetInspectableWebContents()->GetWebContents();
|
||||||
auto* api_web_contents = api::WebContents::From(vwc);
|
auto* api_web_contents = api::WebContents::From(vwc);
|
||||||
|
|
||||||
// Required to make beforeunload handler work.
|
// Required to make beforeunload handler work.
|
||||||
|
|
|
@ -51,8 +51,6 @@ class BrowserWindow : public BaseWindow,
|
||||||
|
|
||||||
// ExtendedWebContentsObserver:
|
// ExtendedWebContentsObserver:
|
||||||
void OnCloseContents() override;
|
void OnCloseContents() override;
|
||||||
void OnDraggableRegionsUpdated(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) override;
|
|
||||||
void OnSetContentBounds(const gfx::Rect& rect) override;
|
void OnSetContentBounds(const gfx::Rect& rect) override;
|
||||||
void OnActivateContents() override;
|
void OnActivateContents() override;
|
||||||
void OnPageTitleUpdated(const std::u16string& title,
|
void OnPageTitleUpdated(const std::u16string& title,
|
||||||
|
@ -90,10 +88,6 @@ class BrowserWindow : public BaseWindow,
|
||||||
private:
|
private:
|
||||||
// Helpers.
|
// Helpers.
|
||||||
|
|
||||||
// Called when the window needs to update its draggable region.
|
|
||||||
void UpdateDraggableRegions(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions);
|
|
||||||
|
|
||||||
// Schedule a notification unresponsive event.
|
// Schedule a notification unresponsive event.
|
||||||
void ScheduleUnresponsiveEvent(int ms);
|
void ScheduleUnresponsiveEvent(int ms);
|
||||||
|
|
||||||
|
|
|
@ -1875,8 +1875,7 @@ void WebContents::MessageHost(const std::string& channel,
|
||||||
|
|
||||||
void WebContents::UpdateDraggableRegions(
|
void WebContents::UpdateDraggableRegions(
|
||||||
std::vector<mojom::DraggableRegionPtr> regions) {
|
std::vector<mojom::DraggableRegionPtr> regions) {
|
||||||
for (ExtendedWebContentsObserver& observer : observers_)
|
draggable_region_ = DraggableRegionsToSkRegion(regions);
|
||||||
observer.OnDraggableRegionsUpdated(regions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::DidStartNavigation(
|
void WebContents::DidStartNavigation(
|
||||||
|
|
|
@ -77,6 +77,8 @@ class Arguments;
|
||||||
|
|
||||||
class ExclusiveAccessManager;
|
class ExclusiveAccessManager;
|
||||||
|
|
||||||
|
class SkRegion;
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
class ElectronBrowserContext;
|
class ElectronBrowserContext;
|
||||||
|
@ -438,6 +440,8 @@ class WebContents : public ExclusiveAccessContext,
|
||||||
// content::RenderWidgetHost::InputEventObserver:
|
// content::RenderWidgetHost::InputEventObserver:
|
||||||
void OnInputEvent(const blink::WebInputEvent& event) override;
|
void OnInputEvent(const blink::WebInputEvent& event) override;
|
||||||
|
|
||||||
|
SkRegion* draggable_region() { return draggable_region_.get(); }
|
||||||
|
|
||||||
// disable copy
|
// disable copy
|
||||||
WebContents(const WebContents&) = delete;
|
WebContents(const WebContents&) = delete;
|
||||||
WebContents& operator=(const WebContents&) = delete;
|
WebContents& operator=(const WebContents&) = delete;
|
||||||
|
@ -819,6 +823,8 @@ class WebContents : public ExclusiveAccessContext,
|
||||||
// Stores the frame thats currently in fullscreen, nullptr if there is none.
|
// Stores the frame thats currently in fullscreen, nullptr if there is none.
|
||||||
content::RenderFrameHost* fullscreen_frame_ = nullptr;
|
content::RenderFrameHost* fullscreen_frame_ = nullptr;
|
||||||
|
|
||||||
|
std::unique_ptr<SkRegion> draggable_region_;
|
||||||
|
|
||||||
base::WeakPtrFactory<WebContents> weak_factory_{this};
|
base::WeakPtrFactory<WebContents> weak_factory_{this};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "shell/common/gin_helper/dictionary.h"
|
#include "shell/common/gin_helper/dictionary.h"
|
||||||
#include "shell/common/gin_helper/object_template_builder.h"
|
#include "shell/common/gin_helper/object_template_builder.h"
|
||||||
#include "shell/common/node_includes.h"
|
#include "shell/common/node_includes.h"
|
||||||
|
#include "third_party/skia/include/core/SkRegion.h"
|
||||||
|
#include "ui/base/hit_test.h"
|
||||||
|
|
||||||
#if BUILDFLAG(IS_MAC)
|
#if BUILDFLAG(IS_MAC)
|
||||||
#include "shell/browser/ui/cocoa/delayed_native_view_host.h"
|
#include "shell/browser/ui/cocoa/delayed_native_view_host.h"
|
||||||
|
@ -50,6 +52,15 @@ gin::Handle<WebContents> WebContentsView::GetWebContents(v8::Isolate* isolate) {
|
||||||
return gin::CreateHandle(isolate, api_web_contents_);
|
return gin::CreateHandle(isolate, api_web_contents_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WebContentsView::NonClientHitTest(const gfx::Point& point) {
|
||||||
|
gfx::Point local_point(point);
|
||||||
|
views::View::ConvertPointFromWidget(view(), &local_point);
|
||||||
|
SkRegion* region = api_web_contents_->draggable_region();
|
||||||
|
if (region && region->contains(local_point.x(), local_point.y()))
|
||||||
|
return HTCAPTION;
|
||||||
|
return HTNOWHERE;
|
||||||
|
}
|
||||||
|
|
||||||
void WebContentsView::WebContentsDestroyed() {
|
void WebContentsView::WebContentsDestroyed() {
|
||||||
api_web_contents_ = nullptr;
|
api_web_contents_ = nullptr;
|
||||||
web_contents_.Reset();
|
web_contents_.Reset();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "content/public/browser/web_contents_observer.h"
|
#include "content/public/browser/web_contents_observer.h"
|
||||||
#include "shell/browser/api/electron_api_view.h"
|
#include "shell/browser/api/electron_api_view.h"
|
||||||
|
#include "shell/browser/draggable_region_provider.h"
|
||||||
|
|
||||||
namespace gin_helper {
|
namespace gin_helper {
|
||||||
class Dictionary;
|
class Dictionary;
|
||||||
|
@ -16,7 +17,9 @@ namespace electron::api {
|
||||||
|
|
||||||
class WebContents;
|
class WebContents;
|
||||||
|
|
||||||
class WebContentsView : public View, public content::WebContentsObserver {
|
class WebContentsView : public View,
|
||||||
|
public content::WebContentsObserver,
|
||||||
|
public DraggableRegionProvider {
|
||||||
public:
|
public:
|
||||||
// Create a new instance of WebContentsView.
|
// Create a new instance of WebContentsView.
|
||||||
static gin::Handle<WebContentsView> Create(
|
static gin::Handle<WebContentsView> Create(
|
||||||
|
@ -33,6 +36,8 @@ class WebContentsView : public View, public content::WebContentsObserver {
|
||||||
// Public APIs.
|
// Public APIs.
|
||||||
gin::Handle<WebContents> GetWebContents(v8::Isolate* isolate);
|
gin::Handle<WebContents> GetWebContents(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
int NonClientHitTest(const gfx::Point& point) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Takes an existing WebContents.
|
// Takes an existing WebContents.
|
||||||
WebContentsView(v8::Isolate* isolate, gin::Handle<WebContents> web_contents);
|
WebContentsView(v8::Isolate* isolate, gin::Handle<WebContents> web_contents);
|
||||||
|
|
13
shell/browser/draggable_region_provider.h
Normal file
13
shell/browser/draggable_region_provider.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright (c) 2022 Salesforce, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef ELECTRON_SHELL_BROWSER_DRAGGABLE_REGION_PROVIDER_H_
|
||||||
|
#define ELECTRON_SHELL_BROWSER_DRAGGABLE_REGION_PROVIDER_H_
|
||||||
|
|
||||||
|
class DraggableRegionProvider {
|
||||||
|
public:
|
||||||
|
virtual int NonClientHitTest(const gfx::Point& point) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ELECTRON_SHELL_BROWSER_DRAGGABLE_REGION_PROVIDER_H_
|
|
@ -73,9 +73,6 @@ void NativeBrowserViewMac::SetBounds(const gfx::Rect& bounds) {
|
||||||
superview_height - bounds.y() - bounds.height() + titlebar_height;
|
superview_height - bounds.y() - bounds.height() + titlebar_height;
|
||||||
view.frame =
|
view.frame =
|
||||||
NSMakeRect(bounds.x(), new_height, bounds.width(), bounds.height());
|
NSMakeRect(bounds.x(), new_height, bounds.width(), bounds.height());
|
||||||
|
|
||||||
// Ensure draggable regions are properly updated to reflect new bounds.
|
|
||||||
iwc_view->UpdateDraggableRegions(iwc_view->GetDraggableRegions());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Rect NativeBrowserViewMac::GetBounds() {
|
gfx::Rect NativeBrowserViewMac::GetBounds() {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "shell/common/gin_helper/persistent_dictionary.h"
|
#include "shell/common/gin_helper/persistent_dictionary.h"
|
||||||
#include "shell/common/options_switches.h"
|
#include "shell/common/options_switches.h"
|
||||||
#include "third_party/skia/include/core/SkRegion.h"
|
#include "third_party/skia/include/core/SkRegion.h"
|
||||||
|
#include "ui/base/hit_test.h"
|
||||||
#include "ui/views/widget/widget.h"
|
#include "ui/views/widget/widget.h"
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
|
@ -685,9 +686,28 @@ void NativeWindow::NotifyWindowMessage(UINT message,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void NativeWindow::UpdateDraggableRegions(
|
int NativeWindow::NonClientHitTest(const gfx::Point& point) {
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
for (auto* provider : draggable_region_providers_) {
|
||||||
draggable_region_ = DraggableRegionsToSkRegion(regions);
|
int hit = provider->NonClientHitTest(point);
|
||||||
|
if (hit != HTNOWHERE)
|
||||||
|
return hit;
|
||||||
|
}
|
||||||
|
return HTNOWHERE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindow::AddDraggableRegionProvider(
|
||||||
|
DraggableRegionProvider* provider) {
|
||||||
|
if (std::find(draggable_region_providers_.begin(),
|
||||||
|
draggable_region_providers_.end(),
|
||||||
|
provider) == draggable_region_providers_.end()) {
|
||||||
|
draggable_region_providers_.push_back(provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeWindow::RemoveDraggableRegionProvider(
|
||||||
|
DraggableRegionProvider* provider) {
|
||||||
|
draggable_region_providers_.remove_if(
|
||||||
|
[&provider](DraggableRegionProvider* p) { return p == provider; });
|
||||||
}
|
}
|
||||||
|
|
||||||
views::Widget* NativeWindow::GetWidget() {
|
views::Widget* NativeWindow::GetWidget() {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "content/public/browser/desktop_media_id.h"
|
#include "content/public/browser/desktop_media_id.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 "shell/browser/draggable_region_provider.h"
|
||||||
#include "shell/browser/native_window_observer.h"
|
#include "shell/browser/native_window_observer.h"
|
||||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||||
#include "shell/common/api/api.mojom.h"
|
#include "shell/common/api/api.mojom.h"
|
||||||
|
@ -351,11 +352,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
return fullscreen_transition_type_;
|
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::Widget* widget() const { return widget_.get(); }
|
||||||
views::View* content_view() const { return content_view_; }
|
views::View* content_view() const { return content_view_; }
|
||||||
|
|
||||||
|
@ -384,12 +380,12 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
|
|
||||||
std::list<NativeBrowserView*> browser_views() const { return browser_views_; }
|
std::list<NativeBrowserView*> browser_views() const { return browser_views_; }
|
||||||
|
|
||||||
std::list<InspectableWebContentsView*> inspectable_views() const {
|
|
||||||
return inspectable_views_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t window_id() const { return next_id_; }
|
int32_t window_id() const { return next_id_; }
|
||||||
|
|
||||||
|
int NonClientHitTest(const gfx::Point& point);
|
||||||
|
void AddDraggableRegionProvider(DraggableRegionProvider* provider);
|
||||||
|
void RemoveDraggableRegionProvider(DraggableRegionProvider* provider);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class api::BrowserView;
|
friend class api::BrowserView;
|
||||||
|
|
||||||
|
@ -410,16 +406,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
[&browser_view](NativeBrowserView* n) { return (n == browser_view); });
|
[&browser_view](NativeBrowserView* n) { return (n == browser_view); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_inspectable_view(InspectableWebContentsView* inspectable_view) {
|
|
||||||
inspectable_views_.push_back(inspectable_view);
|
|
||||||
}
|
|
||||||
void remove_inspectable_view(InspectableWebContentsView* inspectable_view) {
|
|
||||||
inspectable_views_.remove_if(
|
|
||||||
[&inspectable_view](InspectableWebContentsView* n) {
|
|
||||||
return (n == inspectable_view);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// The boolean parsing of the "titleBarOverlay" option
|
// The boolean parsing of the "titleBarOverlay" option
|
||||||
bool titlebar_overlay_ = false;
|
bool titlebar_overlay_ = false;
|
||||||
|
|
||||||
|
@ -483,8 +469,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
// The browser view layer.
|
// The browser view layer.
|
||||||
std::list<NativeBrowserView*> browser_views_;
|
std::list<NativeBrowserView*> browser_views_;
|
||||||
|
|
||||||
// The inspectable webContents views.
|
std::list<DraggableRegionProvider*> draggable_region_providers_;
|
||||||
std::list<InspectableWebContentsView*> inspectable_views_;
|
|
||||||
|
|
||||||
// Observers of this window.
|
// Observers of this window.
|
||||||
base::ObserverList<NativeWindowObserver> observers_;
|
base::ObserverList<NativeWindowObserver> observers_;
|
||||||
|
@ -494,10 +479,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
|
|
||||||
gfx::Rect overlay_rect_;
|
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};
|
base::WeakPtrFactory<NativeWindow> weak_factory_{this};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1664,9 +1664,9 @@ class NativeAppWindowFrameViewMac : public views::NativeFrameViewMac {
|
||||||
|
|
||||||
// Check for possible draggable region in the client area for the frameless
|
// Check for possible draggable region in the client area for the frameless
|
||||||
// window.
|
// window.
|
||||||
SkRegion const* draggable_region = native_window_->draggable_region();
|
int contents_hit_test = native_window_->NonClientHitTest(point);
|
||||||
if (draggable_region && draggable_region->contains(point.x(), point.y()))
|
if (contents_hit_test != HTNOWHERE)
|
||||||
return HTCAPTION;
|
return contents_hit_test;
|
||||||
|
|
||||||
return HTCLIENT;
|
return HTCLIENT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1594,17 +1594,7 @@ bool NativeWindowViews::ShouldDescendIntoChildForEventHandling(
|
||||||
const gfx::Point& location) {
|
const gfx::Point& location) {
|
||||||
// App window should claim mouse events that fall within any BrowserViews'
|
// App window should claim mouse events that fall within any BrowserViews'
|
||||||
// draggable region.
|
// draggable region.
|
||||||
for (auto* view : inspectable_views()) {
|
if (NonClientHitTest(location) != HTNOWHERE)
|
||||||
auto* inspectable_view =
|
|
||||||
static_cast<InspectableWebContentsViewViews*>(view);
|
|
||||||
if (inspectable_view->IsContainedInDraggableRegion(content_view(),
|
|
||||||
location))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// App window should claim mouse events that fall within the draggable region.
|
|
||||||
if (draggable_region() &&
|
|
||||||
draggable_region()->contains(location.x(), location.y()))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// And the events on border for dragging resizable frameless window.
|
// And the events on border for dragging resizable frameless window.
|
||||||
|
|
|
@ -41,10 +41,6 @@ class InspectableWebContentsView {
|
||||||
}
|
}
|
||||||
InspectableWebContentsViewDelegate* GetDelegate() const { return delegate_; }
|
InspectableWebContentsViewDelegate* GetDelegate() const { return delegate_; }
|
||||||
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& GetDraggableRegions() const {
|
|
||||||
return draggable_regions_;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC)
|
#if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC)
|
||||||
// Returns the container control, which has devtools view attached.
|
// Returns the container control, which has devtools view attached.
|
||||||
virtual views::View* GetView() = 0;
|
virtual views::View* GetView() = 0;
|
||||||
|
@ -66,16 +62,10 @@ class InspectableWebContentsView {
|
||||||
const DevToolsContentsResizingStrategy& strategy) = 0;
|
const DevToolsContentsResizingStrategy& strategy) = 0;
|
||||||
virtual void SetTitle(const std::u16string& title) = 0;
|
virtual void SetTitle(const std::u16string& title) = 0;
|
||||||
|
|
||||||
// Called when the window needs to update its draggable region.
|
|
||||||
virtual void UpdateDraggableRegions(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Owns us.
|
// Owns us.
|
||||||
InspectableWebContents* inspectable_web_contents_;
|
InspectableWebContents* inspectable_web_contents_;
|
||||||
|
|
||||||
std::vector<mojom::DraggableRegionPtr> draggable_regions_;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InspectableWebContentsViewDelegate* delegate_ = nullptr; // weak references.
|
InspectableWebContentsViewDelegate* delegate_ = nullptr; // weak references.
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,8 +34,6 @@ class InspectableWebContentsViewMac : public InspectableWebContentsView {
|
||||||
void SetContentsResizingStrategy(
|
void SetContentsResizingStrategy(
|
||||||
const DevToolsContentsResizingStrategy& strategy) override;
|
const DevToolsContentsResizingStrategy& strategy) override;
|
||||||
void SetTitle(const std::u16string& title) override;
|
void SetTitle(const std::u16string& title) override;
|
||||||
void UpdateDraggableRegions(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
base::scoped_nsobject<ElectronInspectableWebContentsView> view_;
|
base::scoped_nsobject<ElectronInspectableWebContentsView> view_;
|
||||||
|
|
|
@ -267,65 +267,4 @@ void InspectableWebContentsViewMac::SetTitle(const std::u16string& title) {
|
||||||
[view_ setTitle:base::SysUTF16ToNSString(title)];
|
[view_ setTitle:base::SysUTF16ToNSString(title)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectableWebContentsViewMac::UpdateDraggableRegions(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
|
||||||
auto* web_contents = inspectable_web_contents()->GetWebContents();
|
|
||||||
NSView* web_view = web_contents->GetNativeView().GetNativeNSView();
|
|
||||||
NSView* inspectable_view = GetNativeView().GetNativeNSView();
|
|
||||||
NSView* inspectable_superview = inspectable_view.superview;
|
|
||||||
|
|
||||||
NSInteger webViewWidth = NSWidth([web_view bounds]);
|
|
||||||
NSInteger webViewHeight = NSHeight([web_view bounds]);
|
|
||||||
|
|
||||||
// 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 (draggable_regions_.empty()) {
|
|
||||||
drag_exclude_rects.emplace_back(0, 0, webViewWidth, webViewHeight);
|
|
||||||
} else {
|
|
||||||
drag_exclude_rects = CalculateNonDraggableRegions(
|
|
||||||
DraggableRegionsToSkRegion(draggable_regions_), webViewWidth,
|
|
||||||
webViewHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove all DragRegionViews that were added last time. Note that we need
|
|
||||||
// to copy the `subviews` array to avoid mutation during iteration.
|
|
||||||
base::scoped_nsobject<NSArray> subviews([[web_view subviews] copy]);
|
|
||||||
for (NSView* subview in subviews.get()) {
|
|
||||||
if ([subview isKindOfClass:[DragRegionView class]])
|
|
||||||
[subview removeFromSuperview];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create one giant NSView that is draggable.
|
|
||||||
base::scoped_nsobject<NSView> drag_region_view(
|
|
||||||
[[DragRegionView alloc] initWithFrame:web_view.bounds]);
|
|
||||||
[web_view addSubview:drag_region_view];
|
|
||||||
|
|
||||||
// Then, on top of that, add "exclusion zones".
|
|
||||||
const int superview_height =
|
|
||||||
(inspectable_superview) ? inspectable_superview.frame.size.height : 0;
|
|
||||||
if (!inspectable_superview)
|
|
||||||
inspectable_superview = inspectable_view;
|
|
||||||
const int offset_x = inspectable_view.frame.origin.x;
|
|
||||||
const int offset_y = superview_height - inspectable_view.frame.origin.y -
|
|
||||||
inspectable_view.frame.size.height;
|
|
||||||
for (const auto& rect : drag_exclude_rects) {
|
|
||||||
const auto x = rect.x() + offset_x;
|
|
||||||
const auto y = superview_height - (rect.bottom() + offset_y);
|
|
||||||
const auto exclude_rect = NSMakeRect(x, y, rect.width(), rect.height());
|
|
||||||
|
|
||||||
const auto drag_region_view_exclude_rect =
|
|
||||||
[inspectable_superview convertRect:exclude_rect
|
|
||||||
toView:drag_region_view];
|
|
||||||
|
|
||||||
base::scoped_nsobject<NSView> exclude_drag_region_view(
|
|
||||||
[[ExcludeDragRegionView alloc]
|
|
||||||
initWithFrame:drag_region_view_exclude_rect]);
|
|
||||||
[drag_region_view addSubview:exclude_drag_region_view];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -76,30 +76,19 @@ gfx::Rect FramelessView::GetWindowBoundsForClientBounds(
|
||||||
return window_bounds;
|
return window_bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FramelessView::NonClientHitTest(const gfx::Point& cursor) {
|
int FramelessView::NonClientHitTest(const gfx::Point& point) {
|
||||||
if (frame_->IsFullscreen())
|
if (frame_->IsFullscreen())
|
||||||
return HTCLIENT;
|
return HTCLIENT;
|
||||||
|
|
||||||
// Check attached BrowserViews for potential draggable areas.
|
int contents_hit_test = window_->NonClientHitTest(point);
|
||||||
for (auto* view : window_->inspectable_views()) {
|
if (contents_hit_test != HTNOWHERE)
|
||||||
auto* inspectable_view =
|
return contents_hit_test;
|
||||||
static_cast<InspectableWebContentsViewViews*>(view);
|
|
||||||
if (inspectable_view->IsContainedInDraggableRegion(window_->content_view(),
|
|
||||||
cursor))
|
|
||||||
return HTCAPTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support resizing frameless window by dragging the border.
|
// Support resizing frameless window by dragging the border.
|
||||||
int frame_component = ResizingBorderHitTest(cursor);
|
int frame_component = ResizingBorderHitTest(point);
|
||||||
if (frame_component != HTNOWHERE)
|
if (frame_component != HTNOWHERE)
|
||||||
return frame_component;
|
return frame_component;
|
||||||
|
|
||||||
// Check for possible draggable region in the client area for the frameless
|
|
||||||
// window.
|
|
||||||
const SkRegion* draggable_region = window_->draggable_region();
|
|
||||||
if (draggable_region && draggable_region->contains(cursor.x(), cursor.y()))
|
|
||||||
return HTCAPTION;
|
|
||||||
|
|
||||||
return HTCLIENT;
|
return HTCLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,19 +105,6 @@ InspectableWebContentsViewViews::~InspectableWebContentsViewViews() {
|
||||||
devtools_window_->GetWindowBoundsInScreen());
|
devtools_window_->GetWindowBoundsInScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InspectableWebContentsViewViews::IsContainedInDraggableRegion(
|
|
||||||
views::View* root_view,
|
|
||||||
const gfx::Point& location) {
|
|
||||||
if (!draggable_region_.get())
|
|
||||||
return false;
|
|
||||||
// Draggable regions are defined relative to the web contents.
|
|
||||||
gfx::Point point_in_contents_web_view_coords(location);
|
|
||||||
views::View::ConvertPointToTarget(root_view, this,
|
|
||||||
&point_in_contents_web_view_coords);
|
|
||||||
return draggable_region_->contains(point_in_contents_web_view_coords.x(),
|
|
||||||
point_in_contents_web_view_coords.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
views::View* InspectableWebContentsViewViews::GetView() {
|
views::View* InspectableWebContentsViewViews::GetView() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -227,14 +214,6 @@ void InspectableWebContentsViewViews::SetTitle(const std::u16string& title) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectableWebContentsViewViews::UpdateDraggableRegions(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
|
||||||
if (&draggable_regions_ == ®ions)
|
|
||||||
return;
|
|
||||||
draggable_regions_ = mojo::Clone(regions);
|
|
||||||
draggable_region_ = DraggableRegionsToSkRegion(draggable_regions_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InspectableWebContentsViewViews::Layout() {
|
void InspectableWebContentsViewViews::Layout() {
|
||||||
if (!devtools_web_view_->GetVisible()) {
|
if (!devtools_web_view_->GetVisible()) {
|
||||||
contents_web_view_->SetBoundsRect(GetContentsBounds());
|
contents_web_view_->SetBoundsRect(GetContentsBounds());
|
||||||
|
|
|
@ -29,9 +29,6 @@ class InspectableWebContentsViewViews : public InspectableWebContentsView,
|
||||||
InspectableWebContents* inspectable_web_contents);
|
InspectableWebContents* inspectable_web_contents);
|
||||||
~InspectableWebContentsViewViews() override;
|
~InspectableWebContentsViewViews() override;
|
||||||
|
|
||||||
bool IsContainedInDraggableRegion(views::View* root_view,
|
|
||||||
const gfx::Point& location);
|
|
||||||
|
|
||||||
// InspectableWebContentsView:
|
// InspectableWebContentsView:
|
||||||
views::View* GetView() override;
|
views::View* GetView() override;
|
||||||
views::View* GetWebView() override;
|
views::View* GetWebView() override;
|
||||||
|
@ -43,8 +40,6 @@ class InspectableWebContentsViewViews : public InspectableWebContentsView,
|
||||||
void SetContentsResizingStrategy(
|
void SetContentsResizingStrategy(
|
||||||
const DevToolsContentsResizingStrategy& strategy) override;
|
const DevToolsContentsResizingStrategy& strategy) override;
|
||||||
void SetTitle(const std::u16string& title) override;
|
void SetTitle(const std::u16string& title) override;
|
||||||
void UpdateDraggableRegions(
|
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) override;
|
|
||||||
|
|
||||||
// views::View:
|
// views::View:
|
||||||
void Layout() override;
|
void Layout() override;
|
||||||
|
@ -61,8 +56,6 @@ class InspectableWebContentsViewViews : public InspectableWebContentsView,
|
||||||
bool devtools_visible_ = false;
|
bool devtools_visible_ = false;
|
||||||
views::WidgetDelegate* devtools_window_delegate_ = nullptr;
|
views::WidgetDelegate* devtools_window_delegate_ = nullptr;
|
||||||
std::u16string title_;
|
std::u16string title_;
|
||||||
|
|
||||||
std::unique_ptr<SkRegion> draggable_region_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue