From 558cedae18760e72f5a756b276a8eee45c35d0d4 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 6 Jan 2026 16:10:43 +0000 Subject: [PATCH 01/31] Include details width in slot width, scroll to slot on show, hide --- src/View/Miller.vala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/View/Miller.vala b/src/View/Miller.vala index 5648aed47..e498daac8 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -40,7 +40,7 @@ namespace Files.View { public GLib.List slot_list = null; public int total_width = 0; - private View.DetailsColumn details; + private View.DetailsColumn? details = null; public override bool is_frozen { set { @@ -149,7 +149,10 @@ namespace Files.View { details = new View.DetailsColumn (file, view); last_slot.colpane.pack_start (details, false, false); last_slot.hpane.show_all (); + last_slot.width += details.width; update_total_width (); + schedule_scroll_to_slot (last_slot, true); + return Source.REMOVE; }); } @@ -157,9 +160,12 @@ namespace Files.View { public void clear_file_details () { if (details is Gtk.Widget) { + last_slot.width -= details.width; last_slot.colpane.remove (details); last_slot.hpane.show_all (); + details = null; update_total_width (); + schedule_scroll_to_slot (last_slot, true); } } From 9c4e9a2f26e6126bc3c46df81de75d323a641c0a Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Mon, 26 Jan 2026 20:13:58 +0000 Subject: [PATCH 02/31] Ensure details drawn in last slot --- src/View/Miller.vala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/View/Miller.vala b/src/View/Miller.vala index e4b854874..7f7db4839 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -480,9 +480,13 @@ namespace Files.View { private void on_slot_selection_changed (AbstractSlot source, GLib.List files) { if (source == current_slot) { clear_file_details (); + if (Files.Preferences.get_default ().show_file_preview && files.length () == 1) { + // Preview must be added to the last slot so make sure current slot + // is the last + truncate_list_after_slot (current_slot); draw_file_details (files.data, current_slot.get_directory_view ()); } } From 8d7d9d4d6150295595de33d584fddd4db554a897 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 27 Jan 2026 13:46:20 +0000 Subject: [PATCH 03/31] Allow side widget in AbstractSlot (using Box) --- libcore/AbstractSlot.vala | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/libcore/AbstractSlot.vala b/libcore/AbstractSlot.vala index e3f5025d4..61b58b360 100644 --- a/libcore/AbstractSlot.vala +++ b/libcore/AbstractSlot.vala @@ -48,7 +48,9 @@ public abstract class Files.AbstractSlot : GLib.Object { protected Gtk.Box extra_location_widgets; protected Gtk.Box extra_action_widgets; - protected Gtk.Box content_box; + protected Gtk.Grid content_box; + protected Gtk.Box side_widget_box; + public Gtk.Overlay overlay { get; protected set; } public int slot_number { get; protected set; } protected int width; @@ -77,17 +79,21 @@ public abstract class Files.AbstractSlot : GLib.Object { content_box.add (overlay); } + protected void add_side_widget (Gtk.Widget widget, bool expand, bool fill, uint padding) { + side_widget_box.pack_end (widget, expand, fill, padding); + } + construct { - content_box = new Gtk.Box (VERTICAL, 0) { + content_box = new Gtk.Grid () { vexpand = true, hexpand = true }; - extra_location_widgets = new Gtk.Box (VERTICAL, 0); - content_box.add (extra_location_widgets); + side_widget_box = new Gtk.Box (HORIZONTAL, 0); extra_action_widgets = new Gtk.Box (VERTICAL, 0); content_box.add (extra_action_widgets); + side_widget_box.pack_start (content_box, true, true, 0); slot_number = -1; } @@ -107,8 +113,8 @@ public abstract class Files.AbstractSlot : GLib.Object { public virtual void zoom_in () {} public virtual void zoom_normal () {} public virtual bool set_all_selected (bool all_selected) { return false; } - public virtual Gtk.Widget get_content_box () { return content_box as Gtk.Widget; } + public virtual Gtk.Widget get_content_box () { return side_widget_box as Gtk.Widget; } public virtual string? get_root_uri () { return directory.file.uri; } public virtual string? get_tip_uri () { return null; } - public virtual bool get_realized () { return content_box.get_realized (); } + public virtual bool get_realized () { return side_widget_box.get_realized (); } } From c0e20b6c81e981f9363b43f883fd06f442deab36 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 27 Jan 2026 13:46:48 +0000 Subject: [PATCH 04/31] Use only one scrolled window in DetailsColumn --- src/View/DetailsColumn.vala | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index 891967e2c..efb238d04 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -41,8 +41,9 @@ public class Files.View.DetailsColumn : Gtk.Bin { hexpand = true, vexpand = true, halign = CENTER, - valign = CENTER + valign = CENTER, }; + file_image.get_style_context ().add_class (Granite.STYLE_CLASS_CARD); file_image.get_style_context ().add_class (Granite.STYLE_CLASS_CHECKERBOARD); @@ -214,36 +215,33 @@ public class Files.View.DetailsColumn : Gtk.Bin { var box = new Gtk.Box (VERTICAL, 12) { halign = CENTER, + hexpand = true, margin_top = 12, margin_bottom = 12, margin_start = 12, margin_end = 12, }; + var scrolled_window = new Gtk.ScrolledWindow (null, null) { + width_request = PREVIEW_SIZE, + max_content_height = PREVIEW_SIZE, + max_content_width = PREVIEW_SIZE, + min_content_height = PREVIEW_SIZE / 2, + min_content_width = PREVIEW_SIZE / 2, + }; + if (previewing_text) { - var text_window = new Gtk.ScrolledWindow (null, null) { - child = file_text, - width_request = PREVIEW_SIZE, - height_request = PREVIEW_SIZE, - max_content_height = PREVIEW_SIZE, - max_content_width = PREVIEW_SIZE - }; - - box.add (text_window); + scrolled_window.child = file_text; } else { - box.add (file_image); + scrolled_window.child = file_image; } + box.add (scrolled_window); + box.add (new Gtk.Separator (HORIZONTAL)); box.add (info_grid); box.add (more_info_button); - var scrolled = new Gtk.ScrolledWindow (null, null) { - child = box, - propagate_natural_height = true, - hscrollbar_policy = NEVER - }; - - child = scrolled; + child = box; show_all (); more_info_button.clicked.connect (() => { From c59ed923555cacc7ee16d3289ab9729636e5bac8 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 27 Jan 2026 13:48:55 +0000 Subject: [PATCH 05/31] Add details column as Miller slot side widget --- src/View/Miller.vala | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/View/Miller.vala b/src/View/Miller.vala index 7f7db4839..9a00a8c20 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -147,9 +147,7 @@ namespace Files.View { draw_file_details_timeout_id = Timeout.add (200, () => { draw_file_details_timeout_id = 0; details = new View.DetailsColumn (file, view); - last_slot.colpane.add (details); - last_slot.hpane.show_all (); - last_slot.width += details.width; + add_side_widget (details, true, true, 0); update_total_width (); schedule_scroll_to_slot (last_slot, true); @@ -160,12 +158,8 @@ namespace Files.View { public void clear_file_details () { if (details is Gtk.Widget) { - last_slot.width -= details.width; - last_slot.colpane.remove (details); - last_slot.hpane.show_all (); - details = null; + details.destroy (); update_total_width (); - schedule_scroll_to_slot (last_slot, true); } } From afc343a0988b71904dc5c7795ed17ced1e45eced Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 27 Jan 2026 14:08:40 +0000 Subject: [PATCH 06/31] Tweak packing of details column --- libcore/AbstractSlot.vala | 2 +- src/View/DetailsColumn.vala | 7 ++----- src/View/Miller.vala | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/libcore/AbstractSlot.vala b/libcore/AbstractSlot.vala index 61b58b360..1f034c1f5 100644 --- a/libcore/AbstractSlot.vala +++ b/libcore/AbstractSlot.vala @@ -93,7 +93,7 @@ public abstract class Files.AbstractSlot : GLib.Object { extra_action_widgets = new Gtk.Box (VERTICAL, 0); content_box.add (extra_action_widgets); - side_widget_box.pack_start (content_box, true, true, 0); + side_widget_box.pack_start (content_box, false, true, 0); slot_number = -1; } diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index efb238d04..bd71812b2 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -30,6 +30,7 @@ public class Files.View.DetailsColumn : Gtk.Bin { } construct { + hexpand = false; var file_real_size = PropertiesWindow.file_real_size (file); var info_grid = new Gtk.Grid () { @@ -215,19 +216,15 @@ public class Files.View.DetailsColumn : Gtk.Bin { var box = new Gtk.Box (VERTICAL, 12) { halign = CENTER, - hexpand = true, margin_top = 12, margin_bottom = 12, - margin_start = 12, margin_end = 12, + width_request = PREVIEW_SIZE + 2 * margin_end }; var scrolled_window = new Gtk.ScrolledWindow (null, null) { - width_request = PREVIEW_SIZE, max_content_height = PREVIEW_SIZE, max_content_width = PREVIEW_SIZE, - min_content_height = PREVIEW_SIZE / 2, - min_content_width = PREVIEW_SIZE / 2, }; if (previewing_text) { diff --git a/src/View/Miller.vala b/src/View/Miller.vala index 9a00a8c20..43065998a 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -147,7 +147,7 @@ namespace Files.View { draw_file_details_timeout_id = Timeout.add (200, () => { draw_file_details_timeout_id = 0; details = new View.DetailsColumn (file, view); - add_side_widget (details, true, true, 0); + add_side_widget (details, false, false, 0); update_total_width (); schedule_scroll_to_slot (last_slot, true); From f5229e7ebcd1d6f308689700cf9ef71de5ea6b76 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 17:22:38 +0000 Subject: [PATCH 07/31] Use Paned to contain content_box and detailscolumn --- libcore/AbstractSlot.vala | 10 +++++----- src/View/Miller.vala | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libcore/AbstractSlot.vala b/libcore/AbstractSlot.vala index 1f034c1f5..3fd17fcbc 100644 --- a/libcore/AbstractSlot.vala +++ b/libcore/AbstractSlot.vala @@ -49,7 +49,7 @@ public abstract class Files.AbstractSlot : GLib.Object { protected Gtk.Box extra_location_widgets; protected Gtk.Box extra_action_widgets; protected Gtk.Grid content_box; - protected Gtk.Box side_widget_box; + protected Gtk.Paned side_widget_box; public Gtk.Overlay overlay { get; protected set; } public int slot_number { get; protected set; } @@ -79,8 +79,8 @@ public abstract class Files.AbstractSlot : GLib.Object { content_box.add (overlay); } - protected void add_side_widget (Gtk.Widget widget, bool expand, bool fill, uint padding) { - side_widget_box.pack_end (widget, expand, fill, padding); + protected void add_side_widget (Gtk.Widget widget) { + side_widget_box.pack2 (widget, false, false); } construct { @@ -89,11 +89,11 @@ public abstract class Files.AbstractSlot : GLib.Object { hexpand = true }; - side_widget_box = new Gtk.Box (HORIZONTAL, 0); + side_widget_box = new Gtk.Paned (HORIZONTAL); extra_action_widgets = new Gtk.Box (VERTICAL, 0); content_box.add (extra_action_widgets); - side_widget_box.pack_start (content_box, false, true, 0); + side_widget_box.pack1 (content_box, true, false); slot_number = -1; } diff --git a/src/View/Miller.vala b/src/View/Miller.vala index 43065998a..4aa336fd1 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -147,7 +147,7 @@ namespace Files.View { draw_file_details_timeout_id = Timeout.add (200, () => { draw_file_details_timeout_id = 0; details = new View.DetailsColumn (file, view); - add_side_widget (details, false, false, 0); + add_side_widget (details); update_total_width (); schedule_scroll_to_slot (last_slot, true); From 586018a88316f93f65bbc2aca51ea00afe8407f7 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 17:35:30 +0000 Subject: [PATCH 08/31] Tweak packing into paned --- libcore/AbstractSlot.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcore/AbstractSlot.vala b/libcore/AbstractSlot.vala index 3fd17fcbc..ed094997a 100644 --- a/libcore/AbstractSlot.vala +++ b/libcore/AbstractSlot.vala @@ -80,7 +80,7 @@ public abstract class Files.AbstractSlot : GLib.Object { } protected void add_side_widget (Gtk.Widget widget) { - side_widget_box.pack2 (widget, false, false); + side_widget_box.pack2 (widget, false, true); } construct { @@ -93,7 +93,7 @@ public abstract class Files.AbstractSlot : GLib.Object { extra_action_widgets = new Gtk.Box (VERTICAL, 0); content_box.add (extra_action_widgets); - side_widget_box.pack1 (content_box, true, false); + side_widget_box.pack1 (content_box, true, true); slot_number = -1; } From 470ce88f7822b2b4a800142aa2981555415259c1 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 17:36:01 +0000 Subject: [PATCH 09/31] Scroll to current slot when paned pos changes --- src/View/Miller.vala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/View/Miller.vala b/src/View/Miller.vala index 4aa336fd1..e3f536cfc 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -86,6 +86,9 @@ namespace Files.View { }; hadj = scrolled_window.get_hadjustment (); + hadj.notify["page-size"].connect (() => { + schedule_scroll_to_slot (current_slot); + }); add_overlay (scrolled_window); From 388426f521da0e7ba3c7921bf853ccced92f7ed2 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 17:38:45 +0000 Subject: [PATCH 10/31] Make preview width comparable to columnview --- src/View/DetailsColumn.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index bd71812b2..3c554d80d 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -15,8 +15,8 @@ public class Files.View.DetailsColumn : Gtk.Bin { public Files.File file { get; construct; } public Files.AbstractDirectoryView view { get; construct; } - private const int PREVIEW_SIZE = 512; - private const int PREVIEW_H_MARGIN = 24; + private const int PREVIEW_SIZE = 256; + private const int PREVIEW_H_MARGIN = 12; private const int MAX_PREVIEW_FILE_SIZE = 2 * 8 * 1024 * 1024; // 2MB private GLib.Cancellable? cancellable; private Gtk.Label resolution_value; From b965c983fb4c74d65c6e91b53df61e837c12847a Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 17:45:59 +0000 Subject: [PATCH 11/31] Lose unneeded spinner --- src/View/DetailsColumn.vala | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index 3c554d80d..fad6b0548 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -122,17 +122,13 @@ public class Files.View.DetailsColumn : Gtk.Bin { /** begin adapted copy-pasta from PropertiesWindow.construct_info_panel **/ var size_key_label = make_key_label (_("Size:")); - var spinner = new Gtk.Spinner () { - halign = START - }; var size_value = make_value_label (""); size_value.label = GLib.format_size (file_real_size); info_grid.attach (name_key_label, 0, 1); info_grid.attach_next_to (name_value, name_key_label, RIGHT); - info_grid.attach (size_key_label, 0, 2, 1); - info_grid.attach_next_to (spinner, size_key_label, RIGHT); + info_grid.attach (size_key_label, 0, 2); info_grid.attach_next_to (size_value, size_key_label, RIGHT); var time_created = FileUtils.get_formatted_time_attribute_from_info ( From b08daf5ba3f4d9fe1f573c86d03973f04036cacf Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 19:27:20 +0000 Subject: [PATCH 12/31] FileUtils: option not to pad formatted date-time --- libcore/FileUtils.vala | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/libcore/FileUtils.vala b/libcore/FileUtils.vala index 15df61484..adb73c83f 100644 --- a/libcore/FileUtils.vala +++ b/libcore/FileUtils.vala @@ -589,7 +589,8 @@ namespace Files.FileUtils { public string get_formatted_time_attribute_from_info ( FileInfo info, string attr, - DateFormatMode format = Files.Preferences.get_default ().date_format + DateFormatMode format = Files.Preferences.get_default ().date_format, + bool pad = true ) { DateTime? dt = null; switch (attr) { @@ -619,32 +620,36 @@ namespace Files.FileUtils { break; } - return get_formatted_date_time (dt, format); + return get_formatted_date_time (dt, format, pad); } - private string get_formatted_date_time (DateTime? dt, DateFormatMode format) { + private string get_formatted_date_time (DateTime? dt, DateFormatMode format, bool pad = true) { if (dt == null) { return ""; } switch (format) { case DateFormatMode.LOCALE: - return emspace_pad (dt.format ("%c")); + return emspace_pad (dt.format ("%c"), pad); case DateFormatMode.ISO: - return emspace_pad (dt.format ("%Y-%m-%d %H:%M:%S")); + return emspace_pad (dt.format ("%Y-%m-%d %H:%M:%S"), pad); case DateFormatMode.COMPACT : var locale_format_string = Posix.nl_langinfo (D_FMT); var compact_format = string.join (" ", locale_format_string.down (), "%H:%M"); - return emspace_pad (dt.format (compact_format)); + return emspace_pad (dt.format (compact_format), pad); default: - return emspace_pad (get_informal_date_time (dt)); + return emspace_pad (get_informal_date_time (dt), pad); } } // We add a fixed-width space as both prefix and suffix to ensure date is not obscured by the scrollbar (unless hovered) // regardless of the text direction // See https://github.com/elementary/files/issues/1538 - private string emspace_pad (string s) { + private string emspace_pad (string s, bool pad) { + if (!pad) { + return s; + } + var sb = new StringBuilder (s); sb.prepend_unichar (' '); //Unichar emspace (U2003); sb.append_unichar (' '); //Unichar emspace (U2003); From d9f4001712331a889b263bef6de2461d7dab1e5a Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 19:27:49 +0000 Subject: [PATCH 13/31] Allow value labels to wrap and ellupsize --- src/Utils/AppUtils.vala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Utils/AppUtils.vala b/src/Utils/AppUtils.vala index 8ee47e5d5..2aa418e43 100644 --- a/src/Utils/AppUtils.vala +++ b/src/Utils/AppUtils.vala @@ -37,7 +37,11 @@ namespace Files { return new Gtk.Label (label) { halign = Gtk.Align.START, selectable = true, - use_markup = true + use_markup = true, + wrap = true, + ellipsize = END, + lines = 2, + xalign = 0 }; } } From b370effbcea93fbd91b369571de38b629523b048 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 19:28:31 +0000 Subject: [PATCH 14/31] Packing of side widget specified by caller --- libcore/AbstractSlot.vala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libcore/AbstractSlot.vala b/libcore/AbstractSlot.vala index ed094997a..47c4d175a 100644 --- a/libcore/AbstractSlot.vala +++ b/libcore/AbstractSlot.vala @@ -79,8 +79,9 @@ public abstract class Files.AbstractSlot : GLib.Object { content_box.add (overlay); } - protected void add_side_widget (Gtk.Widget widget) { - side_widget_box.pack2 (widget, false, true); + protected void add_side_widget (Gtk.Widget widget, bool resize, bool shrink) { + // Settings suitable for preview widget + side_widget_box.pack2 (widget, resize, shrink); } construct { From cb0eb4c824563b3dc7c0e68548d5dd40f44340e3 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 19:31:54 +0000 Subject: [PATCH 15/31] DetailsColumn: Use unpadded date-time, simplify --- src/View/DetailsColumn.vala | 43 ++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index fad6b0548..0975c3d2c 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -131,7 +131,7 @@ public class Files.View.DetailsColumn : Gtk.Bin { info_grid.attach (size_key_label, 0, 2); info_grid.attach_next_to (size_value, size_key_label, RIGHT); - var time_created = FileUtils.get_formatted_time_attribute_from_info ( + var time_created = get_formated_date_time_from_info ( file.info, FileAttribute.TIME_CREATED ); @@ -140,12 +140,12 @@ public class Files.View.DetailsColumn : Gtk.Bin { if (time_created != "") { var key_label = make_key_label (_("Created:")); var value_label = make_value_label (time_created); - info_grid.attach (key_label, 0, n, 1, 1); + info_grid.attach (key_label, 0, n++); info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); n++; } - var time_modified = FileUtils.get_formatted_time_attribute_from_info ( + var time_modified = get_formated_date_time_from_info ( file.info, FileAttribute.TIME_MODIFIED ); @@ -153,13 +153,12 @@ public class Files.View.DetailsColumn : Gtk.Bin { if (time_modified != "") { var key_label = make_key_label (_("Modified:")); var value_label = make_value_label (time_modified); - info_grid.attach (key_label, 0, n, 1, 1); - info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); - n++; + info_grid.attach (key_label, 0, n++); + info_grid.attach_next_to (value_label, key_label, RIGHT); } if (file.is_trashed ()) { - var deletion_date = FileUtils.get_formatted_time_attribute_from_info ( + var deletion_date = get_formated_date_time_from_info ( file.info, FileAttribute.TRASH_DELETION_DATE ); @@ -167,25 +166,22 @@ public class Files.View.DetailsColumn : Gtk.Bin { if (deletion_date != "") { var key_label = make_key_label (_("Deleted:")); var value_label = make_value_label (deletion_date); - info_grid.attach (key_label, 0, n, 1, 1); + info_grid.attach (key_label, 0, n++); info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); - n++; } } var ftype = filetype (file); var mimetype_key = make_key_label (_("Media type:")); var mimetype_value = make_value_label (ftype); - info_grid.attach (mimetype_key, 0, n, 1, 1); + info_grid.attach (mimetype_key, 0, n++); info_grid.attach_next_to (mimetype_value, mimetype_key, RIGHT, 3, 1); - n++; if (file.is_image ()) { var resolution_key = make_key_label (_("Resolution:")); resolution_value = make_value_label (resolution (file)); - info_grid.attach (resolution_key, 0, n, 1, 1); + info_grid.attach (resolution_key, 0, n++); info_grid.attach_next_to (resolution_value, resolution_key, RIGHT, 3, 1); - n++; } if (file.info.get_attribute_boolean (GLib.FileAttribute.STANDARD_IS_SYMLINK)) { @@ -193,21 +189,22 @@ public class Files.View.DetailsColumn : Gtk.Bin { var value_label = make_value_label ( file.info.get_attribute_byte_string (GLib.FileAttribute.STANDARD_SYMLINK_TARGET) ); - info_grid.attach (key_label, 0, n, 1, 1); + info_grid.attach (key_label, 0, n++); info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); - n++; } if (file.is_trashed ()) { var key_label = make_key_label (_("Original Location:")); var value_label = make_value_label (original_location (file)); - info_grid.attach (key_label, 0, n, 1, 1); + info_grid.attach (key_label, 0, n++); info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); n++; } var more_info_button = new Gtk.Button.with_label (_("Properties…")) { - halign = END + halign = END, + margin_end = 12, + margin_bottom = 12 }; var box = new Gtk.Box (VERTICAL, 12) { @@ -244,6 +241,18 @@ public class Files.View.DetailsColumn : Gtk.Bin { }); } + private static string get_formated_date_time_from_info ( + FileInfo info, + string attrib + ) { + // We do not want padded string and we want max detail + return FileUtils.get_formatted_time_attribute_from_info ( + info, + attrib, + DateFormatMode.LOCALE, + false // Do not add hard padding (cannot easily remove) + ); + } /** Also an adjusted copy from PropertiesWindow **/ public static string original_location (Files.File file) { /* print orig location of trashed files */ From f16a4aac11a242c4963c530d24882783933652c7 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 19:32:35 +0000 Subject: [PATCH 16/31] DetailsColumn: Simplify layout --- src/View/DetailsColumn.vala | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index 0975c3d2c..f5afd7169 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -6,17 +6,11 @@ */ public class Files.View.DetailsColumn : Gtk.Bin { - public int width { - get { - return PREVIEW_SIZE + 2 * PREVIEW_H_MARGIN; - } - } public Files.File file { get; construct; } public Files.AbstractDirectoryView view { get; construct; } - private const int PREVIEW_SIZE = 256; - private const int PREVIEW_H_MARGIN = 12; + private const int PREVIEW_SIZE = 256 + 100; private const int MAX_PREVIEW_FILE_SIZE = 2 * 8 * 1024 * 1024; // 2MB private GLib.Cancellable? cancellable; private Gtk.Label resolution_value; @@ -30,7 +24,9 @@ public class Files.View.DetailsColumn : Gtk.Bin { } construct { + width_request = PREVIEW_SIZE; hexpand = false; + var file_real_size = PropertiesWindow.file_real_size (file); var info_grid = new Gtk.Grid () { @@ -39,8 +35,6 @@ public class Files.View.DetailsColumn : Gtk.Bin { }; var file_image = new Gtk.Image () { - hexpand = true, - vexpand = true, halign = CENTER, valign = CENTER, }; @@ -51,10 +45,6 @@ public class Files.View.DetailsColumn : Gtk.Bin { var file_text = new Gtk.TextView () { cursor_visible = false, editable = false, - top_margin = 12, - bottom_margin = 12, - left_margin = 12, - right_margin = 12, }; Gdk.Pixbuf? ico_pix = file.get_icon_pixbuf ( @@ -209,15 +199,11 @@ public class Files.View.DetailsColumn : Gtk.Bin { var box = new Gtk.Box (VERTICAL, 12) { halign = CENTER, - margin_top = 12, - margin_bottom = 12, - margin_end = 12, - width_request = PREVIEW_SIZE + 2 * margin_end }; var scrolled_window = new Gtk.ScrolledWindow (null, null) { - max_content_height = PREVIEW_SIZE, - max_content_width = PREVIEW_SIZE, + propagate_natural_width = true, + propagate_natural_height = true }; if (previewing_text) { @@ -226,7 +212,7 @@ public class Files.View.DetailsColumn : Gtk.Bin { scrolled_window.child = file_image; } - box.add (scrolled_window); + box.pack_start (scrolled_window, false, false, 0); box.add (new Gtk.Separator (HORIZONTAL)); box.add (info_grid); box.add (more_info_button); From 8f18a311a112a6bd1b6d8cdd15df366fc48a5451 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 19:32:58 +0000 Subject: [PATCH 17/31] Miller: specify packing of details column into paned --- src/View/Miller.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/View/Miller.vala b/src/View/Miller.vala index e3f536cfc..749510c04 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -150,7 +150,7 @@ namespace Files.View { draw_file_details_timeout_id = Timeout.add (200, () => { draw_file_details_timeout_id = 0; details = new View.DetailsColumn (file, view); - add_side_widget (details); + add_side_widget (details, false, true); // Shrink but not resize update_total_width (); schedule_scroll_to_slot (last_slot, true); From 8572bef78216d169c27433dfbe827af93e3aabaf Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 29 Jan 2026 19:49:22 +0000 Subject: [PATCH 18/31] Cleanup lint --- libcore/AbstractSlot.vala | 1 - src/View/DetailsColumn.vala | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libcore/AbstractSlot.vala b/libcore/AbstractSlot.vala index 47c4d175a..e6fdbb8f5 100644 --- a/libcore/AbstractSlot.vala +++ b/libcore/AbstractSlot.vala @@ -80,7 +80,6 @@ public abstract class Files.AbstractSlot : GLib.Object { } protected void add_side_widget (Gtk.Widget widget, bool resize, bool shrink) { - // Settings suitable for preview widget side_widget_box.pack2 (widget, resize, shrink); } diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index f5afd7169..f26ad23cb 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -228,7 +228,7 @@ public class Files.View.DetailsColumn : Gtk.Bin { } private static string get_formated_date_time_from_info ( - FileInfo info, + FileInfo info, string attrib ) { // We do not want padded string and we want max detail From 64f73ae61ab5f4526e9280d29e30bc9a0dea73ae Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Fri, 30 Jan 2026 17:17:50 +0000 Subject: [PATCH 19/31] AbstractSlot: Layout overlay on construct to ensure correct position --- libcore/AbstractSlot.vala | 19 +++++++++++-------- src/View/Miller.vala | 2 +- src/View/Slot.vala | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/libcore/AbstractSlot.vala b/libcore/AbstractSlot.vala index e6fdbb8f5..a499b03bc 100644 --- a/libcore/AbstractSlot.vala +++ b/libcore/AbstractSlot.vala @@ -46,6 +46,7 @@ public abstract class Files.AbstractSlot : GLib.Object { public virtual bool is_frozen { get; set; default = true; } + //TODO Make private so layout fixed? protected Gtk.Box extra_location_widgets; protected Gtk.Box extra_action_widgets; protected Gtk.Grid content_box; @@ -70,13 +71,8 @@ public abstract class Files.AbstractSlot : GLib.Object { extra_action_widgets.add (widget); } - public void add_overlay (Gtk.Widget widget) { - overlay = new Gtk.Overlay () { - hexpand = true, - vexpand = true, - child = widget - }; - content_box.add (overlay); + public void add_overlay_widget (Gtk.Widget widget) { + overlay.child = widget; } protected void add_side_widget (Gtk.Widget widget, bool resize, bool shrink) { @@ -89,10 +85,17 @@ public abstract class Files.AbstractSlot : GLib.Object { hexpand = true }; + overlay = new Gtk.Overlay () { + hexpand = true, + vexpand = true, + }; + side_widget_box = new Gtk.Paned (HORIZONTAL); extra_action_widgets = new Gtk.Box (VERTICAL, 0); - content_box.add (extra_action_widgets); + content_box.attach (extra_action_widgets, 0, 0); + content_box.attach (overlay, 0, 1); + side_widget_box.pack1 (content_box, true, true); slot_number = -1; } diff --git a/src/View/Miller.vala b/src/View/Miller.vala index 749510c04..42e587756 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -90,7 +90,7 @@ namespace Files.View { schedule_scroll_to_slot (current_slot); }); - add_overlay (scrolled_window); + add_overlay_widget (scrolled_window); content_box.show_all (); diff --git a/src/View/Slot.vala b/src/View/Slot.vala index df4c73370..6fcb20ac2 100644 --- a/src/View/Slot.vala +++ b/src/View/Slot.vala @@ -102,7 +102,7 @@ namespace Files.View { /* Miller View creates its own overlay and handles packing of the directory view */ if (mode != ViewMode.MILLER_COLUMNS) { - add_overlay (dir_view); + add_overlay_widget (dir_view); } connect_dir_signals (); From cc94e5a92e232cc9f435a4e9dbc3698331203058 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Fri, 30 Jan 2026 17:47:51 +0000 Subject: [PATCH 20/31] Ensure trash plugin updates when active slot changes without reloading --- plugins/pantheon-files-trash/plugin.vala | 8 ++++++-- src/View/Miller.vala | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/pantheon-files-trash/plugin.vala b/plugins/pantheon-files-trash/plugin.vala index e2d2b85ed..28385df8a 100644 --- a/plugins/pantheon-files-trash/plugin.vala +++ b/plugins/pantheon-files-trash/plugin.vala @@ -113,13 +113,17 @@ public class Files.Plugins.Trash : Files.Plugins.Base { }); view.add_extra_action_widget (actionbar); + actionbar.show_all (); + actionbars.@set (view, actionbar); } - set_actionbar (actionbar); + + } else if (actionbar != null) { /* not showing trash directory */ - actionbar.destroy (); actionbars.unset (view); + actionbar.destroy (); + actionbar = null; } } diff --git a/src/View/Miller.vala b/src/View/Miller.vala index 42e587756..d717b25c4 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -350,7 +350,6 @@ namespace Files.View { **/ private void on_slot_active (Files.AbstractSlot aslot, bool scroll = true, bool animate = true) { View.Slot slot; - if (!(aslot is View.Slot)) { return; } else { @@ -372,6 +371,10 @@ namespace Files.View { } /* Always emit this signal so that UI updates (e.g. pathbar) */ active (); + + // Ensure plugins (especially trash plugins) update as directory is not + // actually reloaded + plugins.directory_loaded (this.ctab.window, this, slot.directory.file); } private void show_hidden_files_changed (bool show_hidden) { From 36ea31506afce504f4d486dab921b4c52d27994c Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 31 Jan 2026 18:37:10 +0000 Subject: [PATCH 21/31] Refine scrolling and sizing in Miller View --- src/View/Miller.vala | 60 ++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/src/View/Miller.vala b/src/View/Miller.vala index d717b25c4..36061ecfd 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -18,6 +18,8 @@ namespace Files.View { public class Miller : Files.AbstractSlot { + private const int END_GAP = 120; // Space for manually expanding last slot + private const int ANIMATION_RATE_MSEC = 1000 / 60 ; public unowned View.ViewContainer ctab { get; construct; } /* Need private copy of initial location as Miller @@ -29,6 +31,8 @@ namespace Files.View { private uint scroll_to_slot_timeout_id = 0; private Gtk.ScrolledWindow scrolled_window; + private double page_size; + private Gtk.Viewport viewport; public Gtk.Adjustment hadj; public unowned View.Slot? current_slot; @@ -87,7 +91,11 @@ namespace Files.View { hadj = scrolled_window.get_hadjustment (); hadj.notify["page-size"].connect (() => { - schedule_scroll_to_slot (current_slot); + // Ignore many notififications where page_size has not changed + if ((hadj.page_size - page_size).abs () > 12) { + this.page_size = hadj.page_size; + schedule_scroll_to_slot (current_slot); + } }); add_overlay_widget (scrolled_window); @@ -112,7 +120,10 @@ namespace Files.View { path_changed (); guest.slot_number = (host != null) ? host.slot_number + 1 : 0; guest.colpane = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); - guest.colpane.set_size_request (guest.width, -1); + // guest.colpane.set_size_request (guest.width, -1); + guest.colpane.set_size_request ( + 2 * guest.width, -1 + ); guest.hpane = new Gtk.Paned (Gtk.Orientation.HORIZONTAL) { hexpand = true }; @@ -133,10 +144,9 @@ namespace Files.View { } slot_list.append (guest); // Must add to list before scrolling + update_total_width (); // Must set the new slot to be active here as the tab does not change (which normally sets its slot active) guest.set_active_state (true, true); - - update_total_width (); } private uint draw_file_details_timeout_id = 0; @@ -151,7 +161,8 @@ namespace Files.View { draw_file_details_timeout_id = 0; details = new View.DetailsColumn (file, view); add_side_widget (details, false, true); // Shrink but not resize - update_total_width (); + // Preview pane not part of slot list so no need to update width + // but need to scroll according to new available space schedule_scroll_to_slot (last_slot, true); return Source.REMOVE; @@ -162,7 +173,7 @@ namespace Files.View { public void clear_file_details () { if (details is Gtk.Widget) { details.destroy (); - update_total_width (); + schedule_scroll_to_slot (last_slot, true); } } @@ -191,10 +202,15 @@ namespace Files.View { } private void calculate_total_width () { - total_width = 100; // Extra space to allow increasing the size of columns by dragging the edge + // Extra space to allow increasing the size of columns by dragging the edge + // Also without it, the scrolled window page size increases unnecessarily for non-obvious + // reasons + total_width = END_GAP; slot_list.@foreach ((slot) => { total_width += slot.width; }); + + this.colpane.set_size_request (total_width, -1); } private uint total_width_timeout_id = 0; @@ -528,20 +544,24 @@ namespace Files.View { } // Calculate position to scroll to - int total_width_before = 0; /* left edge of active slot */ + double total_width_before = 0; /* left edge of active slot */ slot_list.@foreach ((abs) => { if (abs.slot_number < slot.slot_number) { total_width_before += abs.width; } }); - int hadj_value = (int) this.hadj.get_value (); - int offset = total_width_before - hadj_value; + var hadj_value = hadj.get_value (); + var offset = total_width_before - hadj_value; if (offset < 0) { /*scroll until left hand edge of active slot is in view*/ hadj_value += offset; } - offset = total_width_before + slot.width - hadj_value - viewport.get_view_window ().get_width (); + offset = total_width_before + + (double) slot.width - + hadj_value - + (double) viewport.get_view_window ().get_width (); + if (offset > 0) { /*scroll until right hand edge of active slot is in view*/ hadj_value += offset; } @@ -645,27 +665,26 @@ namespace Files.View { /* Animation functions */ private uint animation_timeout_source_id = 0; - private void smooth_adjustment_to (Gtk.Adjustment adj, int final) { + private void smooth_adjustment_to (Gtk.Adjustment adj, double final) { cancel_animation (); var initial = adj.value; var to_do = final - initial; - int factor; - (to_do > 0) ? factor = 1 : factor = -1; - to_do = (double) (((int) to_do).abs () + 1); + double factor; + var to_do_abs = to_do.abs (); - var newvalue = 0; + double newvalue = 0; var old_adj_value = adj.value; - animation_timeout_source_id = Timeout.add (1000 / 60, () => { + animation_timeout_source_id = Timeout.add (ANIMATION_RATE_MSEC, () => { /* If the user move it at the same time, just stop the animation */ if (old_adj_value != adj.value) { animation_timeout_source_id = 0; return GLib.Source.REMOVE; } - if (newvalue >= to_do - 10) { + if (newvalue >= to_do_abs) { /* to be sure that there is not a little problem */ adj.value = final; animation_timeout_source_id = 0; @@ -673,9 +692,8 @@ namespace Files.View { } newvalue += 10; - - adj.value = initial + factor * - Math.sin (((double) newvalue / (double) to_do) * Math.PI / 2) * to_do; + adj.value = initial + + Math.sin ((newvalue / to_do_abs) * Math.PI / 2) * to_do; old_adj_value = adj.value; return GLib.Source.CONTINUE; From ca95aa47307136f42ab84a163eaa9e06c0cdff96 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 7 Mar 2026 18:36:48 +0000 Subject: [PATCH 22/31] Revert "DetailsColumn: Simplify layout" This reverts commit f16a4aac11a242c4963c530d24882783933652c7. --- src/View/DetailsColumn.vala | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index f26ad23cb..8cab5eb8e 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -6,11 +6,17 @@ */ public class Files.View.DetailsColumn : Gtk.Bin { + public int width { + get { + return PREVIEW_SIZE + 2 * PREVIEW_H_MARGIN; + } + } public Files.File file { get; construct; } public Files.AbstractDirectoryView view { get; construct; } - private const int PREVIEW_SIZE = 256 + 100; + private const int PREVIEW_SIZE = 256; + private const int PREVIEW_H_MARGIN = 12; private const int MAX_PREVIEW_FILE_SIZE = 2 * 8 * 1024 * 1024; // 2MB private GLib.Cancellable? cancellable; private Gtk.Label resolution_value; @@ -24,9 +30,7 @@ public class Files.View.DetailsColumn : Gtk.Bin { } construct { - width_request = PREVIEW_SIZE; hexpand = false; - var file_real_size = PropertiesWindow.file_real_size (file); var info_grid = new Gtk.Grid () { @@ -35,6 +39,8 @@ public class Files.View.DetailsColumn : Gtk.Bin { }; var file_image = new Gtk.Image () { + hexpand = true, + vexpand = true, halign = CENTER, valign = CENTER, }; @@ -45,6 +51,10 @@ public class Files.View.DetailsColumn : Gtk.Bin { var file_text = new Gtk.TextView () { cursor_visible = false, editable = false, + top_margin = 12, + bottom_margin = 12, + left_margin = 12, + right_margin = 12, }; Gdk.Pixbuf? ico_pix = file.get_icon_pixbuf ( @@ -199,11 +209,15 @@ public class Files.View.DetailsColumn : Gtk.Bin { var box = new Gtk.Box (VERTICAL, 12) { halign = CENTER, + margin_top = 12, + margin_bottom = 12, + margin_end = 12, + width_request = PREVIEW_SIZE + 2 * margin_end }; var scrolled_window = new Gtk.ScrolledWindow (null, null) { - propagate_natural_width = true, - propagate_natural_height = true + max_content_height = PREVIEW_SIZE, + max_content_width = PREVIEW_SIZE, }; if (previewing_text) { @@ -212,7 +226,7 @@ public class Files.View.DetailsColumn : Gtk.Bin { scrolled_window.child = file_image; } - box.pack_start (scrolled_window, false, false, 0); + box.add (scrolled_window); box.add (new Gtk.Separator (HORIZONTAL)); box.add (info_grid); box.add (more_info_button); From 26c8502f3b50198638e0ed7fee719f68b0bec643 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 7 Mar 2026 18:43:15 +0000 Subject: [PATCH 23/31] Revert "DetailsColumn: Use unpadded date-time, simplify" This reverts commit cb0eb4c824563b3dc7c0e68548d5dd40f44340e3. # Conflicts: # src/View/DetailsColumn.vala --- src/View/DetailsColumn.vala | 43 +++++++++++++++---------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index 8cab5eb8e..fad6b0548 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -131,7 +131,7 @@ public class Files.View.DetailsColumn : Gtk.Bin { info_grid.attach (size_key_label, 0, 2); info_grid.attach_next_to (size_value, size_key_label, RIGHT); - var time_created = get_formated_date_time_from_info ( + var time_created = FileUtils.get_formatted_time_attribute_from_info ( file.info, FileAttribute.TIME_CREATED ); @@ -140,12 +140,12 @@ public class Files.View.DetailsColumn : Gtk.Bin { if (time_created != "") { var key_label = make_key_label (_("Created:")); var value_label = make_value_label (time_created); - info_grid.attach (key_label, 0, n++); + info_grid.attach (key_label, 0, n, 1, 1); info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); n++; } - var time_modified = get_formated_date_time_from_info ( + var time_modified = FileUtils.get_formatted_time_attribute_from_info ( file.info, FileAttribute.TIME_MODIFIED ); @@ -153,12 +153,13 @@ public class Files.View.DetailsColumn : Gtk.Bin { if (time_modified != "") { var key_label = make_key_label (_("Modified:")); var value_label = make_value_label (time_modified); - info_grid.attach (key_label, 0, n++); - info_grid.attach_next_to (value_label, key_label, RIGHT); + info_grid.attach (key_label, 0, n, 1, 1); + info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); + n++; } if (file.is_trashed ()) { - var deletion_date = get_formated_date_time_from_info ( + var deletion_date = FileUtils.get_formatted_time_attribute_from_info ( file.info, FileAttribute.TRASH_DELETION_DATE ); @@ -166,22 +167,25 @@ public class Files.View.DetailsColumn : Gtk.Bin { if (deletion_date != "") { var key_label = make_key_label (_("Deleted:")); var value_label = make_value_label (deletion_date); - info_grid.attach (key_label, 0, n++); + info_grid.attach (key_label, 0, n, 1, 1); info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); + n++; } } var ftype = filetype (file); var mimetype_key = make_key_label (_("Media type:")); var mimetype_value = make_value_label (ftype); - info_grid.attach (mimetype_key, 0, n++); + info_grid.attach (mimetype_key, 0, n, 1, 1); info_grid.attach_next_to (mimetype_value, mimetype_key, RIGHT, 3, 1); + n++; if (file.is_image ()) { var resolution_key = make_key_label (_("Resolution:")); resolution_value = make_value_label (resolution (file)); - info_grid.attach (resolution_key, 0, n++); + info_grid.attach (resolution_key, 0, n, 1, 1); info_grid.attach_next_to (resolution_value, resolution_key, RIGHT, 3, 1); + n++; } if (file.info.get_attribute_boolean (GLib.FileAttribute.STANDARD_IS_SYMLINK)) { @@ -189,22 +193,21 @@ public class Files.View.DetailsColumn : Gtk.Bin { var value_label = make_value_label ( file.info.get_attribute_byte_string (GLib.FileAttribute.STANDARD_SYMLINK_TARGET) ); - info_grid.attach (key_label, 0, n++); + info_grid.attach (key_label, 0, n, 1, 1); info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); + n++; } if (file.is_trashed ()) { var key_label = make_key_label (_("Original Location:")); var value_label = make_value_label (original_location (file)); - info_grid.attach (key_label, 0, n++); + info_grid.attach (key_label, 0, n, 1, 1); info_grid.attach_next_to (value_label, key_label, RIGHT, 3, 1); n++; } var more_info_button = new Gtk.Button.with_label (_("Properties…")) { - halign = END, - margin_end = 12, - margin_bottom = 12 + halign = END }; var box = new Gtk.Box (VERTICAL, 12) { @@ -241,18 +244,6 @@ public class Files.View.DetailsColumn : Gtk.Bin { }); } - private static string get_formated_date_time_from_info ( - FileInfo info, - string attrib - ) { - // We do not want padded string and we want max detail - return FileUtils.get_formatted_time_attribute_from_info ( - info, - attrib, - DateFormatMode.LOCALE, - false // Do not add hard padding (cannot easily remove) - ); - } /** Also an adjusted copy from PropertiesWindow **/ public static string original_location (Files.File file) { /* print orig location of trashed files */ From ea611f6daded7a70dfffb79712da1d1b4e8effb6 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 7 Mar 2026 18:52:07 +0000 Subject: [PATCH 24/31] Revert "Lose unneeded spinner" This reverts commit b965c983fb4c74d65c6e91b53df61e837c12847a. --- src/View/DetailsColumn.vala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index fad6b0548..3c554d80d 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -122,13 +122,17 @@ public class Files.View.DetailsColumn : Gtk.Bin { /** begin adapted copy-pasta from PropertiesWindow.construct_info_panel **/ var size_key_label = make_key_label (_("Size:")); + var spinner = new Gtk.Spinner () { + halign = START + }; var size_value = make_value_label (""); size_value.label = GLib.format_size (file_real_size); info_grid.attach (name_key_label, 0, 1); info_grid.attach_next_to (name_value, name_key_label, RIGHT); - info_grid.attach (size_key_label, 0, 2); + info_grid.attach (size_key_label, 0, 2, 1); + info_grid.attach_next_to (spinner, size_key_label, RIGHT); info_grid.attach_next_to (size_value, size_key_label, RIGHT); var time_created = FileUtils.get_formatted_time_attribute_from_info ( From d06c5d27978e424a05e968d33a3c376db48d170f Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 7 Mar 2026 18:53:35 +0000 Subject: [PATCH 25/31] Revert "Make preview width comparable to columnview" This reverts commit 388426f521da0e7ba3c7921bf853ccced92f7ed2. --- src/View/DetailsColumn.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index 3c554d80d..bd71812b2 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -15,8 +15,8 @@ public class Files.View.DetailsColumn : Gtk.Bin { public Files.File file { get; construct; } public Files.AbstractDirectoryView view { get; construct; } - private const int PREVIEW_SIZE = 256; - private const int PREVIEW_H_MARGIN = 12; + private const int PREVIEW_SIZE = 512; + private const int PREVIEW_H_MARGIN = 24; private const int MAX_PREVIEW_FILE_SIZE = 2 * 8 * 1024 * 1024; // 2MB private GLib.Cancellable? cancellable; private Gtk.Label resolution_value; From d34aea31d0f33114e2c0d98e2f85252ffe3b7aa6 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 7 Mar 2026 18:59:42 +0000 Subject: [PATCH 26/31] Revert afc343a relating to DetailsColumn --- src/View/DetailsColumn.vala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index bd71812b2..d836a230a 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -30,7 +30,6 @@ public class Files.View.DetailsColumn : Gtk.Bin { } construct { - hexpand = false; var file_real_size = PropertiesWindow.file_real_size (file); var info_grid = new Gtk.Grid () { @@ -216,15 +215,19 @@ public class Files.View.DetailsColumn : Gtk.Bin { var box = new Gtk.Box (VERTICAL, 12) { halign = CENTER, + hexpand = true, margin_top = 12, margin_bottom = 12, + margin_start = 12, margin_end = 12, - width_request = PREVIEW_SIZE + 2 * margin_end }; var scrolled_window = new Gtk.ScrolledWindow (null, null) { + width_request = PREVIEW_SIZE, max_content_height = PREVIEW_SIZE, max_content_width = PREVIEW_SIZE, + min_content_height = PREVIEW_SIZE / 2, + min_content_width = PREVIEW_SIZE / 2 }; if (previewing_text) { From 7a7d152321e6a3da7e034f44af336574167c338e Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 7 Mar 2026 19:05:54 +0000 Subject: [PATCH 27/31] Revert "Use only one scrolled window in DetailsColumn" This reverts commit c0e20b6c81e981f9363b43f883fd06f442deab36. # Conflicts: # src/View/DetailsColumn.vala --- src/View/DetailsColumn.vala | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index d836a230a..891967e2c 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -41,9 +41,8 @@ public class Files.View.DetailsColumn : Gtk.Bin { hexpand = true, vexpand = true, halign = CENTER, - valign = CENTER, + valign = CENTER }; - file_image.get_style_context ().add_class (Granite.STYLE_CLASS_CARD); file_image.get_style_context ().add_class (Granite.STYLE_CLASS_CHECKERBOARD); @@ -215,33 +214,36 @@ public class Files.View.DetailsColumn : Gtk.Bin { var box = new Gtk.Box (VERTICAL, 12) { halign = CENTER, - hexpand = true, margin_top = 12, margin_bottom = 12, margin_start = 12, margin_end = 12, }; - var scrolled_window = new Gtk.ScrolledWindow (null, null) { - width_request = PREVIEW_SIZE, - max_content_height = PREVIEW_SIZE, - max_content_width = PREVIEW_SIZE, - min_content_height = PREVIEW_SIZE / 2, - min_content_width = PREVIEW_SIZE / 2 - }; - if (previewing_text) { - scrolled_window.child = file_text; + var text_window = new Gtk.ScrolledWindow (null, null) { + child = file_text, + width_request = PREVIEW_SIZE, + height_request = PREVIEW_SIZE, + max_content_height = PREVIEW_SIZE, + max_content_width = PREVIEW_SIZE + }; + + box.add (text_window); } else { - scrolled_window.child = file_image; + box.add (file_image); } - box.add (scrolled_window); - box.add (new Gtk.Separator (HORIZONTAL)); box.add (info_grid); box.add (more_info_button); - child = box; + var scrolled = new Gtk.ScrolledWindow (null, null) { + child = box, + propagate_natural_height = true, + hscrollbar_policy = NEVER + }; + + child = scrolled; show_all (); more_info_button.clicked.connect (() => { From 166be56b0d3b36e246788829c9cc241d63421cae Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 23 Apr 2026 17:23:14 +0100 Subject: [PATCH 28/31] Use more meaningful names for two slot members --- libcore/AbstractSlot.vala | 20 ++++++++++---------- src/View/Miller.vala | 2 +- src/View/ViewContainer.vala | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libcore/AbstractSlot.vala b/libcore/AbstractSlot.vala index 53458159b..8dd1487aa 100644 --- a/libcore/AbstractSlot.vala +++ b/libcore/AbstractSlot.vala @@ -49,8 +49,8 @@ public abstract class Files.AbstractSlot : GLib.Object { //TODO Make private so layout fixed? protected Gtk.Box extra_location_widgets; protected Gtk.Box extra_action_widgets; - protected Gtk.Grid content_box; - protected Gtk.Paned side_widget_box; + protected Gtk.Grid content_grid; // Holds view, overlay and extra action widgets + protected Gtk.Paned main_paned; // Holds all displayed widgets (content_grid and preview or other side widget) public Gtk.Overlay overlay { get; protected set; } public int slot_number { get; protected set; } @@ -77,11 +77,11 @@ public abstract class Files.AbstractSlot : GLib.Object { } protected void add_side_widget (Gtk.Widget widget, bool resize, bool shrink) { - side_widget_box.pack2 (widget, resize, shrink); + main_paned.pack2 (widget, resize, shrink); } construct { - content_box = new Gtk.Grid () { + content_grid = new Gtk.Grid () { vexpand = true, hexpand = true }; @@ -91,13 +91,13 @@ public abstract class Files.AbstractSlot : GLib.Object { vexpand = true, }; - side_widget_box = new Gtk.Paned (HORIZONTAL); + main_paned = new Gtk.Paned (HORIZONTAL); extra_action_widgets = new Gtk.Box (VERTICAL, 0); - content_box.attach (extra_action_widgets, 0, 0); - content_box.attach (overlay, 0, 1); + content_grid.attach (extra_action_widgets, 0, 0); + content_grid.attach (overlay, 0, 1); - side_widget_box.pack1 (content_box, true, true); + main_paned.pack1 (content_grid, true, true); slot_number = -1; } @@ -117,8 +117,8 @@ public abstract class Files.AbstractSlot : GLib.Object { public virtual void zoom_in () {} public virtual void zoom_normal () {} public virtual bool set_all_selected (bool all_selected) { return false; } - public virtual Gtk.Widget get_content_box () { return side_widget_box as Gtk.Widget; } + public virtual Gtk.Widget get_main_widget () { return main_paned as Gtk.Widget; } public virtual string? get_root_uri () { return directory.file.uri; } public virtual string? get_tip_uri () { return null; } - public virtual bool get_realized () { return side_widget_box.get_realized (); } + public virtual bool get_realized () { return main_paned.get_realized (); } } diff --git a/src/View/Miller.vala b/src/View/Miller.vala index 53159e074..d8bfaf225 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -100,7 +100,7 @@ namespace Files.View { add_overlay_widget (scrolled_window); - content_box.show_all (); + content_grid.show_all (); current_slot = null; add_location (root_location, null); /* current slot gets set by this */ diff --git a/src/View/ViewContainer.vala b/src/View/ViewContainer.vala index 29a6a36c7..ce5da5b43 100644 --- a/src/View/ViewContainer.vala +++ b/src/View/ViewContainer.vala @@ -427,7 +427,7 @@ namespace Files.View { } if (can_show_folder) { - content = view.get_content_box (); + content = view.get_main_widget (); var directory = dir.file; /* Only record valid folders (will also log Zeitgeist event) */ From 7df710184510a4e8fffe31ad829ad39fc4e92901 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 23 Apr 2026 17:47:10 +0100 Subject: [PATCH 29/31] Do not pad datetime in details column --- src/View/DetailsColumn.vala | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/View/DetailsColumn.vala b/src/View/DetailsColumn.vala index 28f4f2a89..e686c11af 100644 --- a/src/View/DetailsColumn.vala +++ b/src/View/DetailsColumn.vala @@ -135,7 +135,9 @@ public class Files.View.DetailsColumn : Gtk.Bin { var time_created = FileUtils.get_formatted_time_attribute_from_info ( file.info, - FileAttribute.TIME_CREATED + FileAttribute.TIME_CREATED, + Files.Preferences.get_default ().date_format, + false ); int n = 5; @@ -149,7 +151,9 @@ public class Files.View.DetailsColumn : Gtk.Bin { var time_modified = FileUtils.get_formatted_time_attribute_from_info ( file.info, - FileAttribute.TIME_MODIFIED + FileAttribute.TIME_MODIFIED, + Files.Preferences.get_default ().date_format, + false ); if (time_modified != "") { @@ -163,7 +167,9 @@ public class Files.View.DetailsColumn : Gtk.Bin { if (file.is_trashed ()) { var deletion_date = FileUtils.get_formatted_time_attribute_from_info ( file.info, - FileAttribute.TRASH_DELETION_DATE + FileAttribute.TRASH_DELETION_DATE, + Files.Preferences.get_default ().date_format, + false ); if (deletion_date != "") { From 450fc5ef9d07a8ef822b0eee915b0e801aa756da Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 23 Apr 2026 17:50:20 +0100 Subject: [PATCH 30/31] Remove commented out code --- src/View/Miller.vala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/View/Miller.vala b/src/View/Miller.vala index d8bfaf225..de8fb9229 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -120,7 +120,6 @@ namespace Files.View { path_changed (); guest.slot_number = (host != null) ? host.slot_number + 1 : 0; guest.colpane = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); - // guest.colpane.set_size_request (guest.width, -1); guest.colpane.set_size_request ( 2 * guest.width, -1 ); From 9748554523315f967afd334937147bb3eab7231d Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 23 Apr 2026 17:54:07 +0100 Subject: [PATCH 31/31] Use width_request property where possible --- src/View/Miller.vala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/View/Miller.vala b/src/View/Miller.vala index de8fb9229..df2e46f68 100644 --- a/src/View/Miller.vala +++ b/src/View/Miller.vala @@ -120,9 +120,7 @@ namespace Files.View { path_changed (); guest.slot_number = (host != null) ? host.slot_number + 1 : 0; guest.colpane = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); - guest.colpane.set_size_request ( - 2 * guest.width, -1 - ); + guest.colpane.width_request = 2 * guest.width; guest.hpane = new Gtk.Paned (Gtk.Orientation.HORIZONTAL) { hexpand = true }; @@ -209,7 +207,7 @@ namespace Files.View { total_width += slot.width; }); - this.colpane.set_size_request (total_width, -1); + this.colpane.width_request = total_width; } private uint total_width_timeout_id = 0;