| Index: ash/wm/overview/window_selector.cc
|
| diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc
|
| index 7e50d44514aa6d6469a6f6982695bb2eb100a7fd..a38bd9e8ab797e467214596498249354ed4cd396 100644
|
| --- a/ash/wm/overview/window_selector.cc
|
| +++ b/ash/wm/overview/window_selector.cc
|
| @@ -19,6 +19,7 @@
|
| #include "ash/shelf/shelf.h"
|
| #include "ash/shell.h"
|
| #include "ash/wm/mru_window_tracker.h"
|
| +#include "ash/wm/overview/overview_window_drag_controller.h"
|
| #include "ash/wm/overview/window_grid.h"
|
| #include "ash/wm/overview/window_selector_delegate.h"
|
| #include "ash/wm/overview/window_selector_item.h"
|
| @@ -137,13 +138,31 @@ void UpdateShelfVisibility() {
|
| Shelf::ForWindow(root)->UpdateVisibilityState();
|
| }
|
|
|
| +// Returns the bounds for the overview window grid according to the split view
|
| +// state. If split view mode is active, the overview window should open on the
|
| +// opposite side of the default snap window.
|
| +gfx::Rect GetGridBoundsInScreen(aura::Window* root_window) {
|
| + SplitViewController* split_view_controller =
|
| + Shell::Get()->split_view_controller();
|
| + if (split_view_controller->IsSplitViewModeActive()) {
|
| + SplitViewController::SnapPosition oppsite_position =
|
| + (split_view_controller->default_snap_position() ==
|
| + SplitViewController::LEFT)
|
| + ? SplitViewController::RIGHT
|
| + : SplitViewController::LEFT;
|
| + return split_view_controller->GetSnappedWindowBoundsInScreen(
|
| + root_window, oppsite_position);
|
| + } else {
|
| + return split_view_controller->GetDisplayWorkAreaBoundsInScreen(root_window);
|
| + }
|
| +}
|
| +
|
| gfx::Rect GetTextFilterPosition(aura::Window* root_window) {
|
| - gfx::Rect total_bounds = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
|
| - root_window->GetChildById(kShellWindowId_DefaultContainer));
|
| - ::wm::ConvertRectToScreen(root_window, &total_bounds);
|
| + const gfx::Rect total_bounds = GetGridBoundsInScreen(root_window);
|
| return gfx::Rect(
|
| - 0.5 * (total_bounds.width() -
|
| - std::min(kTextFilterWidth, total_bounds.width())),
|
| + total_bounds.x() +
|
| + 0.5 * (total_bounds.width() -
|
| + std::min(kTextFilterWidth, total_bounds.width())),
|
| total_bounds.y() + total_bounds.height() * kTextFilterTopScreenProportion,
|
| std::min(kTextFilterWidth, total_bounds.width()), kTextFilterHeight);
|
| }
|
| @@ -268,7 +287,8 @@ void WindowSelector::Init(const WindowList& windows) {
|
| // root windows that don't contain any panel windows.
|
| PanelLayoutManager::Get(root)->SetShowCalloutWidgets(false);
|
|
|
| - std::unique_ptr<WindowGrid> grid(new WindowGrid(root, windows, this));
|
| + std::unique_ptr<WindowGrid> grid(
|
| + new WindowGrid(root, windows, this, GetGridBoundsInScreen(root)));
|
| if (grid->empty())
|
| continue;
|
| num_items_ += grid->size();
|
| @@ -305,6 +325,7 @@ void WindowSelector::Init(const WindowList& windows) {
|
| UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_);
|
|
|
| Shell::Get()->activation_client()->AddObserver(this);
|
| + Shell::Get()->split_view_controller()->AddObserver(this);
|
|
|
| display::Screen::GetScreen()->AddObserver(this);
|
| Shell::Get()->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW);
|
| @@ -324,6 +345,11 @@ void WindowSelector::Shutdown() {
|
| // windows in response to work area changes from window activation.
|
| display::Screen::GetScreen()->RemoveObserver(this);
|
|
|
| + // Stop observing split view state changes before restoring window focus.
|
| + // Otherwise the activation of the window triggers OnSplitViewStateChanged()
|
| + // that will call into this function again.
|
| + Shell::Get()->split_view_controller()->RemoveObserver(this);
|
| +
|
| size_t remaining_items = 0;
|
| for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) {
|
| for (const auto& window_selector_item : window_grid->window_list())
|
| @@ -443,6 +469,52 @@ void WindowSelector::WindowClosing(WindowSelectorItem* window) {
|
| grid_list_[selected_grid_index_]->WindowClosing(window);
|
| }
|
|
|
| +void WindowSelector::SetBoundsForWindowGridsInScreen(const gfx::Rect& bounds) {
|
| + for (std::unique_ptr<WindowGrid>& grid : grid_list_)
|
| + grid->SetBoundsAndUpdatePositions(bounds);
|
| +}
|
| +
|
| +void WindowSelector::RemoveWindowSelectorItem(WindowSelectorItem* item) {
|
| + if (item->GetWindow()->HasObserver(this)) {
|
| + item->GetWindow()->RemoveObserver(this);
|
| + observed_windows_.erase(item->GetWindow());
|
| + if (item->GetWindow() == restore_focus_window_)
|
| + restore_focus_window_ = nullptr;
|
| + }
|
| +
|
| + // Remove |item| from the corresponding grid.
|
| + for (std::unique_ptr<WindowGrid>& grid : grid_list_) {
|
| + if (grid->Contains(item->GetWindow())) {
|
| + grid->RemoveItem(item);
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void WindowSelector::InitiateDrag(WindowSelectorItem* item,
|
| + const gfx::Point& location_in_screen) {
|
| + window_drag_controller_.reset(new OverviewWindowDragController(this));
|
| + window_drag_controller_->InitiateDrag(item, location_in_screen);
|
| +}
|
| +
|
| +void WindowSelector::Drag(WindowSelectorItem* item,
|
| + const gfx::Point& location_in_screen) {
|
| + DCHECK(window_drag_controller_.get());
|
| + DCHECK_EQ(item, window_drag_controller_->item());
|
| + window_drag_controller_->Drag(location_in_screen);
|
| +}
|
| +
|
| +void WindowSelector::CompleteDrag(WindowSelectorItem* item) {
|
| + DCHECK(window_drag_controller_.get());
|
| + DCHECK_EQ(item, window_drag_controller_->item());
|
| + window_drag_controller_->CompleteDrag();
|
| +}
|
| +
|
| +void WindowSelector::PositionWindows(bool animate) {
|
| + for (std::unique_ptr<WindowGrid>& grid : grid_list_)
|
| + grid->PositionWindows(animate);
|
| +}
|
| +
|
| bool WindowSelector::HandleKeyEvent(views::Textfield* sender,
|
| const ui::KeyEvent& key_event) {
|
| if (key_event.type() != ui::ET_KEY_PRESSED)
|
| @@ -511,6 +583,11 @@ void WindowSelector::OnDisplayRemoved(const display::Display& display) {
|
|
|
| void WindowSelector::OnDisplayMetricsChanged(const display::Display& display,
|
| uint32_t metrics) {
|
| + // Re-calculate the bounds for the window grids and position all the windows.
|
| + for (std::unique_ptr<WindowGrid>& grid : grid_list_) {
|
| + SetBoundsForWindowGridsInScreen(
|
| + GetGridBoundsInScreen(const_cast<aura::Window*>(grid->root_window())));
|
| + }
|
| PositionWindows(/* animate */ false);
|
| RepositionTextFilterOnDisplayMetricsChange();
|
| }
|
| @@ -573,6 +650,11 @@ void WindowSelector::OnWindowActivated(ActivationReason reason,
|
| return;
|
| }
|
|
|
| + // Do not cancel the overview mode if the window activation was caused by
|
| + // snapping window to one side of the screen.
|
| + if (Shell::Get()->IsSplitViewModeActive())
|
| + return;
|
| +
|
| // Don't restore focus on exit if a window was just activated.
|
| ResetFocusRestoreWindow(false);
|
| CancelSelection();
|
| @@ -623,13 +705,41 @@ void WindowSelector::ContentsChanged(views::Textfield* sender,
|
| Move(WindowSelector::RIGHT, false);
|
| }
|
|
|
| -aura::Window* WindowSelector::GetTextFilterWidgetWindow() {
|
| - return text_filter_widget_->GetNativeWindow();
|
| +void WindowSelector::OnSplitViewStateChanged(
|
| + SplitViewController::State previous_state,
|
| + SplitViewController::State state) {
|
| + if (state != SplitViewController::NO_SNAP) {
|
| + // Do not restore focus if a window was just snapped and activated.
|
| + ResetFocusRestoreWindow(false);
|
| + }
|
| +
|
| + if (state == SplitViewController::LEFT_SNAPPED) {
|
| + aura::Window* snapped_window =
|
| + Shell::Get()->split_view_controller()->left_window();
|
| + const gfx::Rect bounds_in_screen =
|
| + Shell::Get()->split_view_controller()->GetSnappedWindowBoundsInScreen(
|
| + snapped_window, SplitViewController::RIGHT);
|
| + SetBoundsForWindowGridsInScreen(bounds_in_screen);
|
| + } else if (state == SplitViewController::RIGHT_SNAPPED) {
|
| + aura::Window* snapped_window =
|
| + Shell::Get()->split_view_controller()->right_window();
|
| + const gfx::Rect bounds_in_screen =
|
| + Shell::Get()->split_view_controller()->GetSnappedWindowBoundsInScreen(
|
| + snapped_window, SplitViewController::LEFT);
|
| + SetBoundsForWindowGridsInScreen(bounds_in_screen);
|
| + } else {
|
| + DCHECK(state == SplitViewController::BOTH_SNAPPED ||
|
| + state == SplitViewController::NO_SNAP);
|
| + // If two windows were snapped to both sides of the screen, end overview
|
| + // mode. If split view mode was ended (e.g., one of the snapped window was
|
| + // closed or minimized / fullscreened / maximized), also end overview mode
|
| + // if overview mode is active.
|
| + CancelSelection();
|
| + }
|
| }
|
|
|
| -void WindowSelector::PositionWindows(bool animate) {
|
| - for (std::unique_ptr<WindowGrid>& grid : grid_list_)
|
| - grid->PositionWindows(animate);
|
| +aura::Window* WindowSelector::GetTextFilterWidgetWindow() {
|
| + return text_filter_widget_->GetNativeWindow();
|
| }
|
|
|
| void WindowSelector::RepositionTextFilterOnDisplayMetricsChange() {
|
|
|