fix(run): turn on tmux mouse mode on every attach, not just at session creation
Sessions created before the mouse-on fix landed (or before the server restarted to pick it up) never got the set-option call, so their pane still had no drag/wheel scroll. Moving it into pty-attach's attach() makes it idempotent per-connection instead of once-at-birth.
This commit is contained in:
@@ -5,10 +5,11 @@
|
|||||||
* or PTY spawned).
|
* or PTY spawned).
|
||||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||||
*/
|
*/
|
||||||
const { describe, it, beforeEach } = require("node:test");
|
const { describe, it, beforeEach, afterEach } = require("node:test");
|
||||||
const assert = require("node:assert/strict");
|
const assert = require("node:assert/strict");
|
||||||
const { EventEmitter } = require("node:events");
|
const { EventEmitter } = require("node:events");
|
||||||
const ptyAttach = require("../lib/pty-attach");
|
const ptyAttach = require("../lib/pty-attach");
|
||||||
|
const tmux = require("../lib/tmux");
|
||||||
|
|
||||||
function makeFakePty() {
|
function makeFakePty() {
|
||||||
const emitter = new EventEmitter();
|
const emitter = new EventEmitter();
|
||||||
@@ -41,6 +42,10 @@ describe("pty-attach", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fakePty = makeFakePty();
|
fakePty = makeFakePty();
|
||||||
ptyAttach.__setSpawnImpl(() => fakePty);
|
ptyAttach.__setSpawnImpl(() => fakePty);
|
||||||
|
tmux.__setExecImpl(() => "");
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
tmux.__reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("rejects a runId that doesn't match ccam-lane-<digits>", () => {
|
it("rejects a runId that doesn't match ccam-lane-<digits>", () => {
|
||||||
@@ -52,6 +57,25 @@ describe("pty-attach", () => {
|
|||||||
assert.doesNotThrow(() => ptyAttach.validateRunId("ccam-lane-42"));
|
assert.doesNotThrow(() => ptyAttach.validateRunId("ccam-lane-42"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("turns tmux mouse mode on for the session it attaches to", () => {
|
||||||
|
const calls = [];
|
||||||
|
tmux.__setExecImpl((args) => {
|
||||||
|
calls.push(args);
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
ptyAttach.attach(makeFakeWs(), "ccam-lane-1", { cols: 80, rows: 24 });
|
||||||
|
assert.deepEqual(calls[0], ["set-option", "-t", "ccam-lane-1", "mouse", "on"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("still attaches even if the mouse-mode set-option call fails", () => {
|
||||||
|
tmux.__setExecImpl(() => {
|
||||||
|
throw new Error("no such session: ccam-lane-1");
|
||||||
|
});
|
||||||
|
assert.doesNotThrow(() =>
|
||||||
|
ptyAttach.attach(makeFakeWs(), "ccam-lane-1", { cols: 80, rows: 24 })
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("wires PTY data to binary WS frames and WS binary frames to PTY writes", () => {
|
it("wires PTY data to binary WS frames and WS binary frames to PTY writes", () => {
|
||||||
const ws = makeFakeWs();
|
const ws = makeFakeWs();
|
||||||
ptyAttach.attach(ws, "ccam-lane-1", { cols: 80, rows: 24 });
|
ptyAttach.attach(ws, "ccam-lane-1", { cols: 80, rows: 24 });
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const tmux = require("./tmux");
|
||||||
|
|
||||||
const RUN_ID_RE = /^ccam-lane-\d+$/;
|
const RUN_ID_RE = /^ccam-lane-\d+$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,6 +40,14 @@ function __setSpawnImpl(fn) {
|
|||||||
*/
|
*/
|
||||||
function attach(ws, runId, { cols, rows }) {
|
function attach(ws, runId, { cols, rows }) {
|
||||||
validateRunId(runId);
|
validateRunId(runId);
|
||||||
|
// Retroactively covers sessions started before mouse mode was wired into
|
||||||
|
// newSession (or before a server restart picked that change up) — see
|
||||||
|
// tmux.js's enableMouse.
|
||||||
|
try {
|
||||||
|
tmux.enableMouse(runId);
|
||||||
|
} catch {
|
||||||
|
/* session gone or tmux unavailable — attach below will surface that */
|
||||||
|
}
|
||||||
const pty = spawnImpl("tmux", ["attach-session", "-t", runId], {
|
const pty = spawnImpl("tmux", ["attach-session", "-t", runId], {
|
||||||
name: "xterm-256color",
|
name: "xterm-256color",
|
||||||
cols: cols || 80,
|
cols: cols || 80,
|
||||||
|
|||||||
@@ -40,10 +40,17 @@ function hasSession(name) {
|
|||||||
*/
|
*/
|
||||||
function newSession({ name, cwd, argv }) {
|
function newSession({ name, cwd, argv }) {
|
||||||
execImpl(["new-session", "-d", "-s", name, "-c", cwd, "--", ...argv]);
|
execImpl(["new-session", "-d", "-s", name, "-c", cwd, "--", ...argv]);
|
||||||
|
enableMouse(name);
|
||||||
|
}
|
||||||
|
|
||||||
// Without this the pane has no scrollbar/drag scroll at all — wheel events
|
// Without this the pane has no scrollbar/drag scroll at all — wheel events
|
||||||
// just pass through to the running program instead of entering tmux's own
|
// just pass through to the running program instead of entering tmux's own
|
||||||
// copy-mode scrollback. xterm.js forwards tmux's mouse-tracking escapes
|
// copy-mode scrollback. xterm.js forwards tmux's mouse-tracking escapes
|
||||||
// automatically once mouse mode is on, so no client-side change is needed.
|
// automatically once mouse mode is on, so no client-side change is needed.
|
||||||
|
// Called on every attach (not just at creation) so a session started before
|
||||||
|
// this option existed — or before a server restart picked up the change —
|
||||||
|
// still gets it; `set-option` is idempotent, so re-running it is harmless.
|
||||||
|
function enableMouse(name) {
|
||||||
execImpl(["set-option", "-t", name, "mouse", "on"]);
|
execImpl(["set-option", "-t", name, "mouse", "on"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +119,7 @@ function isTmuxAvailable() {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
hasSession,
|
hasSession,
|
||||||
newSession,
|
newSession,
|
||||||
|
enableMouse,
|
||||||
paneCommand,
|
paneCommand,
|
||||||
sendCommand,
|
sendCommand,
|
||||||
killSession,
|
killSession,
|
||||||
|
|||||||
Reference in New Issue
Block a user