diff options
author | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-14 02:44:38 +0000 |
---|---|---|
committer | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-14 02:44:38 +0000 |
commit | 77cbe50efd143af46e0c2138f931f186d9e2b529 (patch) | |
tree | bcff4635945d6f149e3422feaca0503c1072ca2c | |
parent | 5d0f00fdedc5c8181c3f1fd5db67a0f81df8462c (diff) | |
download | chromium_src-77cbe50efd143af46e0c2138f931f186d9e2b529.zip chromium_src-77cbe50efd143af46e0c2138f931f186d9e2b529.tar.gz chromium_src-77cbe50efd143af46e0c2138f931f186d9e2b529.tar.bz2 |
First pass at making Chrome support metro snap mode. It creates a fullscreen-alike mode that Chrome may enter when in metro snap mode.
This mode removes the chrome parts of Chrome as well as disabling the F11 key, while clamping Chrome to the size of the snap view portion of the screen.
Identical to http://crrev.com/141723 except for minor fixes in browser_view.cc to compile on Aura.
BUG=130623
TEST=NONE
Review URL: https://chromiumcodereview.appspot.com/10536144
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142074 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/chrome_command_ids.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/browser.cc | 38 | ||||
-rw-r--r-- | chrome/browser/ui/browser.h | 22 | ||||
-rw-r--r-- | chrome/browser/ui/browser_win.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/browser_window.h | 8 | ||||
-rw-r--r-- | chrome/browser/ui/fullscreen_controller.cc | 12 | ||||
-rw-r--r-- | chrome/browser/ui/fullscreen_controller.h | 10 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_browser_window.cc | 11 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_browser_window.h | 4 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.cc | 44 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.h | 10 | ||||
-rw-r--r-- | chrome/test/base/test_browser_window.cc | 6 | ||||
-rw-r--r-- | chrome/test/base/test_browser_window.h | 4 | ||||
-rw-r--r-- | ui/views/widget/native_widget_win.cc | 72 | ||||
-rw-r--r-- | ui/views/widget/native_widget_win.h | 22 |
15 files changed, 240 insertions, 30 deletions
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index c365bf1..4104fc3 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h @@ -63,6 +63,8 @@ #define IDC_TABPOSE 34036 #define IDC_DEBUG_FRAME_TOGGLE 34038 #define IDC_PRESENTATION_MODE 34039 +#define IDC_METRO_SNAP_ENABLE 34040 +#define IDC_METRO_SNAP_DISABLE 34041 // Page-related commands #define IDC_BOOKMARK_PAGE 35000 diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 012d2f5..b92d409 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -189,6 +189,7 @@ #include "webkit/plugins/webplugininfo.h" #if defined(OS_WIN) +#include "base/win/metro.h" #include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/ssl/ssl_error_info.h" @@ -1276,7 +1277,16 @@ browser::NavigateParams Browser::GetSingletonTabNavigateParams( void Browser::WindowFullscreenStateChanged() { fullscreen_controller_->WindowFullscreenStateChanged(); - UpdateCommandsForFullscreenMode(window_->IsFullscreen()); + FullScreenMode fullscreen_mode = FULLSCREEN_DISABLED; + if (window_->IsFullscreen()) { +#if defined(OS_WIN) + fullscreen_mode = window_->IsInMetroSnapMode() ? FULLSCREEN_METRO_SNAP : + FULLSCREEN_NORMAL; +#else + fullscreen_mode = FULLSCREEN_NORMAL; +#endif + } + UpdateCommandsForFullscreenMode(fullscreen_mode); UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN); } @@ -2489,6 +2499,10 @@ void Browser::ExecuteCommandWithDisposition( case IDC_COPY_URL: WriteCurrentURLToClipboard(); break; case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break; case IDC_FULLSCREEN: ToggleFullscreenMode(); break; +#if defined(OS_WIN) + case IDC_METRO_SNAP_ENABLE: SetMetroSnapMode(true); break; + case IDC_METRO_SNAP_DISABLE: SetMetroSnapMode(false); break; +#endif #if defined(OS_MACOSX) case IDC_PRESENTATION_MODE: TogglePresentationMode(); break; #endif @@ -4170,6 +4184,11 @@ void Browser::InitCommandState() { command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window); command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window); command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window); +#if defined(OS_WIN) + const bool metro_mode = (base::win::GetMetroModule() != NULL); + command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_ENABLE, metro_mode); + command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_DISABLE, metro_mode); +#endif #if defined(OS_MACOSX) command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window); command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE, @@ -4201,7 +4220,7 @@ void Browser::InitCommandState() { command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true); // Initialize other commands whose state changes based on fullscreen mode. - UpdateCommandsForFullscreenMode(false); + UpdateCommandsForFullscreenMode(FULLSCREEN_DISABLED); UpdateCommandsForContentRestrictionState(); @@ -4341,16 +4360,18 @@ void Browser::MarkHomePageAsChanged(PrefService* pref_service) { pref_service->SetBoolean(prefs::kHomePageChanged, true); } -void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) { - const bool show_main_ui = IsShowingMainUI(is_fullscreen); - bool main_not_fullscreen = show_main_ui && !is_fullscreen; +void Browser::UpdateCommandsForFullscreenMode(FullScreenMode fullscreen_mode) { + const bool show_main_ui = + IsShowingMainUI(fullscreen_mode != FULLSCREEN_DISABLED); + bool main_not_fullscreen = show_main_ui && + (fullscreen_mode == FULLSCREEN_DISABLED); // Navigation commands command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui); // Window management commands command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB, - type_ != TYPE_TABBED && !is_fullscreen); + type_ != TYPE_TABBED && (fullscreen_mode == FULLSCREEN_DISABLED)); // Focus various bits of UI command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui); @@ -4387,6 +4408,11 @@ void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) { command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui); #endif + // Disable explicit fullscreen toggling when in metro snap mode. + command_updater_.UpdateCommandEnabled( + IDC_FULLSCREEN, + fullscreen_mode != FULLSCREEN_METRO_SNAP); + UpdateCommandsForBookmarkBar(); UpdateCommandsForMultipleProfiles(); } diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 4045f63..4740b46 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -548,6 +548,10 @@ class Browser : public TabStripModelDelegate, // See the description of // FullscreenController::ToggleFullscreenModeWithExtension. void ToggleFullscreenModeWithExtension(const GURL& extension_url); +#if defined(OS_WIN) + // See the description of FullscreenController::ToggleMetroSnapMode. + void SetMetroSnapMode(bool enable); +#endif #if defined(OS_MACOSX) void TogglePresentationMode(); #endif @@ -901,6 +905,18 @@ class Browser : public TabStripModelDelegate, BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN, }; + enum FullScreenMode { + // Not in fullscreen mode. + FULLSCREEN_DISABLED, + + // Fullscreen mode, occupying the whole screen. + FULLSCREEN_NORMAL, + + // Fullscreen mode for metro snap, occupying the full height and 20% of + // the screen width. + FULLSCREEN_METRO_SNAP, + }; + // Overridden from content::WebContentsDelegate: virtual content::WebContents* OpenURLFromTab( content::WebContents* source, @@ -1110,9 +1126,9 @@ class Browser : public TabStripModelDelegate, // Set the preference that indicates that the home page has been changed. void MarkHomePageAsChanged(PrefService* pref_service); - // Update commands whose state depends on whether the window is in fullscreen - // mode. - void UpdateCommandsForFullscreenMode(bool is_fullscreen); + // Update commands whose state depends on the type of fullscreen mode the + // window is in. + void UpdateCommandsForFullscreenMode(FullScreenMode fullscreen_mode); // Update commands whose state depends on whether multiple profiles are // allowed. diff --git a/chrome/browser/ui/browser_win.cc b/chrome/browser/ui/browser_win.cc index eb1e2f6..796a7d5 100644 --- a/chrome/browser/ui/browser_win.cc +++ b/chrome/browser/ui/browser_win.cc @@ -9,6 +9,7 @@ #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/fullscreen_controller.h" #include "chrome/browser/ui/tab_contents/tab_contents.h" namespace { @@ -53,6 +54,10 @@ void Browser::NewIncognitoWindow() { NewEmptyWindow(profile_->GetOffTheRecordProfile()); } +void Browser::SetMetroSnapMode(bool enable) { + fullscreen_controller_->SetMetroSnapMode(enable); +} + void Browser::PinCurrentPageToStartScreen() { HMODULE metro_module = base::win::GetMetroModule(); if (metro_module) { diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 743a3cc..9672c65 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h @@ -150,6 +150,14 @@ class BrowserWindow : public BaseWindow { // Returns true if the fullscreen bubble is visible. virtual bool IsFullscreenBubbleVisible() const = 0; +#if defined(OS_WIN) + // Sets state for entering or exiting Win8 Metro snap mode. + virtual void SetMetroSnapMode(bool enable) = 0; + + // Returns whether the window is currently in Win8 Metro snap mode. + virtual bool IsInMetroSnapMode() const = 0; +#endif + // Returns the location bar. virtual LocationBar* GetLocationBar() const = 0; diff --git a/chrome/browser/ui/fullscreen_controller.cc b/chrome/browser/ui/fullscreen_controller.cc index 72c3ec2..b875328 100644 --- a/chrome/browser/ui/fullscreen_controller.cc +++ b/chrome/browser/ui/fullscreen_controller.cc @@ -58,6 +58,12 @@ bool FullscreenController::IsFullscreenForTabOrPending( return true; } +#if defined(OS_WIN) +bool FullscreenController::IsInMetroSnapMode() { + return window_->IsInMetroSnapMode(); +} +#endif + bool FullscreenController::IsMouseLockRequested() const { return mouse_lock_state_ == MOUSELOCK_REQUESTED; } @@ -170,6 +176,12 @@ void FullscreenController::ToggleFullscreenModeForTab(WebContents* web_contents, } } +#if defined(OS_WIN) +void FullscreenController::SetMetroSnapMode(bool enable) { + window_->SetMetroSnapMode(enable); +} +#endif + #if defined(OS_MACOSX) void FullscreenController::TogglePresentationMode() { TogglePresentationModeInternal(false); diff --git a/chrome/browser/ui/fullscreen_controller.h b/chrome/browser/ui/fullscreen_controller.h index b47ec5e..281622f 100644 --- a/chrome/browser/ui/fullscreen_controller.h +++ b/chrome/browser/ui/fullscreen_controller.h @@ -51,6 +51,11 @@ class FullscreenController : public base::RefCounted<FullscreenController> { bool IsFullscreenForTabOrPending( const content::WebContents* web_contents) const; +#if defined(OS_WIN) + // Returns whether we are currently in a Metro snap view. + bool IsInMetroSnapMode(); +#endif + bool IsMouseLockRequested() const; bool IsMouseLocked() const; @@ -60,6 +65,11 @@ class FullscreenController : public base::RefCounted<FullscreenController> { bool last_unlocked_by_target); void ToggleFullscreenModeForTab(content::WebContents* web_contents, bool enter_fullscreen); +#if defined(OS_WIN) + // API that puts the window into a mode suitable for rendering when Chrome + // is rendered in a 20% screen-width Metro snap view on Windows 8. + void SetMetroSnapMode(bool enable); +#endif #if defined(OS_MACOSX) void TogglePresentationMode(); #endif diff --git a/chrome/browser/ui/panels/panel_browser_window.cc b/chrome/browser/ui/panels/panel_browser_window.cc index ff4ebae..d73a805 100644 --- a/chrome/browser/ui/panels/panel_browser_window.cc +++ b/chrome/browser/ui/panels/panel_browser_window.cc @@ -183,6 +183,17 @@ void PanelBrowserWindow::ExitFullscreen() { NOTIMPLEMENTED(); } +#if defined(OS_WIN) +void PanelBrowserWindow::SetMetroSnapMode(bool enable) { + NOTIMPLEMENTED(); +} + +bool PanelBrowserWindow::IsInMetroSnapMode() const { + NOTIMPLEMENTED(); + return false; +} +#endif + void PanelBrowserWindow::UpdateFullscreenExitBubbleContent( const GURL& url, FullscreenExitBubbleType bubble_type) { diff --git a/chrome/browser/ui/panels/panel_browser_window.h b/chrome/browser/ui/panels/panel_browser_window.h index 0db35d3..11c831a 100644 --- a/chrome/browser/ui/panels/panel_browser_window.h +++ b/chrome/browser/ui/panels/panel_browser_window.h @@ -68,6 +68,10 @@ class PanelBrowserWindow : public BrowserWindow, virtual void EnterFullscreen( const GURL& url, FullscreenExitBubbleType type) OVERRIDE; virtual void ExitFullscreen() OVERRIDE; +#if defined(OS_WIN) + virtual void SetMetroSnapMode(bool enable) OVERRIDE; + virtual bool IsInMetroSnapMode() const OVERRIDE; +#endif virtual void UpdateFullscreenExitBubbleContent( const GURL& url, FullscreenExitBubbleType bubble_type) OVERRIDE; diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 3401bd4..edb16a6 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -770,14 +770,14 @@ void BrowserView::EnterFullscreen( if (IsFullscreen()) return; // Nothing to do. - ProcessFullscreen(true, url, bubble_type); + ProcessFullscreen(true, FOR_DESKTOP, url, bubble_type); } void BrowserView::ExitFullscreen() { if (!IsFullscreen()) return; // Nothing to do. - ProcessFullscreen(false, GURL(), FEB_TYPE_NONE); + ProcessFullscreen(false, FOR_DESKTOP, GURL(), FEB_TYPE_NONE); } void BrowserView::UpdateFullscreenExitBubbleContent( @@ -805,17 +805,33 @@ void BrowserView::FullScreenStateChanged() { if (IsFullscreen()) { if (fullscreen_request_.pending) { fullscreen_request_.pending = false; - ProcessFullscreen(true, fullscreen_request_.url, + ProcessFullscreen(true, FOR_DESKTOP, + fullscreen_request_.url, fullscreen_request_.bubble_type); } else { - ProcessFullscreen(true, GURL(), + ProcessFullscreen(true, FOR_DESKTOP, GURL(), FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION); } } else { - ProcessFullscreen(false, GURL(), FEB_TYPE_NONE); + ProcessFullscreen(false, FOR_DESKTOP, GURL(), FEB_TYPE_NONE); } } +#if defined(OS_WIN) +void BrowserView::SetMetroSnapMode(bool enable) { + ProcessFullscreen(enable, FOR_METRO, GURL(), FEB_TYPE_NONE); +} + +bool BrowserView::IsInMetroSnapMode() const { +#if defined(USE_AURA) + return false; +#else + return static_cast<views::NativeWidgetWin*>( + frame_->native_widget())->IsInMetroSnapMode(); +#endif +} +#endif // defined(OS_WIN) + void BrowserView::RestoreFocus() { WebContents* selected_web_contents = GetActiveWebContents(); if (selected_web_contents) @@ -2086,6 +2102,7 @@ bool BrowserView::UpdateChildViewAndLayout(views::View* new_view, } void BrowserView::ProcessFullscreen(bool fullscreen, + FullscreenType type, const GURL& url, FullscreenExitBubbleType bubble_type) { // Reduce jankiness during the following position changes by: @@ -2098,7 +2115,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen, OmniboxViewWin* omnibox_view = static_cast<OmniboxViewWin*>(location_bar->GetLocationEntry()); #endif - if (!fullscreen) { + + if (!fullscreen && type != FOR_METRO) { // Hide the fullscreen bubble as soon as possible, since the mode toggle can // take enough time for the user to notice. fullscreen_bubble_.reset(); @@ -2125,15 +2143,23 @@ void BrowserView::ProcessFullscreen(bool fullscreen, PushForceHidden(); #endif - // Toggle fullscreen mode. - frame_->SetFullscreen(fullscreen); + if (type == FOR_METRO) { +#if defined(OS_WIN) && !defined(USE_AURA) + // Enter metro snap mode. + static_cast<views::NativeWidgetWin*>( + frame_->native_widget())->SetMetroSnapFullscreen(fullscreen); +#endif + } else { + // Toggle fullscreen mode. + frame_->SetFullscreen(fullscreen); + } browser_->WindowFullscreenStateChanged(); if (fullscreen) { bool is_kiosk = CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode); - if (!is_kiosk) { + if (!is_kiosk && type != FOR_METRO) { fullscreen_bubble_.reset(new FullscreenExitBubbleViews( GetWidget(), browser_.get(), url, bubble_type)); } diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 8c00ef0..d25c96b 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -254,6 +254,10 @@ class BrowserView : public BrowserWindow, const GURL& url, FullscreenExitBubbleType bubble_type) OVERRIDE; virtual bool IsFullscreen() const OVERRIDE; +#if defined(OS_WIN) + virtual void SetMetroSnapMode(bool enable) OVERRIDE; + virtual bool IsInMetroSnapMode() const OVERRIDE; +#endif virtual LocationBar* GetLocationBar() const OVERRIDE; virtual void SetFocusToLocationBar(bool select_all) OVERRIDE; virtual void UpdateReloadStopState(bool is_loading, bool force) OVERRIDE; @@ -443,6 +447,11 @@ class BrowserView : public BrowserWindow, FRIEND_TEST_ALL_PREFIXES(BrowserViewsAccessibilityTest, TestAboutChromeViewAccObj); + enum FullscreenType { + FOR_DESKTOP, + FOR_METRO + }; + // We store this on linux because we must call ProcessFullscreen() // asynchronously from FullScreenStateChanged() instead of directly from // EnterFullscreen(). @@ -506,6 +515,7 @@ class BrowserView : public BrowserWindow, // |bubble_type| determines what should be shown in the fullscreen exit // bubble. void ProcessFullscreen(bool fullscreen, + FullscreenType fullscreen_type, const GURL& url, FullscreenExitBubbleType bubble_type); diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc index 6440afe..a09b8e8 100644 --- a/chrome/test/base/test_browser_window.cc +++ b/chrome/test/base/test_browser_window.cc @@ -52,6 +52,12 @@ bool TestBrowserWindow::IsFullscreen() const { return false; } +#if defined(OS_WIN) +bool TestBrowserWindow::IsInMetroSnapMode() const { + return false; +} +#endif + bool TestBrowserWindow::IsFullscreenBubbleVisible() const { return false; } diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 42f167c..b8f901e 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h @@ -62,6 +62,10 @@ class TestBrowserWindow : public BrowserWindow { const GURL& url, FullscreenExitBubbleType bubble_type) OVERRIDE {} virtual bool IsFullscreen() const OVERRIDE; +#if defined(OS_WIN) + virtual void SetMetroSnapMode(bool enable) OVERRIDE {} + virtual bool IsInMetroSnapMode() const; +#endif virtual bool IsFullscreenBubbleVisible() const OVERRIDE; virtual LocationBar* GetLocationBar() const OVERRIDE; virtual void SetFocusToLocationBar(bool select_all) OVERRIDE {} diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc index 1ed9057..b6a5d1a 100644 --- a/ui/views/widget/native_widget_win.cc +++ b/ui/views/widget/native_widget_win.cc @@ -422,6 +422,7 @@ NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate) accessibility_view_events_(kMaxAccessibilityViewEvents), previous_cursor_(NULL), fullscreen_(false), + metro_snap_(false), force_hidden_count_(0), lock_updates_count_(0), ignore_window_pos_changes_(false), @@ -990,7 +991,40 @@ void NativeWidgetWin::Restore() { void NativeWidgetWin::SetFullscreen(bool fullscreen) { if (fullscreen_ == fullscreen) - return; // Nothing to do. + return; + + gfx::Rect window_rect; + if (fullscreen) { + MONITORINFO monitor_info; + monitor_info.cbSize = sizeof(monitor_info); + GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), + &monitor_info); + window_rect = monitor_info.rcMonitor; + } + + SetFullscreenInternal(fullscreen, window_rect); +} + +void NativeWidgetWin::SetMetroSnapFullscreen(bool metro_snap) { + if (metro_snap_ == metro_snap) + return; + + metro_snap_ = metro_snap; + + gfx::Rect window_rect; + if (!metro_snap) { + MONITORINFO monitor_info; + monitor_info.cbSize = sizeof(monitor_info); + GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), + &monitor_info); + window_rect = monitor_info.rcMonitor; + } + + SetFullscreenInternal(metro_snap, window_rect); +} + +void NativeWidgetWin::SetFullscreenInternal(bool fullscreen, + const gfx::Rect& window_rect) { // Reduce jankiness during the following position changes by hiding the window // until it's in the final position. @@ -1013,26 +1047,35 @@ void NativeWidgetWin::SetFullscreen(bool fullscreen) { if (fullscreen_) { // Set new window style and size. - MONITORINFO monitor_info; - monitor_info.cbSize = sizeof(monitor_info); - GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), - &monitor_info); - gfx::Rect monitor_rect(monitor_info.rcMonitor); SetWindowLong(GWL_STYLE, saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME)); SetWindowLong(GWL_EXSTYLE, saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); - SetWindowPos(NULL, monitor_rect.x(), monitor_rect.y(), - monitor_rect.width(), monitor_rect.height(), - SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); + + // On expand, if we're given a window_rect, grow to it, otherwise do + // not resize. + if (window_rect.width() > 0) { + SetWindowPos(NULL, window_rect.x(), window_rect.y(), + window_rect.width(), window_rect.height(), + SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); + } } else { // Reset original window style and size. The multiple window size/moves // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be // repainted. Better-looking methods welcome. - gfx::Rect new_rect(saved_window_info_.window_rect); SetWindowLong(GWL_STYLE, saved_window_info_.style); SetWindowLong(GWL_EXSTYLE, saved_window_info_.ex_style); + + // On restore, if we're given a window_rect resize to that, otherwise + // resize to the previous saved rect size. + gfx::Rect new_rect; + if (window_rect.width() > 0) { + new_rect = window_rect; + } else { + new_rect = saved_window_info_.window_rect; + } + SetWindowPos(NULL, new_rect.x(), new_rect.y(), new_rect.width(), new_rect.height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); @@ -1048,6 +1091,10 @@ bool NativeWidgetWin::IsFullscreen() const { return fullscreen_; } +bool NativeWidgetWin::IsInMetroSnapMode() const { + return metro_snap_; +} + void NativeWidgetWin::SetOpacity(unsigned char opacity) { layered_alpha_ = static_cast<BYTE>(opacity); GetWidget()->GetRootView()->SchedulePaint(); @@ -2111,9 +2158,10 @@ void NativeWidgetWin::OnWindowPosChanging(WINDOWPOS* window_pos) { gfx::Rect monitor_rect, work_area; if (GetWindowRect(&window_rect) && GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { + bool work_area_changed = (monitor_rect == last_monitor_rect_) && + (work_area != last_work_area_); if (monitor && (monitor == last_monitor_) && - (IsFullscreen() || ((monitor_rect == last_monitor_rect_) && - (work_area != last_work_area_)))) { + ((IsFullscreen() && !metro_snap_) || work_area_changed)) { // A rect for the monitor we're on changed. Normally Windows notifies // us about this (and thus we're reaching here due to the SetWindowPos() // call in OnSettingChange() above), but with some software (e.g. diff --git a/ui/views/widget/native_widget_win.h b/ui/views/widget/native_widget_win.h index d584390..868c24b 100644 --- a/ui/views/widget/native_widget_win.h +++ b/ui/views/widget/native_widget_win.h @@ -115,6 +115,13 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl, // the top of the stack. See PushForceHidden. void PopForceHidden(); + // Places the window in a pseudo-fullscreen mode where it looks and acts as + // like a fullscreen window except that it remains within the boundaries + // of the metro snap divider. + void SetMetroSnapFullscreen(bool metro_snap); + + bool IsInMetroSnapMode() const; + BOOL IsWindow() const { return ::IsWindow(GetNativeView()); } @@ -531,6 +538,18 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl, // Overridden from internal::InputMethodDelegate virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE; + // Common implementation of fullscreen-related code. This method handles + // changing from windowed mode to a display mode (dubbed fullscreen mode) + // where the window occupies a fixed portion (possibly 100%) of the screen. + // |fullscreen| specifies whether we are entering or leaving fullscreen mode. + // |window_rect| contains sizing information that describes the portion of the + // screen to be occupied. |window_rect| may be a rect of width + // 0, which indicates that sizing should be skipped when + // entering fullscreen mode and previously-stored size should + // be used when exiting fullscreen mode. + void SetFullscreenInternal(bool fullscreen, + const gfx::Rect& window_rect); + // A delegate implementation that handles events received here. // See class documentation for Widget in widget.h for a note about ownership. internal::NativeWidgetDelegate* delegate_; @@ -612,6 +631,9 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl, // True if we're in fullscreen mode. bool fullscreen_; + // True if we're in metro snap mode. + bool metro_snap_; + // If this is greater than zero, we should prevent attempts to make the window // visible when we handle WM_WINDOWPOSCHANGING. Some calls like // ShowWindow(SW_RESTORE) make the window visible in addition to restoring it, |