refactor: remove InspectableWebContentsViewMac in favor of the Views version (#44628)
* refactor: remove InspectableWebContentsViewMac in favor of the Views version
* cherry-pick: refactor: remove InspectableWebContentsViewMac in favor of the Views version (#41326)
commit e67ab9a93d
Confilcts not resolved, except removal of the files removed
by the original commit.
* resolved conflicts and build issues after cherry-pick
* cherry-picked: fix: add method allowing to disable headless mode in native widget
https://github.com/electron/electron/pull/42996
fixing
https://github.com/electron/electron/issues/42995
* fix: displaying select popup in window created as fullscreen window
`constrainFrameRect:toScreen:` is not being call for windows created
with `fullscreen: true` therefore `headless` mode was not being removed
and `RenderWidgetHostNSViewBridge::DisplayPopupMenu` ignored displaying
popup.
Issue could be fixed by placing additional removal of `headless` mode
in the `toggleFullScreen:`, but `orderWindow:relativeTo:` is called
both for a regular and a fullscreen window, therefore there will be
a single place fixing both cases.
Because `electron::NativeWindowMac` lifetime may be shorter than
`ElectronNSWindow` on which macOS may execute `orderWindow:relativeTo:`
we need to clear `shell_` when `NativeWindow` is being closed.
Fixes #43010.
* fix: Content visibility when using `vibrancy`
We need to put `NSVisualEffectView` before `ViewsCompositorSuperview`
otherwise when using `vibrancy` in `BrowserWindow` `NSVisualEffectView`
will hide content displayed by the compositor.
Fixes #43003
Fixes #42336
In fact main issues reported in these tickets were not present after
cherry-picking original refactor switching to `views::WebView`, so
text could be selected and click event was properly generated. However
both issues testcases were using `vibrancy` and actual content was
invisible, because it was covered by the `NSVisualEffectView`.
* fix: EXCEPTION_ACCESS_VIOLATION crash on BrowserWindow.destroy()
Restored postponed deletion of the `NativeWindow`.
Restoration caused `DCHECK(new_parent_ui_layer->GetCompositor());` failure
in `BrowserCompositorMac::SetParentUiLayer` after the spec test:
`chrome extensions chrome.webRequest does not take precedence over Electron webRequest - http`
with stack:
```
7   Electron Framework 0x000000011fe07830 content::BrowserCompositorMac::SetParentUiLayer(ui::Layer*) + 628
8   Electron Framework 0x000000011fe0c154 content::RenderWidgetHostViewMac::SetParentUiLayer(ui::Layer*) + 220
9   Electron Framework 0x000000011fe226a8 content::WebContentsViewMac::CreateViewForWidget(content::RenderWidgetHost*) + 600
10  Electron Framework 0x000000011fd37e4c content::WebContentsImpl::CreateRenderWidgetHostViewForRenderManager(content::RenderViewHost*) + 164
11  Electron Framework 0x000000011fb32278 content::RenderFrameHostManager::CreateSpeculativeRenderFrame(content::SiteInstanceImpl*, bool, scoped_refptr<content::BrowsingContextState> const&) + 816
12  Electron Framework 0x000000011fb2ab8c content::RenderFrameHostManager::CreateSpeculativeRenderFrameHost(content::SiteInstanceImpl*, content::SiteInstanceImpl*, bool) + 1308
13  Electron Framework 0x000000011fb28598 content::RenderFrameHostManager::GetFrameHostForNavigation(content::NavigationRequest*, content::BrowsingContextGroupSwap*, std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>>*) + 1796
14  Electron Framework 0x000000011fa78660 content::NavigationRequest::SelectFrameHostForOnRequestFailedInternal(bool, bool, std::__Cr::optional<std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>>> const&) + 280
15  Electron Framework 0x000000011fa6a994 content::NavigationRequest::OnRequestFailedInternal(network::URLLoaderCompletionStatus const&, bool, std::__Cr::optional<std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>>> const&, bo
+ 1008
16  Electron Framework 0x000000011fa7772c content::NavigationRequest::OnRequestFailed(network::URLLoaderCompletionStatus const&) + 72
17  Electron Framework 0x000000011f8554ac content::NavigationURLLoaderImpl::NotifyRequestFailed(network::URLLoaderCompletionStatus const&) + 248
```
This was probably the reason of removing `NativeWindow` immediately
in order to cleanup `views_host_` in `WebContentsViewMac` to prevent
using layer without compositor in `WebContentsViewMac::CreateViewForWidget`.
`[ElectronNSWindowDelegate windowWillClose:]` is deleting window host
and the compositor used by the `NativeWindow` therefore detach `NativeWindow`
contents from parent. This will clear `views_host_` and prevent failing
mentioned `DCHECK`.
Fixes #42975
* chore: Applied review suggestions
* refactor: directly cleanup shell
---------
Co-authored-by: Samuel Maddock <smaddock@slack-corp.com>
	
	
This commit is contained in:
		
					parent
					
						
							
								45f90cd5dd
							
						
					
				
			
			
				commit
				
					
						6953f5505f
					
				
			
		
					 23 changed files with 378 additions and 951 deletions
				
			
		| 
						 | 
					@ -159,12 +159,8 @@ filenames = {
 | 
				
			||||||
    "shell/browser/osr/osr_web_contents_view_mac.mm",
 | 
					    "shell/browser/osr/osr_web_contents_view_mac.mm",
 | 
				
			||||||
    "shell/browser/relauncher_mac.cc",
 | 
					    "shell/browser/relauncher_mac.cc",
 | 
				
			||||||
    "shell/browser/ui/certificate_trust_mac.mm",
 | 
					    "shell/browser/ui/certificate_trust_mac.mm",
 | 
				
			||||||
    "shell/browser/ui/cocoa/delayed_native_view_host.h",
 | 
					 | 
				
			||||||
    "shell/browser/ui/cocoa/delayed_native_view_host.mm",
 | 
					 | 
				
			||||||
    "shell/browser/ui/cocoa/electron_bundle_mover.h",
 | 
					    "shell/browser/ui/cocoa/electron_bundle_mover.h",
 | 
				
			||||||
    "shell/browser/ui/cocoa/electron_bundle_mover.mm",
 | 
					    "shell/browser/ui/cocoa/electron_bundle_mover.mm",
 | 
				
			||||||
    "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h",
 | 
					 | 
				
			||||||
    "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm",
 | 
					 | 
				
			||||||
    "shell/browser/ui/cocoa/electron_menu_controller.h",
 | 
					    "shell/browser/ui/cocoa/electron_menu_controller.h",
 | 
				
			||||||
    "shell/browser/ui/cocoa/electron_menu_controller.mm",
 | 
					    "shell/browser/ui/cocoa/electron_menu_controller.mm",
 | 
				
			||||||
    "shell/browser/ui/cocoa/electron_native_widget_mac.h",
 | 
					    "shell/browser/ui/cocoa/electron_native_widget_mac.h",
 | 
				
			||||||
| 
						 | 
					@ -191,8 +187,6 @@ filenames = {
 | 
				
			||||||
    "shell/browser/ui/cocoa/window_buttons_proxy.mm",
 | 
					    "shell/browser/ui/cocoa/window_buttons_proxy.mm",
 | 
				
			||||||
    "shell/browser/ui/drag_util_mac.mm",
 | 
					    "shell/browser/ui/drag_util_mac.mm",
 | 
				
			||||||
    "shell/browser/ui/file_dialog_mac.mm",
 | 
					    "shell/browser/ui/file_dialog_mac.mm",
 | 
				
			||||||
    "shell/browser/ui/inspectable_web_contents_view_mac.h",
 | 
					 | 
				
			||||||
    "shell/browser/ui/inspectable_web_contents_view_mac.mm",
 | 
					 | 
				
			||||||
    "shell/browser/ui/message_box_mac.mm",
 | 
					    "shell/browser/ui/message_box_mac.mm",
 | 
				
			||||||
    "shell/browser/ui/tray_icon_cocoa.h",
 | 
					    "shell/browser/ui/tray_icon_cocoa.h",
 | 
				
			||||||
    "shell/browser/ui/tray_icon_cocoa.mm",
 | 
					    "shell/browser/ui/tray_icon_cocoa.mm",
 | 
				
			||||||
| 
						 | 
					@ -224,8 +218,6 @@ filenames = {
 | 
				
			||||||
    "shell/browser/ui/views/electron_views_delegate.h",
 | 
					    "shell/browser/ui/views/electron_views_delegate.h",
 | 
				
			||||||
    "shell/browser/ui/views/frameless_view.cc",
 | 
					    "shell/browser/ui/views/frameless_view.cc",
 | 
				
			||||||
    "shell/browser/ui/views/frameless_view.h",
 | 
					    "shell/browser/ui/views/frameless_view.h",
 | 
				
			||||||
    "shell/browser/ui/views/inspectable_web_contents_view_views.cc",
 | 
					 | 
				
			||||||
    "shell/browser/ui/views/inspectable_web_contents_view_views.h",
 | 
					 | 
				
			||||||
    "shell/browser/ui/views/menu_bar.cc",
 | 
					    "shell/browser/ui/views/menu_bar.cc",
 | 
				
			||||||
    "shell/browser/ui/views/menu_bar.h",
 | 
					    "shell/browser/ui/views/menu_bar.h",
 | 
				
			||||||
    "shell/browser/ui/views/menu_delegate.cc",
 | 
					    "shell/browser/ui/views/menu_delegate.cc",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,6 +133,8 @@ osr_shared_texture_remove_keyed_mutex_on_win_dxgi.patch
 | 
				
			||||||
feat_allow_usage_of_sccontentsharingpicker_on_supported_platforms.patch
 | 
					feat_allow_usage_of_sccontentsharingpicker_on_supported_platforms.patch
 | 
				
			||||||
chore_partial_revert_of.patch
 | 
					chore_partial_revert_of.patch
 | 
				
			||||||
fix_software_compositing_infinite_loop.patch
 | 
					fix_software_compositing_infinite_loop.patch
 | 
				
			||||||
 | 
					fix_add_method_which_disables_headless_mode_on_native_widget.patch
 | 
				
			||||||
 | 
					fix_put_nsvisualeffectview_before_viewscompositorsuperview.patch
 | 
				
			||||||
refactor_unfilter_unresponsive_events.patch
 | 
					refactor_unfilter_unresponsive_events.patch
 | 
				
			||||||
build_disable_thin_lto_mac.patch
 | 
					build_disable_thin_lto_mac.patch
 | 
				
			||||||
build_add_public_config_simdutf_config.patch
 | 
					build_add_public_config_simdutf_config.patch
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
				
			||||||
 | 
					From: Cezary Kulakowski <cezary@openfin.co>
 | 
				
			||||||
 | 
					Date: Mon, 22 Jul 2024 16:23:13 +0200
 | 
				
			||||||
 | 
					Subject: fix: add method which disables headless mode on native widget
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We need this method as we create window in headless mode and we
 | 
				
			||||||
 | 
					switch it back to normal mode only after inital paint is done in
 | 
				
			||||||
 | 
					order to get some events like WebContents.beginFrameSubscription.
 | 
				
			||||||
 | 
					If we don't set `is_headless_` to false then some child windows
 | 
				
			||||||
 | 
					e.g. autofill popups will be created in headless mode leading to
 | 
				
			||||||
 | 
					ui problems (like dissapearing popup during typing in html's
 | 
				
			||||||
 | 
					input list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
 | 
				
			||||||
 | 
					index 30d0ea6633cb0f7f9aab37951a38be9b0482a12a..734e91e6d50c8d3afd20b39167c6254e934e7c1e 100644
 | 
				
			||||||
 | 
					--- a/ui/views/widget/widget.h
 | 
				
			||||||
 | 
					+++ b/ui/views/widget/widget.h
 | 
				
			||||||
 | 
					@@ -1144,6 +1144,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
 | 
				
			||||||
 | 
					   // True if widget was created in headless mode.
 | 
				
			||||||
 | 
					   bool is_headless() const { return is_headless_; }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+  void DisableHeadlessMode() { is_headless_ = false; }
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					   // True if the window size will follow the content preferred size.
 | 
				
			||||||
 | 
					   bool is_autosized() const { return is_autosized_; }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
				
			||||||
 | 
					From: =?UTF-8?q?Micha=C5=82=20Pichli=C5=84ski?=
 | 
				
			||||||
 | 
					 <michal.pichlinski@openfin.co>
 | 
				
			||||||
 | 
					Date: Tue, 29 Oct 2024 21:16:29 +0100
 | 
				
			||||||
 | 
					Subject: fix: Put NSVisualEffectView before ViewsCompositorSuperview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Upstreamed at https://chromium-review.googlesource.com/c/chromium/src/+/6030552
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Otherwise when using `vibrancy` in `BrowserWindow` NSVisualEffectView
 | 
				
			||||||
 | 
					will hide content displayed by the compositor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
 | 
				
			||||||
 | 
					index 07c3997e6565cf77362ee73959c4d21da4fefe96..3353a7847df90b58eec34ea4d6ff8fb19617f5cc 100644
 | 
				
			||||||
 | 
					--- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
 | 
				
			||||||
 | 
					+++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
 | 
				
			||||||
 | 
					@@ -223,8 +223,19 @@ NSComparisonResult SubviewSorter(__kindof NSView* lhs,
 | 
				
			||||||
 | 
					                                  void* rank_as_void) {
 | 
				
			||||||
 | 
					   DCHECK_NE(lhs, rhs);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-  if ([lhs isKindOfClass:[ViewsCompositorSuperview class]])
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+  // Put NSVisualEffectView before ViewsCompositorSuperview otherwise when using
 | 
				
			||||||
 | 
					+  // `vibrancy` in `BrowserWindow` NSVisualEffectView will hide content
 | 
				
			||||||
 | 
					+  // displayed by the compositor.
 | 
				
			||||||
 | 
					+  if ([lhs isKindOfClass:[NSVisualEffectView class]]) {
 | 
				
			||||||
 | 
					     return NSOrderedAscending;
 | 
				
			||||||
 | 
					+  }
 | 
				
			||||||
 | 
					+  if ([lhs isKindOfClass:[ViewsCompositorSuperview class]]) {
 | 
				
			||||||
 | 
					+    if ([rhs isKindOfClass:[NSVisualEffectView class]]) {
 | 
				
			||||||
 | 
					+      return NSOrderedDescending;
 | 
				
			||||||
 | 
					+    }
 | 
				
			||||||
 | 
					+    return NSOrderedAscending;
 | 
				
			||||||
 | 
					+  }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					   const RankMap* rank = static_cast<const RankMap*>(rank_as_void);
 | 
				
			||||||
 | 
					   auto left_rank = rank->find(lhs);
 | 
				
			||||||
| 
						 | 
					@ -27,29 +27,14 @@
 | 
				
			||||||
#include "ui/views/view_class_properties.h"
 | 
					#include "ui/views/view_class_properties.h"
 | 
				
			||||||
#include "ui/views/widget/widget.h"
 | 
					#include "ui/views/widget/widget.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if BUILDFLAG(IS_MAC)
 | 
					 | 
				
			||||||
#include "shell/browser/ui/cocoa/delayed_native_view_host.h"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace electron::api {
 | 
					namespace electron::api {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WebContentsView::WebContentsView(v8::Isolate* isolate,
 | 
					WebContentsView::WebContentsView(v8::Isolate* isolate,
 | 
				
			||||||
                                 gin::Handle<WebContents> web_contents)
 | 
					                                 gin::Handle<WebContents> web_contents)
 | 
				
			||||||
#if BUILDFLAG(IS_MAC)
 | 
					    : View(web_contents->inspectable_web_contents()->GetView()),
 | 
				
			||||||
    : View(new DelayedNativeViewHost(web_contents->inspectable_web_contents()
 | 
					 | 
				
			||||||
                                         ->GetView()
 | 
					 | 
				
			||||||
                                         ->GetNativeView())),
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    : View(web_contents->inspectable_web_contents()->GetView()->GetView()),
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
      web_contents_(isolate, web_contents.ToV8()),
 | 
					      web_contents_(isolate, web_contents.ToV8()),
 | 
				
			||||||
      api_web_contents_(web_contents.get()) {
 | 
					      api_web_contents_(web_contents.get()) {
 | 
				
			||||||
#if !BUILDFLAG(IS_MAC)
 | 
					 | 
				
			||||||
  // On macOS the View is a newly-created |DelayedNativeViewHost| and it is our
 | 
					 | 
				
			||||||
  // responsibility to delete it. On other platforms the View is created and
 | 
					 | 
				
			||||||
  // managed by InspectableWebContents.
 | 
					 | 
				
			||||||
  set_delete_view(false);
 | 
					  set_delete_view(false);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  view()->SetProperty(
 | 
					  view()->SetProperty(
 | 
				
			||||||
      views::kFlexBehaviorKey,
 | 
					      views::kFlexBehaviorKey,
 | 
				
			||||||
      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum,
 | 
					      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,9 +169,6 @@ class NativeWindowMac : public NativeWindow,
 | 
				
			||||||
  void NotifyWindowDidFailToEnterFullScreen();
 | 
					  void NotifyWindowDidFailToEnterFullScreen();
 | 
				
			||||||
  void NotifyWindowWillLeaveFullScreen();
 | 
					  void NotifyWindowWillLeaveFullScreen();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // views::WidgetDelegate:
 | 
					 | 
				
			||||||
  views::View* GetContentsView() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Cleanup observers when window is getting closed. Note that the destructor
 | 
					  // Cleanup observers when window is getting closed. Note that the destructor
 | 
				
			||||||
  // can be called much later after window gets closed, so we should not do
 | 
					  // can be called much later after window gets closed, so we should not do
 | 
				
			||||||
  // cleanup in destructor.
 | 
					  // cleanup in destructor.
 | 
				
			||||||
| 
						 | 
					@ -223,6 +220,7 @@ class NativeWindowMac : public NativeWindow,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 protected:
 | 
					 protected:
 | 
				
			||||||
  // views::WidgetDelegate:
 | 
					  // views::WidgetDelegate:
 | 
				
			||||||
 | 
					  views::View* GetContentsView() override;
 | 
				
			||||||
  bool CanMaximize() const override;
 | 
					  bool CanMaximize() const override;
 | 
				
			||||||
  std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
 | 
					  std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
 | 
				
			||||||
      views::Widget* widget) override;
 | 
					      views::Widget* widget) override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -194,6 +194,8 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
 | 
				
			||||||
  params.bounds = bounds;
 | 
					  params.bounds = bounds;
 | 
				
			||||||
  params.delegate = this;
 | 
					  params.delegate = this;
 | 
				
			||||||
  params.type = views::Widget::InitParams::TYPE_WINDOW;
 | 
					  params.type = views::Widget::InitParams::TYPE_WINDOW;
 | 
				
			||||||
 | 
					  // Allow painting before shown, to be later disabled in ElectronNSWindow.
 | 
				
			||||||
 | 
					  params.headless_mode = true;
 | 
				
			||||||
  params.native_widget =
 | 
					  params.native_widget =
 | 
				
			||||||
      new ElectronNativeWidgetMac(this, windowType, styleMask, widget());
 | 
					      new ElectronNativeWidgetMac(this, windowType, styleMask, widget());
 | 
				
			||||||
  widget()->Init(std::move(params));
 | 
					  widget()->Init(std::move(params));
 | 
				
			||||||
| 
						 | 
					@ -1674,6 +1676,7 @@ void NativeWindowMac::Cleanup() {
 | 
				
			||||||
  DCHECK(!IsClosed());
 | 
					  DCHECK(!IsClosed());
 | 
				
			||||||
  ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
 | 
					  ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
 | 
				
			||||||
  display::Screen::GetScreen()->RemoveObserver(this);
 | 
					  display::Screen::GetScreen()->RemoveObserver(this);
 | 
				
			||||||
 | 
					  [window_ cleanup];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NativeAppWindowFrameViewMac : public views::NativeFrameViewMac {
 | 
					class NativeAppWindowFrameViewMac : public views::NativeFrameViewMac {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@
 | 
				
			||||||
#include "content/public/browser/desktop_media_id.h"
 | 
					#include "content/public/browser/desktop_media_id.h"
 | 
				
			||||||
#include "content/public/common/color_parser.h"
 | 
					#include "content/public/common/color_parser.h"
 | 
				
			||||||
#include "shell/browser/api/electron_api_web_contents.h"
 | 
					#include "shell/browser/api/electron_api_web_contents.h"
 | 
				
			||||||
 | 
					#include "shell/browser/ui/inspectable_web_contents_view.h"
 | 
				
			||||||
#include "shell/browser/ui/views/root_view.h"
 | 
					#include "shell/browser/ui/views/root_view.h"
 | 
				
			||||||
#include "shell/browser/web_contents_preferences.h"
 | 
					#include "shell/browser/web_contents_preferences.h"
 | 
				
			||||||
#include "shell/browser/web_view_manager.h"
 | 
					#include "shell/browser/web_view_manager.h"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,33 +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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef ELECTRON_SHELL_BROWSER_UI_COCOA_DELAYED_NATIVE_VIEW_HOST_H_
 | 
					 | 
				
			||||||
#define ELECTRON_SHELL_BROWSER_UI_COCOA_DELAYED_NATIVE_VIEW_HOST_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "ui/views/controls/native/native_view_host.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace electron {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Automatically attach the native view after the NativeViewHost is attached to
 | 
					 | 
				
			||||||
// a widget. (Attaching it directly would cause crash.)
 | 
					 | 
				
			||||||
class DelayedNativeViewHost : public views::NativeViewHost {
 | 
					 | 
				
			||||||
 public:
 | 
					 | 
				
			||||||
  explicit DelayedNativeViewHost(gfx::NativeView native_view);
 | 
					 | 
				
			||||||
  ~DelayedNativeViewHost() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // disable copy
 | 
					 | 
				
			||||||
  DelayedNativeViewHost(const DelayedNativeViewHost&) = delete;
 | 
					 | 
				
			||||||
  DelayedNativeViewHost& operator=(const DelayedNativeViewHost&) = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // views::View:
 | 
					 | 
				
			||||||
  void ViewHierarchyChanged(
 | 
					 | 
				
			||||||
      const views::ViewHierarchyChangedDetails& details) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 private:
 | 
					 | 
				
			||||||
  gfx::NativeView native_view_;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace electron
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif  // ELECTRON_SHELL_BROWSER_UI_COCOA_DELAYED_NATIVE_VIEW_HOST_H_
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,23 +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/ui/cocoa/delayed_native_view_host.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace electron {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DelayedNativeViewHost::DelayedNativeViewHost(gfx::NativeView native_view)
 | 
					 | 
				
			||||||
    : native_view_(native_view) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DelayedNativeViewHost::~DelayedNativeViewHost() = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DelayedNativeViewHost::ViewHierarchyChanged(
 | 
					 | 
				
			||||||
    const views::ViewHierarchyChangedDetails& details) {
 | 
					 | 
				
			||||||
  if (!details.is_add && native_view())
 | 
					 | 
				
			||||||
    Detach();
 | 
					 | 
				
			||||||
  NativeViewHost::ViewHierarchyChanged(details);
 | 
					 | 
				
			||||||
  if (details.is_add && GetWidget() && !native_view())
 | 
					 | 
				
			||||||
    Attach(native_view_);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace electron
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,54 +0,0 @@
 | 
				
			||||||
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
 | 
					 | 
				
			||||||
// Use of this source code is governed by a BSD-style license that can be
 | 
					 | 
				
			||||||
// found in the LICENSE-CHROMIUM file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_INSPECTABLE_WEB_CONTENTS_VIEW_H_
 | 
					 | 
				
			||||||
#define ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_INSPECTABLE_WEB_CONTENTS_VIEW_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#import <AppKit/AppKit.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "base/apple/owned_objc.h"
 | 
					 | 
				
			||||||
#include "base/memory/raw_ptr.h"
 | 
					 | 
				
			||||||
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
 | 
					 | 
				
			||||||
#include "ui/base/cocoa/base_view.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace electron {
 | 
					 | 
				
			||||||
class InspectableWebContentsViewMac;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using electron::InspectableWebContentsViewMac;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@interface NSView (WebContentsView)
 | 
					 | 
				
			||||||
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
 | 
					 | 
				
			||||||
@end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@interface ElectronInspectableWebContentsView : BaseView <NSWindowDelegate> {
 | 
					 | 
				
			||||||
 @private
 | 
					 | 
				
			||||||
  raw_ptr<electron::InspectableWebContentsViewMac> inspectableWebContentsView_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  NSView* __strong fake_view_;
 | 
					 | 
				
			||||||
  NSWindow* __strong devtools_window_;
 | 
					 | 
				
			||||||
  BOOL devtools_visible_;
 | 
					 | 
				
			||||||
  BOOL devtools_docked_;
 | 
					 | 
				
			||||||
  BOOL devtools_is_first_responder_;
 | 
					 | 
				
			||||||
  BOOL attached_to_window_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DevToolsContentsResizingStrategy strategy_;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (instancetype)initWithInspectableWebContentsViewMac:
 | 
					 | 
				
			||||||
    (InspectableWebContentsViewMac*)view;
 | 
					 | 
				
			||||||
- (void)notifyDevToolsFocused;
 | 
					 | 
				
			||||||
- (void)setCornerRadii:(CGFloat)cornerRadius;
 | 
					 | 
				
			||||||
- (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate;
 | 
					 | 
				
			||||||
- (BOOL)isDevToolsVisible;
 | 
					 | 
				
			||||||
- (BOOL)isDevToolsFocused;
 | 
					 | 
				
			||||||
- (void)setIsDocked:(BOOL)docked activate:(BOOL)activate;
 | 
					 | 
				
			||||||
- (void)setContentsResizingStrategy:
 | 
					 | 
				
			||||||
    (const DevToolsContentsResizingStrategy&)strategy;
 | 
					 | 
				
			||||||
- (void)setTitle:(NSString*)title;
 | 
					 | 
				
			||||||
- (NSString*)getTitle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif  // ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_INSPECTABLE_WEB_CONTENTS_VIEW_H_
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,337 +0,0 @@
 | 
				
			||||||
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
 | 
					 | 
				
			||||||
// Use of this source code is governed by a BSD-style license that can be
 | 
					 | 
				
			||||||
// found in the LICENSE-CHROMIUM file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "content/public/browser/render_widget_host_view.h"
 | 
					 | 
				
			||||||
#include "shell/browser/api/electron_api_web_contents.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/cocoa/event_dispatching_window.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_view_delegate.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_view_mac.h"
 | 
					 | 
				
			||||||
#include "ui/base/cocoa/base_view.h"
 | 
					 | 
				
			||||||
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@implementation ElectronInspectableWebContentsView
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (instancetype)initWithInspectableWebContentsViewMac:
 | 
					 | 
				
			||||||
    (InspectableWebContentsViewMac*)view {
 | 
					 | 
				
			||||||
  self = [super init];
 | 
					 | 
				
			||||||
  if (!self)
 | 
					 | 
				
			||||||
    return nil;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  inspectableWebContentsView_ = view;
 | 
					 | 
				
			||||||
  devtools_visible_ = NO;
 | 
					 | 
				
			||||||
  devtools_docked_ = NO;
 | 
					 | 
				
			||||||
  devtools_is_first_responder_ = NO;
 | 
					 | 
				
			||||||
  attached_to_window_ = NO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (inspectableWebContentsView_->inspectable_web_contents()->is_guest()) {
 | 
					 | 
				
			||||||
    fake_view_ = [[NSView alloc] init];
 | 
					 | 
				
			||||||
    [fake_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
 | 
					 | 
				
			||||||
    [self addSubview:fake_view_];
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    auto* contents = inspectableWebContentsView_->inspectable_web_contents()
 | 
					 | 
				
			||||||
                         ->GetWebContents();
 | 
					 | 
				
			||||||
    auto* contentsView = contents->GetNativeView().GetNativeNSView();
 | 
					 | 
				
			||||||
    [contentsView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
 | 
					 | 
				
			||||||
    [self addSubview:contentsView];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // See https://code.google.com/p/chromium/issues/detail?id=348490.
 | 
					 | 
				
			||||||
  [self setWantsLayer:YES];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return self;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)dealloc {
 | 
					 | 
				
			||||||
  [[NSNotificationCenter defaultCenter] removeObserver:self];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
 | 
					 | 
				
			||||||
  [self adjustSubviews];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)viewDidMoveToWindow {
 | 
					 | 
				
			||||||
  if (attached_to_window_ && !self.window) {
 | 
					 | 
				
			||||||
    attached_to_window_ = NO;
 | 
					 | 
				
			||||||
    [[NSNotificationCenter defaultCenter] removeObserver:self];
 | 
					 | 
				
			||||||
  } else if (!attached_to_window_ && self.window) {
 | 
					 | 
				
			||||||
    attached_to_window_ = YES;
 | 
					 | 
				
			||||||
    [[NSNotificationCenter defaultCenter]
 | 
					 | 
				
			||||||
        addObserver:self
 | 
					 | 
				
			||||||
           selector:@selector(viewDidBecomeFirstResponder:)
 | 
					 | 
				
			||||||
               name:kViewDidBecomeFirstResponder
 | 
					 | 
				
			||||||
             object:nil];
 | 
					 | 
				
			||||||
    [[NSNotificationCenter defaultCenter]
 | 
					 | 
				
			||||||
        addObserver:self
 | 
					 | 
				
			||||||
           selector:@selector(parentWindowBecameMain:)
 | 
					 | 
				
			||||||
               name:NSWindowDidBecomeMainNotification
 | 
					 | 
				
			||||||
             object:nil];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (IBAction)showDevTools:(id)sender {
 | 
					 | 
				
			||||||
  inspectableWebContentsView_->inspectable_web_contents()->ShowDevTools(true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)notifyDevToolsFocused {
 | 
					 | 
				
			||||||
  if (inspectableWebContentsView_->GetDelegate())
 | 
					 | 
				
			||||||
    inspectableWebContentsView_->GetDelegate()->DevToolsFocused();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)setCornerRadii:(CGFloat)cornerRadius {
 | 
					 | 
				
			||||||
  auto* inspectable_web_contents =
 | 
					 | 
				
			||||||
      inspectableWebContentsView_->inspectable_web_contents();
 | 
					 | 
				
			||||||
  DCHECK(inspectable_web_contents);
 | 
					 | 
				
			||||||
  auto* webContents = inspectable_web_contents->GetWebContents();
 | 
					 | 
				
			||||||
  if (!webContents)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  auto* webContentsView = webContents->GetNativeView().GetNativeNSView();
 | 
					 | 
				
			||||||
  webContentsView.wantsLayer = YES;
 | 
					 | 
				
			||||||
  webContentsView.layer.cornerRadius = cornerRadius;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)notifyDevToolsResized {
 | 
					 | 
				
			||||||
  // When devtools is opened, resizing devtools would not trigger
 | 
					 | 
				
			||||||
  // UpdateDraggableRegions for WebContents, so we have to notify the window
 | 
					 | 
				
			||||||
  // to do an update of draggable regions.
 | 
					 | 
				
			||||||
  if (inspectableWebContentsView_->GetDelegate())
 | 
					 | 
				
			||||||
    inspectableWebContentsView_->GetDelegate()->DevToolsResized();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate {
 | 
					 | 
				
			||||||
  if (visible == devtools_visible_)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  auto* inspectable_web_contents =
 | 
					 | 
				
			||||||
      inspectableWebContentsView_->inspectable_web_contents();
 | 
					 | 
				
			||||||
  auto* devToolsWebContents =
 | 
					 | 
				
			||||||
      inspectable_web_contents->GetDevToolsWebContents();
 | 
					 | 
				
			||||||
  auto* devToolsView = devToolsWebContents->GetNativeView().GetNativeNSView();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  devtools_visible_ = visible;
 | 
					 | 
				
			||||||
  if (devtools_docked_) {
 | 
					 | 
				
			||||||
    if (visible) {
 | 
					 | 
				
			||||||
      // 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];
 | 
					 | 
				
			||||||
      [self adjustSubviews];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Focus on web view.
 | 
					 | 
				
			||||||
      devToolsWebContents->RestoreFocus();
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      gfx::ScopedCocoaDisableScreenUpdates disabler;
 | 
					 | 
				
			||||||
      [devToolsView removeFromSuperview];
 | 
					 | 
				
			||||||
      [self adjustSubviews];
 | 
					 | 
				
			||||||
      [self notifyDevToolsResized];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    if (visible) {
 | 
					 | 
				
			||||||
      if (activate) {
 | 
					 | 
				
			||||||
        [devtools_window_ makeKeyAndOrderFront:nil];
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        [devtools_window_ orderBack:nil];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      [devtools_window_ setDelegate:nil];
 | 
					 | 
				
			||||||
      [devtools_window_ close];
 | 
					 | 
				
			||||||
      devtools_window_ = nil;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (BOOL)isDevToolsVisible {
 | 
					 | 
				
			||||||
  return devtools_visible_;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (BOOL)isDevToolsFocused {
 | 
					 | 
				
			||||||
  if (devtools_docked_) {
 | 
					 | 
				
			||||||
    return [[self window] isKeyWindow] && devtools_is_first_responder_;
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    return [devtools_window_ isKeyWindow];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO: remove NSWindowStyleMaskTexturedBackground.
 | 
					 | 
				
			||||||
// https://github.com/electron/electron/issues/43125
 | 
					 | 
				
			||||||
#pragma clang diagnostic push
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)setIsDocked:(BOOL)docked activate:(BOOL)activate {
 | 
					 | 
				
			||||||
  // Revert to no-devtools state.
 | 
					 | 
				
			||||||
  [self setDevToolsVisible:NO activate:NO];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Switch to new state.
 | 
					 | 
				
			||||||
  devtools_docked_ = docked;
 | 
					 | 
				
			||||||
  auto* inspectable_web_contents =
 | 
					 | 
				
			||||||
      inspectableWebContentsView_->inspectable_web_contents();
 | 
					 | 
				
			||||||
  auto* devToolsWebContents =
 | 
					 | 
				
			||||||
      inspectable_web_contents->GetDevToolsWebContents();
 | 
					 | 
				
			||||||
  auto devToolsView = devToolsWebContents->GetNativeView().GetNativeNSView();
 | 
					 | 
				
			||||||
  if (!docked) {
 | 
					 | 
				
			||||||
    auto styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
 | 
					 | 
				
			||||||
                     NSWindowStyleMaskMiniaturizable |
 | 
					 | 
				
			||||||
                     NSWindowStyleMaskResizable |
 | 
					 | 
				
			||||||
                     NSWindowStyleMaskTexturedBackground |
 | 
					 | 
				
			||||||
                     NSWindowStyleMaskUnifiedTitleAndToolbar;
 | 
					 | 
				
			||||||
    devtools_window_ = [[EventDispatchingWindow alloc]
 | 
					 | 
				
			||||||
        initWithContentRect:NSMakeRect(0, 0, 800, 600)
 | 
					 | 
				
			||||||
                  styleMask:styleMask
 | 
					 | 
				
			||||||
                    backing:NSBackingStoreBuffered
 | 
					 | 
				
			||||||
                      defer:YES];
 | 
					 | 
				
			||||||
    [devtools_window_ setDelegate:self];
 | 
					 | 
				
			||||||
    [devtools_window_ setFrameAutosaveName:@"electron.devtools"];
 | 
					 | 
				
			||||||
    [devtools_window_ setTitle:@"Developer Tools"];
 | 
					 | 
				
			||||||
    [devtools_window_ setReleasedWhenClosed:NO];
 | 
					 | 
				
			||||||
    [devtools_window_ setAutorecalculatesContentBorderThickness:NO
 | 
					 | 
				
			||||||
                                                        forEdge:NSMaxYEdge];
 | 
					 | 
				
			||||||
    [devtools_window_ setContentBorderThickness:24 forEdge:NSMaxYEdge];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    NSView* contentView = [devtools_window_ contentView];
 | 
					 | 
				
			||||||
    devToolsView.frame = contentView.bounds;
 | 
					 | 
				
			||||||
    devToolsView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [contentView addSubview:devToolsView];
 | 
					 | 
				
			||||||
    [devToolsView setMouseDownCanMoveWindow:NO];
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    [devToolsView setMouseDownCanMoveWindow:YES];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  [self setDevToolsVisible:YES activate:activate];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// -Wdeprecated-declarations
 | 
					 | 
				
			||||||
#pragma clang diagnostic pop
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)setContentsResizingStrategy:
 | 
					 | 
				
			||||||
    (const DevToolsContentsResizingStrategy&)strategy {
 | 
					 | 
				
			||||||
  strategy_.CopyFrom(strategy);
 | 
					 | 
				
			||||||
  [self adjustSubviews];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)adjustSubviews {
 | 
					 | 
				
			||||||
  if (![[self subviews] count])
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (![self isDevToolsVisible] || devtools_window_) {
 | 
					 | 
				
			||||||
    DCHECK_EQ(1u, [[self subviews] count]);
 | 
					 | 
				
			||||||
    NSView* contents = [[self subviews] objectAtIndex:0];
 | 
					 | 
				
			||||||
    [contents setFrame:[self bounds]];
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  NSView* devToolsView = [[self subviews] objectAtIndex:0];
 | 
					 | 
				
			||||||
  NSView* contentsView = [[self subviews] objectAtIndex:1];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DCHECK_EQ(2u, [[self subviews] count]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  gfx::Rect new_devtools_bounds;
 | 
					 | 
				
			||||||
  gfx::Rect new_contents_bounds;
 | 
					 | 
				
			||||||
  ApplyDevToolsContentsResizingStrategy(
 | 
					 | 
				
			||||||
      strategy_, gfx::Size(NSSizeToCGSize([self bounds].size)),
 | 
					 | 
				
			||||||
      &new_devtools_bounds, &new_contents_bounds);
 | 
					 | 
				
			||||||
  [devToolsView setFrame:[self flipRectToNSRect:new_devtools_bounds]];
 | 
					 | 
				
			||||||
  [contentsView setFrame:[self flipRectToNSRect:new_contents_bounds]];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Move mask to the devtools area to exclude it from dragging.
 | 
					 | 
				
			||||||
  NSRect cf = contentsView.frame;
 | 
					 | 
				
			||||||
  NSRect sb = [self bounds];
 | 
					 | 
				
			||||||
  NSRect devtools_frame;
 | 
					 | 
				
			||||||
  if (cf.size.height < sb.size.height) {  // bottom docked
 | 
					 | 
				
			||||||
    devtools_frame.origin.x = 0;
 | 
					 | 
				
			||||||
    devtools_frame.origin.y = 0;
 | 
					 | 
				
			||||||
    devtools_frame.size.width = sb.size.width;
 | 
					 | 
				
			||||||
    devtools_frame.size.height = sb.size.height - cf.size.height;
 | 
					 | 
				
			||||||
  } else {                // left or right docked
 | 
					 | 
				
			||||||
    if (cf.origin.x > 0)  // left docked
 | 
					 | 
				
			||||||
      devtools_frame.origin.x = 0;
 | 
					 | 
				
			||||||
    else  // right docked.
 | 
					 | 
				
			||||||
      devtools_frame.origin.x = cf.size.width;
 | 
					 | 
				
			||||||
    devtools_frame.origin.y = 0;
 | 
					 | 
				
			||||||
    devtools_frame.size.width = sb.size.width - cf.size.width;
 | 
					 | 
				
			||||||
    devtools_frame.size.height = sb.size.height;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  [self notifyDevToolsResized];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)setTitle:(NSString*)title {
 | 
					 | 
				
			||||||
  [devtools_window_ setTitle:title];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (NSString*)getTitle {
 | 
					 | 
				
			||||||
  return [devtools_window_ title];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)viewDidBecomeFirstResponder:(NSNotification*)notification {
 | 
					 | 
				
			||||||
  auto* inspectable_web_contents =
 | 
					 | 
				
			||||||
      inspectableWebContentsView_->inspectable_web_contents();
 | 
					 | 
				
			||||||
  DCHECK(inspectable_web_contents);
 | 
					 | 
				
			||||||
  auto* webContents = inspectable_web_contents->GetWebContents();
 | 
					 | 
				
			||||||
  if (!webContents)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  auto* webContentsView = webContents->GetNativeView().GetNativeNSView();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  NSView* view = [notification object];
 | 
					 | 
				
			||||||
  if ([[webContentsView subviews] containsObject:view]) {
 | 
					 | 
				
			||||||
    devtools_is_first_responder_ = NO;
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  auto* devToolsWebContents =
 | 
					 | 
				
			||||||
      inspectable_web_contents->GetDevToolsWebContents();
 | 
					 | 
				
			||||||
  if (!devToolsWebContents)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  auto devToolsView = devToolsWebContents->GetNativeView().GetNativeNSView();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if ([[devToolsView subviews] containsObject:view]) {
 | 
					 | 
				
			||||||
    devtools_is_first_responder_ = YES;
 | 
					 | 
				
			||||||
    [self notifyDevToolsFocused];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)parentWindowBecameMain:(NSNotification*)notification {
 | 
					 | 
				
			||||||
  NSWindow* parentWindow = [notification object];
 | 
					 | 
				
			||||||
  if ([self window] == parentWindow && devtools_docked_ &&
 | 
					 | 
				
			||||||
      devtools_is_first_responder_)
 | 
					 | 
				
			||||||
    [self notifyDevToolsFocused];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma mark - NSWindowDelegate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)windowWillClose:(NSNotification*)notification {
 | 
					 | 
				
			||||||
  inspectableWebContentsView_->inspectable_web_contents()->CloseDevTools();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)windowDidBecomeMain:(NSNotification*)notification {
 | 
					 | 
				
			||||||
  content::WebContents* web_contents =
 | 
					 | 
				
			||||||
      inspectableWebContentsView_->inspectable_web_contents()
 | 
					 | 
				
			||||||
          ->GetDevToolsWebContents();
 | 
					 | 
				
			||||||
  if (!web_contents)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  web_contents->RestoreFocus();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
 | 
					 | 
				
			||||||
  if (rwhv)
 | 
					 | 
				
			||||||
    rwhv->SetActive(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  [self notifyDevToolsFocused];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (void)windowDidResignMain:(NSNotification*)notification {
 | 
					 | 
				
			||||||
  content::WebContents* web_contents =
 | 
					 | 
				
			||||||
      inspectableWebContentsView_->inspectable_web_contents()
 | 
					 | 
				
			||||||
          ->GetDevToolsWebContents();
 | 
					 | 
				
			||||||
  if (!web_contents)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  web_contents->StoreFocus();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  content::RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
 | 
					 | 
				
			||||||
  if (rwhv)
 | 
					 | 
				
			||||||
    rwhv->SetActive(false);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@end
 | 
					 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,8 @@ class ScopedDisableResize {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace electron
 | 
					}  // namespace electron
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ElectronNativeWindowObserver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@interface ElectronNSWindow : NativeWidgetMacNSWindow {
 | 
					@interface ElectronNSWindow : NativeWidgetMacNSWindow {
 | 
				
			||||||
 @private
 | 
					 @private
 | 
				
			||||||
  raw_ptr<electron::NativeWindowMac> shell_;
 | 
					  raw_ptr<electron::NativeWindowMac> shell_;
 | 
				
			||||||
| 
						 | 
					@ -41,6 +43,7 @@ class ScopedDisableResize {
 | 
				
			||||||
@property(nonatomic, retain) NSImage* cornerMask;
 | 
					@property(nonatomic, retain) NSImage* cornerMask;
 | 
				
			||||||
- (id)initWithShell:(electron::NativeWindowMac*)shell
 | 
					- (id)initWithShell:(electron::NativeWindowMac*)shell
 | 
				
			||||||
          styleMask:(NSUInteger)styleMask;
 | 
					          styleMask:(NSUInteger)styleMask;
 | 
				
			||||||
 | 
					- (void)cleanup;
 | 
				
			||||||
- (electron::NativeWindowMac*)shell;
 | 
					- (electron::NativeWindowMac*)shell;
 | 
				
			||||||
- (id)accessibilityFocusedUIElement;
 | 
					- (id)accessibilityFocusedUIElement;
 | 
				
			||||||
- (NSRect)originalContentRectForFrameRect:(NSRect)frameRect;
 | 
					- (NSRect)originalContentRectForFrameRect:(NSRect)frameRect;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,8 +8,6 @@
 | 
				
			||||||
#include "electron/mas.h"
 | 
					#include "electron/mas.h"
 | 
				
			||||||
#include "shell/browser/api/electron_api_web_contents.h"
 | 
					#include "shell/browser/api/electron_api_web_contents.h"
 | 
				
			||||||
#include "shell/browser/native_window_mac.h"
 | 
					#include "shell/browser/native_window_mac.h"
 | 
				
			||||||
#include "shell/browser/ui/cocoa/delayed_native_view_host.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/cocoa/electron_preview_item.h"
 | 
					#include "shell/browser/ui/cocoa/electron_preview_item.h"
 | 
				
			||||||
#include "shell/browser/ui/cocoa/electron_touch_bar.h"
 | 
					#include "shell/browser/ui/cocoa/electron_touch_bar.h"
 | 
				
			||||||
#include "shell/browser/ui/cocoa/root_view_mac.h"
 | 
					#include "shell/browser/ui/cocoa/root_view_mac.h"
 | 
				
			||||||
| 
						 | 
					@ -113,6 +111,7 @@ void SwizzleSwipeWithEvent(NSView* view, SEL swiz_selector) {
 | 
				
			||||||
                           method_getImplementation(new_swipe_with_event));
 | 
					                           method_getImplementation(new_swipe_with_event));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@implementation ElectronNSWindow
 | 
					@implementation ElectronNSWindow
 | 
				
			||||||
| 
						 | 
					@ -168,6 +167,10 @@ void SwizzleSwipeWithEvent(NSView* view, SEL swiz_selector) {
 | 
				
			||||||
  return self;
 | 
					  return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (void)cleanup {
 | 
				
			||||||
 | 
					  shell_ = nullptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (electron::NativeWindowMac*)shell {
 | 
					- (electron::NativeWindowMac*)shell {
 | 
				
			||||||
  return shell_;
 | 
					  return shell_;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -255,6 +258,17 @@ void SwizzleSwipeWithEvent(NSView* view, SEL swiz_selector) {
 | 
				
			||||||
    [super setFrame:windowFrame display:displayViews];
 | 
					    [super setFrame:windowFrame display:displayViews];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (void)orderWindow:(NSWindowOrderingMode)place relativeTo:(NSInteger)otherWin {
 | 
				
			||||||
 | 
					  if (shell_) {
 | 
				
			||||||
 | 
					    // We initialize the window in headless mode to allow painting before it is
 | 
				
			||||||
 | 
					    // shown, but we don't want the headless behavior of allowing the window to
 | 
				
			||||||
 | 
					    // be placed unconstrained.
 | 
				
			||||||
 | 
					    self.isHeadless = false;
 | 
				
			||||||
 | 
					    shell_->widget()->DisableHeadlessMode();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  [super orderWindow:place relativeTo:otherWin];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (id)accessibilityAttributeValue:(NSString*)attribute {
 | 
					- (id)accessibilityAttributeValue:(NSString*)attribute {
 | 
				
			||||||
  if ([attribute isEqual:NSAccessibilityEnabledAttribute])
 | 
					  if ([attribute isEqual:NSAccessibilityEnabledAttribute])
 | 
				
			||||||
    return [NSNumber numberWithBool:YES];
 | 
					    return [NSNumber numberWithBool:YES];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -365,6 +365,19 @@ using FullScreenTransitionState =
 | 
				
			||||||
      shell_->GetNativeWindow());
 | 
					      shell_->GetNativeWindow());
 | 
				
			||||||
  auto* bridged_view = bridge_host->GetInProcessNSWindowBridge();
 | 
					  auto* bridged_view = bridge_host->GetInProcessNSWindowBridge();
 | 
				
			||||||
  bridged_view->OnWindowWillClose();
 | 
					  bridged_view->OnWindowWillClose();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Native widget and its compositor have been destroyed upon close. We need
 | 
				
			||||||
 | 
					  // to detach contents view in order to prevent reusing its layer without
 | 
				
			||||||
 | 
					  // compositor in the `WebContentsViewMac::CreateViewForWidget`, leading to
 | 
				
			||||||
 | 
					  // `DCHECK` failure in `BrowserCompositorMac::SetParentUiLayer`.
 | 
				
			||||||
 | 
					  auto* contents_view =
 | 
				
			||||||
 | 
					      static_cast<views::WidgetDelegate*>(shell_)->GetContentsView();
 | 
				
			||||||
 | 
					  if (contents_view) {
 | 
				
			||||||
 | 
					    auto* parent = contents_view->parent();
 | 
				
			||||||
 | 
					    if (parent) {
 | 
				
			||||||
 | 
					      parent->RemoveChildView(contents_view);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (BOOL)windowShouldClose:(id)window {
 | 
					- (BOOL)windowShouldClose:(id)window {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -297,11 +297,6 @@ class InspectableWebContents::NetworkResourceLoader
 | 
				
			||||||
  base::TimeDelta retry_delay_;
 | 
					  base::TimeDelta retry_delay_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Implemented separately on each platform.
 | 
					 | 
				
			||||||
InspectableWebContentsView* CreateInspectableContentsView(
 | 
					 | 
				
			||||||
    InspectableWebContents* inspectable_web_contents);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// static
 | 
					 | 
				
			||||||
// static
 | 
					// static
 | 
				
			||||||
void InspectableWebContents::RegisterPrefs(PrefRegistrySimple* registry) {
 | 
					void InspectableWebContents::RegisterPrefs(PrefRegistrySimple* registry) {
 | 
				
			||||||
  registry->RegisterDictionaryPref(kDevToolsBoundsPref,
 | 
					  registry->RegisterDictionaryPref(kDevToolsBoundsPref,
 | 
				
			||||||
| 
						 | 
					@ -317,7 +312,7 @@ InspectableWebContents::InspectableWebContents(
 | 
				
			||||||
    : pref_service_(pref_service),
 | 
					    : pref_service_(pref_service),
 | 
				
			||||||
      web_contents_(std::move(web_contents)),
 | 
					      web_contents_(std::move(web_contents)),
 | 
				
			||||||
      is_guest_(is_guest),
 | 
					      is_guest_(is_guest),
 | 
				
			||||||
      view_(CreateInspectableContentsView(this)) {
 | 
					      view_(new InspectableWebContentsView(this)) {
 | 
				
			||||||
  const base::Value* bounds_dict =
 | 
					  const base::Value* bounds_dict =
 | 
				
			||||||
      &pref_service_->GetValue(kDevToolsBoundsPref);
 | 
					      &pref_service_->GetValue(kDevToolsBoundsPref);
 | 
				
			||||||
  if (bounds_dict->is_dict()) {
 | 
					  if (bounds_dict->is_dict()) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,12 +5,250 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
 | 
					#include "shell/browser/ui/inspectable_web_contents_view.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					#include <utility>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "base/memory/raw_ptr.h"
 | 
				
			||||||
 | 
					#include "base/strings/utf_string_conversions.h"
 | 
				
			||||||
 | 
					#include "shell/browser/ui/drag_util.h"
 | 
				
			||||||
 | 
					#include "shell/browser/ui/inspectable_web_contents.h"
 | 
				
			||||||
 | 
					#include "shell/browser/ui/inspectable_web_contents_delegate.h"
 | 
				
			||||||
 | 
					#include "shell/browser/ui/inspectable_web_contents_view_delegate.h"
 | 
				
			||||||
 | 
					#include "ui/base/models/image_model.h"
 | 
				
			||||||
 | 
					#include "ui/views/controls/label.h"
 | 
				
			||||||
 | 
					#include "ui/views/controls/webview/webview.h"
 | 
				
			||||||
 | 
					#include "ui/views/widget/widget.h"
 | 
				
			||||||
 | 
					#include "ui/views/widget/widget_delegate.h"
 | 
				
			||||||
 | 
					#include "ui/views/window/client_view.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace electron {
 | 
					namespace electron {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DevToolsWindowDelegate : public views::ClientView,
 | 
				
			||||||
 | 
					                               public views::WidgetDelegate {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  DevToolsWindowDelegate(InspectableWebContentsView* shell,
 | 
				
			||||||
 | 
					                         views::View* view,
 | 
				
			||||||
 | 
					                         views::Widget* widget)
 | 
				
			||||||
 | 
					      : views::ClientView(widget, view),
 | 
				
			||||||
 | 
					        shell_(shell),
 | 
				
			||||||
 | 
					        view_(view),
 | 
				
			||||||
 | 
					        widget_(widget) {
 | 
				
			||||||
 | 
					    SetOwnedByWidget(true);
 | 
				
			||||||
 | 
					    set_owned_by_client();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (shell->GetDelegate())
 | 
				
			||||||
 | 
					      icon_ = shell->GetDelegate()->GetDevToolsWindowIcon();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ~DevToolsWindowDelegate() override = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // disable copy
 | 
				
			||||||
 | 
					  DevToolsWindowDelegate(const DevToolsWindowDelegate&) = delete;
 | 
				
			||||||
 | 
					  DevToolsWindowDelegate& operator=(const DevToolsWindowDelegate&) = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // views::WidgetDelegate:
 | 
				
			||||||
 | 
					  views::View* GetInitiallyFocusedView() override { return view_; }
 | 
				
			||||||
 | 
					  std::u16string GetWindowTitle() const override { return shell_->GetTitle(); }
 | 
				
			||||||
 | 
					  ui::ImageModel GetWindowAppIcon() override { return GetWindowIcon(); }
 | 
				
			||||||
 | 
					  ui::ImageModel GetWindowIcon() override { return icon_; }
 | 
				
			||||||
 | 
					  views::Widget* GetWidget() override { return widget_; }
 | 
				
			||||||
 | 
					  const views::Widget* GetWidget() const override { return widget_; }
 | 
				
			||||||
 | 
					  views::View* GetContentsView() override { return view_; }
 | 
				
			||||||
 | 
					  views::ClientView* CreateClientView(views::Widget* widget) override {
 | 
				
			||||||
 | 
					    return this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // views::ClientView:
 | 
				
			||||||
 | 
					  views::CloseRequestResult OnWindowCloseRequested() override {
 | 
				
			||||||
 | 
					    shell_->inspectable_web_contents()->CloseDevTools();
 | 
				
			||||||
 | 
					    return views::CloseRequestResult::kCannotClose;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  raw_ptr<InspectableWebContentsView> shell_;
 | 
				
			||||||
 | 
					  raw_ptr<views::View> view_;
 | 
				
			||||||
 | 
					  raw_ptr<views::Widget> widget_;
 | 
				
			||||||
 | 
					  ui::ImageModel icon_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
InspectableWebContentsView::InspectableWebContentsView(
 | 
					InspectableWebContentsView::InspectableWebContentsView(
 | 
				
			||||||
    InspectableWebContents* inspectable_web_contents)
 | 
					    InspectableWebContents* inspectable_web_contents)
 | 
				
			||||||
    : inspectable_web_contents_(inspectable_web_contents) {}
 | 
					    : inspectable_web_contents_(inspectable_web_contents),
 | 
				
			||||||
 | 
					      devtools_web_view_(new views::WebView(nullptr)),
 | 
				
			||||||
 | 
					      title_(u"Developer Tools") {
 | 
				
			||||||
 | 
					  if (!inspectable_web_contents_->is_guest() &&
 | 
				
			||||||
 | 
					      inspectable_web_contents_->GetWebContents()->GetNativeView()) {
 | 
				
			||||||
 | 
					    auto* contents_web_view = new views::WebView(nullptr);
 | 
				
			||||||
 | 
					    contents_web_view->SetWebContents(
 | 
				
			||||||
 | 
					        inspectable_web_contents_->GetWebContents());
 | 
				
			||||||
 | 
					    contents_web_view_ = contents_web_view;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    no_contents_view_ = new views::Label(u"No content under offscreen mode");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
InspectableWebContentsView::~InspectableWebContentsView() = default;
 | 
					  devtools_web_view_->SetVisible(false);
 | 
				
			||||||
 | 
					  AddChildView(devtools_web_view_.get());
 | 
				
			||||||
 | 
					  AddChildView(GetContentsView());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					InspectableWebContentsView::~InspectableWebContentsView() {
 | 
				
			||||||
 | 
					  if (devtools_window_)
 | 
				
			||||||
 | 
					    inspectable_web_contents()->SaveDevToolsBounds(
 | 
				
			||||||
 | 
					        devtools_window_->GetWindowBoundsInScreen());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InspectableWebContentsView::SetCornerRadii(
 | 
				
			||||||
 | 
					    const gfx::RoundedCornersF& corner_radii) {
 | 
				
			||||||
 | 
					  // WebView won't exist for offscreen rendering.
 | 
				
			||||||
 | 
					  if (contents_web_view_) {
 | 
				
			||||||
 | 
					    contents_web_view_->holder()->SetCornerRadii(corner_radii);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InspectableWebContentsView::ShowDevTools(bool activate) {
 | 
				
			||||||
 | 
					  if (devtools_visible_)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  devtools_visible_ = true;
 | 
				
			||||||
 | 
					  if (devtools_window_) {
 | 
				
			||||||
 | 
					    devtools_window_web_view_->SetWebContents(
 | 
				
			||||||
 | 
					        inspectable_web_contents_->GetDevToolsWebContents());
 | 
				
			||||||
 | 
					    devtools_window_->SetBounds(inspectable_web_contents()->dev_tools_bounds());
 | 
				
			||||||
 | 
					    if (activate) {
 | 
				
			||||||
 | 
					      devtools_window_->Show();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      devtools_window_->ShowInactive();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update draggable regions to account for the new dock position.
 | 
				
			||||||
 | 
					    if (GetDelegate())
 | 
				
			||||||
 | 
					      GetDelegate()->DevToolsResized();
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    devtools_web_view_->SetVisible(true);
 | 
				
			||||||
 | 
					    devtools_web_view_->SetWebContents(
 | 
				
			||||||
 | 
					        inspectable_web_contents_->GetDevToolsWebContents());
 | 
				
			||||||
 | 
					    devtools_web_view_->RequestFocus();
 | 
				
			||||||
 | 
					    DeprecatedLayoutImmediately();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InspectableWebContentsView::CloseDevTools() {
 | 
				
			||||||
 | 
					  if (!devtools_visible_)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  devtools_visible_ = false;
 | 
				
			||||||
 | 
					  if (devtools_window_) {
 | 
				
			||||||
 | 
					    auto save_bounds = devtools_window_->IsMinimized()
 | 
				
			||||||
 | 
					                           ? devtools_window_->GetRestoredBounds()
 | 
				
			||||||
 | 
					                           : devtools_window_->GetWindowBoundsInScreen();
 | 
				
			||||||
 | 
					    inspectable_web_contents()->SaveDevToolsBounds(save_bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    devtools_window_.reset();
 | 
				
			||||||
 | 
					    devtools_window_web_view_ = nullptr;
 | 
				
			||||||
 | 
					    devtools_window_delegate_ = nullptr;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    devtools_web_view_->SetVisible(false);
 | 
				
			||||||
 | 
					    devtools_web_view_->SetWebContents(nullptr);
 | 
				
			||||||
 | 
					    DeprecatedLayoutImmediately();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool InspectableWebContentsView::IsDevToolsViewShowing() {
 | 
				
			||||||
 | 
					  return devtools_visible_;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool InspectableWebContentsView::IsDevToolsViewFocused() {
 | 
				
			||||||
 | 
					  if (devtools_window_web_view_)
 | 
				
			||||||
 | 
					    return devtools_window_web_view_->HasFocus();
 | 
				
			||||||
 | 
					  else if (devtools_web_view_)
 | 
				
			||||||
 | 
					    return devtools_web_view_->HasFocus();
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InspectableWebContentsView::SetIsDocked(bool docked, bool activate) {
 | 
				
			||||||
 | 
					  CloseDevTools();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!docked) {
 | 
				
			||||||
 | 
					    devtools_window_ = std::make_unique<views::Widget>();
 | 
				
			||||||
 | 
					    devtools_window_web_view_ = new views::WebView(nullptr);
 | 
				
			||||||
 | 
					    devtools_window_delegate_ = new DevToolsWindowDelegate(
 | 
				
			||||||
 | 
					        this, devtools_window_web_view_, devtools_window_.get());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    views::Widget::InitParams params(
 | 
				
			||||||
 | 
					        views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
 | 
				
			||||||
 | 
					        views::Widget::InitParams::TYPE_WINDOW);
 | 
				
			||||||
 | 
					    params.delegate = devtools_window_delegate_;
 | 
				
			||||||
 | 
					    params.bounds = inspectable_web_contents()->dev_tools_bounds();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if BUILDFLAG(IS_LINUX)
 | 
				
			||||||
 | 
					    params.wm_role_name = "devtools";
 | 
				
			||||||
 | 
					    if (GetDelegate())
 | 
				
			||||||
 | 
					      GetDelegate()->GetDevToolsWindowWMClass(¶ms.wm_class_name,
 | 
				
			||||||
 | 
					                                              ¶ms.wm_class_class);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    devtools_window_->Init(std::move(params));
 | 
				
			||||||
 | 
					    devtools_window_->UpdateWindowIcon();
 | 
				
			||||||
 | 
					    devtools_window_->widget_delegate()->SetHasWindowSizeControls(true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ShowDevTools(activate);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InspectableWebContentsView::SetContentsResizingStrategy(
 | 
				
			||||||
 | 
					    const DevToolsContentsResizingStrategy& strategy) {
 | 
				
			||||||
 | 
					  strategy_.CopyFrom(strategy);
 | 
				
			||||||
 | 
					  DeprecatedLayoutImmediately();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InspectableWebContentsView::SetTitle(const std::u16string& title) {
 | 
				
			||||||
 | 
					  if (devtools_window_) {
 | 
				
			||||||
 | 
					    title_ = title;
 | 
				
			||||||
 | 
					    devtools_window_->UpdateWindowTitle();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const std::u16string InspectableWebContentsView::GetTitle() {
 | 
				
			||||||
 | 
					  return title_;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InspectableWebContentsView::Layout(PassKey) {
 | 
				
			||||||
 | 
					  if (!devtools_web_view_->GetVisible()) {
 | 
				
			||||||
 | 
					    GetContentsView()->SetBoundsRect(GetContentsBounds());
 | 
				
			||||||
 | 
					    // Propagate layout call to all children, for example browser views.
 | 
				
			||||||
 | 
					    LayoutSuperclass<View>(this);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  gfx::Size container_size(width(), height());
 | 
				
			||||||
 | 
					  gfx::Rect new_devtools_bounds;
 | 
				
			||||||
 | 
					  gfx::Rect new_contents_bounds;
 | 
				
			||||||
 | 
					  ApplyDevToolsContentsResizingStrategy(
 | 
				
			||||||
 | 
					      strategy_, container_size, &new_devtools_bounds, &new_contents_bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // DevTools cares about the specific position, so we have to compensate RTL
 | 
				
			||||||
 | 
					  // layout here.
 | 
				
			||||||
 | 
					  new_devtools_bounds.set_x(GetMirroredXForRect(new_devtools_bounds));
 | 
				
			||||||
 | 
					  new_contents_bounds.set_x(GetMirroredXForRect(new_contents_bounds));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  devtools_web_view_->SetBoundsRect(new_devtools_bounds);
 | 
				
			||||||
 | 
					  GetContentsView()->SetBoundsRect(new_contents_bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Propagate layout call to all children, for example browser views.
 | 
				
			||||||
 | 
					  LayoutSuperclass<View>(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (GetDelegate())
 | 
				
			||||||
 | 
					    GetDelegate()->DevToolsResized();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					views::View* InspectableWebContentsView::GetContentsView() const {
 | 
				
			||||||
 | 
					  DCHECK(contents_web_view_ || no_contents_view_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return contents_web_view_ ? contents_web_view_ : no_contents_view_;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace electron
 | 
					}  // namespace electron
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,13 +9,9 @@
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "base/memory/raw_ptr.h"
 | 
					#include "base/memory/raw_ptr.h"
 | 
				
			||||||
#include "build/build_config.h"
 | 
					#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC)
 | 
					 | 
				
			||||||
#include "ui/views/view.h"
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#include "ui/gfx/native_widget_types.h"
 | 
					#include "ui/gfx/native_widget_types.h"
 | 
				
			||||||
#endif
 | 
					#include "ui/views/view.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DevToolsContentsResizingStrategy;
 | 
					class DevToolsContentsResizingStrategy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,23 +19,22 @@ namespace gfx {
 | 
				
			||||||
class RoundedCornersF;
 | 
					class RoundedCornersF;
 | 
				
			||||||
}  // namespace gfx
 | 
					}  // namespace gfx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(TOOLKIT_VIEWS)
 | 
					 | 
				
			||||||
namespace views {
 | 
					namespace views {
 | 
				
			||||||
class View;
 | 
					 | 
				
			||||||
class WebView;
 | 
					class WebView;
 | 
				
			||||||
 | 
					class Widget;
 | 
				
			||||||
 | 
					class WidgetDelegate;
 | 
				
			||||||
}  // namespace views
 | 
					}  // namespace views
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace electron {
 | 
					namespace electron {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InspectableWebContents;
 | 
					class InspectableWebContents;
 | 
				
			||||||
class InspectableWebContentsViewDelegate;
 | 
					class InspectableWebContentsViewDelegate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InspectableWebContentsView {
 | 
					class InspectableWebContentsView : public views::View {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  explicit InspectableWebContentsView(
 | 
					  explicit InspectableWebContentsView(
 | 
				
			||||||
      InspectableWebContents* inspectable_web_contents);
 | 
					      InspectableWebContents* inspectable_web_contents);
 | 
				
			||||||
  virtual ~InspectableWebContentsView();
 | 
					  ~InspectableWebContentsView() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  InspectableWebContents* inspectable_web_contents() {
 | 
					  InspectableWebContents* inspectable_web_contents() {
 | 
				
			||||||
    return inspectable_web_contents_;
 | 
					    return inspectable_web_contents_;
 | 
				
			||||||
| 
						 | 
					@ -51,32 +46,40 @@ class InspectableWebContentsView {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  InspectableWebContentsViewDelegate* GetDelegate() const { return delegate_; }
 | 
					  InspectableWebContentsViewDelegate* GetDelegate() const { return delegate_; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC)
 | 
					  void SetCornerRadii(const gfx::RoundedCornersF& corner_radii);
 | 
				
			||||||
  // Returns the container control, which has devtools view attached.
 | 
					 | 
				
			||||||
  virtual views::View* GetView() = 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
  virtual gfx::NativeView GetNativeView() const = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void ShowDevTools(bool activate) = 0;
 | 
					  void ShowDevTools(bool activate);
 | 
				
			||||||
  virtual void SetCornerRadii(const gfx::RoundedCornersF& corner_radii) = 0;
 | 
					  void CloseDevTools();
 | 
				
			||||||
  // Hide the DevTools view.
 | 
					  bool IsDevToolsViewShowing();
 | 
				
			||||||
  virtual void CloseDevTools() = 0;
 | 
					  bool IsDevToolsViewFocused();
 | 
				
			||||||
  virtual bool IsDevToolsViewShowing() = 0;
 | 
					  void SetIsDocked(bool docked, bool activate);
 | 
				
			||||||
  virtual bool IsDevToolsViewFocused() = 0;
 | 
					  void SetContentsResizingStrategy(
 | 
				
			||||||
  virtual void SetIsDocked(bool docked, bool activate) = 0;
 | 
					      const DevToolsContentsResizingStrategy& strategy);
 | 
				
			||||||
  virtual void SetContentsResizingStrategy(
 | 
					  void SetTitle(const std::u16string& title);
 | 
				
			||||||
      const DevToolsContentsResizingStrategy& strategy) = 0;
 | 
					  const std::u16string GetTitle();
 | 
				
			||||||
  virtual void SetTitle(const std::u16string& title) = 0;
 | 
					
 | 
				
			||||||
  virtual const std::u16string GetTitle() = 0;
 | 
					  // views::View:
 | 
				
			||||||
 | 
					  void Layout(PassKey) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  views::View* GetContentsView() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 protected:
 | 
					 | 
				
			||||||
  // Owns us.
 | 
					  // Owns us.
 | 
				
			||||||
  raw_ptr<InspectableWebContents> inspectable_web_contents_;
 | 
					  raw_ptr<InspectableWebContents> inspectable_web_contents_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 | 
				
			||||||
  raw_ptr<InspectableWebContentsViewDelegate> delegate_ =
 | 
					  raw_ptr<InspectableWebContentsViewDelegate> delegate_ =
 | 
				
			||||||
      nullptr;  // weak references.
 | 
					      nullptr;  // weak references.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::unique_ptr<views::Widget> devtools_window_;
 | 
				
			||||||
 | 
					  raw_ptr<views::WebView> devtools_window_web_view_ = nullptr;
 | 
				
			||||||
 | 
					  raw_ptr<views::WebView> contents_web_view_ = nullptr;
 | 
				
			||||||
 | 
					  raw_ptr<views::View> no_contents_view_ = nullptr;
 | 
				
			||||||
 | 
					  raw_ptr<views::WebView> devtools_web_view_ = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DevToolsContentsResizingStrategy strategy_;
 | 
				
			||||||
 | 
					  bool devtools_visible_ = false;
 | 
				
			||||||
 | 
					  raw_ptr<views::WidgetDelegate> devtools_window_delegate_ = nullptr;
 | 
				
			||||||
 | 
					  std::u16string title_;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace electron
 | 
					}  // namespace electron
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,42 +0,0 @@
 | 
				
			||||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 | 
					 | 
				
			||||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
 | 
					 | 
				
			||||||
// Use of this source code is governed by a BSD-style license that can be
 | 
					 | 
				
			||||||
// found in the LICENSE-CHROMIUM file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef ELECTRON_SHELL_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_MAC_H_
 | 
					 | 
				
			||||||
#define ELECTRON_SHELL_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_MAC_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@class ElectronInspectableWebContentsView;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace electron {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class InspectableWebContentsViewMac : public InspectableWebContentsView {
 | 
					 | 
				
			||||||
 public:
 | 
					 | 
				
			||||||
  explicit InspectableWebContentsViewMac(
 | 
					 | 
				
			||||||
      InspectableWebContents* inspectable_web_contents);
 | 
					 | 
				
			||||||
  InspectableWebContentsViewMac(const InspectableWebContentsViewMac&) = delete;
 | 
					 | 
				
			||||||
  InspectableWebContentsViewMac& operator=(
 | 
					 | 
				
			||||||
      const InspectableWebContentsViewMac&) = delete;
 | 
					 | 
				
			||||||
  ~InspectableWebContentsViewMac() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  gfx::NativeView GetNativeView() const override;
 | 
					 | 
				
			||||||
  void SetCornerRadii(const gfx::RoundedCornersF& corner_radii) override;
 | 
					 | 
				
			||||||
  void ShowDevTools(bool activate) override;
 | 
					 | 
				
			||||||
  void CloseDevTools() override;
 | 
					 | 
				
			||||||
  bool IsDevToolsViewShowing() override;
 | 
					 | 
				
			||||||
  bool IsDevToolsViewFocused() override;
 | 
					 | 
				
			||||||
  void SetIsDocked(bool docked, bool activate) override;
 | 
					 | 
				
			||||||
  void SetContentsResizingStrategy(
 | 
					 | 
				
			||||||
      const DevToolsContentsResizingStrategy& strategy) override;
 | 
					 | 
				
			||||||
  void SetTitle(const std::u16string& title) override;
 | 
					 | 
				
			||||||
  const std::u16string GetTitle() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 private:
 | 
					 | 
				
			||||||
  ElectronInspectableWebContentsView* __strong view_;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace electron
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif  // ELECTRON_SHELL_BROWSER_UI_INSPECTABLE_WEB_CONTENTS_VIEW_MAC_H_
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,75 +0,0 @@
 | 
				
			||||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 | 
					 | 
				
			||||||
// Copyright (c) 2013 Adam Roben <adam@roben.org>. All rights reserved.
 | 
					 | 
				
			||||||
// Use of this source code is governed by a BSD-style license that can be
 | 
					 | 
				
			||||||
// found in the LICENSE-CHROMIUM file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_view_mac.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "base/strings/sys_string_conversions.h"
 | 
					 | 
				
			||||||
#import "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_view_delegate.h"
 | 
					 | 
				
			||||||
#include "ui/gfx/geometry/rounded_corners_f.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace electron {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
InspectableWebContentsView* CreateInspectableContentsView(
 | 
					 | 
				
			||||||
    InspectableWebContents* inspectable_web_contents) {
 | 
					 | 
				
			||||||
  return new InspectableWebContentsViewMac(inspectable_web_contents);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
InspectableWebContentsViewMac::InspectableWebContentsViewMac(
 | 
					 | 
				
			||||||
    InspectableWebContents* inspectable_web_contents)
 | 
					 | 
				
			||||||
    : InspectableWebContentsView(inspectable_web_contents),
 | 
					 | 
				
			||||||
      view_([[ElectronInspectableWebContentsView alloc]
 | 
					 | 
				
			||||||
          initWithInspectableWebContentsViewMac:this]) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
InspectableWebContentsViewMac::~InspectableWebContentsViewMac() {
 | 
					 | 
				
			||||||
  [[NSNotificationCenter defaultCenter] removeObserver:view_];
 | 
					 | 
				
			||||||
  CloseDevTools();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
gfx::NativeView InspectableWebContentsViewMac::GetNativeView() const {
 | 
					 | 
				
			||||||
  return view_;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewMac::SetCornerRadii(
 | 
					 | 
				
			||||||
    const gfx::RoundedCornersF& corner_radii) {
 | 
					 | 
				
			||||||
  // We can assume all four values are identical.
 | 
					 | 
				
			||||||
  [view_ setCornerRadii:corner_radii.upper_left()];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewMac::ShowDevTools(bool activate) {
 | 
					 | 
				
			||||||
  [view_ setDevToolsVisible:YES activate:activate];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewMac::CloseDevTools() {
 | 
					 | 
				
			||||||
  [view_ setDevToolsVisible:NO activate:NO];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool InspectableWebContentsViewMac::IsDevToolsViewShowing() {
 | 
					 | 
				
			||||||
  return [view_ isDevToolsVisible];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool InspectableWebContentsViewMac::IsDevToolsViewFocused() {
 | 
					 | 
				
			||||||
  return [view_ isDevToolsFocused];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewMac::SetIsDocked(bool docked, bool activate) {
 | 
					 | 
				
			||||||
  [view_ setIsDocked:docked activate:activate];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewMac::SetContentsResizingStrategy(
 | 
					 | 
				
			||||||
    const DevToolsContentsResizingStrategy& strategy) {
 | 
					 | 
				
			||||||
  [view_ setContentsResizingStrategy:strategy];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewMac::SetTitle(const std::u16string& title) {
 | 
					 | 
				
			||||||
  [view_ setTitle:base::SysUTF16ToNSString(title)];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const std::u16string InspectableWebContentsViewMac::GetTitle() {
 | 
					 | 
				
			||||||
  return base::SysNSStringToUTF16([view_ getTitle]);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace electron
 | 
					 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,8 @@
 | 
				
			||||||
#include "shell/browser/ui/views/frameless_view.h"
 | 
					#include "shell/browser/ui/views/frameless_view.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "shell/browser/native_window_views.h"
 | 
					#include "shell/browser/native_window_views.h"
 | 
				
			||||||
 | 
					#include "shell/browser/ui/inspectable_web_contents_view.h"
 | 
				
			||||||
 | 
					#include "ui/aura/window.h"
 | 
				
			||||||
#include "ui/base/hit_test.h"
 | 
					#include "ui/base/hit_test.h"
 | 
				
			||||||
#include "ui/base/metadata/metadata_impl_macros.h"
 | 
					#include "ui/base/metadata/metadata_impl_macros.h"
 | 
				
			||||||
#include "ui/views/widget/widget.h"
 | 
					#include "ui/views/widget/widget.h"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,257 +0,0 @@
 | 
				
			||||||
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
 | 
					 | 
				
			||||||
// Use of this source code is governed by a BSD-style license that can be
 | 
					 | 
				
			||||||
// found in the LICENSE-CHROMIUM file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "shell/browser/ui/views/inspectable_web_contents_view_views.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <memory>
 | 
					 | 
				
			||||||
#include <utility>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "base/memory/raw_ptr.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/drag_util.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_delegate.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_view_delegate.h"
 | 
					 | 
				
			||||||
#include "ui/base/models/image_model.h"
 | 
					 | 
				
			||||||
#include "ui/gfx/geometry/rounded_corners_f.h"
 | 
					 | 
				
			||||||
#include "ui/views/controls/label.h"
 | 
					 | 
				
			||||||
#include "ui/views/controls/webview/webview.h"
 | 
					 | 
				
			||||||
#include "ui/views/widget/widget.h"
 | 
					 | 
				
			||||||
#include "ui/views/widget/widget_delegate.h"
 | 
					 | 
				
			||||||
#include "ui/views/window/client_view.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace electron {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DevToolsWindowDelegate : public views::ClientView,
 | 
					 | 
				
			||||||
                               public views::WidgetDelegate {
 | 
					 | 
				
			||||||
 public:
 | 
					 | 
				
			||||||
  DevToolsWindowDelegate(InspectableWebContentsViewViews* shell,
 | 
					 | 
				
			||||||
                         views::View* view,
 | 
					 | 
				
			||||||
                         views::Widget* widget)
 | 
					 | 
				
			||||||
      : views::ClientView(widget, view),
 | 
					 | 
				
			||||||
        shell_(shell),
 | 
					 | 
				
			||||||
        view_(view),
 | 
					 | 
				
			||||||
        widget_(widget) {
 | 
					 | 
				
			||||||
    SetOwnedByWidget(true);
 | 
					 | 
				
			||||||
    set_owned_by_client();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (shell->GetDelegate())
 | 
					 | 
				
			||||||
      icon_ = shell->GetDelegate()->GetDevToolsWindowIcon();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ~DevToolsWindowDelegate() override = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // disable copy
 | 
					 | 
				
			||||||
  DevToolsWindowDelegate(const DevToolsWindowDelegate&) = delete;
 | 
					 | 
				
			||||||
  DevToolsWindowDelegate& operator=(const DevToolsWindowDelegate&) = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // views::WidgetDelegate:
 | 
					 | 
				
			||||||
  views::View* GetInitiallyFocusedView() override { return view_; }
 | 
					 | 
				
			||||||
  std::u16string GetWindowTitle() const override { return shell_->GetTitle(); }
 | 
					 | 
				
			||||||
  ui::ImageModel GetWindowAppIcon() override { return GetWindowIcon(); }
 | 
					 | 
				
			||||||
  ui::ImageModel GetWindowIcon() override { return icon_; }
 | 
					 | 
				
			||||||
  views::Widget* GetWidget() override { return widget_; }
 | 
					 | 
				
			||||||
  const views::Widget* GetWidget() const override { return widget_; }
 | 
					 | 
				
			||||||
  views::View* GetContentsView() override { return view_; }
 | 
					 | 
				
			||||||
  views::ClientView* CreateClientView(views::Widget* widget) override {
 | 
					 | 
				
			||||||
    return this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // views::ClientView:
 | 
					 | 
				
			||||||
  views::CloseRequestResult OnWindowCloseRequested() override {
 | 
					 | 
				
			||||||
    shell_->inspectable_web_contents()->CloseDevTools();
 | 
					 | 
				
			||||||
    return views::CloseRequestResult::kCannotClose;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 private:
 | 
					 | 
				
			||||||
  raw_ptr<InspectableWebContentsViewViews> shell_;
 | 
					 | 
				
			||||||
  raw_ptr<views::View> view_;
 | 
					 | 
				
			||||||
  raw_ptr<views::Widget> widget_;
 | 
					 | 
				
			||||||
  ui::ImageModel icon_;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
InspectableWebContentsView* CreateInspectableContentsView(
 | 
					 | 
				
			||||||
    InspectableWebContents* inspectable_web_contents) {
 | 
					 | 
				
			||||||
  return new InspectableWebContentsViewViews(inspectable_web_contents);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
InspectableWebContentsViewViews::InspectableWebContentsViewViews(
 | 
					 | 
				
			||||||
    InspectableWebContents* inspectable_web_contents)
 | 
					 | 
				
			||||||
    : InspectableWebContentsView(inspectable_web_contents),
 | 
					 | 
				
			||||||
      devtools_web_view_(new views::WebView(nullptr)),
 | 
					 | 
				
			||||||
      title_(u"Developer Tools") {
 | 
					 | 
				
			||||||
  if (!inspectable_web_contents_->is_guest() &&
 | 
					 | 
				
			||||||
      inspectable_web_contents_->GetWebContents()->GetNativeView()) {
 | 
					 | 
				
			||||||
    auto* contents_web_view = new views::WebView(nullptr);
 | 
					 | 
				
			||||||
    contents_web_view->SetWebContents(
 | 
					 | 
				
			||||||
        inspectable_web_contents_->GetWebContents());
 | 
					 | 
				
			||||||
    contents_view_ = contents_web_view_ = contents_web_view;
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    contents_view_ = new views::Label(u"No content under offscreen mode");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  devtools_web_view_->SetVisible(false);
 | 
					 | 
				
			||||||
  AddChildView(devtools_web_view_.get());
 | 
					 | 
				
			||||||
  AddChildView(contents_view_.get());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
InspectableWebContentsViewViews::~InspectableWebContentsViewViews() {
 | 
					 | 
				
			||||||
  if (devtools_window_)
 | 
					 | 
				
			||||||
    inspectable_web_contents()->SaveDevToolsBounds(
 | 
					 | 
				
			||||||
        devtools_window_->GetWindowBoundsInScreen());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
views::View* InspectableWebContentsViewViews::GetView() {
 | 
					 | 
				
			||||||
  return this;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewViews::SetCornerRadii(
 | 
					 | 
				
			||||||
    const gfx::RoundedCornersF& corner_radii) {
 | 
					 | 
				
			||||||
  // WebView won't exist for offscreen rendering.
 | 
					 | 
				
			||||||
  if (contents_web_view_) {
 | 
					 | 
				
			||||||
    contents_web_view_->holder()->SetCornerRadii(
 | 
					 | 
				
			||||||
        gfx::RoundedCornersF(corner_radii));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewViews::ShowDevTools(bool activate) {
 | 
					 | 
				
			||||||
  if (devtools_visible_)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  devtools_visible_ = true;
 | 
					 | 
				
			||||||
  if (devtools_window_) {
 | 
					 | 
				
			||||||
    devtools_window_web_view_->SetWebContents(
 | 
					 | 
				
			||||||
        inspectable_web_contents_->GetDevToolsWebContents());
 | 
					 | 
				
			||||||
    devtools_window_->SetBounds(inspectable_web_contents()->dev_tools_bounds());
 | 
					 | 
				
			||||||
    if (activate) {
 | 
					 | 
				
			||||||
      devtools_window_->Show();
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      devtools_window_->ShowInactive();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Update draggable regions to account for the new dock position.
 | 
					 | 
				
			||||||
    if (GetDelegate())
 | 
					 | 
				
			||||||
      GetDelegate()->DevToolsResized();
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    devtools_web_view_->SetVisible(true);
 | 
					 | 
				
			||||||
    devtools_web_view_->SetWebContents(
 | 
					 | 
				
			||||||
        inspectable_web_contents_->GetDevToolsWebContents());
 | 
					 | 
				
			||||||
    devtools_web_view_->RequestFocus();
 | 
					 | 
				
			||||||
    DeprecatedLayoutImmediately();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewViews::CloseDevTools() {
 | 
					 | 
				
			||||||
  if (!devtools_visible_)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  devtools_visible_ = false;
 | 
					 | 
				
			||||||
  if (devtools_window_) {
 | 
					 | 
				
			||||||
    auto save_bounds = devtools_window_->IsMinimized()
 | 
					 | 
				
			||||||
                           ? devtools_window_->GetRestoredBounds()
 | 
					 | 
				
			||||||
                           : devtools_window_->GetWindowBoundsInScreen();
 | 
					 | 
				
			||||||
    inspectable_web_contents()->SaveDevToolsBounds(save_bounds);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    devtools_window_.reset();
 | 
					 | 
				
			||||||
    devtools_window_web_view_ = nullptr;
 | 
					 | 
				
			||||||
    devtools_window_delegate_ = nullptr;
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    devtools_web_view_->SetVisible(false);
 | 
					 | 
				
			||||||
    devtools_web_view_->SetWebContents(nullptr);
 | 
					 | 
				
			||||||
    DeprecatedLayoutImmediately();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool InspectableWebContentsViewViews::IsDevToolsViewShowing() {
 | 
					 | 
				
			||||||
  return devtools_visible_;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool InspectableWebContentsViewViews::IsDevToolsViewFocused() {
 | 
					 | 
				
			||||||
  if (devtools_window_web_view_)
 | 
					 | 
				
			||||||
    return devtools_window_web_view_->HasFocus();
 | 
					 | 
				
			||||||
  else if (devtools_web_view_)
 | 
					 | 
				
			||||||
    return devtools_web_view_->HasFocus();
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewViews::SetIsDocked(bool docked, bool activate) {
 | 
					 | 
				
			||||||
  CloseDevTools();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!docked) {
 | 
					 | 
				
			||||||
    devtools_window_ = std::make_unique<views::Widget>();
 | 
					 | 
				
			||||||
    devtools_window_web_view_ = new views::WebView(nullptr);
 | 
					 | 
				
			||||||
    devtools_window_delegate_ = new DevToolsWindowDelegate(
 | 
					 | 
				
			||||||
        this, devtools_window_web_view_, devtools_window_.get());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    views::Widget::InitParams params{
 | 
					 | 
				
			||||||
        views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET};
 | 
					 | 
				
			||||||
    params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
 | 
					 | 
				
			||||||
    params.delegate = devtools_window_delegate_;
 | 
					 | 
				
			||||||
    params.bounds = inspectable_web_contents()->dev_tools_bounds();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if BUILDFLAG(IS_LINUX)
 | 
					 | 
				
			||||||
    params.wm_role_name = "devtools";
 | 
					 | 
				
			||||||
    if (GetDelegate())
 | 
					 | 
				
			||||||
      GetDelegate()->GetDevToolsWindowWMClass(¶ms.wm_class_name,
 | 
					 | 
				
			||||||
                                              ¶ms.wm_class_class);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    devtools_window_->Init(std::move(params));
 | 
					 | 
				
			||||||
    devtools_window_->UpdateWindowIcon();
 | 
					 | 
				
			||||||
    devtools_window_->widget_delegate()->SetHasWindowSizeControls(true);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ShowDevTools(activate);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewViews::SetContentsResizingStrategy(
 | 
					 | 
				
			||||||
    const DevToolsContentsResizingStrategy& strategy) {
 | 
					 | 
				
			||||||
  strategy_.CopyFrom(strategy);
 | 
					 | 
				
			||||||
  DeprecatedLayoutImmediately();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewViews::SetTitle(const std::u16string& title) {
 | 
					 | 
				
			||||||
  if (devtools_window_) {
 | 
					 | 
				
			||||||
    title_ = title;
 | 
					 | 
				
			||||||
    devtools_window_->UpdateWindowTitle();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const std::u16string InspectableWebContentsViewViews::GetTitle() {
 | 
					 | 
				
			||||||
  return title_;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void InspectableWebContentsViewViews::Layout(PassKey) {
 | 
					 | 
				
			||||||
  if (!devtools_web_view_->GetVisible()) {
 | 
					 | 
				
			||||||
    contents_view_->SetBoundsRect(GetContentsBounds());
 | 
					 | 
				
			||||||
    // Propagate layout call to all children, for example browser views.
 | 
					 | 
				
			||||||
    LayoutSuperclass<View>(this);
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  gfx::Size container_size(width(), height());
 | 
					 | 
				
			||||||
  gfx::Rect new_devtools_bounds;
 | 
					 | 
				
			||||||
  gfx::Rect new_contents_bounds;
 | 
					 | 
				
			||||||
  ApplyDevToolsContentsResizingStrategy(
 | 
					 | 
				
			||||||
      strategy_, container_size, &new_devtools_bounds, &new_contents_bounds);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // DevTools cares about the specific position, so we have to compensate RTL
 | 
					 | 
				
			||||||
  // layout here.
 | 
					 | 
				
			||||||
  new_devtools_bounds.set_x(GetMirroredXForRect(new_devtools_bounds));
 | 
					 | 
				
			||||||
  new_contents_bounds.set_x(GetMirroredXForRect(new_contents_bounds));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  devtools_web_view_->SetBoundsRect(new_devtools_bounds);
 | 
					 | 
				
			||||||
  contents_view_->SetBoundsRect(new_contents_bounds);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Propagate layout call to all children, for example browser views.
 | 
					 | 
				
			||||||
  LayoutSuperclass<View>(this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (GetDelegate())
 | 
					 | 
				
			||||||
    GetDelegate()->DevToolsResized();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace electron
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,63 +0,0 @@
 | 
				
			||||||
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
 | 
					 | 
				
			||||||
// Use of this source code is governed by a BSD-style license that can be
 | 
					 | 
				
			||||||
// found in the LICENSE-CHROMIUM file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef ELECTRON_SHELL_BROWSER_UI_VIEWS_INSPECTABLE_WEB_CONTENTS_VIEW_VIEWS_H_
 | 
					 | 
				
			||||||
#define ELECTRON_SHELL_BROWSER_UI_VIEWS_INSPECTABLE_WEB_CONTENTS_VIEW_VIEWS_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <memory>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "base/compiler_specific.h"
 | 
					 | 
				
			||||||
#include "base/memory/raw_ptr.h"
 | 
					 | 
				
			||||||
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
 | 
					 | 
				
			||||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
 | 
					 | 
				
			||||||
#include "third_party/skia/include/core/SkRegion.h"
 | 
					 | 
				
			||||||
#include "ui/views/view.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace views {
 | 
					 | 
				
			||||||
class WebView;
 | 
					 | 
				
			||||||
class Widget;
 | 
					 | 
				
			||||||
class WidgetDelegate;
 | 
					 | 
				
			||||||
}  // namespace views
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace electron {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class InspectableWebContentsViewViews : public InspectableWebContentsView,
 | 
					 | 
				
			||||||
                                        public views::View {
 | 
					 | 
				
			||||||
 public:
 | 
					 | 
				
			||||||
  explicit InspectableWebContentsViewViews(
 | 
					 | 
				
			||||||
      InspectableWebContents* inspectable_web_contents);
 | 
					 | 
				
			||||||
  ~InspectableWebContentsViewViews() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // InspectableWebContentsView:
 | 
					 | 
				
			||||||
  views::View* GetView() override;
 | 
					 | 
				
			||||||
  void ShowDevTools(bool activate) override;
 | 
					 | 
				
			||||||
  void SetCornerRadii(const gfx::RoundedCornersF& corner_radii) override;
 | 
					 | 
				
			||||||
  void CloseDevTools() override;
 | 
					 | 
				
			||||||
  bool IsDevToolsViewShowing() override;
 | 
					 | 
				
			||||||
  bool IsDevToolsViewFocused() override;
 | 
					 | 
				
			||||||
  void SetIsDocked(bool docked, bool activate) override;
 | 
					 | 
				
			||||||
  void SetContentsResizingStrategy(
 | 
					 | 
				
			||||||
      const DevToolsContentsResizingStrategy& strategy) override;
 | 
					 | 
				
			||||||
  void SetTitle(const std::u16string& title) override;
 | 
					 | 
				
			||||||
  const std::u16string GetTitle() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // views::View:
 | 
					 | 
				
			||||||
  void Layout(PassKey) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 private:
 | 
					 | 
				
			||||||
  std::unique_ptr<views::Widget> devtools_window_;
 | 
					 | 
				
			||||||
  raw_ptr<views::WebView> devtools_window_web_view_ = nullptr;
 | 
					 | 
				
			||||||
  raw_ptr<views::WebView> contents_web_view_ = nullptr;
 | 
					 | 
				
			||||||
  raw_ptr<views::View> contents_view_ = nullptr;
 | 
					 | 
				
			||||||
  raw_ptr<views::WebView> devtools_web_view_ = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DevToolsContentsResizingStrategy strategy_;
 | 
					 | 
				
			||||||
  bool devtools_visible_ = false;
 | 
					 | 
				
			||||||
  raw_ptr<views::WidgetDelegate> devtools_window_delegate_ = nullptr;
 | 
					 | 
				
			||||||
  std::u16string title_;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // namespace electron
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif  // ELECTRON_SHELL_BROWSER_UI_VIEWS_INSPECTABLE_WEB_CONTENTS_VIEW_VIEWS_H_
 | 
					 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue