Stick process view at the top in the absence of user action

Until the user manually scrolls down by some means, the view remains
stuck at the top. When the view subsequently returns to this position,
it automatically sticks again, pending further user action.

Closes: #18
MR: !30
This commit is contained in:
Gaël Bonithon
2022-02-12 13:18:17 +01:00
committed by Alexander Schwinn
parent 8751a5dbb0
commit 8500675125
2 changed files with 67 additions and 1 deletions

View File

@@ -839,6 +839,9 @@ xtm_process_tree_view_highlight_pid (XtmProcessTreeView *treeview, GPid pid) {
{
path = gtk_tree_model_get_path (model, &iter);
gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), path);
/* set cursor before scrolling to unstick the view from top if needed */
gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, NULL, FALSE);
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (treeview), path, NULL, TRUE, 0.5, 0);
gtk_tree_path_free (path);
break;

View File

@@ -66,6 +66,7 @@ struct _XtmProcessWindow
gint width;
gint height;
gulong handler;
gboolean view_stuck;
};
G_DEFINE_TYPE (XtmProcessWindow, xtm_process_window, GTK_TYPE_WIDGET)
@@ -230,6 +231,52 @@ show_settings_dialog (GtkButton *button, gpointer user_data)
g_signal_handler_unblock (G_OBJECT (window->window), window->handler);
}
static void
xtm_process_window_stick_view (GtkAdjustment *adjustment, XtmProcessWindow *window)
{
if (window->view_stuck)
gtk_adjustment_set_value (adjustment, 0);
else if (gtk_adjustment_get_value (adjustment) == 0)
window->view_stuck = TRUE;
}
static gboolean
xtm_process_window_unstick_view_event (GtkWidget *widget, GdkEvent *event, XtmProcessWindow *window)
{
GdkScrollDirection dir;
gdouble y;
if (! window->view_stuck)
return FALSE;
if (event->type == GDK_SCROLL && (
(gdk_event_get_scroll_direction (event, &dir) && dir == GDK_SCROLL_UP)
|| (gdk_event_get_scroll_deltas (event, NULL, &y) && y <= 0)
))
return FALSE;
window->view_stuck = FALSE;
return FALSE;
}
static void
xtm_process_window_unstick_view_cursor (GtkTreeView *tree_view, XtmProcessWindow *window)
{
GtkTreePath *cursor, *end;
if (! window->view_stuck)
return;
gtk_tree_view_get_cursor (tree_view, &cursor, NULL);
gtk_tree_view_get_visible_range (tree_view, NULL, &end);
if (gtk_tree_path_compare (cursor, end) >= 0)
window->view_stuck = FALSE;
gtk_tree_path_free (cursor);
gtk_tree_path_free (end);
}
static void
xtm_process_window_init (XtmProcessWindow *window)
{
@@ -297,7 +344,23 @@ xtm_process_window_init (XtmProcessWindow *window)
window->treeview = xtm_process_tree_view_new ();
gtk_widget_show (window->treeview);
gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (window->builder, "scrolledwindow")), window->treeview);
{
GtkScrolledWindow *s_window;
GtkWidget *bar;
GtkAdjustment *adjust;
s_window = GTK_SCROLLED_WINDOW (gtk_builder_get_object (window->builder, "scrolledwindow"));
bar = gtk_scrolled_window_get_vscrollbar (s_window);
adjust = gtk_scrolled_window_get_vadjustment (s_window);
window->view_stuck = TRUE;
gtk_container_add (GTK_CONTAINER (s_window), window->treeview);
g_signal_connect (adjust, "value-changed", G_CALLBACK (xtm_process_window_stick_view), window);
g_signal_connect (bar, "button-press-event", G_CALLBACK (xtm_process_window_unstick_view_event), window);
g_signal_connect (bar, "scroll-event", G_CALLBACK (xtm_process_window_unstick_view_event), window);
g_signal_connect (window->treeview, "scroll-event", G_CALLBACK (xtm_process_window_unstick_view_event), window);
g_signal_connect (window->treeview, "cursor-changed", G_CALLBACK (xtm_process_window_unstick_view_cursor), window);
}
g_object_bind_property(window->settings, "show-legend",
gtk_builder_get_object(window->builder, "legend"), "visible",