Fix terminal height: fit addon now measures real container size
- Show terminal container BEFORE calling fitAddon.fit() so it can measure actual dimensions (was measuring display:none → 0 height) - Read actual terminal rows from JS after init (getDimensions) - Remove max-height:600px CSS constraint, let terminal fill viewport - Revert preRender approach that caused flickering on arrow selection - Height is now dynamic (instance property) instead of hardcoded 30
This commit is contained in:
parent
2c43e31605
commit
a6eada7473
4 changed files with 35 additions and 19 deletions
|
|
@ -592,7 +592,7 @@ public sealed class WebGameHost
|
||||||
ColorSystem = ColorSystemSupport.TrueColor
|
ColorSystem = ColorSystemSupport.TrueColor
|
||||||
});
|
});
|
||||||
bufferConsole.Profile.Width = WebTerminal.Width;
|
bufferConsole.Profile.Width = WebTerminal.Width;
|
||||||
bufferConsole.Profile.Height = WebTerminal.Height;
|
bufferConsole.Profile.Height = _terminal.Height;
|
||||||
|
|
||||||
bufferConsole.Write(InventoryPanel.Render(_state, _registry, _loc, scrollOffset, selectedIndex: selectedIndex));
|
bufferConsole.Write(InventoryPanel.Render(_state, _registry, _loc, scrollOffset, selectedIndex: selectedIndex));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ public sealed class WebTerminal
|
||||||
});
|
});
|
||||||
|
|
||||||
public const int Width = 120;
|
public const int Width = 120;
|
||||||
public const int Height = 30;
|
public int Height { get; private set; } = 30;
|
||||||
|
|
||||||
public WebTerminal(IJSRuntime js)
|
public WebTerminal(IJSRuntime js)
|
||||||
{
|
{
|
||||||
|
|
@ -37,13 +37,24 @@ public sealed class WebTerminal
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the xterm.js terminal in the browser.
|
/// Initializes the xterm.js terminal in the browser and reads actual dimensions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task InitAsync()
|
public async Task InitAsync()
|
||||||
{
|
{
|
||||||
await _js.InvokeVoidAsync("terminalInterop.init");
|
await _js.InvokeVoidAsync("terminalInterop.init");
|
||||||
|
|
||||||
|
// Read actual terminal dimensions after fitAddon has sized the terminal
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var dims = await _js.InvokeAsync<TerminalDimensions>("terminalInterop.getDimensions");
|
||||||
|
if (dims.rows >= 30)
|
||||||
|
Height = dims.rows;
|
||||||
|
}
|
||||||
|
catch { /* fallback to 30 */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private record TerminalDimensions(int cols, int rows);
|
||||||
|
|
||||||
// ── Output ───────────────────────────────────────────────────────────
|
// ── Output ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -83,7 +94,7 @@ public sealed class WebTerminal
|
||||||
ColorSystem = ColorSystemSupport.TrueColor
|
ColorSystem = ColorSystemSupport.TrueColor
|
||||||
});
|
});
|
||||||
console.Profile.Width = Width;
|
console.Profile.Width = Width;
|
||||||
console.Profile.Height = Height;
|
console.Profile.Height = _instance?.Height ?? 50;
|
||||||
console.Write(renderable);
|
console.Write(renderable);
|
||||||
return writer.ToString();
|
return writer.ToString();
|
||||||
}
|
}
|
||||||
|
|
@ -227,6 +238,7 @@ public sealed class WebTerminal
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
||||||
int scrollOffset = 0;
|
int scrollOffset = 0;
|
||||||
if (selected >= pageSize)
|
if (selected >= pageSize)
|
||||||
scrollOffset = selected - pageSize + 1;
|
scrollOffset = selected - pageSize + 1;
|
||||||
|
|
@ -262,7 +274,6 @@ public sealed class WebTerminal
|
||||||
console.MarkupLine("[dim] ▼ ...[/]");
|
console.MarkupLine("[dim] ▼ ...[/]");
|
||||||
|
|
||||||
string rendered = writer.ToString().Replace("\n", "\r\n");
|
string rendered = writer.ToString().Replace("\n", "\r\n");
|
||||||
// Count actual line breaks — Split('\n').Length overcounts by 1 due to trailing newline
|
|
||||||
int lineCount = rendered.Count(c => c == '\n');
|
int lineCount = rendered.Count(c => c == '\n');
|
||||||
|
|
||||||
await WriteAsync(rendered);
|
await WriteAsync(rendered);
|
||||||
|
|
@ -278,7 +289,6 @@ public sealed class WebTerminal
|
||||||
selected = (selected + 1) % options.Count;
|
selected = (selected + 1) % options.Count;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.Enter:
|
case ConsoleKey.Enter:
|
||||||
// Clear the rendered selection before returning
|
|
||||||
await WriteAsync($"\x1b[{lineCount}A\x1b[J");
|
await WriteAsync($"\x1b[{lineCount}A\x1b[J");
|
||||||
return selected;
|
return selected;
|
||||||
case ConsoleKey.D1 or ConsoleKey.NumPad1: if (options.Count >= 1) { await WriteAsync($"\x1b[{lineCount}A\x1b[J"); return 0; } break;
|
case ConsoleKey.D1 or ConsoleKey.NumPad1: if (options.Count >= 1) { await WriteAsync($"\x1b[{lineCount}A\x1b[J"); return 0; } break;
|
||||||
|
|
@ -292,7 +302,7 @@ public sealed class WebTerminal
|
||||||
case ConsoleKey.D9 or ConsoleKey.NumPad9: if (options.Count >= 9) { await WriteAsync($"\x1b[{lineCount}A\x1b[J"); return 8; } break;
|
case ConsoleKey.D9 or ConsoleKey.NumPad9: if (options.Count >= 9) { await WriteAsync($"\x1b[{lineCount}A\x1b[J"); return 8; } break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear and re-render
|
// Clear menu before re-rendering
|
||||||
await WriteAsync($"\x1b[{lineCount}A\x1b[J");
|
await WriteAsync($"\x1b[{lineCount}A\x1b[J");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,7 @@ body {
|
||||||
#terminal {
|
#terminal {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 960px;
|
max-width: 1200px;
|
||||||
max-height: 600px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loading screen */
|
/* Loading screen */
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,17 @@ window.terminalInterop = {
|
||||||
const fitAddon = new FitAddon.FitAddon();
|
const fitAddon = new FitAddon.FitAddon();
|
||||||
term.loadAddon(fitAddon);
|
term.loadAddon(fitAddon);
|
||||||
|
|
||||||
|
// Show terminal container BEFORE opening so fitAddon can measure real dimensions
|
||||||
|
document.getElementById('loading').classList.add('hidden');
|
||||||
|
document.getElementById('terminal-container').classList.add('active');
|
||||||
|
|
||||||
term.open(document.getElementById('terminal'));
|
term.open(document.getElementById('terminal'));
|
||||||
|
|
||||||
// Fit to container, but enforce minimum dimensions for game readability
|
// Fit to container, enforce minimum dimensions for game readability
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
if (term.cols < 120 || term.rows < 30) {
|
const minCols = 120, minRows = 30;
|
||||||
term.resize(Math.max(term.cols, 120), Math.max(term.rows, 30));
|
if (term.cols < minCols || term.rows < minRows) {
|
||||||
|
term.resize(Math.max(term.cols, minCols), Math.max(term.rows, minRows));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward key input to C#
|
// Forward key input to C#
|
||||||
|
|
@ -40,18 +45,13 @@ window.terminalInterop = {
|
||||||
// Handle resize
|
// Handle resize
|
||||||
window.addEventListener('resize', function () {
|
window.addEventListener('resize', function () {
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
if (term.cols < 120 || term.rows < 30) {
|
if (term.cols < minCols || term.rows < minRows) {
|
||||||
term.resize(Math.max(term.cols, 120), Math.max(term.rows, 30));
|
term.resize(Math.max(term.cols, minCols), Math.max(term.rows, minRows));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.term = term;
|
this.term = term;
|
||||||
this.fitAddon = fitAddon;
|
this.fitAddon = fitAddon;
|
||||||
|
|
||||||
// Show terminal, hide loading
|
|
||||||
document.getElementById('loading').classList.add('hidden');
|
|
||||||
document.getElementById('terminal-container').classList.add('active');
|
|
||||||
|
|
||||||
term.focus();
|
term.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -72,5 +72,12 @@ window.terminalInterop = {
|
||||||
if (this.term) {
|
if (this.term) {
|
||||||
this.term.focus();
|
this.term.focus();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getDimensions: function () {
|
||||||
|
if (this.term) {
|
||||||
|
return { cols: this.term.cols, rows: this.term.rows };
|
||||||
|
}
|
||||||
|
return { cols: 120, rows: 30 };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue