Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / app_list / linux / app_list_linux.cc
index 0389aa8..e513121 100644 (file)
@@ -4,38 +4,61 @@
 
 #include "chrome/browser/ui/views/app_list/linux/app_list_linux.h"
 
-#include "base/command_line.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_list/app_list_positioner.h"
 #include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/views/app_list_view.h"
 #include "ui/gfx/screen.h"
+#include "ui/views/linux_ui/linux_ui.h"
 #include "ui/views/widget/widget.h"
 
-AppListLinux::AppListLinux(app_list::AppListView* view,
-                           const base::Closure& on_should_dismiss)
-    : view_(view),
-      window_icon_updated_(false),
-      on_should_dismiss_(on_should_dismiss) {
-  view_->AddObserver(this);
-}
+// static
+AppListPositioner::ScreenEdge AppListLinux::ShelfLocationInDisplay(
+    const gfx::Display& display) {
+  // On Linux, it is difficult to find the shelf (due to the large variety of
+  // desktop environments). The shelf can usually be found on the edge where the
+  // display edge and work area do not match up, but there can be more than one
+  // such edge. The shelf is assumed to be on the side of the screen with the
+  // largest delta between the display edge and the work area edge. Ties are
+  // broken in the order: top, left, right, bottom.
+  const gfx::Rect work_area = display.work_area();
+  const gfx::Rect display_bounds = display.bounds();
+
+  int winning_margin = 0;
+  AppListPositioner::ScreenEdge winning_edge =
+      AppListPositioner::SCREEN_EDGE_UNKNOWN;
+
+  if (work_area.y() - display_bounds.y() > winning_margin) {
+    winning_margin = work_area.y() - display_bounds.y();
+    winning_edge = AppListPositioner::SCREEN_EDGE_TOP;
+  }
+
+  if (work_area.x() - display_bounds.x() > winning_margin) {
+    winning_margin = work_area.x() - display_bounds.x();
+    winning_edge = AppListPositioner::SCREEN_EDGE_LEFT;
+  }
+
+  if (display_bounds.right() - work_area.right() > winning_margin) {
+    winning_margin = display_bounds.right() - work_area.right();
+    winning_edge = AppListPositioner::SCREEN_EDGE_RIGHT;
+  }
 
-AppListLinux::~AppListLinux() {
-  view_->RemoveObserver(this);
+  if (display_bounds.bottom() - work_area.bottom() > winning_margin) {
+    winning_margin = display_bounds.bottom() - work_area.bottom();
+    winning_edge = AppListPositioner::SCREEN_EDGE_BOTTOM;
+  }
+
+  return winning_edge;
 }
 
 // static
 gfx::Point AppListLinux::FindAnchorPoint(const gfx::Size& view_size,
                                          const gfx::Display& display,
                                          const gfx::Point& cursor,
-                                         AppListPositioner::ScreenEdge edge) {
+                                         AppListPositioner::ScreenEdge edge,
+                                         bool center_window) {
   AppListPositioner positioner(display, view_size, 0);
 
-  // The experimental app list is placed in the center of the screen.
-  if (app_list::switches::IsExperimentalAppListPositionEnabled())
+  // Special case for app list in the center of the screen.
+  if (center_window)
     return positioner.GetAnchorPointForScreenCenter();
 
   gfx::Point anchor;
@@ -58,61 +81,30 @@ gfx::Point AppListLinux::FindAnchorPoint(const gfx::Size& view_size,
   return positioner.GetAnchorPointForShelfCursor(edge, cursor);
 }
 
-void AppListLinux::Show() {
-  view_->GetWidget()->Show();
-  if (!window_icon_updated_) {
-    view_->GetWidget()->GetTopLevelWidget()->UpdateWindowIcon();
-    window_icon_updated_ = true;
-  }
-  view_->GetWidget()->Activate();
-}
-
-void AppListLinux::Hide() {
-  view_->GetWidget()->Hide();
-}
-
-void AppListLinux::MoveNearCursor() {
+// static
+void AppListLinux::MoveNearCursor(app_list::AppListView* view) {
   gfx::Point cursor = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
   gfx::Screen* screen =
-      gfx::Screen::GetScreenFor(view_->GetWidget()->GetNativeView());
+      gfx::Screen::GetScreenFor(view->GetWidget()->GetNativeView());
   gfx::Display display = screen->GetDisplayNearestPoint(cursor);
 
-  view_->SetBubbleArrow(views::BubbleBorder::FLOAT);
-  // Find which edge of the screen the shelf is attached to. For now, just
-  // assume Ubuntu Unity (fixed to left edge).
-  // TODO(mgiuca): Support other window manager configurations, and multiple
-  // monitors (where the current display may not have an edge).
-  AppListPositioner::ScreenEdge edge = AppListPositioner::SCREEN_EDGE_LEFT;
-  view_->SetAnchorPoint(FindAnchorPoint(view_->GetPreferredSize(), display,
-                                        cursor, edge));
-}
-
-bool AppListLinux::IsVisible() {
-  return view_->GetWidget()->IsVisible();
-}
-
-void AppListLinux::Prerender() {
-  view_->Prerender();
-}
-
-void AppListLinux::ReactivateOnNextFocusLoss() {
-  // This is only used on Windows 8, so we ignore it on Linux.
-}
-
-gfx::NativeWindow AppListLinux::GetWindow() {
-  return view_->GetWidget()->GetNativeWindow();
-}
-
-void AppListLinux::SetProfile(Profile* profile) {
-  view_->SetProfileByPath(profile->GetPath());
-}
-
-void AppListLinux::OnActivationChanged(
-    views::Widget* /*widget*/, bool active) {
-  if (active)
-    return;
-
-  // Call |on_should_dismiss_| asynchronously. This must be done asynchronously
-  // or our caller will crash, as it expects the app list to remain alive.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, on_should_dismiss_);
+  view->SetBubbleArrow(views::BubbleBorder::FLOAT);
+
+  // In the Unity desktop environment, special case SCREEN_EDGE_LEFT. It is
+  // always on the left side in Unity, but ShelfLocationInDisplay will not
+  // detect this if the shelf is hidden.
+  // TODO(mgiuca): Apply this special case in Gnome Shell also. The same logic
+  // applies, but we currently have no way to detect whether Gnome Shell is
+  // running.
+  views::LinuxUI* ui = views::LinuxUI::instance();
+  AppListPositioner::ScreenEdge edge;
+  if (ui && ui->UnityIsRunning())
+    edge = AppListPositioner::SCREEN_EDGE_LEFT;
+  else
+    edge = ShelfLocationInDisplay(display);
+  view->SetAnchorPoint(FindAnchorPoint(view->GetPreferredSize(),
+                                       display,
+                                       cursor,
+                                       edge,
+                                       view->ShouldCenterWindow()));
 }