Fix WSL sessions not starting in home directory on newer Windows builds (#11663)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Eugene <inbox@null.page>
This commit is contained in:
Ken Kuang
2026-09-12 14:39:22 +02:00
committed by GitHub
co-authored by Copilot Eugene
parent 63a318185a
commit cdae0b6ea2
5 changed files with 40 additions and 8 deletions
+1
View File
@@ -5,6 +5,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
export const WIN_BUILD_CONPTY_SUPPORTED = 17692
export const WIN_BUILD_CONPTY_STABLE = 18309
export const WIN_BUILD_WSL_EXE_DISTRO_FLAG = 17763
export const WIN_BUILD_WSL_EXE_CD_FLAG = 19041
export const WIN_BUILD_FLUENT_BG_SUPPORTED = 17063
export function getWindows10Build (): number|undefined {
+8 -1
View File
@@ -2,7 +2,7 @@ import * as fs from 'mz/fs'
import slugify from 'slugify'
import { Injectable } from '@angular/core'
import { HostAppService, Platform, isWindowsBuild, WIN_BUILD_WSL_EXE_DISTRO_FLAG } from 'tabby-core'
import { HostAppService, Platform, isWindowsBuild, WIN_BUILD_WSL_EXE_DISTRO_FLAG, WIN_BUILD_WSL_EXE_CD_FLAG } from 'tabby-core'
import { ShellProvider, Shell } from 'tabby-local'
@@ -63,6 +63,11 @@ export class WSLShellProvider extends ShellProvider {
const lxss = wnr.getRegistryKey(wnr.HK.CU, lxssPath)
const shells: Shell[] = []
// WSL only honors `--cd` for Linux-style paths (e.g. `~`) starting with this build.
// On older builds, omit it and fall back to the previous (native cwd inheritance) behavior.
// https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp
const homeDirArgs = isWindowsBuild(WIN_BUILD_WSL_EXE_CD_FLAG) ? ['--cd', '~'] : undefined
if (lxss?.DefaultDistribution) {
const defaultDistKey = wnr.getRegistryKey(wnr.HK.CU, lxssPath + '\\' + String(lxss.DefaultDistribution.value))
if (defaultDistKey?.DistributionName) {
@@ -71,6 +76,7 @@ export class WSLShellProvider extends ShellProvider {
id: 'wsl',
name: 'WSL / Default distro',
command: wslPath,
homeDirArgs,
env: {
TERM: 'xterm-color',
COLORTERM: 'truecolor',
@@ -114,6 +120,7 @@ export class WSLShellProvider extends ShellProvider {
name: `WSL / ${name}`,
command: wslPath,
args: ['-d', name],
homeDirArgs,
fsBase,
env: {
TERM: 'xterm-color',
+9
View File
@@ -17,6 +17,13 @@ export interface Shell {
cwd?: string
/**
* Args that make the shell start in its own home directory (e.g. WSL's `--cd ~`).
* Only applied when the session has no working directory of its own, since these
* would otherwise override it.
*/
homeDirArgs?: string[]
/**
* SVG icon
*/
@@ -39,6 +46,8 @@ export interface SessionOptions {
restoreFromPTYID: string | null
command: string
args: string[]
/** See {@link Shell.homeDirArgs} */
homeDirArgs: string[]
cwd: string | null
env: Record<string, string>
width: number | null
+2
View File
@@ -16,6 +16,7 @@ export class LocalProfilesService extends ProfileProvider<LocalProfile> {
restoreFromPTYID: null,
command: '',
args: [],
homeDirArgs: [],
cwd: null,
env: {
__nonStructural: true,
@@ -82,6 +83,7 @@ export class LocalProfilesService extends ProfileProvider<LocalProfile> {
...this.configDefaults.options,
command: shell.command,
args: shell.args ?? [],
homeDirArgs: shell.homeDirArgs ?? [],
env: shell.env,
cwd: shell.cwd ?? null,
shellType: shell.shellType ?? null,
+20 -7
View File
@@ -7,6 +7,17 @@ import { getEnvironment, substituteEnv } from './environment'
import { resolveGuestCWD } from './wslPath'
import { isDirectory, isDirectorySync } from './util'
function usableCWD (path?: string|null): string|undefined {
if (!path) {
return undefined
}
if (!isDirectorySync(path)) {
console.warn('Ignoring invalid CWD:', path)
return undefined
}
return path
}
const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi
function mergeEnv (...envs) {
@@ -87,16 +98,18 @@ export class Session extends BaseSession {
})
}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
let cwd = resolveGuestCWD(options.cwd, options.fsBase) || process.env.HOME
// resolveGuestCWD maps a POSIX cwd reported by a guest shell (WSL) onto its
// Windows-visible path before we validate it.
const explicitCWD = usableCWD(resolveGuestCWD(options.cwd, options.fsBase))
if (!isDirectorySync(cwd)) {
console.warn('Ignoring invalid CWD:', cwd)
cwd = undefined
}
// A shell that knows how to start in its own home directory (WSL's `--cd ~`) only gets
// to do so when we have no working directory for it - those args outrank the cwd below.
const args = explicitCWD ? options.args : [...options.args, ...options.homeDirArgs]
const cwd = explicitCWD ?? usableCWD(process.env.HOME)
try {
pty = await this.ptyInterface.spawn(options.command, options.args, {
pty = await this.ptyInterface.spawn(options.command, args, {
name: 'xterm-256color',
cols: options.width ?? 80,
rows: options.height ?? 30,