Commit ca5e056c authored by zelidrag@chromium.org's avatar zelidrag@chromium.org

Fixed screen capture confirmation dialog to be either system- or window-modal...

Fixed screen capture confirmation dialog to be either system- or window-modal depending on where it got initiated from. Previous implementation created window-modal with no parent window which allowed it to hide underneath its browser window.

Fixed handling of window-modal dialogs. Modal dialogs and their toplevel parent windows weren't properly activated on events (i.e. mouse click) that happen in toplevel parent windows area but outside of the modal dialog.

TEST=added WindowModalityControllerTest.EventsForEclipsedWindows, manual: start go/present/<whatever>, try to alt-tab away from the pop up dialog, try to eclipse it with another browser window
BUG=366956

Review URL: https://codereview.chromium.org/252673002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266319 0039d316-1c4b-4281-b951-d872f2087c98
parent a9e390c4
...@@ -206,6 +206,30 @@ TEST_F(WindowModalityControllerTest, Events) { ...@@ -206,6 +206,30 @@ TEST_F(WindowModalityControllerTest, Events) {
} }
} }
// Events on modal parent activate.
TEST_F(WindowModalityControllerTest, EventsForEclipsedWindows) {
aura::test::TestWindowDelegate d;
scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(&d, -1,
gfx::Rect(0, 0, 100, 100)));
scoped_ptr<aura::Window> w11(CreateTestWindowInShellWithDelegate(&d, -11,
gfx::Rect(20, 20, 50, 50)));
::wm::AddTransientChild(w1.get(), w11.get());
scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(&d, -2,
gfx::Rect(0, 0, 50, 50)));
w11->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
// Partially eclipse w1 with w2.
wm::ActivateWindow(w2.get());
{
// Clicking a point on w1 that is not eclipsed by w2.
aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
gfx::Point(90, 90));
generator.ClickLeftButton();
EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
}
}
// Creates windows w1 and non activatiable child w11. Creates transient window // Creates windows w1 and non activatiable child w11. Creates transient window
// w2 and adds it as a transeint child of w1. Ensures that w2 is parented to // w2 and adds it as a transeint child of w1. Ensures that w2 is parented to
// the parent of w1, and that GetModalTransient(w11) returns w2. // the parent of w1, and that GetModalTransient(w11) returns w2.
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "chrome/browser/media/media_capture_devices_dispatcher.h" #include "chrome/browser/media/media_capture_devices_dispatcher.h"
#include "apps/app_window.h"
#include "apps/app_window_registry.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
...@@ -17,6 +19,9 @@ ...@@ -17,6 +19,9 @@
#include "chrome/browser/media/media_stream_capture_indicator.h" #include "chrome/browser/media/media_stream_capture_indicator.h"
#include "chrome/browser/media/media_stream_infobar_delegate.h" #include "chrome/browser/media/media_stream_infobar_delegate.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/screen_capture_notification_ui.h" #include "chrome/browser/ui/screen_capture_notification_ui.h"
#include "chrome/browser/ui/simple_message_box.h" #include "chrome/browser/ui/simple_message_box.h"
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h" #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
...@@ -238,6 +243,28 @@ void StopAudioStreamMonitoringOnUIThread( ...@@ -238,6 +243,28 @@ void StopAudioStreamMonitoringOnUIThread(
#endif // defined(AUDIO_STREAM_MONITORING) #endif // defined(AUDIO_STREAM_MONITORING)
#if !defined(OS_ANDROID)
// Find browser or app window from a given |web_contents|.
gfx::NativeWindow FindParentWindowForWebContents(
content::WebContents* web_contents) {
Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
if (browser && browser->window())
return browser->window()->GetNativeWindow();
const apps::AppWindowRegistry::AppWindowList& window_list =
apps::AppWindowRegistry::Get(
web_contents->GetBrowserContext())->app_windows();
for (apps::AppWindowRegistry::AppWindowList::const_iterator iter =
window_list.begin();
iter != window_list.end(); ++iter) {
if ((*iter)->web_contents() == web_contents)
return (*iter)->GetNativeWindow();
}
return NULL;
}
#endif
} // namespace } // namespace
MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest( MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest(
...@@ -454,6 +481,12 @@ void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( ...@@ -454,6 +481,12 @@ void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest(
// is closed. See http://crbug.com/326690. // is closed. See http://crbug.com/326690.
base::string16 application_title = base::string16 application_title =
GetApplicationTitle(web_contents, extension); GetApplicationTitle(web_contents, extension);
#if !defined(OS_ANDROID)
gfx::NativeWindow parent_window =
FindParentWindowForWebContents(web_contents);
#else
gfx::NativeWindow parent_window = NULL;
#endif
web_contents = NULL; web_contents = NULL;
// For component extensions, bypass message box. // For component extensions, bypass message box.
...@@ -467,7 +500,7 @@ void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( ...@@ -467,7 +500,7 @@ void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest(
IDS_MEDIA_SCREEN_AND_AUDIO_CAPTURE_CONFIRMATION_TEXT, IDS_MEDIA_SCREEN_AND_AUDIO_CAPTURE_CONFIRMATION_TEXT,
application_name); application_name);
chrome::MessageBoxResult result = chrome::ShowMessageBox( chrome::MessageBoxResult result = chrome::ShowMessageBox(
NULL, parent_window,
l10n_util::GetStringFUTF16( l10n_util::GetStringFUTF16(
IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name), IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name),
confirmation_text, confirmation_text,
......
...@@ -33,6 +33,7 @@ class SimpleMessageBoxViews : public views::DialogDelegate { ...@@ -33,6 +33,7 @@ class SimpleMessageBoxViews : public views::DialogDelegate {
MessageBoxType type, MessageBoxType type,
const base::string16& yes_text, const base::string16& yes_text,
const base::string16& no_text, const base::string16& no_text,
bool is_system_modal,
MessageBoxResult* result); MessageBoxResult* result);
virtual ~SimpleMessageBoxViews(); virtual ~SimpleMessageBoxViews();
...@@ -61,6 +62,7 @@ class SimpleMessageBoxViews : public views::DialogDelegate { ...@@ -61,6 +62,7 @@ class SimpleMessageBoxViews : public views::DialogDelegate {
base::string16 yes_text_; base::string16 yes_text_;
base::string16 no_text_; base::string16 no_text_;
MessageBoxResult* result_; MessageBoxResult* result_;
bool is_system_modal_;
views::MessageBoxView* message_box_view_; views::MessageBoxView* message_box_view_;
DISALLOW_COPY_AND_ASSIGN(SimpleMessageBoxViews); DISALLOW_COPY_AND_ASSIGN(SimpleMessageBoxViews);
...@@ -74,12 +76,14 @@ SimpleMessageBoxViews::SimpleMessageBoxViews(const base::string16& title, ...@@ -74,12 +76,14 @@ SimpleMessageBoxViews::SimpleMessageBoxViews(const base::string16& title,
MessageBoxType type, MessageBoxType type,
const base::string16& yes_text, const base::string16& yes_text,
const base::string16& no_text, const base::string16& no_text,
bool is_system_modal,
MessageBoxResult* result) MessageBoxResult* result)
: window_title_(title), : window_title_(title),
type_(type), type_(type),
yes_text_(yes_text), yes_text_(yes_text),
no_text_(no_text), no_text_(no_text),
result_(result), result_(result),
is_system_modal_(is_system_modal),
message_box_view_(new views::MessageBoxView( message_box_view_(new views::MessageBoxView(
views::MessageBoxView::InitParams(message))) { views::MessageBoxView::InitParams(message))) {
CHECK(result_); CHECK(result_);
...@@ -142,7 +146,7 @@ void SimpleMessageBoxViews::DeleteDelegate() { ...@@ -142,7 +146,7 @@ void SimpleMessageBoxViews::DeleteDelegate() {
} }
ui::ModalType SimpleMessageBoxViews::GetModalType() const { ui::ModalType SimpleMessageBoxViews::GetModalType() const {
return ui::MODAL_TYPE_WINDOW; return is_system_modal_ ? ui::MODAL_TYPE_SYSTEM : ui::MODAL_TYPE_WINDOW;
} }
views::View* SimpleMessageBoxViews::GetContentsView() { views::View* SimpleMessageBoxViews::GetContentsView() {
...@@ -209,7 +213,13 @@ MessageBoxResult ShowMessageBoxImpl(gfx::NativeWindow parent, ...@@ -209,7 +213,13 @@ MessageBoxResult ShowMessageBoxImpl(gfx::NativeWindow parent,
MessageBoxResult result = MESSAGE_BOX_RESULT_NO; MessageBoxResult result = MESSAGE_BOX_RESULT_NO;
SimpleMessageBoxViews* dialog = new SimpleMessageBoxViews( SimpleMessageBoxViews* dialog = new SimpleMessageBoxViews(
title, message, type, yes_text, no_text, &result); title,
message,
type,
yes_text,
no_text,
parent == NULL, // is_system_modal
&result);
CreateBrowserModalDialogViews(dialog, parent)->Show(); CreateBrowserModalDialogViews(dialog, parent)->Show();
// Use the widget's window itself so that the message loop exists when the // Use the widget's window itself so that the message loop exists when the
......
...@@ -184,6 +184,13 @@ bool WindowModalityController::ProcessLocatedEvent(aura::Window* target, ...@@ -184,6 +184,13 @@ bool WindowModalityController::ProcessLocatedEvent(aura::Window* target,
aura::Window* modal_transient_child = GetModalTransient(target); aura::Window* modal_transient_child = GetModalTransient(target);
if (modal_transient_child && (event->type() == ui::ET_MOUSE_PRESSED || if (modal_transient_child && (event->type() == ui::ET_MOUSE_PRESSED ||
event->type() == ui::ET_TOUCH_PRESSED)) { event->type() == ui::ET_TOUCH_PRESSED)) {
// Activate top window if transient child window is window modal.
if (TransientChildIsWindowModal(modal_transient_child)) {
aura::Window* toplevel = GetToplevelWindow(target);
DCHECK(toplevel);
ActivateWindow(toplevel);
}
AnimateWindow(modal_transient_child, WINDOW_ANIMATION_TYPE_BOUNCE); AnimateWindow(modal_transient_child, WINDOW_ANIMATION_TYPE_BOUNCE);
} }
if (event->type() == ui::ET_TOUCH_CANCELLED) if (event->type() == ui::ET_TOUCH_CANCELLED)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment