Skip to content

macOS TextField wraps to multiple lines instead of staying single-line (diverges from iOS/GTK4/Android/Windows) #10155

Description

@steinybot

Summary

On macOS, an editable TextField wraps its text to multiple lines when the text is wider than the field, instead of staying on one line and scrolling horizontally. macOS is the only platform where TextField is not single-line — the other four backends all make it single-line. A fixed-width field grows tall and misrenders single-line input (URLs, paths, queries).

Environment

  • Perry 0.5.1531 (local build)
  • macOS, Darwin 25.6.0, arm64
  • Native macOS target (perry-ui-macos)

Steps to reproduce

  1. Create a TextField and give it a fixed width narrower than its text.
  2. Set a long single-line value, e.g. assignee = currentUser() AND statusCategory != Done.
  3. The text wraps onto multiple lines instead of staying on one line and scrolling.

Expected

A single-line TextField keeps one line and clips/scrolls horizontally, matching the other platforms and a normal single-line NSTextField. Multiline input already has its own widget, TextArea.

Cross-platform comparison

Every other backend's create() makes TextField single-line; macOS is the outlier.

Platform Widget Single-line
iOS (perry-ui-ios) UITextField yes — inherently (UITextView is the multiline widget)
GTK4 / Linux (perry-ui-gtk4) gtk4::Entry yes — GtkEntry is inherently single-line
Android (perry-ui-android) EditText yes — explicit setSingleLine in create()
Windows (perry-ui-windows) Win32 EDIT yes — ES_AUTOHSCROLL, no ES_MULTILINE
macOS (perry-ui-macos) NSTextField no — wraps

Cause (confirmed in source)

crates/perry-ui-macos/src/widgets/textfield.rs create() builds the field with NSTextField::textFieldWithString(...) and sets only setEditable(true) and setBezeled(true). It never sets usesSingleLineMode on the field, nor setScrollable(true) / setWraps(false) / a clipping line-break mode on the cell. AppKit's textFieldWithString: returns a cell configured to wrap and grow, so a fixed-width field wraps rather than scrolls.

Perry ships a distinct TextArea widget for multiline, so TextField carrying a wrapping cell is the wrong default, not a limitation. There is also no single-line lever in the perry/ui API (textfieldSet* covers string, focus, border, font, colors — nothing for line mode), so a caller cannot correct it from TypeScript.

Suggested fix

In create(), configure the field for single-line editing to match the other platforms: setUsesSingleLineMode(true), and on the cell setScrollable(true), setWraps(false), and a clipping line-break mode. Multiline already lives in TextArea, so no new option is needed.

Scope

Every editable TextField on the macOS target.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions