vcl/unx/gtk3/gtkinst.cxx |  113 ++++++++++++++++++++++++-----------------------
 1 file changed, 60 insertions(+), 53 deletions(-)

New commits:
commit 284739963674f018cb946b3d2ab855afb498c87e
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri May 28 17:01:05 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri May 28 20:54:25 2021 +0200

    gtk4: restore typeahead in ComboBox dropdown widget
    
    Change-Id: I851c4b3d43ae0b12055f3c76c8e7f7d78c9f1b75
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116352
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 5f51609309f9..3809bd35d4e5 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -1899,6 +1899,9 @@ class GtkInstanceBuilder;
             guint updated_keyval = 
GtkSalFrame::GetKeyValFor(gdk_keymap_get_default(), hardware_keycode, group);
             nKeyCode = GtkSalFrame::GetKeyCode(updated_keyval);
         }
+#else
+        (void)hardware_keycode;
+        (void)group;
 #endif
         nKeyCode |= GtkSalFrame::GetKeyModCode(state);
         return KeyEvent(gdk_keyval_to_unicode(keyval), nKeyCode, 0);
@@ -16239,7 +16242,7 @@ private:
 //    GtkOverlay* m_pOverlay;
 //    GtkTreeView* m_pTreeView;
 //    GtkMenuButton* m_pOverlayButton; // button that the StyleDropdown uses 
on an active row
-//    GtkWindow* m_pMenuWindow;
+    GtkWidget* m_pMenuWindow;
     GtkTreeModel* m_pTreeModel;
     GtkCellRenderer* m_pButtonTextRenderer;
     GtkCellRenderer* m_pMenuTextRenderer;
@@ -16260,7 +16263,7 @@ private:
     bool m_bAutoCompleteCaseSensitive;
     bool m_bChangedByMenu;
     bool m_bCustomRenderer;
-    bool m_bActivateCalled;
+    bool m_bUserSelectEntry;
     gint m_nTextCol;
     gint m_nIdCol;
 //    gulong m_nToggleFocusInSignalId;
@@ -16378,7 +16381,7 @@ private:
         }
     }
 
-    static void signalChanged(GtkEntry*, gpointer widget)
+    static void signalChanged(GtkComboBox*, gpointer widget)
     {
         GtkInstanceComboBox* pThis = static_cast<GtkInstanceComboBox*>(widget);
         SolarMutexGuard aGuard;
@@ -16387,6 +16390,8 @@ private:
 
     void fire_signal_changed()
     {
+        m_bUserSelectEntry = true;
+        m_bChangedByMenu = toggle_button_get_active();
         signal_changed();
         m_bChangedByMenu = false;
     }
@@ -16439,11 +16444,19 @@ private:
     }
 #endif
 
-#if 0
+    bool toggle_button_get_active()
+    {
+        GValue value = G_VALUE_INIT;
+        g_value_init(&value, G_TYPE_BOOLEAN);
+        g_object_get_property(G_OBJECT(m_pComboBox), "popup-shown", &value);
+        return g_value_get_boolean(&value);
+    }
+
     void toggle_menu()
     {
-        if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_pToggleButton)))
+        if (!toggle_button_get_active())
         {
+#if 0
             if (m_bHoverSelection)
             {
                 // turn hover selection back off until mouse is moved again
@@ -16451,63 +16464,38 @@ private:
                 gtk_tree_view_set_hover_selection(m_pTreeView, false);
                 m_bHoverSelection = false;
             }
+#endif
 
-            do_ungrab(GTK_WIDGET(m_pMenuWindow));
-
-            gtk_widget_hide(GTK_WIDGET(m_pMenuWindow));
-
-            // so gdk_window_move_to_rect will work again the next time
-            gtk_widget_unrealize(GTK_WIDGET(m_pMenuWindow));
-
-            gtk_widget_set_size_request(GTK_WIDGET(m_pMenuWindow), -1, -1);
-
-            if (!m_bActivateCalled)
-                tree_view_set_cursor(m_nPrePopupCursorPos);
+            if (!m_bUserSelectEntry)
+                set_active_including_mru(m_nPrePopupCursorPos, true);
 
+#if 0
             // undo show_menu tooltip blocking
             GtkWidget* pParent = widget_get_toplevel(m_pToggleButton);
             GtkSalFrame* pFrame = pParent ? 
GtkSalFrame::getFromWindow(pParent) : nullptr;
             if (pFrame)
                 pFrame->UnblockTooltip();
+#endif
         }
         else
         {
-            GtkWidget* pComboBox = GTK_WIDGET(getContainer());
-
-            gint nComboWidth = gtk_widget_get_allocated_width(pComboBox);
-            GtkRequisition size;
-            gtk_widget_get_preferred_size(GTK_WIDGET(m_pMenuWindow), nullptr, 
&size);
-
-            gint nPopupWidth = size.width;
-            gint nPopupHeight = get_popup_height(nPopupWidth);
-            nPopupWidth = std::max(nPopupWidth, nComboWidth);
-
-            gtk_widget_set_size_request(GTK_WIDGET(m_pMenuWindow), 
nPopupWidth, nPopupHeight);
-
             m_nPrePopupCursorPos = get_active();
 
-            m_bActivateCalled = false;
+            m_bUserSelectEntry = false;
 
             // if we are in mru mode always start with the cursor at the top 
of the menu
             if (m_nMaxMRUCount)
-                tree_view_set_cursor(0);
-
-            show_menu(pComboBox, m_pMenuWindow);
+                set_active_including_mru(0, true);
         }
     }
-#endif
 
     virtual void signal_popup_toggled() override
     {
         m_aQuickSelectionEngine.Reset();
 
-        // toggle_menu();
-
-        GValue value = G_VALUE_INIT;
-        g_value_init(&value, G_TYPE_BOOLEAN);
-        g_object_get_property(G_OBJECT(m_pComboBox), "popup-shown", &value);
-        bool bIsShown = g_value_get_boolean(&value);
+        toggle_menu();
 
+        bool bIsShown = toggle_button_get_active();
         if (m_bPopupActive != bIsShown)
         {
             m_bPopupActive = bIsShown;
@@ -16807,8 +16795,18 @@ private:
                 m_aQuickSelectionEngine.Reset();
                 sal_uInt16 nKeyMod = aKeyCode.GetModifier();
                 // tdf#131076 don't let bare return toggle menu popup active, 
but do allow deactivate
-                if (nCode == KEY_RETURN && !nKeyMod && !m_bPopupActive)
-                    bDone = combobox_activate();
+                if (nCode == KEY_RETURN && !nKeyMod)
+                {
+                    if (!m_bPopupActive)
+                        bDone = combobox_activate();
+                    else
+                    {
+                        // treat 'return' as if the active entry was clicked on
+                        signalChanged(m_pComboBox, this);
+                        gtk_combo_box_popdown(m_pComboBox);
+                        bDone = true;
+                    }
+                }
                 else if (nCode == KEY_UP && nKeyMod == KEY_MOD2 && 
m_bPopupActive)
                 {
                     gtk_combo_box_popdown(m_pComboBox);
@@ -16914,10 +16912,7 @@ private:
 
     void set_typeahead_selected_entry(int nSelect)
     {
-        if (m_bPopupActive)
-            tree_view_set_cursor(nSelect);
-        else
-            set_active_including_mru(nSelect, true);
+        set_active_including_mru(nSelect, true);
     }
 
     virtual vcl::StringEntryIdentifier CurrentEntry(OUString& out_entryText) 
const override
@@ -17031,7 +17026,7 @@ private:
 
     void handle_row_activated()
     {
-        m_bActivateCalled = true;
+        m_bUserSelectEntry = true;
         m_bChangedByMenu = true;
         disable_notify_events();
         int nActive = get_active();
@@ -17276,7 +17271,7 @@ public:
 //        , m_pOverlay(GTK_OVERLAY(gtk_builder_get_object(pComboBuilder, 
"overlay")))
 //        , m_pTreeView(GTK_TREE_VIEW(gtk_builder_get_object(pComboBuilder, 
"treeview")))
 //        , 
m_pOverlayButton(GTK_MENU_BUTTON(gtk_builder_get_object(pComboBuilder, 
"overlaybutton")))
-//        , m_pMenuWindow(GTK_WINDOW(gtk_builder_get_object(pComboBuilder, 
"popup")))
+        , m_pMenuWindow(nullptr)
         , m_pTreeModel(gtk_combo_box_get_model(pComboBox))
         , m_pButtonTextRenderer(nullptr)
 //        , m_pToggleButton(GTK_WIDGET(gtk_builder_get_object(pComboBuilder, 
"button")))
@@ -17291,7 +17286,7 @@ public:
         , m_bAutoCompleteCaseSensitive(false)
         , m_bChangedByMenu(false)
         , m_bCustomRenderer(false)
-        , m_bActivateCalled(false)
+        , m_bUserSelectEntry(false)
         , m_nTextCol(gtk_combo_box_get_entry_text_column(pComboBox))
         , m_nIdCol(gtk_combo_box_get_id_column(pComboBox))
 //        , m_nToggleFocusInSignalId(0)
@@ -17305,7 +17300,16 @@ public:
         , m_nMRUCount(0)
         , m_nMaxMRUCount(0)
     {
-        int nActive = gtk_combo_box_get_active(m_pComboBox);
+        for (GtkWidget* pChild = 
gtk_widget_get_first_child(GTK_WIDGET(m_pComboBox));
+             pChild; pChild = gtk_widget_get_next_sibling(pChild))
+        {
+            if (GTK_IS_POPOVER(pChild))
+            {
+                m_pMenuWindow = pChild;
+                break;
+            }
+        }
+        SAL_WARN_IF(!m_pMenuWindow, "vcl.gtk", "GtkInstanceComboBox: couldn't 
find popup menu");
 
         if (gtk_combo_box_get_has_entry(m_pComboBox))
         {
@@ -17330,15 +17334,18 @@ public:
             gtk_widget_add_controller(GTK_WIDGET(m_pComboBox), 
m_pKeyController);
         }
 
-        if (nActive != -1)
-            tree_view_set_cursor(nActive);
-
 //        g_signal_connect(m_pMenuWindow, "grab-broken-event", 
G_CALLBACK(signalGrabBroken), this);
 //        g_signal_connect(m_pMenuWindow, "button-press-event", 
G_CALLBACK(signalButtonPress), this);
 //        g_signal_connect(m_pMenuWindow, "motion-notify-event", 
G_CALLBACK(signalMotion), this);
+
         // support typeahead for the menu itself, typing into the menu will
         // select via the vcl selection engine, a matching entry.
-//        g_signal_connect(m_pMenuWindow, "key-press-event", 
G_CALLBACK(signalKeyPress), this);
+        if (m_pMenuWindow)
+        {
+            GtkEventController* pMenuKeyController = 
GTK_EVENT_CONTROLLER(gtk_event_controller_key_new());
+            g_signal_connect(pMenuKeyController, "key-pressed", 
G_CALLBACK(signalKeyPress), this);
+            gtk_widget_add_controller(m_pMenuWindow, pMenuKeyController);
+        }
 #if 0
         g_signal_connect(m_pOverlay, "get-child-position", 
G_CALLBACK(signalGetChildPosition), this);
         gtk_overlay_add_overlay(m_pOverlay, GTK_WIDGET(m_pOverlayButton));
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to