nextcloud / nextcloud/ios

Avoid visual gap between truncated filename and its extension

Open
#4,282 0 comments 0 reactions 1 assignee View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Swift
Stars
2.5k
Forks
1k
Avg merge
2d 18h
Merged PRs (30d)
13

Description

Steps to reproduce
  1. Open a folder containing files with long names.
  2. Display the files using the list layout.
  3. Reduce the available horizontal space enough to truncate the filename.
  4. Compare multiple filenames ending with the same extension.
Expected behaviour

The extension should appear immediately after the visible filename, without an apparent space:

Combo 01x01...manuale.avi
Actual behaviour

For some filenames, a variable visual gap appears before the extension:

Combo 01x01...manuale .avi

The filename itself does not contain a space before the extension.

This happens because setBidiSafeFilename displays the basename and extension using two separate UILabel instances. The basename label uses middle truncation and Auto Layout assigns it all the remaining available width.

When UIKit truncates the text, the rendered glyphs do not always occupy the label's entire frame. The extension label is positioned after the frame rather than immediately after the last rendered glyph, making the unused width look like a space. The size of the gap varies depending on the filename, font metrics and available width.

Reasoning or why should it be changed?

The gap makes filenames look incorrect and may suggest that a space is part of the actual filename.

The separate labels were introduced to prevent Unicode bidirectional-control characters in the basename from visually disguising the real file extension. Any solution should preserve this security property.

Possible solution

Keep the basename and extension logically isolated, but use a dedicated filename view that controls their layout.

The view could use TextKit/Core Text to:

  1. Truncate the basename in the middle using the available width.
  2. Measure the typographic width of the resulting truncated text.
  3. Position the extension immediately after the last rendered glyph instead of after the original UILabel frame.
  4. Keep the extension untruncated and isolated from any bidirectional-control characters contained in the basename.

A simpler alternative worth evaluating is rendering the complete filename in one label after removing unsafe bidi formatting controls and explicitly wrapping the basename and extension in separate Unicode directional isolates. This approach should only be adopted after verifying that malformed or nested bidi controls cannot influence the real extension.

Image

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.