summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2021-04-24 19:15:47 +0100
committerCaolán McNamara <caolanm@redhat.com>2021-04-29 10:56:41 +0200
commit5753386c2353ad4866e7c5dd9e8751ccaa58e93c (patch)
tree26ac68f6bcb5f6d6ae3cedaacc1902d0b935a0b8
parentb6b02e0b4c9d739836e1f61a886ea45b01e6696e (diff)
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 <caolanm@redhat.com>
-rw-r--r--include/vcl/weld.hxx12
-rw-r--r--vcl/inc/salvtables.hxx4
-rw-r--r--vcl/source/app/salvtables.cxx39
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx105
4 files changed, 113 insertions, 47 deletions
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();
}