diff --git a/Userland/Services/WindowServer/Menu.cpp b/Userland/Services/WindowServer/Menu.cpp index f99fceba5c..ed9bb4e177 100644 --- a/Userland/Services/WindowServer/Menu.cpp +++ b/Userland/Services/WindowServer/Menu.cpp @@ -43,7 +43,7 @@ namespace WindowServer { -static u32 find_ampersand_shortcut_character(const String& string) +u32 find_ampersand_shortcut_character(const StringView& string) { Utf8View utf8_view { string }; for (auto it = utf8_view.begin(); it != utf8_view.end(); ++it) { @@ -265,7 +265,7 @@ void Menu::draw() auto& previous_font = painter.font(); if (item.is_default()) painter.set_font(Gfx::FontDatabase::default_bold_font()); - painter.draw_text(text_rect, item.text(), Gfx::TextAlignment::CenterLeft, text_color); + painter.draw_ui_text(text_rect, item.text(), painter.font(), Gfx::TextAlignment::CenterLeft, text_color); if (!item.shortcut_text().is_empty()) { painter.draw_text(item.rect().translated(-right_padding(), 0), item.shortcut_text(), Gfx::TextAlignment::CenterRight, text_color); } diff --git a/Userland/Services/WindowServer/Menu.h b/Userland/Services/WindowServer/Menu.h index 42f5400ac1..40521a3135 100644 --- a/Userland/Services/WindowServer/Menu.h +++ b/Userland/Services/WindowServer/Menu.h @@ -42,10 +42,10 @@ namespace WindowServer { class ClientConnection; class MenuBar; -class Event; class Menu final : public Core::Object { - C_OBJECT(Menu) + C_OBJECT(Menu); + public: Menu(ClientConnection*, int menu_id, String name); virtual ~Menu() override; @@ -160,4 +160,6 @@ private: int m_max_scroll_offset { 0 }; }; +u32 find_ampersand_shortcut_character(const StringView&); + } diff --git a/Userland/Services/WindowServer/MenuManager.cpp b/Userland/Services/WindowServer/MenuManager.cpp index cdff3a0460..34ec07a70f 100644 --- a/Userland/Services/WindowServer/MenuManager.cpp +++ b/Userland/Services/WindowServer/MenuManager.cpp @@ -30,11 +30,11 @@ #include #include #include +#include namespace WindowServer { static MenuManager* s_the; -static constexpr int s_search_timeout = 3000; MenuManager& MenuManager::the() { @@ -45,10 +45,6 @@ MenuManager& MenuManager::the() MenuManager::MenuManager() { s_the = this; - - m_search_timer = Core::Timer::create_single_shot(0, [this] { - m_current_search.clear(); - }); } MenuManager::~MenuManager() @@ -91,23 +87,33 @@ void MenuManager::event(Core::Event& event) return; } - if (key_event.key() == Key_Backspace) { - m_current_search.clear(); - return; - } - if (m_current_menu && event.type() == Event::KeyDown && ((key_event.key() >= Key_A && key_event.key() <= Key_Z) || (key_event.key() >= Key_0 && key_event.key() <= Key_9))) { - m_current_search.append_code_point(key_event.code_point()); - m_search_timer->restart(s_search_timeout); + + // FIXME: Maybe cache this on the menu instead of recomputing it on every alphanumeric menu keystroke? + HashMap alt_shortcut_to_item_index; for (int i = 0; i < m_current_menu->item_count(); ++i) { - auto text = m_current_menu->item(i).text(); - if (text.to_lowercase().starts_with(m_current_search.to_string().to_lowercase())) { - m_current_menu->set_hovered_item(i); - return; - } + auto& item = m_current_menu->item(i); + if (!item.is_enabled()) + continue; + auto alt_shortcut = find_ampersand_shortcut_character(item.text()); + if (!alt_shortcut) + continue; + alt_shortcut_to_item_index.set(tolower(alt_shortcut), i); } + + auto it = alt_shortcut_to_item_index.find(tolower(key_event.code_point())); + + if (it != alt_shortcut_to_item_index.end()) { + auto& item = m_current_menu->item(it->value); + m_current_menu->set_hovered_item(it->value); + if (item.is_submenu()) + m_current_menu->descend_into_submenu_at_hovered_item(); + else + m_current_menu->open_hovered_item(false); + } + return; } @@ -246,7 +252,6 @@ void MenuManager::close_everyone() menu->clear_hovered_item(); } m_open_menu_stack.clear(); - m_current_search.clear(); clear_current_menu(); refresh(); } @@ -372,8 +377,6 @@ void MenuManager::set_current_menu(Menu* menu) return; } - m_current_search.clear(); - Menu* previous_current_menu = m_current_menu; m_current_menu = menu; diff --git a/Userland/Services/WindowServer/MenuManager.h b/Userland/Services/WindowServer/MenuManager.h index bdf7f076ba..5d034c66a2 100644 --- a/Userland/Services/WindowServer/MenuManager.h +++ b/Userland/Services/WindowServer/MenuManager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2018-2021, Andreas Kling * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,13 +31,12 @@ #include "Window.h" #include #include -#include -#include namespace WindowServer { class MenuManager final : public Core::Object { - C_OBJECT(MenuManager) + C_OBJECT(MenuManager); + public: static MenuManager& the(); @@ -80,9 +79,6 @@ private: WeakPtr m_previous_input_window; Vector> m_open_menu_stack; - RefPtr m_search_timer; - StringBuilder m_current_search; - int m_theme_index { 0 }; WeakPtr m_hovered_menu;