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 "ui/views/win/fullscreen_handler.h" 6 7#include "base/logging.h" 8#include "ui/gfx/rect.h" 9#include "ui/views/win/scoped_fullscreen_visibility.h" 10 11namespace views { 12 13//////////////////////////////////////////////////////////////////////////////// 14// FullscreenHandler, public: 15 16FullscreenHandler::FullscreenHandler() 17 : hwnd_(NULL), 18 fullscreen_(false), 19 metro_snap_(false) { 20} 21 22FullscreenHandler::~FullscreenHandler() { 23} 24 25void FullscreenHandler::SetFullscreen(bool fullscreen) { 26 if (fullscreen_ == fullscreen) 27 return; 28 29 SetFullscreenImpl(fullscreen, false); 30} 31 32void FullscreenHandler::SetMetroSnap(bool metro_snap) { 33 if (metro_snap_ == metro_snap) 34 return; 35 36 SetFullscreenImpl(metro_snap, true); 37 metro_snap_ = metro_snap; 38} 39 40gfx::Rect FullscreenHandler::GetRestoreBounds() const { 41 return gfx::Rect(saved_window_info_.window_rect); 42} 43 44//////////////////////////////////////////////////////////////////////////////// 45// FullscreenHandler, private: 46 47void FullscreenHandler::SetFullscreenImpl(bool fullscreen, bool for_metro) { 48 ScopedFullscreenVisibility visibility(hwnd_); 49 50 // Save current window state if not already fullscreen. 51 if (!fullscreen_) { 52 // Save current window information. We force the window into restored mode 53 // before going fullscreen because Windows doesn't seem to hide the 54 // taskbar if the window is in the maximized state. 55 saved_window_info_.maximized = !!::IsZoomed(hwnd_); 56 if (saved_window_info_.maximized) 57 ::SendMessage(hwnd_, WM_SYSCOMMAND, SC_RESTORE, 0); 58 saved_window_info_.style = GetWindowLong(hwnd_, GWL_STYLE); 59 saved_window_info_.ex_style = GetWindowLong(hwnd_, GWL_EXSTYLE); 60 GetWindowRect(hwnd_, &saved_window_info_.window_rect); 61 } 62 63 fullscreen_ = fullscreen; 64 65 if (fullscreen_) { 66 // Set new window style and size. 67 SetWindowLong(hwnd_, GWL_STYLE, 68 saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME)); 69 SetWindowLong(hwnd_, GWL_EXSTYLE, 70 saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | 71 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); 72 73 // On expand, if we're given a window_rect, grow to it, otherwise do 74 // not resize. 75 if (!for_metro) { 76 MONITORINFO monitor_info; 77 monitor_info.cbSize = sizeof(monitor_info); 78 GetMonitorInfo(MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST), 79 &monitor_info); 80 gfx::Rect window_rect(monitor_info.rcMonitor); 81 SetWindowPos(hwnd_, NULL, window_rect.x(), window_rect.y(), 82 window_rect.width(), window_rect.height(), 83 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); 84 } 85 } else { 86 // Reset original window style and size. The multiple window size/moves 87 // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be 88 // repainted. Better-looking methods welcome. 89 SetWindowLong(hwnd_, GWL_STYLE, saved_window_info_.style); 90 SetWindowLong(hwnd_, GWL_EXSTYLE, saved_window_info_.ex_style); 91 92 if (!for_metro) { 93 // On restore, resize to the previous saved rect size. 94 gfx::Rect new_rect(saved_window_info_.window_rect); 95 SetWindowPos(hwnd_, NULL, new_rect.x(), new_rect.y(), 96 new_rect.width(), new_rect.height(), 97 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); 98 } 99 if (saved_window_info_.maximized) 100 ::SendMessage(hwnd_, WM_SYSCOMMAND, SC_MAXIMIZE, 0); 101 } 102} 103 104} // namespace views 105