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