Commit 5e093817 authored by Sammie Quon's avatar Sammie Quon Committed by Chromium LUCI CQ

capture_mode: Keyboard shortcuts to create/resize a region.

Add the following keyboard shortcuts to a capture session.

Space: Creates a default region 1/12th the size of the root.
Tab: Cycles through and highlights the region and affordance circles.
  Also handles events as these were affecting the top window.
Arrow keys: Shifts the region if it is focused, resizes the region if
  a affordance circle is focused.

Not in this CL:
  - moving focus to capture bar/capture button, requires those widgets
    to be focusable
  - leave focus on mouse click and start tabbing from the last mouse
    click

Bug: 1154778
Test: manual, added test
Change-Id: Ib4adf61e93bc7ad759fb33bac3185d069de0da65
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2575325
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836336}
parent 3ec3ab06
...@@ -27,6 +27,10 @@ constexpr SkColor kInkDropBaseColor = SK_ColorWHITE; ...@@ -27,6 +27,10 @@ constexpr SkColor kInkDropBaseColor = SK_ColorWHITE;
// CaptureModeBarView. // CaptureModeBarView.
constexpr int kBetweenChildSpacing = 16; constexpr int kBetweenChildSpacing = 16;
// The amount the capture region changes when using the arrow keys to adjust it.
constexpr int kArrowKeyboardRegionChangeDp = 1;
constexpr int kShiftArrowKeyboardRegionChangeDp = 10;
} // namespace capture_mode } // namespace capture_mode
} // namespace ash } // namespace ash
......
This diff is collapsed.
...@@ -217,6 +217,19 @@ class ASH_EXPORT CaptureModeSession : public ui::LayerOwner, ...@@ -217,6 +217,19 @@ class ASH_EXPORT CaptureModeSession : public ui::LayerOwner,
void EndSelection(bool is_event_on_capture_bar, void EndSelection(bool is_event_on_capture_bar,
bool region_intersects_capture_bar); bool region_intersects_capture_bar);
// Schedules a paint on the region and enough inset around it so that the
// shadow, affordance circles, etc. are all repainted.
void RepaintRegion();
// Selects a default region that is centered and whose size is a ratio of the
// root window bounds. Called when the space key is pressed.
void SelectDefaultRegion();
// Updates the region either horizontally or vertically. Called when the arrow
// keys are pressed.
void UpdateRegionHorizontally(bool left, bool is_shift_down);
void UpdateRegionVertically(bool up, bool is_shift_down);
CaptureModeController* const controller_; CaptureModeController* const controller_;
// The current root window on which the capture session is active, which may // The current root window on which the capture session is active, which may
...@@ -286,6 +299,10 @@ class ASH_EXPORT CaptureModeSession : public ui::LayerOwner, ...@@ -286,6 +299,10 @@ class ASH_EXPORT CaptureModeSession : public ui::LayerOwner,
// True if at any point during the lifetime of |this|, the capture source // True if at any point during the lifetime of |this|, the capture source
// changed. Used for metrics collection. // changed. Used for metrics collection.
bool capture_source_changed_ = false; bool capture_source_changed_ = false;
// The current focused fine tune position. This changes as user tabs while a
// in capture region mode.
FineTunePosition focused_fine_tune_position_ = FineTunePosition::kNone;
}; };
} // namespace ash } // namespace ash
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "ash/capture_mode/capture_mode_bar_view.h" #include "ash/capture_mode/capture_mode_bar_view.h"
#include "ash/capture_mode/capture_mode_button.h" #include "ash/capture_mode/capture_mode_button.h"
#include "ash/capture_mode/capture_mode_constants.h"
#include "ash/capture_mode/capture_mode_controller.h" #include "ash/capture_mode/capture_mode_controller.h"
#include "ash/capture_mode/capture_mode_metrics.h" #include "ash/capture_mode/capture_mode_metrics.h"
#include "ash/capture_mode/capture_mode_session.h" #include "ash/capture_mode/capture_mode_session.h"
...@@ -71,9 +72,11 @@ void ClickOnView(const views::View* view, ...@@ -71,9 +72,11 @@ void ClickOnView(const views::View* view,
} }
void SendKey(ui::KeyboardCode key_code, void SendKey(ui::KeyboardCode key_code,
ui::test::EventGenerator* event_generator) { ui::test::EventGenerator* event_generator,
event_generator->PressKey(key_code, /*flags=*/0); bool shift_down = false) {
event_generator->ReleaseKey(key_code, /*flags=*/0); int flags = shift_down ? ui::EF_SHIFT_DOWN : 0;
event_generator->PressKey(key_code, flags);
event_generator->ReleaseKey(key_code, flags);
} }
// Moves the mouse and updates the cursor's display manually to imitate what a // Moves the mouse and updates the cursor's display manually to imitate what a
...@@ -1945,6 +1948,68 @@ TEST_F(CaptureModeTest, ReenterOnSmallerDisplay) { ...@@ -1945,6 +1948,68 @@ TEST_F(CaptureModeTest, ReenterOnSmallerDisplay) {
EXPECT_EQ(gfx::Rect(600, 400), controller->user_capture_region()); EXPECT_EQ(gfx::Rect(600, 400), controller->user_capture_region());
} }
// Tests that functionality to create and adjust a region with keyboard
// shortcuts works as intended.
TEST_F(CaptureModeTest, SelectRegionWithKeyboard) {
auto* controller = StartImageRegionCapture();
auto* event_generator = GetEventGenerator();
ASSERT_TRUE(controller->user_capture_region().IsEmpty());
// Test that hitting space will create a default region.
SendKey(ui::VKEY_SPACE, event_generator);
gfx::Rect capture_region = controller->user_capture_region();
EXPECT_FALSE(capture_region.IsEmpty());
// Test that hitting an arrow key will do nothing as nothing is focused
// initially.
SendKey(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(capture_region, controller->user_capture_region());
const int arrow_shift = capture_mode::kArrowKeyboardRegionChangeDp;
// Hit tab so that the whole region is focused. Arrow keys should shift the
// whole region.
SendKey(ui::VKEY_TAB, event_generator);
SendKey(ui::VKEY_RIGHT, event_generator);
EXPECT_EQ(capture_region.origin() + gfx::Vector2d(arrow_shift, 0),
controller->user_capture_region().origin());
EXPECT_EQ(capture_region.size(), controller->user_capture_region().size());
SendKey(ui::VKEY_RIGHT, event_generator, /*shift_down=*/true);
EXPECT_EQ(
capture_region.origin() +
gfx::Vector2d(
arrow_shift + capture_mode::kShiftArrowKeyboardRegionChangeDp, 0),
controller->user_capture_region().origin());
EXPECT_EQ(capture_region.size(), controller->user_capture_region().size());
// Hit tab so that the top left affordance circle is focused. Left and up keys
// should enlarge the region, right and bottom keys should shrink the region.
capture_region = controller->user_capture_region();
SendKey(ui::VKEY_TAB, event_generator);
SendKey(ui::VKEY_LEFT, event_generator);
SendKey(ui::VKEY_UP, event_generator);
EXPECT_EQ(capture_region.size() + gfx::Size(arrow_shift, arrow_shift),
controller->user_capture_region().size());
SendKey(ui::VKEY_RIGHT, event_generator);
SendKey(ui::VKEY_DOWN, event_generator);
EXPECT_EQ(capture_region.size(), controller->user_capture_region().size());
// Tab until we focus the bottom right affordance circle. Left and up keys
// should shrink the region, right and bottom keys should enlarge the region.
SendKey(ui::VKEY_TAB, event_generator);
SendKey(ui::VKEY_TAB, event_generator);
SendKey(ui::VKEY_TAB, event_generator);
SendKey(ui::VKEY_TAB, event_generator);
SendKey(ui::VKEY_LEFT, event_generator);
SendKey(ui::VKEY_UP, event_generator);
EXPECT_EQ(capture_region.size() - gfx::Size(arrow_shift, arrow_shift),
controller->user_capture_region().size());
SendKey(ui::VKEY_RIGHT, event_generator);
SendKey(ui::VKEY_DOWN, event_generator);
EXPECT_EQ(capture_region.size(), controller->user_capture_region().size());
}
// A test class that uses a mock time task environment. // A test class that uses a mock time task environment.
class CaptureModeMockTimeTest : public CaptureModeTest { class CaptureModeMockTimeTest : public CaptureModeTest {
public: public:
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
#include "shell_tab_handler.h" #include "shell_tab_handler.h"
#include "ash/capture_mode/capture_mode_controller.h"
#include "ash/focus_cycler.h" #include "ash/focus_cycler.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/shelf/shelf.h" #include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_navigation_widget.h" #include "ash/shelf/shelf_navigation_widget.h"
#include "ash/shell.h" #include "ash/shell.h"
...@@ -27,6 +29,12 @@ void ShellTabHandler::OnKeyEvent(ui::KeyEvent* key_event) { ...@@ -27,6 +29,12 @@ void ShellTabHandler::OnKeyEvent(ui::KeyEvent* key_event) {
return; return;
} }
// Capture session will process their own tab events.
if (features::IsCaptureModeEnabled() &&
CaptureModeController::Get()->IsActive()) {
return;
}
aura::Window* root_window_for_new_windows = aura::Window* root_window_for_new_windows =
Shell::GetRootWindowForNewWindows(); Shell::GetRootWindowForNewWindows();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment