Commit e2151716 authored by David Black's avatar David Black Committed by Commit Bot

Paste as plain text from ClipboardHistory when pressing shift.

Previously, it was not possible to paste as plain text when pasting via
the clipboard history feature. After this change, it is possible to
paste as plain text by holding down the shift key when selecting a
history item to paste.

Bug: 1114774
Change-Id: I6f74cdb3f3915074be8be5562b36850e44477f67
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2348294
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarAndrew Xu <andrewxu@chromium.org>
Reviewed-by: default avatarDarwin Huang <huangdarwin@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarRobert Liao <robliao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797926}
parent 8cade3e0
...@@ -63,11 +63,10 @@ ui::ImageModel GetImageModelForClipboardData(const ui::ClipboardData& item) { ...@@ -63,11 +63,10 @@ ui::ImageModel GetImageModelForClipboardData(const ui::ClipboardData& item) {
return ui::ImageModel(); return ui::ImageModel();
} }
void WriteClipboardDataToClipboard(const ui::ClipboardData& data) { ui::ClipboardNonBacked* GetClipboard() {
auto* clipboard = ui::ClipboardNonBacked::GetForCurrentThread(); auto* clipboard = ui::ClipboardNonBacked::GetForCurrentThread();
CHECK(clipboard); DCHECK(clipboard);
return clipboard;
clipboard->WriteClipboardData(std::make_unique<ui::ClipboardData>(data));
} }
} // namespace } // namespace
...@@ -96,7 +95,7 @@ class ClipboardHistoryController::AcceleratorTarget ...@@ -96,7 +95,7 @@ class ClipboardHistoryController::AcceleratorTarget
// ui::AcceleratorTarget: // ui::AcceleratorTarget:
bool AcceleratorPressed(const ui::Accelerator& accelerator) override { bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
if (controller_->IsMenuShowing()) if (controller_->IsMenuShowing())
controller_->ExecuteSelectedMenuItem(); controller_->ExecuteSelectedMenuItem(accelerator.modifiers());
else else
controller_->ShowMenu(); controller_->ShowMenu();
return true; return true;
...@@ -122,7 +121,7 @@ class ClipboardHistoryController::MenuDelegate ...@@ -122,7 +121,7 @@ class ClipboardHistoryController::MenuDelegate
// ui::SimpleMenuModel::Delegate: // ui::SimpleMenuModel::Delegate:
void ExecuteCommand(int command_id, int event_flags) override { void ExecuteCommand(int command_id, int event_flags) override {
controller_->MenuOptionSelected(/*index=*/command_id); controller_->MenuOptionSelected(/*index=*/command_id, event_flags);
} }
private: private:
...@@ -155,19 +154,16 @@ bool ClipboardHistoryController::CanShowMenu() const { ...@@ -155,19 +154,16 @@ bool ClipboardHistoryController::CanShowMenu() const {
return !clipboard_history_->IsEmpty(); return !clipboard_history_->IsEmpty();
} }
void ClipboardHistoryController::ExecuteSelectedMenuItem() { void ClipboardHistoryController::ExecuteSelectedMenuItem(int event_flags) {
DCHECK(IsMenuShowing()); DCHECK(IsMenuShowing());
auto command = context_menu_->GetSelectedMenuItemCommand(); auto command = context_menu_->GetSelectedMenuItemCommand();
// TODO(crbug.com/1106849): Update once sequential paste is supported.
// Force close the context menu. Failure to do so before dispatching our // Force close the context menu. Failure to do so before dispatching our
// synthetic key event will result in the context menu consuming the event. // synthetic key event will result in the context menu consuming the event.
// Currently we don't support sequential copy-paste. Once we do, we'll have to
// update this logic.
context_menu_->Cancel(); context_menu_->Cancel();
// If no menu item is currently selected, we'll fallback to the first item. // If no menu item is currently selected, we'll fallback to the first item.
menu_delegate_->ExecuteCommand(command.value_or(0), ui::EF_NONE); menu_delegate_->ExecuteCommand(command.value_or(0), event_flags);
} }
void ClipboardHistoryController::ShowMenu() { void ClipboardHistoryController::ShowMenu() {
...@@ -200,7 +196,8 @@ void ClipboardHistoryController::ShowMenu() { ...@@ -200,7 +196,8 @@ void ClipboardHistoryController::ShowMenu() {
context_menu_->Run(CalculateAnchorRect()); context_menu_->Run(CalculateAnchorRect());
} }
void ClipboardHistoryController::MenuOptionSelected(int index) { void ClipboardHistoryController::MenuOptionSelected(int index,
int event_flags) {
auto it = clipboard_items_.begin(); auto it = clipboard_items_.begin();
std::advance(it, index); std::advance(it, index);
...@@ -210,14 +207,25 @@ void ClipboardHistoryController::MenuOptionSelected(int index) { ...@@ -210,14 +207,25 @@ void ClipboardHistoryController::MenuOptionSelected(int index) {
return; return;
} }
// Pause clipboard history when manipulating the clipboard for the purpose of auto* clipboard = GetClipboard();
// a paste. std::unique_ptr<ui::ClipboardData> original_data;
ClipboardHistory::ScopedPause scoped_pause(clipboard_history_.get());
// If necessary, replace the clipboard's |original_data| temporarily so that
// Place the selected item on top of the clipboard. // we can paste the selected history item.
const bool selected_item_not_on_top = it != clipboard_items_.begin(); const bool shift_key_pressed = event_flags & ui::EF_SHIFT_DOWN;
if (selected_item_not_on_top) if (shift_key_pressed || *it != *clipboard->GetClipboardData()) {
WriteClipboardDataToClipboard(*it); std::unique_ptr<ui::ClipboardData> temp_data;
if (shift_key_pressed) {
// When the shift key is pressed, we only paste plain text.
temp_data = std::make_unique<ui::ClipboardData>();
temp_data->set_text(it->text());
} else {
temp_data = std::make_unique<ui::ClipboardData>(*it);
}
// Pause clipboard history when manipulating the clipboard for a paste.
ClipboardHistory::ScopedPause scoped_pause(clipboard_history_.get());
original_data = clipboard->WriteClipboardData(std::move(temp_data));
}
ui::KeyEvent synthetic_key_event(ui::ET_KEY_PRESSED, ui::VKEY_V, ui::KeyEvent synthetic_key_event(ui::ET_KEY_PRESSED, ui::VKEY_V,
static_cast<ui::DomCode>(0), static_cast<ui::DomCode>(0),
...@@ -227,7 +235,7 @@ void ClipboardHistoryController::MenuOptionSelected(int index) { ...@@ -227,7 +235,7 @@ void ClipboardHistoryController::MenuOptionSelected(int index) {
DCHECK(host); DCHECK(host);
host->DeliverEventToSink(&synthetic_key_event); host->DeliverEventToSink(&synthetic_key_event);
if (!selected_item_not_on_top) if (!original_data)
return; return;
// Replace the original item back on top of the clipboard. Some apps take a // Replace the original item back on top of the clipboard. Some apps take a
...@@ -238,7 +246,7 @@ void ClipboardHistoryController::MenuOptionSelected(int index) { ...@@ -238,7 +246,7 @@ void ClipboardHistoryController::MenuOptionSelected(int index) {
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(
[](const base::WeakPtr<ClipboardHistoryController>& weak_ptr, [](const base::WeakPtr<ClipboardHistoryController>& weak_ptr,
ui::ClipboardData clipboard_data) { std::unique_ptr<ui::ClipboardData> original_data) {
// When restoring the original item back on top of the clipboard we // When restoring the original item back on top of the clipboard we
// need to pause clipboard history. Failure to do so will result in // need to pause clipboard history. Failure to do so will result in
// the original item being re-recorded when this restoration step // the original item being re-recorded when this restoration step
...@@ -248,9 +256,9 @@ void ClipboardHistoryController::MenuOptionSelected(int index) { ...@@ -248,9 +256,9 @@ void ClipboardHistoryController::MenuOptionSelected(int index) {
scoped_pause = std::make_unique<ClipboardHistory::ScopedPause>( scoped_pause = std::make_unique<ClipboardHistory::ScopedPause>(
weak_ptr->clipboard_history_.get()); weak_ptr->clipboard_history_.get());
} }
WriteClipboardDataToClipboard(clipboard_data); GetClipboard()->WriteClipboardData(std::move(original_data));
}, },
weak_ptr_factory_.GetWeakPtr(), *clipboard_items_.begin()), weak_ptr_factory_.GetWeakPtr(), std::move(original_data)),
base::TimeDelta::FromMilliseconds(100)); base::TimeDelta::FromMilliseconds(100));
} }
......
...@@ -51,8 +51,8 @@ class ASH_EXPORT ClipboardHistoryController { ...@@ -51,8 +51,8 @@ class ASH_EXPORT ClipboardHistoryController {
bool CanShowMenu() const; bool CanShowMenu() const;
void ShowMenu(); void ShowMenu();
void ExecuteSelectedMenuItem(); void ExecuteSelectedMenuItem(int event_flags);
void MenuOptionSelected(int index); void MenuOptionSelected(int index, int event_flags);
gfx::Rect CalculateAnchorRect() const; gfx::Rect CalculateAnchorRect() const;
......
...@@ -8,13 +8,20 @@ ...@@ -8,13 +8,20 @@
#include "ash/clipboard/clipboard_history.h" #include "ash/clipboard/clipboard_history.h"
#include "ash/clipboard/clipboard_history_controller.h" #include "ash/clipboard/clipboard_history_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "chrome/browser/chromeos/login/login_manager_test.h" #include "chrome/browser/chromeos/login/login_manager_test.h"
#include "chrome/browser/chromeos/login/test/login_manager_mixin.h" #include "chrome/browser/chromeos/login/test/login_manager_mixin.h"
#include "chrome/browser/chromeos/login/ui/user_adding_screen.h" #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h" #include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/events/test/event_generator.h" #include "ui/events/test/event_generator.h"
#include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_config.h"
...@@ -34,14 +41,34 @@ std::unique_ptr<views::Widget> CreateTestWidget() { ...@@ -34,14 +41,34 @@ std::unique_ptr<views::Widget> CreateTestWidget() {
return widget; return widget;
} }
void FlushMessageLoop() {
base::RunLoop run_loop;
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
run_loop.QuitClosure());
run_loop.Run();
}
void SetClipboardText(const std::string& text) { void SetClipboardText(const std::string& text) {
ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste) ui::ScopedClipboardWriter(ui::ClipboardBuffer::kCopyPaste)
.WriteText(base::ASCIIToUTF16(text)); .WriteText(base::UTF8ToUTF16(text));
// ClipboardHistory will post a task to process clipboard data in order to
// debounce multiple clipboard writes occurring in sequence. Here we give
// ClipboardHistory the chance to run its posted tasks before proceeding.
FlushMessageLoop();
}
void SetClipboardTextAndHtml(const std::string& text, const std::string& html) {
{
ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste);
scw.WriteText(base::UTF8ToUTF16(text));
scw.WriteHTML(base::UTF8ToUTF16(html), /*source_url=*/"");
}
// ClipboardHistory will post a task to process clipboard data in order to // ClipboardHistory will post a task to process clipboard data in order to
// debounce multiple clipboard writes occurring in sequence. Here we give // debounce multiple clipboard writes occurring in sequence. Here we give
// ClipboardHistory the chance to run its posted tasks before proceeding. // ClipboardHistory the chance to run its posted tasks before proceeding.
base::RunLoop().RunUntilIdle(); FlushMessageLoop();
} }
ash::ClipboardHistoryController* GetClipboardHistoryController() { ash::ClipboardHistoryController* GetClipboardHistoryController() {
...@@ -324,3 +351,107 @@ IN_PROC_BROWSER_TEST_F(ClipboardHistoryWithMultiProfileBrowserTest, ...@@ -324,3 +351,107 @@ IN_PROC_BROWSER_TEST_F(ClipboardHistoryWithMultiProfileBrowserTest,
EXPECT_EQ("A", base::UTF16ToUTF8(textfield->GetText())); EXPECT_EQ("A", base::UTF16ToUTF8(textfield->GetText()));
Release(ui::KeyboardCode::VKEY_COMMAND); Release(ui::KeyboardCode::VKEY_COMMAND);
} }
IN_PROC_BROWSER_TEST_F(ClipboardHistoryWithMultiProfileBrowserTest,
ShouldPasteHistoryAsPlainText) {
LoginUser(account_id1_);
// Create a browser and cache its active web contents.
auto* browser = CreateBrowser(
chromeos::ProfileHelper::Get()->GetProfileByAccountId(account_id1_));
auto* web_contents = browser->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents);
// Load the web contents synchronously.
// The contained script:
// - Listens for paste events and caches the last pasted data.
// - Notifies observers of paste events by changing document title.
// - Provides an API to expose the last pasted data.
ASSERT_TRUE(content::NavigateToURL(web_contents, GURL(R"(data:text/html,
<!DOCTYPE html>
<html>
<body>
<script>
let lastPaste = undefined;
let lastPasteId = 1;
window.addEventListener('paste', e => {
e.stopPropagation();
e.preventDefault();
const clipboardData = e.clipboardData || window.clipboardData;
lastPaste = clipboardData.types.reduce((data, type) => {
data.push(`${type}: ${clipboardData.getData(type)}`);
return data;
}, []);
document.title = `Paste ${lastPasteId++}`;
});
window.getLastPaste = () => {
return lastPaste || [];
};
</script>
</body>
</html>
)")));
// Cache a function to return the last paste.
auto GetLastPaste = [&]() {
auto result = content::EvalJs(
web_contents, "(function() { return window.getLastPaste(); })();");
EXPECT_EQ(result.error, "");
return result.ExtractList();
};
// Confirm initial state.
ASSERT_TRUE(GetLastPaste().GetList().empty());
// Write some things to the clipboard.
SetClipboardTextAndHtml("A", "<span>A</span>");
SetClipboardTextAndHtml("B", "<span>B</span>");
SetClipboardTextAndHtml("C", "<span>C</span>");
// Open clipboard history and paste the last history item.
PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN);
EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing());
PressAndRelease(ui::KeyboardCode::VKEY_DOWN);
PressAndRelease(ui::KeyboardCode::VKEY_DOWN);
PressAndRelease(ui::KeyboardCode::VKEY_DOWN);
PressAndRelease(ui::KeyboardCode::VKEY_RETURN);
EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing());
// Wait for the paste event to propagate to the web contents.
// The web contents will notify us a paste occurred by updating page title.
ignore_result(
content::TitleWatcher(web_contents, base ::UTF8ToUTF16("Paste 1"))
.WaitAndGetTitle());
// Confirm the expected paste data.
base::ListValue last_paste = GetLastPaste();
ASSERT_EQ(last_paste.GetList().size(), 2u);
EXPECT_EQ(last_paste.GetList()[0].GetString(), "text/plain: A");
EXPECT_EQ(last_paste.GetList()[1].GetString(), "text/html: <span>A</span>");
// Open clipboard history and paste the middle history item as plain text.
PressAndRelease(ui::KeyboardCode::VKEY_V, ui::EF_COMMAND_DOWN);
EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing());
PressAndRelease(ui::KeyboardCode::VKEY_DOWN);
PressAndRelease(ui::KeyboardCode::VKEY_DOWN);
PressAndRelease(ui::KeyboardCode::VKEY_DOWN);
PressAndRelease(ui::KeyboardCode::VKEY_RETURN, ui::EF_SHIFT_DOWN);
EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing());
// Wait for the paste event to propagate to the web contents.
// The web contents will notify us a paste occurred by updating page title.
ignore_result(
content::TitleWatcher(web_contents, base ::UTF8ToUTF16("Paste 2"))
.WaitAndGetTitle());
// Confirm the expected paste data.
last_paste = GetLastPaste();
ASSERT_EQ(last_paste.GetList().size(), 1u);
EXPECT_EQ(last_paste.GetList()[0].GetString(), "text/plain: A");
}
...@@ -217,12 +217,15 @@ class ClipboardInternal { ...@@ -217,12 +217,15 @@ class ClipboardInternal {
*result = data->custom_data_data(); *result = data->custom_data_data();
} }
// Writes |data| to the ClipboardData. // Writes |data| to the ClipboardData and returns the previous data.
void WriteData(std::unique_ptr<ClipboardData> data) { std::unique_ptr<ClipboardData> WriteData(
std::unique_ptr<ClipboardData> data) {
DCHECK(data); DCHECK(data);
++sequence_number_; std::unique_ptr<ClipboardData> previous_data = std::move(data_);
data_ = std::move(data); data_ = std::move(data);
++sequence_number_;
ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged(); ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged();
return previous_data;
} }
void SetDlpController( void SetDlpController(
...@@ -365,10 +368,10 @@ const ClipboardData* ClipboardNonBacked::GetClipboardData() const { ...@@ -365,10 +368,10 @@ const ClipboardData* ClipboardNonBacked::GetClipboardData() const {
return clipboard_internal_->GetData(); return clipboard_internal_->GetData();
} }
void ClipboardNonBacked::WriteClipboardData( std::unique_ptr<ClipboardData> ClipboardNonBacked::WriteClipboardData(
std::unique_ptr<ClipboardData> data) { std::unique_ptr<ClipboardData> data) {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
clipboard_internal_->WriteData(std::move(data)); return clipboard_internal_->WriteData(std::move(data));
} }
void ClipboardNonBacked::OnPreShutdown() {} void ClipboardNonBacked::OnPreShutdown() {}
......
...@@ -34,8 +34,9 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardNonBacked ...@@ -34,8 +34,9 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardNonBacked
// Returns the current ClipboardData. // Returns the current ClipboardData.
const ClipboardData* GetClipboardData() const; const ClipboardData* GetClipboardData() const;
// Writes the current ClipboardData. // Writes the current ClipboardData and returns the previous data.
void WriteClipboardData(std::unique_ptr<ClipboardData> data); std::unique_ptr<ClipboardData> WriteClipboardData(
std::unique_ptr<ClipboardData> data);
private: private:
friend class Clipboard; friend class Clipboard;
......
...@@ -36,4 +36,22 @@ TEST_F(ClipboardNonBackedTest, WriteAndGetClipboardData) { ...@@ -36,4 +36,22 @@ TEST_F(ClipboardNonBackedTest, WriteAndGetClipboardData) {
EXPECT_EQ(expected_clipboard_data_ptr, actual_clipboard_data_ptr); EXPECT_EQ(expected_clipboard_data_ptr, actual_clipboard_data_ptr);
} }
// Verifies that WriteClipboardData() writes a ClipboardData instance to the
// clipboard and returns the previous instance.
TEST_F(ClipboardNonBackedTest, WriteClipboardData) {
auto first_data = std::make_unique<ClipboardData>();
auto second_data = std::make_unique<ClipboardData>();
auto* first_data_ptr = first_data.get();
auto* second_data_ptr = second_data.get();
auto previous_data = clipboard()->WriteClipboardData(std::move(first_data));
EXPECT_EQ(previous_data.get(), nullptr);
previous_data = clipboard()->WriteClipboardData(std::move(second_data));
EXPECT_EQ(first_data_ptr, previous_data.get());
EXPECT_EQ(second_data_ptr, clipboard()->GetClipboardData());
}
} // namespace ui } // namespace ui
...@@ -1187,18 +1187,18 @@ ui::PostDispatchAction MenuController::OnWillDispatchKeyEvent( ...@@ -1187,18 +1187,18 @@ ui::PostDispatchAction MenuController::OnWillDispatchKeyEvent(
// Special handling for Option-Up and Option-Down, which should behave like // Special handling for Option-Up and Option-Down, which should behave like
// Home and End respectively in menus. // Home and End respectively in menus.
if ((event->flags() & ui::EF_ALT_DOWN)) { if ((event->flags() & ui::EF_ALT_DOWN)) {
ui::KeyEvent rewritten_event(*event);
if (event->key_code() == ui::VKEY_UP) { if (event->key_code() == ui::VKEY_UP) {
key_handled = OnKeyPressed(ui::VKEY_HOME); rewritten_event.set_key_code(ui::VKEY_HOME);
} else if (event->key_code() == ui::VKEY_DOWN) { } else if (event->key_code() == ui::VKEY_DOWN) {
key_handled = OnKeyPressed(ui::VKEY_END); rewritten_event.set_key_code(ui::VKEY_END);
} else {
key_handled = OnKeyPressed(event->key_code());
} }
key_handled = OnKeyPressed(rewritten_event);
} else { } else {
key_handled = OnKeyPressed(event->key_code()); key_handled = OnKeyPressed(*event);
} }
#else #else
key_handled = OnKeyPressed(event->key_code()); key_handled = OnKeyPressed(*event);
#endif #endif
if (key_handled) if (key_handled)
...@@ -1486,13 +1486,16 @@ void MenuController::StartDrag(SubmenuView* source, ...@@ -1486,13 +1486,16 @@ void MenuController::StartDrag(SubmenuView* source,
did_initiate_drag_ = false; did_initiate_drag_ = false;
} }
bool MenuController::OnKeyPressed(ui::KeyboardCode key_code) { bool MenuController::OnKeyPressed(const ui::KeyEvent& event) {
// Do not process while performing drag-and-drop DCHECK_EQ(event.type(), ui::ET_KEY_PRESSED);
// Do not process while performing drag-and-drop.
if (for_drop_) if (for_drop_)
return false; return false;
bool handled_key_code = false; bool handled_key_code = false;
const ui::KeyboardCode key_code = event.key_code();
switch (key_code) { switch (key_code) {
case ui::VKEY_HOME: case ui::VKEY_HOME:
if (IsEditableCombobox()) if (IsEditableCombobox())
...@@ -1573,7 +1576,7 @@ bool MenuController::OnKeyPressed(ui::KeyboardCode key_code) { ...@@ -1573,7 +1576,7 @@ bool MenuController::OnKeyPressed(ui::KeyboardCode key_code) {
handled_key_code = true; handled_key_code = true;
if (!SendAcceleratorToHotTrackedView() && if (!SendAcceleratorToHotTrackedView() &&
pending_state_.item->GetEnabled()) { pending_state_.item->GetEnabled()) {
Accept(pending_state_.item, 0); Accept(pending_state_.item, event.flags());
} }
} }
} }
......
...@@ -353,9 +353,8 @@ class VIEWS_EXPORT MenuController ...@@ -353,9 +353,8 @@ class VIEWS_EXPORT MenuController
const ui::LocatedEvent* event); const ui::LocatedEvent* event);
void StartDrag(SubmenuView* source, const gfx::Point& location); void StartDrag(SubmenuView* source, const gfx::Point& location);
// Handles |key_code| as a keypress. Returns true if OnKeyPressed handled the // Returns true if OnKeyPressed handled the key |event|.
// key code. bool OnKeyPressed(const ui::KeyEvent& event);
bool OnKeyPressed(ui::KeyboardCode key_code);
// Creates a MenuController. See |for_drop_| member for details on |for_drop|. // Creates a MenuController. See |for_drop_| member for details on |for_drop|.
MenuController(bool for_drop, internal::MenuControllerDelegate* delegate); MenuController(bool for_drop, internal::MenuControllerDelegate* delegate);
......
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