Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ash / wm / app_list_controller.cc
index 560f004..45915c4 100644 (file)
 #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.
@@ -114,6 +114,24 @@ gfx::Vector2d GetAnchorPositionOffsetToShelf(
   }
 }
 
+// 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
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -122,6 +140,7 @@ gfx::Vector2d GetAnchorPositionOffsetToShelf(
 AppListController::AppListController()
     : pagination_model_(new app_list::PaginationModel),
       is_visible_(false),
+      is_centered_(false),
       view_(NULL),
       should_snap_back_(false) {
   Shell::GetInstance()->AddShellObserver(this);
@@ -166,9 +185,21 @@ void AppListController::SetVisible(bool visible, aura::Window* window) {
     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,
@@ -183,23 +214,12 @@ void AppListController::SetVisible(bool visible, aura::Window* 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();
@@ -229,6 +249,10 @@ void AppListController::SetView(app_list::AppListView* view) {
   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);
@@ -244,6 +268,10 @@ void AppListController::ResetView() {
   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);
@@ -279,6 +307,9 @@ void AppListController::ScheduleAnimation() {
 }
 
 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());
@@ -286,32 +317,30 @@ void AppListController::ProcessLocatedEvent(ui::LocatedEvent* event) {
     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_));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -372,6 +401,13 @@ void AppListController::OnWidgetDestroying(views::Widget* widget) {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// 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_)
@@ -435,5 +471,4 @@ void AppListController::TransitionChanged() {
   }
 }
 
-}  // namespace internal
 }  // namespace ash