Skip to content

Commit

Permalink
Make sure the non browser/no app widget is fully visible when created…
Browse files Browse the repository at this point in the history
… on ash

added minimum_visibility flag to WindowState to guarantee that the part of widget is always visible.

TEST=open TaskManager on 2nd display, close it, disconnect display, then open task manager again. minimum visibility is covered by test.

Review URL: https://codereview.chromium.org/55303006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232400 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
oshima@chromium.org committed Nov 1, 2013
1 parent f8c9260 commit 0194049
Show file tree
Hide file tree
Showing 17 changed files with 107 additions and 5 deletions.
1 change: 1 addition & 0 deletions ash/shell/toplevel_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ void ToplevelWindow::SaveWindowPlacement(const gfx::Rect& bounds,
}

bool ToplevelWindow::GetSavedWindowPlacement(
const views::Widget* widget,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const {
bool is_saved_bounds = !!saved_state;
Expand Down
1 change: 1 addition & 0 deletions ash/shell/toplevel_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class ToplevelWindow : public views::WidgetDelegateView {
const gfx::Rect& bounds,
ui::WindowShowState show_state) OVERRIDE;
virtual bool GetSavedWindowPlacement(
const views::Widget* widget,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const OVERRIDE;
virtual View* GetContentsView() OVERRIDE;
Expand Down
16 changes: 14 additions & 2 deletions ash/wm/window_positioner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,23 @@ bool WindowPositioner::DisableAutoPositioning(bool ignore) {
void WindowPositioner::RearrangeVisibleWindowOnShow(
aura::Window* added_window) {
wm::WindowState* added_window_state = wm::GetWindowState(added_window);
if (!added_window->TargetVisibility())
return;

if (!UseAutoWindowManager(added_window) ||
added_window_state->bounds_changed_by_user() ||
!added_window->TargetVisibility())
added_window_state->bounds_changed_by_user()) {
if (added_window_state->minimum_visibility()) {
// Guarante minimum visibility within the work area.
gfx::Rect work_area = GetWorkAreaForWindowInParent(added_window);
gfx::Rect bounds = added_window->bounds();
gfx::Rect new_bounds = bounds;
ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area,
&new_bounds);
if (new_bounds != bounds)
added_window->SetBounds(new_bounds);
}
return;
}
// Find a single open managed window.
bool single_window;
aura::Window* other_shown_window = GetReferenceWindow(
Expand Down
51 changes: 51 additions & 0 deletions ash/wm/window_positioner_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ui/aura/root_window.h"
#include "ui/gfx/screen.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace ash {

Expand Down Expand Up @@ -49,4 +50,54 @@ TEST_F(WindowPositionerTest, OpenDefaultWindowOnSecondDisplay) {
second_root_window).bounds().Contains(bounds));
}

namespace {

// A WidgetDelegate that returns the out of display saved bounds.
class OutOfDisplayDelegate : public views::WidgetDelegate {
public:
explicit OutOfDisplayDelegate(views::Widget* widget) : widget_(widget) {}
virtual ~OutOfDisplayDelegate() {}

// Overridden from WidgetDelegate:
virtual void DeleteDelegate() OVERRIDE {
delete this;
}
virtual views::Widget* GetWidget() OVERRIDE {
return widget_;
}
virtual const views::Widget* GetWidget() const OVERRIDE {
return widget_;
}
virtual bool GetSavedWindowPlacement(
const views::Widget* widget,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const OVERRIDE {
bounds->SetRect(450, 10, 100, 100);
*show_state = ui::SHOW_STATE_NORMAL;
return true;
}

private:
views::Widget* widget_;

DISALLOW_COPY_AND_ASSIGN(OutOfDisplayDelegate);
};

} // namespace

TEST_F(WindowPositionerTest, EnsureMinimumVisibility) {
UpdateDisplay("400x400");
views::Widget* widget = new views::Widget();
views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
params.delegate = new OutOfDisplayDelegate(widget);
params.context = Shell::GetPrimaryRootWindow();
widget->Init(params);
widget->SetBounds(gfx::Rect(450,10, 100, 100));
wm::GetWindowState(widget->GetNativeView())->set_minimum_visibility(true);
widget->Show();
// Make sure the bounds is adjusted to be inside the work area.
EXPECT_EQ("390,10 100x100", widget->GetWindowBoundsInScreen().ToString());
widget->CloseNow();
}

} // namespace
1 change: 1 addition & 0 deletions ash/wm/window_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ WindowState::WindowState(aura::Window* window)
always_restores_to_restore_bounds_(false),
hide_shelf_when_fullscreen_(true),
animate_to_fullscreen_(true),
minimum_visibility_(false),
window_show_type_(ToWindowShowType(GetShowState())) {
window_->AddObserver(this);
}
Expand Down
13 changes: 13 additions & 0 deletions ash/wm/window_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ class ASH_EXPORT WindowState : public aura::WindowObserver {
animate_to_fullscreen_ = value;
}

// If the minimum visibilty is true, ash will try to keep a
// minimum amount of the window is always visible on the work area
// when shown.
// TODO(oshima): Consolidate this and window_position_managed
// into single parameter to control the window placement.
bool minimum_visibility() const {
return minimum_visibility_;
}
void set_minimum_visibility(bool minimum_visibility) {
minimum_visibility_ = minimum_visibility;
}

// Gets/Sets the bounds of the window before it was moved by the auto window
// management. As long as it was not auto-managed, it will return NULL.
const gfx::Rect* pre_auto_manage_window_bounds() const {
Expand Down Expand Up @@ -262,6 +274,7 @@ class ASH_EXPORT WindowState : public aura::WindowObserver {
bool always_restores_to_restore_bounds_;
bool hide_shelf_when_fullscreen_;
bool animate_to_fullscreen_;
bool minimum_visibility_;

// A property to remember the window position which was set before the
// auto window position manager changed the window bounds, so that it can get
Expand Down
1 change: 1 addition & 0 deletions ash/wm/workspace/workspace_layout_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class MaximizeDelegateView : public views::WidgetDelegateView {
virtual ~MaximizeDelegateView() {}

virtual bool GetSavedWindowPlacement(
const views::Widget* widget,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const OVERRIDE {
*bounds = initial_bounds_;
Expand Down
14 changes: 14 additions & 0 deletions chrome/browser/ui/views/chrome_views_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#if defined(USE_ASH)
#include "ash/shell.h"
#include "ash/wm/window_state.h"
#include "chrome/browser/ui/ash/ash_init.h"
#include "chrome/browser/ui/ash/ash_util.h"
#endif
Expand Down Expand Up @@ -92,6 +93,7 @@ void ChromeViewsDelegate::SaveWindowPlacement(const views::Widget* window,
}

bool ChromeViewsDelegate::GetSavedWindowPlacement(
const views::Widget* widget,
const std::string& window_name,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const {
Expand All @@ -115,6 +117,18 @@ bool ChromeViewsDelegate::GetSavedWindowPlacement(
dictionary->GetBoolean("maximized", &maximized);
*show_state = maximized ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL;

#if defined(USE_ASH)
// On Ash environment, a window won't span across displays. Adjust
// the bounds to fit the work area.
gfx::NativeView window = widget->GetNativeView();
if (chrome::GetHostDesktopTypeForNativeView(window) ==
chrome::HOST_DESKTOP_TYPE_ASH) {
gfx::Display display = gfx::Screen::GetScreenFor(window)->
GetDisplayMatching(*bounds);
bounds->AdjustToFit(display.work_area());
ash::wm::GetWindowState(window)->set_minimum_visibility(true);
}
#endif
return true;
}

Expand Down
1 change: 1 addition & 0 deletions chrome/browser/ui/views/chrome_views_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class ChromeViewsDelegate : public views::ViewsDelegate {
const gfx::Rect& bounds,
ui::WindowShowState show_state) OVERRIDE;
virtual bool GetSavedWindowPlacement(
const views::Widget* widget,
const std::string& window_name,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const OVERRIDE;
Expand Down
1 change: 1 addition & 0 deletions chrome/browser/ui/views/frame/browser_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,7 @@ void BrowserView::SaveWindowPlacement(const gfx::Rect& bounds,
}

bool BrowserView::GetSavedWindowPlacement(
const views::Widget* widget,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const {
if (!ShouldSaveOrRestoreWindowPos())
Expand Down
1 change: 1 addition & 0 deletions chrome/browser/ui/views/frame/browser_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ class BrowserView : public BrowserWindow,
virtual void SaveWindowPlacement(const gfx::Rect& bounds,
ui::WindowShowState show_state) OVERRIDE;
virtual bool GetSavedWindowPlacement(
const views::Widget* widget,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const OVERRIDE;
virtual views::View* GetContentsView() OVERRIDE;
Expand Down
1 change: 1 addition & 0 deletions ui/views/test/test_views_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void TestViewsDelegate::SaveWindowPlacement(const Widget* window,
}

bool TestViewsDelegate::GetSavedWindowPlacement(
const Widget* window,
const std::string& window_name,
gfx::Rect* bounds,
ui:: WindowShowState* show_state) const {
Expand Down
1 change: 1 addition & 0 deletions ui/views/test/test_views_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class TestViewsDelegate : public ViewsDelegate {
const gfx::Rect& bounds,
ui::WindowShowState show_state) OVERRIDE;
virtual bool GetSavedWindowPlacement(
const Widget* window,
const std::string& window_name,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const OVERRIDE;
Expand Down
1 change: 1 addition & 0 deletions ui/views/views_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class VIEWS_EXPORT ViewsDelegate {
// Retrieves the saved position and size and "show" state for the window with
// the specified name.
virtual bool GetSavedWindowPlacement(
const Widget* widget,
const std::string& window_name,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const = 0;
Expand Down
2 changes: 1 addition & 1 deletion ui/views/widget/widget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1396,7 +1396,7 @@ bool Widget::GetSavedWindowPlacement(gfx::Rect* bounds,
// track maximized state independently of sizing information.

// Restore the window's placement from the controller.
if (widget_delegate_->GetSavedWindowPlacement(bounds, show_state)) {
if (widget_delegate_->GetSavedWindowPlacement(this, bounds, show_state)) {
if (!widget_delegate_->ShouldRestoreWindowSize()) {
bounds->set_size(non_client_view_->GetPreferredSize());
} else {
Expand Down
3 changes: 2 additions & 1 deletion ui/views/widget/widget_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,15 @@ void WidgetDelegate::SaveWindowPlacement(const gfx::Rect& bounds,
}

bool WidgetDelegate::GetSavedWindowPlacement(
const Widget* widget,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const {
std::string window_name = GetWindowName();
if (!ViewsDelegate::views_delegate || window_name.empty())
return false;

return ViewsDelegate::views_delegate->GetSavedWindowPlacement(
window_name, bounds, show_state);
widget, window_name, bounds, show_state);
}

bool WidgetDelegate::ShouldRestoreWindowSize() const {
Expand Down
3 changes: 2 additions & 1 deletion ui/views/widget/widget_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ class VIEWS_EXPORT WidgetDelegate {

// Retrieves the window's bounds and "show" states.
// This behavior can be overridden to provide additional functionality.
virtual bool GetSavedWindowPlacement(gfx::Rect* bounds,
virtual bool GetSavedWindowPlacement(const Widget* widget,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const;

// Returns true if the window's size should be restored. If this is false,
Expand Down

0 comments on commit 0194049

Please sign in to comment.