macOS: Use sheet window as modal window
This commit is contained in:
		
					parent
					
						
							
								1866dbe608
							
						
					
				
			
			
				commit
				
					
						e33e4be257
					
				
			
		
					 8 changed files with 81 additions and 112 deletions
				
			
		| 
						 | 
					@ -76,8 +76,7 @@ v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options)
 | 
					Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
 | 
				
			||||||
    : is_modal_(false) {
 | 
					 | 
				
			||||||
  // Use options.webPreferences to create WebContents.
 | 
					  // Use options.webPreferences to create WebContents.
 | 
				
			||||||
  mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
 | 
					  mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
 | 
				
			||||||
  options.Get(options::kWebPreferences, &web_preferences);
 | 
					  options.Get(options::kWebPreferences, &web_preferences);
 | 
				
			||||||
| 
						 | 
					@ -312,6 +311,10 @@ void Window::Show() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Window::ShowInactive() {
 | 
					void Window::ShowInactive() {
 | 
				
			||||||
 | 
					  // This method doesn't make sense for modal window..
 | 
				
			||||||
 | 
					  if (IsModal())
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  window_->ShowInactive();
 | 
					  window_->ShowInactive();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -696,6 +699,11 @@ void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Window::SetParentWindow(v8::Local<v8::Value> value,
 | 
					void Window::SetParentWindow(v8::Local<v8::Value> value,
 | 
				
			||||||
                             mate::Arguments* args) {
 | 
					                             mate::Arguments* args) {
 | 
				
			||||||
 | 
					  if (IsModal()) {
 | 
				
			||||||
 | 
					    args->ThrowError("Can not be called for modal window");
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mate::Handle<Window> parent;
 | 
					  mate::Handle<Window> parent;
 | 
				
			||||||
  if (value->IsNull()) {
 | 
					  if (value->IsNull()) {
 | 
				
			||||||
    RemoveFromParentChildWindows();
 | 
					    RemoveFromParentChildWindows();
 | 
				
			||||||
| 
						 | 
					@ -721,43 +729,8 @@ std::vector<v8::Local<v8::Object>> Window::GetChildWindows() const {
 | 
				
			||||||
  return child_windows_.Values(isolate());
 | 
					  return child_windows_.Values(isolate());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Window::SetModal(bool modal, mate::Arguments* args) {
 | 
					 | 
				
			||||||
  if (parent_window_.IsEmpty()) {
 | 
					 | 
				
			||||||
    args->ThrowError("setModal can only be called for child window");
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  mate::Handle<Window> parent;
 | 
					 | 
				
			||||||
  if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent)) {
 | 
					 | 
				
			||||||
    args->ThrowError("Invalid parent window");  // should never happen
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (modal == is_modal_)
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (modal)
 | 
					 | 
				
			||||||
    parent->Disable();
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    parent->Enable();
 | 
					 | 
				
			||||||
  window_->SetModal(modal);
 | 
					 | 
				
			||||||
  is_modal_ = modal;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool Window::IsModal() const {
 | 
					bool Window::IsModal() const {
 | 
				
			||||||
  return is_modal_;
 | 
					  return window_->is_modal();
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Window::BeginSheet(mate::Handle<Window> sheet, mate::Arguments* args) {
 | 
					 | 
				
			||||||
  if (sheet->IsVisible()) {
 | 
					 | 
				
			||||||
    args->ThrowError("Sheet window must not be visible");
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  window_->BeginSheet(sheet->window_.get());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Window::EndSheet(mate::Handle<Window> sheet) {
 | 
					 | 
				
			||||||
  window_->EndSheet(sheet->window_.get());
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
v8::Local<v8::Value> Window::GetNativeWindowHandle() {
 | 
					v8::Local<v8::Value> Window::GetNativeWindowHandle() {
 | 
				
			||||||
| 
						 | 
					@ -794,10 +767,8 @@ void Window::RemoveFromParentChildWindows() {
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  parent->child_windows_.Remove(ID());
 | 
					  parent->child_windows_.Remove(ID());
 | 
				
			||||||
  if (IsModal()) {
 | 
					  if (IsModal())
 | 
				
			||||||
    parent->Enable();
 | 
					    parent->Enable();
 | 
				
			||||||
    is_modal_ = false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// static
 | 
					// static
 | 
				
			||||||
| 
						 | 
					@ -828,10 +799,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
 | 
				
			||||||
      .SetMethod("setParentWindow", &Window::SetParentWindow)
 | 
					      .SetMethod("setParentWindow", &Window::SetParentWindow)
 | 
				
			||||||
      .SetMethod("getParentWindow", &Window::GetParentWindow)
 | 
					      .SetMethod("getParentWindow", &Window::GetParentWindow)
 | 
				
			||||||
      .SetMethod("getChildWindows", &Window::GetChildWindows)
 | 
					      .SetMethod("getChildWindows", &Window::GetChildWindows)
 | 
				
			||||||
      .SetMethod("setModal", &Window::SetModal)
 | 
					 | 
				
			||||||
      .SetMethod("isModal", &Window::IsModal)
 | 
					      .SetMethod("isModal", &Window::IsModal)
 | 
				
			||||||
      .SetMethod("beginSheet", &Window::BeginSheet)
 | 
					 | 
				
			||||||
      .SetMethod("endSheet", &Window::EndSheet)
 | 
					 | 
				
			||||||
      .SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
 | 
					      .SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
 | 
				
			||||||
      .SetMethod("getBounds", &Window::GetBounds)
 | 
					      .SetMethod("getBounds", &Window::GetBounds)
 | 
				
			||||||
      .SetMethod("setBounds", &Window::SetBounds)
 | 
					      .SetMethod("setBounds", &Window::SetBounds)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,10 +170,7 @@ class Window : public mate::TrackableObject<Window>,
 | 
				
			||||||
  void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
 | 
					  void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
 | 
				
			||||||
  v8::Local<v8::Value> GetParentWindow() const;
 | 
					  v8::Local<v8::Value> GetParentWindow() const;
 | 
				
			||||||
  std::vector<v8::Local<v8::Object>> GetChildWindows() const;
 | 
					  std::vector<v8::Local<v8::Object>> GetChildWindows() const;
 | 
				
			||||||
  void SetModal(bool modal, mate::Arguments* args);
 | 
					 | 
				
			||||||
  bool IsModal() const;
 | 
					  bool IsModal() const;
 | 
				
			||||||
  void BeginSheet(mate::Handle<Window> sheet, mate::Arguments* args);
 | 
					 | 
				
			||||||
  void EndSheet(mate::Handle<Window> sheet);
 | 
					 | 
				
			||||||
  v8::Local<v8::Value> GetNativeWindowHandle();
 | 
					  v8::Local<v8::Value> GetNativeWindowHandle();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(OS_WIN)
 | 
					#if defined(OS_WIN)
 | 
				
			||||||
| 
						 | 
					@ -209,9 +206,6 @@ class Window : public mate::TrackableObject<Window>,
 | 
				
			||||||
  v8::Global<v8::Value> parent_window_;
 | 
					  v8::Global<v8::Value> parent_window_;
 | 
				
			||||||
  KeyWeakMap<int> child_windows_;
 | 
					  KeyWeakMap<int> child_windows_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Is current window modal.
 | 
					 | 
				
			||||||
  bool is_modal_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  api::WebContents* api_web_contents_;
 | 
					  api::WebContents* api_web_contents_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::unique_ptr<NativeWindow> window_;
 | 
					  std::unique_ptr<NativeWindow> window_;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,8 @@ namespace atom {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NativeWindow::NativeWindow(
 | 
					NativeWindow::NativeWindow(
 | 
				
			||||||
    brightray::InspectableWebContents* inspectable_web_contents,
 | 
					    brightray::InspectableWebContents* inspectable_web_contents,
 | 
				
			||||||
    const mate::Dictionary& options)
 | 
					    const mate::Dictionary& options,
 | 
				
			||||||
 | 
					    NativeWindow* parent)
 | 
				
			||||||
    : content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
 | 
					    : content::WebContentsObserver(inspectable_web_contents->GetWebContents()),
 | 
				
			||||||
      has_frame_(true),
 | 
					      has_frame_(true),
 | 
				
			||||||
      transparent_(false),
 | 
					      transparent_(false),
 | 
				
			||||||
| 
						 | 
					@ -57,12 +58,17 @@ NativeWindow::NativeWindow(
 | 
				
			||||||
      sheet_offset_y_(0.0),
 | 
					      sheet_offset_y_(0.0),
 | 
				
			||||||
      aspect_ratio_(0.0),
 | 
					      aspect_ratio_(0.0),
 | 
				
			||||||
      disable_count_(0),
 | 
					      disable_count_(0),
 | 
				
			||||||
 | 
					      parent_(parent),
 | 
				
			||||||
 | 
					      is_modal_(false),
 | 
				
			||||||
      inspectable_web_contents_(inspectable_web_contents),
 | 
					      inspectable_web_contents_(inspectable_web_contents),
 | 
				
			||||||
      weak_factory_(this) {
 | 
					      weak_factory_(this) {
 | 
				
			||||||
  options.Get(options::kFrame, &has_frame_);
 | 
					  options.Get(options::kFrame, &has_frame_);
 | 
				
			||||||
  options.Get(options::kTransparent, &transparent_);
 | 
					  options.Get(options::kTransparent, &transparent_);
 | 
				
			||||||
  options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_);
 | 
					  options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (parent)
 | 
				
			||||||
 | 
					    options.Get("modal", &is_modal_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Tell the content module to initialize renderer widget with transparent
 | 
					  // Tell the content module to initialize renderer widget with transparent
 | 
				
			||||||
  // mode.
 | 
					  // mode.
 | 
				
			||||||
  ui::GpuSwitchingManager::SetTransparent(transparent_);
 | 
					  ui::GpuSwitchingManager::SetTransparent(transparent_);
 | 
				
			||||||
| 
						 | 
					@ -305,10 +311,8 @@ bool NativeWindow::HasModalDialog() {
 | 
				
			||||||
  return has_dialog_attached_;
 | 
					  return has_dialog_attached_;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindow::BeginSheet(NativeWindow* sheet) {
 | 
					void NativeWindow::SetParentWindow(NativeWindow* parent) {
 | 
				
			||||||
}
 | 
					  parent_ = parent;
 | 
				
			||||||
 | 
					 | 
				
			||||||
void NativeWindow::EndSheet(NativeWindow* sheet) {
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindow::FocusOnWebView() {
 | 
					void NativeWindow::FocusOnWebView() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,7 @@ class NativeWindow : public base::SupportsUserData,
 | 
				
			||||||
  virtual bool IsVisible() = 0;
 | 
					  virtual bool IsVisible() = 0;
 | 
				
			||||||
  virtual void Disable();
 | 
					  virtual void Disable();
 | 
				
			||||||
  virtual void Enable();
 | 
					  virtual void Enable();
 | 
				
			||||||
  virtual void SetEnabled(bool enable) = 0;  // should not be used
 | 
					  virtual void SetEnabled(bool enable) = 0;  // internal API, should not be used
 | 
				
			||||||
  virtual bool IsEnabled() = 0;
 | 
					  virtual bool IsEnabled() = 0;
 | 
				
			||||||
  virtual void Maximize() = 0;
 | 
					  virtual void Maximize() = 0;
 | 
				
			||||||
  virtual void Unmaximize() = 0;
 | 
					  virtual void Unmaximize() = 0;
 | 
				
			||||||
| 
						 | 
					@ -163,10 +163,7 @@ class NativeWindow : public base::SupportsUserData,
 | 
				
			||||||
  virtual void SetFocusable(bool focusable);
 | 
					  virtual void SetFocusable(bool focusable);
 | 
				
			||||||
  virtual void SetMenu(ui::MenuModel* menu);
 | 
					  virtual void SetMenu(ui::MenuModel* menu);
 | 
				
			||||||
  virtual bool HasModalDialog();
 | 
					  virtual bool HasModalDialog();
 | 
				
			||||||
  virtual void SetParentWindow(NativeWindow* parent) = 0;
 | 
					  virtual void SetParentWindow(NativeWindow* parent);
 | 
				
			||||||
  virtual void BeginSheet(NativeWindow* sheet);
 | 
					 | 
				
			||||||
  virtual void EndSheet(NativeWindow* sheet);
 | 
					 | 
				
			||||||
  virtual void SetModal(bool modal) = 0;
 | 
					 | 
				
			||||||
  virtual gfx::NativeWindow GetNativeWindow() = 0;
 | 
					  virtual gfx::NativeWindow GetNativeWindow() = 0;
 | 
				
			||||||
  virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
 | 
					  virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -264,9 +261,13 @@ class NativeWindow : public base::SupportsUserData,
 | 
				
			||||||
    has_dialog_attached_ = has_dialog_attached;
 | 
					    has_dialog_attached_ = has_dialog_attached;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NativeWindow* parent() const { return parent_; }
 | 
				
			||||||
 | 
					  bool is_modal() const { return is_modal_; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 protected:
 | 
					 protected:
 | 
				
			||||||
  NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
 | 
					  NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
 | 
				
			||||||
               const mate::Dictionary& options);
 | 
					               const mate::Dictionary& options,
 | 
				
			||||||
 | 
					               NativeWindow* parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Convert draggable regions in raw format to SkRegion format. Caller is
 | 
					  // Convert draggable regions in raw format to SkRegion format. Caller is
 | 
				
			||||||
  // responsible for deleting the returned SkRegion instance.
 | 
					  // responsible for deleting the returned SkRegion instance.
 | 
				
			||||||
| 
						 | 
					@ -341,6 +342,12 @@ class NativeWindow : public base::SupportsUserData,
 | 
				
			||||||
  // How many times the Disable has been called.
 | 
					  // How many times the Disable has been called.
 | 
				
			||||||
  int disable_count_;
 | 
					  int disable_count_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // The parent window, it is guaranteed to be valid during this window's life.
 | 
				
			||||||
 | 
					  NativeWindow* parent_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Is this a modal window.
 | 
				
			||||||
 | 
					  bool is_modal_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // The page this window is viewing.
 | 
					  // The page this window is viewing.
 | 
				
			||||||
  brightray::InspectableWebContents* inspectable_web_contents_;
 | 
					  brightray::InspectableWebContents* inspectable_web_contents_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,9 +82,6 @@ class NativeWindowMac : public NativeWindow {
 | 
				
			||||||
  void SetIgnoreMouseEvents(bool ignore) override;
 | 
					  void SetIgnoreMouseEvents(bool ignore) override;
 | 
				
			||||||
  bool HasModalDialog() override;
 | 
					  bool HasModalDialog() override;
 | 
				
			||||||
  void SetParentWindow(NativeWindow* parent) override;
 | 
					  void SetParentWindow(NativeWindow* parent) override;
 | 
				
			||||||
  void BeginSheet(NativeWindow* sheet) override;
 | 
					 | 
				
			||||||
  void EndSheet(NativeWindow* sheet) override;
 | 
					 | 
				
			||||||
  void SetModal(bool modal) override;
 | 
					 | 
				
			||||||
  gfx::NativeWindow GetNativeWindow() override;
 | 
					  gfx::NativeWindow GetNativeWindow() override;
 | 
				
			||||||
  gfx::AcceleratedWidget GetAcceleratedWidget() override;
 | 
					  gfx::AcceleratedWidget GetAcceleratedWidget() override;
 | 
				
			||||||
  void SetProgressBar(double progress) override;
 | 
					  void SetProgressBar(double progress) override;
 | 
				
			||||||
| 
						 | 
					@ -151,9 +148,6 @@ class NativeWindowMac : public NativeWindow {
 | 
				
			||||||
  // The "titleBarStyle" option.
 | 
					  // The "titleBarStyle" option.
 | 
				
			||||||
  TitleBarStyle title_bar_style_;
 | 
					  TitleBarStyle title_bar_style_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Whether to hide the native toolbar under fullscreen mode.
 | 
					 | 
				
			||||||
  bool should_hide_native_toolbar_in_fullscreen_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
 | 
					  DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -455,7 +455,7 @@ NativeWindowMac::NativeWindowMac(
 | 
				
			||||||
    brightray::InspectableWebContents* web_contents,
 | 
					    brightray::InspectableWebContents* web_contents,
 | 
				
			||||||
    const mate::Dictionary& options,
 | 
					    const mate::Dictionary& options,
 | 
				
			||||||
    NativeWindow* parent)
 | 
					    NativeWindow* parent)
 | 
				
			||||||
    : NativeWindow(web_contents, options),
 | 
					    : NativeWindow(web_contents, options, parent),
 | 
				
			||||||
      is_kiosk_(false),
 | 
					      is_kiosk_(false),
 | 
				
			||||||
      attention_request_id_(0),
 | 
					      attention_request_id_(0),
 | 
				
			||||||
      title_bar_style_(NORMAL) {
 | 
					      title_bar_style_(NORMAL) {
 | 
				
			||||||
| 
						 | 
					@ -527,7 +527,8 @@ NativeWindowMac::NativeWindowMac(
 | 
				
			||||||
  window_delegate_.reset([[AtomNSWindowDelegate alloc] initWithShell:this]);
 | 
					  window_delegate_.reset([[AtomNSWindowDelegate alloc] initWithShell:this]);
 | 
				
			||||||
  [window_ setDelegate:window_delegate_];
 | 
					  [window_ setDelegate:window_delegate_];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (parent) {
 | 
					  // Only use native parent window for non-modal windows.
 | 
				
			||||||
 | 
					  if (parent && !is_modal()) {
 | 
				
			||||||
    SetParentWindow(parent);
 | 
					    SetParentWindow(parent);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -625,6 +626,12 @@ NativeWindowMac::~NativeWindowMac() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindowMac::Close() {
 | 
					void NativeWindowMac::Close() {
 | 
				
			||||||
 | 
					  // When this is a sheet showing, performClose won't work.
 | 
				
			||||||
 | 
					  if (is_modal() && parent() && IsVisible()) {
 | 
				
			||||||
 | 
					    CloseImmediately();
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!IsClosable()) {
 | 
					  if (!IsClosable()) {
 | 
				
			||||||
    WindowList::WindowCloseCancelled(this);
 | 
					    WindowList::WindowCloseCancelled(this);
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
| 
						 | 
					@ -654,6 +661,12 @@ bool NativeWindowMac::IsFocused() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindowMac::Show() {
 | 
					void NativeWindowMac::Show() {
 | 
				
			||||||
 | 
					  if (is_modal() && parent()) {
 | 
				
			||||||
 | 
					    [parent()->GetNativeWindow() beginSheet:window_
 | 
				
			||||||
 | 
					                          completionHandler:^(NSModalResponse) {}];
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // This method is supposed to put focus on window, however if the app does not
 | 
					  // This method is supposed to put focus on window, however if the app does not
 | 
				
			||||||
  // have focus then "makeKeyAndOrderFront" will only show the window.
 | 
					  // have focus then "makeKeyAndOrderFront" will only show the window.
 | 
				
			||||||
  [NSApp activateIgnoringOtherApps:YES];
 | 
					  [NSApp activateIgnoringOtherApps:YES];
 | 
				
			||||||
| 
						 | 
					@ -666,6 +679,12 @@ void NativeWindowMac::ShowInactive() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindowMac::Hide() {
 | 
					void NativeWindowMac::Hide() {
 | 
				
			||||||
 | 
					  if (is_modal() && parent()) {
 | 
				
			||||||
 | 
					    [window_ orderOut:nil];
 | 
				
			||||||
 | 
					    [parent()->GetNativeWindow() endSheet:window_];
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [window_ orderOut:nil];
 | 
					  [window_ orderOut:nil];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -679,7 +698,7 @@ void NativeWindowMac::SetEnabled(bool enable) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool NativeWindowMac::IsEnabled() {
 | 
					bool NativeWindowMac::IsEnabled() {
 | 
				
			||||||
  return ![window_ disableMouseEvents];
 | 
					  return [window_ attachedSheet] == nil;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindowMac::Maximize() {
 | 
					void NativeWindowMac::Maximize() {
 | 
				
			||||||
| 
						 | 
					@ -951,6 +970,11 @@ bool NativeWindowMac::HasModalDialog() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
 | 
					void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
 | 
				
			||||||
 | 
					  if (is_modal())
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NativeWindow::SetParentWindow(parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Remove current parent window.
 | 
					  // Remove current parent window.
 | 
				
			||||||
  if ([window_ parentWindow])
 | 
					  if ([window_ parentWindow])
 | 
				
			||||||
    [[window_ parentWindow] removeChildWindow:window_];
 | 
					    [[window_ parentWindow] removeChildWindow:window_];
 | 
				
			||||||
| 
						 | 
					@ -960,21 +984,6 @@ void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
 | 
				
			||||||
    [parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove];
 | 
					    [parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindowMac::BeginSheet(NativeWindow* sheet) {
 | 
					 | 
				
			||||||
  [window_ beginSheet:sheet->GetNativeWindow()
 | 
					 | 
				
			||||||
    completionHandler:^(NSModalResponse) {
 | 
					 | 
				
			||||||
  }];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void NativeWindowMac::EndSheet(NativeWindow* sheet) {
 | 
					 | 
				
			||||||
  sheet->Hide();
 | 
					 | 
				
			||||||
  [window_ endSheet:sheet->GetNativeWindow()];
 | 
					 | 
				
			||||||
  sheet->CloseImmediately();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void NativeWindowMac::SetModal(bool modal) {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
gfx::NativeWindow NativeWindowMac::GetNativeWindow() {
 | 
					gfx::NativeWindow NativeWindowMac::GetNativeWindow() {
 | 
				
			||||||
  return window_;
 | 
					  return window_;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -806,6 +806,8 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
 | 
					void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
 | 
				
			||||||
 | 
					  NativeWindow::SetParentWindow(parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(USE_X11)
 | 
					#if defined(USE_X11)
 | 
				
			||||||
  XDisplay* xdisplay = gfx::GetXDisplay();
 | 
					  XDisplay* xdisplay = gfx::GetXDisplay();
 | 
				
			||||||
  XSetTransientForHint(
 | 
					  XSetTransientForHint(
 | 
				
			||||||
| 
						 | 
					@ -830,6 +832,7 @@ void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NativeWindowViews::SetModal(bool modal) {
 | 
					void NativeWindowViews::SetModal(bool modal) {
 | 
				
			||||||
 | 
					  NativeWindow::SetModal(modal);
 | 
				
			||||||
#if defined(USE_X11)
 | 
					#if defined(USE_X11)
 | 
				
			||||||
  SetWindowType(GetAcceleratedWidget(), modal ? "dialog" : "normal");
 | 
					  SetWindowType(GetAcceleratedWidget(), modal ? "dialog" : "normal");
 | 
				
			||||||
  Show();
 | 
					  Show();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -902,10 +902,18 @@ describe('browser-window module', function () {
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe('win.setModal(modal)', function () {
 | 
					    describe('modal option', function () {
 | 
				
			||||||
 | 
					      // The isEnabled API is not reliable on macOS.
 | 
				
			||||||
 | 
					      if (process.platform === 'darwin') return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      beforeEach(function () {
 | 
				
			||||||
 | 
					        if (c != null) c.destroy()
 | 
				
			||||||
 | 
					        c = new BrowserWindow({show: false, parent: w, modal: true})
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it('disables parent window', function () {
 | 
					      it('disables parent window', function () {
 | 
				
			||||||
        assert.equal(w.isEnabled(), true)
 | 
					        assert.equal(w.isEnabled(), true)
 | 
				
			||||||
        c.setModal(true)
 | 
					        c.show()
 | 
				
			||||||
        assert.equal(w.isEnabled(), false)
 | 
					        assert.equal(w.isEnabled(), false)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -914,38 +922,20 @@ describe('browser-window module', function () {
 | 
				
			||||||
          assert.equal(w.isEnabled(), true)
 | 
					          assert.equal(w.isEnabled(), true)
 | 
				
			||||||
          done()
 | 
					          done()
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        c.setModal(true)
 | 
					        c.show()
 | 
				
			||||||
        c.close()
 | 
					        c.close()
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it('enables parent window when setting not modal', function () {
 | 
					 | 
				
			||||||
        assert.equal(w.isEnabled(), true)
 | 
					 | 
				
			||||||
        c.setModal(true)
 | 
					 | 
				
			||||||
        assert.equal(w.isEnabled(), false)
 | 
					 | 
				
			||||||
        c.setModal(false)
 | 
					 | 
				
			||||||
        assert.equal(w.isEnabled(), true)
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it('enables parent window when removing parent', function () {
 | 
					 | 
				
			||||||
        if (process.platform !== 'darwin') return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert.equal(w.isEnabled(), true)
 | 
					 | 
				
			||||||
        c.setModal(true)
 | 
					 | 
				
			||||||
        assert.equal(w.isEnabled(), false)
 | 
					 | 
				
			||||||
        c.setParentWindow(null)
 | 
					 | 
				
			||||||
        assert.equal(w.isEnabled(), true)
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it('disables parent window recursively', function () {
 | 
					      it('disables parent window recursively', function () {
 | 
				
			||||||
        let c2 = new BrowserWindow({show: false, parent: w})
 | 
					        let c2 = new BrowserWindow({show: false, parent: w, modal: true})
 | 
				
			||||||
        c.setModal(true)
 | 
					        c.show()
 | 
				
			||||||
        c2.setModal(true)
 | 
					 | 
				
			||||||
        assert.equal(w.isEnabled(), false)
 | 
					        assert.equal(w.isEnabled(), false)
 | 
				
			||||||
        c.setModal(false)
 | 
					        c2.show()
 | 
				
			||||||
 | 
					        assert.equal(w.isEnabled(), false)
 | 
				
			||||||
 | 
					        c.destroy()
 | 
				
			||||||
        assert.equal(w.isEnabled(), false)
 | 
					        assert.equal(w.isEnabled(), false)
 | 
				
			||||||
        c2.setModal(false)
 | 
					 | 
				
			||||||
        assert.equal(w.isEnabled(), true)
 | 
					 | 
				
			||||||
        c2.destroy()
 | 
					        c2.destroy()
 | 
				
			||||||
 | 
					        assert.equal(w.isEnabled(), true)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue