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) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_desktop_window_tree_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" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/theme_provider.h" 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/win/dpi.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/menu/native_menu_win.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "dwmapi.lib") 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kClientEdgeThickness = 3; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We need to offset the DWMFrame into the toolbar so that the blackness 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doesn't show up on our rounded corners. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDWMFrameTopOffset = 3; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DesktopThemeProvider maps resource ids using MapThemeImage(). This is 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// necessary for BrowserDesktopWindowTreeHostWin so that it uses the windows 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// theme images rather than the ash theme images. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DesktopThemeProvider : public ui::ThemeProvider { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit DesktopThemeProvider(ui::ThemeProvider* delegate) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : delegate_(delegate) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual bool UsingSystemTheme() const OVERRIDE { 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return delegate_->UsingSystemTheme(); 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual gfx::ImageSkia* GetImageSkiaNamed(int id) const OVERRIDE { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->GetImageSkiaNamed( 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::MapThemeImage(chrome::HOST_DESKTOP_TYPE_NATIVE, id)); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual SkColor GetColor(int id) const OVERRIDE { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->GetColor(id); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) virtual int GetDisplayProperty(int id) const OVERRIDE { 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return delegate_->GetDisplayProperty(id); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool ShouldUseNativeFrame() const OVERRIDE { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->ShouldUseNativeFrame(); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool HasCustomImage(int id) const OVERRIDE { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->HasCustomImage( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::MapThemeImage(chrome::HOST_DESKTOP_TYPE_NATIVE, id)); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual base::RefCountedMemory* GetRawData( 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int id, 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ScaleFactor scale_factor) const OVERRIDE { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return delegate_->GetRawData(id, scale_factor); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::ThemeProvider* delegate_; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DesktopThemeProvider); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// BrowserDesktopWindowTreeHostWin, public: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BrowserDesktopWindowTreeHostWin::BrowserDesktopWindowTreeHostWin( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::internal::NativeWidgetDelegate* native_widget_delegate, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::DesktopNativeWidgetAura* desktop_native_widget_aura, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserView* browser_view, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserFrame* browser_frame) 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : DesktopWindowTreeHostWin(native_widget_delegate, 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) desktop_native_widget_aura), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_view_(browser_view), 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) browser_frame_(browser_frame), 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) did_gdi_clear_(false) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ui::ThemeProvider> theme_provider( 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new DesktopThemeProvider(ThemeServiceFactory::GetForProfile( 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_view->browser()->profile()))); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_frame->SetThemeProvider(theme_provider.Pass()); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BrowserDesktopWindowTreeHostWin::~BrowserDesktopWindowTreeHostWin() { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)views::NativeMenuWin* BrowserDesktopWindowTreeHostWin::GetSystemMenu() { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!system_menu_.get()) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SystemMenuInsertionDelegateWin insertion_delegate; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system_menu_.reset( 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new views::NativeMenuWin(browser_frame_->GetSystemMenuModel(), 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetHWND())); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system_menu_->Rebuild(&insertion_delegate); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return system_menu_.get(); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// BrowserDesktopWindowTreeHostWin, BrowserDesktopWindowTreeHost implementation: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)views::DesktopWindowTreeHost* 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserDesktopWindowTreeHostWin::AsDesktopWindowTreeHost() { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BrowserDesktopWindowTreeHostWin::GetMinimizeButtonOffset() const { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return minimize_button_metrics_.GetMinimizeButtonOffsetX(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BrowserDesktopWindowTreeHostWin::UsesNativeSystemMenu() const { 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// BrowserDesktopWindowTreeHostWin, views::DesktopWindowTreeHostWin overrides: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BrowserDesktopWindowTreeHostWin::GetInitialShowState() const { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STARTUPINFO si = {0}; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) si.cb = sizeof(si); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) si.dwFlags = STARTF_USESHOWWINDOW; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetStartupInfo(&si); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return si.wShowWindow; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BrowserDesktopWindowTreeHostWin::GetClientAreaInsets( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Insets* insets) const { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the default client insets for an opaque frame or a glass popup/app 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetWidget()->ShouldUseNativeFrame() || 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !browser_view_->IsBrowserTypeNormal()) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In fullscreen mode, we have no frame. In restored mode, we draw our own 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // client edge over part of the default frame. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetWidget()->IsFullscreen()) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) border_thickness = 0; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (!IsMaximized()) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) border_thickness -= kClientEdgeThickness; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insets->Set(0, border_thickness, border_thickness, border_thickness); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserDesktopWindowTreeHostWin::HandleCreate() { 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DesktopWindowTreeHostWin::HandleCreate(); 1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser_window_property_manager_ = 1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserWindowPropertyManager::CreateBrowserWindowPropertyManager( 1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser_view_); 1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (browser_window_property_manager_) 1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser_window_property_manager_->UpdateWindowProperties(GetHWND()); 1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserDesktopWindowTreeHostWin::HandleFrameChanged() { 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Reinitialize the status bubble, since it needs to be initialized 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // differently depending on whether or not DWM composition is enabled 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch browser_view_->InitStatusBubble(); 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to update the glass region on or off before the base class adjusts 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the window region. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDWMFrame(); 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DesktopWindowTreeHostWin::HandleFrameChanged(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BrowserDesktopWindowTreeHostWin::PreHandleMSG(UINT message, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WPARAM w_param, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LPARAM l_param, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LRESULT* result) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (message) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_ACTIVATE: 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (LOWORD(w_param) != WA_INACTIVE) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) minimize_button_metrics_.OnHWNDActivated(); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_ENDSESSION: 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::SessionEnding(); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_INITMENUPOPUP: 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSystemMenu()->UpdateStates(); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return DesktopWindowTreeHostWin::PreHandleMSG( 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message, w_param, l_param, result); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserDesktopWindowTreeHostWin::PostHandleMSG(UINT message, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WPARAM w_param, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LPARAM l_param) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (message) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_CREATE: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) minimize_button_metrics_.Init(GetHWND()); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case WM_WINDOWPOSCHANGED: { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDWMFrame(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Windows lies to us about the position of the minimize button before a 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window is visible. We use this position to place the OTR avatar in RTL 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mode, so when the window is shown, we need to re-layout and schedule a 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // paint for the non-client frame view so that the icon top has the correct 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position when the window becomes visible. This fixes bugs where the icon 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appears to overlay the minimize button. 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we will call Layout every time SetWindowPos is called with 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SWP_SHOWWINDOW, however callers typically are careful about not 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specifying this flag unless necessary to avoid flicker. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This may be invoked during creation on XP and before the non_client_view 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has been created. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WINDOWPOS* window_pos = reinterpret_cast<WINDOWPOS*>(l_param); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_pos->flags & SWP_SHOWWINDOW && GetWidget()->non_client_view()) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->non_client_view()->Layout(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->non_client_view()->SchedulePaint(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case WM_ERASEBKGND: 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!did_gdi_clear_ && DesktopWindowTreeHostWin::ShouldUseNativeFrame()) { 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // This is necessary to avoid white flashing in the titlebar area around 226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // the minimize/maximize/close buttons. 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) HDC dc = GetDC(GetHWND()); 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) MARGINS margins = GetDWMFrameMargins(); 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RECT client_rect; 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GetClientRect(GetHWND(), &client_rect); 231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) HBRUSH brush = CreateSolidBrush(0); 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RECT rect = { 0, 0, client_rect.right, margins.cyTopHeight }; 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FillRect(dc, &rect, brush); 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DeleteObject(brush); 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ReleaseDC(GetHWND(), dc); 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) did_gdi_clear_ = true; 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BrowserDesktopWindowTreeHostWin::IsUsingCustomFrame() const { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't theme popup or app windows, so regardless of whether or not a 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // theme is active for normal browser windows, we don't want to use the custom 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame for popups/apps. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_view_->IsBrowserTypeNormal() && 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !DesktopWindowTreeHostWin::IsUsingCustomFrame()) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, we use the native frame when we're told we should by the theme 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provider (e.g. no custom theme is active). 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !GetWidget()->GetThemeProvider()->ShouldUseNativeFrame(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BrowserDesktopWindowTreeHostWin::ShouldUseNativeFrame() const { 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!views::DesktopWindowTreeHostWin::ShouldUseNativeFrame()) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This function can get called when the Browser window is closed i.e. in the 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // context of the BrowserView destructor. 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!browser_view_->browser()) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return chrome::ShouldUseNativeFrame(browser_view_, 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetWidget()->GetThemeProvider()); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserDesktopWindowTreeHostWin::FrameTypeChanged() { 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::DesktopWindowTreeHostWin::FrameTypeChanged(); 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) did_gdi_clear_ = false; 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// BrowserDesktopWindowTreeHostWin, private: 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserDesktopWindowTreeHostWin::UpdateDWMFrame() { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For "normal" windows on Aero, we always need to reset the glass area 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // correctly, even if we're not currently showing the native frame (e.g. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because a theme is showing), so we explicitly check for that case rather 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // than checking browser_frame_->ShouldUseNativeFrame() here. Using that here 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would mean we wouldn't reset the glass area to zero when moving from the 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // native frame to an opaque frame, leading to graphical glitches behind the 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // opaque frame. Instead, we use that function below to tell us whether the 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame is currently native or opaque. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetWidget()->client_view() || !browser_view_->IsBrowserTypeNormal() || 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !DesktopWindowTreeHostWin::ShouldUseNativeFrame()) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) MARGINS margins = GetDWMFrameMargins(); 290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DwmExtendFrameIntoClientArea(GetHWND(), &margins); 292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MARGINS BrowserDesktopWindowTreeHostWin::GetDWMFrameMargins() const { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MARGINS margins = { 0 }; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the opaque frame is visible, we use the default (zero) margins. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, we need to figure out how to extend the glass in. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetWidget()->ShouldUseNativeFrame()) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In fullscreen mode, we don't extend glass into the client area at all, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because the GDI-drawn text in the web content composited over it will 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // become semi-transparent over any glass area. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsMaximized() && !GetWidget()->IsFullscreen()) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cxLeftWidth = kClientEdgeThickness + 1; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cxRightWidth = kClientEdgeThickness + 1; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cyBottomHeight = kClientEdgeThickness + 1; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cyTopHeight = kClientEdgeThickness + 1; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In maximized mode, we only have a titlebar strip of glass, no side/bottom 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // borders. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_view_->IsFullscreen()) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect tabstrip_bounds( 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_frame_->GetBoundsForTabStrip(browser_view_->tabstrip())); 31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) tabstrip_bounds = gfx::win::DIPToScreenRect(tabstrip_bounds); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) margins.cyTopHeight = tabstrip_bounds.bottom() + kDWMFrameTopOffset; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return margins; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// BrowserDesktopWindowTreeHost, public: 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BrowserDesktopWindowTreeHost* 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserDesktopWindowTreeHost::CreateBrowserDesktopWindowTreeHost( 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::internal::NativeWidgetDelegate* native_widget_delegate, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::DesktopNativeWidgetAura* desktop_native_widget_aura, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserView* browser_view, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserFrame* browser_frame) { 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new BrowserDesktopWindowTreeHostWin(native_widget_delegate, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desktop_native_widget_aura, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_view, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_frame); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 336