Home | History | Annotate | Download | only in win
      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       GetMonitorInfo(MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST),
     80                      &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