15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_frame_aura.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/aura_constants.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_observer.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/font.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/ash_init.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_CHROMEOS)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/desktop_browser_frame_aura.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using aura::Window;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserFrameAura::WindowPropertyWatcher
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserFrameAura::WindowPropertyWatcher : public aura::WindowObserver {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit WindowPropertyWatcher(BrowserFrameAura* browser_frame_aura,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 BrowserFrame* browser_frame)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : browser_frame_aura_(browser_frame_aura),
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_frame_(browser_frame) {}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowPropertyChanged(aura::Window* window,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const void* key,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       intptr_t old) OVERRIDE {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (key != aura::client::kShowStateKey)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::WindowShowState new_state =
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        window->GetProperty(aura::client::kShowStateKey);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Allow the frame to be replaced when entering or exiting the maximized
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // state.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (browser_frame_->non_client_view() &&
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_frame_aura_->browser_view()->browser()->is_app() &&
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (old_state == ui::SHOW_STATE_MAXIMIZED ||
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         new_state == ui::SHOW_STATE_MAXIMIZED)) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Defer frame layout when replacing the frame. Layout will occur when the
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // window's bounds are updated. The window maximize/restore animations
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // clone the window's layers and rely on the subsequent layout to set
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the layer sizes.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If the window is minimized, the frame view needs to be updated via
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // an OnBoundsChanged event so that the frame will change its size
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // properly.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_frame_->non_client_view()->UpdateFrame(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          old_state == ui::SHOW_STATE_MINIMIZED);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowBoundsChanged(aura::Window* window,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const gfx::Rect& old_bounds,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const gfx::Rect& new_bounds) OVERRIDE {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't do anything if we don't have our non-client view yet.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!browser_frame_->non_client_view())
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the window just moved to the top of the screen, or just moved away
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // from it, invoke Layout() so the header size can change.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((old_bounds.y() == 0 && new_bounds.y() != 0) ||
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (old_bounds.y() != 0 && new_bounds.y() == 0))
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_frame_->non_client_view()->Layout();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserFrameAura* browser_frame_aura_;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserFrame* browser_frame_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WindowPropertyWatcher);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserFrameAura, public:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char BrowserFrameAura::kWindowName[] = "BrowserFrameAura";
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserFrameAura::BrowserFrameAura(BrowserFrame* browser_frame,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   BrowserView* browser_view)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : views::NativeWidgetAura(browser_frame),
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_view_(browser_view),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_property_watcher_(new WindowPropertyWatcher(this, browser_frame)) {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetNativeWindow()->SetName(kWindowName);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetNativeWindow()->AddObserver(window_property_watcher_.get());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Turn on auto window management if we don't need an explicit bounds.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This way the requested bounds are honored.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!browser_view->browser()->bounds_overridden() &&
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !browser_view->browser()->is_session_restore())
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetWindowAutoManaged();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserFrameAura, views::NativeWidgetAura overrides:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserFrameAura::OnWindowDestroying() {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Window is destroyed before our destructor is called, so clean up our
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // observer here.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetNativeWindow()->RemoveObserver(window_property_watcher_.get());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::NativeWidgetAura::OnWindowDestroying();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserFrameAura::OnWindowTargetVisibilityChanged(bool visible) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (visible) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once the window has been shown we know the requested bounds
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (if provided) have been honored and we can switch on window management.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetWindowAutoManaged();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::NativeWidgetAura::OnWindowTargetVisibilityChanged(visible);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserFrameAura, NativeBrowserFrame implementation:
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::NativeWidget* BrowserFrameAura::AsNativeWidget() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const views::NativeWidget* BrowserFrameAura::AsNativeWidget() const {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserFrameAura::UsesNativeSystemMenu() const {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BrowserFrameAura::GetMinimizeButtonOffset() const {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserFrameAura::TabStripDisplayModeChanged() {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserFrame, public:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::Font& BrowserFrame::GetTitleFont() {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gfx::Font* title_font = new gfx::Font;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *title_font;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeBrowserFrame, public:
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeBrowserFrame* NativeBrowserFrame::CreateNativeBrowserFrame(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserFrame* browser_frame,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserView* browser_view) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_CHROMEOS)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !chrome::ShouldOpenAshOnStartup() &&
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser_view->browser()->
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new DesktopBrowserFrameAura(browser_frame, browser_view);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new BrowserFrameAura(browser_frame, browser_view);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserFrameAura, private:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserFrameAura::~BrowserFrameAura() {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserFrameAura::SetWindowAutoManaged() {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser_view_->browser()->type() != Browser::TYPE_POPUP ||
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_view_->browser()->is_app())
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::wm::SetWindowPositionManaged(GetNativeWindow(), true);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
194