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
- Create a
TextField and give it a fixed width narrower than its text.
- Set a long single-line value, e.g.
assignee = currentUser() AND statusCategory != Done.
- 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.
Summary
On macOS, an editable
TextFieldwraps 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 whereTextFieldis 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-ui-macos)Steps to reproduce
TextFieldand give it a fixed width narrower than its text.assignee = currentUser() AND statusCategory != Done.Expected
A single-line
TextFieldkeeps one line and clips/scrolls horizontally, matching the other platforms and a normal single-lineNSTextField. Multiline input already has its own widget,TextArea.Cross-platform comparison
Every other backend's
create()makesTextFieldsingle-line; macOS is the outlier.perry-ui-ios)UITextFieldUITextViewis the multiline widget)perry-ui-gtk4)gtk4::EntryGtkEntryis inherently single-lineperry-ui-android)EditTextsetSingleLineincreate()perry-ui-windows)ES_AUTOHSCROLL, noES_MULTILINEperry-ui-macos)NSTextFieldCause (confirmed in source)
crates/perry-ui-macos/src/widgets/textfield.rscreate()builds the field withNSTextField::textFieldWithString(...)and sets onlysetEditable(true)andsetBezeled(true). It never setsusesSingleLineModeon the field, norsetScrollable(true)/setWraps(false)/ a clipping line-break mode on the cell. AppKit'stextFieldWithString:returns a cell configured to wrap and grow, so a fixed-width field wraps rather than scrolls.Perry ships a distinct
TextAreawidget for multiline, soTextFieldcarrying a wrapping cell is the wrong default, not a limitation. There is also no single-line lever in theperry/uiAPI (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 cellsetScrollable(true),setWraps(false), and a clipping line-break mode. Multiline already lives inTextArea, so no new option is needed.Scope
Every editable
TextFieldon the macOS target.