Rename terminal state aggregate type to avoid conflict (#788)

This commit is contained in:
Jake Wharton
2025-03-13 14:28:45 -04:00
committed by GitHub
parent e17a8d8abf
commit 0350c20416
7 changed files with 34 additions and 51 deletions

View File

@ -13,6 +13,7 @@ Changed:
- Switched to our own terminal integration library. Report any issues with keyboard input, incorrect size reporting, or garbled output.
- Only disable the cursor and emit synchronized rendering markers if the terminal reports support for those features.
- `Static` function is now called `StaticEffect` to better indicate that it only renders its content once.
- The runtime's `Terminal` was renamed to `TerminalState` to avoid conflict with new, lower-level `Terminal` type.
Fixed:
- Prevent final character from being erased when a row writes into the last column of the terminal.

View File

@ -26,9 +26,12 @@ public final class com/jakewharton/mosaic/StaticLogger {
public final fun plusAssign (Ljava/lang/String;)V
}
public final class com/jakewharton/mosaic/Terminal {
public final class com/jakewharton/mosaic/TerminalKt {
public static final fun getLocalTerminalState ()Landroidx/compose/runtime/ProvidableCompositionLocal;
}
public final class com/jakewharton/mosaic/TerminalState {
public static final field $stable I
public static final field Companion Lcom/jakewharton/mosaic/Terminal$Companion;
public synthetic fun <init> (ZZJLkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun equals (Ljava/lang/Object;)Z
public final fun getDarkTheme ()Z
@ -38,14 +41,6 @@ public final class com/jakewharton/mosaic/Terminal {
public fun toString ()Ljava/lang/String;
}
public final class com/jakewharton/mosaic/Terminal$Companion {
public final fun getDefault ()Lcom/jakewharton/mosaic/Terminal;
}
public final class com/jakewharton/mosaic/TerminalKt {
public static final fun getLocalTerminal ()Landroidx/compose/runtime/ProvidableCompositionLocal;
}
public abstract interface class com/jakewharton/mosaic/TextCanvas {
public abstract fun appendRowTo (Ljava/lang/Appendable;ILcom/jakewharton/mosaic/terminal/AnsiLevel;Z)V
public abstract fun getHeight ()I

View File

@ -387,24 +387,19 @@ final class com.jakewharton.mosaic/StaticLogger { // com.jakewharton.mosaic/Stat
final inline fun plusAssign(kotlin/String) // com.jakewharton.mosaic/StaticLogger.plusAssign|plusAssign(kotlin.String){}[0]
}
final class com.jakewharton.mosaic/Terminal { // com.jakewharton.mosaic/Terminal|null[0]
constructor <init>(kotlin/Boolean, kotlin/Boolean, com.jakewharton.mosaic.ui.unit/IntSize) // com.jakewharton.mosaic/Terminal.<init>|<init>(kotlin.Boolean;kotlin.Boolean;com.jakewharton.mosaic.ui.unit.IntSize){}[0]
final class com.jakewharton.mosaic/TerminalState { // com.jakewharton.mosaic/TerminalState|null[0]
constructor <init>(kotlin/Boolean, kotlin/Boolean, com.jakewharton.mosaic.ui.unit/IntSize) // com.jakewharton.mosaic/TerminalState.<init>|<init>(kotlin.Boolean;kotlin.Boolean;com.jakewharton.mosaic.ui.unit.IntSize){}[0]
final val darkTheme // com.jakewharton.mosaic/Terminal.darkTheme|{}darkTheme[0]
final fun <get-darkTheme>(): kotlin/Boolean // com.jakewharton.mosaic/Terminal.darkTheme.<get-darkTheme>|<get-darkTheme>(){}[0]
final val focused // com.jakewharton.mosaic/Terminal.focused|{}focused[0]
final fun <get-focused>(): kotlin/Boolean // com.jakewharton.mosaic/Terminal.focused.<get-focused>|<get-focused>(){}[0]
final val size // com.jakewharton.mosaic/Terminal.size|{}size[0]
final fun <get-size>(): com.jakewharton.mosaic.ui.unit/IntSize // com.jakewharton.mosaic/Terminal.size.<get-size>|<get-size>(){}[0]
final val darkTheme // com.jakewharton.mosaic/TerminalState.darkTheme|{}darkTheme[0]
final fun <get-darkTheme>(): kotlin/Boolean // com.jakewharton.mosaic/TerminalState.darkTheme.<get-darkTheme>|<get-darkTheme>(){}[0]
final val focused // com.jakewharton.mosaic/TerminalState.focused|{}focused[0]
final fun <get-focused>(): kotlin/Boolean // com.jakewharton.mosaic/TerminalState.focused.<get-focused>|<get-focused>(){}[0]
final val size // com.jakewharton.mosaic/TerminalState.size|{}size[0]
final fun <get-size>(): com.jakewharton.mosaic.ui.unit/IntSize // com.jakewharton.mosaic/TerminalState.size.<get-size>|<get-size>(){}[0]
final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic/Terminal.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // com.jakewharton.mosaic/Terminal.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // com.jakewharton.mosaic/Terminal.toString|toString(){}[0]
final object Companion { // com.jakewharton.mosaic/Terminal.Companion|null[0]
final val Default // com.jakewharton.mosaic/Terminal.Companion.Default|{}Default[0]
final fun <get-Default>(): com.jakewharton.mosaic/Terminal // com.jakewharton.mosaic/Terminal.Companion.Default.<get-Default>|<get-Default>(){}[0]
}
final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic/TerminalState.equals|equals(kotlin.Any?){}[0]
final fun hashCode(): kotlin/Int // com.jakewharton.mosaic/TerminalState.hashCode|hashCode(){}[0]
final fun toString(): kotlin/String // com.jakewharton.mosaic/TerminalState.toString|toString(){}[0]
}
final value class com.jakewharton.mosaic.ui.unit/Constraints { // com.jakewharton.mosaic.ui.unit/Constraints|null[0]
@ -720,15 +715,15 @@ final val com.jakewharton.mosaic.ui/isUnspecifiedUnderlineStyle // com.jakewhart
final inline fun (com.jakewharton.mosaic.ui/UnderlineStyle).<get-isUnspecifiedUnderlineStyle>(): kotlin/Boolean // com.jakewharton.mosaic.ui/isUnspecifiedUnderlineStyle.<get-isUnspecifiedUnderlineStyle>|<get-isUnspecifiedUnderlineStyle>@com.jakewharton.mosaic.ui.UnderlineStyle(){}[0]
final val com.jakewharton.mosaic/LocalStaticLogger // com.jakewharton.mosaic/LocalStaticLogger|{}LocalStaticLogger[0]
final fun <get-LocalStaticLogger>(): androidx.compose.runtime/ProvidableCompositionLocal<com.jakewharton.mosaic/StaticLogger> // com.jakewharton.mosaic/LocalStaticLogger.<get-LocalStaticLogger>|<get-LocalStaticLogger>(){}[0]
final val com.jakewharton.mosaic/LocalTerminal // com.jakewharton.mosaic/LocalTerminal|{}LocalTerminal[0]
final fun <get-LocalTerminal>(): androidx.compose.runtime/ProvidableCompositionLocal<com.jakewharton.mosaic/Terminal> // com.jakewharton.mosaic/LocalTerminal.<get-LocalTerminal>|<get-LocalTerminal>(){}[0]
final val com.jakewharton.mosaic/LocalTerminalState // com.jakewharton.mosaic/LocalTerminalState|{}LocalTerminalState[0]
final fun <get-LocalTerminalState>(): androidx.compose.runtime/ProvidableCompositionLocal<com.jakewharton.mosaic/TerminalState> // com.jakewharton.mosaic/LocalTerminalState.<get-LocalTerminalState>|<get-LocalTerminalState>(){}[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_AnsiRendering$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_AnsiRendering$stableprop|#static{}com_jakewharton_mosaic_AnsiRendering$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_DebugRendering$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_DebugRendering$stableprop|#static{}com_jakewharton_mosaic_DebugRendering$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_GlobalSnapshotManager$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_GlobalSnapshotManager$stableprop|#static{}com_jakewharton_mosaic_GlobalSnapshotManager$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicComposition$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicComposition$stableprop|#static{}com_jakewharton_mosaic_MosaicComposition$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicNodeApplier$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicNodeApplier$stableprop|#static{}com_jakewharton_mosaic_MosaicNodeApplier$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_StaticLogger$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_StaticLogger$stableprop|#static{}com_jakewharton_mosaic_StaticLogger$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_Terminal$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_Terminal$stableprop|#static{}com_jakewharton_mosaic_Terminal$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_TerminalState$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_TerminalState$stableprop|#static{}com_jakewharton_mosaic_TerminalState$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_TextPixel$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_TextPixel$stableprop|#static{}com_jakewharton_mosaic_TextPixel$stableprop[0]
final val com.jakewharton.mosaic/com_jakewharton_mosaic_TextSurface$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_TextSurface$stableprop|#static{}com_jakewharton_mosaic_TextSurface$stableprop[0]
@ -844,7 +839,7 @@ final fun com.jakewharton.mosaic/com_jakewharton_mosaic_GlobalSnapshotManager$st
final fun com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicComposition$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicComposition$stableprop_getter|com_jakewharton_mosaic_MosaicComposition$stableprop_getter(){}[0]
final fun com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicNodeApplier$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicNodeApplier$stableprop_getter|com_jakewharton_mosaic_MosaicNodeApplier$stableprop_getter(){}[0]
final fun com.jakewharton.mosaic/com_jakewharton_mosaic_StaticLogger$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_StaticLogger$stableprop_getter|com_jakewharton_mosaic_StaticLogger$stableprop_getter(){}[0]
final fun com.jakewharton.mosaic/com_jakewharton_mosaic_Terminal$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_Terminal$stableprop_getter|com_jakewharton_mosaic_Terminal$stableprop_getter(){}[0]
final fun com.jakewharton.mosaic/com_jakewharton_mosaic_TerminalState$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_TerminalState$stableprop_getter|com_jakewharton_mosaic_TerminalState$stableprop_getter(){}[0]
final fun com.jakewharton.mosaic/com_jakewharton_mosaic_TextPixel$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_TextPixel$stableprop_getter|com_jakewharton_mosaic_TextPixel$stableprop_getter(){}[0]
final fun com.jakewharton.mosaic/com_jakewharton_mosaic_TextSurface$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_TextSurface$stableprop_getter|com_jakewharton_mosaic_TextSurface$stableprop_getter(){}[0]
final fun com.jakewharton.mosaic/runMosaicBlocking(kotlin/Function2<androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // com.jakewharton.mosaic/runMosaicBlocking|runMosaicBlocking(kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]

View File

@ -17,6 +17,7 @@ import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.compose.LocalLifecycleOwner
import com.jakewharton.mosaic.layout.KeyEvent
import com.jakewharton.mosaic.layout.MosaicNode
import com.jakewharton.mosaic.terminal.Terminal
import com.jakewharton.mosaic.tty.Tty
import com.jakewharton.mosaic.tty.terminal.asTerminal
import com.jakewharton.mosaic.ui.BoxMeasurePolicy
@ -63,7 +64,7 @@ public suspend fun runMosaic(content: @Composable () -> Unit) {
}
internal suspend fun runMosaicComposition(
terminal: com.jakewharton.mosaic.terminal.Terminal,
terminal: Terminal,
rendering: Rendering,
content: @Composable () -> Unit,
) {
@ -107,7 +108,7 @@ public interface Mosaic {
public fun Mosaic(
coroutineContext: CoroutineContext,
onDraw: (Mosaic) -> Unit,
terminal: com.jakewharton.mosaic.terminal.Terminal,
terminal: Terminal,
): Mosaic {
return MosaicComposition(coroutineContext, onDraw, terminal)
}
@ -115,7 +116,7 @@ public fun Mosaic(
internal class MosaicComposition(
coroutineContext: CoroutineContext,
private val onDraw: (Mosaic) -> Unit,
private val terminal: com.jakewharton.mosaic.terminal.Terminal,
private val terminal: Terminal,
) : Mosaic,
LifecycleOwner {
private val externalClock = checkNotNull(coroutineContext[MonotonicFrameClock]) {
@ -138,7 +139,7 @@ internal class MosaicComposition(
override val lifecycle = LifecycleRegistry.createUnsafe(this)
private var terminalState = mutableStateOf(
Terminal(
TerminalState(
terminal.state.focused.value,
terminal.state.systemTheme.value,
terminal.state.size.value.let { IntSize(it.columns, it.rows) },
@ -301,7 +302,7 @@ internal class MosaicComposition(
override fun setContent(content: @Composable () -> Unit) {
composition.setContent {
CompositionLocalProvider(
LocalTerminal provides terminalState.value,
LocalTerminalState provides terminalState.value,
LocalStaticLogger provides staticLogger,
LocalLifecycleOwner provides this,
content = content,

View File

@ -6,29 +6,20 @@ import androidx.compose.runtime.compositionLocalOf
import com.jakewharton.mosaic.ui.unit.IntSize
import dev.drewhamilton.poko.Poko
public val LocalTerminal: ProvidableCompositionLocal<Terminal> = compositionLocalOf {
public val LocalTerminalState: ProvidableCompositionLocal<TerminalState> = compositionLocalOf {
error("No terminal info provided")
}
@[Immutable Poko]
public class Terminal(
public class TerminalState(
public val focused: Boolean,
public val darkTheme: Boolean,
public val size: IntSize,
) {
public companion object {
public val Default: Terminal = Terminal(
focused = true,
darkTheme = false,
// https://en.wikipedia.org/wiki/VT52
size = IntSize(width = 80, height = 24),
)
}
}
)
@Suppress("NOTHING_TO_INLINE")
internal inline fun Terminal.copy(
internal inline fun TerminalState.copy(
focused: Boolean = this.focused,
darkTheme: Boolean = this.darkTheme,
size: IntSize = this.size,
) = Terminal(focused, darkTheme, size)
) = TerminalState(focused, darkTheme, size)

View File

@ -88,7 +88,7 @@ class CounterTest {
var count by remember { mutableIntStateOf(0) }
Box(
modifier = Modifier.width(LocalTerminal.current.size.width),
modifier = Modifier.width(LocalTerminalState.current.size.width),
contentAlignment = Alignment.Center,
) {
Text("The count is: $count")

View File

@ -132,7 +132,7 @@ class MosaicTest {
@Test fun lifecycleUpdatesWithTerminal() = runTest {
runMosaicTest {
setContent {
val terminal = LocalTerminal.current
val terminal = LocalTerminalState.current
val lifecycle = LocalLifecycleOwner.current.lifecycle
Text("${terminal.focused} ${lifecycle.currentState}")
}