14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_frame_ash.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ash/wm/window_properties.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_state.h"
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/wm/window_state_delegate.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_util.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_shutdown.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/aura_constants.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_observer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using aura::Window;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace {
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// BrowserWindowStateDelegate class handles a user's fullscreen
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// request (Shift+F4/F4).
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class BrowserWindowStateDelegate : public ash::wm::WindowStateDelegate {
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public:
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  explicit BrowserWindowStateDelegate(Browser* browser)
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      : browser_(browser) {
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(browser_);
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual ~BrowserWindowStateDelegate(){}
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Overridden from ash::wm::WindowStateDelegate.
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual bool ToggleFullscreen(ash::wm::WindowState* window_state) OVERRIDE {
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(window_state->IsFullscreen() || window_state->CanMaximize());
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Windows which cannot be maximized should not be fullscreened.
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!window_state->IsFullscreen() && !window_state->CanMaximize())
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return true;
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    chrome::ToggleFullscreenMode(browser_);
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return true;
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Browser* browser_;  // not owned.
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BrowserWindowStateDelegate);
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// BrowserFrameAsh, public:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char BrowserFrameAsh::kWindowName[] = "BrowserFrameAsh";
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)BrowserFrameAsh::BrowserFrameAsh(BrowserFrame* browser_frame,
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 BrowserView* browser_view)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : views::NativeWidgetAura(browser_frame),
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      browser_view_(browser_view) {
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetNativeWindow()->SetName(kWindowName);
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Browser* browser = browser_view->browser();
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ash::wm::WindowState* window_state =
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ash::wm::GetWindowState(GetNativeWindow());
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window_state->SetDelegate(
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scoped_ptr<ash::wm::WindowStateDelegate>(
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          new BrowserWindowStateDelegate(browser)).Pass());
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Turn on auto window management if we don't need an explicit bounds.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This way the requested bounds are honored.
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!browser->bounds_overridden() && !browser->is_session_restore())
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetWindowAutoManaged();
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_CHROMEOS)
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For legacy reasons v1 apps (like Secure Shell) are allowed to consume keys
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // like brightness, volume, etc. Otherwise these keys are handled by the
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Ash window manager.
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  window_state->set_can_consume_system_keys(browser->is_app());
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(OS_CHROMEOS)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// BrowserFrameAsh, views::NativeWidgetAura overrides:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BrowserFrameAsh::OnWindowDestroying(aura::Window* window) {
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Destroy any remaining WebContents early on. Doing so may result in
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // calling back to one of the Views/LayoutManagers or supporting classes of
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // BrowserView. By destroying here we ensure all said classes are valid.
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DestroyBrowserWebContents(browser_view_->browser());
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NativeWidgetAura::OnWindowDestroying(window);
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserFrameAsh::OnWindowTargetVisibilityChanged(bool visible) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (visible) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once the window has been shown we know the requested bounds
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (if provided) have been honored and we can switch on window management.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetWindowAutoManaged();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::NativeWidgetAura::OnWindowTargetVisibilityChanged(visible);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool BrowserFrameAsh::ShouldSaveWindowPlacement() const {
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return NULL == GetWidget()->GetNativeWindow()->GetProperty(
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     ash::kRestoreBoundsOverrideKey);
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BrowserFrameAsh::GetWindowPlacement(
107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    gfx::Rect* bounds,
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ui::WindowShowState* show_state) const {
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  gfx::Rect* override_bounds = GetWidget()->GetNativeWindow()->GetProperty(
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   ash::kRestoreBoundsOverrideKey);
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (override_bounds && !override_bounds->IsEmpty()) {
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    *bounds = *override_bounds;
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    *show_state = GetWidget()->GetNativeWindow()->GetProperty(
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                      ash::kRestoreShowStateOverrideKey);
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else {
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    *bounds = GetWidget()->GetRestoredBounds();
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    *show_state = GetWidget()->GetNativeWindow()->GetProperty(
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                      aura::client::kShowStateKey);
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (*show_state != ui::SHOW_STATE_MAXIMIZED &&
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      *show_state != ui::SHOW_STATE_MINIMIZED) {
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    *show_state = ui::SHOW_STATE_NORMAL;
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// BrowserFrameAsh, NativeBrowserFrame implementation:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)views::NativeWidget* BrowserFrameAsh::AsNativeWidget() {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const views::NativeWidget* BrowserFrameAsh::AsNativeWidget() const {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool BrowserFrameAsh::UsesNativeSystemMenu() const {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int BrowserFrameAsh::GetMinimizeButtonOffset() const {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)BrowserFrameAsh::~BrowserFrameAsh() {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// BrowserFrameAsh, private:
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserFrameAsh::SetWindowAutoManaged() {
153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!browser_view_->browser()->is_type_popup() ||
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      browser_view_->browser()->is_app()) {
15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ash::wm::GetWindowState(GetNativeWindow())->
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        set_window_position_managed(true);
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
159