Index: chrome/browser/ui/views/apps/chrome_native_app_window_views.cc |
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc |
index cf3624ec8db86604ad71f67e390a75edb7fd5f35..27a7ccfb24006fff920f05d9a90c300c0d85f174 100644 |
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc |
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc |
@@ -10,15 +10,19 @@ |
#include "chrome/browser/app_mode/app_mode_utils.h" |
#include "chrome/browser/favicon/favicon_tab_helper.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" |
+#include "chrome/browser/ui/exclusive_access/mouse_lock_controller.h" |
#include "chrome/browser/ui/host_desktop.h" |
#include "chrome/browser/ui/views/apps/desktop_keyboard_capture.h" |
#include "chrome/browser/ui/views/apps/shaped_app_window_targeter.h" |
+#include "chrome/browser/ui/views/exclusive_access_bubble_views.h" |
#include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views.h" |
#include "chrome/browser/ui/views/frame/taskbar_decorator.h" |
#include "chrome/browser/web_applications/web_app.h" |
#include "chrome/common/chrome_switches.h" |
#include "components/ui/zoom/page_zoom.h" |
#include "components/ui/zoom/zoom_controller.h" |
+#include "content/public/browser/native_web_keyboard_event.h" |
#include "extensions/common/extension.h" |
#include "ui/aura/window.h" |
#include "ui/base/hit_test.h" |
@@ -199,7 +203,9 @@ ChromeNativeAppWindowViews::ChromeNativeAppWindowViews() |
: is_fullscreen_(false), |
has_frame_color_(false), |
active_frame_color_(SK_ColorBLACK), |
- inactive_frame_color_(SK_ColorBLACK) { |
+ inactive_frame_color_(SK_ColorBLACK), |
+ key_capture_requested_(false) { |
+ exclusive_access_manager_.reset(new ExclusiveAccessManager(this)); |
} |
ChromeNativeAppWindowViews::~ChromeNativeAppWindowViews() {} |
@@ -346,8 +352,65 @@ ChromeNativeAppWindowViews::CreateStandardDesktopAppFrame() { |
return views::WidgetDelegateView::CreateNonClientFrameView(widget()); |
} |
-// ui::BaseWindow implementation. |
+apps::AppWindowFrameView* |
+ChromeNativeAppWindowViews::CreateNonStandardAppFrame() { |
+ apps::AppWindowFrameView* frame = |
+ new apps::AppWindowFrameView(widget(), this, has_frame_color_, |
+ active_frame_color_, inactive_frame_color_); |
+ frame->Init(); |
+#if defined(USE_ASH) |
+ // For Aura windows on the Ash desktop the sizes are different and the user |
+ // can resize the window from slightly outside the bounds as well. |
+ if (chrome::IsNativeWindowInAsh(widget()->GetNativeWindow())) { |
+ frame->SetResizeSizes(ash::kResizeInsideBoundsSize, |
+ ash::kResizeOutsideBoundsSize, |
+ ash::kResizeAreaCornerSize); |
+ } |
+#endif |
+ |
+#if !defined(OS_CHROMEOS) |
+ // For non-Ash windows, install an easy resize window targeter, which ensures |
+ // that the root window (not the app) receives mouse events on the edges. |
+ if (chrome::GetHostDesktopTypeForNativeWindow(widget()->GetNativeWindow()) != |
+ chrome::HOST_DESKTOP_TYPE_ASH) { |
+ aura::Window* window = widget()->GetNativeWindow(); |
+ int resize_inside = frame->resize_inside_bounds_size(); |
+ gfx::Insets inset(resize_inside, resize_inside, resize_inside, |
+ resize_inside); |
+ // Add the EasyResizeWindowTargeter on the window, not its root window. The |
+ // root window does not have a delegate, which is needed to handle the event |
+ // in Linux. |
+ window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( |
+ new wm::EasyResizeWindowTargeter(window, inset, inset))); |
+ } |
+#endif |
+ |
+ return frame; |
+} |
+ |
+void ChromeNativeAppWindowViews::Activate() { |
+ NativeAppWindowViews::Activate(); |
+ exclusive_access_manager_->OnTabDetachedFromView(GetActiveWebContents()); |
+} |
+void ChromeNativeAppWindowViews::Deactivate() { |
+ NativeAppWindowViews::Deactivate(); |
+ exclusive_access_manager_->OnTabDeactivated(GetActiveWebContents()); |
+} |
+ |
+bool ChromeNativeAppWindowViews::PreHandleKeyboardEvent( |
+ content::WebContents* source, |
+ const content::NativeWebKeyboardEvent& event, |
+ bool* is_keyboard_shortcut) { |
+ if (event.windowsKeyCode == ui::VKEY_ESCAPE && |
+ exclusive_access_manager_->HandleUserPressedEscape()) { |
+ return true; |
+ } |
+ return NativeAppWindowViews::PreHandleKeyboardEvent(source, event, |
+ is_keyboard_shortcut); |
+} |
+ |
+// ui::BaseWindow implementation. |
gfx::Rect ChromeNativeAppWindowViews::GetRestoredBounds() const { |
#if defined(USE_ASH) |
gfx::Rect* bounds = widget()->GetNativeWindow()->GetProperty( |
@@ -646,10 +709,18 @@ SkColor ChromeNativeAppWindowViews::InactiveFrameColor() const { |
} |
void ChromeNativeAppWindowViews::SetInterceptAllKeys(bool want_all_keys) { |
- if (want_all_keys && (desktop_keyboard_capture_.get() == NULL)) { |
- desktop_keyboard_capture_.reset(new DesktopKeyboardCapture(widget())); |
- } else if (!want_all_keys) { |
- desktop_keyboard_capture_.reset(NULL); |
+ // Noop if there is no state change. |
+ if (want_all_keys == key_capture_requested_) { |
+ return; |
+ } |
+ |
+ key_capture_requested_ = want_all_keys; |
+ if (want_all_keys) { |
+ exclusive_access_manager_->mouse_lock_controller()->RequestToLockMouse( |
+ GetActiveWebContents(), true, true); |
+ } else { |
+ desktop_keyboard_capture_.reset(nullptr); |
+ exclusive_access_manager_->mouse_lock_controller()->LostMouseLock(); |
} |
} |
@@ -675,41 +746,101 @@ void ChromeNativeAppWindowViews::InitializeWindow( |
NULL)); |
} |
-apps::AppWindowFrameView* |
-ChromeNativeAppWindowViews::CreateNonStandardAppFrame() { |
- apps::AppWindowFrameView* frame = |
- new apps::AppWindowFrameView(widget(), |
- this, |
- has_frame_color_, |
- active_frame_color_, |
- inactive_frame_color_); |
- frame->Init(); |
-#if defined(USE_ASH) |
- // For Aura windows on the Ash desktop the sizes are different and the user |
- // can resize the window from slightly outside the bounds as well. |
- if (chrome::IsNativeWindowInAsh(widget()->GetNativeWindow())) { |
- frame->SetResizeSizes(ash::kResizeInsideBoundsSize, |
- ash::kResizeOutsideBoundsSize, |
- ash::kResizeAreaCornerSize); |
+// ExclusiveAccessContext implementation |
+Profile* ChromeNativeAppWindowViews::GetProfile() { |
+ return Profile::FromBrowserContext(app_window()->browser_context()); |
+} |
+ |
+bool ChromeNativeAppWindowViews::IsFullscreen() const { |
+ return NativeAppWindowViews::IsFullscreen(); |
+} |
+ |
+bool ChromeNativeAppWindowViews::IsFullscreenWithToolbar() { |
+ return false; |
+} |
+ |
+bool ChromeNativeAppWindowViews::SupportsFullscreenWithToolbar() { |
+ return false; |
+} |
+ |
+void ChromeNativeAppWindowViews::EnterFullscreen( |
+ const GURL& url, |
+ ExclusiveAccessBubbleType bubble_type, |
+ bool with_toolbar) { |
+ app_window()->Fullscreen(); |
+ UpdateExclusiveAccessExitBubbleContent(url, bubble_type); |
+} |
+ |
+void ChromeNativeAppWindowViews::ExitFullscreen() { |
+ app_window()->Restore(); |
+ UpdateExclusiveAccessExitBubbleContent(GURL(), |
+ EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE); |
+} |
+ |
+void ChromeNativeAppWindowViews::UpdateExclusiveAccessExitBubbleContent( |
+ GURL url, |
+ ExclusiveAccessBubbleType bubble_type) { |
+ if (bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE || url.is_empty()) { |
+ exclusive_access_bubble_views_.reset(); |
+ } else if (exclusive_access_bubble_views_.get()) { |
+ exclusive_access_bubble_views_->UpdateContent(url, bubble_type); |
+ } else { |
+ exclusive_access_bubble_views_.reset( |
+ new ExclusiveAccessBubbleViews(this, url, bubble_type)); |
} |
-#endif |
+} |
-#if !defined(OS_CHROMEOS) |
- // For non-Ash windows, install an easy resize window targeter, which ensures |
- // that the root window (not the app) receives mouse events on the edges. |
- if (chrome::GetHostDesktopTypeForNativeWindow(widget()->GetNativeWindow()) != |
- chrome::HOST_DESKTOP_TYPE_ASH) { |
- aura::Window* window = widget()->GetNativeWindow(); |
- int resize_inside = frame->resize_inside_bounds_size(); |
- gfx::Insets inset( |
- resize_inside, resize_inside, resize_inside, resize_inside); |
- // Add the EasyResizeWindowTargeter on the window, not its root window. The |
- // root window does not have a delegate, which is needed to handle the event |
- // in Linux. |
- window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( |
- new wm::EasyResizeWindowTargeter(window, inset, inset))); |
+content::WebContents* ChromeNativeAppWindowViews::GetActiveWebContents() { |
+ return web_view()->GetWebContents(); |
+} |
+ |
+void ChromeNativeAppWindowViews::UpdateFullscreenWithToolbar( |
+ bool with_toolbar) { |
+ // This is currently a Mac only feature. |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void ChromeNativeAppWindowViews::SetMetroSnapMode(bool enable) { |
+ // Not implemented for chrome app. |
+ NOTIMPLEMENTED(); |
+} |
+ |
+bool ChromeNativeAppWindowViews::IsInMetroSnapMode() { |
+ return false; |
+} |
+ |
+void ChromeNativeAppWindowViews::UpdateDownloadShelf(bool unhide) { |
+ // Apps don't have a download shelf and so nothing to do here. |
+} |
+ |
+bool ChromeNativeAppWindowViews::UseCallbackForMouseLock() { |
+ return true; |
+} |
+ |
+bool ChromeNativeAppWindowViews::MouseLockCallback(bool acquired) { |
+ if (key_capture_requested_ && acquired) { |
+ desktop_keyboard_capture_.reset(new DesktopKeyboardCapture(widget())); |
+ } else { |
+ desktop_keyboard_capture_.reset(nullptr); |
} |
-#endif |
- return frame; |
+ return key_capture_requested_; |
+} |
+ |
+// ExclusiveAccessBubbleViewsContext implementation |
+ExclusiveAccessManager* |
+ChromeNativeAppWindowViews::GetExclusiveAccessManager() { |
+ return exclusive_access_manager_.get(); |
+} |
+ |
+views::Widget* ChromeNativeAppWindowViews::GetWidget() { |
+ return widget(); |
+} |
+ |
+bool ChromeNativeAppWindowViews::IsImmersiveModeEnabled() { |
+ return false; |
+} |
+ |
+gfx::Rect ChromeNativeAppWindowViews::GetTopContainerBoundsInScreen() { |
+ return widget()->GetWindowBoundsInScreen(); |
} |