include/vcl/weld.hxx | 12 ++++ vcl/inc/salvtables.hxx | 4 + vcl/source/app/salvtables.cxx | 39 ++++++++++++--- vcl/unx/gtk3/gtk3gtkinst.cxx | 105 ++++++++++++++++++++++++++---------------- 4 files changed, 113 insertions(+), 47 deletions(-)
New commits: commit 5753386c2353ad4866e7c5dd9e8751ccaa58e93c Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Sat Apr 24 19:15:47 2021 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Thu Apr 29 10:56:41 2021 +0200 allow push/pop multiple levels of freeze/thaw so can freely protect a block with freeze/thaw regardless of current freeze/thaw state Change-Id: I1bd60bfc02fe784e36ae371a737f4fdfb15a0888 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114615 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index c055ee0e87b3..9821005fb9e6 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -284,7 +284,19 @@ public: virtual bool get_direction() const = 0; virtual void set_direction(bool bRTL) = 0; + /* Increases the freeze count on widget. + + If the freeze count is non-zero, emission of the widget's notifications + is stopped. The notifications are queued until the freeze count is + decreased to zero. Duplicate notifications may be squashed together. + */ virtual void freeze() = 0; + + /* Reverts the effect of a previous call to freeze. + + The freeze count is decreased on the widget and when it reaches zero, + queued notifications are emitted. + */ virtual void thaw() = 0; /* push/pop busy mouse cursor state diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index f71ce7a055b2..c274b4bd234c 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -185,6 +185,7 @@ private: bool m_bKeyEventListener; bool m_bMouseEventListener; int m_nBlockNotify; + int m_nFreezeCount; protected: void ensure_event_listener(); @@ -198,6 +199,9 @@ protected: // so use this variant, we will need to filter them later void ensure_mouse_listener(); + bool IsFirstFreeze() const { return m_nFreezeCount == 0; } + bool IsLastThaw() const { return m_nFreezeCount == 1; } + virtual void HandleEventListener(VclWindowEvent& rEvent); virtual bool HandleKeyEventListener(VclWindowEvent& rEvent); virtual void HandleMouseEventListener(VclSimpleEvent& rEvent); diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 585fbebda541..f482d4ee7145 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -249,6 +249,7 @@ SalInstanceWidget::SalInstanceWidget(vcl::Window* pWidget, SalInstanceBuilder* p , m_bKeyEventListener(false) , m_bMouseEventListener(false) , m_nBlockNotify(0) + , m_nFreezeCount(0) { } @@ -484,9 +485,19 @@ bool SalInstanceWidget::get_direction() const { return m_xWidget->IsRTLEnabled() void SalInstanceWidget::set_direction(bool bRTL) { m_xWidget->EnableRTL(bRTL); } -void SalInstanceWidget::freeze() { m_xWidget->SetUpdateMode(false); } +void SalInstanceWidget::freeze() +{ + if (m_nFreezeCount == 0) + m_xWidget->SetUpdateMode(false); + ++m_nFreezeCount; +} -void SalInstanceWidget::thaw() { m_xWidget->SetUpdateMode(true); } +void SalInstanceWidget::thaw() +{ + --m_nFreezeCount; + if (m_nFreezeCount == 0) + m_xWidget->SetUpdateMode(true); +} void SalInstanceWidget::set_busy_cursor(bool bBusy) { @@ -3704,15 +3715,23 @@ void SalInstanceTreeView::columns_autosize() void SalInstanceTreeView::freeze() { + bool bIsFirstFreeze = IsFirstFreeze(); SalInstanceWidget::freeze(); - m_xTreeView->SetUpdateMode(false); - m_xTreeView->GetModel()->EnableInvalidate(false); + if (bIsFirstFreeze) + { + m_xTreeView->SetUpdateMode(false); + m_xTreeView->GetModel()->EnableInvalidate(false); + } } void SalInstanceTreeView::thaw() { - m_xTreeView->GetModel()->EnableInvalidate(true); - m_xTreeView->SetUpdateMode(true); + bool bIsLastThaw = IsLastThaw(); + if (bIsLastThaw) + { + m_xTreeView->GetModel()->EnableInvalidate(true); + m_xTreeView->SetUpdateMode(true); + } SalInstanceWidget::thaw(); } @@ -5144,13 +5163,17 @@ SalInstanceIconView::SalInstanceIconView(::IconView* pIconView, SalInstanceBuild void SalInstanceIconView::freeze() { + bool bIsFirstFreeze = IsFirstFreeze(); SalInstanceWidget::freeze(); - m_xIconView->SetUpdateMode(false); + if (bIsFirstFreeze) + m_xIconView->SetUpdateMode(false); } void SalInstanceIconView::thaw() { - m_xIconView->SetUpdateMode(true); + bool bIsLastThaw = IsLastThaw(); + if (bIsLastThaw) + m_xIconView->SetUpdateMode(true); SalInstanceWidget::thaw(); } diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 43189617bf63..af252ea05bfa 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -1984,6 +1984,9 @@ protected: DECL_LINK(async_drag_cancel, void*, void); + bool IsFirstFreeze() const { return m_nFreezeCount == 0; } + bool IsLastThaw() const { return m_nFreezeCount == 1; } + static gboolean signalFocusIn(GtkWidget*, GdkEvent*, gpointer widget) { GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); @@ -2110,6 +2113,7 @@ private: bool m_bTakeOwnership; bool m_bDraggedOver; int m_nWaitCount; + int m_nFreezeCount; sal_uInt16 m_nLastMouseButton; sal_uInt16 m_nLastMouseClicks; int m_nPressedButton; @@ -2482,6 +2486,7 @@ public: , m_bTakeOwnership(bTakeOwnership) , m_bDraggedOver(false) , m_nWaitCount(0) + , m_nFreezeCount(0) , m_nLastMouseButton(0) , m_nLastMouseClicks(0) , m_nPressedButton(-1) @@ -3011,12 +3016,14 @@ public: virtual void freeze() override { + ++m_nFreezeCount; gtk_widget_freeze_child_notify(m_pWidget); g_object_freeze_notify(G_OBJECT(m_pWidget)); } virtual void thaw() override { + --m_nFreezeCount; g_object_thaw_notify(G_OBJECT(m_pWidget)); gtk_widget_thaw_child_notify(m_pWidget); } @@ -12092,20 +12099,24 @@ public: virtual void freeze() override { disable_notify_events(); + bool bIsFirstFreeze = IsFirstFreeze(); GtkInstanceContainer::freeze(); - g_object_ref(m_pTreeModel); - gtk_tree_view_set_model(m_pTreeView, nullptr); - g_object_freeze_notify(G_OBJECT(m_pTreeModel)); - if (m_xSorter) + if (bIsFirstFreeze) { - int nSortColumn; - GtkSortType eSortType; - GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel); - gtk_tree_sortable_get_sort_column_id(pSortable, &nSortColumn, &eSortType); - gtk_tree_sortable_set_sort_column_id(pSortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, eSortType); - - m_aSavedSortColumns.push_back(nSortColumn); - m_aSavedSortTypes.push_back(eSortType); + g_object_ref(m_pTreeModel); + gtk_tree_view_set_model(m_pTreeView, nullptr); + g_object_freeze_notify(G_OBJECT(m_pTreeModel)); + if (m_xSorter) + { + int nSortColumn; + GtkSortType eSortType; + GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel); + gtk_tree_sortable_get_sort_column_id(pSortable, &nSortColumn, &eSortType); + gtk_tree_sortable_set_sort_column_id(pSortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, eSortType); + + m_aSavedSortColumns.push_back(nSortColumn); + m_aSavedSortTypes.push_back(eSortType); + } } enable_notify_events(); } @@ -12113,16 +12124,19 @@ public: virtual void thaw() override { disable_notify_events(); - if (m_xSorter) + if (IsLastThaw()) { - GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel); - gtk_tree_sortable_set_sort_column_id(pSortable, m_aSavedSortColumns.back(), m_aSavedSortTypes.back()); - m_aSavedSortTypes.pop_back(); - m_aSavedSortColumns.pop_back(); + if (m_xSorter) + { + GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel); + gtk_tree_sortable_set_sort_column_id(pSortable, m_aSavedSortColumns.back(), m_aSavedSortTypes.back()); + m_aSavedSortTypes.pop_back(); + m_aSavedSortColumns.pop_back(); + } + g_object_thaw_notify(G_OBJECT(m_pTreeModel)); + gtk_tree_view_set_model(m_pTreeView, GTK_TREE_MODEL(m_pTreeModel)); + g_object_unref(m_pTreeModel); } - g_object_thaw_notify(G_OBJECT(m_pTreeModel)); - gtk_tree_view_set_model(m_pTreeView, GTK_TREE_MODEL(m_pTreeModel)); - g_object_unref(m_pTreeModel); GtkInstanceContainer::thaw(); enable_notify_events(); } @@ -12742,19 +12756,26 @@ public: virtual void freeze() override { disable_notify_events(); + bool bIsFirstFreeze = IsFirstFreeze(); GtkInstanceContainer::freeze(); - g_object_ref(m_pTreeStore); - gtk_icon_view_set_model(m_pIconView, nullptr); - g_object_freeze_notify(G_OBJECT(m_pTreeStore)); + if (bIsFirstFreeze) + { + g_object_ref(m_pTreeStore); + gtk_icon_view_set_model(m_pIconView, nullptr); + g_object_freeze_notify(G_OBJECT(m_pTreeStore)); + } enable_notify_events(); } virtual void thaw() override { disable_notify_events(); - g_object_thaw_notify(G_OBJECT(m_pTreeStore)); - gtk_icon_view_set_model(m_pIconView, GTK_TREE_MODEL(m_pTreeStore)); - g_object_unref(m_pTreeStore); + if (IsLastThaw()) + { + g_object_thaw_notify(G_OBJECT(m_pTreeStore)); + gtk_icon_view_set_model(m_pIconView, GTK_TREE_MODEL(m_pTreeStore)); + g_object_unref(m_pTreeStore); + } GtkInstanceContainer::thaw(); enable_notify_events(); } @@ -15920,14 +15941,18 @@ public: virtual void freeze() override { disable_notify_events(); + bool bIsFirstFreeze = IsFirstFreeze(); GtkInstanceContainer::freeze(); - g_object_ref(m_pTreeModel); - gtk_tree_view_set_model(m_pTreeView, nullptr); - g_object_freeze_notify(G_OBJECT(m_pTreeModel)); - if (m_xSorter) + if (bIsFirstFreeze) { - GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel); - gtk_tree_sortable_set_sort_column_id(pSortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING); + g_object_ref(m_pTreeModel); + gtk_tree_view_set_model(m_pTreeView, nullptr); + g_object_freeze_notify(G_OBJECT(m_pTreeModel)); + if (m_xSorter) + { + GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel); + gtk_tree_sortable_set_sort_column_id(pSortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING); + } } enable_notify_events(); } @@ -15935,15 +15960,17 @@ public: virtual void thaw() override { disable_notify_events(); - if (m_xSorter) + if (IsLastThaw()) { - GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel); - gtk_tree_sortable_set_sort_column_id(pSortable, m_nTextCol, GTK_SORT_ASCENDING); + if (m_xSorter) + { + GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel); + gtk_tree_sortable_set_sort_column_id(pSortable, m_nTextCol, GTK_SORT_ASCENDING); + } + g_object_thaw_notify(G_OBJECT(m_pTreeModel)); + gtk_tree_view_set_model(m_pTreeView, m_pTreeModel); + g_object_unref(m_pTreeModel); } - g_object_thaw_notify(G_OBJECT(m_pTreeModel)); - gtk_tree_view_set_model(m_pTreeView, m_pTreeModel); - g_object_unref(m_pTreeModel); - GtkInstanceContainer::thaw(); enable_notify_events(); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits