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/relauncher_mac.cc",
 | 
			
		||||
    "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.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.mm",
 | 
			
		||||
    "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/drag_util_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/tray_icon_cocoa.h",
 | 
			
		||||
    "shell/browser/ui/tray_icon_cocoa.mm",
 | 
			
		||||
| 
						 | 
				
			
			@ -224,8 +218,6 @@ filenames = {
 | 
			
		|||
    "shell/browser/ui/views/electron_views_delegate.h",
 | 
			
		||||
    "shell/browser/ui/views/frameless_view.cc",
 | 
			
		||||
    "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.h",
 | 
			
		||||
    "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
 | 
			
		||||
chore_partial_revert_of.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
 | 
			
		||||
build_disable_thin_lto_mac.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/widget/widget.h"
 | 
			
		||||
 | 
			
		||||
#if BUILDFLAG(IS_MAC)
 | 
			
		||||
#include "shell/browser/ui/cocoa/delayed_native_view_host.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace electron::api {
 | 
			
		||||
 | 
			
		||||
WebContentsView::WebContentsView(v8::Isolate* isolate,
 | 
			
		||||
                                 gin::Handle<WebContents> web_contents)
 | 
			
		||||
#if BUILDFLAG(IS_MAC)
 | 
			
		||||
    : View(new DelayedNativeViewHost(web_contents->inspectable_web_contents()
 | 
			
		||||
                                         ->GetView()
 | 
			
		||||
                                         ->GetNativeView())),
 | 
			
		||||
#else
 | 
			
		||||
    : View(web_contents->inspectable_web_contents()->GetView()->GetView()),
 | 
			
		||||
#endif
 | 
			
		||||
    : View(web_contents->inspectable_web_contents()->GetView()),
 | 
			
		||||
      web_contents_(isolate, web_contents.ToV8()),
 | 
			
		||||
      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);
 | 
			
		||||
#endif
 | 
			
		||||
  view()->SetProperty(
 | 
			
		||||
      views::kFlexBehaviorKey,
 | 
			
		||||
      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -169,9 +169,6 @@ class NativeWindowMac : public NativeWindow,
 | 
			
		|||
  void NotifyWindowDidFailToEnterFullScreen();
 | 
			
		||||
  void NotifyWindowWillLeaveFullScreen();
 | 
			
		||||
 | 
			
		||||
  // views::WidgetDelegate:
 | 
			
		||||
  views::View* GetContentsView() override;
 | 
			
		||||
 | 
			
		||||
  // 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
 | 
			
		||||
  // cleanup in destructor.
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +220,7 @@ class NativeWindowMac : public NativeWindow,
 | 
			
		|||
 | 
			
		||||
 protected:
 | 
			
		||||
  // views::WidgetDelegate:
 | 
			
		||||
  views::View* GetContentsView() override;
 | 
			
		||||
  bool CanMaximize() const override;
 | 
			
		||||
  std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView(
 | 
			
		||||
      views::Widget* widget) override;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -194,6 +194,8 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
 | 
			
		|||
  params.bounds = bounds;
 | 
			
		||||
  params.delegate = this;
 | 
			
		||||
  params.type = views::Widget::InitParams::TYPE_WINDOW;
 | 
			
		||||
  // Allow painting before shown, to be later disabled in ElectronNSWindow.
 | 
			
		||||
  params.headless_mode = true;
 | 
			
		||||
  params.native_widget =
 | 
			
		||||
      new ElectronNativeWidgetMac(this, windowType, styleMask, widget());
 | 
			
		||||
  widget()->Init(std::move(params));
 | 
			
		||||
| 
						 | 
				
			
			@ -1674,6 +1676,7 @@ void NativeWindowMac::Cleanup() {
 | 
			
		|||
  DCHECK(!IsClosed());
 | 
			
		||||
  ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this);
 | 
			
		||||
  display::Screen::GetScreen()->RemoveObserver(this);
 | 
			
		||||
  [window_ cleanup];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class NativeAppWindowFrameViewMac : public views::NativeFrameViewMac {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@
 | 
			
		|||
#include "content/public/browser/desktop_media_id.h"
 | 
			
		||||
#include "content/public/common/color_parser.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/web_contents_preferences.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
 | 
			
		||||
 | 
			
		||||
class ElectronNativeWindowObserver;
 | 
			
		||||
 | 
			
		||||
@interface ElectronNSWindow : NativeWidgetMacNSWindow {
 | 
			
		||||
 @private
 | 
			
		||||
  raw_ptr<electron::NativeWindowMac> shell_;
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +43,7 @@ class ScopedDisableResize {
 | 
			
		|||
@property(nonatomic, retain) NSImage* cornerMask;
 | 
			
		||||
- (id)initWithShell:(electron::NativeWindowMac*)shell
 | 
			
		||||
          styleMask:(NSUInteger)styleMask;
 | 
			
		||||
- (void)cleanup;
 | 
			
		||||
- (electron::NativeWindowMac*)shell;
 | 
			
		||||
- (id)accessibilityFocusedUIElement;
 | 
			
		||||
- (NSRect)originalContentRectForFrameRect:(NSRect)frameRect;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,8 +8,6 @@
 | 
			
		|||
#include "electron/mas.h"
 | 
			
		||||
#include "shell/browser/api/electron_api_web_contents.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_touch_bar.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));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
@implementation ElectronNSWindow
 | 
			
		||||
| 
						 | 
				
			
			@ -168,6 +167,10 @@ void SwizzleSwipeWithEvent(NSView* view, SEL swiz_selector) {
 | 
			
		|||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)cleanup {
 | 
			
		||||
  shell_ = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (electron::NativeWindowMac*)shell {
 | 
			
		||||
  return shell_;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -255,6 +258,17 @@ void SwizzleSwipeWithEvent(NSView* view, SEL swiz_selector) {
 | 
			
		|||
    [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 {
 | 
			
		||||
  if ([attribute isEqual:NSAccessibilityEnabledAttribute])
 | 
			
		||||
    return [NSNumber numberWithBool:YES];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -365,6 +365,19 @@ using FullScreenTransitionState =
 | 
			
		|||
      shell_->GetNativeWindow());
 | 
			
		||||
  auto* bridged_view = bridge_host->GetInProcessNSWindowBridge();
 | 
			
		||||
  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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -297,11 +297,6 @@ class InspectableWebContents::NetworkResourceLoader
 | 
			
		|||
  base::TimeDelta retry_delay_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Implemented separately on each platform.
 | 
			
		||||
InspectableWebContentsView* CreateInspectableContentsView(
 | 
			
		||||
    InspectableWebContents* inspectable_web_contents);
 | 
			
		||||
 | 
			
		||||
// static
 | 
			
		||||
// static
 | 
			
		||||
void InspectableWebContents::RegisterPrefs(PrefRegistrySimple* registry) {
 | 
			
		||||
  registry->RegisterDictionaryPref(kDevToolsBoundsPref,
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +312,7 @@ InspectableWebContents::InspectableWebContents(
 | 
			
		|||
    : pref_service_(pref_service),
 | 
			
		||||
      web_contents_(std::move(web_contents)),
 | 
			
		||||
      is_guest_(is_guest),
 | 
			
		||||
      view_(CreateInspectableContentsView(this)) {
 | 
			
		||||
      view_(new InspectableWebContentsView(this)) {
 | 
			
		||||
  const base::Value* bounds_dict =
 | 
			
		||||
      &pref_service_->GetValue(kDevToolsBoundsPref);
 | 
			
		||||
  if (bounds_dict->is_dict()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,12 +5,250 @@
 | 
			
		|||
 | 
			
		||||
#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 {
 | 
			
		||||
 | 
			
		||||
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(
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,13 +9,9 @@
 | 
			
		|||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "base/memory/raw_ptr.h"
 | 
			
		||||
#include "build/build_config.h"
 | 
			
		||||
 | 
			
		||||
#if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC)
 | 
			
		||||
#include "ui/views/view.h"
 | 
			
		||||
#else
 | 
			
		||||
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
 | 
			
		||||
#include "ui/gfx/native_widget_types.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "ui/views/view.h"
 | 
			
		||||
 | 
			
		||||
class DevToolsContentsResizingStrategy;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,23 +19,22 @@ namespace gfx {
 | 
			
		|||
class RoundedCornersF;
 | 
			
		||||
}  // namespace gfx
 | 
			
		||||
 | 
			
		||||
#if defined(TOOLKIT_VIEWS)
 | 
			
		||||
namespace views {
 | 
			
		||||
class View;
 | 
			
		||||
class WebView;
 | 
			
		||||
class Widget;
 | 
			
		||||
class WidgetDelegate;
 | 
			
		||||
}  // namespace views
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace electron {
 | 
			
		||||
 | 
			
		||||
class InspectableWebContents;
 | 
			
		||||
class InspectableWebContentsViewDelegate;
 | 
			
		||||
 | 
			
		||||
class InspectableWebContentsView {
 | 
			
		||||
class InspectableWebContentsView : public views::View {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit InspectableWebContentsView(
 | 
			
		||||
      InspectableWebContents* inspectable_web_contents);
 | 
			
		||||
  virtual ~InspectableWebContentsView();
 | 
			
		||||
  ~InspectableWebContentsView() override;
 | 
			
		||||
 | 
			
		||||
  InspectableWebContents* inspectable_web_contents() {
 | 
			
		||||
    return inspectable_web_contents_;
 | 
			
		||||
| 
						 | 
				
			
			@ -51,32 +46,40 @@ class InspectableWebContentsView {
 | 
			
		|||
  }
 | 
			
		||||
  InspectableWebContentsViewDelegate* GetDelegate() const { return delegate_; }
 | 
			
		||||
 | 
			
		||||
#if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC)
 | 
			
		||||
  // Returns the container control, which has devtools view attached.
 | 
			
		||||
  virtual views::View* GetView() = 0;
 | 
			
		||||
#else
 | 
			
		||||
  virtual gfx::NativeView GetNativeView() const = 0;
 | 
			
		||||
#endif
 | 
			
		||||
  void SetCornerRadii(const gfx::RoundedCornersF& corner_radii);
 | 
			
		||||
 | 
			
		||||
  virtual void ShowDevTools(bool activate) = 0;
 | 
			
		||||
  virtual void SetCornerRadii(const gfx::RoundedCornersF& corner_radii) = 0;
 | 
			
		||||
  // Hide the DevTools view.
 | 
			
		||||
  virtual void CloseDevTools() = 0;
 | 
			
		||||
  virtual bool IsDevToolsViewShowing() = 0;
 | 
			
		||||
  virtual bool IsDevToolsViewFocused() = 0;
 | 
			
		||||
  virtual void SetIsDocked(bool docked, bool activate) = 0;
 | 
			
		||||
  virtual void SetContentsResizingStrategy(
 | 
			
		||||
      const DevToolsContentsResizingStrategy& strategy) = 0;
 | 
			
		||||
  virtual void SetTitle(const std::u16string& title) = 0;
 | 
			
		||||
  virtual const std::u16string GetTitle() = 0;
 | 
			
		||||
  void ShowDevTools(bool activate);
 | 
			
		||||
  void CloseDevTools();
 | 
			
		||||
  bool IsDevToolsViewShowing();
 | 
			
		||||
  bool IsDevToolsViewFocused();
 | 
			
		||||
  void SetIsDocked(bool docked, bool activate);
 | 
			
		||||
  void SetContentsResizingStrategy(
 | 
			
		||||
      const DevToolsContentsResizingStrategy& strategy);
 | 
			
		||||
  void SetTitle(const std::u16string& title);
 | 
			
		||||
  const std::u16string GetTitle();
 | 
			
		||||
 | 
			
		||||
  // views::View:
 | 
			
		||||
  void Layout(PassKey) override;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  views::View* GetContentsView() const;
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  // Owns us.
 | 
			
		||||
  raw_ptr<InspectableWebContents> inspectable_web_contents_;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  raw_ptr<InspectableWebContentsViewDelegate> delegate_ =
 | 
			
		||||
      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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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/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/metadata/metadata_impl_macros.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