mirror of
https://github.com/electron/electron.git
synced 2026-01-26 07:48:08 -05:00
Merge pull request #6432 from electron/global-unresponsive-suppresser
Suppress the unresponsive event globally
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#import "atom/browser/api/atom_api_menu_mac.h"
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
@@ -67,6 +68,9 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
if (rightmostMenuPoint > screenRight)
|
||||
position.x = position.x - [menu size].width;
|
||||
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Show the menu.
|
||||
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/api/atom_api_menu_views.h"
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
@@ -36,6 +37,9 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
location = gfx::Point(origin.x() + x, origin.y() + y);
|
||||
}
|
||||
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Show the menu.
|
||||
views::MenuRunner menu_runner(
|
||||
model(),
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
@@ -52,7 +53,6 @@ NativeWindow::NativeWindow(
|
||||
transparent_(false),
|
||||
enable_larger_than_screen_(false),
|
||||
is_closed_(false),
|
||||
has_dialog_attached_(false),
|
||||
sheet_offset_x_(0.0),
|
||||
sheet_offset_y_(0.0),
|
||||
aspect_ratio_(0.0),
|
||||
@@ -293,10 +293,6 @@ void NativeWindow::SetFocusable(bool focusable) {
|
||||
void NativeWindow::SetMenu(AtomMenuModel* menu) {
|
||||
}
|
||||
|
||||
bool NativeWindow::HasModalDialog() {
|
||||
return has_dialog_attached_;
|
||||
}
|
||||
|
||||
void NativeWindow::SetParentWindow(NativeWindow* parent) {
|
||||
parent_ = parent;
|
||||
}
|
||||
@@ -590,7 +586,7 @@ void NativeWindow::ScheduleUnresponsiveEvent(int ms) {
|
||||
void NativeWindow::NotifyWindowUnresponsive() {
|
||||
window_unresposive_closure_.Cancel();
|
||||
|
||||
if (!is_closed_ && !HasModalDialog() && IsEnabled())
|
||||
if (!is_closed_ && !IsUnresponsiveEventSuppressed() && IsEnabled())
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver,
|
||||
observers_,
|
||||
OnRendererUnresponsive());
|
||||
|
||||
@@ -51,26 +51,7 @@ struct DraggableRegion;
|
||||
class NativeWindow : public base::SupportsUserData,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
class DialogScope {
|
||||
public:
|
||||
explicit DialogScope(NativeWindow* window)
|
||||
: window_(window) {
|
||||
if (window_ != NULL)
|
||||
window_->set_has_dialog_attached(true);
|
||||
}
|
||||
|
||||
~DialogScope() {
|
||||
if (window_ != NULL)
|
||||
window_->set_has_dialog_attached(false);
|
||||
}
|
||||
|
||||
private:
|
||||
NativeWindow* window_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DialogScope);
|
||||
};
|
||||
|
||||
virtual ~NativeWindow();
|
||||
~NativeWindow() override;
|
||||
|
||||
// Create window with existing WebContents, the caller is responsible for
|
||||
// managing the window's live.
|
||||
@@ -155,7 +136,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual void SetContentProtection(bool enable) = 0;
|
||||
virtual void SetFocusable(bool focusable);
|
||||
virtual void SetMenu(AtomMenuModel* menu);
|
||||
virtual bool HasModalDialog();
|
||||
virtual void SetParentWindow(NativeWindow* parent);
|
||||
virtual gfx::NativeWindow GetNativeWindow() = 0;
|
||||
virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
|
||||
@@ -245,10 +225,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
|
||||
|
||||
void set_has_dialog_attached(bool has_dialog_attached) {
|
||||
has_dialog_attached_ = has_dialog_attached;
|
||||
}
|
||||
|
||||
NativeWindow* parent() const { return parent_; }
|
||||
bool is_modal() const { return is_modal_; }
|
||||
|
||||
@@ -305,9 +281,6 @@ class NativeWindow : public base::SupportsUserData,
|
||||
// The windows has been closed.
|
||||
bool is_closed_;
|
||||
|
||||
// There is a dialog that has been attached to window.
|
||||
bool has_dialog_attached_;
|
||||
|
||||
// Closure that would be called when window is unresponsive when closing,
|
||||
// it should be cancelled when we can prove that the window is responsive.
|
||||
base::CancelableClosure window_unresposive_closure_;
|
||||
|
||||
@@ -80,7 +80,6 @@ class NativeWindowMac : public NativeWindow {
|
||||
bool IsDocumentEdited() override;
|
||||
void SetIgnoreMouseEvents(bool ignore) override;
|
||||
void SetContentProtection(bool enable) override;
|
||||
bool HasModalDialog() override;
|
||||
void SetParentWindow(NativeWindow* parent) override;
|
||||
gfx::NativeWindow GetNativeWindow() override;
|
||||
gfx::AcceleratedWidget GetAcceleratedWidget() override;
|
||||
|
||||
@@ -960,10 +960,6 @@ void NativeWindowMac::SetContentProtection(bool enable) {
|
||||
: NSWindowSharingReadOnly];
|
||||
}
|
||||
|
||||
bool NativeWindowMac::HasModalDialog() {
|
||||
return [window_ attachedSheet] != nil;
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetParentWindow(NativeWindow* parent) {
|
||||
if (is_modal())
|
||||
return;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
@@ -41,7 +42,6 @@ class FileChooserDialog {
|
||||
const base::FilePath& default_path,
|
||||
const Filters& filters)
|
||||
: parent_(static_cast<atom::NativeWindowViews*>(parent_window)),
|
||||
dialog_scope_(parent_window),
|
||||
filters_(filters) {
|
||||
const char* confirm_text = GTK_STOCK_OK;
|
||||
|
||||
@@ -153,7 +153,7 @@ class FileChooserDialog {
|
||||
base::FilePath AddExtensionForFilename(const gchar* filename) const;
|
||||
|
||||
atom::NativeWindowViews* parent_;
|
||||
atom::NativeWindow::DialogScope dialog_scope_;
|
||||
atom::UnresponsiveSuppressor unresponsive_suppressor_;
|
||||
|
||||
GtkWidget* dialog_;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/i18n/case_conversion.h"
|
||||
#include "base/strings/string_util.h"
|
||||
@@ -108,7 +109,7 @@ class FileDialog {
|
||||
}
|
||||
|
||||
bool Show(atom::NativeWindow* parent_window) {
|
||||
atom::NativeWindow::DialogScope dialog_scope(parent_window);
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
HWND window = parent_window ? static_cast<atom::NativeWindowViews*>(
|
||||
parent_window)->GetAcceleratedWidget() :
|
||||
NULL;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
@@ -35,8 +36,7 @@ class GtkMessageBox {
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon)
|
||||
: dialog_scope_(parent_window),
|
||||
cancel_id_(cancel_id),
|
||||
: cancel_id_(cancel_id),
|
||||
parent_(static_cast<NativeWindowViews*>(parent_window)) {
|
||||
// Create dialog.
|
||||
dialog_ = gtk_message_dialog_new(
|
||||
@@ -147,7 +147,7 @@ class GtkMessageBox {
|
||||
CHROMEGTK_CALLBACK_1(GtkMessageBox, void, OnResponseDialog, int);
|
||||
|
||||
private:
|
||||
atom::NativeWindow::DialogScope dialog_scope_;
|
||||
atom::UnresponsiveSuppressor unresponsive_suppressor_;
|
||||
|
||||
// The id to return when the dialog is closed without pressing buttons.
|
||||
int cancel_id_;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
@@ -198,7 +199,7 @@ int ShowMessageBox(NativeWindow* parent,
|
||||
static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() :
|
||||
NULL;
|
||||
|
||||
NativeWindow::DialogScope dialog_scope(parent);
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
return ShowMessageBoxUTF16(hwnd_parent,
|
||||
type,
|
||||
utf16_buttons,
|
||||
@@ -239,6 +240,7 @@ void ShowMessageBox(NativeWindow* parent,
|
||||
}
|
||||
|
||||
void ShowErrorBox(const base::string16& title, const base::string16& content) {
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
ShowMessageBoxUTF16(NULL, MESSAGE_BOX_TYPE_ERROR, {}, -1, 0, 0, L"Error",
|
||||
title, content, gfx::ImageSkia());
|
||||
}
|
||||
|
||||
27
atom/browser/unresponsive_suppressor.cc
Normal file
27
atom/browser/unresponsive_suppressor.cc
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
int g_suppress_level = 0;
|
||||
|
||||
} // namespace
|
||||
|
||||
bool IsUnresponsiveEventSuppressed() {
|
||||
return g_suppress_level > 0;
|
||||
}
|
||||
|
||||
UnresponsiveSuppressor::UnresponsiveSuppressor() {
|
||||
g_suppress_level++;
|
||||
}
|
||||
|
||||
UnresponsiveSuppressor::~UnresponsiveSuppressor() {
|
||||
g_suppress_level--;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
25
atom/browser/unresponsive_suppressor.h
Normal file
25
atom/browser/unresponsive_suppressor.h
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UNRESPONSIVE_SUPPRESSOR_H_
|
||||
#define ATOM_BROWSER_UNRESPONSIVE_SUPPRESSOR_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
bool IsUnresponsiveEventSuppressed();
|
||||
|
||||
class UnresponsiveSuppressor {
|
||||
public:
|
||||
UnresponsiveSuppressor();
|
||||
~UnresponsiveSuppressor();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(UnresponsiveSuppressor);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UNRESPONSIVE_SUPPRESSOR_H_
|
||||
@@ -299,6 +299,8 @@
|
||||
'atom/browser/ui/x/window_state_watcher.h',
|
||||
'atom/browser/ui/x/x_window_utils.cc',
|
||||
'atom/browser/ui/x/x_window_utils.h',
|
||||
'atom/browser/unresponsive_suppressor.cc',
|
||||
'atom/browser/unresponsive_suppressor.h',
|
||||
'atom/browser/web_contents_permission_helper.cc',
|
||||
'atom/browser/web_contents_permission_helper.h',
|
||||
'atom/browser/web_contents_preferences.cc',
|
||||
|
||||
Reference in New Issue
Block a user