summaryrefslogtreecommitdiff
path: root/thunar
diff options
context:
space:
mode:
authorAlexander Schwinn <alexxcons@xfce.org>2022-01-09 15:46:21 +0100
committerAlexander Schwinn <alexxcons@xfce.org>2022-01-26 21:07:17 +0000
commit173ed8df1e1d21a70748c255fed117e154a96113 (patch)
treecb20651b1c7dbf9b53620f70390b89a6bf5ff443 /thunar
parentc8f27b292d63573f63f3c91d2f334f7d00473064 (diff)
downloadthunar-173ed8df1e1d21a70748c255fed117e154a96113.tar.gz
Use 'g_timeout_add_full' to set tree-view cursor (Issue #351)
In order to prevent 100% CPU in some cases Cancel the 'set cursor' operation if it takes more than 5 seconds
Diffstat (limited to 'thunar')
-rw-r--r--thunar/thunar-tree-view.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/thunar/thunar-tree-view.c b/thunar/thunar-tree-view.c
index 117eaa82..69de731c 100644
--- a/thunar/thunar-tree-view.c
+++ b/thunar/thunar-tree-view.c
@@ -22,6 +22,9 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
#include <gdk/gdkkeysyms.h>
@@ -153,8 +156,8 @@ static gboolean thunar_tree_view_selection_func (G
GtkTreePath *path,
gboolean path_currently_selected,
gpointer user_data);
-static gboolean thunar_tree_view_cursor_idle (gpointer user_data);
-static void thunar_tree_view_cursor_idle_destroy (gpointer user_data);
+static gboolean thunar_tree_view_set_cursor (gpointer user_data);
+static void set_cursor_event_source_destroy (gpointer user_data);
static gboolean thunar_tree_view_drag_scroll_timer (gpointer user_data);
static void thunar_tree_view_drag_scroll_timer_destroy (gpointer user_data);
static gboolean thunar_tree_view_expand_timer (gpointer user_data);
@@ -214,7 +217,8 @@ struct _ThunarTreeView
gulong queue_resize_signal_id;
/* set cursor to current directory idle source */
- guint cursor_idle_id;
+ guint set_cursor_event_source_id;
+ time_t set_cursor_start_timestamp;
/* autoscroll during drag timer source */
guint drag_scroll_timer_id;
@@ -427,8 +431,8 @@ thunar_tree_view_finalize (GObject *object)
g_signal_handler_disconnect (G_OBJECT (view->preferences), view->queue_resize_signal_id);
/* be sure to cancel the cursor idle source */
- if (G_UNLIKELY (view->cursor_idle_id != 0))
- g_source_remove (view->cursor_idle_id);
+ if (G_UNLIKELY (view->set_cursor_event_source_id != 0))
+ g_source_remove (view->set_cursor_event_source_id);
/* cancel any running autoscroll timer */
if (G_LIKELY (view->drag_scroll_timer_id != 0))
@@ -598,9 +602,13 @@ thunar_tree_view_set_current_directory (ThunarNavigator *navigator,
}
}
- /* schedule an idle source to set the cursor to the current directory */
- if (G_LIKELY (view->cursor_idle_id == 0))
- view->cursor_idle_id = g_idle_add_full (G_PRIORITY_LOW, thunar_tree_view_cursor_idle, view, thunar_tree_view_cursor_idle_destroy);
+ /* set the cursor to the current directory, and unfold the tree accordingly */
+ /* Multiple iterations might be needed here. We throttle the call to prevent CPU spikes in certain cases */
+ /* If we fail to set the cursor in 5 seconds, the operation is aborted. */
+ view->set_cursor_start_timestamp = time (NULL);
+ if (G_LIKELY (view->set_cursor_event_source_id == 0))
+ view->set_cursor_event_source_id = g_timeout_add_full (G_PRIORITY_LOW, 10, thunar_tree_view_set_cursor,
+ view, set_cursor_event_source_destroy);
}
/* refilter the model if necessary */
@@ -1155,8 +1163,8 @@ thunar_tree_view_test_expand_row (GtkTreeView *tree_view,
}
/* cancel the cursor idle source if not expandable */
- if (!expandable && view->cursor_idle_id != 0)
- g_source_remove (view->cursor_idle_id);
+ if (!expandable && view->set_cursor_event_source_id != 0)
+ g_source_remove (view->set_cursor_event_source_id);
return !expandable;
}
@@ -1610,7 +1618,7 @@ thunar_tree_view_selection_func (GtkTreeSelection *selection,
static gboolean
-thunar_tree_view_cursor_idle (gpointer user_data)
+thunar_tree_view_set_cursor (gpointer user_data)
{
ThunarTreeView *view = THUNAR_TREE_VIEW (user_data);
GtkTreePath *path;
@@ -1624,6 +1632,13 @@ thunar_tree_view_cursor_idle (gpointer user_data)
GList *lp;
GList *path_as_list = NULL;
+ /* Stop attempt to set the cursor if we fail to do so after 5 seconds */
+ if (time (NULL) > view->set_cursor_start_timestamp + 5)
+ {
+ g_warning ("Failed to set the tree-view cursor in less than 5 seconds. Aborting the operation.");
+ return FALSE;
+ }
+
THUNAR_THREADS_ENTER
/* for easier navigation, we sometimes want to force/keep selection of a certain path */
@@ -1728,7 +1743,7 @@ THUNAR_THREADS_ENTER
}
}
break; /* we dont have a valid child_iter by now, so we cannot continue. */
- /* Since done is FALSE, the next iteration on thunar_tree_view_cursor_idle will go deeper */
+ /* Since done is FALSE, the next iteration on thunar_tree_view_set_cursor will go deeper */
}
/* expand path up to the current tree level */
@@ -1756,9 +1771,9 @@ THUNAR_THREADS_LEAVE
static void
-thunar_tree_view_cursor_idle_destroy (gpointer user_data)
+set_cursor_event_source_destroy (gpointer user_data)
{
- THUNAR_TREE_VIEW (user_data)->cursor_idle_id = 0;
+ THUNAR_TREE_VIEW (user_data)->set_cursor_event_source_id = 0;
}