Repository navigation
Releases
Releases Β· FoedusProgramme/mosaic
0.22.0
New:
Clipboard.lastCopyis what was put on the clipboard last, withsetTextor by selecting text on the screen, so that a program can say that something was copied. Each copy is a value of its own.
Fixed:
ProgressBarcovers what is below it, also where it has no track color, rather than letting it show through the part still to fill.- Keys which arrive at once, like the text an input method commits or a paste in a terminal without bracketed paste, all reach the program. Past 64 keys the earliest were dropped.
- Shift+Enter, and other keys which otherwise arrive as plain ones, are told apart in iTerm2, xterm, and tmux, which lack the Kitty keyboard protocol, through xterm's modifyOtherKeys. Shift+Enter arrived as Enter, so a
TextFieldwithonSubmitsubmitted instead of breaking the line.
0.21.0
New:
ProgressBarfills from the left to an eighth of a cell as its progress goes from 0 to 1, in a color of its own over a track color for the part still to fill. It is one row high andDefaultProgressBarWidthcells wide unless its modifier sizes it.Spinnershows the frames of aSpinnerStylein turn while it is composed, as wide as the widest frame.SpinnerStylehasDots,Line, andPulse, and takes frames and an interval of one's own.
Fixed:
- A program which fails leaves the terminal as one which completes does, with the cursor shown. The terminal was restored before the program's last output, which hid the cursor again.
- The
runMosaic*family of functions closes the TTY only once the terminal stopped reading it. Quitting could fail withIOException: 9(EBADF) from a read of the closed TTY. - On JDK 22 and newer, reads which reach the end of the input return -1, as they do on older JDKs, rather than throwing
IndexOutOfBoundsException. This coversTty,TestTerminal, andStandardStreams.
0.20.0
New:
LocalTerminalControlhands the terminal over to other programs withreleased, like an editor or an interactive command, and takes it over again afterwards, drawing everything anew. Meanwhile, nothing is drawn, input is left to those programs, and stdout and stderr are no longer intercepted.- Ctrl+Z suspends the program when no key handler consumes it, like it does in a shell, and
fgresumes it.TerminalControl.suspendProcessdoes the same. Neither is supported on Windows. Terminal.releasedandTerminal.suspendProcessdo the same for the terminal alone, without Mosaic, andTty.suspendProcessstops the process.TextFieldmoves between rows with β and β, leaving them to other handlers on the first and last row, for example to recall earlier input. Alt or Ctrl with β and β, and Alt+B and Alt+F, move by words, and Alt+Backspace and Alt+D delete them.TextFieldselects with Shift and the keys which move the cursor, and by dragging the mouse, which copies the selection to the clipboard. Typing and pasting replace the selection.TextFieldStatehasselectionStart,selectionEnd,selectedText,select, andselectAll.TextFieldundoes edits with Ctrl+_ (or Ctrl+/) and redoes them with Ctrl+Shift+Z, grouping typed characters by word.TextFieldStatehasundo,redo,canUndo, andcanRedo.- Text deleted with Ctrl+U, Ctrl+K, Ctrl+W, Alt+Backspace, and Alt+D is inserted again with Ctrl+Y, like in a shell.
TextFieldtakesminLines.Modifier.onPreviewPasteEventreceives pastes before the focused node, like a text field, so that ancestors can intercept them, for example to insert a placeholder for a large paste.- With the mouse enabled, dragging where no pointer handler takes the press selects text, like the terminal does without mouse tracking, and copies it to the clipboard once released. Double clicks select words, and triple clicks rows.
Changed:
- Ctrl+, Ctrl+], Ctrl+^, and Ctrl+_ are reported as those keys with Ctrl in terminals without the Kitty keyboard protocol, rather than as control characters which were dropped.
0.19.0
The first release of the fork, under the org.unitedsoftware.mosaic group and packages.
New:
- JVM support for RISC-V and s390x!
- Keys with modifiers which used to be indistinguishable, such as Shift+Enter and Enter, are now reported separately in terminals which support the Kitty keyboard protocol.
Modifier.onPasteEventreceives pasted text as a singlePasteEventin terminals which support bracketed paste, rather than one key event per character withEnterfor each line break. Unhandled pastes are still delivered as key events.TestMosaic.sendEventsends any terminal event, such as theBracketedPasteEvents around pasted text.DrawScope.drawCursorplaces and shows the terminal's cursor once the frame is rendered, so that input methods show their composition at the caret of text input.TextFieldandTextFieldStatefor editing text. Text wraps to the field's width,maxLineslimits its height, and the terminal's cursor marks the caret. WithonSubmit, Enter submits and Shift+Enter or Alt+Enter break lines. Pastes are inserted as a whole, and Ctrl+A, Ctrl+E, Ctrl+U, Ctrl+K, and Ctrl+W work like in a shell.runMosaic,runMosaicBlocking, andrunMosaicMaintakealternateScreen, which renders full screen on the terminal's alternate screen and restores what it showed before when done. Static output is written once done.WindowTitlesets the title of the terminal window while it is in the composition, restoring the previous title afterwards in terminals which support it.LocalClipboardcopies text to the clipboard with OSC 52, andLocalNotifiershows desktop notifications with the Kitty notification protocol or OSC 9.SpanStyle.linkandwithLinklink text to a URL with OSC 8 hyperlinks.Modifier.clipToBoundskeeps the content of a node, including its children, within its bounds.Modifier.verticalScrollandModifier.horizontalScrollwithScrollStateshow part of content which is larger than the node.ScrollState.scrollToEndkeeps following the end as the content grows.LazyColumnwithLazyListStateonly composes the items which are visible, so it can hold long lists like the messages of a conversation. Keyed items keep their position when items are added before them, andscrollToEndscrolls to the latest item.- A focus system:
Modifier.focusable,Modifier.focusRequester,Modifier.onFocusChanged, andLocalFocusManager. Key and paste events go to the focused node and its ancestors first, and to the other nodes only when those do not handle them. Tab and Shift+Tab move the focus, and the first focusable node is focused when nothing else is. Popupshows content on top of everything else, like a completion menu, without taking up space in the layout or being clipped by its ancestors. Itsalignmentlets it extend up from its position, for example above a text field at the bottom of the screen.- Writes to stdout and stderr by other means than Mosaic, like
printlnor a logging library, are intercepted whilerunMosaicruns and shown as static output above the display, rather than corrupting it (JakeWharton#681). TexttakessoftWrap,maxLines, andoverflow.TextOverflow.Ellipsisends text which does not fit with an ellipsis.Imageshows anImageBitmap, scaled to fit. kitty and Ghostty show the image itself with the Kitty graphics protocol, using Unicode placeholders so that it moves with the text. iTerm2 and WezTerm use their inline images, which keep transparency, terminals which report Sixel support Sixel graphics, and others half block characters.Terminal.Capabilities.sixelGraphicsis true when the terminal reports Sixel support in its primary device attributes.WindowPointerShapesets the shape of the mouse pointer with the Kitty pointer shape protocol while it is in the composition, restoring the previous shape afterwards.- Mouse input:
Modifier.onPointerEvent,onClick, andonHover. Events go to the innermost node under the pointer first, then to its ancestors, and drags and releases go to the nodes the press went to. Clicks focus focusable nodes and place the cursor ofTextFields, and the wheel scrollsverticalScroll,horizontalScroll(with Shift), andLazyColumn.runMosaictakesmouse, which is enabled on the alternate screen by default. Inline, the output is located on the screen with cursor position requests. Modifier.borderdraws a box of aBorderStylearound the content, with an optional title.- New
mosaic-markdownlibrary withMarkdown, which renders Markdown with syntax highlighted code, diffs, tables, task lists, and OSC 8 links. It handles incomplete input, so responses of language models can be rendered while they stream in.
Changed:
TextFieldis focusable and edits while focused, instead of taking afocusedparameter.Textrespects the incoming constraints. Lines wider than the maximum width wrap, after the last space which fits where possible, and text is clipped to the bounds of its node. Previously text was always as large as its content and drew over its surroundings.- Only rows which changed since the last frame are written to the terminal again.
- Output taller than the terminal shows its bottom instead of corrupting the screen, since the cursor cannot move above the top of the screen to redraw it.
- Content is measured with the width of the terminal as its maximum width. With
alternateScreen, it is measured to exactly the size of the terminal. - Use the AndroidX versions of the Compose runtime and lifecycle dependencies which are now fully multiplatform. Dependency constraints to the corresponding JetBrains artifacts (which are now empty) are present to prevent symbol duplication.
- Remove support for x86 macOS targets. These have been deprecated for a bit, but support has been removed from the Compose runtime so we have no choice but to match.
Fixed:
- Clear the set of states which were read during layout and draw passes before each pass. Previously these sets grew infinitely, which was both a memory leak and a performance problem.
- Close the underlying TTY at the end of the
runMosaic*family of functions. - Frame times on Linux and Windows no longer jump backwards once per second.
- Fix arc-based animations on native targets, which built their lookup table incorrectly.
- Report Shift+Tab as a key event when the terminal sends it as
CSI Z. - Typing characters outside of ASCII, such as CJK text committed by an input method, no longer crashes. They are delivered as
KeyEvents whosekeyis the character. - Wide characters, such as CJK text and most emoji, are measured and drawn as two columns, so they no longer push the rest of the row out of place. Combining marks and emoji joined with zero width joiners stay in the column of the character they modify. Widths follow Unicode 18.
- Drawing outside of the surface, for example while the terminal is being resized, is clipped instead of crashing.
- The initial size comes from the TTY in terminals which support in-band resize events but do not report their size when they are enabled, like iTerm2. Previously the size stayed at 80 by 24 until the window was resized.
- Inline output can be as tall as the terminal. The cursor rests at the end of the last row rather than on a line below the output, which kept the last row of the terminal empty.
- Resizing terminals which do not report size changes in-band, such as tmux and Terminal.app, no longer crashes the JVM. The resize callback was invoked from the signal handler, on whichever thread received the signal, with the JNI environment of another thread.