Skip to content

Commit bc120fb

Browse files
merge: integrate pinned main into Windows clipboard fix
2 parents 918a076 + b34501a commit bc120fb

426 files changed

Lines changed: 17718 additions & 2707 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/deploy-relay.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
deploy_relay:
2828
name: Deploy production relay
2929
# A manual run from another branch would deploy that branch to production.
30-
if: github.ref == 'refs/heads/main'
30+
if: github.repository == 'pingdotgg/t3code' && github.ref == 'refs/heads/main'
3131
runs-on: blacksmith-8vcpu-ubuntu-2404
3232
timeout-minutes: 15
3333
environment:

‎.github/workflows/mobile-android-apk.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ concurrency:
1515
jobs:
1616
mirror:
1717
name: Mirror beta APK
18+
if: github.repository == 'pingdotgg/t3code'
1819
runs-on: blacksmith-2vcpu-ubuntu-2404
1920
timeout-minutes: 10
2021
permissions:

‎.github/workflows/mobile-eas-production.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ concurrency:
7575
jobs:
7676
production:
7777
name: EAS ${{ inputs.profile || 'production' }} ${{ github.event_name == 'push' && 'auto' || inputs.mode }}
78+
if: github.repository == 'pingdotgg/t3code'
7879
runs-on: blacksmith-8vcpu-ubuntu-2404
7980
permissions:
8081
contents: read

‎.github/workflows/publish-aur.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ concurrency:
3737
jobs:
3838
publish:
3939
name: Validate and publish
40+
if: github.repository == 'pingdotgg/t3code'
4041
runs-on: blacksmith-8vcpu-ubuntu-2404
4142
timeout-minutes: 30
4243
container:

‎.github/workflows/release.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ jobs:
5050
# have already run. Scheduled runs also decide here whether a nightly is due.
5151
resolve_commit:
5252
name: Resolve release commit
53+
if: github.repository == 'pingdotgg/t3code'
5354
runs-on: blacksmith-8vcpu-ubuntu-2404
5455
timeout-minutes: 5
5556
outputs:
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
!macro customInstall
2+
!ifndef DO_NOT_CREATE_START_MENU_SHORTCUT
3+
${IfNot} ${FileExists} "$newStartMenuLink"
4+
!insertmacro createMenuDirectory
5+
CreateShortCut "$newStartMenuLink" "$appExe" "" "$appExe" 0 "" "" "${APP_DESCRIPTION}"
6+
ClearErrors
7+
WinShell::SetLnkAUMI "$newStartMenuLink" "${APP_ID}"
8+
${EndIf}
9+
!endif
10+
!macroend

‎apps/desktop/scripts/build-preview-annotation-css.mjs‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,16 @@ const compilerInput = [
2929
annotationSource.replace('@import "tailwindcss";', "@tailwind utilities;"),
3030
].join("\n");
3131
const compiler = await compile(compilerInput, { base: appRoot });
32-
const css = compiler.build([...candidates]);
32+
// Shadow-root styles cannot register @property defaults. Make Tailwind's
33+
// fallback unconditional so border, shadow, and ring utilities have defaults.
34+
const compiledCss = compiler.build([...candidates]);
35+
const css = compiledCss.replace(
36+
/(@layer properties \{\n) @supports [^\n]*\{\n([\s\S]*?)\n \}\n(\})/,
37+
"$1$2\n$3",
38+
);
39+
if (css === compiledCss || /@layer properties\s*\{\s*@supports\b/.test(css)) {
40+
throw new Error("Tailwind @property fallback was not unwrapped; update the pattern above.");
41+
}
3342
const encodedCss = `'${css
3443
.replaceAll("\\", "\\\\")
3544
.replaceAll("'", "\\'")

‎apps/desktop/src/app/DesktopEarlyElectronStartup.test.ts‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as NodePath from "node:path";
33
import { assert, describe, it } from "@effect/vitest";
44

55
import {
6+
restoreEarlyLinuxDeviceScaleFactor,
67
resolveEarlyLinuxElectronOptions,
78
resolveEarlyLinuxPasswordStorePreference,
89
resolveLinuxDisableFeaturesSwitch,
@@ -269,3 +270,70 @@ describe("DesktopEarlyElectronStartup", () => {
269270
});
270271
});
271272
});
273+
274+
describe("Linux device scale persistence failures", () => {
275+
const input = {
276+
env: { T3CODE_HOME: "/isolated" },
277+
homeDirectory: "/home/user",
278+
joinPath: NodePath.posix.join,
279+
};
280+
281+
it.each(["0", "Infinity", "garbage"])("ignores invalid persisted scale %j", (value) => {
282+
const applied: Array<[string, string]> = [];
283+
const writes: Array<string> = [];
284+
restoreEarlyLinuxDeviceScaleFactor({
285+
...input,
286+
commandLine: {
287+
hasSwitch: () => false,
288+
getSwitchValue: () => "",
289+
appendSwitch: (name, scale) => applied.push([name, scale]),
290+
},
291+
readFileString: () => value,
292+
writeFileString: (_path, contents) => writes.push(contents),
293+
});
294+
assert.deepEqual(applied, []);
295+
assert.deepEqual(writes, []);
296+
});
297+
298+
it("keeps startup available with default scaling when saved state cannot be read", () => {
299+
const applied: Array<[string, string]> = [];
300+
restoreEarlyLinuxDeviceScaleFactor({
301+
...input,
302+
commandLine: {
303+
hasSwitch: () => false,
304+
getSwitchValue: () => "",
305+
appendSwitch: (name, value) => applied.push([name, value]),
306+
},
307+
readFileString: () => {
308+
throw new Error("ENOENT");
309+
},
310+
writeFileString: () => {},
311+
});
312+
assert.deepEqual(applied, []);
313+
});
314+
315+
it("keeps an explicit scale when saving it fails, without falling back to saved state", () => {
316+
const applied: Array<[string, string]> = [];
317+
const reads: Array<string> = [];
318+
const writes: Array<string> = [];
319+
restoreEarlyLinuxDeviceScaleFactor({
320+
...input,
321+
commandLine: {
322+
hasSwitch: () => true,
323+
getSwitchValue: () => "1",
324+
appendSwitch: (name, value) => applied.push([name, value]),
325+
},
326+
readFileString: (path) => {
327+
reads.push(path);
328+
return "1.75";
329+
},
330+
writeFileString: (_path, value) => {
331+
writes.push(value);
332+
throw new Error("EACCES");
333+
},
334+
});
335+
assert.deepEqual(writes, ["1"]);
336+
assert.deepEqual(reads, []);
337+
assert.deepEqual(applied, []);
338+
});
339+
});

‎apps/desktop/src/app/DesktopEarlyElectronStartup.ts‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,43 @@ export function resolveEarlyLinuxElectronOptions(
159159
}),
160160
};
161161
}
162+
163+
/** Remember the explicit Chromium scale across AppImage updates, which drop launch arguments. */
164+
export function restoreEarlyLinuxDeviceScaleFactor(
165+
input: EarlyDesktopSettingsInput & {
166+
readonly commandLine: {
167+
readonly hasSwitch: (name: string) => boolean;
168+
readonly getSwitchValue: (name: string) => string;
169+
readonly appendSwitch: (name: string, value: string) => void;
170+
};
171+
readonly writeFileString: (path: string, value: string) => void;
172+
},
173+
): void {
174+
// Keep this separate from desktop-settings.json: the settings service rewrites
175+
// that document, and Chromium needs the value before that service is available.
176+
const path = input.joinPath(
177+
resolveEarlyDesktopSettingsPath(input),
178+
"..",
179+
"linux-device-scale-factor",
180+
);
181+
const switchName = "force-device-scale-factor";
182+
const isValid = (value: string) =>
183+
value.trim().length > 0 && Number.isFinite(Number(value)) && Number(value) > 0;
184+
if (input.commandLine.hasSwitch(switchName)) {
185+
const value = input.commandLine.getSwitchValue(switchName);
186+
if (isValid(value)) {
187+
try {
188+
input.writeFileString(path, value);
189+
} catch {
190+
// A read-only state directory must not prevent startup with the explicit switch.
191+
}
192+
}
193+
return;
194+
}
195+
try {
196+
const value = input.readFileString(path).trim();
197+
if (isValid(value)) input.commandLine.appendSwitch(switchName, value);
198+
} catch {
199+
// First launch, missing state, or unreadable state: keep Chromium's default.
200+
}
201+
}

‎apps/desktop/src/app/DesktopLinuxUrlHandler.test.ts‎

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,25 @@ describe("DesktopLinuxUrlHandler", () => {
179179
assert.include(entry, "Icon=/home/al ice/icons/T3\\\\x.png");
180180
});
181181

182+
it.each([
183+
{
184+
execTarget: "/opt/T3(beta)/t3code.AppImage",
185+
execLine: 'Exec="/opt/T3(beta)/t3code.AppImage" %U',
186+
},
187+
{
188+
execTarget: "/opt/t3%20code/t3code.AppImage",
189+
execLine: "Exec=/opt/t3%%20code/t3code.AppImage %U",
190+
},
191+
])("renders the handler Exec line for $execTarget", ({ execTarget, execLine }) => {
192+
const entry = DesktopLinuxUrlHandler.renderUrlHandlerDesktopEntry({
193+
displayName: "T3 Code",
194+
execTarget,
195+
scheme: "t3code",
196+
});
197+
198+
assert.include(entry.split("\n"), execLine);
199+
});
200+
182201
it("carries structured context on registration errors", () => {
183202
const writeError = new DesktopLinuxUrlHandler.DesktopLinuxUrlHandlerRegistrationError({
184203
step: "write-desktop-entry",
@@ -222,7 +241,7 @@ describe("DesktopLinuxUrlHandler", () => {
222241
);
223242
assert.include(
224243
recorded.files[0]?.content,
225-
'Exec="/home/alice/Applications/T3-Code.AppImage" %U',
244+
"Exec=/home/alice/Applications/T3-Code.AppImage %U",
226245
);
227246
assert.include(recorded.files[0]?.content, "MimeType=x-scheme-handler/t3code;");
228247
assert.deepEqual(recorded.commands, [
@@ -247,7 +266,12 @@ describe("DesktopLinuxUrlHandler", () => {
247266

248267
assert.include(
249268
recorded.files[0]?.content,
250-
`Exec=${DesktopLinuxUrlHandler.escapeDesktopEntryExecArgument(process.execPath)} %U`,
269+
DesktopLinuxUrlHandler.renderUrlHandlerDesktopEntry({
270+
displayName: "T3 Code (Alpha)",
271+
execTarget: process.execPath,
272+
scheme: "t3code",
273+
iconPath: "/home/alice/.local/share/icons/com.t3tools.T3Code.desktop.png",
274+
}),
251275
);
252276
});
253277
});

0 commit comments

Comments
 (0)