summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-09 06:10:57 +0000
committerstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-09 06:10:57 +0000
commit68eeede20e63fbb9a8756ed73e482b87dde57c72 (patch)
tree26d1bd889cbfd7b32131d585a97dcb9b447b8733
parentc2ff9b4ec2549c5b3b36c11fe2fca7b5495adf9a (diff)
downloadchromium_src-68eeede20e63fbb9a8756ed73e482b87dde57c72.zip
chromium_src-68eeede20e63fbb9a8756ed73e482b87dde57c72.tar.gz
chromium_src-68eeede20e63fbb9a8756ed73e482b87dde57c72.tar.bz2
Save and restore State for ShellWindows, including panels
This replaces ShellWindow::CreateParams::State with ui::WindowShowState for simplicty and consistency with Browser session restore. BUG=233556 TBR=flackr@chromium.org, skuhne@chromium.org, sky@chromium.org Original CL: https://codereview.chromium.org/14031021/ + disabled flakey browser tests on linux Review URL: https://chromiumcodereview.appspot.com/14663010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@199145 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/wm/base_layout_manager.cc6
-rw-r--r--ash/wm/window_properties.cc2
-rw-r--r--ash/wm/window_properties.h4
-rw-r--r--ash/wm/workspace/workspace_layout_manager.cc6
-rw-r--r--ash/wm/workspace/workspace_manager.cc2
-rw-r--r--chrome/browser/extensions/api/app_window/app_window_api.cc32
-rw-r--r--chrome/browser/extensions/platform_app_browsertest.cc12
-rw-r--r--chrome/browser/extensions/shell_window_geometry_cache.cc21
-rw-r--r--chrome/browser/extensions/shell_window_geometry_cache.h13
-rw-r--r--chrome/browser/extensions/shell_window_geometry_cache_unittest.cc101
-rw-r--r--chrome/browser/sessions/session_service.cc9
-rw-r--r--chrome/browser/ui/base_window.h4
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.h1
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.mm8
-rw-r--r--chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.h2
-rw-r--r--chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm10
-rw-r--r--chrome/browser/ui/extensions/native_app_window.h3
-rw-r--r--chrome/browser/ui/extensions/shell_window.cc42
-rw-r--r--chrome/browser/ui/extensions/shell_window.h10
-rw-r--r--chrome/browser/ui/gtk/browser_window_gtk.cc8
-rw-r--r--chrome/browser/ui/gtk/browser_window_gtk.h15
-rw-r--r--chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc10
-rw-r--r--chrome/browser/ui/gtk/extensions/native_app_window_gtk.h2
-rw-r--r--chrome/browser/ui/panels/panel.cc4
-rw-r--r--chrome/browser/ui/panels/panel.h1
-rw-r--r--chrome/browser/ui/views/extensions/native_app_window_views.cc54
-rw-r--r--chrome/browser/ui/views/extensions/native_app_window_views.h2
-rw-r--r--chrome/browser/ui/views/frame/browser_view.cc8
-rw-r--r--chrome/browser/ui/views/frame/browser_view.h1
-rw-r--r--chrome/renderer/resources/extensions/app_window_custom_bindings.js6
-rw-r--r--chrome/test/base/test_browser_window.cc4
-rw-r--r--chrome/test/base/test_browser_window.h1
-rw-r--r--chrome/test/data/extensions/platform_apps/restore_state/empty.html1
-rw-r--r--chrome/test/data/extensions/platform_apps/restore_state/manifest.json9
-rw-r--r--chrome/test/data/extensions/platform_apps/restore_state/test.js46
-rw-r--r--ui/aura/client/aura_constants.cc2
-rw-r--r--ui/aura/client/aura_constants.h5
-rw-r--r--ui/base/ui_base_types.h3
38 files changed, 347 insertions, 123 deletions
diff --git a/ash/wm/base_layout_manager.cc b/ash/wm/base_layout_manager.cc
index d5bb54f..89e99d9 100644
--- a/ash/wm/base_layout_manager.cc
+++ b/ash/wm/base_layout_manager.cc
@@ -89,8 +89,8 @@ void BaseLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
if (visible && wm::IsWindowMinimized(child)) {
// Attempting to show a minimized window. Unminimize it.
child->SetProperty(aura::client::kShowStateKey,
- child->GetProperty(internal::kRestoreShowStateKey));
- child->ClearProperty(internal::kRestoreShowStateKey);
+ child->GetProperty(aura::client::kRestoreShowStateKey));
+ child->ClearProperty(aura::client::kRestoreShowStateKey);
}
}
@@ -171,7 +171,7 @@ void BaseLayoutManager::ShowStateChanged(aura::Window* window,
ui::WindowShowState last_show_state) {
if (wm::IsWindowMinimized(window)) {
// Save the previous show state so that we can correctly restore it.
- window->SetProperty(internal::kRestoreShowStateKey, last_show_state);
+ window->SetProperty(aura::client::kRestoreShowStateKey, last_show_state);
views::corewm::SetWindowVisibilityAnimationType(
window, WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
diff --git a/ash/wm/window_properties.cc b/ash/wm/window_properties.cc
index 21f205a..64d55a7 100644
--- a/ash/wm/window_properties.cc
+++ b/ash/wm/window_properties.cc
@@ -26,8 +26,6 @@ DEFINE_WINDOW_PROPERTY_KEY(bool, kFullscreenUsesMinimalChromeKey, false);
DEFINE_WINDOW_PROPERTY_KEY(bool, kIgnoreSoloWindowFramePainterPolicy, false);
DEFINE_WINDOW_PROPERTY_KEY(bool, kIgnoredByShelfKey, false);
DEFINE_WINDOW_PROPERTY_KEY(bool, kPanelAttachedKey, true);
-DEFINE_WINDOW_PROPERTY_KEY(
- ui::WindowShowState, kRestoreShowStateKey, ui::SHOW_STATE_DEFAULT);
DEFINE_WINDOW_PROPERTY_KEY(RootWindowController*,
kRootWindowControllerKey, NULL);
DEFINE_WINDOW_PROPERTY_KEY(bool, kSoloWindowHeaderKey, false);
diff --git a/ash/wm/window_properties.h b/ash/wm/window_properties.h
index 7847b62..ae30435 100644
--- a/ash/wm/window_properties.h
+++ b/ash/wm/window_properties.h
@@ -57,10 +57,6 @@ extern const aura::WindowProperty<bool>* const
// True if this window is an attached panel.
ASH_EXPORT extern const aura::WindowProperty<bool>* const kPanelAttachedKey;
-// Used to remember the show state before the window was minimized.
-extern const aura::WindowProperty<ui::WindowShowState>* const
- kRestoreShowStateKey;
-
extern const aura::WindowProperty<RootWindowController*>* const
kRootWindowControllerKey;
diff --git a/ash/wm/workspace/workspace_layout_manager.cc b/ash/wm/workspace/workspace_layout_manager.cc
index 65ed116..e4e6c84 100644
--- a/ash/wm/workspace/workspace_layout_manager.cc
+++ b/ash/wm/workspace/workspace_layout_manager.cc
@@ -126,8 +126,8 @@ void WorkspaceLayoutManager::OnChildWindowVisibilityChanged(Window* child,
if (visible && wm::IsWindowMinimized(child)) {
// Attempting to show a minimized window. Unminimize it.
child->SetProperty(aura::client::kShowStateKey,
- child->GetProperty(internal::kRestoreShowStateKey));
- child->ClearProperty(internal::kRestoreShowStateKey);
+ child->GetProperty(aura::client::kRestoreShowStateKey));
+ child->ClearProperty(aura::client::kRestoreShowStateKey);
}
workspace_manager()->OnWorkspaceChildWindowVisibilityChanged(workspace_,
child);
@@ -257,7 +257,7 @@ void WorkspaceLayoutManager::ShowStateChanged(
if (wm::IsWindowMinimized(window)) {
DCHECK(!cloned_layer);
// Save the previous show state so that we can correctly restore it.
- window->SetProperty(internal::kRestoreShowStateKey, last_show_state);
+ window->SetProperty(aura::client::kRestoreShowStateKey, last_show_state);
views::corewm::SetWindowVisibilityAnimationType(
window, WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
workspace_manager()->OnWorkspaceWindowShowStateChanged(
diff --git a/ash/wm/workspace/workspace_manager.cc b/ash/wm/workspace/workspace_manager.cc
index 69413fe..b4d4226 100644
--- a/ash/wm/workspace/workspace_manager.cc
+++ b/ash/wm/workspace/workspace_manager.cc
@@ -160,7 +160,7 @@ bool WorkspaceManager::IsMaximizedState(ui::WindowShowState state) {
// static
bool WorkspaceManager::WillRestoreMaximized(Window* window) {
return wm::IsWindowMinimized(window) &&
- IsMaximizedState(window->GetProperty(internal::kRestoreShowStateKey));
+ IsMaximizedState(window->GetProperty(aura::client::kRestoreShowStateKey));
}
WorkspaceWindowState WorkspaceManager::GetWindowState() const {
diff --git a/chrome/browser/extensions/api/app_window/app_window_api.cc b/chrome/browser/extensions/api/app_window/app_window_api.cc
index a421b95..2dccb33 100644
--- a/chrome/browser/extensions/api/app_window/app_window_api.cc
+++ b/chrome/browser/extensions/api/app_window/app_window_api.cc
@@ -22,6 +22,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "googleurl/src/gurl.h"
+#include "ui/base/ui_base_types.h"
#include "ui/gfx/rect.h"
#if defined(USE_ASH)
@@ -82,6 +83,20 @@ class DevToolsRestorer : public content::NotificationObserver {
content::NotificationRegistrar registrar_;
};
+void SetCreateResultFromShellWindow(ShellWindow* window,
+ base::DictionaryValue* result) {
+ result->SetBoolean("fullscreen", window->GetBaseWindow()->IsFullscreen());
+ result->SetBoolean("minimized", window->GetBaseWindow()->IsMinimized());
+ result->SetBoolean("maximized", window->GetBaseWindow()->IsMaximized());
+ DictionaryValue* boundsValue = new DictionaryValue();
+ gfx::Rect bounds = window->GetClientBounds();
+ boundsValue->SetInteger("left", bounds.x());
+ boundsValue->SetInteger("top", bounds.y());
+ boundsValue->SetInteger("width", bounds.width());
+ boundsValue->SetInteger("height", bounds.height());
+ result->Set("bounds", boundsValue);
+}
+
} // namespace
void AppWindowCreateFunction::SendDelayedResponse() {
@@ -140,6 +155,7 @@ bool AppWindowCreateFunction::RunImpl() {
window->GetBaseWindow()->Show();
base::DictionaryValue* result = new base::DictionaryValue;
result->Set("viewId", base::Value::CreateIntegerValue(view_id));
+ SetCreateResultFromShellWindow(window, result);
result->SetBoolean("existingWindow", true);
result->SetBoolean("injectTitlebar", false);
SetResult(result);
@@ -230,13 +246,13 @@ bool AppWindowCreateFunction::RunImpl() {
case extensions::api::app_window::STATE_NORMAL:
break;
case extensions::api::app_window::STATE_FULLSCREEN:
- create_params.state = ShellWindow::CreateParams::STATE_FULLSCREEN;
+ create_params.state = ui::SHOW_STATE_FULLSCREEN;
break;
case extensions::api::app_window::STATE_MAXIMIZED:
- create_params.state = ShellWindow::CreateParams::STATE_MAXIMIZED;
+ create_params.state = ui::SHOW_STATE_MAXIMIZED;
break;
case extensions::api::app_window::STATE_MINIMIZED:
- create_params.state = ShellWindow::CreateParams::STATE_MINIMIZED;
+ create_params.state = ui::SHOW_STATE_MINIMIZED;
break;
}
} else {
@@ -266,7 +282,7 @@ bool AppWindowCreateFunction::RunImpl() {
#endif
if (force_maximize)
- create_params.state = ShellWindow::CreateParams::STATE_MAXIMIZED;
+ create_params.state = ui::SHOW_STATE_MAXIMIZED;
ShellWindow* shell_window =
ShellWindow::Create(profile(), GetExtension(), url, create_params);
@@ -285,13 +301,7 @@ bool AppWindowCreateFunction::RunImpl() {
result->Set("injectTitlebar",
base::Value::CreateBooleanValue(inject_html_titlebar));
result->Set("id", base::Value::CreateStringValue(shell_window->window_key()));
- DictionaryValue* boundsValue = new DictionaryValue();
- gfx::Rect bounds = shell_window->GetClientBounds();
- boundsValue->SetInteger("left", bounds.x());
- boundsValue->SetInteger("top", bounds.y());
- boundsValue->SetInteger("width", bounds.width());
- boundsValue->SetInteger("height", bounds.height());
- result->Set("bounds", boundsValue);
+ SetCreateResultFromShellWindow(shell_window, result);
SetResult(result);
if (ShellWindowRegistry::Get(profile())->HadDevToolsAttached(created_view)) {
diff --git a/chrome/browser/extensions/platform_app_browsertest.cc b/chrome/browser/extensions/platform_app_browsertest.cc
index 642f948..3e9551a 100644
--- a/chrome/browser/extensions/platform_app_browsertest.cc
+++ b/chrome/browser/extensions/platform_app_browsertest.cc
@@ -632,6 +632,18 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
ASSERT_TRUE(RunPlatformAppTest("platform_apps/geometry"));
}
+// This appears to be unreliable on linux.
+// TODO(stevenjb): Investigate and enable
+#if defined(OS_LINUX) && !defined(USE_ASH)
+#define MAYBE_ShellWindowRestoreState DISABLED_ShellWindowRestoreState
+#else
+#define MAYBE_ShellWindowRestoreState ShellWindowRestoreState
+#endif
+IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
+ MAYBE_ShellWindowRestoreState) {
+ ASSERT_TRUE(RunPlatformAppTest("platform_apps/restore_state"));
+}
+
namespace {
class PlatformAppDevToolsBrowserTest : public PlatformAppBrowserTest {
diff --git a/chrome/browser/extensions/shell_window_geometry_cache.cc b/chrome/browser/extensions/shell_window_geometry_cache.cc
index f08f085..7d01f9c 100644
--- a/chrome/browser/extensions/shell_window_geometry_cache.cc
+++ b/chrome/browser/extensions/shell_window_geometry_cache.cc
@@ -40,18 +40,21 @@ ShellWindowGeometryCache::~ShellWindowGeometryCache() {
void ShellWindowGeometryCache::SaveGeometry(
const std::string& extension_id,
const std::string& window_id,
- const gfx::Rect& bounds) {
+ const gfx::Rect& bounds,
+ ui::WindowShowState window_state) {
ExtensionData& extension_data = cache_[extension_id];
// If we don't have any unsynced changes and this is a duplicate of what's
// already in the cache, just ignore it.
if (extension_data[window_id].bounds == bounds &&
+ extension_data[window_id].window_state == window_state &&
!ContainsKey(unsynced_extensions_, extension_id))
return;
base::Time now = base::Time::Now();
extension_data[window_id].bounds = bounds;
+ extension_data[window_id].window_state = window_state;
extension_data[window_id].last_change = now;
if (extension_data.size() > kMaxCachedWindows) {
@@ -99,6 +102,7 @@ void ShellWindowGeometryCache::SyncToStorage() {
value->SetInteger("y", bounds.y());
value->SetInteger("w", bounds.width());
value->SetInteger("h", bounds.height());
+ value->SetInteger("state", it->second.window_state);
value->SetString(
"ts", base::Int64ToString(it->second.last_change.ToInternalValue()));
dict->SetWithoutPathExpansion(it->first, value);
@@ -110,7 +114,8 @@ void ShellWindowGeometryCache::SyncToStorage() {
bool ShellWindowGeometryCache::GetGeometry(
const std::string& extension_id,
const std::string& window_id,
- gfx::Rect* bounds) const {
+ gfx::Rect* bounds,
+ ui::WindowShowState* window_state) const {
std::map<std::string, ExtensionData>::const_iterator
extension_data_it = cache_.find(extension_id);
@@ -125,7 +130,10 @@ bool ShellWindowGeometryCache::GetGeometry(
if (window_data == extension_data_it->second.end())
return false;
- *bounds = window_data->second.bounds;
+ if (bounds)
+ *bounds = window_data->second.bounds;
+ if (window_state)
+ *window_state = window_data->second.window_state;
return true;
}
@@ -171,8 +179,7 @@ void ShellWindowGeometryCache::OnExtensionLoaded(
// overwrite that information since it is probably the result of an
// application starting up very quickly.
const std::string& window_id = it.key();
- ExtensionData::iterator cached_window =
- extension_data.find(window_id);
+ ExtensionData::iterator cached_window = extension_data.find(window_id);
if (cached_window == extension_data.end()) {
const base::DictionaryValue* stored_window;
if (it.value().GetAsDictionary(&stored_window)) {
@@ -187,6 +194,10 @@ void ShellWindowGeometryCache::OnExtensionLoaded(
window_data.bounds.set_width(i);
if (stored_window->GetInteger("h", &i))
window_data.bounds.set_height(i);
+ if (stored_window->GetInteger("state", &i)) {
+ window_data.window_state =
+ static_cast<ui::WindowShowState>(i);
+ }
std::string ts_as_string;
if (stored_window->GetString("ts", &ts_as_string)) {
int64 ts;
diff --git a/chrome/browser/extensions/shell_window_geometry_cache.h b/chrome/browser/extensions/shell_window_geometry_cache.h
index 744077c..5648b0d 100644
--- a/chrome/browser/extensions/shell_window_geometry_cache.h
+++ b/chrome/browser/extensions/shell_window_geometry_cache.h
@@ -16,6 +16,7 @@
#include "base/values.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "ui/base/ui_base_types.h"
#include "ui/gfx/rect.h"
class Profile;
@@ -36,13 +37,19 @@ class ShellWindowGeometryCache
virtual ~ShellWindowGeometryCache();
+ // Save the geometry and state associated with |extension_id| and |window_id|.
void SaveGeometry(const std::string& extension_id,
const std::string& window_id,
- const gfx::Rect& bounds);
+ const gfx::Rect& bounds,
+ ui::WindowShowState state);
+ // Get any saved geometry and state associated with |extension_id| and
+ // |window_id|. If saved data exists, sets |bounds| and |state| if not NULL
+ // and returns true.
bool GetGeometry(const std::string& extension_id,
const std::string& window_id,
- gfx::Rect* bounds) const;
+ gfx::Rect* bounds,
+ ui::WindowShowState* state) const;
// Maximum number of windows we'll cache the geometry for per app.
static const size_t kMaxCachedWindows = 100;
@@ -58,7 +65,9 @@ class ShellWindowGeometryCache
private:
// Data stored for each window.
struct WindowData {
+ WindowData() : window_state(ui::SHOW_STATE_DEFAULT) {}
gfx::Rect bounds;
+ ui::WindowShowState window_state;
base::Time last_change;
};
diff --git a/chrome/browser/extensions/shell_window_geometry_cache_unittest.cc b/chrome/browser/extensions/shell_window_geometry_cache_unittest.cc
index e349da8..efab64f 100644
--- a/chrome/browser/extensions/shell_window_geometry_cache_unittest.cc
+++ b/chrome/browser/extensions/shell_window_geometry_cache_unittest.cc
@@ -36,9 +36,11 @@ class ShellWindowGeometryCacheTest : public testing::Test {
cache_->SetSyncDelayForTests(0);
}
- void AddGeometryAndLoadExtension(const std::string& extension_id,
- const std::string& window_id,
- const gfx::Rect& bounds);
+ void AddGeometryAndLoadExtension(
+ const std::string& extension_id,
+ const std::string& window_id,
+ const gfx::Rect& bounds,
+ ui::WindowShowState state);
// Spins the UI threads' message loops to make sure any task
// posted to sync the geometry to the value store gets a chance to run.
@@ -56,14 +58,17 @@ class ShellWindowGeometryCacheTest : public testing::Test {
};
void ShellWindowGeometryCacheTest::AddGeometryAndLoadExtension(
- const std::string& extension_id, const std::string& window_id,
- const gfx::Rect& bounds) {
+ const std::string& extension_id,
+ const std::string& window_id,
+ const gfx::Rect& bounds,
+ ui::WindowShowState state) {
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
base::DictionaryValue* value = new base::DictionaryValue;
value->SetInteger("x", bounds.x());
value->SetInteger("y", bounds.y());
value->SetInteger("w", bounds.width());
value->SetInteger("h", bounds.height());
+ value->SetInteger("state", state);
dict->SetWithoutPathExpansion(window_id, value);
prefs_->prefs()->SetGeometryCache(extension_id, dict.Pass());
LoadExtension(extension_id);
@@ -88,8 +93,7 @@ void ShellWindowGeometryCacheTest::UnloadExtension(
// Test getting geometry from an empty store.
TEST_F(ShellWindowGeometryCacheTest, GetGeometryEmptyStore) {
const std::string extension_id = prefs_->AddExtensionAndReturnId("ext1");
- gfx::Rect bounds;
- ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId, &bounds));
+ ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId, NULL, NULL));
}
// Test getting geometry for an unknown extension.
@@ -97,32 +101,37 @@ TEST_F(ShellWindowGeometryCacheTest, GetGeometryUnkownExtension) {
const std::string extension_id1 = prefs_->AddExtensionAndReturnId("ext1");
const std::string extension_id2 = prefs_->AddExtensionAndReturnId("ext2");
AddGeometryAndLoadExtension(extension_id1, kWindowId,
- gfx::Rect(4, 5, 31, 43));
- gfx::Rect bounds;
- ASSERT_FALSE(cache_->GetGeometry(extension_id2, kWindowId, &bounds));
+ gfx::Rect(4, 5, 31, 43),
+ ui::SHOW_STATE_DEFAULT);
+ ASSERT_FALSE(cache_->GetGeometry(extension_id2, kWindowId, NULL, NULL));
}
// Test getting geometry for an unknown window in a known extension.
TEST_F(ShellWindowGeometryCacheTest, GetGeometryUnkownWindow) {
const std::string extension_id = prefs_->AddExtensionAndReturnId("ext1");
AddGeometryAndLoadExtension(extension_id, kWindowId,
- gfx::Rect(4, 5, 31, 43));
- gfx::Rect bounds;
- ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId2, &bounds));
+ gfx::Rect(4, 5, 31, 43),
+ ui::SHOW_STATE_DEFAULT);
+ ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId2, NULL, NULL));
}
-// Test that loading geometry from the store works correctly.
-TEST_F(ShellWindowGeometryCacheTest, GetGeometryFromStore) {
+// Test that loading geometry and state from the store works correctly.
+TEST_F(ShellWindowGeometryCacheTest, GetGeometryAndStateFromStore) {
const std::string extension_id = prefs_->AddExtensionAndReturnId("ext1");
gfx::Rect bounds(4, 5, 31, 43);
- AddGeometryAndLoadExtension(extension_id, kWindowId, bounds);
- gfx::Rect newBounds;
- ASSERT_TRUE(cache_->GetGeometry(extension_id, kWindowId, &newBounds));
- ASSERT_EQ(bounds, newBounds);
+ ui::WindowShowState state = ui::SHOW_STATE_NORMAL;
+ AddGeometryAndLoadExtension(extension_id, kWindowId, bounds, state);
+ gfx::Rect new_bounds;
+ ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT;
+ ASSERT_TRUE(cache_->GetGeometry(
+ extension_id, kWindowId, &new_bounds, &new_state));
+ ASSERT_EQ(bounds, new_bounds);
+ ASSERT_EQ(state, new_state);
}
-// Test saving geometry to the cache and state store, and reading it back.
-TEST_F(ShellWindowGeometryCacheTest, SaveGeometryToStore) {
+// Test saving geometry and state to the cache and state store, and reading
+// it back.
+TEST_F(ShellWindowGeometryCacheTest, SaveGeometryAndStateToStore) {
const std::string extension_id = prefs_->AddExtensionAndReturnId("ext1");
const std::string window_id(kWindowId);
@@ -131,12 +140,16 @@ TEST_F(ShellWindowGeometryCacheTest, SaveGeometryToStore) {
// update geometry stored in cache
gfx::Rect bounds(4, 5, 31, 43);
- gfx::Rect newBounds;
- cache_->SaveGeometry(extension_id, window_id, bounds);
+ ui::WindowShowState state = ui::SHOW_STATE_NORMAL;
+ cache_->SaveGeometry(extension_id, window_id, bounds, state);
// make sure that immediately reading back geometry works
- ASSERT_TRUE(cache_->GetGeometry(extension_id, window_id, &newBounds));
- ASSERT_EQ(bounds, newBounds);
+ gfx::Rect new_bounds;
+ ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT;
+ ASSERT_TRUE(cache_->GetGeometry(
+ extension_id, window_id, &new_bounds, &new_state));
+ ASSERT_EQ(bounds, new_bounds);
+ ASSERT_EQ(state, new_state);
// unload extension to force cache to save data to the state store
UnloadExtension(extension_id);
@@ -156,15 +169,20 @@ TEST_F(ShellWindowGeometryCacheTest, SaveGeometryToStore) {
ASSERT_EQ(bounds.width(), v);
ASSERT_TRUE(dict->GetInteger(window_id + ".h", &v));
ASSERT_EQ(bounds.height(), v);
+ ASSERT_TRUE(dict->GetInteger(window_id + ".state", &v));
+ ASSERT_EQ(state, v);
// check to make sure cache indeed doesn't know about this extension anymore
- ASSERT_FALSE(cache_->GetGeometry(extension_id, window_id, &newBounds));
+ ASSERT_FALSE(cache_->GetGeometry(
+ extension_id, window_id, &new_bounds, &new_state));
// reload extension
LoadExtension(extension_id);
// and make sure the geometry got reloaded properly too
- ASSERT_TRUE(cache_->GetGeometry(extension_id, window_id, &newBounds));
- ASSERT_EQ(bounds, newBounds);
+ ASSERT_TRUE(cache_->GetGeometry(
+ extension_id, window_id, &new_bounds, &new_state));
+ ASSERT_EQ(bounds, new_bounds);
+ ASSERT_EQ(state, new_state);
}
// Tests that we won't do writes to the state store for SaveGeometry calls
@@ -185,20 +203,30 @@ TEST_F(ShellWindowGeometryCacheTest, NoDuplicateWrites) {
// Write the first bounds - it should do > 0 writes.
EXPECT_CALL(observer, OnPreferenceChanged(_));
- cache_->SaveGeometry(extension_id, kWindowId, bounds1);
+ cache_->SaveGeometry(extension_id, kWindowId, bounds1,
+ ui::SHOW_STATE_DEFAULT);
WaitForSync();
Mock::VerifyAndClearExpectations(&observer);
// Write a different bounds - it should also do > 0 writes.
EXPECT_CALL(observer, OnPreferenceChanged(_));
- cache_->SaveGeometry(extension_id, kWindowId, bounds2);
+ cache_->SaveGeometry(extension_id, kWindowId, bounds2,
+ ui::SHOW_STATE_DEFAULT);
WaitForSync();
Mock::VerifyAndClearExpectations(&observer);
- // Write a bounds that's a duplicate of what we already have. This should
- // not do any writes.
+ // Write a different state - it should also do > 0 writes.
+ EXPECT_CALL(observer, OnPreferenceChanged(_));
+ cache_->SaveGeometry(extension_id, kWindowId, bounds2,
+ ui::SHOW_STATE_NORMAL);
+ WaitForSync();
+ Mock::VerifyAndClearExpectations(&observer);
+
+ // Write a bounds and state that's a duplicate of what we already have.
+ // This should not do any writes.
EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
- cache_->SaveGeometry(extension_id, kWindowId, bounds2_duplicate);
+ cache_->SaveGeometry(extension_id, kWindowId, bounds2_duplicate,
+ ui::SHOW_STATE_NORMAL);
WaitForSync();
Mock::VerifyAndClearExpectations(&observer);
}
@@ -212,15 +240,16 @@ TEST_F(ShellWindowGeometryCacheTest, MaxWindows) {
gfx::Rect bounds(4, 5, 31, 43);
for (size_t i = 0; i < ShellWindowGeometryCache::kMaxCachedWindows + 1; ++i) {
std::string window_id = "window_" + base::IntToString(i);
- cache_->SaveGeometry(extension_id, window_id, bounds);
+ cache_->SaveGeometry(extension_id, window_id, bounds,
+ ui::SHOW_STATE_DEFAULT);
}
// The first added window should no longer have cached geometry.
- EXPECT_FALSE(cache_->GetGeometry(extension_id, "window_0", &bounds));
+ EXPECT_FALSE(cache_->GetGeometry(extension_id, "window_0", NULL, NULL));
// All other windows should still exist.
for (size_t i = 1; i < ShellWindowGeometryCache::kMaxCachedWindows + 1; ++i) {
std::string window_id = "window_" + base::IntToString(i);
- EXPECT_TRUE(cache_->GetGeometry(extension_id, window_id, &bounds));
+ EXPECT_TRUE(cache_->GetGeometry(extension_id, window_id, NULL, NULL));
}
}
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index 85af48e..0cace94 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -140,6 +140,7 @@ ui::WindowShowState AdjustShowState(ui::WindowShowState state) {
case ui::SHOW_STATE_MINIMIZED:
case ui::SHOW_STATE_MAXIMIZED:
case ui::SHOW_STATE_FULLSCREEN:
+ case ui::SHOW_STATE_DETACHED:
return state;
case ui::SHOW_STATE_DEFAULT:
@@ -1348,16 +1349,10 @@ void SessionService::BuildCommandsForBrowser(
DCHECK(browser && commands);
DCHECK(browser->session_id().id());
- ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL;
- if (browser->window()->IsMaximized())
- show_state = ui::SHOW_STATE_MAXIMIZED;
- else if (browser->window()->IsMinimized())
- show_state = ui::SHOW_STATE_MINIMIZED;
-
commands->push_back(
CreateSetWindowBoundsCommand(browser->session_id(),
browser->window()->GetRestoredBounds(),
- show_state));
+ browser->window()->GetRestoredState()));
commands->push_back(CreateSetWindowTypeCommand(
browser->session_id(), WindowTypeForBrowserType(browser->type())));
diff --git a/chrome/browser/ui/base_window.h b/chrome/browser/ui/base_window.h
index deaa700..823b7dc 100644
--- a/chrome/browser/ui/base_window.h
+++ b/chrome/browser/ui/base_window.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_BASE_WINDOW_H_
#include "base/compiler_specific.h"
+#include "ui/base/ui_base_types.h" // WindowShowState
#include "ui/gfx/native_widget_types.h"
namespace gfx {
@@ -38,6 +39,9 @@ class BaseWindow {
// currently maximized or minimized) in terms of the screen coordinates.
virtual gfx::Rect GetRestoredBounds() const = 0;
+ // Returns the restore state for the window (platform dependent).
+ virtual ui::WindowShowState GetRestoredState() const = 0;
+
// Retrieves the window's current bounds, including its window.
// This will only differ from GetRestoredBounds() for maximized
// and minimized windows.
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h
index 71a3666..925f288 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -60,6 +60,7 @@ class BrowserWindowCocoa :
virtual void SetStarredState(bool is_starred) OVERRIDE;
virtual void ZoomChangedForActiveTab(bool can_show_bubble) OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
+ virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual bool IsMaximized() const OVERRIDE;
virtual bool IsMinimized() const OVERRIDE;
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 773dff8..65c506b 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -316,6 +316,14 @@ gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
return bounds;
}
+ui::WindowShowState BrowserWindowCocoa::GetRestoredState() const {
+ if (IsMaximized())
+ return ui::SHOW_STATE_MAXIMIZED;
+ if (IsMinimized())
+ return ui::SHOW_STATE_MINIMIZED;
+ return ui::SHOW_STATE_NORMAL;
+}
+
gfx::Rect BrowserWindowCocoa::GetBounds() const {
return GetRestoredBounds();
}
diff --git a/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.h b/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.h
index e9f12a0..d021e36 100644
--- a/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.h
@@ -53,6 +53,7 @@ class NativeAppWindowCocoa : public NativeAppWindow {
virtual bool IsFullscreen() const OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
+ virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual void Show() OVERRIDE;
virtual void ShowInactive() OVERRIDE;
@@ -104,6 +105,7 @@ class NativeAppWindowCocoa : public NativeAppWindow {
// NativeAppWindow implementation.
virtual void SetFullscreen(bool fullscreen) OVERRIDE;
virtual bool IsFullscreenOrPending() const OVERRIDE;
+ virtual bool IsDetached() const OVERRIDE;
virtual void UpdateWindowIcon() OVERRIDE;
virtual void UpdateWindowTitle() OVERRIDE;
virtual void UpdateDraggableRegions(
diff --git a/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm b/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm
index 21dbb2d..34dbc59 100644
--- a/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/extensions/native_app_window_cocoa.mm
@@ -394,6 +394,10 @@ bool NativeAppWindowCocoa::IsFullscreenOrPending() const {
return is_fullscreen_;
}
+bool NativeAppWindowCocoa::IsDetached() const {
+ return false;
+}
+
gfx::NativeWindow NativeAppWindowCocoa::GetNativeWindow() {
return window();
}
@@ -407,6 +411,12 @@ gfx::Rect NativeAppWindowCocoa::GetRestoredBounds() const {
return bounds;
}
+ui::WindowShowState NativeAppWindowCocoa::GetRestoredState() const {
+ if (IsMaximized())
+ return ui::SHOW_STATE_MAXIMIZED;
+ return ui::SHOW_STATE_NORMAL;
+}
+
gfx::Rect NativeAppWindowCocoa::GetBounds() const {
return GetRestoredBounds();
}
diff --git a/chrome/browser/ui/extensions/native_app_window.h b/chrome/browser/ui/extensions/native_app_window.h
index 811f4ed..447a9e0 100644
--- a/chrome/browser/ui/extensions/native_app_window.h
+++ b/chrome/browser/ui/extensions/native_app_window.h
@@ -26,6 +26,9 @@ class NativeAppWindow : public BaseWindow, public WebContentsModalDialogHost {
virtual void SetFullscreen(bool fullscreen) = 0;
virtual bool IsFullscreenOrPending() const = 0;
+ // Returns true if the window is a panel that has been detached.
+ virtual bool IsDetached() const = 0;
+
// Called when the icon of the window changes.
virtual void UpdateWindowIcon() = 0;
diff --git a/chrome/browser/ui/extensions/shell_window.cc b/chrome/browser/ui/extensions/shell_window.cc
index e6c48ed..f167e74 100644
--- a/chrome/browser/ui/extensions/shell_window.cc
+++ b/chrome/browser/ui/extensions/shell_window.cc
@@ -72,7 +72,7 @@ ShellWindow::CreateParams::CreateParams()
transparent_background(false),
bounds(INT_MIN, INT_MIN, 0, 0),
creator_process_id(0),
- state(STATE_NORMAL),
+ state(ui::SHOW_STATE_DEFAULT),
hidden(false),
resizable(true),
focused(true) {
@@ -104,7 +104,7 @@ ShellWindow::ShellWindow(Profile* profile,
void ShellWindow::Init(const GURL& url,
ShellWindowContents* shell_window_contents,
- const ShellWindow::CreateParams& params) {
+ const CreateParams& params) {
// Initialize the render interface and web contents
shell_window_contents_.reset(shell_window_contents);
shell_window_contents_->Initialize(profile(), url);
@@ -130,6 +130,7 @@ void ShellWindow::Init(const GURL& url,
// If left and top are left undefined, the native shell window will center
// the window on the main screen in a platform-defined manner.
+ ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT;
if (!params.window_key.empty()) {
window_key_ = params.window_key;
@@ -138,11 +139,12 @@ void ShellWindow::Init(const GURL& url,
shell_window_geometry_cache();
gfx::Rect cached_bounds;
if (cache->GetGeometry(extension()->id(), params.window_key,
- &cached_bounds))
+ &cached_bounds, &cached_state)) {
bounds = cached_bounds;
+ }
}
- ShellWindow::CreateParams new_params = params;
+ CreateParams new_params = params;
gfx::Size& minimum_size = new_params.minimum_size;
gfx::Size& maximum_size = new_params.maximum_size;
@@ -166,30 +168,27 @@ void ShellWindow::Init(const GURL& url,
new_params.bounds = bounds;
- native_app_window_.reset(NativeAppWindow::Create(this, new_params));
- OnNativeWindowChanged();
+ if (cached_state != ui::SHOW_STATE_DEFAULT)
+ new_params.state = cached_state;
- switch (params.state) {
- case CreateParams::STATE_NORMAL:
- break;
- case CreateParams::STATE_FULLSCREEN:
- Fullscreen();
- break;
- case CreateParams::STATE_MAXIMIZED:
- Maximize();
- break;
- case CreateParams::STATE_MINIMIZED:
- Minimize();
- break;
- }
+ native_app_window_.reset(NativeAppWindow::Create(this, new_params));
- if (!params.hidden) {
+ if (!new_params.hidden) {
if (window_type_is_panel())
GetBaseWindow()->ShowInactive(); // Panels are not activated by default.
else
GetBaseWindow()->Show();
}
+ if (new_params.state == ui::SHOW_STATE_FULLSCREEN)
+ Fullscreen();
+ else if (new_params.state == ui::SHOW_STATE_MAXIMIZED)
+ Maximize();
+ else if (new_params.state == ui::SHOW_STATE_MINIMIZED)
+ Minimize();
+
+ OnNativeWindowChanged();
+
// When the render view host is changed, the native window needs to know
// about it in case it has any setup to do to make the renderer appear
// properly. In particular, on Windows, the view's clickthrough region needs
@@ -576,7 +575,8 @@ void ShellWindow::SaveWindowPosition() {
gfx::Rect bounds = native_app_window_->GetRestoredBounds();
bounds.Inset(native_app_window_->GetFrameInsets());
- cache->SaveGeometry(extension()->id(), window_key_, bounds);
+ ui::WindowShowState window_state = native_app_window_->GetRestoredState();
+ cache->SaveGeometry(extension()->id(), window_key_, bounds, window_state);
}
// static
diff --git a/chrome/browser/ui/extensions/shell_window.h b/chrome/browser/ui/extensions/shell_window.h
index 7b28a5c..05b06ab 100644
--- a/chrome/browser/ui/extensions/shell_window.h
+++ b/chrome/browser/ui/extensions/shell_window.h
@@ -15,6 +15,7 @@
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/console_message_level.h"
+#include "ui/base/ui_base_types.h" // WindowShowState
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
@@ -102,15 +103,8 @@ class ShellWindow : public content::NotificationObserver,
// The process ID of the process that requested the create.
int32 creator_process_id;
- enum State {
- STATE_NORMAL,
- STATE_FULLSCREEN,
- STATE_MAXIMIZED,
- STATE_MINIMIZED
- };
-
// Initial state of the window.
- State state;
+ ui::WindowShowState state;
// If true, don't show the window after creation.
bool hidden;
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc
index e594a6c..22ac92a 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_window_gtk.cc
@@ -799,6 +799,14 @@ gfx::Rect BrowserWindowGtk::GetRestoredBounds() const {
return restored_bounds_;
}
+ui::WindowShowState BrowserWindowGtk::GetRestoredState() const {
+ if (IsMaximized())
+ return ui::SHOW_STATE_MAXIMIZED;
+ if (IsMinimized())
+ return ui::SHOW_STATE_MINIMIZED;
+ return ui::SHOW_STATE_NORMAL;
+}
+
gfx::Rect BrowserWindowGtk::GetBounds() const {
return bounds_;
}
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h
index 5ff445f..67dac6b 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.h
+++ b/chrome/browser/ui/gtk/browser_window_gtk.h
@@ -59,13 +59,13 @@ class PrefRegistrySyncable;
// An implementation of BrowserWindow for GTK. Cross-platform code will interact
// with this object when it needs to manipulate the window.
-class BrowserWindowGtk :
- public BrowserWindow,
- public content::NotificationObserver,
- public TabStripModelObserver,
- public ui::ActiveWindowWatcherXObserver,
- public InfoBarContainer::Delegate,
- public extensions::ExtensionKeybindingRegistry::Delegate {
+class BrowserWindowGtk
+ : public BrowserWindow,
+ public content::NotificationObserver,
+ public TabStripModelObserver,
+ public ui::ActiveWindowWatcherXObserver,
+ public InfoBarContainer::Delegate,
+ public extensions::ExtensionKeybindingRegistry::Delegate {
public:
explicit BrowserWindowGtk(Browser* browser);
virtual ~BrowserWindowGtk();
@@ -95,6 +95,7 @@ class BrowserWindowGtk :
virtual void SetStarredState(bool is_starred) OVERRIDE;
virtual void ZoomChangedForActiveTab(bool can_show_bubble) OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
+ virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual bool IsMaximized() const OVERRIDE;
virtual bool IsMinimized() const OVERRIDE;
diff --git a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
index b717e10..6e3a488 100644
--- a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
+++ b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
@@ -170,6 +170,12 @@ gfx::Rect NativeAppWindowGtk::GetRestoredBounds() const {
return window_bounds;
}
+ui::WindowShowState NativeAppWindowGtk::GetRestoredState() const {
+ if (IsMaximized())
+ return ui::SHOW_STATE_MAXIMIZED;
+ return ui::SHOW_STATE_NORMAL;
+}
+
gfx::Rect NativeAppWindowGtk::GetBounds() const {
gfx::Rect window_bounds = bounds_;
window_bounds.Inset(-GetFrameInsets());
@@ -485,6 +491,10 @@ bool NativeAppWindowGtk::IsFullscreenOrPending() const {
return content_thinks_its_fullscreen_;
}
+bool NativeAppWindowGtk::IsDetached() const {
+ return false;
+}
+
void NativeAppWindowGtk::UpdateWindowIcon() {
Profile* profile = shell_window_->profile();
gfx::Image app_icon = shell_window_->app_icon();
diff --git a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
index 7facadd..c75c46a 100644
--- a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
+++ b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
@@ -36,8 +36,10 @@ class NativeAppWindowGtk : public NativeAppWindow,
virtual bool IsMaximized() const OVERRIDE;
virtual bool IsMinimized() const OVERRIDE;
virtual bool IsFullscreen() const OVERRIDE;
+ virtual bool IsDetached() const OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
+ virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual void Show() OVERRIDE;
virtual void ShowInactive() OVERRIDE;
diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc
index 7fadec8..02af37e 100644
--- a/chrome/browser/ui/panels/panel.cc
+++ b/chrome/browser/ui/panels/panel.cc
@@ -253,6 +253,10 @@ gfx::Rect Panel::GetRestoredBounds() const {
return bounds;
}
+ui::WindowShowState Panel::GetRestoredState() const {
+ return ui::SHOW_STATE_NORMAL;
+}
+
gfx::Rect Panel::GetBounds() const {
return native_panel_->GetPanelBounds();
}
diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h
index b2362a4..1542aa9 100644
--- a/chrome/browser/ui/panels/panel.h
+++ b/chrome/browser/ui/panels/panel.h
@@ -119,6 +119,7 @@ class Panel : public BaseWindow,
virtual bool IsFullscreen() const OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
+ virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual void Show() OVERRIDE;
virtual void Hide() OVERRIDE;
diff --git a/chrome/browser/ui/views/extensions/native_app_window_views.cc b/chrome/browser/ui/views/extensions/native_app_window_views.cc
index e981a84..6781fcd 100644
--- a/chrome/browser/ui/views/extensions/native_app_window_views.cc
+++ b/chrome/browser/ui/views/extensions/native_app_window_views.cc
@@ -41,7 +41,9 @@
#include "ash/wm/panels/panel_frame_view.h"
#include "ash/wm/window_properties.h"
#include "chrome/browser/ui/ash/ash_util.h"
+#include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
#endif
namespace {
@@ -261,15 +263,21 @@ void NativeAppWindowViews::InitializePanelWindow(
window_->Init(params);
window_->set_focus_on_creation(create_params.focused);
-#if !defined(USE_ASH)
- // TODO(oshima|stevenjb): Ideally, we should be able to just pre-determine
- // the exact location and size, but this doesn't work well
- // on non-ash environment where we don't have full control over
- // window management.
- gfx::Rect window_bounds =
- window_->non_client_view()->GetWindowBoundsForClientBounds(
- create_params.bounds);
- window_->SetBounds(window_bounds);
+#if defined(USE_ASH)
+ if (create_params.state == ui::SHOW_STATE_DETACHED) {
+ gfx::Rect window_bounds(create_params.bounds.x(),
+ create_params.bounds.y(),
+ preferred_size_.width(),
+ preferred_size_.height());
+ aura::Window* native_window = GetNativeWindow();
+ native_window->SetProperty(ash::internal::kPanelAttachedKey, false);
+ native_window->SetDefaultParentByRootWindow(
+ native_window->GetRootWindow(), native_window->GetBoundsInScreen());
+ window_->SetBounds(window_bounds);
+ }
+#else
+ // TODO(stevenjb): NativeAppWindow panels need to be implemented for other
+ // platforms.
#endif
}
@@ -299,6 +307,23 @@ gfx::Rect NativeAppWindowViews::GetRestoredBounds() const {
return window_->GetRestoredBounds();
}
+ui::WindowShowState NativeAppWindowViews::GetRestoredState() const {
+ if (IsMaximized())
+ return ui::SHOW_STATE_MAXIMIZED;
+#if defined(USE_ASH)
+ // On Ash, restore fullscreen.
+ if (IsFullscreen())
+ return ui::SHOW_STATE_FULLSCREEN;
+ // Use kRestoreShowStateKey in case a window is minimized/hidden.
+ ui::WindowShowState restore_state =
+ window_->GetNativeWindow()->GetProperty(
+ aura::client::kRestoreShowStateKey);
+ if (restore_state != ui::SHOW_STATE_MINIMIZED)
+ return restore_state;
+#endif
+ return ui::SHOW_STATE_NORMAL;
+}
+
gfx::Rect NativeAppWindowViews::GetBounds() const {
return window_->GetWindowBoundsInScreen();
}
@@ -670,6 +695,17 @@ bool NativeAppWindowViews::IsFullscreenOrPending() const {
return is_fullscreen_;
}
+bool NativeAppWindowViews::IsDetached() const {
+ if (!shell_window_->window_type_is_panel())
+ return false;
+#if defined(USE_ASH)
+ return !window_->GetNativeWindow()->GetProperty(
+ ash::internal::kPanelAttachedKey);
+#else
+ return false;
+#endif
+}
+
views::View* NativeAppWindowViews::GetContentsView() {
return this;
}
diff --git a/chrome/browser/ui/views/extensions/native_app_window_views.h b/chrome/browser/ui/views/extensions/native_app_window_views.h
index 4a5cbac..90448d2 100644
--- a/chrome/browser/ui/views/extensions/native_app_window_views.h
+++ b/chrome/browser/ui/views/extensions/native_app_window_views.h
@@ -69,6 +69,7 @@ class NativeAppWindowViews : public NativeAppWindow,
virtual bool IsFullscreen() const OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
+ virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual void Show() OVERRIDE;
virtual void ShowInactive() OVERRIDE;
@@ -129,6 +130,7 @@ class NativeAppWindowViews : public NativeAppWindow,
// NativeAppWindow implementation.
virtual void SetFullscreen(bool fullscreen) OVERRIDE;
virtual bool IsFullscreenOrPending() const OVERRIDE;
+ virtual bool IsDetached() const OVERRIDE;
virtual void UpdateWindowIcon() OVERRIDE;
virtual void UpdateWindowTitle() OVERRIDE;
virtual void UpdateDraggableRegions(
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 0604615..ebe1f38 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -774,6 +774,14 @@ gfx::Rect BrowserView::GetRestoredBounds() const {
return frame_->GetRestoredBounds();
}
+ui::WindowShowState BrowserView::GetRestoredState() const {
+ if (IsMaximized())
+ return ui::SHOW_STATE_MAXIMIZED;
+ if (IsMinimized())
+ return ui::SHOW_STATE_MINIMIZED;
+ return ui::SHOW_STATE_NORMAL;
+}
+
gfx::Rect BrowserView::GetBounds() const {
return frame_->GetWindowBoundsInScreen();
}
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index d307e87..4744a17 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -276,6 +276,7 @@ class BrowserView : public BrowserWindow,
virtual void SetStarredState(bool is_starred) OVERRIDE;
virtual void ZoomChangedForActiveTab(bool can_show_bubble) OVERRIDE;
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
+ virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual bool IsMaximized() const OVERRIDE;
virtual bool IsMinimized() const OVERRIDE;
diff --git a/chrome/renderer/resources/extensions/app_window_custom_bindings.js b/chrome/renderer/resources/extensions/app_window_custom_bindings.js
index 83322cf..a2a5af1 100644
--- a/chrome/renderer/resources/extensions/app_window_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/app_window_custom_bindings.js
@@ -122,9 +122,9 @@ appWindow.registerCustomHook(function(bindingsAPI) {
id: params.id || '',
bounds: { left: params.bounds.left, top: params.bounds.top,
width: params.bounds.width, height: params.bounds.height },
- fullscreen: false,
- minimized: false,
- maximized: false
+ fullscreen: params.fullscreen,
+ minimized: params.minimized,
+ maximized: params.maximized
};
chromeHidden.currentAppWindow = new AppWindow;
});
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc
index e454194..25102b2 100644
--- a/chrome/test/base/test_browser_window.cc
+++ b/chrome/test/base/test_browser_window.cc
@@ -38,6 +38,10 @@ gfx::Rect TestBrowserWindow::GetRestoredBounds() const {
return gfx::Rect();
}
+ui::WindowShowState TestBrowserWindow::GetRestoredState() const {
+ return ui::SHOW_STATE_DEFAULT;
+}
+
gfx::Rect TestBrowserWindow::GetBounds() const {
return gfx::Rect();
}
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index 2394601..1f84811 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -47,6 +47,7 @@ class TestBrowserWindow : public BrowserWindow {
virtual void SetStarredState(bool is_starred) OVERRIDE {}
virtual void ZoomChangedForActiveTab(bool can_show_bubble) OVERRIDE {}
virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
+ virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual bool IsMaximized() const OVERRIDE;
virtual bool IsMinimized() const OVERRIDE;
diff --git a/chrome/test/data/extensions/platform_apps/restore_state/empty.html b/chrome/test/data/extensions/platform_apps/restore_state/empty.html
new file mode 100644
index 0000000..aabcd1b
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/restore_state/empty.html
@@ -0,0 +1 @@
+<!-- This file intentionally left blank. -->
diff --git a/chrome/test/data/extensions/platform_apps/restore_state/manifest.json b/chrome/test/data/extensions/platform_apps/restore_state/manifest.json
new file mode 100644
index 0000000..1d8f040
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/restore_state/manifest.json
@@ -0,0 +1,9 @@
+{
+ "name": "Platform App Test: restore window state",
+ "version": "1",
+ "app": {
+ "background": {
+ "scripts": ["test.js"]
+ }
+ }
+}
diff --git a/chrome/test/data/extensions/platform_apps/restore_state/test.js b/chrome/test/data/extensions/platform_apps/restore_state/test.js
new file mode 100644
index 0000000..d7497be
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/restore_state/test.js
@@ -0,0 +1,46 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var assertState = function(win) {
+ if (win.id == 'normal') {
+ chrome.test.assertFalse(win.isMinimized());
+ chrome.test.assertFalse(win.isMaximized());
+ }
+ if (win.id == 'maximized') {
+ chrome.test.assertFalse(win.isMinimized());
+ chrome.test.assertTrue(win.isMaximized());
+ }
+}
+
+var testRestoreState = function(state_type) {
+ chrome.app.window.create(
+ 'empty.html',
+ { id: state_type, state: state_type },
+ chrome.test.callbackPass(windowCreated)
+ );
+ function windowCreated(win) {
+ assertState(win);
+ win.onClosed.addListener(chrome.test.callbackPass(windowClosed));
+ win.close();
+ function windowClosed() {
+ chrome.app.window.create(
+ 'empty.html',
+ { id: state_type },
+ function(win2) { assertState(win2); }
+ );
+ }
+ };
+}
+
+chrome.app.runtime.onLaunched.addListener(function() {
+ chrome.test.runTests([
+ function testRestoreNormal() {
+ testRestoreState('normal');
+ },
+ function testRestoreMaximized() {
+ testRestoreState('maximized');
+ },
+ // Minimize and fullscreen behavior are platform dependent.
+ ]);
+});
diff --git a/ui/aura/client/aura_constants.cc b/ui/aura/client/aura_constants.cc
index 739f2e0..7ba9f87 100644
--- a/ui/aura/client/aura_constants.cc
+++ b/ui/aura/client/aura_constants.cc
@@ -28,6 +28,8 @@ DEFINE_WINDOW_PROPERTY_KEY(ui::ModalType, kModalKey, ui::MODAL_TYPE_NONE);
// gfx::Rect object for RestoreBoundsKey property is owned by the window
// and will be freed automatically.
DEFINE_OWNED_WINDOW_PROPERTY_KEY(gfx::Rect, kRestoreBoundsKey, NULL);
+DEFINE_WINDOW_PROPERTY_KEY(
+ ui::WindowShowState, kRestoreShowStateKey, ui::SHOW_STATE_DEFAULT);
DEFINE_WINDOW_PROPERTY_KEY(ui::InputMethod*, kRootWindowInputMethodKey, NULL);
DEFINE_WINDOW_PROPERTY_KEY(
ui::WindowShowState, kShowStateKey, ui::SHOW_STATE_DEFAULT);
diff --git a/ui/aura/client/aura_constants.h b/ui/aura/client/aura_constants.h
index 6681eea..32c524f 100644
--- a/ui/aura/client/aura_constants.h
+++ b/ui/aura/client/aura_constants.h
@@ -44,6 +44,11 @@ AURA_EXPORT extern const WindowProperty<ui::ModalType>* const kModalKey;
// A property key to store the restore bounds for a window.
AURA_EXPORT extern const WindowProperty<gfx::Rect*>* const kRestoreBoundsKey;
+// A property key to store ui::WindowShowState for restoring a window.
+// Used in Ash to remember the show state before the window was minimized.
+AURA_EXPORT extern const WindowProperty<ui::WindowShowState>* const
+ kRestoreShowStateKey;
+
// A property key to store an input method object that handles a key event.
AURA_EXPORT extern const WindowProperty<ui::InputMethod*>* const
kRootWindowInputMethodKey;
diff --git a/ui/base/ui_base_types.h b/ui/base/ui_base_types.h
index 3eb46ca..2f1bcec 100644
--- a/ui/base/ui_base_types.h
+++ b/ui/base/ui_base_types.h
@@ -17,7 +17,8 @@ enum WindowShowState {
SHOW_STATE_MAXIMIZED = 3,
SHOW_STATE_INACTIVE = 4, // Views only, not persisted.
SHOW_STATE_FULLSCREEN = 5,
- SHOW_STATE_END = 6 // The end of show state enum.
+ SHOW_STATE_DETACHED = 6, // Views only; detached panel.
+ SHOW_STATE_END = 7 // The end of show state enum.
};
// Dialog button identifiers used to specify which buttons to show the user.