diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-05-22 12:49:05 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-05-23 10:10:36 +0200 |
commit | 237a656db82951e06f8a34e6ca2c1e50f24eb508 (patch) | |
tree | 1f714c3a2162e820ebc4330206abda844b1e1f6e | |
parent | 0ea9fd65847dd2f4e435c6c8e5325d306256560d (diff) |
tdf#125388 disable gtk callback that makes long combobox menus unusable
Change-Id: Ic5cb575189984246365d8a1067e61ea84eaa5dce
Reviewed-on: https://gerrit.libreoffice.org/72768
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index fa8fbd554973..fa98e2e2e208 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -8663,6 +8663,27 @@ public: } }; +#define g_signal_handlers_block_by_data(instance, data) \ + g_signal_handlers_block_matched ((instance), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, (data)) + +/* tdf#125388 on measuring each row, the GtkComboBox GtkTreeMenu will call + its area_apply_attributes_cb function on the row, but that calls + gtk_tree_menu_get_path_item which then loops through each child of the + menu looking for the widget of the row, so performance drops to useless. + + All area_apply_attributes_cb does it set menu item sensitivity, so block it from running + with fragile hackery which assumes that the unwanted callback is the only one with a + user_data of the ComboBox GtkTreeMenu */ +static void disable_area_apply_attributes_cb(GtkWidget* pItem, gpointer userdata) +{ + GtkMenuItem* pMenuItem = GTK_MENU_ITEM(pItem); + GtkWidget* child = gtk_bin_get_child(GTK_BIN(pMenuItem)); + GtkCellView* pCellView = GTK_CELL_VIEW(child); + GtkCellLayout* pCellLayout = GTK_CELL_LAYOUT(pCellView); + GtkCellArea* pCellArea = gtk_cell_layout_get_area(pCellLayout); + g_signal_handlers_block_by_data(pCellArea, userdata); +} + class GtkInstanceComboBox : public GtkInstanceContainer, public vcl::ISearchableStringList, public virtual weld::ComboBox { private: @@ -9238,6 +9259,11 @@ public: #endif } + void bodge_area_apply_attributes_cb() + { + gtk_container_foreach(GTK_CONTAINER(m_pMenu), disable_area_apply_attributes_cb, m_pMenu); + } + virtual void insert_vector(const std::vector<weld::ComboBoxEntry>& rItems, bool bKeepExisting) override { freeze(); @@ -9455,6 +9481,7 @@ public: enable_notify_events(); bodge_wayland_menu_not_appearing(); + bodge_area_apply_attributes_cb(); } virtual bool get_popup_shown() const override |