172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_frame_win.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <dwmapi.h>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <shellapi.h>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/accessibility/browser_accessibility_state.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/themes/theme_service.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/themes/theme_service_factory.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h"
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/glass_browser_frame_view.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h"
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/font.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/screen.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/widget/root_view.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/widget/widget_win.h"
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/window/window_win.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kClientEdgeThickness = 3;
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kTabDragWindowAlpha = 200;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We need to offset the DWMFrame into the toolbar so that the blackness
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// doesn't show up on our rounded corners.
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kDWMFrameTopOffset = 3;
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// If not -1, windows are shown with this state.
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic int explicit_show_state = -1;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static (Factory method.)
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserFrame* BrowserFrame::Create(BrowserView* browser_view,
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   Profile* profile) {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowserFrameWin* frame = new BrowserFrameWin(browser_view, profile);
40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  frame->InitBrowserFrame();
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return frame;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// BrowserFrameWin, public:
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserFrameWin::BrowserFrameWin(BrowserView* browser_view, Profile* profile)
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : WindowWin(browser_view),
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserFrame(browser_view),
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser_view_(browser_view),
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)) {
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  set_native_browser_frame(this);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_view_->set_frame(this);
54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  non_client_view()->SetFrameView(CreateFrameViewForWindow());
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't focus anything on creation, selecting a tab will set the focus.
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_focus_on_creation(false);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserFrameWin::~BrowserFrameWin() {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserFrameWin::InitBrowserFrame() {
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WindowWin::Init(NULL, gfx::Rect());
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserFrameWin::SetShowState(int state) {
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  explicit_show_state = state;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen///////////////////////////////////////////////////////////////////////////////
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// BrowserFrameWin, views::WindowWin overrides:
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint BrowserFrameWin::GetShowState() const {
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (explicit_show_state != -1)
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return explicit_show_state;
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  STARTUPINFO si = {0};
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  si.cb = sizeof(si);
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  si.dwFlags = STARTF_USESHOWWINDOW;
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetStartupInfo(&si);
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return si.wShowWindow;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Insets BrowserFrameWin::GetClientAreaInsets() const {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Use the default client insets for an opaque frame or a glass popup/app
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // frame.
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!non_client_view()->UseNativeFrame() ||
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !browser_view_->IsBrowserTypeNormal()) {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return WindowWin::GetClientAreaInsets();
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // In fullscreen mode, we have no frame. In restored mode, we draw our own
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // client edge over part of the default frame.
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (IsFullscreen())
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    border_thickness = 0;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (!IsMaximized())
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    border_thickness -= kClientEdgeThickness;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return gfx::Insets(0, border_thickness, border_thickness, border_thickness);
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserFrameWin::GetAccelerator(int cmd_id,
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                     ui::Accelerator* accelerator) {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser_view_->GetAccelerator(cmd_id, accelerator);
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserFrameWin::OnEndSession(BOOL ending, UINT logoff) {
1094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  BrowserList::SessionEnding();
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserFrameWin::OnInitMenuPopup(HMENU menu, UINT position,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      BOOL is_system_menu) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_view_->PrepareToRunSystemMenu(menu);
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserFrameWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  WindowWin::OnWindowPosChanged(window_pos);
1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateDWMFrame();
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Windows lies to us about the position of the minimize button before a
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // window is visible.  We use this position to place the OTR avatar in RTL
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // mode, so when the window is shown, we need to re-layout and schedule a
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // paint for the non-client frame view so that the icon top has the correct
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // position when the window becomes visible.  This fixes bugs where the icon
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // appears to overlay the minimize button.
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that we will call Layout every time SetWindowPos is called with
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SWP_SHOWWINDOW, however callers typically are careful about not specifying
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // this flag unless necessary to avoid flicker.
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (window_pos->flags & SWP_SHOWWINDOW) {
131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    non_client_view()->Layout();
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    non_client_view()->SchedulePaint();
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochThemeProvider* BrowserFrameWin::GetThemeProvider() const {
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return ThemeServiceFactory::GetForProfile(
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      browser_view_->browser()->profile());
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid BrowserFrameWin::OnScreenReaderDetected() {
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BrowserAccessibilityState::GetInstance()->OnScreenReaderDetected();
143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  WindowWin::OnScreenReaderDetected();
144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// BrowserFrameWin, views::Window overrides:
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserFrameWin::Activate() {
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When running under remote desktop, if the remote desktop client is not
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // active on the users desktop, then none of the windows contained in the
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // remote desktop will be activated.  However, WindowWin::Activate will still
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // bring this browser window to the foreground.  We explicitly set ourselves
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // as the last active browser window to ensure that we get treated as such by
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the rest of Chrome.
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowserList::SetLastActive(browser_view_->browser());
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WindowWin::Activate();
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserFrameWin::UpdateFrameAfterFrameChange() {
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We need to update the glass region on or off before the base class adjusts
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the window region.
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateDWMFrame();
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WindowWin::UpdateFrameAfterFrameChange();
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochviews::RootView* BrowserFrameWin::CreateRootView() {
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return delegate_->DelegateCreateRootView();
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenviews::NonClientFrameView* BrowserFrameWin::CreateFrameViewForWindow() {
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return delegate_->DelegateCreateFrameViewForWindow();
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool BrowserFrameWin::ShouldUseNativeFrame() const {
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return AlwaysUseNativeFrame();
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// BrowserFrameWin, NativeBrowserFrame implementation:
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenviews::NativeWindow* BrowserFrameWin::AsNativeWindow() {
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return this;
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst views::NativeWindow* BrowserFrameWin::AsNativeWindow() const {
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return this;
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenBrowserNonClientFrameView* BrowserFrameWin::CreateBrowserNonClientFrameView() {
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (AlwaysUseNativeFrame())
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return new GlassBrowserFrameView(this, browser_view_);
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return browser::CreateBrowserNonClientFrameView(this, browser_view_);
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint BrowserFrameWin::GetMinimizeButtonOffset() const {
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TITLEBARINFOEX titlebar_info;
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SendMessage(GetNativeView(), WM_GETTITLEBARINFOEX, 0, (WPARAM)&titlebar_info);
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CPoint minimize_button_corner(titlebar_info.rgrect[2].left,
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                titlebar_info.rgrect[2].top);
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MapWindowPoints(HWND_DESKTOP, GetNativeView(), &minimize_button_corner, 1);
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return minimize_button_corner.x;
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenui::ThemeProvider* BrowserFrameWin::GetThemeProviderForFrame() const {
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // This is implemented for a different interface than GetThemeProvider is,
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // but they mean the same things.
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return GetThemeProvider();
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool BrowserFrameWin::AlwaysUseNativeFrame() const {
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // App panel windows draw their own frame.
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (browser_view_->IsBrowserTypePanel())
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We don't theme popup or app windows, so regardless of whether or not a
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // theme is active for normal browser windows, we don't want to use the custom
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // frame for popups/apps.
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!browser_view_->IsBrowserTypeNormal() &&
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      views::WidgetWin::IsAeroGlassEnabled())
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return true;
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Otherwise, we use the native frame when we're told we should by the theme
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // provider (e.g. no custom theme is active).
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return GetThemeProvider()->ShouldUseNativeFrame();
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserFrameWin::TabStripDisplayModeChanged() {
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (GetRootView()->has_children()) {
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Make sure the child of the root view gets Layout again.
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    GetRootView()->GetChildViewAt(0)->InvalidateLayout();
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetRootView()->Layout();
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateDWMFrame();
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// BrowserFrameWin, private:
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserFrameWin::UpdateDWMFrame() {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Nothing to do yet, or we're not showing a DWM frame.
247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!client_view() || !AlwaysUseNativeFrame())
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MARGINS margins = { 0 };
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (browser_view_->IsBrowserTypeNormal()) {
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // In fullscreen mode, we don't extend glass into the client area at all,
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // because the GDI-drawn text in the web content composited over it will
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // become semi-transparent over any glass area.
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!IsMaximized() && !IsFullscreen()) {
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      margins.cxLeftWidth = kClientEdgeThickness + 1;
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      margins.cxRightWidth = kClientEdgeThickness + 1;
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      margins.cyBottomHeight = kClientEdgeThickness + 1;
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      margins.cyTopHeight = kClientEdgeThickness + 1;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // In maximized mode, we only have a titlebar strip of glass, no side/bottom
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // borders.
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!browser_view_->IsFullscreen()) {
2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      gfx::Rect tabstrip_bounds(
2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          GetBoundsForTabStrip(browser_view_->tabstrip()));
2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      margins.cyTopHeight = (browser_view_->UseVerticalTabs() ?
2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          tabstrip_bounds.y() : tabstrip_bounds.bottom()) + kDWMFrameTopOffset;
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // For popup and app windows we want to use the default margins.
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DwmExtendFrameIntoClientArea(GetNativeView(), &margins);
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// BrowserFrame, public:
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst gfx::Font& BrowserFrame::GetTitleFont() {
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static gfx::Font* title_font =
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new gfx::Font(views::WindowWin::GetWindowTitleFont());
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return *title_font;
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
285