From f3ad8a70c3c15fd57891b0d2fe0bb0a5d2aa39a2 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Tue, 4 Feb 2020 11:34:29 +0000 Subject: weld SvxFontSizeBox_Impl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit which enables making a native gtk widget a member of a toolbar This widget wants to distinguish between a value getting selected by the menu or not, which is fairly tricky Change-Id: I9014785530bd0d82ffa66842f940feb2d3237e68 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87971 Tested-by: Jenkins Reviewed-by: Caolán McNamara --- vcl/unx/gtk3/gtk3gtkinst.cxx | 78 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) (limited to 'vcl/unx') diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 623dd1205452..47c8e9993308 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -85,6 +85,8 @@ #include #include +#include + using namespace com::sun::star; using namespace com::sun::star::uno; using namespace com::sun::star::lang; @@ -2695,6 +2697,12 @@ public: return m_xDropTarget.get(); } + virtual boost::property_tree::ptree get_property_tree() const override + { + //not implemented for the gtk variant + return boost::property_tree::ptree(); + } + virtual void set_stack_background() override { OUString sColor = Application::GetSettings().GetStyleSettings().GetWindowColor().AsRGBHexString(); @@ -11151,6 +11159,7 @@ private: bool m_bPopupActive; bool m_bAutoComplete; bool m_bAutoCompleteCaseSensitive; + bool m_bChangedByMenu; gulong m_nToggleFocusInSignalId; gulong m_nToggleFocusOutSignalId; gulong m_nChangedSignalId; @@ -11160,6 +11169,8 @@ private: gulong m_nEntryActivateSignalId; gulong m_nEntryFocusInSignalId; gulong m_nEntryFocusOutSignalId; + gulong m_nOriginalMenuActivateEventId; + gulong m_nMenuActivateSignalId; guint m_nAutoCompleteIdleId; static gboolean idleAutoComplete(gpointer widget) @@ -11257,7 +11268,13 @@ private: { GtkInstanceComboBox* pThis = static_cast(widget); SolarMutexGuard aGuard; - pThis->signal_changed(); + pThis->fire_signal_changed(); + } + + void fire_signal_changed() + { + signal_changed(); + m_bChangedByMenu = false; } static void signalPopupToggled(GtkComboBox*, GParamSpec*, gpointer widget) @@ -11432,6 +11449,27 @@ private: return bDone; } + static void signalMenuActivate(GtkWidget* pWidget, const gchar *path, gpointer widget) + { + GtkInstanceComboBox* pThis = static_cast(widget); + return pThis->signal_menu_activate(pWidget, path); + } + + void signal_menu_activate(GtkWidget* pWidget, const gchar *path) + { + // we disabled the original menu-active to get our own handler in first + // so we know before changed is called that it will be called by the + // menu, now block our handler and unblock the original and replay the + // event to call the original handler + m_bChangedByMenu = true; + g_signal_handler_block(m_pMenu, m_nMenuActivateSignalId); + g_signal_handler_unblock(m_pMenu, m_nOriginalMenuActivateEventId); + guint nMenuActivateSignalId = g_signal_lookup("menu-activate", G_TYPE_FROM_INSTANCE(m_pMenu)); + g_signal_emit(pWidget, nMenuActivateSignalId, 0, path); + g_signal_handler_block(m_pMenu, m_nOriginalMenuActivateEventId); + g_signal_handler_unblock(m_pMenu, m_nMenuActivateSignalId); + } + bool signal_key_press(const GdkEventKey* pEvent) { KeyEvent aKEvt(GtkToVcl(*pEvent)); @@ -11562,10 +11600,21 @@ private: return; m_pMenu = GTK_MENU(pWidget); - guint nSignalId = g_signal_lookup("key-press-event", GTK_TYPE_MENU); - gulong nOriginalMenuKeyPressEventId = g_signal_handler_find(m_pMenu, G_SIGNAL_MATCH_DATA, nSignalId, 0, + guint nKeyPressSignalId = g_signal_lookup("key-press-event", GTK_TYPE_MENU); + gulong nOriginalMenuKeyPressEventId = g_signal_handler_find(m_pMenu, + static_cast(G_SIGNAL_MATCH_DATA | G_SIGNAL_MATCH_ID), + nKeyPressSignalId, 0, nullptr, nullptr, m_pComboBox); + guint nMenuActivateSignalId = g_signal_lookup("menu-activate", G_TYPE_FROM_INSTANCE(m_pMenu)); + m_nOriginalMenuActivateEventId = g_signal_handler_find(m_pMenu, + static_cast(G_SIGNAL_MATCH_DATA | G_SIGNAL_MATCH_ID), + nMenuActivateSignalId, 0, + nullptr, nullptr, m_pComboBox); + + g_signal_handler_block(m_pMenu, m_nOriginalMenuActivateEventId); + m_nMenuActivateSignalId = g_signal_connect(m_pMenu, "menu-activate", G_CALLBACK(signalMenuActivate), this); + g_signal_handler_block(m_pMenu, nOriginalMenuKeyPressEventId); g_signal_connect(m_pMenu, "key-press-event", G_CALLBACK(signalKeyPress), this); } @@ -11592,10 +11641,13 @@ public: , m_bPopupActive(false) , m_bAutoComplete(false) , m_bAutoCompleteCaseSensitive(false) + , m_bChangedByMenu(false) , m_nToggleFocusInSignalId(0) , m_nToggleFocusOutSignalId(0) , m_nChangedSignalId(g_signal_connect(m_pComboBox, "changed", G_CALLBACK(signalChanged), this)) , m_nPopupShownSignalId(g_signal_connect(m_pComboBox, "notify::popup-shown", G_CALLBACK(signalPopupToggled), this)) + , m_nOriginalMenuActivateEventId(0) + , m_nMenuActivateSignalId(0) , m_nAutoCompleteIdleId(0) { GList* cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(m_pComboBox)); @@ -11658,6 +11710,7 @@ public: disable_notify_events(); OString aId(OUStringToOString(rStr, RTL_TEXTENCODING_UTF8)); gtk_combo_box_set_active_id(m_pComboBox, aId.getStr()); + m_bChangedByMenu = false; enable_notify_events(); } @@ -11704,6 +11757,7 @@ public: { disable_notify_events(); gtk_combo_box_set_active(m_pComboBox, pos); + m_bChangedByMenu = false; enable_notify_events(); } @@ -12017,8 +12071,17 @@ public: return gtk_widget_has_focus(m_pToggleButton) || GtkInstanceWidget::has_focus(); } + virtual bool changed_by_menu() const override + { + return m_bChangedByMenu; + } + virtual ~GtkInstanceComboBox() override { + if (m_nOriginalMenuActivateEventId) + g_signal_handler_unblock(m_pMenu, m_nOriginalMenuActivateEventId); + if (m_nMenuActivateSignalId) + g_signal_handler_disconnect(m_pMenu, m_nMenuActivateSignalId); if (m_nAutoCompleteIdleId) g_source_remove(m_nAutoCompleteIdleId); if (GtkEntry* pEntry = get_entry()) @@ -12048,6 +12111,7 @@ private: gulong m_nEntryInsertTextSignalId; guint m_nAutoCompleteIdleId; bool m_bAutoCompleteCaseSensitive; + bool m_bTreeChange; bool signal_key_press(GdkEventKey* pEvent) { @@ -12075,7 +12139,9 @@ private: } m_xEntry->select_region(0, -1); enable_notify_events(); + m_bTreeChange = true; m_pEntry->fire_signal_changed(); + m_bTreeChange = false; return true; } return false; @@ -12176,6 +12242,7 @@ public: , m_pTreeView(dynamic_cast(m_xTreeView.get())) , m_nAutoCompleteIdleId(0) , m_bAutoCompleteCaseSensitive(false) + , m_bTreeChange(false) { assert(m_pEntry); GtkWidget* pWidget = m_pEntry->getWidget(); @@ -12232,6 +12299,11 @@ public: GtkInstanceContainer::disable_notify_events(); } + virtual bool changed_by_menu() const override + { + return m_bTreeChange; + } + virtual ~GtkInstanceEntryTreeView() override { if (m_nAutoCompleteIdleId) -- cgit