Procházet zdrojové kódy

LibGUI: Search for actions with a Shortcut instead of for KeyEvent

Instead of having widget/window/application create a shortcut from a
KeyEvent within their find methods, we'll just pass them a Shortcut
so that the "where to search" logic doesn't need to be duplicated
for different Shortcut types.

It also lets us handle invalid Shortcut rejection at a higher level,
with most things letting the caller be responsible for not searching
for actions with an invalid shortcut.
Geordie Hall před 3 roky
rodič
revize
737c1c86dc

+ 2 - 2
Userland/Libraries/LibGUI/Application.cpp

@@ -136,9 +136,9 @@ void Application::unregister_global_shortcut_action(Badge<Action>, Action& actio
     m_global_shortcut_actions.remove(action.alternate_shortcut());
 }
 
-Action* Application::action_for_key_event(KeyEvent const& event)
+Action* Application::action_for_shortcut(Shortcut const& shortcut) const
 {
-    auto it = m_global_shortcut_actions.find(Shortcut(event.modifiers(), (KeyCode)event.key()));
+    auto it = m_global_shortcut_actions.find(shortcut);
     if (it == m_global_shortcut_actions.end())
         return nullptr;
     return (*it).value;

+ 1 - 1
Userland/Libraries/LibGUI/Application.h

@@ -33,7 +33,7 @@ public:
     int exec();
     void quit(int = 0);
 
-    Action* action_for_key_event(KeyEvent const&);
+    Action* action_for_shortcut(Shortcut const&) const;
 
     void register_global_shortcut_action(Badge<Action>, Action&);
     void unregister_global_shortcut_action(Badge<Action>, Action&);

+ 8 - 7
Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp

@@ -19,6 +19,7 @@
 #include <LibGUI/Event.h>
 #include <LibGUI/Menu.h>
 #include <LibGUI/MouseTracker.h>
+#include <LibGUI/Shortcut.h>
 #include <LibGUI/Window.h>
 #include <LibGfx/Bitmap.h>
 #include <LibGfx/Font/FontDatabase.h>
@@ -133,28 +134,28 @@ void ConnectionToWindowServer::window_left(i32 window_id)
         Core::EventLoop::current().post_event(*window, make<Event>(Event::WindowLeft));
 }
 
-static Action* action_for_key_event(Window& window, KeyEvent const& event)
+static Action* action_for_shortcut(Window& window, Shortcut const& shortcut)
 {
-    if (event.key() == KeyCode::Key_Invalid)
+    if (!shortcut.is_valid())
         return nullptr;
 
-    dbgln_if(KEYBOARD_SHORTCUTS_DEBUG, "Looking up action for {}", event.to_string());
+    dbgln_if(KEYBOARD_SHORTCUTS_DEBUG, "Looking up action for {}", shortcut.to_string());
 
     for (auto* widget = window.focused_widget(); widget; widget = widget->parent_widget()) {
-        if (auto* action = widget->action_for_key_event(event)) {
+        if (auto* action = widget->action_for_shortcut(shortcut)) {
             dbgln_if(KEYBOARD_SHORTCUTS_DEBUG, "  > Focused widget {} gave action: {}", *widget, action);
             return action;
         }
     }
 
-    if (auto* action = window.action_for_key_event(event)) {
+    if (auto* action = window.action_for_shortcut(shortcut)) {
         dbgln_if(KEYBOARD_SHORTCUTS_DEBUG, "  > Asked window {}, got action: {}", window, action);
         return action;
     }
 
     // NOTE: Application-global shortcuts are ignored while a modal window is up.
     if (!window.is_modal()) {
-        if (auto* action = Application::the()->action_for_key_event(event)) {
+        if (auto* action = Application::the()->action_for_shortcut(shortcut)) {
             dbgln_if(KEYBOARD_SHORTCUTS_DEBUG, "  > Asked application, got action: {}", action);
             return action;
         }
@@ -171,7 +172,7 @@ void ConnectionToWindowServer::key_down(i32 window_id, u32 code_point, u32 key,
 
     auto key_event = make<KeyEvent>(Event::KeyDown, (KeyCode)key, modifiers, code_point, scancode);
 
-    if (auto* action = action_for_key_event(*window, *key_event)) {
+    if (auto* action = action_for_shortcut(*window, Shortcut(key_event->modifiers(), key_event->key()))) {
         if (action->is_enabled()) {
             action->flash_menubar_menu(*window);
             action->activate();

+ 1 - 0
Userland/Libraries/LibGUI/Forward.h

@@ -60,6 +60,7 @@ class ResizeEvent;
 class ScreenRectsChangeEvent;
 class Scrollbar;
 class AbstractScrollableWidget;
+class Shortcut;
 class Slider;
 class SortingProxyModel;
 class SpinBox;

+ 1 - 7
Userland/Libraries/LibGUI/Widget.cpp

@@ -904,14 +904,8 @@ bool Widget::is_backmost() const
     return &parent->children().first() == this;
 }
 
-Action* Widget::action_for_key_event(KeyEvent const& event)
+Action* Widget::action_for_shortcut(Shortcut const& shortcut)
 {
-    Shortcut shortcut(event.modifiers(), (KeyCode)event.key());
-
-    if (!shortcut.is_valid()) {
-        return nullptr;
-    }
-
     Action* found_action = nullptr;
     for_each_child_of_type<Action>([&](auto& action) {
         if (action.shortcut() == shortcut || action.alternate_shortcut() == shortcut) {

+ 1 - 1
Userland/Libraries/LibGUI/Widget.h

@@ -259,7 +259,7 @@ public:
     bool is_frontmost() const;
     bool is_backmost() const;
 
-    Action* action_for_key_event(KeyEvent const&);
+    Action* action_for_shortcut(Shortcut const&);
 
     template<typename Callback>
     void for_each_child_widget(Callback callback)

+ 1 - 2
Userland/Libraries/LibGUI/Window.cpp

@@ -1090,9 +1090,8 @@ void Window::notify_state_changed(Badge<ConnectionToWindowServer>, bool minimize
     }
 }
 
-Action* Window::action_for_key_event(KeyEvent const& event)
+Action* Window::action_for_shortcut(Shortcut const& shortcut)
 {
-    Shortcut shortcut(event.modifiers(), (KeyCode)event.key());
     Action* found_action = nullptr;
     for_each_child_of_type<Action>([&](auto& action) {
         if (action.shortcut() == shortcut || action.alternate_shortcut() == shortcut) {

+ 1 - 1
Userland/Libraries/LibGUI/Window.h

@@ -196,7 +196,7 @@ public:
 
     virtual bool is_visible_for_timer_purposes() const override { return m_visible_for_timer_purposes; }
 
-    Action* action_for_key_event(KeyEvent const&);
+    Action* action_for_shortcut(Shortcut const&);
 
     void did_add_widget(Badge<Widget>, Widget&);
     void did_remove_widget(Badge<Widget>, Widget&);