From 225f120fbe6c816734c8f1e728ed56b721be0771 Mon Sep 17 00:00:00 2001 From: sawka Date: Sat, 3 Sep 2022 23:39:50 -0700 Subject: [PATCH] move width from ScreenWindowView to ScreenWindow. pass termopts.cols in uicontext to cmdrunner --- src/main.tsx | 52 ++++++++++++++++++++-------------------------------- src/model.ts | 38 +++++++++++++++++++++++++++++++------- src/term.ts | 4 +++- src/types.ts | 8 ++++++++ 4 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index fb1b32fc..a6e06d0e 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -887,15 +887,19 @@ class CmdInput extends React.Component<{}, {}> { } } +// sw is not null @mobxReact.observer class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { mutObs : any; rszObs : any; interObs : IntersectionObserver; randomId : string; - width : mobx.IObservableValue = mobx.observable.box(0); lastHeight : number = null; + constructor(props : any) { + super(props); + } + scrollToBottom(reason : string) { let elem = document.getElementById(this.getLinesDOMId()); if (elem == null) { @@ -911,7 +915,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { let {sw} = this.props; let target = event.target; let atBottom = (target.scrollTop + 30 > (target.scrollHeight - target.offsetHeight)); - if (sw && sw.shouldFollow.get() != atBottom) { + if (sw.shouldFollow.get() != atBottom) { mobx.action(() => sw.shouldFollow.set(atBottom))(); } // console.log("scroll-handler (sw)>", atBottom, target.scrollTop, target.scrollHeight, event); @@ -924,7 +928,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { this.mutObs.observe(elem, {childList: true}); elem.addEventListener("termresize", this.handleTermResize); let {sw} = this.props; - if (sw && sw.shouldFollow.get()) { + if (sw.shouldFollow.get()) { setTimeout(() => this.scrollToBottom("mount"), 0); } this.interObs = new IntersectionObserver(interObsCallback, { @@ -940,12 +944,6 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { } } - updateWidth(width : number) { - mobx.action(() => { - this.width.set(width); - })(); - } - componentWillUnmount() { if (this.mutObs) { this.mutObs.disconnect(); @@ -956,6 +954,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { if (this.interObs) { this.interObs.disconnect(); } + this.props.sw.setWidth(0); } handleResize(entries : any) { @@ -964,7 +963,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { } let entry = entries[0]; let width = entry.target.offsetWidth; - this.updateWidth(width); + this.props.sw.setWidth(width); if (this.lastHeight == null) { this.lastHeight = entry.target.offsetHeight; return; @@ -981,16 +980,13 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { doConditionalScrollToBottom(reason : string) { let {sw} = this.props; - if (sw && sw.shouldFollow.get()) { + if (sw.shouldFollow.get()) { setTimeout(() => this.scrollToBottom(reason), 0); } } getWindow() : Window { let {sw} = this.props; - if (sw == null) { - return null; - } let win = GlobalModel.getWindowById(sw.sessionId, sw.windowId); if (win == null) { win = GlobalModel.loadWindow(sw.sessionId, sw.windowId); @@ -1005,7 +1001,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { @boundMethod handleTermResize(e : any) { let {sw} = this.props; - if (sw && sw.shouldFollow.get()) { + if (sw.shouldFollow.get()) { setTimeout(() => this.scrollToBottom("termresize"), 0); } } @@ -1017,12 +1013,6 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { getWindowId() : string { let {sw} = this.props; - if (sw == null) { - if (!this.randomId) { - this.randomId = uuidv4(); - } - return this.randomId; - } return sw.windowId; } @@ -1035,9 +1025,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { return (
- - {sw.name.get()}{sw.shouldFollow.get() ? "*" : ""} - + {sw.name.get()}{sw.shouldFollow.get() ? "*" : ""}
@@ -1049,9 +1037,6 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { render() { let {sw} = this.props; - if (sw == null) { - return this.renderError("(no screen window)"); - } let win = this.getWindow(); if (win == null || !win.loaded.get()) { return this.renderError("(loading)"); @@ -1059,7 +1044,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { if (win.loadError.get() != null) { return this.renderError(sprintf("(%s)", win.loadError.get())); } - if (this.width.get() == 0) { + if (sw.width.get() == 0) { return this.renderError(""); } let idx = 0; @@ -1087,7 +1072,7 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> {
- win.lines.length-1-7} cmdRefNum={cmdRefMap[line.lineid] ?? 0}/> + win.lines.length-1-7} cmdRefNum={cmdRefMap[line.lineid] ?? 0}/>
@@ -1104,14 +1089,17 @@ class ScreenWindowView extends React.Component<{sw : ScreenWindow}, {}> { class ScreenView extends React.Component<{screen : Screen}, {}> { render() { let {screen} = this.props; - if (screen == null) { + let sw : ScreenWindow = null; + if (screen != null) { + sw = screen.getActiveSW(); + } + if (screen == null || sw == null) { return (
- (no screen) + (no screen or window)
); } - let sw = screen.getActiveSW(); return (
diff --git a/src/model.ts b/src/model.ts index 9d583150..3d7ad20f 100644 --- a/src/model.ts +++ b/src/model.ts @@ -8,6 +8,16 @@ import type {SessionDataType, WindowDataType, LineType, RemoteType, HistoryItem, import {WSControl} from "./ws"; var GlobalUser = "sawka"; +const DefaultCellWidth = 8; +const DefaultCellHeight = 16; + +function widthToCols(width : number) : number { + let cols = Math.trunc((width - 25) / DefaultCellWidth) - 1; + if (cols < 0) { + return 0; + } + return cols; +} type OV = mobx.IObservableValue; type OArr = mobx.IObservableArray; @@ -242,6 +252,7 @@ class ScreenWindow { name : OV; layout : OV; shouldFollow : OV = mobx.observable.box(true); + width : OV = mobx.observable.box(0); // cmdid => TermWrap terms : Record = {}; @@ -264,6 +275,12 @@ class ScreenWindow { term.updatePtyData(ptyMsg.ptypos, data); } + setWidth(width : number) : void { + mobx.action(() => { + this.width.set(width); + })(); + } + getTermWrap(cmdId : string) : TermWrap { return this.terms[cmdId]; } @@ -275,7 +292,8 @@ class ScreenWindow { console.log("term-wrap already exists for", this.screenId, this.windowId, cmdId); return; } - let usedRows = GlobalModel.getTUR(this.sessionId, cmdId, width); + let cols = widthToCols(width); + let usedRows = GlobalModel.getTUR(this.sessionId, cmdId, cols); termWrap = new TermWrap(elem, this.sessionId, cmdId, usedRows, cmd.getTermOpts(), {height: 0, width: width}, cmd.handleKey.bind(cmd)); this.terms[cmdId] = termWrap; return; @@ -296,7 +314,8 @@ class ScreenWindow { } let termWrap = this.getTermWrap(cmd.cmdId); if (termWrap == null) { - let usedRows = GlobalModel.getTUR(this.sessionId, cmd.cmdId, width); + let cols = widthToCols(width); + let usedRows = GlobalModel.getTUR(this.sessionId, cmd.cmdId, cols); if (usedRows != null) { return usedRows; } @@ -1127,13 +1146,13 @@ class Model { getApi().onDigitCmd(this.onDigitCmd.bind(this)); } - getTUR(sessionId : string, cmdId : string, width : number) : number { - let key = sessionId + "/" + cmdId + "/" + width; + getTUR(sessionId : string, cmdId : string, cols : number) : number { + let key = sessionId + "/" + cmdId + "/" + cols; return this.termUsedRowsCache[key]; } - setTUR(sessionId : string, cmdId : string, width : number, usedRows : number) : void { - let key = sessionId + "/" + cmdId + "/" + width; + setTUR(sessionId : string, cmdId : string, cols : number, usedRows : number) : void { + let key = sessionId + "/" + cmdId + "/" + cols; this.termUsedRowsCache[key] = usedRows; } @@ -1148,6 +1167,7 @@ class Model { screenid : null, windowid : null, remote : null, + termopts : {}, }; let session = this.getActiveSession(); if (session != null) { @@ -1160,6 +1180,10 @@ class Model { rtn.windowid = win.windowId; rtn.remote = win.curRemote.get(); } + let sw = screen.getActiveSW(); + if (sw != null) { + rtn.termopts.cols = widthToCols(sw.width.get()); + } } } return rtn; @@ -1731,6 +1755,6 @@ if ((window as any).GlobalModal == null) { GlobalModel = (window as any).GlobalModel; GlobalCommandRunner = (window as any).GlobalCommandRunner; -export {Model, Session, Window, GlobalModel, GlobalCommandRunner, Cmd, Screen, ScreenWindow, riToRPtr}; +export {Model, Session, Window, GlobalModel, GlobalCommandRunner, Cmd, Screen, ScreenWindow, riToRPtr, widthToCols}; diff --git a/src/term.ts b/src/term.ts index 92e75bd2..78f18004 100644 --- a/src/term.ts +++ b/src/term.ts @@ -48,6 +48,7 @@ class TermWrap { loadError : mobx.IObservableValue = mobx.observable.box(false); winSize : WindowSize; numParseErrors : number = 0; + termCols : number; constructor(elem : Element, sessionId : string, cmdId : string, usedRows : number, termOpts : TermOptsType, winSize : WindowSize, keyHandler : (event : any) => void) { this.sessionId = sessionId; @@ -68,6 +69,7 @@ class TermWrap { if (maxCols > cols) { cols = maxCols; } + this.termCols = maxCols; this.terminal = new Terminal({rows: termOpts.rows, cols: maxCols, fontSize: 14, theme: {foreground: "#d3d7cf"}}); this.terminal._core._inputHandler._parser.setErrorHandler((state) => { this.numParseErrors++; @@ -155,7 +157,7 @@ class TermWrap { mobx.action(() => { let oldUsedRows = this.usedRows.get(); this.usedRows.set(tur); - GlobalModel.setTUR(this.sessionId, this.cmdId, this.winSize.width, tur); + GlobalModel.setTUR(this.sessionId, this.cmdId, this.termCols, tur); if (this.connectedElem) { let resizeEvent = new CustomEvent("termresize", { bubbles: true, diff --git a/src/types.ts b/src/types.ts index eff669a8..3f1e216a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -139,11 +139,19 @@ type CmdRemoteStateType = { cwd : string, }; +type UIContextTermOptsType = { + rows? : number, + cols? : number, + term? : string, + maxptysize? : number, +}; + type UIContextType = { sessionid : string, screenid : string, windowid : string, remote : RemotePtrType, + termopts : UIContextTermOptsType, }; type FeCmdPacketType = {