#include "ash/shell_window_ids.h"
#include "base/command_line.h"
#include "ui/app_list/app_list_constants.h"
+#include "ui/app_list/app_list_switches.h"
#include "ui/app_list/pagination_model.h"
#include "ui/app_list/views/app_list_view.h"
#include "ui/aura/client/focus_client.h"
-#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
+#include "ui/aura/window_event_dispatcher.h"
#include "ui/compositor/layer.h"
#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 (ash::switches::UseAlternateShelfLayout()) {
- gfx::Rect applist_button_bounds = Shelf::ForWindow(container)->
- GetAppListButtonView()->GetBoundsInScreen();
+ 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(
+ container,
+ pagination_model_.get(),
+ GetCenterOfDisplayForView(applist_button),
+ views::BubbleBorder::FLOAT,
+ true /* border_accepts_events */);
+ } 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
// handle items.
- if (!CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAshDisableDragAndDropAppListToLauncher)) {
- SetDragAndDropHostOfCurrentAppList(
- Shelf::ForWindow(window)->GetDragAndDropHostForAppList());
- }
+ SetDragAndDropHostOfCurrentAppList(
+ Shelf::ForWindow(window)->GetDragAndDropHostForAppList());
}
// Update applist button status when app list visibility is changed.
Shelf::ForWindow(window)->GetAppListButtonView()->SchedulePaint();
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);
}
void AppListController::ProcessLocatedEvent(ui::LocatedEvent* event) {
+ if (!view_ || !is_visible_)
+ return;
+
// If the event happened on a menu, then the event should not close the app
// list.
aura::Window* target = static_cast<aura::Window*>(event->target());
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;
}
}
- if (view_ && is_visible_) {
- aura::Window* window = view_->GetWidget()->GetNativeView();
- gfx::Point window_local_point(event->root_location());
- aura::Window::ConvertPointToTarget(window->GetRootWindow(),
- window,
- &window_local_point);
- // Use HitTest to respect the hit test mask of the bubble.
- if (!window->HitTest(window_local_point))
- SetVisible(false, window);
- }
+ aura::Window* window = view_->GetWidget()->GetNativeView()->parent();
+ if (!window->Contains(target))
+ SetVisible(false, window);
}
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