fix: draggable regions exclusively on BrowserViews (#26145)

This commit is contained in:
Shelley Vohr 2020-10-27 14:28:43 -07:00 committed by GitHub
parent 760c4aeb3e
commit 7cdc42f43a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 139 additions and 68 deletions

View file

@ -4,9 +4,12 @@
#include "shell/browser/api/electron_api_browser_view.h"
#include <vector>
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/browser.h"
#include "shell/browser/native_browser_view.h"
#include "shell/browser/ui/drag_util.h"
#include "shell/common/color_util.h"
#include "shell/common/gin_converters/gfx_converter.h"
#include "shell/common/gin_helper/dictionary.h"
@ -80,6 +83,7 @@ BrowserView::BrowserView(gin::Arguments* args,
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
api_web_contents_->AddObserver(this);
Observe(web_contents->web_contents());
view_.reset(
@ -90,6 +94,7 @@ BrowserView::~BrowserView() {
if (api_web_contents_) { // destroy() is called
// Destroy WebContents asynchronously unless app is shutting down,
// because destroy() might be called inside WebContents's event handler.
api_web_contents_->RemoveObserver(this);
api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down());
}
}
@ -100,6 +105,11 @@ void BrowserView::WebContentsDestroyed() {
Unpin();
}
void BrowserView::OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) {
view_->UpdateDraggableRegions(regions);
}
// static
gin::Handle<BrowserView> BrowserView::New(gin_helper::ErrorThrower thrower,
gin::Arguments* args) {

View file

@ -7,11 +7,14 @@
#include <memory>
#include <string>
#include <vector>
#include "content/public/browser/web_contents_observer.h"
#include "gin/handle.h"
#include "gin/wrappable.h"
#include "shell/browser/extended_web_contents_observer.h"
#include "shell/browser/native_browser_view.h"
#include "shell/common/api/api.mojom.h"
#include "shell/common/gin_helper/constructible.h"
#include "shell/common/gin_helper/error_thrower.h"
#include "shell/common/gin_helper/pinnable.h"
@ -35,7 +38,8 @@ class WebContents;
class BrowserView : public gin::Wrappable<BrowserView>,
public gin_helper::Constructible<BrowserView>,
public gin_helper::Pinnable<BrowserView>,
public content::WebContentsObserver {
public content::WebContentsObserver,
public ExtendedWebContentsObserver {
public:
// gin_helper::Constructible
static gin::Handle<BrowserView> New(gin_helper::ErrorThrower thrower,
@ -59,6 +63,10 @@ class BrowserView : public gin::Wrappable<BrowserView>,
// content::WebContentsObserver:
void WebContentsDestroyed() override;
// ExtendedWebContentsObserver:
void OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) override;
private:
void SetAutoResize(AutoResizeFlags flags);
void SetBounds(const gfx::Rect& bounds);

View file

@ -414,19 +414,6 @@ v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
return v8::Local<v8::Value>::New(isolate, web_contents_);
}
// Convert draggable regions in raw format to SkRegion format.
std::unique_ptr<SkRegion> BrowserWindow::DraggableRegionsToSkRegion(
const std::vector<mojom::DraggableRegionPtr>& regions) {
auto sk_region = std::make_unique<SkRegion>();
for (const auto& 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) {
if (!window_unresponsive_closure_.IsCancelled())
return;

View file

@ -12,6 +12,7 @@
#include "base/cancelable_callback.h"
#include "shell/browser/api/electron_api_base_window.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/ui/drag_util.h"
#include "shell/common/gin_helper/error_thrower.h"
namespace electron {
@ -102,10 +103,6 @@ class BrowserWindow : public BaseWindow,
void UpdateDraggableRegions(
const std::vector<mojom::DraggableRegionPtr>& regions);
// Convert draggable regions in raw format to SkRegion format.
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
const std::vector<mojom::DraggableRegionPtr>& regions);
// Schedule a notification unresponsive event.
void ScheduleUnresponsiveEvent(int ms);

View file

@ -37,26 +37,6 @@ namespace electron {
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;
SkRegion non_draggable;
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::OverrideNSWindowContentView(InspectableWebContents* iwc) {
// Make NativeWindow use a NSView as content view.
static_cast<NativeWindowMac*>(window())->OverrideNSWindowContentView();
@ -109,6 +89,12 @@ void BrowserWindow::UpdateDraggableRegions(
for (const auto& r : regions)
draggable_regions_.push_back(r.Clone());
}
auto browser_views = window_->browser_views();
for (NativeBrowserView* view : browser_views) {
view->UpdateDraggableRegions(draggable_regions_);
}
std::vector<gfx::Rect> drag_exclude_rects;
if (regions.empty()) {
drag_exclude_rects.push_back(gfx::Rect(0, 0, webViewWidth, webViewHeight));
@ -117,11 +103,6 @@ void BrowserWindow::UpdateDraggableRegions(
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
}
auto browser_views = window_->browser_views();
for (NativeBrowserView* view : browser_views) {
view->UpdateDraggableRegions(drag_exclude_rects);
}
// Create and add a ControlRegionView for each region that needs to be
// excluded from the dragging.
for (const auto& rect : drag_exclude_rects) {

View file

@ -15,7 +15,7 @@ void BrowserWindow::UpdateDraggableRegions(
if (window_->has_frame())
return;
static_cast<NativeWindowViews*>(window_.get())
->UpdateDraggableRegions(DraggableRegionsToSkRegion(regions));
->UpdateDraggableRegions(regions);
}
} // namespace api

View file

@ -31,6 +31,7 @@
#include "shell/browser/api/save_page_handler.h"
#include "shell/browser/common_web_contents_delegate.h"
#include "shell/browser/event_emitter_mixin.h"
#include "shell/browser/extended_web_contents_observer.h"
#include "shell/common/gin_helper/cleaned_up_at_exit.h"
#include "shell/common/gin_helper/constructible.h"
#include "shell/common/gin_helper/error_thrower.h"
@ -120,22 +121,6 @@ class OffScreenRenderWidgetHostView;
namespace api {
// Certain events are only in WebContentsDelegate, provide our own Observer to
// dispatch those events.
class ExtendedWebContentsObserver : public base::CheckedObserver {
public:
virtual void OnCloseContents() {}
virtual void OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) {}
virtual void OnSetContentBounds(const gfx::Rect& rect) {}
virtual void OnActivateContents() {}
virtual void OnPageTitleUpdated(const base::string16& title,
bool explicit_set) {}
protected:
~ExtendedWebContentsObserver() override {}
};
// Wrapper around the content::WebContents.
class WebContents : public gin::Wrappable<WebContents>,
public gin_helper::EventEmitterMixin<WebContents>,