summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authormukai <mukai@chromium.org>2014-12-17 19:40:39 -0800
committerCommit bot <commit-bot@chromium.org>2014-12-18 03:40:59 +0000
commit9cc85e7f6620abd70fe5518260985e26c0307961 (patch)
treef73d62d68b908e9e51a24f844717c856e5941072 /ash
parentd1f925590d2ace289cf29cfb133f968961d3f330 (diff)
downloadchromium_src-9cc85e7f6620abd70fe5518260985e26c0307961.zip
chromium_src-9cc85e7f6620abd70fe5518260985e26c0307961.tar.gz
chromium_src-9cc85e7f6620abd70fe5518260985e26c0307961.tar.bz2
Refactor partial screenshot region selector (2nd)
This is the reland of crrev.com/308508 which was reverted due to a failure of valgrind bot. Previously PartialScreenshotView is a view inside of a frameless window, which is actually problematic because it needs to deal with several window manager concepts such like mouse captures and activations. This is now built with ui::Layer and EventHandler, therefore it makes no effects. Also this CL moves the file location to a new directory ash/utility, because this is nothing related to the window manager. BUG=330348 R=oshima@chromium.org TEST=the new test covers with valgrind bot Review URL: https://codereview.chromium.org/813523002 Cr-Commit-Position: refs/heads/master@{#308942}
Diffstat (limited to 'ash')
-rw-r--r--ash/accelerators/accelerator_controller.cc4
-rw-r--r--ash/ash.gyp6
-rw-r--r--ash/utility/partial_screenshot_controller.cc266
-rw-r--r--ash/utility/partial_screenshot_controller.h93
-rw-r--r--ash/utility/partial_screenshot_controller_unittest.cc139
-rw-r--r--ash/wm/overlay_event_filter.cc1
-rw-r--r--ash/wm/partial_screenshot_view.cc245
-rw-r--r--ash/wm/partial_screenshot_view.h75
-rw-r--r--ash/wm/partial_screenshot_view_unittest.cc124
9 files changed, 503 insertions, 450 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index 8441e97..c8c9932 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -41,11 +41,11 @@
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/system/web_notification/web_notification_tray.h"
#include "ash/touch/touch_hud_debug.h"
+#include "ash/utility/partial_screenshot_controller.h"
#include "ash/volume_control_delegate.h"
#include "ash/wm/maximize_mode/maximize_mode_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/window_selector_controller.h"
-#include "ash/wm/partial_screenshot_view.h"
#include "ash/wm/power_button_controller.h"
#include "ash/wm/window_cycle_controller.h"
#include "ash/wm/window_state.h"
@@ -405,7 +405,7 @@ void HandleSwitchIme(ImeControlDelegate* ime_control_delegate,
void HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
if (screenshot_delegate) {
- ash::PartialScreenshotView::StartPartialScreenshot(
+ ash::PartialScreenshotController::StartPartialScreenshotSession(
screenshot_delegate);
}
}
diff --git a/ash/ash.gyp b/ash/ash.gyp
index ca3191b..36246b3 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -470,6 +470,8 @@
'touch/touch_uma.h',
'touch/touchscreen_util.cc',
'touch/touchscreen_util.h',
+ 'utility/partial_screenshot_controller.cc',
+ 'utility/partial_screenshot_controller.h',
'virtual_keyboard_controller.cc',
'virtual_keyboard_controller.h',
'volume_control_delegate.h',
@@ -574,8 +576,6 @@
'wm/panels/panel_window_event_handler.h',
'wm/panels/panel_window_resizer.cc',
'wm/panels/panel_window_resizer.h',
- 'wm/partial_screenshot_view.cc',
- 'wm/partial_screenshot_view.h',
'wm/power_button_controller.cc',
'wm/power_button_controller.h',
'wm/resize_handle_window_targeter.cc',
@@ -830,6 +830,7 @@
'touch/touch_observer_hud_unittest.cc',
'touch/touch_transformer_controller_unittest.cc',
'touch/touchscreen_util_unittest.cc',
+ 'utility/partial_screenshot_controller_unittest.cc',
'virtual_keyboard_controller_unittest.cc',
'wm/always_on_top_controller_unittest.cc',
'wm/app_list_controller_unittest.cc',
@@ -848,7 +849,6 @@
'wm/overview/window_selector_unittest.cc',
'wm/panels/panel_layout_manager_unittest.cc',
'wm/panels/panel_window_resizer_unittest.cc',
- 'wm/partial_screenshot_view_unittest.cc',
'wm/resize_shadow_and_cursor_unittest.cc',
'wm/screen_dimmer_unittest.cc',
'wm/stacking_controller_unittest.cc',
diff --git a/ash/utility/partial_screenshot_controller.cc b/ash/utility/partial_screenshot_controller.cc
new file mode 100644
index 0000000..286fa0d
--- /dev/null
+++ b/ash/utility/partial_screenshot_controller.cc
@@ -0,0 +1,266 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/utility/partial_screenshot_controller.h"
+
+#include <cmath>
+
+#include "ash/screenshot_delegate.h"
+#include "ash/shell.h"
+#include "ash/shell_window_ids.h"
+#include "base/stl_util.h"
+#include "ui/events/event_handler.h"
+#include "ui/gfx/canvas.h"
+#include "ui/wm/core/cursor_manager.h"
+
+namespace ash {
+
+namespace {
+
+PartialScreenshotController* instance = nullptr;
+
+// The size to increase the invalidated area in the layer to repaint. The area
+// should be slightly bigger than the actual region because the region indicator
+// rectangles are drawn outside of the selected region.
+const int kInvalidateRegionAdditionalSize = 3;
+
+} // namespace
+
+class PartialScreenshotController::PartialScreenshotLayer
+ : public ui::LayerOwner,
+ public ui::LayerDelegate {
+ public:
+ PartialScreenshotLayer(ui::Layer* parent) {
+ SetLayer(new ui::Layer(ui::LAYER_TEXTURED));
+ layer()->SetFillsBoundsOpaquely(false);
+ layer()->SetBounds(parent->bounds());
+ parent->Add(layer());
+ parent->StackAtTop(layer());
+ layer()->SetVisible(true);
+ layer()->set_delegate(this);
+ }
+ ~PartialScreenshotLayer() {}
+
+ const gfx::Rect& region() const { return region_; }
+
+ void SetRegion(const gfx::Rect& region) {
+ // Invalidates the region which covers the current and new region.
+ gfx::Rect union_rect(region_);
+ union_rect.Union(region);
+ union_rect.Inset(-kInvalidateRegionAdditionalSize,
+ -kInvalidateRegionAdditionalSize);
+ union_rect.Intersects(layer()->bounds());
+
+ region_ = region;
+ layer()->SchedulePaint(union_rect);
+ }
+
+ private:
+ // ui::LayerDelegate:
+ void OnPaintLayer(gfx::Canvas* canvas) override {
+ if (region_.IsEmpty())
+ return;
+
+ // Screenshot area representation: black rectangle with white
+ // rectangle inside. To avoid capturing these rectangles when mouse
+ // release, they should be outside of the actual capturing area.
+ gfx::Rect rect(region_);
+ rect.Inset(-1, -1);
+ canvas->DrawRect(rect, SK_ColorWHITE);
+ rect.Inset(-1, -1);
+ canvas->DrawRect(rect, SK_ColorBLACK);
+ }
+
+ void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
+
+ void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
+
+ base::Closure PrepareForLayerBoundsChange() override {
+ return base::Closure();
+ }
+
+ gfx::Rect region_;
+
+ DISALLOW_COPY_AND_ASSIGN(PartialScreenshotLayer);
+};
+
+class PartialScreenshotController::ScopedCursorSetter {
+ public:
+ ScopedCursorSetter(::wm::CursorManager* cursor_manager,
+ gfx::NativeCursor cursor)
+ : cursor_manager_(nullptr) {
+ if (cursor_manager->IsCursorLocked())
+ return;
+ gfx::NativeCursor original_cursor = cursor_manager->GetCursor();
+ cursor_manager_ = cursor_manager;
+ cursor_manager_->SetCursor(cursor);
+ cursor_manager_->LockCursor();
+ // SetCursor does not make any effects at this point but it sets back to the
+ // original cursor when unlocked.
+ cursor_manager_->SetCursor(original_cursor);
+ }
+
+ ~ScopedCursorSetter() {
+ if (cursor_manager_)
+ cursor_manager_->UnlockCursor();
+ }
+
+ private:
+ ::wm::CursorManager* cursor_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedCursorSetter);
+};
+
+// static
+void PartialScreenshotController::StartPartialScreenshotSession(
+ ScreenshotDelegate* screenshot_delegate) {
+ // Already in the session.
+ if (instance)
+ return;
+ instance = new PartialScreenshotController(screenshot_delegate);
+}
+
+// static
+PartialScreenshotController* PartialScreenshotController::GetInstanceForTest() {
+ return instance;
+}
+
+PartialScreenshotController::PartialScreenshotController(
+ ScreenshotDelegate* screenshot_delegate)
+ : root_window_(nullptr), screenshot_delegate_(screenshot_delegate) {
+ DCHECK(screenshot_delegate_);
+ Shell* shell = Shell::GetInstance();
+ shell->PrependPreTargetHandler(this);
+ shell->AddShellObserver(this);
+ Shell::GetScreen()->AddObserver(this);
+
+ for (aura::Window* root : Shell::GetAllRootWindows()) {
+ layers_[root] = new PartialScreenshotLayer(
+ Shell::GetContainer(root, kShellWindowId_OverlayContainer)->layer());
+ }
+
+ cursor_setter_.reset(
+ new ScopedCursorSetter(shell->cursor_manager(), ui::kCursorCross));
+}
+
+PartialScreenshotController::~PartialScreenshotController() {
+ DCHECK_EQ(this, instance);
+ instance = nullptr;
+
+ Shell::GetScreen()->RemoveObserver(this);
+ Shell::GetInstance()->RemovePreTargetHandler(this);
+ Shell::GetInstance()->RemoveShellObserver(this);
+ STLDeleteValues(&layers_);
+}
+
+void PartialScreenshotController::MaybeStart(const ui::LocatedEvent& event) {
+ aura::Window* current_root =
+ static_cast<aura::Window*>(event.target())->GetRootWindow();
+ if (root_window_) {
+ // It's already started. This can happen when the second finger touches
+ // the screen, or combination of the touch and mouse. We should grab the
+ // partial screenshot instead of restarting.
+ if (current_root == root_window_) {
+ Update(event);
+ Complete();
+ }
+ } else {
+ root_window_ = current_root;
+ start_position_ = event.root_location();
+ }
+}
+
+void PartialScreenshotController::Complete() {
+ const gfx::Rect& region = layers_[root_window_]->region();
+ if (!region.IsEmpty()) {
+ screenshot_delegate_->HandleTakePartialScreenshot(
+ root_window_, gfx::IntersectRects(root_window_->bounds(), region));
+ }
+ Cancel();
+}
+
+void PartialScreenshotController::Cancel() {
+ delete this;
+}
+
+void PartialScreenshotController::Update(const ui::LocatedEvent& event) {
+ // Update may happen without MaybeStart() if the partial screenshot session
+ // starts when dragging.
+ if (!root_window_)
+ MaybeStart(event);
+
+ DCHECK(layers_.find(root_window_) != layers_.end());
+ layers_[root_window_]->SetRegion(
+ gfx::Rect(std::min(start_position_.x(), event.root_location().x()),
+ std::min(start_position_.y(), event.root_location().y()),
+ ::abs(start_position_.x() - event.root_location().x()),
+ ::abs(start_position_.y() - event.root_location().y())));
+}
+
+void PartialScreenshotController::OnKeyEvent(ui::KeyEvent* event) {
+ if (event->type() == ui::ET_KEY_RELEASED &&
+ event->key_code() == ui::VKEY_ESCAPE) {
+ Cancel();
+ }
+
+ // Intercepts all key events.
+ event->StopPropagation();
+}
+
+void PartialScreenshotController::OnMouseEvent(ui::MouseEvent* event) {
+ switch (event->type()) {
+ case ui::ET_MOUSE_PRESSED:
+ MaybeStart(*event);
+ break;
+ case ui::ET_MOUSE_DRAGGED:
+ Update(*event);
+ break;
+ case ui::ET_MOUSE_RELEASED:
+ Complete();
+ break;
+ default:
+ // Do nothing.
+ break;
+ }
+ event->StopPropagation();
+}
+
+void PartialScreenshotController::OnTouchEvent(ui::TouchEvent* event) {
+ switch (event->type()) {
+ case ui::ET_TOUCH_PRESSED:
+ MaybeStart(*event);
+ break;
+ case ui::ET_TOUCH_MOVED:
+ Update(*event);
+ break;
+ case ui::ET_TOUCH_RELEASED:
+ Complete();
+ break;
+ default:
+ // Do nothing.
+ break;
+ }
+ event->StopPropagation();
+}
+
+void PartialScreenshotController::OnAppTerminating() {
+ Cancel();
+}
+
+void PartialScreenshotController::OnDisplayAdded(
+ const gfx::Display& new_display) {
+ Cancel();
+}
+
+void PartialScreenshotController::OnDisplayRemoved(
+ const gfx::Display& old_display) {
+ Cancel();
+}
+
+void PartialScreenshotController::OnDisplayMetricsChanged(
+ const gfx::Display& display,
+ uint32_t changed_metrics) {
+}
+
+} // namespace ash
diff --git a/ash/utility/partial_screenshot_controller.h b/ash/utility/partial_screenshot_controller.h
new file mode 100644
index 0000000..c1a4845
--- /dev/null
+++ b/ash/utility/partial_screenshot_controller.h
@@ -0,0 +1,93 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_UTILITY_PARTIAL_SCREENSHOT_CONTROLLER_H_
+#define ASH_UTILITY_PARTIAL_SCREENSHOT_CONTROLLER_H_
+
+#include <map>
+
+#include "ash/ash_export.h"
+#include "ash/shell_observer.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/events/event_handler.h"
+#include "ui/gfx/display_observer.h"
+#include "ui/gfx/point.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ui {
+class LocatedEvent;
+}
+
+namespace ash {
+class ScreenshotDelegate;
+
+// This class controls a session of taking partial screenshot, i.e.: drawing
+// region rectangles during drag, and changing the mouse cursor to indicate
+// the current mode.
+// This class does not use aura::Window / views::Widget intentionally to avoid
+// the conflicts of window manager features like mouse captures or window focus.
+class ASH_EXPORT PartialScreenshotController : public ui::EventHandler,
+ public ShellObserver,
+ public gfx::DisplayObserver {
+ public:
+ // Starts the UI for taking partial screenshot; dragging to select a region.
+ // PartialScreenshotController manage their own lifetime so caller must not
+ // delete the returned values.
+ static void StartPartialScreenshotSession(
+ ScreenshotDelegate* screenshot_delegate);
+
+ ~PartialScreenshotController() override;
+
+ private:
+ friend class PartialScreenshotControllerTest;
+
+ class ScopedCursorSetter;
+ class PartialScreenshotLayer;
+
+ static PartialScreenshotController* GetInstanceForTest();
+
+ PartialScreenshotController(ScreenshotDelegate* screenshot_delegate);
+
+ // Starts, ends, cancels, or updates the region selection.
+ void MaybeStart(const ui::LocatedEvent& event);
+ void Complete();
+ void Cancel();
+ void Update(const ui::LocatedEvent& event);
+
+ // ui::EventHandler:
+ void OnKeyEvent(ui::KeyEvent* event) override;
+ void OnMouseEvent(ui::MouseEvent* event) override;
+ void OnTouchEvent(ui::TouchEvent* event) override;
+
+ // ShellObserver:
+ void OnAppTerminating() override;
+
+ // gfx::DisplayObserver:
+ void OnDisplayAdded(const gfx::Display& new_display) override;
+ void OnDisplayRemoved(const gfx::Display& old_display) override;
+ void OnDisplayMetricsChanged(const gfx::Display& display,
+ uint32_t changed_metrics) override;
+
+ // The data to build the screenshot region.
+ gfx::Point start_position_;
+ aura::Window* root_window_;
+
+ // Layers to create the visual effect of region selection.
+ std::map<aura::Window*, PartialScreenshotLayer*> layers_;
+
+ // The object to specify the crosshair cursor.
+ scoped_ptr<ScopedCursorSetter> cursor_setter_;
+
+ // ScreenshotDelegate to take the actual screenshot. No ownership.
+ ScreenshotDelegate* screenshot_delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(PartialScreenshotController);
+};
+
+} // namespace ash
+
+#endif // #ifndef ASH_WM_PARTIAL_SCREENSHOT_VIEW_H_
diff --git a/ash/utility/partial_screenshot_controller_unittest.cc b/ash/utility/partial_screenshot_controller_unittest.cc
new file mode 100644
index 0000000..edd79ef
--- /dev/null
+++ b/ash/utility/partial_screenshot_controller_unittest.cc
@@ -0,0 +1,139 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/utility/partial_screenshot_controller.h"
+
+#include "ash/screenshot_delegate.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/test_screenshot_delegate.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/events/test/event_generator.h"
+
+namespace ash {
+
+class PartialScreenshotControllerTest : public test::AshTestBase {
+ public:
+ PartialScreenshotControllerTest() {}
+ ~PartialScreenshotControllerTest() override {}
+
+ void SetUp() override {
+ test::AshTestBase::SetUp();
+ PartialScreenshotController::StartPartialScreenshotSession(
+ GetScreenshotDelegate());
+ }
+
+ protected:
+ static PartialScreenshotController* GetInstance() {
+ return PartialScreenshotController::GetInstanceForTest();
+ }
+
+ const gfx::Point& GetStartPosition() const {
+ return GetInstance()->start_position_;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PartialScreenshotControllerTest);
+};
+
+TEST_F(PartialScreenshotControllerTest, BasicMouse) {
+ test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+ ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+ generator.MoveMouseTo(100, 100);
+ generator.PressLeftButton();
+ EXPECT_EQ("100,100", GetStartPosition().ToString());
+ EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+
+ generator.MoveMouseTo(200, 200);
+ EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+
+ generator.ReleaseLeftButton();
+ EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
+ EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
+
+ RunAllPendingInMessageLoop();
+ EXPECT_EQ(nullptr, GetInstance());
+}
+
+TEST_F(PartialScreenshotControllerTest, JustClick) {
+ test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+ ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+ generator.MoveMouseTo(100, 100);
+
+ // No moves, just clicking at the same position.
+ generator.ClickLeftButton();
+ EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+
+ RunAllPendingInMessageLoop();
+ EXPECT_EQ(nullptr, GetInstance());
+}
+
+TEST_F(PartialScreenshotControllerTest, BasicTouch) {
+ test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+ ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+ generator.set_current_location(gfx::Point(100, 100));
+ generator.PressTouch();
+ EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+ EXPECT_EQ("100,100", GetStartPosition().ToString());
+
+ generator.MoveTouch(gfx::Point(200, 200));
+ EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+
+ generator.ReleaseTouch();
+ EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
+ EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
+
+ RunAllPendingInMessageLoop();
+ EXPECT_EQ(nullptr, GetInstance());
+}
+
+TEST_F(PartialScreenshotControllerTest, TwoFingerTouch) {
+ test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+ ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+ generator.set_current_location(gfx::Point(100, 100));
+ generator.PressTouch();
+ EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+ EXPECT_EQ("100,100", GetStartPosition().ToString());
+
+ generator.set_current_location(gfx::Point(200, 200));
+ generator.PressTouchId(1);
+ EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
+ EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
+
+ RunAllPendingInMessageLoop();
+ EXPECT_EQ(nullptr, GetInstance());
+}
+
+TEST_F(PartialScreenshotControllerTest, DontStartTwice) {
+ PartialScreenshotController* controller = GetInstance();
+
+ PartialScreenshotController::StartPartialScreenshotSession(
+ GetScreenshotDelegate());
+
+ // The same instance.
+ EXPECT_EQ(controller, GetInstance());
+}
+
+TEST_F(PartialScreenshotControllerTest, MultipleDisplays) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ EXPECT_NE(nullptr, GetInstance());
+ UpdateDisplay("400x400,500x500");
+ RunAllPendingInMessageLoop();
+ EXPECT_EQ(nullptr, GetInstance());
+
+ PartialScreenshotController::StartPartialScreenshotSession(
+ GetScreenshotDelegate());
+ EXPECT_NE(nullptr, GetInstance());
+ UpdateDisplay("400x400");
+ RunAllPendingInMessageLoop();
+ EXPECT_EQ(nullptr, GetInstance());
+}
+
+} // namespace ash
diff --git a/ash/wm/overlay_event_filter.cc b/ash/wm/overlay_event_filter.cc
index 03c4947..b349bf9 100644
--- a/ash/wm/overlay_event_filter.cc
+++ b/ash/wm/overlay_event_filter.cc
@@ -4,7 +4,6 @@
#include "ash/wm/overlay_event_filter.h"
-#include "ash/wm/partial_screenshot_view.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/events/event.h"
diff --git a/ash/wm/partial_screenshot_view.cc b/ash/wm/partial_screenshot_view.cc
deleted file mode 100644
index 233a286..0000000
--- a/ash/wm/partial_screenshot_view.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/partial_screenshot_view.h"
-
-#include <algorithm>
-
-#include "ash/display/mouse_cursor_event_filter.h"
-#include "ash/screenshot_delegate.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/wm/overlay_event_filter.h"
-#include "ui/aura/client/capture_client.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/base/cursor/cursor.h"
-#include "ui/events/event.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/rect.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
-
-namespace ash {
-
-// A self-owned object to handle the cancel and the finish of current partial
-// screenshot session.
-class PartialScreenshotView::OverlayDelegate
- : public OverlayEventFilter::Delegate,
- public views::WidgetObserver {
- public:
- OverlayDelegate() {
- Shell::GetInstance()->overlay_filter()->Activate(this);
- }
-
- void RegisterWidget(views::Widget* widget) {
- widgets_.push_back(widget);
- widget->AddObserver(this);
- }
-
- // Overridden from OverlayEventFilter::Delegate:
- void Cancel() override {
- // Make sure the mouse_warp_mode allows warping. It can be stopped by a
- // partial screenshot view.
- MouseCursorEventFilter* mouse_cursor_filter =
- Shell::GetInstance()->mouse_cursor_filter();
- mouse_cursor_filter->set_mouse_warp_mode(
- MouseCursorEventFilter::WARP_ALWAYS);
- for (size_t i = 0; i < widgets_.size(); ++i)
- widgets_[i]->Close();
- }
-
- bool IsCancelingKeyEvent(ui::KeyEvent* event) override {
- return event->key_code() == ui::VKEY_ESCAPE;
- }
-
- aura::Window* GetWindow() override {
- // Just returns NULL because this class does not handle key events in
- // OverlayEventFilter, except for cancel keys.
- return NULL;
- }
-
- // Overridden from views::WidgetObserver:
- void OnWidgetDestroying(views::Widget* widget) override {
- widget->RemoveObserver(this);
- widgets_.erase(std::remove(widgets_.begin(), widgets_.end(), widget));
- if (widgets_.empty())
- delete this;
- }
-
- private:
- ~OverlayDelegate() override {
- Shell::GetInstance()->overlay_filter()->Deactivate(this);
- }
-
- std::vector<views::Widget*> widgets_;
-
- DISALLOW_COPY_AND_ASSIGN(OverlayDelegate);
-};
-
-// static
-std::vector<PartialScreenshotView*>
-PartialScreenshotView::StartPartialScreenshot(
- ScreenshotDelegate* screenshot_delegate) {
- std::vector<PartialScreenshotView*> views;
-
- if (Shell::GetInstance()->overlay_filter()->IsActive())
- return views;
-
- OverlayDelegate* overlay_delegate = new OverlayDelegate();
- aura::Window::Windows root_windows = Shell::GetAllRootWindows();
- for (aura::Window::Windows::iterator it = root_windows.begin();
- it != root_windows.end(); ++it) {
- PartialScreenshotView* new_view = new PartialScreenshotView(
- overlay_delegate, screenshot_delegate);
- new_view->Init(*it);
- views.push_back(new_view);
- }
- return views;
-}
-
-PartialScreenshotView::PartialScreenshotView(
- PartialScreenshotView::OverlayDelegate* overlay_delegate,
- ScreenshotDelegate* screenshot_delegate)
- : is_dragging_(false),
- overlay_delegate_(overlay_delegate),
- screenshot_delegate_(screenshot_delegate) {
-}
-
-PartialScreenshotView::~PartialScreenshotView() {
- overlay_delegate_ = NULL;
- screenshot_delegate_ = NULL;
-}
-
-void PartialScreenshotView::Init(aura::Window* root_window) {
- views::Widget* widget = new views::Widget;
- views::Widget::InitParams params(
- views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
- params.delegate = this;
- // The partial screenshot rectangle has to be at the real top of
- // the screen.
- params.parent =
- Shell::GetContainer(root_window, kShellWindowId_OverlayContainer);
-
- widget->Init(params);
- widget->SetContentsView(this);
- widget->SetBounds(root_window->GetBoundsInScreen());
- widget->GetNativeView()->SetName("PartialScreenshotView");
- widget->StackAtTop();
- widget->Show();
- // Releases the mouse capture to let mouse events come to the view. This
- // will close the context menu.
- aura::client::CaptureClient* capture_client =
- aura::client::GetCaptureClient(root_window);
- if (capture_client->GetCaptureWindow())
- capture_client->ReleaseCapture(capture_client->GetCaptureWindow());
-
- overlay_delegate_->RegisterWidget(widget);
-}
-
-gfx::Rect PartialScreenshotView::GetScreenshotRect() const {
- int left = std::min(start_position_.x(), current_position_.x());
- int top = std::min(start_position_.y(), current_position_.y());
- int width = ::abs(start_position_.x() - current_position_.x());
- int height = ::abs(start_position_.y() - current_position_.y());
- return gfx::Rect(left, top, width, height);
-}
-
-void PartialScreenshotView::OnSelectionStarted(const gfx::Point& position) {
- start_position_ = position;
-}
-
-void PartialScreenshotView::OnSelectionChanged(const gfx::Point& position) {
- if (is_dragging_ && current_position_ == position)
- return;
- current_position_ = position;
- SchedulePaint();
- is_dragging_ = true;
-}
-
-void PartialScreenshotView::OnSelectionFinished() {
- overlay_delegate_->Cancel();
- if (!is_dragging_)
- return;
-
- is_dragging_ = false;
- if (screenshot_delegate_) {
- aura::Window*root_window =
- GetWidget()->GetNativeWindow()->GetRootWindow();
- screenshot_delegate_->HandleTakePartialScreenshot(
- root_window,
- gfx::IntersectRects(root_window->bounds(), GetScreenshotRect()));
- }
-}
-
-gfx::NativeCursor PartialScreenshotView::GetCursor(
- const ui::MouseEvent& event) {
- // Always use "crosshair" cursor.
- return ui::kCursorCross;
-}
-
-void PartialScreenshotView::OnPaint(gfx::Canvas* canvas) {
- if (is_dragging_) {
- // Screenshot area representation: black rectangle with white
- // rectangle inside. To avoid capturing these rectangles when mouse
- // release, they should be outside of the actual capturing area.
- gfx::Rect screenshot_rect = GetScreenshotRect();
- screenshot_rect.Inset(-1, -1, -1, -1);
- canvas->DrawRect(screenshot_rect, SK_ColorWHITE);
- screenshot_rect.Inset(-1, -1, -1, -1);
- canvas->DrawRect(screenshot_rect, SK_ColorBLACK);
- }
-}
-
-bool PartialScreenshotView::OnMousePressed(const ui::MouseEvent& event) {
- // Prevent moving across displays during drag. Capturing a screenshot across
- // the displays is not supported yet.
- // TODO(mukai): remove this restriction.
- MouseCursorEventFilter* mouse_cursor_filter =
- Shell::GetInstance()->mouse_cursor_filter();
- mouse_cursor_filter->set_mouse_warp_mode(MouseCursorEventFilter::WARP_NONE);
- OnSelectionStarted(event.location());
- return true;
-}
-
-bool PartialScreenshotView::OnMouseDragged(const ui::MouseEvent& event) {
- OnSelectionChanged(event.location());
- return true;
-}
-
-bool PartialScreenshotView::OnMouseWheel(const ui::MouseWheelEvent& event) {
- // Do nothing but do not propagate events futhermore.
- return true;
-}
-
-void PartialScreenshotView::OnMouseReleased(const ui::MouseEvent& event) {
- OnSelectionFinished();
-}
-
-void PartialScreenshotView::OnMouseCaptureLost() {
- is_dragging_ = false;
- OnSelectionFinished();
-}
-
-void PartialScreenshotView::OnGestureEvent(ui::GestureEvent* event) {
- switch(event->type()) {
- case ui::ET_GESTURE_TAP_DOWN:
- OnSelectionStarted(event->location());
- break;
- case ui::ET_GESTURE_SCROLL_UPDATE:
- OnSelectionChanged(event->location());
- break;
- case ui::ET_GESTURE_SCROLL_END:
- case ui::ET_SCROLL_FLING_START:
- OnSelectionFinished();
- break;
- default:
- break;
- }
-
- event->SetHandled();
-}
-
-} // namespace ash
diff --git a/ash/wm/partial_screenshot_view.h b/ash/wm/partial_screenshot_view.h
deleted file mode 100644
index 71e0242..0000000
--- a/ash/wm/partial_screenshot_view.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WM_PARTIAL_SCREENSHOT_VIEW_H_
-#define ASH_WM_PARTIAL_SCREENSHOT_VIEW_H_
-
-#include <vector>
-
-#include "ash/ash_export.h"
-#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "ui/gfx/point.h"
-#include "ui/views/widget/widget_delegate.h"
-
-namespace ash {
-class ScreenshotDelegate;
-
-// The view of taking partial screenshot, i.e.: drawing region
-// rectangles during drag, and changing the mouse cursor to indicate
-// the current mode.
-class ASH_EXPORT PartialScreenshotView : public views::WidgetDelegateView {
- public:
- // Starts the UI for taking partial screenshot; dragging to select a region.
- // PartialScreenshotViews manage their own lifetime so caller must not delete
- // the returned PartialScreenshotViews.
- static std::vector<PartialScreenshotView*>
- StartPartialScreenshot(ScreenshotDelegate* screenshot_delegate);
-
- private:
- FRIEND_TEST_ALL_PREFIXES(PartialScreenshotViewTest, BasicMouse);
- FRIEND_TEST_ALL_PREFIXES(PartialScreenshotViewTest, BasicTouch);
-
- class OverlayDelegate;
-
- PartialScreenshotView(OverlayDelegate* overlay_delegate,
- ScreenshotDelegate* screenshot_delegate);
- ~PartialScreenshotView() override;
-
- // Initializes partial screenshot UI widget for |root_window|.
- void Init(aura::Window* root_window);
-
- // Returns the currently selected region.
- gfx::Rect GetScreenshotRect() const;
-
- void OnSelectionStarted(const gfx::Point& position);
- void OnSelectionChanged(const gfx::Point& position);
- void OnSelectionFinished();
-
- // Overridden from views::View:
- gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override;
- void OnPaint(gfx::Canvas* canvas) override;
- bool OnMousePressed(const ui::MouseEvent& event) override;
- bool OnMouseDragged(const ui::MouseEvent& event) override;
- bool OnMouseWheel(const ui::MouseWheelEvent& event) override;
- void OnMouseReleased(const ui::MouseEvent& event) override;
- void OnMouseCaptureLost() override;
- void OnGestureEvent(ui::GestureEvent* event) override;
-
- bool is_dragging_;
- gfx::Point start_position_;
- gfx::Point current_position_;
-
- // The delegate to receive Cancel. No ownership.
- OverlayDelegate* overlay_delegate_;
-
- // ScreenshotDelegate to take the actual screenshot. No ownership.
- ScreenshotDelegate* screenshot_delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(PartialScreenshotView);
-};
-
-} // namespace ash
-
-#endif // #ifndef ASH_WM_PARTIAL_SCREENSHOT_VIEW_H_
diff --git a/ash/wm/partial_screenshot_view_unittest.cc b/ash/wm/partial_screenshot_view_unittest.cc
deleted file mode 100644
index 7ad5205..0000000
--- a/ash/wm/partial_screenshot_view_unittest.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/wm/partial_screenshot_view.h"
-
-#include "ash/screenshot_delegate.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/test/test_overlay_delegate.h"
-#include "ash/test/test_screenshot_delegate.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/events/test/event_generator.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
-
-namespace ash {
-
-class PartialScreenshotViewTest : public test::AshTestBase,
- public views::WidgetObserver {
- public:
- PartialScreenshotViewTest() : view_(NULL) {}
- ~PartialScreenshotViewTest() override {
- if (view_)
- view_->GetWidget()->RemoveObserver(this);
- }
-
- void StartPartialScreenshot() {
- std::vector<PartialScreenshotView*> views =
- PartialScreenshotView::StartPartialScreenshot(GetScreenshotDelegate());
- if (!views.empty()) {
- view_ = views[0];
- view_->GetWidget()->AddObserver(this);
- }
- }
-
- protected:
- PartialScreenshotView* view_;
-
- private:
- // views::WidgetObserver:
- void OnWidgetDestroying(views::Widget* widget) override {
- if (view_ && view_->GetWidget() == widget)
- view_ = NULL;
- widget->RemoveObserver(this);
- }
-
- DISALLOW_COPY_AND_ASSIGN(PartialScreenshotViewTest);
-};
-
-TEST_F(PartialScreenshotViewTest, BasicMouse) {
- StartPartialScreenshot();
- ASSERT_TRUE(view_);
-
- ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
-
- generator.MoveMouseTo(100, 100);
- generator.PressLeftButton();
- EXPECT_FALSE(view_->is_dragging_);
- EXPECT_EQ("100,100", view_->start_position_.ToString());
-
- generator.MoveMouseTo(200, 200);
- EXPECT_TRUE(view_->is_dragging_);
- EXPECT_EQ("200,200", view_->current_position_.ToString());
-
- generator.ReleaseLeftButton();
- EXPECT_FALSE(view_->is_dragging_);
- EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
- EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
-}
-
-TEST_F(PartialScreenshotViewTest, BasicTouch) {
- StartPartialScreenshot();
- ASSERT_TRUE(view_);
-
- ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
-
- generator.set_current_location(gfx::Point(100,100));
- generator.GestureTapDownAndUp(gfx::Point(100,100));
- EXPECT_FALSE(view_->is_dragging_);
- EXPECT_EQ(0, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
-
- generator.PressTouch();
- EXPECT_FALSE(view_->is_dragging_);
- EXPECT_EQ("100,100", view_->start_position_.ToString());
-
- generator.MoveTouch(gfx::Point(200, 200));
- EXPECT_TRUE(view_->is_dragging_);
- EXPECT_EQ("200,200", view_->current_position_.ToString());
-
- generator.ReleaseTouch();
- EXPECT_FALSE(view_->is_dragging_);
- EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
- EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
-}
-
-// Partial screenshot session should not start when there is already another
-// overlay. See: http://crbug.com/341958
-TEST_F(PartialScreenshotViewTest, DontStartOverOverlay) {
- OverlayEventFilter* overlay_filter = Shell::GetInstance()->overlay_filter();
- test::TestOverlayDelegate delegate;
- overlay_filter->Activate(&delegate);
- EXPECT_EQ(&delegate, overlay_filter->delegate_);
-
- StartPartialScreenshot();
- EXPECT_TRUE(view_ == NULL);
- EXPECT_EQ(&delegate, overlay_filter->delegate_);
- overlay_filter->Deactivate(&delegate);
-
- StartPartialScreenshot();
- EXPECT_TRUE(view_ != NULL);
-
- // Someone else attempts to activate the overlay session, which should cancel
- // the current partial screenshot session.
- overlay_filter->Activate(&delegate);
- RunAllPendingInMessageLoop();
- EXPECT_EQ(&delegate, overlay_filter->delegate_);
- EXPECT_TRUE(view_ == NULL);
-
- overlay_filter->Deactivate(&delegate);
-}
-
-} // namespace ash