Home | History | Annotate | Download | only in frame
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/views/frame/browser_frame_aura.h"
      6 
      7 #include "base/command_line.h"
      8 #include "chrome/app/chrome_command_ids.h"
      9 #include "chrome/browser/ui/views/frame/browser_view.h"
     10 #include "grit/chromium_strings.h"
     11 #include "grit/generated_resources.h"
     12 #include "ui/aura/client/aura_constants.h"
     13 #include "ui/aura/window.h"
     14 #include "ui/aura/window_observer.h"
     15 #include "ui/base/hit_test.h"
     16 #include "ui/base/l10n/l10n_util.h"
     17 #include "ui/gfx/font.h"
     18 #include "ui/views/view.h"
     19 
     20 #if defined(USE_ASH)
     21 #include "ash/wm/window_util.h"
     22 #include "chrome/browser/ui/ash/ash_init.h"
     23 #endif
     24 
     25 #if !defined(OS_CHROMEOS)
     26 #include "chrome/browser/ui/views/frame/desktop_browser_frame_aura.h"
     27 #endif
     28 
     29 using aura::Window;
     30 
     31 ////////////////////////////////////////////////////////////////////////////////
     32 // BrowserFrameAura::WindowPropertyWatcher
     33 
     34 class BrowserFrameAura::WindowPropertyWatcher : public aura::WindowObserver {
     35  public:
     36   explicit WindowPropertyWatcher(BrowserFrameAura* browser_frame_aura,
     37                                  BrowserFrame* browser_frame)
     38       : browser_frame_aura_(browser_frame_aura),
     39         browser_frame_(browser_frame) {}
     40 
     41   virtual void OnWindowPropertyChanged(aura::Window* window,
     42                                        const void* key,
     43                                        intptr_t old) OVERRIDE {
     44     if (key != aura::client::kShowStateKey)
     45       return;
     46 
     47     ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old);
     48     ui::WindowShowState new_state =
     49         window->GetProperty(aura::client::kShowStateKey);
     50 
     51     // Allow the frame to be replaced when entering or exiting the maximized
     52     // state.
     53     if (browser_frame_->non_client_view() &&
     54         browser_frame_aura_->browser_view()->browser()->is_app() &&
     55         (old_state == ui::SHOW_STATE_MAXIMIZED ||
     56          new_state == ui::SHOW_STATE_MAXIMIZED)) {
     57       // Defer frame layout when replacing the frame. Layout will occur when the
     58       // window's bounds are updated. The window maximize/restore animations
     59       // clone the window's layers and rely on the subsequent layout to set
     60       // the layer sizes.
     61       // If the window is minimized, the frame view needs to be updated via
     62       // an OnBoundsChanged event so that the frame will change its size
     63       // properly.
     64       browser_frame_->non_client_view()->UpdateFrame(
     65           old_state == ui::SHOW_STATE_MINIMIZED);
     66     }
     67   }
     68 
     69   virtual void OnWindowBoundsChanged(aura::Window* window,
     70                                      const gfx::Rect& old_bounds,
     71                                      const gfx::Rect& new_bounds) OVERRIDE {
     72     // Don't do anything if we don't have our non-client view yet.
     73     if (!browser_frame_->non_client_view())
     74       return;
     75 
     76     // If the window just moved to the top of the screen, or just moved away
     77     // from it, invoke Layout() so the header size can change.
     78     if ((old_bounds.y() == 0 && new_bounds.y() != 0) ||
     79         (old_bounds.y() != 0 && new_bounds.y() == 0))
     80       browser_frame_->non_client_view()->Layout();
     81   }
     82 
     83  private:
     84   BrowserFrameAura* browser_frame_aura_;
     85   BrowserFrame* browser_frame_;
     86 
     87   DISALLOW_COPY_AND_ASSIGN(WindowPropertyWatcher);
     88 };
     89 
     90 ///////////////////////////////////////////////////////////////////////////////
     91 // BrowserFrameAura, public:
     92 
     93 // static
     94 const char BrowserFrameAura::kWindowName[] = "BrowserFrameAura";
     95 
     96 BrowserFrameAura::BrowserFrameAura(BrowserFrame* browser_frame,
     97                                    BrowserView* browser_view)
     98     : views::NativeWidgetAura(browser_frame),
     99       browser_view_(browser_view),
    100       window_property_watcher_(new WindowPropertyWatcher(this, browser_frame)) {
    101   GetNativeWindow()->SetName(kWindowName);
    102   GetNativeWindow()->AddObserver(window_property_watcher_.get());
    103 #if defined(USE_ASH)
    104   // Turn on auto window management if we don't need an explicit bounds.
    105   // This way the requested bounds are honored.
    106   if (!browser_view->browser()->bounds_overridden() &&
    107       !browser_view->browser()->is_session_restore())
    108     SetWindowAutoManaged();
    109 #endif
    110 }
    111 
    112 ///////////////////////////////////////////////////////////////////////////////
    113 // BrowserFrameAura, views::NativeWidgetAura overrides:
    114 
    115 void BrowserFrameAura::OnWindowDestroying() {
    116   // Window is destroyed before our destructor is called, so clean up our
    117   // observer here.
    118   GetNativeWindow()->RemoveObserver(window_property_watcher_.get());
    119   views::NativeWidgetAura::OnWindowDestroying();
    120 }
    121 
    122 void BrowserFrameAura::OnWindowTargetVisibilityChanged(bool visible) {
    123   if (visible) {
    124     // Once the window has been shown we know the requested bounds
    125     // (if provided) have been honored and we can switch on window management.
    126     SetWindowAutoManaged();
    127   }
    128   views::NativeWidgetAura::OnWindowTargetVisibilityChanged(visible);
    129 }
    130 
    131 ////////////////////////////////////////////////////////////////////////////////
    132 // BrowserFrameAura, NativeBrowserFrame implementation:
    133 
    134 views::NativeWidget* BrowserFrameAura::AsNativeWidget() {
    135   return this;
    136 }
    137 
    138 const views::NativeWidget* BrowserFrameAura::AsNativeWidget() const {
    139   return this;
    140 }
    141 
    142 bool BrowserFrameAura::UsesNativeSystemMenu() const {
    143   return false;
    144 }
    145 
    146 int BrowserFrameAura::GetMinimizeButtonOffset() const {
    147   return 0;
    148 }
    149 
    150 void BrowserFrameAura::TabStripDisplayModeChanged() {
    151 }
    152 
    153 ////////////////////////////////////////////////////////////////////////////////
    154 // BrowserFrame, public:
    155 
    156 // static
    157 const gfx::Font& BrowserFrame::GetTitleFont() {
    158   static gfx::Font* title_font = new gfx::Font;
    159   return *title_font;
    160 }
    161 
    162 ////////////////////////////////////////////////////////////////////////////////
    163 // NativeBrowserFrame, public:
    164 
    165 // static
    166 NativeBrowserFrame* NativeBrowserFrame::CreateNativeBrowserFrame(
    167     BrowserFrame* browser_frame,
    168     BrowserView* browser_view) {
    169 #if !defined(OS_CHROMEOS)
    170   if (
    171 #if defined(USE_ASH)
    172       !chrome::ShouldOpenAshOnStartup() &&
    173 #endif
    174       browser_view->browser()->
    175           host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE)
    176     return new DesktopBrowserFrameAura(browser_frame, browser_view);
    177 #endif
    178   return new BrowserFrameAura(browser_frame, browser_view);
    179 }
    180 
    181 ///////////////////////////////////////////////////////////////////////////////
    182 // BrowserFrameAura, private:
    183 
    184 BrowserFrameAura::~BrowserFrameAura() {
    185 }
    186 
    187 void BrowserFrameAura::SetWindowAutoManaged() {
    188 #if defined(USE_ASH)
    189   if (browser_view_->browser()->type() != Browser::TYPE_POPUP ||
    190       browser_view_->browser()->is_app())
    191     ash::wm::SetWindowPositionManaged(GetNativeWindow(), true);
    192 #endif
    193 }
    194