feat: separator before the first remote bookmark in the side panel

Inserts a separator row (IS_SEPARATOR column) between local and remote
bookmarks in the shortcuts model; the progress renderer draws it as a line.
This is what thunar 4.20.2-1~bpo24.04+usagebars1 was built from.
This commit is contained in:
4aiman 2026-11-03 22:21:39 +03:00
commit 49eba329ed
4 changed files with 81 additions and 1 deletions

View file

@ -217,6 +217,8 @@ struct _ThunarShortcutsModel
guint bookmarks_idle_id;
guint busy_timeout_id;
gboolean bookmark_separator_added;
};
struct _ThunarShortcut
@ -236,6 +238,7 @@ struct _ThunarShortcut
ThunarDevice *device;
guint hidden : 1;
guint is_separator : 1;
};
@ -538,6 +541,9 @@ thunar_shortcuts_model_get_column_type (GtkTreeModel *tree_model,
case THUNAR_SHORTCUTS_MODEL_COLUMN_USAGE_PERCENT:
return G_TYPE_INT;
case THUNAR_SHORTCUTS_MODEL_COLUMN_IS_SEPARATOR:
return G_TYPE_BOOLEAN;
}
_thunar_assert_not_reached ();
@ -818,6 +824,11 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
g_value_set_boolean (value, FALSE);
break;
case THUNAR_SHORTCUTS_MODEL_COLUMN_IS_SEPARATOR:
g_value_init (value, G_TYPE_BOOLEAN);
g_value_set_boolean (value, shortcut->is_separator);
break;
case THUNAR_SHORTCUTS_MODEL_COLUMN_USAGE_PERCENT:
g_value_init (value, G_TYPE_INT);
if ((shortcut->group & THUNAR_SHORTCUT_GROUP_DEVICES) != 0
@ -1410,6 +1421,18 @@ thunar_shortcuts_model_load_line (GFile *file_path,
_thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
_thunar_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL));
/* insert a separator before the first remote bookmark */
if (!thunar_shortcuts_model_local_file (file_path)
&& !model->bookmark_separator_added)
{
ThunarShortcut *sep = g_slice_new0 (ThunarShortcut);
sep->group = THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS;
sep->is_separator = TRUE;
sep->sort_id = row_num;
thunar_shortcuts_model_add_shortcut (model, sep);
model->bookmark_separator_added = TRUE;
}
shortcut = g_slice_new0 (ThunarShortcut);
shortcut->group = THUNAR_SHORTCUT_GROUP_PLACES_BOOKMARKS;
shortcut->location = g_object_ref (file_path);
@ -1471,6 +1494,9 @@ thunar_shortcuts_model_reload_bookmarks (gpointer data)
_thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
/* reset separator flag */
model->bookmark_separator_added = FALSE;
/* Find all user-defined shortcuts (bookmarks) */
for (lp = model->shortcuts; lp != NULL; lp = lp->next)
{

View file

@ -54,6 +54,7 @@ typedef enum
THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY_PULSE,
THUNAR_SHORTCUTS_MODEL_COLUMN_HIDDEN,
THUNAR_SHORTCUTS_MODEL_COLUMN_USAGE_PERCENT,
THUNAR_SHORTCUTS_MODEL_COLUMN_IS_SEPARATOR,
THUNAR_SHORTCUTS_MODEL_N_COLUMNS,
} ThunarShortcutsModelColumn;

View file

@ -36,6 +36,7 @@ enum
{
PROP_0,
PROP_USAGE_PERCENT,
PROP_IS_SEPARATOR,
};
@ -49,7 +50,8 @@ struct _ThunarShortcutsProgressRenderer
{
GtkCellRendererText __parent__;
gint usage_percent; /* -1 = no bar, 0..100 = percent used */
gint usage_percent; /* -1 = no bar, 0..100 = percent used */
gboolean is_separator;
};
@ -74,6 +76,10 @@ thunar_shortcuts_progress_renderer_get_property (GObject *object,
g_value_set_int (value, renderer->usage_percent);
break;
case PROP_IS_SEPARATOR:
g_value_set_boolean (value, renderer->is_separator);
break;
default:
G_OBJECT_CLASS (thunar_shortcuts_progress_renderer_parent_class)->get_property (object, prop_id, value, pspec);
break;
@ -96,6 +102,10 @@ thunar_shortcuts_progress_renderer_set_property (GObject *object,
renderer->usage_percent = g_value_get_int (value);
break;
case PROP_IS_SEPARATOR:
renderer->is_separator = g_value_get_boolean (value);
break;
default:
G_OBJECT_CLASS (thunar_shortcuts_progress_renderer_parent_class)->set_property (object, prop_id, value, pspec);
break;
@ -151,6 +161,24 @@ thunar_shortcuts_progress_renderer_render (GtkCellRenderer *cell,
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
/* draw a horizontal line for separator rows */
if (renderer->is_separator)
{
GdkRGBA fg_color;
context = gtk_widget_get_style_context (widget);
gtk_style_context_get_color (context, gtk_style_context_get_state (context), &fg_color);
fg_color.alpha = 0.3;
cairo_save (cr);
gdk_cairo_set_source_rgba (cr, &fg_color);
cairo_set_line_width (cr, 1.0);
cairo_move_to (cr, cell_area->x + xpad, cell_area->y + cell_area->height / 2 + 0.5);
cairo_line_to (cr, cell_area->x + cell_area->width - xpad, cell_area->y + cell_area->height / 2 + 0.5);
cairo_stroke (cr);
cairo_restore (cr);
return;
}
if (renderer->usage_percent >= 0)
{
/* calculate how much space the bar needs, then shrink cell_area for text */
@ -274,6 +302,14 @@ thunar_shortcuts_progress_renderer_class_init (ThunarShortcutsProgressRendererCl
"Disk usage percentage (0-100, -1 = hidden)",
-1, 100, -1,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_IS_SEPARATOR,
g_param_spec_boolean ("is-separator",
"is-separator",
"Draw a horizontal line instead of text",
FALSE,
G_PARAM_READWRITE));
}

View file

@ -320,6 +320,20 @@ thunar_shortcuts_view_navigator_init (ThunarNavigatorIface *iface)
static gboolean
thunar_shortcuts_view_row_separator (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
gboolean is_separator = FALSE;
gtk_tree_model_get (model, iter,
THUNAR_SHORTCUTS_MODEL_COLUMN_IS_SEPARATOR, &is_separator,
-1);
return is_separator;
}
static void
thunar_shortcuts_view_init (ThunarShortcutsView *view)
{
@ -332,6 +346,8 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (view), THUNAR_SHORTCUTS_MODEL_COLUMN_TOOLTIP);
/* no row_separator_func — separator is drawn by the progress renderer */
/* grab a reference on the provider factory */
view->provider_factory = thunarx_provider_factory_get_default ();
@ -403,6 +419,7 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
gtk_tree_view_column_set_attributes (column, renderer,
"text", THUNAR_SHORTCUTS_MODEL_COLUMN_NAME,
"usage-percent", THUNAR_SHORTCUTS_MODEL_COLUMN_USAGE_PERCENT,
"is-separator", THUNAR_SHORTCUTS_MODEL_COLUMN_IS_SEPARATOR,
"visible", THUNAR_SHORTCUTS_MODEL_COLUMN_IS_ITEM,
NULL);