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_desktop_root_window_host_win.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <dwmapi.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_service.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_service_factory.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_frame.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_frame_common_win.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h" 150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_window_property_manager_win.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/frame/system_menu_insertion_delegate_win.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab_strip.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/theme_image_mapper.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/theme_resources.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/theme_provider.h" 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/win/dpi.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/menu/native_menu_win.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "dwmapi.lib") 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kClientEdgeThickness = 3; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We need to offset the DWMFrame into the toolbar so that the blackness 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doesn't show up on our rounded corners. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDWMFrameTopOffset = 3; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DesktopThemeProvider maps resource ids using MapThemeImage(). This is 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// necessary for BrowserDesktopRootWindowHostWin so that it uses the windows 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// theme images rather than the ash theme images. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DesktopThemeProvider : public ui::ThemeProvider { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit DesktopThemeProvider(ui::ThemeProvider* delegate) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : delegate_(delegate) { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual gfx::ImageSkia* GetImageSkiaNamed(int id) const OVERRIDE { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->GetImageSkiaNamed( 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::MapThemeImage(chrome::HOST_DESKTOP_TYPE_NATIVE, id)); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual SkColor GetColor(int id) const OVERRIDE { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->GetColor(id); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) virtual int GetDisplayProperty(int id) const OVERRIDE { 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return delegate_->GetDisplayProperty(id); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool ShouldUseNativeFrame() const OVERRIDE { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->ShouldUseNativeFrame(); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool HasCustomImage(int id) const OVERRIDE { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->HasCustomImage( 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::MapThemeImage(chrome::HOST_DESKTOP_TYPE_NATIVE, id)); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual base::RefCountedMemory* GetRawData( 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int id, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScaleFactor scale_factor) const OVERRIDE { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->GetRawData(id, scale_factor); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ThemeProvider* delegate_; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DesktopThemeProvider); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserDesktopRootWindowHostWin, public: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserDesktopRootWindowHostWin::BrowserDesktopRootWindowHostWin( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::internal::NativeWidgetDelegate* native_widget_delegate, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::DesktopNativeWidgetAura* desktop_native_widget_aura, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserView* browser_view, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserFrame* browser_frame) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : DesktopRootWindowHostWin(native_widget_delegate, 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) desktop_native_widget_aura), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_view_(browser_view), 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) browser_frame_(browser_frame), 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) did_gdi_clear_(false) { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::ThemeProvider> theme_provider( 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new DesktopThemeProvider(ThemeServiceFactory::GetForProfile( 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_view->browser()->profile()))); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_frame->SetThemeProvider(theme_provider.Pass()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserDesktopRootWindowHostWin::~BrowserDesktopRootWindowHostWin() { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)views::NativeMenuWin* BrowserDesktopRootWindowHostWin::GetSystemMenu() { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!system_menu_.get()) { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SystemMenuInsertionDelegateWin insertion_delegate; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system_menu_.reset( 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new views::NativeMenuWin(browser_frame_->GetSystemMenuModel(), 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetHWND())); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system_menu_->Rebuild(&insertion_delegate); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return system_menu_.get(); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserDesktopRootWindowHostWin, BrowserDesktopRootWindowHost implementation: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::DesktopRootWindowHost* 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDesktopRootWindowHostWin::AsDesktopRootWindowHost() { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BrowserDesktopRootWindowHostWin::GetMinimizeButtonOffset() const { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return minimize_button_metrics_.GetMinimizeButtonOffsetX(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserDesktopRootWindowHostWin::UsesNativeSystemMenu() const { 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserDesktopRootWindowHostWin, views::DesktopRootWindowHostWin overrides: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BrowserDesktopRootWindowHostWin::GetInitialShowState() const { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STARTUPINFO si = {0}; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) si.cb = sizeof(si); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) si.dwFlags = STARTF_USESHOWWINDOW; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetStartupInfo(&si); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return si.wShowWindow; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserDesktopRootWindowHostWin::GetClientAreaInsets( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Insets* insets) const { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the default client insets for an opaque frame or a glass popup/app 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetWidget()->ShouldUseNativeFrame() || 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !browser_view_->IsBrowserTypeNormal()) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In fullscreen mode, we have no frame. In restored mode, we draw our own 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // client edge over part of the default frame. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetWidget()->IsFullscreen()) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) border_thickness = 0; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (!IsMaximized()) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) border_thickness -= kClientEdgeThickness; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insets->Set(0, border_thickness, border_thickness, border_thickness); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void BrowserDesktopRootWindowHostWin::HandleCreate() { 1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DesktopRootWindowHostWin::HandleCreate(); 1560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser_window_property_manager_ = 1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserWindowPropertyManager::CreateBrowserWindowPropertyManager( 1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser_view_); 1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (browser_window_property_manager_) 1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser_window_property_manager_->UpdateWindowProperties(GetHWND()); 1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserDesktopRootWindowHostWin::HandleFrameChanged() { 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Reinitialize the status bubble, since it needs to be initialized 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // differently depending on whether or not DWM composition is enabled 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch browser_view_->InitStatusBubble(); 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to update the glass region on or off before the base class adjusts 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the window region. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDWMFrame(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DesktopRootWindowHostWin::HandleFrameChanged(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserDesktopRootWindowHostWin::PreHandleMSG(UINT message, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WPARAM w_param, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LPARAM l_param, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LRESULT* result) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (message) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_ACTIVATE: 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (LOWORD(w_param) != WA_INACTIVE) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) minimize_button_metrics_.OnHWNDActivated(); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_ENDSESSION: 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::SessionEnding(); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_INITMENUPOPUP: 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSystemMenu()->UpdateStates(); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DesktopRootWindowHostWin::PreHandleMSG( 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message, w_param, l_param, result); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserDesktopRootWindowHostWin::PostHandleMSG(UINT message, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WPARAM w_param, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LPARAM l_param) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (message) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_CREATE: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) minimize_button_metrics_.Init(GetHWND()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case WM_WINDOWPOSCHANGED: { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDWMFrame(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Windows lies to us about the position of the minimize button before a 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window is visible. We use this position to place the OTR avatar in RTL 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mode, so when the window is shown, we need to re-layout and schedule a 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // paint for the non-client frame view so that the icon top has the correct 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position when the window becomes visible. This fixes bugs where the icon 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appears to overlay the minimize button. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we will call Layout every time SetWindowPos is called with 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SWP_SHOWWINDOW, however callers typically are careful about not 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specifying this flag unless necessary to avoid flicker. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This may be invoked during creation on XP and before the non_client_view 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has been created. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WINDOWPOS* window_pos = reinterpret_cast<WINDOWPOS*>(l_param); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_pos->flags & SWP_SHOWWINDOW && GetWidget()->non_client_view()) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->non_client_view()->Layout(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->non_client_view()->SchedulePaint(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case WM_ERASEBKGND: 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!did_gdi_clear_ && DesktopRootWindowHostWin::ShouldUseNativeFrame()) { 224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // This is necessary to avoid white flashing in the titlebar area around 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // the minimize/maximize/close buttons. 226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) HDC dc = GetDC(GetHWND()); 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) MARGINS margins = GetDWMFrameMargins(); 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RECT client_rect; 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GetClientRect(GetHWND(), &client_rect); 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) HBRUSH brush = CreateSolidBrush(0); 231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RECT rect = { 0, 0, client_rect.right, margins.cyTopHeight }; 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FillRect(dc, &rect, brush); 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DeleteObject(brush); 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ReleaseDC(GetHWND(), dc); 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) did_gdi_clear_ = true; 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserDesktopRootWindowHostWin::IsUsingCustomFrame() const { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't theme popup or app windows, so regardless of whether or not a 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // theme is active for normal browser windows, we don't want to use the custom 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame for popups/apps. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_view_->IsBrowserTypeNormal() && 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !DesktopRootWindowHostWin::IsUsingCustomFrame()) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, we use the native frame when we're told we should by the theme 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provider (e.g. no custom theme is active). 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !GetWidget()->GetThemeProvider()->ShouldUseNativeFrame(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserDesktopRootWindowHostWin::ShouldUseNativeFrame() { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!views::DesktopRootWindowHostWin::ShouldUseNativeFrame()) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This function can get called when the Browser window is closed i.e. in the 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // context of the BrowserView destructor. 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!browser_view_->browser()) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return chrome::ShouldUseNativeFrame(browser_view_, 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetWidget()->GetThemeProvider()); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void BrowserDesktopRootWindowHostWin::FrameTypeChanged() { 268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) views::DesktopRootWindowHostWin::FrameTypeChanged(); 269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) did_gdi_clear_ = false; 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserDesktopRootWindowHostWin, private: 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserDesktopRootWindowHostWin::UpdateDWMFrame() { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For "normal" windows on Aero, we always need to reset the glass area 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // correctly, even if we're not currently showing the native frame (e.g. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because a theme is showing), so we explicitly check for that case rather 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // than checking browser_frame_->ShouldUseNativeFrame() here. Using that here 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would mean we wouldn't reset the glass area to zero when moving from the 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // native frame to an opaque frame, leading to graphical glitches behind the 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // opaque frame. Instead, we use that function below to tell us whether the 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame is currently native or opaque. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetWidget()->client_view() || !browser_view_->IsBrowserTypeNormal() || 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !DesktopRootWindowHostWin::ShouldUseNativeFrame()) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) MARGINS margins = GetDWMFrameMargins(); 289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DwmExtendFrameIntoClientArea(GetHWND(), &margins); 291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)MARGINS BrowserDesktopRootWindowHostWin::GetDWMFrameMargins() const { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MARGINS margins = { 0 }; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the opaque frame is visible, we use the default (zero) margins. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, we need to figure out how to extend the glass in. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetWidget()->ShouldUseNativeFrame()) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In fullscreen mode, we don't extend glass into the client area at all, 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because the GDI-drawn text in the web content composited over it will 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // become semi-transparent over any glass area. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsMaximized() && !GetWidget()->IsFullscreen()) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cxLeftWidth = kClientEdgeThickness + 1; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cxRightWidth = kClientEdgeThickness + 1; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cyBottomHeight = kClientEdgeThickness + 1; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cyTopHeight = kClientEdgeThickness + 1; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In maximized mode, we only have a titlebar strip of glass, no side/bottom 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // borders. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_view_->IsFullscreen()) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect tabstrip_bounds( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_frame_->GetBoundsForTabStrip(browser_view_->tabstrip())); 31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) tabstrip_bounds = gfx::win::DIPToScreenRect(tabstrip_bounds); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cyTopHeight = tabstrip_bounds.bottom() + kDWMFrameTopOffset; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return margins; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserDesktopRootWindowHost, public: 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserDesktopRootWindowHost* 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDesktopRootWindowHost::CreateBrowserDesktopRootWindowHost( 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::internal::NativeWidgetDelegate* native_widget_delegate, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::DesktopNativeWidgetAura* desktop_native_widget_aura, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserView* browser_view, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserFrame* browser_frame) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new BrowserDesktopRootWindowHostWin(native_widget_delegate, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desktop_native_widget_aura, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_view, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_frame); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335