Sfoglia il codice sorgente

LibGUI+LibVT: Notify widgets of emoji selection with a callback

Currently, LibGUI modifies the Ctrl+Alt+Space key event to instead
represent the emoji that was selected through EmojiInputDialog. This is
limited to a single code point.

For multiple code point emoji support, individual widgets now set a hook
to be notified of the emoji selection with a UTF-8 encoded string. This
replaces the previous set_accepts_emoji_input() method.
Timothy Flynn 2 anni fa
parent
commit
31b2d93038

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

@@ -192,18 +192,14 @@ void ConnectionToWindowServer::key_down(i32 window_id, u32 code_point, u32 key,
             return;
     }
 
-    bool focused_widget_accepts_emoji_input = window->focused_widget() && window->focused_widget()->accepts_emoji_input();
+    bool focused_widget_accepts_emoji_input = window->focused_widget() && window->focused_widget()->on_emoji_input;
     if (!window->blocks_emoji_input() && focused_widget_accepts_emoji_input && (modifiers == (Mod_Ctrl | Mod_Alt)) && key == Key_Space) {
         auto emoji_input_dialog = EmojiInputDialog::construct(window);
         if (emoji_input_dialog->exec() != EmojiInputDialog::ExecResult::OK)
             return;
-        key_event->m_key = Key_Invalid;
-        key_event->m_modifiers = 0;
 
-        Utf8View m_utf8_view(emoji_input_dialog->selected_emoji_text());
-        u32 emoji_code_point = *m_utf8_view.begin();
-
-        key_event->m_code_point = emoji_code_point;
+        window->focused_widget()->on_emoji_input(emoji_input_dialog->selected_emoji_text());
+        return;
     }
 
     bool accepts_command_palette = !window->blocks_command_palette();

+ 23 - 5
Userland/Libraries/LibGUI/TextEditor.cpp

@@ -52,7 +52,7 @@ TextEditor::TextEditor(Type type)
         { DisplayOnly, "DisplayOnly" });
 
     set_focus_policy(GUI::FocusPolicy::StrongFocus);
-    set_accepts_emoji_input(true);
+    set_or_clear_emoji_input_callback();
     set_override_cursor(Gfx::StandardCursor::IBeam);
     set_background_role(ColorRole::Base);
     set_foreground_role(ColorRole::BaseText);
@@ -775,7 +775,7 @@ void TextEditor::select_all()
 
 void TextEditor::insert_emoji()
 {
-    if (!accepts_emoji_input() || window()->blocks_emoji_input())
+    if (!on_emoji_input || window()->blocks_emoji_input())
         return;
 
     auto emoji_input_dialog = EmojiInputDialog::construct(window());
@@ -786,6 +786,25 @@ void TextEditor::insert_emoji()
     insert_at_cursor_or_replace_selection(emoji_code_point);
 }
 
+void TextEditor::set_or_clear_emoji_input_callback()
+{
+    switch (m_mode) {
+    case Editable:
+        on_emoji_input = [this](auto emoji) {
+            insert_at_cursor_or_replace_selection(emoji);
+        };
+        break;
+
+    case DisplayOnly:
+    case ReadOnly:
+        on_emoji_input = {};
+        break;
+
+    default:
+        VERIFY_NOT_REACHED();
+    }
+}
+
 void TextEditor::keydown_event(KeyEvent& event)
 {
     if (!is_editable() && event.key() == KeyCode::Key_Tab)
@@ -1683,19 +1702,18 @@ void TextEditor::set_mode(const Mode mode)
         m_cut_action->set_enabled(has_selection() && !text_is_secret());
         m_paste_action->set_enabled(true);
         m_insert_emoji_action->set_enabled(true);
-        set_accepts_emoji_input(true);
         break;
     case DisplayOnly:
     case ReadOnly:
         m_cut_action->set_enabled(false);
         m_paste_action->set_enabled(false);
         m_insert_emoji_action->set_enabled(false);
-        set_accepts_emoji_input(false);
         break;
     default:
         VERIFY_NOT_REACHED();
     }
 
+    set_or_clear_emoji_input_callback();
     set_editing_cursor();
 }
 
@@ -1724,7 +1742,7 @@ void TextEditor::context_menu_event(ContextMenuEvent& event)
     if (is_displayonly())
         return;
 
-    m_insert_emoji_action->set_enabled(accepts_emoji_input() && !window()->blocks_emoji_input());
+    m_insert_emoji_action->set_enabled(on_emoji_input && !window()->blocks_emoji_input());
 
     if (!m_context_menu) {
         m_context_menu = Menu::construct();

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

@@ -151,6 +151,7 @@ public:
     void delete_from_line_start_to_cursor();
     void select_all();
     void insert_emoji();
+    void set_or_clear_emoji_input_callback();
     void select_current_line();
     virtual void undo();
     virtual void redo();

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

@@ -337,8 +337,7 @@ public:
 
     Gfx::IntRect relative_non_grabbable_rect() const;
 
-    void set_accepts_emoji_input(bool b) { m_accepts_emoji_input = b; }
-    bool accepts_emoji_input() const { return m_accepts_emoji_input; }
+    Function<void(StringView)> on_emoji_input;
 
     void set_accepts_command_palette(bool b) { m_accepts_command_palette = b; }
     bool accepts_command_palette() const { return m_accepts_command_palette; }
@@ -441,7 +440,6 @@ private:
     bool m_auto_focusable { true };
     bool m_enabled { true };
     bool m_updates_enabled { true };
-    bool m_accepts_emoji_input { false };
     bool m_accepts_command_palette { true };
     bool m_default_font { true };
 

+ 5 - 1
Userland/Libraries/LibVT/TerminalWidget.cpp

@@ -84,8 +84,12 @@ TerminalWidget::TerminalWidget(int ptm_fd, bool automatic_size_policy)
 
     set_override_cursor(Gfx::StandardCursor::IBeam);
     set_focus_policy(GUI::FocusPolicy::StrongFocus);
-    set_accepts_emoji_input(true);
     set_pty_master_fd(ptm_fd);
+
+    on_emoji_input = [this](auto emoji) {
+        inject_string(emoji);
+    };
+
     m_cursor_blink_timer = add<Core::Timer>();
     m_visual_beep_timer = add<Core::Timer>();
     m_auto_scroll_timer = add<Core::Timer>();