Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1280)

Unified Diff: ash/wm/workspace/auto_window_management.cc

Issue 23205027: Correctly restore the auto managed window to the original bounds when becoming single window (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ash/wm/workspace/auto_window_management.h ('k') | ash/wm/workspace_controller_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/wm/workspace/auto_window_management.cc
diff --git a/ash/wm/workspace/auto_window_management.cc b/ash/wm/workspace/auto_window_management.cc
index 07073ff6447d3150ad3ff0bed4b4070806ca56e9..ddcd19c62949823b2658b50f4a9f215b5d51f087 100644
--- a/ash/wm/workspace/auto_window_management.cc
+++ b/ash/wm/workspace/auto_window_management.cc
@@ -6,6 +6,7 @@
#include "ash/ash_switches.h"
#include "ash/shell.h"
+#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/window_util.h"
@@ -41,31 +42,6 @@ bool WindowPositionCanBeManaged(const aura::Window* window) {
!wm::HasUserChangedWindowPositionOrSize(window));
}
-// Given a |window|, return the only |other_window| which has an impact on
-// the automated windows location management. If there is more then one window,
-// false is returned, but the |other_window| will be set to the first one
-// found.
-// If the return value is true a single window was found.
-bool GetOtherVisibleAndManageableWindow(const aura::Window* window,
- aura::Window** other_window) {
- *other_window = NULL;
- const aura::Window::Windows& windows = window->parent()->children();
- // Find a single open managed window.
- for (size_t i = 0; i < windows.size(); i++) {
- aura::Window* iterated_window = windows[i];
- if (window != iterated_window &&
- iterated_window->type() == aura::client::WINDOW_TYPE_NORMAL &&
- iterated_window->TargetVisibility() &&
- wm::IsWindowPositionManaged(iterated_window)) {
- // Bail if we find a second usable window.
- if (*other_window)
- return false;
- *other_window = iterated_window;
- }
- }
- return *other_window != NULL;
-}
-
// Get the work area for a given |window|.
gfx::Rect GetWorkAreaForWindow(aura::Window* window) {
#if defined(OS_WIN)
@@ -137,15 +113,68 @@ void AutoPlaceSingleWindow(aura::Window* window, bool animated) {
window->SetBounds(bounds);
}
+// Get the first open (non minimized) window which is on the screen defined.
+aura::Window* GetReferenceWindow(const aura::RootWindow* root_window,
+ const aura::Window* exclude,
+ bool *single_window) {
+ if (single_window)
+ *single_window = true;
+ // Get the active window.
+ aura::Window* active = ash::wm::GetActiveWindow();
+ if (active && active->GetRootWindow() != root_window)
+ active = NULL;
+
+ // Get a list of all windows.
+ const std::vector<aura::Window*> windows =
sky 2013/08/29 19:33:31 Are you sure we want all windows here? It was my u
oshima 2013/08/29 19:49:52 They're excluded by IsWindowPositionManaged check.
+ ash::MruWindowTracker::BuildWindowList(false);
+
+ if (windows.empty())
+ return NULL;
+
+ aura::Window::Windows::const_iterator iter = windows.begin();
+ // Find the index of the current active window.
+ if (active)
+ iter = std::find(windows.begin(), windows.end(), active);
+
+ int index = (iter == windows.end()) ? 0 : (iter - windows.begin());
+
+ // Scan the cycle list backwards to see which is the second topmost window
+ // (and so on). Note that we might cycle a few indices twice if there is no
+ // suitable window. However - since the list is fairly small this should be
+ // very fast anyways.
+ aura::Window* found = NULL;
+ for (int i = index + windows.size(); i >= 0; i--) {
+ aura::Window* window = windows[i % windows.size()];
+ if (window != exclude &&
+ window->type() == aura::client::WINDOW_TYPE_NORMAL &&
+ window->GetRootWindow() == root_window &&
+ window->TargetVisibility() &&
+ wm::IsWindowPositionManaged(window)) {
+ if (found && found != window) {
+ // no need to check !signle_window because the function must have
sky 2013/08/29 20:18:09 single_window
oshima 2013/08/29 20:48:05 Done.
+ // been already returned in the "if (!single_window)" below.
+ *single_window = false;
+ return found;
+ }
+ found = window;
+ // If there is no need to check single window, return now.
+ if (!single_window)
+ return found;
+ }
+ }
+ return found;
+}
+
} // namespace
void RearrangeVisibleWindowOnHideOrRemove(const aura::Window* removed_window) {
if (!UseAutoWindowManager(removed_window))
return;
// Find a single open browser window.
- aura::Window* other_shown_window = NULL;
- if (!GetOtherVisibleAndManageableWindow(removed_window,
- &other_shown_window) ||
+ bool single_window;
+ aura::Window* other_shown_window = GetReferenceWindow(
+ removed_window->GetRootWindow(), removed_window, &single_window);
+ if (!other_shown_window || !single_window ||
!WindowPositionCanBeManaged(other_shown_window))
return;
AutoPlaceSingleWindow(other_shown_window, true);
@@ -157,9 +186,11 @@ void RearrangeVisibleWindowOnShow(aura::Window* added_window) {
!added_window->TargetVisibility())
return;
// Find a single open managed window.
- aura::Window* other_shown_window = NULL;
- if (!GetOtherVisibleAndManageableWindow(added_window,
- &other_shown_window)) {
+ bool single_window;
+ aura::Window* other_shown_window = GetReferenceWindow(
+ added_window->GetRootWindow(), added_window, &single_window);
+
+ if (!other_shown_window) {
// It could be that this window is the first window joining the workspace.
if (!WindowPositionCanBeManaged(added_window) || other_shown_window)
return;
@@ -169,31 +200,44 @@ void RearrangeVisibleWindowOnShow(aura::Window* added_window) {
return;
}
- // When going from one to two windows both windows loose their "positioned
- // by user" flags.
- ash::wm::SetUserHasChangedWindowPositionOrSize(added_window, false);
- ash::wm::SetUserHasChangedWindowPositionOrSize(other_shown_window, false);
-
- if (WindowPositionCanBeManaged(other_shown_window)) {
- gfx::Rect work_area = GetWorkAreaForWindow(added_window);
-
- // Push away the other window after remembering its current position.
- gfx::Rect other_bounds = other_shown_window->bounds();
- ash::wm::SetPreAutoManageWindowBounds(other_shown_window, other_bounds);
-
- bool move_right = other_bounds.CenterPoint().x() > work_area.width() / 2;
- if (MoveRectToOneSide(work_area.width(), move_right, &other_bounds))
- SetBoundsAnimated(other_shown_window, other_bounds);
+ gfx::Rect other_bounds = other_shown_window->bounds();
+ gfx::Rect work_area = GetWorkAreaForWindow(added_window);
+ bool move_other_right =
+ other_bounds.CenterPoint().x() > work_area.width() / 2;
+
+ // Push the other window to the size only if there are two windows left.
+ if (single_window) {
+ // When going from one to two windows both windows loose their "positioned
+ // by user" flags.
+ ash::wm::SetUserHasChangedWindowPositionOrSize(added_window, false);
+ ash::wm::SetUserHasChangedWindowPositionOrSize(other_shown_window, false);
+
+ if (WindowPositionCanBeManaged(other_shown_window)) {
+ // Don't override pre auto managed bounds as the current bounds
+ // may not be original.
+ if (!ash::wm::GetPreAutoManageWindowBounds(other_shown_window))
+ ash::wm::SetPreAutoManageWindowBounds(other_shown_window, other_bounds);
+
+ // Push away the other window after remembering its current position.
+ if (MoveRectToOneSide(work_area.width(), move_other_right, &other_bounds))
+ SetBoundsAnimated(other_shown_window, other_bounds);
+ }
+ }
- // Remember the current location of the new window and push it also to the
- // opposite location (if needed).
- // Since it is just coming into view, we do not need to animate it.
- gfx::Rect added_bounds = added_window->bounds();
+ // Remember the current location of the window if it's new and push
+ // it also to the opposite location if needed. Since it is just
+ // being shown, we do not need to animate it.
+ gfx::Rect added_bounds = added_window->bounds();
+ if (!ash::wm::GetPreAutoManageWindowBounds(added_window))
ash::wm::SetPreAutoManageWindowBounds(added_window, added_bounds);
- if (MoveRectToOneSide(work_area.width(), !move_right, &added_bounds))
- added_window->SetBounds(added_bounds);
- }
+ if (MoveRectToOneSide(work_area.width(), !move_other_right, &added_bounds))
+ added_window->SetBounds(added_bounds);
}
} // namespace internal
+
+aura::Window* GetTopWindowForNewWindow(const aura::RootWindow* root_window) {
+ return internal::GetReferenceWindow(root_window, NULL, NULL);
+}
+
} // namespace ash
« no previous file with comments | « ash/wm/workspace/auto_window_management.h ('k') | ash/wm/workspace_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698