Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: chrome/browser/ui/views/frame/browser_frame_win.cc

Issue 138943006: Remove a bunch of dead files after the win aura switch. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_win.h"
6
7 #include <dwmapi.h>
8 #include <shellapi.h>
9 #include <set>
10
11 #include "base/command_line.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/win/metro.h"
14 #include "chrome/app/chrome_command_ids.h"
15 #include "chrome/browser/lifetime/application_lifetime.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/search_engines/util.h"
18 #include "chrome/browser/ui/browser_commands.h"
19 #include "chrome/browser/ui/browser_finder.h"
20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "chrome/browser/ui/views/frame/browser_frame_common_win.h"
22 #include "chrome/browser/ui/views/frame/browser_view.h"
23 #include "chrome/browser/ui/views/frame/browser_window_property_manager_win.h"
24 #include "chrome/browser/ui/views/frame/system_menu_insertion_delegate_win.h"
25 #include "chrome/browser/ui/views/tabs/tab_strip.h"
26 #include "chrome/common/chrome_constants.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "content/public/browser/browser_accessibility_state.h"
29 #include "content/public/browser/page_navigator.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/page_transition_types.h"
32 #include "grit/generated_resources.h"
33 #include "grit/theme_resources.h"
34 #include "ui/base/l10n/l10n_util.h"
35 #include "ui/base/layout.h"
36 #include "ui/base/models/simple_menu_model.h"
37 #include "ui/base/resource/resource_bundle.h"
38 #include "ui/base/theme_provider.h"
39 #include "ui/base/window_open_disposition.h"
40 #include "ui/gfx/win/dpi.h"
41 #include "ui/views/controls/menu/native_menu_win.h"
42 #include "ui/views/views_delegate.h"
43 #include "ui/views/widget/native_widget_win.h"
44 #include "ui/views/widget/widget.h"
45 #include "ui/views/win/hwnd_message_handler.h"
46 #include "ui/views/window/non_client_view.h"
47 #include "url/gurl.h"
48 #include "win8/util/win8_util.h"
49
50 #pragma comment(lib, "dwmapi.lib")
51
52 // static
53 static const int kClientEdgeThickness = 3;
54 static const int kTabDragWindowAlpha = 200;
55 // We need to offset the DWMFrame into the toolbar so that the blackness
56 // doesn't show up on our rounded corners.
57 static const int kDWMFrameTopOffset = 3;
58 // If not -1, windows are shown with this state.
59 static int explicit_show_state = -1;
60
61 using content::OpenURLParams;
62 using content::Referrer;
63 using content::WebContents;
64
65 #if !defined(USE_AURA)
66 extern "C" {
67 // Windows metro exported functions from metro_driver.
68 typedef void (*SetFrameWindow)(HWND window);
69 typedef void (*CloseFrameWindow)(HWND window);
70 typedef void (*FlipFrameWindows)();
71 typedef void (*MetroSetFullscreen)(bool fullscreen);
72 }
73 #endif // USE_AURA
74
75 views::Button* MakeWindowSwitcherButton(views::ButtonListener* listener,
76 bool is_off_the_record) {
77 views::ImageButton* switcher_button = new views::ImageButton(listener);
78 // The button in the incognito window has the hot-cold images inverted
79 // with respect to the regular browser window.
80 switcher_button->SetImage(
81 views::ImageButton::STATE_NORMAL,
82 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
83 is_off_the_record ? IDR_INCOGNITO_SWITCH_ON :
84 IDR_INCOGNITO_SWITCH_OFF));
85 switcher_button->SetImage(
86 views::ImageButton::STATE_HOVERED,
87 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
88 is_off_the_record ? IDR_INCOGNITO_SWITCH_OFF :
89 IDR_INCOGNITO_SWITCH_ON));
90 switcher_button->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
91 views::ImageButton::ALIGN_MIDDLE);
92 return switcher_button;
93 }
94
95 ///////////////////////////////////////////////////////////////////////////////
96 // BrowserFrameWin, public:
97
98 BrowserFrameWin::BrowserFrameWin(BrowserFrame* browser_frame,
99 BrowserView* browser_view)
100 : views::NativeWidgetWin(browser_frame),
101 browser_view_(browser_view),
102 browser_frame_(browser_frame) {
103 if (win8::IsSingleWindowMetroMode()) {
104 browser_view->SetWindowSwitcherButton(
105 MakeWindowSwitcherButton(this, browser_view->IsOffTheRecord()));
106 }
107 }
108
109 BrowserFrameWin::~BrowserFrameWin() {
110 }
111
112 // static
113 void BrowserFrameWin::SetShowState(int state) {
114 explicit_show_state = state;
115 }
116
117 void BrowserFrameWin::AdjustFrameForImmersiveMode() {
118 #if defined(USE_AURA)
119 return;
120 #endif // USE_AURA
121 HMODULE metro = base::win::GetMetroModule();
122 if (!metro)
123 return;
124 // We are in metro mode.
125 browser_frame_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
126 SetFrameWindow set_frame_window = reinterpret_cast<SetFrameWindow>(
127 ::GetProcAddress(metro, "SetFrameWindow"));
128 set_frame_window(browser_frame_->GetNativeWindow());
129 }
130
131 void BrowserFrameWin::CloseImmersiveFrame() {
132 #if defined(USE_AURA)
133 return;
134 #endif // USE_AURA
135 HMODULE metro = base::win::GetMetroModule();
136 if (!metro)
137 return;
138 CloseFrameWindow close_frame_window = reinterpret_cast<CloseFrameWindow>(
139 ::GetProcAddress(metro, "CloseFrameWindow"));
140 close_frame_window(browser_frame_->GetNativeWindow());
141 }
142
143
144 views::NativeMenuWin* BrowserFrameWin::GetSystemMenu() {
145 if (!system_menu_.get()) {
146 SystemMenuInsertionDelegateWin insertion_delegate;
147 system_menu_.reset(
148 new views::NativeMenuWin(browser_frame_->GetSystemMenuModel(),
149 GetNativeView()));
150 system_menu_->Rebuild(&insertion_delegate);
151 }
152 return system_menu_.get();
153 }
154
155 ///////////////////////////////////////////////////////////////////////////////
156 // BrowserFrameWin, views::NativeWidgetWin overrides:
157
158 int BrowserFrameWin::GetInitialShowState() const {
159 if (explicit_show_state != -1)
160 return explicit_show_state;
161
162 STARTUPINFO si = {0};
163 si.cb = sizeof(si);
164 si.dwFlags = STARTF_USESHOWWINDOW;
165 GetStartupInfo(&si);
166 return si.wShowWindow;
167 }
168
169 bool BrowserFrameWin::GetClientAreaInsets(gfx::Insets* insets) const {
170 // Use the default client insets for an opaque frame or a glass popup/app
171 // frame.
172 if (!GetWidget()->ShouldUseNativeFrame() ||
173 !browser_view_->IsBrowserTypeNormal()) {
174 return false;
175 }
176
177 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
178 // In fullscreen mode, we have no frame. In restored mode, we draw our own
179 // client edge over part of the default frame.
180 if (IsFullscreen())
181 border_thickness = 0;
182 else if (!IsMaximized())
183 border_thickness -= kClientEdgeThickness;
184 insets->Set(0, border_thickness, border_thickness, border_thickness);
185 return true;
186 }
187
188 void BrowserFrameWin::HandleCreate() {
189 NativeWidgetWin::HandleCreate();
190 browser_window_property_manager_ =
191 BrowserWindowPropertyManager::CreateBrowserWindowPropertyManager(
192 browser_view_);
193 if (browser_window_property_manager_) {
194 browser_window_property_manager_->UpdateWindowProperties(
195 GetMessageHandler()->hwnd());
196 }
197 }
198
199 void BrowserFrameWin::HandleFrameChanged() {
200 // Handle window frame layout changes, then set the updated glass region.
201 NativeWidgetWin::HandleFrameChanged();
202 UpdateDWMFrame();
203 }
204
205 bool BrowserFrameWin::PreHandleMSG(UINT message,
206 WPARAM w_param,
207 LPARAM l_param,
208 LRESULT* result) {
209 static const UINT metro_navigation_search_message =
210 RegisterWindowMessage(chrome::kMetroNavigationAndSearchMessage);
211
212 static const UINT metro_get_current_tab_info_message =
213 RegisterWindowMessage(chrome::kMetroGetCurrentTabInfoMessage);
214
215 if (message == metro_navigation_search_message) {
216 HandleMetroNavSearchRequest(w_param, l_param);
217 return false;
218 } else if (message == metro_get_current_tab_info_message) {
219 GetMetroCurrentTabInfo(w_param);
220 return false;
221 }
222
223 switch (message) {
224 case WM_ACTIVATE:
225 if (LOWORD(w_param) != WA_INACTIVE)
226 minimize_button_metrics_.OnHWNDActivated();
227 return false;
228 case WM_PRINT:
229 if (win8::IsSingleWindowMetroMode()) {
230 // This message is sent by the AnimateWindow API which is used in metro
231 // mode to flip between active chrome windows.
232 RECT client_rect = {0};
233 ::GetClientRect(GetNativeView(), &client_rect);
234 HDC dest_dc = reinterpret_cast<HDC>(w_param);
235 DCHECK(dest_dc);
236 HDC src_dc = ::GetDC(GetNativeView());
237 ::BitBlt(dest_dc, 0, 0, client_rect.right - client_rect.left,
238 client_rect.bottom - client_rect.top, src_dc, 0, 0,
239 SRCCOPY);
240 ::ReleaseDC(GetNativeView(), src_dc);
241 *result = 0;
242 return true;
243 }
244 return false;
245 case WM_ENDSESSION:
246 chrome::SessionEnding();
247 return true;
248 case WM_INITMENUPOPUP:
249 GetSystemMenu()->UpdateStates();
250 return true;
251 }
252 return false;
253 }
254
255 void BrowserFrameWin::PostHandleMSG(UINT message,
256 WPARAM w_param,
257 LPARAM l_param) {
258 switch (message) {
259 case WM_CREATE:
260 minimize_button_metrics_.Init(GetNativeView());
261 break;
262 case WM_WINDOWPOSCHANGED:
263 UpdateDWMFrame();
264
265 // Windows lies to us about the position of the minimize button before a
266 // window is visible. We use this position to place the OTR avatar in RTL
267 // mode, so when the window is shown, we need to re-layout and schedule a
268 // paint for the non-client frame view so that the icon top has the correct
269 // position when the window becomes visible. This fixes bugs where the icon
270 // appears to overlay the minimize button.
271 // Note that we will call Layout every time SetWindowPos is called with
272 // SWP_SHOWWINDOW, however callers typically are careful about not
273 // specifying this flag unless necessary to avoid flicker.
274 // This may be invoked during creation on XP and before the non_client_view
275 // has been created.
276 WINDOWPOS* window_pos = reinterpret_cast<WINDOWPOS*>(l_param);
277 if (window_pos->flags & SWP_SHOWWINDOW && GetWidget()->non_client_view()) {
278 GetWidget()->non_client_view()->Layout();
279 GetWidget()->non_client_view()->SchedulePaint();
280 }
281 break;
282 }
283 }
284
285 bool BrowserFrameWin::ShouldUseNativeFrame() const {
286 if (!NativeWidgetWin::ShouldUseNativeFrame())
287 return false;
288 return chrome::ShouldUseNativeFrame(browser_view_,
289 GetWidget()->GetThemeProvider());
290 }
291
292 void BrowserFrameWin::Show() {
293 AdjustFrameForImmersiveMode();
294 views::NativeWidgetWin::Show();
295 }
296
297 void BrowserFrameWin::ShowMaximizedWithBounds(
298 const gfx::Rect& restored_bounds) {
299 AdjustFrameForImmersiveMode();
300 views::NativeWidgetWin::ShowMaximizedWithBounds(restored_bounds);
301 }
302
303 void BrowserFrameWin::ShowWithWindowState(ui::WindowShowState show_state) {
304 AdjustFrameForImmersiveMode();
305 views::NativeWidgetWin::ShowWithWindowState(show_state);
306 }
307
308 void BrowserFrameWin::Close() {
309 CloseImmersiveFrame();
310 views::NativeWidgetWin::Close();
311 }
312
313 void BrowserFrameWin::FrameTypeChanged() {
314 // In Windows 8 metro mode the frame type is set to FRAME_TYPE_FORCE_CUSTOM
315 // by default. We reset it back to FRAME_TYPE_DEFAULT to ensure that we
316 // don't end up defaulting to BrowserNonClientFrameView in all cases.
317 if (win8::IsSingleWindowMetroMode())
318 browser_frame_->set_frame_type(views::Widget::FRAME_TYPE_DEFAULT);
319
320 views::NativeWidgetWin::FrameTypeChanged();
321
322 // In Windows 8 metro mode we call Show on the BrowserFrame instance to
323 // ensure that the window can be styled appropriately, i.e. no sysmenu,
324 // etc.
325 if (win8::IsSingleWindowMetroMode())
326 Show();
327 }
328
329 void BrowserFrameWin::SetFullscreen(bool fullscreen) {
330 if (win8::IsSingleWindowMetroMode()) {
331 HMODULE metro = base::win::GetMetroModule();
332 if (metro) {
333 MetroSetFullscreen set_full_screen = reinterpret_cast<MetroSetFullscreen>(
334 ::GetProcAddress(metro, "SetFullscreen"));
335 DCHECK(set_full_screen);
336 if (set_full_screen)
337 set_full_screen(fullscreen);
338 } else {
339 NOTREACHED() << "Failed to get metro driver module";
340 }
341 }
342 views::NativeWidgetWin::SetFullscreen(fullscreen);
343 }
344
345 void BrowserFrameWin::Activate() {
346 // In Windows 8 metro mode we have only one window visible at any given time.
347 // The Activate code path is typically called when a new browser window is
348 // being activated. In metro we need to ensure that the window currently
349 // being displayed is hidden and the new window being activated becomes
350 // visible. This is achieved by calling AdjustFrameForImmersiveMode()
351 // followed by ShowWindow().
352 if (win8::IsSingleWindowMetroMode()) {
353 AdjustFrameForImmersiveMode();
354 ::ShowWindow(browser_frame_->GetNativeWindow(), SW_SHOWNORMAL);
355 } else {
356 views::NativeWidgetWin::Activate();
357 }
358 }
359
360
361 ////////////////////////////////////////////////////////////////////////////////
362 // BrowserFrameWin, NativeBrowserFrame implementation:
363
364 views::NativeWidget* BrowserFrameWin::AsNativeWidget() {
365 return this;
366 }
367
368 const views::NativeWidget* BrowserFrameWin::AsNativeWidget() const {
369 return this;
370 }
371
372 bool BrowserFrameWin::UsesNativeSystemMenu() const {
373 return true;
374 }
375
376 int BrowserFrameWin::GetMinimizeButtonOffset() const {
377 return minimize_button_metrics_.GetMinimizeButtonOffsetX();
378 }
379
380 void BrowserFrameWin::ButtonPressed(views::Button* sender,
381 const ui::Event& event) {
382 HMODULE metro = base::win::GetMetroModule();
383 if (!metro)
384 return;
385
386 // Toggle the profile and switch to the corresponding browser window in the
387 // profile. The GetOffTheRecordProfile function is documented to create an
388 // incognito profile if one does not exist. That is not a concern as the
389 // windows 8 window switcher button shows up on the caption only when a
390 // normal window and an incognito window are open simultaneously.
391 Profile* profile_to_switch_to = NULL;
392 Profile* current_profile = browser_view()->browser()->profile();
393 if (current_profile->IsOffTheRecord())
394 profile_to_switch_to = current_profile->GetOriginalProfile();
395 else
396 profile_to_switch_to = current_profile->GetOffTheRecordProfile();
397
398 DCHECK(profile_to_switch_to);
399
400 Browser* browser_to_switch_to = chrome::FindTabbedBrowser(
401 profile_to_switch_to, false, chrome::HOST_DESKTOP_TYPE_NATIVE);
402
403 DCHECK(browser_to_switch_to);
404
405 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(
406 browser_to_switch_to);
407
408 // Tell the metro_driver to switch to the Browser we found above. This
409 // causes the current browser window to be hidden.
410 SetFrameWindow set_frame_window = reinterpret_cast<SetFrameWindow>(
411 ::GetProcAddress(metro, "SetFrameWindow"));
412 set_frame_window(browser_view->frame()->GetNativeWindow());
413 ::ShowWindow(browser_view->frame()->GetNativeWindow(), SW_SHOWNORMAL);
414 }
415
416 ///////////////////////////////////////////////////////////////////////////////
417 // BrowserFrameWin, private:
418
419 void BrowserFrameWin::UpdateDWMFrame() {
420 // For "normal" windows on Aero, we always need to reset the glass area
421 // correctly, even if we're not currently showing the native frame (e.g.
422 // because a theme is showing), so we explicitly check for that case rather
423 // than checking browser_frame_->ShouldUseNativeFrame() here. Using that here
424 // would mean we wouldn't reset the glass area to zero when moving from the
425 // native frame to an opaque frame, leading to graphical glitches behind the
426 // opaque frame. Instead, we use that function below to tell us whether the
427 // frame is currently native or opaque.
428 if (!GetWidget()->client_view() || !browser_view_->IsBrowserTypeNormal() ||
429 !NativeWidgetWin::ShouldUseNativeFrame())
430 return;
431
432 MARGINS margins = { 0 };
433
434 // If the opaque frame is visible, we use the default (zero) margins.
435 // Otherwise, we need to figure out how to extend the glass in.
436 if (browser_frame_->ShouldUseNativeFrame()) {
437 // In fullscreen mode, we don't extend glass into the client area at all,
438 // because the GDI-drawn text in the web content composited over it will
439 // become semi-transparent over any glass area.
440 if (!IsMaximized() && !IsFullscreen()) {
441 margins.cxLeftWidth = kClientEdgeThickness + 1;
442 margins.cxRightWidth = kClientEdgeThickness + 1;
443 margins.cyBottomHeight = kClientEdgeThickness + 1;
444 margins.cyTopHeight = kClientEdgeThickness + 1;
445 }
446 // In maximized mode, we only have a titlebar strip of glass, no side/bottom
447 // borders.
448 if (!IsFullscreen()) {
449 gfx::Rect tabstrip_bounds(
450 browser_frame_->GetBoundsForTabStrip(browser_view_->tabstrip()));
451 tabstrip_bounds = gfx::win::DIPToScreenRect(tabstrip_bounds);
452 margins.cyTopHeight = tabstrip_bounds.bottom() + kDWMFrameTopOffset;
453 }
454 }
455
456 DwmExtendFrameIntoClientArea(GetNativeView(), &margins);
457 }
458
459 void BrowserFrameWin::HandleMetroNavSearchRequest(WPARAM w_param,
460 LPARAM l_param) {
461 if (!base::win::IsMetroProcess()) {
462 NOTREACHED() << "Received unexpected metro navigation request";
463 return;
464 }
465
466 if (!w_param && !l_param) {
467 NOTREACHED() << "Invalid metro request parameters";
468 return;
469 }
470
471 Browser* browser = browser_view()->browser();
472 DCHECK(browser);
473
474 GURL request_url;
475 if (w_param) {
476 request_url = GURL(reinterpret_cast<const wchar_t*>(w_param));
477 } else if (l_param) {
478 request_url = GetDefaultSearchURLForSearchTerms(
479 browser->profile(), reinterpret_cast<const wchar_t*>(l_param));
480 }
481 if (request_url.is_valid()) {
482 browser->OpenURL(OpenURLParams(request_url, Referrer(), NEW_FOREGROUND_TAB,
483 content::PAGE_TRANSITION_TYPED, false));
484 }
485 }
486
487 void BrowserFrameWin::GetMetroCurrentTabInfo(WPARAM w_param) {
488 if (!base::win::IsMetroProcess()) {
489 NOTREACHED() << "Received unexpected metro request";
490 return;
491 }
492
493 if (!w_param) {
494 NOTREACHED() << "Invalid metro request parameter";
495 return;
496 }
497
498 base::win::CurrentTabInfo* current_tab_info =
499 reinterpret_cast<base::win::CurrentTabInfo*>(w_param);
500
501 Browser* browser = browser_view()->browser();
502 DCHECK(browser);
503
504 // We allocate memory for the title and url via LocalAlloc. The caller has to
505 // free the memory via LocalFree.
506 current_tab_info->title = base::win::LocalAllocAndCopyString(
507 browser->GetWindowTitleForCurrentTab());
508
509 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
510 DCHECK(current_tab);
511
512 current_tab_info->url = base::win::LocalAllocAndCopyString(
513 base::UTF8ToWide(current_tab->GetURL().spec()));
514 }
515
516 ////////////////////////////////////////////////////////////////////////////////
517 // BrowserFrame, public:
518
519 bool BrowserFrame::ShouldLeaveOffsetNearTopBorder() {
520 if (win8::IsSingleWindowMetroMode()) {
521 if (ui::GetDisplayLayout() == ui::LAYOUT_DESKTOP)
522 return false;
523 }
524 return !IsMaximized();
525 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/frame/browser_frame_win.h ('k') | chrome/browser/ui/views/frame/browser_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698