include/vcl/weld.hxx | 109 ++++++++++++++++++++++++++++++++++++------ vcl/inc/salvtables.hxx | 11 +--- vcl/source/app/salvtables.cxx | 69 +++----------------------- 3 files changed, 108 insertions(+), 81 deletions(-)
New commits: commit f35a453340beec925f2deed97e6273be77af8654 Author: Michael Weghorn <[email protected]> AuthorDate: Fri Oct 17 21:49:10 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Mon Oct 20 17:05:40 2025 +0200 tdf#130857 weld: Move logic for (not) calling signal hdls to base classes Following previous commit Change-Id: I93ec71e29804fd601e314e24c96d0f18a7cbb98c Author: Michael Weghorn <[email protected]> Date: Fri Oct 17 20:42:30 2025 +0200 tdf#130857 weld: Move signal block counter logic to weld::Widget , now also move the logic to only conditionally call the signal handlers from SalInstanceWidget (and subclasses) to weld::Widget (and subclasses), so this can be reused for other implementations in the future as well. Don't add it this logic to all signal_* methods, but only those for which the SalInstance* implementations were doing this previously, to not change the existing behavior. The only known case where the behavior would slightly differ now is SalInstanceCheckButton::ToggleHdl, which previously was IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void) { if (notify_events_disabled()) return; m_xCheckButton->EnableTriState(false); signal_toggled(); } and now would still call m_xCheckButton->EnableTriState(false); when event notification is disabled. However, that should presumably be fine, and making it dependent on whether or not signal notification is enabled seems a little odd anyway. The gtk3/gtk4 VCL plugin implement their own logic, which remains unchanged for now. Change-Id: I13bb1d4a2b52b2d4494a85895f2e33b98b2c45c6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192598 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index b636f7dfe4b1..883ff09341dd 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -691,7 +691,12 @@ class VCL_DLLPUBLIC Assistant : virtual public Dialog Link<const OUString&, bool> m_aJumpPageHdl; protected: - bool signal_jump_page(const OUString& rIdent) { return m_aJumpPageHdl.Call(rIdent); } + bool signal_jump_page(const OUString& rIdent) + { + if (notify_events_disabled()) + return true; + return m_aJumpPageHdl.Call(rIdent); + } public: virtual int get_current_page() const = 0; @@ -999,8 +1004,20 @@ protected: std::function<int(const weld::TreeIter&, const weld::TreeIter&)> m_aCustomSort; protected: - void signal_selection_changed() { m_aSelectionChangedHdl.Call(*this); } - bool signal_row_activated() { return m_aRowActivatedHdl.Call(*this); } + void signal_selection_changed() + { + if (notify_events_disabled()) + return; + m_aSelectionChangedHdl.Call(*this); + } + + bool signal_row_activated() + { + if (notify_events_disabled()) + return true; + return m_aRowActivatedHdl.Call(*this); + } + void signal_column_clicked(int nColumn) { m_aColumnClickedHdl.Call(nColumn); } bool signal_expanding(const TreeIter& rIter) { @@ -1010,8 +1027,19 @@ protected: { return !m_aCollapsingHdl.IsSet() || m_aCollapsingHdl.Call(rIter); } - void signal_visible_range_changed() { m_aVisibleRangeChangedHdl.Call(*this); } - void signal_model_changed() { m_aModelChangedHdl.Call(*this); } + void signal_visible_range_changed() + { + if (notify_events_disabled()) + return; + m_aVisibleRangeChangedHdl.Call(*this); + } + + void signal_model_changed() + { + if (notify_events_disabled()) + return; + m_aModelChangedHdl.Call(*this); + } void signal_toggled(const iter_col& rIterCol) { m_aRadioToggleHdl.Call(rIterCol); } @@ -1025,7 +1053,13 @@ protected: void signal_popup_menu(const CommandEvent& rCommand) { m_aPopupMenuHdl.Call(rCommand); } Link<const TreeIter&, OUString> m_aQueryTooltipHdl; - OUString signal_query_tooltip(const TreeIter& rIter) { return m_aQueryTooltipHdl.Call(rIter); } + + OUString signal_query_tooltip(const TreeIter& rIter) + { + if (notify_events_disabled()) + return {}; + return m_aQueryTooltipHdl.Call(rIter); + } Link<render_args, void> m_aRenderHdl; void signal_custom_render(vcl::RenderContext& rDevice, const tools::Rectangle& rRect, @@ -1454,10 +1488,24 @@ protected: Link<const TreeIter&, OUString> m_aQueryTooltipHdl; Link<const encoded_image_query&, bool> m_aGetPropertyTreeElemHdl; - void signal_selection_changed() { m_aSelectionChangeHdl.Call(*this); } - bool signal_item_activated() { return m_aItemActivatedHdl.Call(*this); } + void signal_selection_changed() + { + if (notify_events_disabled()) + return; + m_aSelectionChangeHdl.Call(*this); + } + + bool signal_item_activated() + { + if (notify_events_disabled()) + return true; + return m_aItemActivatedHdl.Call(*this); + } + OUString signal_query_tooltip(const TreeIter& rIter) const { + if (notify_events_disabled()) + return {}; return m_aQueryTooltipHdl.Call(rIter); } @@ -1600,7 +1648,12 @@ protected: Link<Toggleable&, void> m_aToggleHdl; TriState m_eSavedValue = TRISTATE_FALSE; - void signal_toggled() { m_aToggleHdl.Call(*this); } + void signal_toggled() + { + if (notify_events_disabled()) + return; + m_aToggleHdl.Call(*this); + } public: virtual void set_active(bool active) = 0; @@ -1788,7 +1841,13 @@ protected: friend class ::LOKTrigger; void signal_changed() { m_aChangeHdl.Call(*this); } - void signal_cursor_position() { m_aCursorPositionHdl.Call(*this); } + + void signal_cursor_position() + { + if (notify_events_disabled()) + return; + m_aCursorPositionHdl.Call(*this); + } public: virtual void set_text(const OUString& rText) = 0; @@ -2042,8 +2101,19 @@ class VCL_DLLPUBLIC Calendar : virtual public Widget Link<Calendar&, void> m_aActivatedHdl; protected: - void signal_selected() { m_aSelectedHdl.Call(*this); } - void signal_activated() { m_aActivatedHdl.Call(*this); } + void signal_selected() + { + if (notify_events_disabled()) + return; + m_aSelectedHdl.Call(*this); + } + + void signal_activated() + { + if (notify_events_disabled()) + return; + m_aActivatedHdl.Call(*this); + } public: void connect_selected(const Link<Calendar&, void>& rLink) { m_aSelectedHdl = rLink; } @@ -2418,7 +2488,14 @@ protected: Link<TextView&, void> m_aCursorPositionHdl; void signal_changed() { m_aChangeHdl.Call(*this); } - void signal_cursor_position() { m_aCursorPositionHdl.Call(*this); } + + void signal_cursor_position() + { + if (notify_events_disabled()) + return; + m_aCursorPositionHdl.Call(*this); + } + void signal_vadjustment_value_changed() { m_aVValueChangeHdl.Call(*this); } public: diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index f791f09918eb..4d6a2f9f1f2d 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -2225,8 +2225,6 @@ SalInstanceAssistant::~SalInstanceAssistant() IMPL_LINK_NOARG(SalInstanceAssistant, OnRoadmapItemSelected, LinkParamNone*, void) { - if (notify_events_disabled()) - return; auto nCurItemId = m_xWizard->GetCurrentRoadmapItemID(); int nPageIndex(find_id(nCurItemId)); if (!signal_jump_page(get_page_ident(nPageIndex)) && nCurItemId != m_xWizard->GetCurLevel()) @@ -3069,12 +3067,7 @@ IMPL_LINK_NOARG(SalInstanceMenuButton, MenuSelectHdl, ::MenuButton*, void) signal_selected(m_xMenuButton->GetCurItemIdent()); } -IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void) -{ - if (notify_events_disabled()) - return; - signal_toggled(); -} +IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void) { signal_toggled(); } IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void) { @@ -3132,17 +3125,10 @@ SalInstanceRadioButton::~SalInstanceRadioButton() m_xRadioButton->SetToggleHdl(Link<::RadioButton&, void>()); } -IMPL_LINK_NOARG(SalInstanceRadioButton, ToggleHdl, ::RadioButton&, void) -{ - if (notify_events_disabled()) - return; - signal_toggled(); -} +IMPL_LINK_NOARG(SalInstanceRadioButton, ToggleHdl, ::RadioButton&, void) { signal_toggled(); } IMPL_LINK(SalInstanceToggleButton, ToggleListener, VclWindowEvent&, rEvent, void) { - if (notify_events_disabled()) - return; if (rEvent.GetId() == VclEventId::PushbuttonToggle) signal_toggled(); } @@ -3177,8 +3163,6 @@ SalInstanceCheckButton::~SalInstanceCheckButton() IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void) { - if (notify_events_disabled()) - return; m_xCheckButton->EnableTriState(false); signal_toggled(); } @@ -3268,19 +3252,9 @@ public: }; } -IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void) -{ - if (notify_events_disabled()) - return; - signal_selected(); -} +IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void) { signal_selected(); } -IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void) -{ - if (notify_events_disabled()) - return; - signal_activated(); -} +IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void) { signal_activated(); } SalInstanceImage::SalInstanceImage(FixedImage* pImage, SalInstanceBuilder* pBuilder, bool bTakeOwnership) @@ -3512,8 +3486,6 @@ IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void) { signal_changed(); } IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void) { - if (notify_events_disabled()) - return; if (rEvent.GetId() == VclEventId::EditSelectionChanged || rEvent.GetId() == VclEventId::EditCaretChanged) signal_cursor_position(); @@ -5120,7 +5092,7 @@ SalInstanceTreeView::~SalInstanceTreeView() IMPL_LINK(SalInstanceTreeView, TooltipHdl, SvTreeListEntry*, pEntry, OUString) { - if (pEntry && !notify_events_disabled()) + if (pEntry) return signal_query_tooltip(SalInstanceTreeIter(pEntry)); return {}; @@ -5194,15 +5166,11 @@ IMPL_LINK(SalInstanceTreeView, CompareHdl, const SvSortData&, rSortData, sal_Int IMPL_LINK_NOARG(SalInstanceTreeView, VisibleRangeChangedHdl, SvTreeListBox*, void) { - if (notify_events_disabled()) - return; signal_visible_range_changed(); } IMPL_LINK_NOARG(SalInstanceTreeView, ModelChangedHdl, SvTreeListBox*, void) { - if (notify_events_disabled()) - return; signal_model_changed(); } @@ -5250,15 +5218,11 @@ IMPL_LINK(SalInstanceTreeView, ToggleHdl, SvLBoxButtonData*, pData, void) IMPL_LINK_NOARG(SalInstanceTreeView, SelectHdl, SvTreeListBox*, void) { - if (notify_events_disabled()) - return; signal_selection_changed(); } IMPL_LINK_NOARG(SalInstanceTreeView, DeSelectHdl, SvTreeListBox*, void) { - if (notify_events_disabled()) - return; if (m_xTreeView->GetSelectionMode() == SelectionMode::Single && !m_xTreeView->GetHoverSelection()) return; @@ -5267,8 +5231,6 @@ IMPL_LINK_NOARG(SalInstanceTreeView, DeSelectHdl, SvTreeListBox*, void) IMPL_LINK_NOARG(SalInstanceTreeView, DoubleClickHdl, SvTreeListBox*, bool) { - if (notify_events_disabled()) - return false; return !signal_row_activated(); } @@ -5448,7 +5410,7 @@ void SalInstanceIconView::insert_separator(int pos, const OUString* /* pId */) IMPL_LINK(SalInstanceIconView, TooltipHdl, SvTreeListEntry*, pEntry, OUString) { - if (pEntry && !notify_events_disabled()) + if (pEntry) return signal_query_tooltip(SalInstanceTreeIter(pEntry)); return {}; @@ -5726,15 +5688,11 @@ SalInstanceIconView::~SalInstanceIconView() IMPL_LINK_NOARG(SalInstanceIconView, SelectHdl, SvTreeListBox*, void) { - if (notify_events_disabled()) - return; signal_selection_changed(); } IMPL_LINK_NOARG(SalInstanceIconView, DeSelectHdl, SvTreeListBox*, void) { - if (notify_events_disabled()) - return; if (m_xIconView->GetSelectionMode() == SelectionMode::Single) return; signal_selection_changed(); @@ -5742,8 +5700,6 @@ IMPL_LINK_NOARG(SalInstanceIconView, DeSelectHdl, SvTreeListBox*, void) IMPL_LINK_NOARG(SalInstanceIconView, DoubleClickHdl, SvTreeListBox*, bool) { - if (notify_events_disabled()) - return false; return !signal_item_activated(); } @@ -6138,8 +6094,6 @@ IMPL_LINK_NOARG(SalInstanceTextView, ChangeHdl, Edit&, void) { signal_changed(); IMPL_LINK(SalInstanceTextView, CursorListener, VclWindowEvent&, rEvent, void) { - if (notify_events_disabled()) - return; if (rEvent.GetId() == VclEventId::EditSelectionChanged || rEvent.GetId() == VclEventId::EditCaretChanged) signal_cursor_position(); commit a049564b4952b6500001717e2c47bb7bda35a63e Author: Michael Weghorn <[email protected]> AuthorDate: Fri Oct 17 20:42:30 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Mon Oct 20 17:05:31 2025 +0200 tdf#130857 weld: Move signal block counter logic to weld::Widget Move the existing member and methods for managing the counter for disabling signal emission from SalInstanceWidget to the weld::Widget base class. This is currently used to avoid signalling about certain weld::Widget changes when they were made programmatically and not manually by the user. For example, when setting the selection for a TextView, signals get disabled like this: void SalInstanceTextView::select_region(int nStartPos, int nEndPos) { disable_notify_events(); tools::Long nStart = nStartPos < 0 ? SELECTION_MAX : nStartPos; tools::Long nEnd = nEndPos < 0 ? SELECTION_MAX : nEndPos; m_xTextView->SetSelection(Selection(nStart, nEnd)); enable_notify_events(); } The corresponding event handler then doesn't call weld::TextView::signal_cursor_position which would otherwise notify about the cursor change. IMPL_LINK(SalInstanceTextView, CursorListener, VclWindowEvent&, rEvent, void) { if (notify_events_disabled()) return; if (rEvent.GetId() == VclEventId::EditSelectionChanged || rEvent.GetId() == VclEventId::EditCaretChanged) signal_cursor_position(); } While the methods were public previously, make them protected now. For SalInstanceTreeView, add public wrappers, so SalInstanceEntryTreeView::KeyPressListener can continue to call this directly for its tree view. This commit only moves those methods from SalInstanceWidget to the weld::Widget base class. More logic will be moved for reuse in other implementations than the vcl one in upcoming commits. (Currently, GtkInstanceWidget implements its own logic and QtInstanceWidget doesn't implement the logic to block signals.) Change-Id: I93ec71e29804fd601e314e24c96d0f18a7cbb98c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192597 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index 4a5bc6a32484..b636f7dfe4b1 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -85,6 +85,8 @@ class VCL_DLLPUBLIC Widget { friend class ::LOKTrigger; + int m_nBlockNotify = 0; + protected: Link<Widget&, void> m_aFocusInHdl; Link<Widget&, void> m_aFocusOutHdl; @@ -97,6 +99,10 @@ protected: Link<const MouseEvent&, bool> m_aMouseMotionHdl; Link<const MouseEvent&, bool> m_aMouseReleaseHdl; + void disable_notify_events() { ++m_nBlockNotify; } + bool notify_events_disabled() const { return m_nBlockNotify != 0; } + void enable_notify_events() { --m_nBlockNotify; } + void signal_focus_in() { m_aFocusInHdl.Call(*this); } void signal_focus_out() { m_aFocusOutHdl.Call(*this); } bool signal_mnemonic_activate() { return m_aMnemonicActivateHdl.Call(*this); } diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index c667cc17b93a..2df36dcc2082 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -202,7 +202,6 @@ private: bool m_bEventListener; bool m_bKeyEventListener; bool m_bMouseEventListener; - int m_nBlockNotify; int m_nFreezeCount; protected: @@ -358,12 +357,6 @@ public: vcl::Window* getWidget() const; - void disable_notify_events(); - - bool notify_events_disabled() const; - - void enable_notify_events(); - virtual void queue_resize() override; virtual void help_hierarchy_foreach(const std::function<bool(const OUString&)>& func) override; @@ -1861,6 +1854,10 @@ public: virtual bool changed_by_hover() const override; virtual ~SalInstanceTreeView() override; + + // public version of protected weld::Widget methods + void disableNotifyEvents() { disable_notify_events(); } + void enableNotifyEvents() { enable_notify_events(); } }; class SalInstanceExpander : public SalInstanceWidget, public virtual weld::Expander diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 9ce9f2f64e8a..f791f09918eb 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -365,7 +365,6 @@ SalInstanceWidget::SalInstanceWidget(vcl::Window* pWidget, SalInstanceBuilder* p , m_bEventListener(false) , m_bKeyEventListener(false) , m_bMouseEventListener(false) - , m_nBlockNotify(0) , m_nFreezeCount(0) { } @@ -653,12 +652,6 @@ SalInstanceWidget::~SalInstanceWidget() vcl::Window* SalInstanceWidget::getWidget() const { return m_xWidget; } -void SalInstanceWidget::disable_notify_events() { ++m_nBlockNotify; } - -bool SalInstanceWidget::notify_events_disabled() const { return m_nBlockNotify != 0; } - -void SalInstanceWidget::enable_notify_events() { --m_nBlockNotify; } - OUString SalInstanceWidget::strip_mnemonic(const OUString& rLabel) const { return rLabel.replaceFirst("~", ""); @@ -6882,7 +6875,7 @@ IMPL_LINK(SalInstanceEntryTreeView, KeyPressListener, VclWindowEvent&, rEvent, v if (!bNavigation) return; - m_pTreeView->disable_notify_events(); + m_pTreeView->disableNotifyEvents(); auto& rListBox = m_pTreeView->getTreeView(); if (!rListBox.FirstSelected()) { @@ -6893,7 +6886,7 @@ IMPL_LINK(SalInstanceEntryTreeView, KeyPressListener, VclWindowEvent&, rEvent, v rListBox.KeyInput(rKeyEvent); m_xEntry->set_text(m_xTreeView->get_selected_text()); m_xEntry->select_region(0, -1); - m_pTreeView->enable_notify_events(); + m_pTreeView->enableNotifyEvents(); m_bTreeChange = true; m_pEntry->fire_signal_changed(); m_bTreeChange = false;
