shortcuts: Unlock kExit action
Allow customization for the sign out action. Includes dynamically updating the sign out prompt to match the first available accelerator of the action. Screenshot: https://screenshot.googleplex.com/3dhguSoLPL6THQS Bug: b/216049298 Test: ash_unittest Change-Id: I1415d66bc96ce55153eb1bb8686eb5042428d9fc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5271122 Commit-Queue: Jimmy Gong <jimmyxgong@chromium.org> Reviewed-by: David Padlipsky <dpad@google.com> Cr-Commit-Position: refs/heads/main@{#1258332}
This commit is contained in:
ash
accelerators
ash_strings.grdash_strings_grd
IDS_ASH_ACCELERATOR_ALT_KEY.png.sha1IDS_ASH_ACCELERATOR_CONTROL_KEY.png.sha1IDS_ASH_ACCELERATOR_LAUNCHER_KEY.png.sha1IDS_ASH_ACCELERATOR_SEARCH_KEY.png.sha1IDS_ASH_ACCELERATOR_SHIFT_KEY.png.sha1IDS_ASH_SIGN_OUT_WARNING_POPUP_TEXT_DYNAMIC.png.sha1
webui
shortcut_customization_ui
backend
@ -5,16 +5,24 @@
|
||||
#include "ash/accelerators/accelerator_lookup.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "ash/public/cpp/accelerators_util.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/strings/grit/ash_strings.h"
|
||||
#include "base/ranges/algorithm.h"
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/types/optional_ref.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/events/ash/keyboard_capability.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char16_t kDetailsDelimiter[] = u"+";
|
||||
|
||||
using AcceleratorDetails = AcceleratorLookup::AcceleratorDetails;
|
||||
|
||||
using OptionalAccelerators =
|
||||
@ -28,6 +36,40 @@ AcceleratorLookup::AcceleratorLookup(
|
||||
|
||||
AcceleratorLookup::~AcceleratorLookup() = default;
|
||||
|
||||
// static
|
||||
std::u16string AcceleratorLookup::GetAcceleratorDetailsText(
|
||||
AcceleratorDetails details) {
|
||||
std::u16string details_text;
|
||||
|
||||
if (details.accelerator.IsCmdDown()) {
|
||||
std::u16string cmd_string =
|
||||
Shell::Get()->keyboard_capability()->HasLauncherButtonOnAnyKeyboard()
|
||||
? l10n_util::GetStringUTF16(IDS_ASH_ACCELERATOR_LAUNCHER_KEY)
|
||||
: l10n_util::GetStringUTF16(IDS_ASH_ACCELERATOR_SEARCH_KEY);
|
||||
details_text = base::StrCat({details_text, cmd_string, kDetailsDelimiter});
|
||||
}
|
||||
|
||||
if (details.accelerator.IsCtrlDown()) {
|
||||
details_text = base::StrCat(
|
||||
{details_text,
|
||||
l10n_util::GetStringUTF16(IDS_ASH_ACCELERATOR_CONTROL_KEY),
|
||||
kDetailsDelimiter});
|
||||
}
|
||||
|
||||
if (details.accelerator.IsAltDown()) {
|
||||
details_text = base::StrCat(
|
||||
{details_text, l10n_util::GetStringUTF16(IDS_ASH_ACCELERATOR_ALT_KEY),
|
||||
kDetailsDelimiter});
|
||||
}
|
||||
|
||||
if (details.accelerator.IsShiftDown()) {
|
||||
details_text = base::StrCat(
|
||||
{details_text, l10n_util::GetStringUTF16(IDS_ASH_ACCELERATOR_SHIFT_KEY),
|
||||
kDetailsDelimiter});
|
||||
}
|
||||
return base::StrCat({details_text, details.key_display});
|
||||
}
|
||||
|
||||
std::vector<AcceleratorDetails> AcceleratorLookup::GetAcceleratorsForAction(
|
||||
uint32_t action) const {
|
||||
CHECK(ash_accelerator_configuration_);
|
||||
|
@ -32,6 +32,8 @@ class ASH_EXPORT AcceleratorLookup {
|
||||
std::u16string key_display;
|
||||
};
|
||||
|
||||
static std::u16string GetAcceleratorDetailsText(AcceleratorDetails details);
|
||||
|
||||
// Returns a list of all accelerator details for `action`.
|
||||
std::vector<AcceleratorDetails> GetAcceleratorsForAction(
|
||||
uint32_t action) const;
|
||||
|
@ -233,4 +233,47 @@ TEST_F(AcceleratorLookupTest, FilteredAccelerators) {
|
||||
EXPECT_TRUE(CompareAccelerators(expected, actual));
|
||||
}
|
||||
|
||||
class AcceleratorDetailsTextTest
|
||||
: public AcceleratorLookupTest,
|
||||
public testing::WithParamInterface<
|
||||
std::tuple<AcceleratorDetails, std::u16string>> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
AcceleratorLookupTest::SetUp();
|
||||
std::tie(details_, expected_) = GetParam();
|
||||
}
|
||||
|
||||
protected:
|
||||
AcceleratorDetails details_;
|
||||
std::u16string expected_;
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
// Empty to simplify gtest output
|
||||
,
|
||||
AcceleratorDetailsTextTest,
|
||||
testing::ValuesIn(std::vector<
|
||||
std::tuple<AcceleratorDetails, std::u16string>>{
|
||||
{{ui::Accelerator(ui::VKEY_A, ui::EF_NONE), u"a"}, u"a"},
|
||||
{{ui::Accelerator(ui::VKEY_BROWSER_REFRESH, ui::EF_NONE),
|
||||
u"browserRefresh"},
|
||||
u"browserRefresh"},
|
||||
{{ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN), u"a"}, u"ctrl+a"},
|
||||
{{ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN),
|
||||
u"a"},
|
||||
u"ctrl+alt+a"},
|
||||
{{ui::Accelerator(ui::VKEY_A,
|
||||
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
|
||||
ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN),
|
||||
u"a"},
|
||||
u"search+ctrl+alt+shift+a"},
|
||||
{{ui::Accelerator(ui::VKEY_A, ui::EF_COMMAND_DOWN), u"a"}, u"search+a"},
|
||||
}));
|
||||
|
||||
TEST_P(AcceleratorDetailsTextTest, ExpectedText) {
|
||||
const std::u16string actual =
|
||||
AcceleratorLookup::GetAcceleratorDetailsText(details_);
|
||||
EXPECT_EQ(expected_, actual);
|
||||
}
|
||||
|
||||
} // namespace ash
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ash/accelerators/accelerator_lookup.h"
|
||||
#include "ash/public/cpp/accelerator_actions.h"
|
||||
#include "ash/public/cpp/shell_window_ids.h"
|
||||
#include "ash/session/session_controller_impl.h"
|
||||
#include "ash/shell.h"
|
||||
@ -30,6 +32,8 @@
|
||||
namespace ash {
|
||||
namespace {
|
||||
|
||||
using AcceleratorDetails = AcceleratorLookup::AcceleratorDetails;
|
||||
|
||||
const int64_t kTimeOutMilliseconds = 2000;
|
||||
// Color of the text of the warning message.
|
||||
const SkColor kTextColor = SK_ColorWHITE;
|
||||
@ -43,10 +47,20 @@ const int kVerticalMarginAroundText = 100;
|
||||
class ExitWarningWidgetDelegateView : public views::WidgetDelegateView {
|
||||
public:
|
||||
ExitWarningWidgetDelegateView()
|
||||
: text_(l10n_util::GetStringUTF16(IDS_ASH_SIGN_OUT_WARNING_POPUP_TEXT)),
|
||||
accessible_name_(l10n_util::GetStringUTF16(
|
||||
: accessible_name_(l10n_util::GetStringUTF16(
|
||||
IDS_ASH_SIGN_OUT_WARNING_POPUP_TEXT_ACCESSIBLE)),
|
||||
text_width_(0) {
|
||||
std::vector<AcceleratorDetails> accelerators =
|
||||
Shell::Get()->accelerator_lookup()->GetAvailableAcceleratorsForAction(
|
||||
AcceleratorAction::kExit);
|
||||
CHECK(!accelerators.empty());
|
||||
// TODO(jimmyxgong): For now fetch the first accelerator of the list. But
|
||||
// maybe there's a possibility to check which accelerator was most recently
|
||||
// pressed.
|
||||
text_ = l10n_util::GetStringFUTF16(
|
||||
IDS_ASH_SIGN_OUT_WARNING_POPUP_TEXT_DYNAMIC,
|
||||
AcceleratorLookup::GetAcceleratorDetailsText(accelerators[0]));
|
||||
|
||||
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
|
||||
const gfx::FontList& font_list =
|
||||
rb.GetFontList(ui::ResourceBundle::LargeFont);
|
||||
|
@ -3776,6 +3776,9 @@ Some features are limited to increase battery life.
|
||||
<message name="IDS_ASH_SIGN_OUT_WARNING_POPUP_TEXT" desc="The text of the popup when the user preses the exit shortcut in chrome-os.">
|
||||
Press Ctrl+Shift+Q twice to sign out.
|
||||
</message>
|
||||
<message name="IDS_ASH_SIGN_OUT_WARNING_POPUP_TEXT_DYNAMIC" desc="The text of the popup when the user preses the exit shortcut in chrome-os.">
|
||||
Press <ph name="accelerator">$1<ex>Ctrl+Shift+Q</ex></ph> twice to sign out.
|
||||
</message>
|
||||
<message name="IDS_ASH_SIGN_OUT_WARNING_POPUP_TEXT_ACCESSIBLE" desc="The message used by accessibility to indicate the content of the popup when the user preses the exit shortcut in chrome-os.">
|
||||
Press Control Shift Q twice to sign out.
|
||||
</message>
|
||||
@ -3911,6 +3914,22 @@ Some features are limited to increase battery life.
|
||||
Full-screen Magnifier enabled. Press Ctrl+Search+M again to toggle it off.
|
||||
</message>
|
||||
|
||||
<message name="IDS_ASH_ACCELERATOR_LAUNCHER_KEY" desc="Label for the launcher key in ChromeOS keyboards.">
|
||||
launcher
|
||||
</message>
|
||||
<message name="IDS_ASH_ACCELERATOR_SEARCH_KEY" desc="Label for the search key in ChromeOS keyboards.">
|
||||
search
|
||||
</message>
|
||||
<message name="IDS_ASH_ACCELERATOR_SHIFT_KEY" desc="Label for the search key in ChromeOS keyboards.">
|
||||
shift
|
||||
</message>
|
||||
<message name="IDS_ASH_ACCELERATOR_CONTROL_KEY" desc="Label for the control key in ChromeOS keyboards.">
|
||||
ctrl
|
||||
</message>
|
||||
<message name="IDS_ASH_ACCELERATOR_ALT_KEY" desc="Label for the alt key in ChromeOS keyboards.">
|
||||
alt
|
||||
</message>
|
||||
|
||||
<!-- Accelerator Actions-->
|
||||
<message name="IDS_ASH_ACCELERATOR_DESCRIPTION_BRIGHTNESS_DOWN" desc="Label for accelerator action - Turn brightness down.">
|
||||
Turn brightness down
|
||||
|
1
ash/ash_strings_grd/IDS_ASH_ACCELERATOR_ALT_KEY.png.sha1
Normal file
1
ash/ash_strings_grd/IDS_ASH_ACCELERATOR_ALT_KEY.png.sha1
Normal file
@ -0,0 +1 @@
|
||||
812e367eb3b4ced3d637a61297b680e2e7c45c37
|
@ -0,0 +1 @@
|
||||
812e367eb3b4ced3d637a61297b680e2e7c45c37
|
@ -0,0 +1 @@
|
||||
0abfaa5e09a524a7922f020d4ffd1c126d4c19cd
|
@ -0,0 +1 @@
|
||||
4f0169e3f7f8845a39566a52fd308cbce5c8fd6d
|
@ -0,0 +1 @@
|
||||
812e367eb3b4ced3d637a61297b680e2e7c45c37
|
@ -0,0 +1 @@
|
||||
812e367eb3b4ced3d637a61297b680e2e7c45c37
|
@ -515,7 +515,7 @@ const AcceleratorLayoutMap& GetAcceleratorLayoutMap() {
|
||||
AcceleratorAction::kExit, IDS_ASH_ACCELERATOR_DESCRIPTION_EXIT,
|
||||
mojom::AcceleratorCategory::kGeneral,
|
||||
mojom::AcceleratorSubcategory::kGeneralControls,
|
||||
/*locked=*/true, mojom::AcceleratorLayoutStyle::kDefault,
|
||||
/*locked=*/false, mojom::AcceleratorLayoutStyle::kDefault,
|
||||
mojom::AcceleratorSource::kAsh)},
|
||||
{AcceleratorAction::kSwitchToNextUser,
|
||||
AcceleratorLayoutDetails(
|
||||
|
Reference in New Issue
Block a user