#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
#include "ui/gfx/transform_util.h"
+#include "ui/keyboard/keyboard_controller.h"
#include "ui/views/widget/widget.h"
namespace ash {
-namespace internal {
-
namespace {
// Duration for show/hide animation in milliseconds.
}
}
+// Gets the point at the center of the display that a particular view is on.
+// This calculation excludes the virtual keyboard area.
+gfx::Point GetCenterOfDisplayForView(const views::View* view) {
+ gfx::Rect bounds = Shell::GetScreen()->GetDisplayNearestWindow(
+ view->GetWidget()->GetNativeView()).bounds();
+
+ // If the virtual keyboard is active, subtract it from the display bounds, so
+ // that the app list is centered in the non-keyboard area of the display.
+ // (Note that work_area excludes the keyboard, but it doesn't get updated
+ // until after this function is called.)
+ keyboard::KeyboardController* keyboard_controller =
+ keyboard::KeyboardController::GetInstance();
+ if (keyboard_controller && keyboard_controller->keyboard_visible())
+ bounds.Subtract(keyboard_controller->current_keyboard_bounds());
+
+ return bounds.CenterPoint();
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
AppListController::AppListController()
: pagination_model_(new app_list::PaginationModel),
is_visible_(false),
+ is_centered_(false),
view_(NULL),
should_snap_back_(false) {
Shell::GetInstance()->AddShellObserver(this);
aura::Window* root_window = window->GetRootWindow();
aura::Window* container = GetRootWindowController(root_window)->
GetContainer(kShellWindowId_AppListContainer);
- if (app_list::switches::IsExperimentalAppListPositionEnabled()) {
- // The experimental app list is centered over the primary display.
+ views::View* applist_button =
+ Shelf::ForWindow(container)->GetAppListButtonView();
+ is_centered_ = view->ShouldCenterWindow();
+ if (is_centered_) {
+ // The experimental app list is centered over the display of the app list
+ // button that was pressed (if triggered via keyboard, this is the display
+ // with the currently focused window).
view->InitAsBubbleAtFixedLocation(
- NULL,
+ container,
pagination_model_.get(),
- Shell::GetScreen()->GetPrimaryDisplay().bounds().CenterPoint(),
+ GetCenterOfDisplayForView(applist_button),
views::BubbleBorder::FLOAT,
true /* border_accepts_events */);
- } else if (ash::switches::UseAlternateShelfLayout()) {
- gfx::Rect applist_button_bounds = Shelf::ForWindow(container)->
- GetAppListButtonView()->GetBoundsInScreen();
+ } else {
+ gfx::Rect applist_button_bounds = applist_button->GetBoundsInScreen();
// We need the location of the button within the local screen.
applist_button_bounds = ScreenUtil::ConvertRectFromScreen(
root_window,
GetBubbleArrow(container),
true /* border_accepts_events */);
view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE);
- } else {
- view->InitAsBubbleAttachedToAnchor(
- container,
- pagination_model_.get(),
- Shelf::ForWindow(container)->GetAppListButtonView(),
- gfx::Vector2d(),
- GetBubbleArrow(container),
- true /* border_accepts_events */);
}
SetView(view);
// By setting us as DnD recipient, the app list knows that we can
view_ = view;
views::Widget* widget = view_->GetWidget();
widget->AddObserver(this);
+ keyboard::KeyboardController* keyboard_controller =
+ keyboard::KeyboardController::GetInstance();
+ if (keyboard_controller)
+ keyboard_controller->AddObserver(this);
Shell::GetInstance()->AddPreTargetHandler(this);
Shelf::ForWindow(widget->GetNativeWindow())->AddIconObserver(this);
widget->GetNativeView()->GetRootWindow()->AddObserver(this);
views::Widget* widget = view_->GetWidget();
widget->RemoveObserver(this);
GetLayer(widget)->GetAnimator()->RemoveObserver(this);
+ keyboard::KeyboardController* keyboard_controller =
+ keyboard::KeyboardController::GetInstance();
+ if (keyboard_controller)
+ keyboard_controller->RemoveObserver(this);
Shell::GetInstance()->RemovePreTargetHandler(this);
Shelf::ForWindow(widget->GetNativeWindow())->RemoveIconObserver(this);
widget->GetNativeView()->GetRootWindow()->RemoveObserver(this);
RootWindowController* root_controller =
GetRootWindowController(target->GetRootWindow());
if (root_controller) {
- aura::Window* menu_container = root_controller->GetContainer(
- internal::kShellWindowId_MenuContainer);
+ aura::Window* menu_container =
+ root_controller->GetContainer(kShellWindowId_MenuContainer);
if (menu_container->Contains(target))
return;
aura::Window* keyboard_container = root_controller->GetContainer(
- internal::kShellWindowId_VirtualKeyboardContainer);
+ kShellWindowId_VirtualKeyboardContainer);
if (keyboard_container->Contains(target))
return;
}
}
void AppListController::UpdateBounds() {
- if (view_ && is_visible_)
- view_->UpdateBounds();
+ if (!view_ || !is_visible_)
+ return;
+
+ view_->UpdateBounds();
+
+ if (is_centered_)
+ view_->SetAnchorPoint(GetCenterOfDisplayForView(view_));
}
////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
+// AppListController, keyboard::KeyboardControllerObserver implementation:
+
+void AppListController::OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) {
+ UpdateBounds();
+}
+
+////////////////////////////////////////////////////////////////////////////////
// AppListController, ShellObserver implementation:
void AppListController::OnShelfAlignmentChanged(aura::Window* root_window) {
if (view_)
}
}
-} // namespace internal
} // namespace ash