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