| ... | @@ -122,6 +122,7 @@ import { | ... | @@ -122,6 +122,7 @@ import { |
| 122 | backgroundActivitySharedPolicySettings, | 122 | backgroundActivitySharedPolicySettings, |
| 123 | durationToSeconds, | 123 | durationToSeconds, |
| 124 | formatDiagnosticsDescription, | 124 | formatDiagnosticsDescription, |
| | 125 | getChangedTypographySettingLabels, |
| 125 | normalizeIntervalSeconds, | 126 | normalizeIntervalSeconds, |
| 126 | PROVIDER_HEALTH_INTERVAL_STEP_SECONDS, | 127 | PROVIDER_HEALTH_INTERVAL_STEP_SECONDS, |
| 127 | hasChangedBackgroundActivitySettings, | 128 | hasChangedBackgroundActivitySettings, |
| ... | @@ -493,16 +494,7 @@ export function useSettingsRestore(onRestored?: () => void) { | ... | @@ -493,16 +494,7 @@ export function useSettingsRestore(onRestored?: () => void) { |
| 493 | ? ["Auto-settle inactive threads"] | 494 | ? ["Auto-settle inactive threads"] |
| 494 | : []), | 495 | : []), |
| 495 | ...(settings.wordWrap !== DEFAULT_UNIFIED_SETTINGS.wordWrap ? ["Word wrap"] : []), | 496 | ...(settings.wordWrap !== DEFAULT_UNIFIED_SETTINGS.wordWrap ? ["Word wrap"] : []), |
| 496 | ...(settings.fontFamilySans !== DEFAULT_UNIFIED_SETTINGS.fontFamilySans | 497 | ...getChangedTypographySettingLabels(settings), |
| 497 | ? ["Interface font"] | | |
| 498 | : []), | | |
| 499 | ...(settings.fontFamilyComposer !== DEFAULT_UNIFIED_SETTINGS.fontFamilyComposer | | |
| 500 | ? ["Prompt font"] | | |
| 501 | : []), | | |
| 502 | ...(settings.fontFamilyCode !== DEFAULT_UNIFIED_SETTINGS.fontFamilyCode ? ["Code font"] : []), | | |
| 503 | ...(settings.fontFamilyTerminal !== DEFAULT_UNIFIED_SETTINGS.fontFamilyTerminal | | |
| 504 | ? ["Terminal font"] | | |
| 505 | : []), | | |
| 506 | ...(settings.diffIgnoreWhitespace !== DEFAULT_UNIFIED_SETTINGS.diffIgnoreWhitespace | 498 | ...(settings.diffIgnoreWhitespace !== DEFAULT_UNIFIED_SETTINGS.diffIgnoreWhitespace |
| 507 | ? ["Diff whitespace changes"] | 499 | ? ["Diff whitespace changes"] |
| 508 | : []), | 500 | : []), |
| ... | @@ -652,6 +644,10 @@ export function useSettingsRestore(onRestored?: () => void) { | ... | @@ -652,6 +644,10 @@ export function useSettingsRestore(onRestored?: () => void) { |
| 652 | fontFamilyComposer: DEFAULT_UNIFIED_SETTINGS.fontFamilyComposer, | 644 | fontFamilyComposer: DEFAULT_UNIFIED_SETTINGS.fontFamilyComposer, |
| 653 | fontFamilyCode: DEFAULT_UNIFIED_SETTINGS.fontFamilyCode, | 645 | fontFamilyCode: DEFAULT_UNIFIED_SETTINGS.fontFamilyCode, |
| 654 | fontFamilyTerminal: DEFAULT_UNIFIED_SETTINGS.fontFamilyTerminal, | 646 | fontFamilyTerminal: DEFAULT_UNIFIED_SETTINGS.fontFamilyTerminal, |
| | 647 | fontSizeInterface: DEFAULT_UNIFIED_SETTINGS.fontSizeInterface, |
| | 648 | fontSizePrompt: DEFAULT_UNIFIED_SETTINGS.fontSizePrompt, |
| | 649 | fontSizeCode: DEFAULT_UNIFIED_SETTINGS.fontSizeCode, |
| | 650 | fontSizeTerminal: DEFAULT_UNIFIED_SETTINGS.fontSizeTerminal, |
| 655 | }); | 651 | }); |
| 656 | onRestored?.(); | 652 | onRestored?.(); |
| 657 | }, [ | 653 | }, [ |
| ... | @@ -1105,13 +1101,21 @@ function InterfaceFontRow({ preview }: { preview?: ReactNode }) { | ... | @@ -1105,13 +1101,21 @@ function InterfaceFontRow({ preview }: { preview?: ReactNode }) { |
| 1105 | {...searchableSetting("interface-font")} | 1101 | {...searchableSetting("interface-font")} |
| 1106 | description="Everything outside code blocks and the terminal." | 1102 | description="Everything outside code blocks and the terminal." |
| 1107 | defaultFamily={defaults.sans} | 1103 | defaultFamily={defaults.sans} |
| | 1104 | defaultValue={DEFAULT_UNIFIED_SETTINGS.fontFamilySans} |
| 1108 | value={settings.fontFamilySans} | 1105 | value={settings.fontFamilySans} |
| 1109 | onValueChange={(fontFamilySans) => updateSettings({ fontFamilySans })} | 1106 | onValueChange={(fontFamilySans) => updateSettings({ fontFamilySans })} |
| | 1107 | onReset={() => |
| | 1108 | updateSettings({ |
| | 1109 | fontFamilySans: DEFAULT_UNIFIED_SETTINGS.fontFamilySans, |
| | 1110 | fontSizeInterface: DEFAULT_UNIFIED_SETTINGS.fontSizeInterface, |
| | 1111 | }) |
| | 1112 | } |
| 1110 | size={{ | 1113 | size={{ |
| 1111 | label: "Interface font size", | 1114 | label: "Interface font size", |
| 1112 | min: MIN_INTERFACE_FONT_SIZE, | 1115 | min: MIN_INTERFACE_FONT_SIZE, |
| 1113 | max: MAX_INTERFACE_FONT_SIZE, | 1116 | max: MAX_INTERFACE_FONT_SIZE, |
| 1114 | value: settings.fontSizeInterface, | 1117 | value: settings.fontSizeInterface, |
| | 1118 | defaultValue: DEFAULT_UNIFIED_SETTINGS.fontSizeInterface, |
| 1115 | onChange: (fontSizeInterface) => updateSettings({ fontSizeInterface }), | 1119 | onChange: (fontSizeInterface) => updateSettings({ fontSizeInterface }), |
| 1116 | }} | 1120 | }} |
| 1117 | {...(preview !== undefined ? { preview } : {})} | 1121 | {...(preview !== undefined ? { preview } : {})} |
| ... | @@ -1128,13 +1132,21 @@ function PromptFontRow() { | ... | @@ -1128,13 +1132,21 @@ function PromptFontRow() { |
| 1128 | {...searchableSetting("prompt-font")} | 1132 | {...searchableSetting("prompt-font")} |
| 1129 | description="Only the box you write prompts in. Mono works well here." | 1133 | description="Only the box you write prompts in. Mono works well here." |
| 1130 | defaultFamily={defaults.interfaceFamily} | 1134 | defaultFamily={defaults.interfaceFamily} |
| | 1135 | defaultValue={DEFAULT_UNIFIED_SETTINGS.fontFamilyComposer} |
| 1131 | value={settings.fontFamilyComposer} | 1136 | value={settings.fontFamilyComposer} |
| 1132 | onValueChange={(fontFamilyComposer) => updateSettings({ fontFamilyComposer })} | 1137 | onValueChange={(fontFamilyComposer) => updateSettings({ fontFamilyComposer })} |
| | 1138 | onReset={() => |
| | 1139 | updateSettings({ |
| | 1140 | fontFamilyComposer: DEFAULT_UNIFIED_SETTINGS.fontFamilyComposer, |
| | 1141 | fontSizePrompt: DEFAULT_UNIFIED_SETTINGS.fontSizePrompt, |
| | 1142 | }) |
| | 1143 | } |
| 1133 | size={{ | 1144 | size={{ |
| 1134 | label: "Prompt font size", | 1145 | label: "Prompt font size", |
| 1135 | min: MIN_PROMPT_FONT_SIZE, | 1146 | min: MIN_PROMPT_FONT_SIZE, |
| 1136 | max: MAX_PROMPT_FONT_SIZE, | 1147 | max: MAX_PROMPT_FONT_SIZE, |
| 1137 | value: settings.fontSizePrompt, | 1148 | value: settings.fontSizePrompt, |
| | 1149 | defaultValue: DEFAULT_UNIFIED_SETTINGS.fontSizePrompt, |
| 1138 | onChange: (fontSizePrompt) => updateSettings({ fontSizePrompt }), | 1150 | onChange: (fontSizePrompt) => updateSettings({ fontSizePrompt }), |
| 1139 | }} | 1151 | }} |
| 1140 | preview={<PromptFontPreview />} | 1152 | preview={<PromptFontPreview />} |
| ... | @@ -1160,14 +1172,22 @@ function CodeFontRow({ | ... | @@ -1160,14 +1172,22 @@ function CodeFontRow({ |
| 1160 | {...(title !== undefined ? { title } : {})} | 1172 | {...(title !== undefined ? { title } : {})} |
| 1161 | description={description} | 1173 | description={description} |
| 1162 | defaultFamily={defaults.code} | 1174 | defaultFamily={defaults.code} |
| | 1175 | defaultValue={DEFAULT_UNIFIED_SETTINGS.fontFamilyCode} |
| 1163 | value={settings.fontFamilyCode} | 1176 | value={settings.fontFamilyCode} |
| 1164 | onValueChange={(fontFamilyCode) => updateSettings({ fontFamilyCode })} | 1177 | onValueChange={(fontFamilyCode) => updateSettings({ fontFamilyCode })} |
| | 1178 | onReset={() => |
| | 1179 | updateSettings({ |
| | 1180 | fontFamilyCode: DEFAULT_UNIFIED_SETTINGS.fontFamilyCode, |
| | 1181 | fontSizeCode: DEFAULT_UNIFIED_SETTINGS.fontSizeCode, |
| | 1182 | }) |
| | 1183 | } |
| 1165 | requireMonospace | 1184 | requireMonospace |
| 1166 | size={{ | 1185 | size={{ |
| 1167 | label: "Code font size", | 1186 | label: "Code font size", |
| 1168 | min: MIN_CODE_FONT_SIZE, | 1187 | min: MIN_CODE_FONT_SIZE, |
| 1169 | max: MAX_CODE_FONT_SIZE, | 1188 | max: MAX_CODE_FONT_SIZE, |
| 1170 | value: settings.fontSizeCode, | 1189 | value: settings.fontSizeCode, |
| | 1190 | defaultValue: DEFAULT_UNIFIED_SETTINGS.fontSizeCode, |
| 1171 | onChange: (fontSizeCode) => updateSettings({ fontSizeCode }), | 1191 | onChange: (fontSizeCode) => updateSettings({ fontSizeCode }), |
| 1172 | }} | 1192 | }} |
| 1173 | preview={preview ?? <CodeFontPreview />} | 1193 | preview={preview ?? <CodeFontPreview />} |
| ... | @@ -1184,14 +1204,22 @@ function TerminalFontRow() { | ... | @@ -1184,14 +1204,22 @@ function TerminalFontRow() { |
| 1184 | {...searchableSetting("terminal-font")} | 1204 | {...searchableSetting("terminal-font")} |
| 1185 | description="Terminal output, independent from code blocks and diffs." | 1205 | description="Terminal output, independent from code blocks and diffs." |
| 1186 | defaultFamily={defaults.code} | 1206 | defaultFamily={defaults.code} |
| | 1207 | defaultValue={DEFAULT_UNIFIED_SETTINGS.fontFamilyTerminal} |
| 1187 | value={settings.fontFamilyTerminal} | 1208 | value={settings.fontFamilyTerminal} |
| 1188 | onValueChange={(fontFamilyTerminal) => updateSettings({ fontFamilyTerminal })} | 1209 | onValueChange={(fontFamilyTerminal) => updateSettings({ fontFamilyTerminal })} |
| | 1210 | onReset={() => |
| | 1211 | updateSettings({ |
| | 1212 | fontFamilyTerminal: DEFAULT_UNIFIED_SETTINGS.fontFamilyTerminal, |
| | 1213 | fontSizeTerminal: DEFAULT_UNIFIED_SETTINGS.fontSizeTerminal, |
| | 1214 | }) |
| | 1215 | } |
| 1189 | requireMonospace | 1216 | requireMonospace |
| 1190 | size={{ | 1217 | size={{ |
| 1191 | label: "Terminal font size", | 1218 | label: "Terminal font size", |
| 1192 | min: MIN_TERMINAL_FONT_SIZE, | 1219 | min: MIN_TERMINAL_FONT_SIZE, |
| 1193 | max: MAX_TERMINAL_FONT_SIZE, | 1220 | max: MAX_TERMINAL_FONT_SIZE, |
| 1194 | value: settings.fontSizeTerminal, | 1221 | value: settings.fontSizeTerminal, |
| | 1222 | defaultValue: DEFAULT_UNIFIED_SETTINGS.fontSizeTerminal, |
| 1195 | onChange: (fontSizeTerminal) => updateSettings({ fontSizeTerminal }), | 1223 | onChange: (fontSizeTerminal) => updateSettings({ fontSizeTerminal }), |
| 1196 | }} | 1224 | }} |
| 1197 | preview={ | 1225 | preview={ |
| ... | @@ -1369,9 +1397,11 @@ function FontFamilySettingsRow({ | ... | @@ -1369,9 +1397,11 @@ function FontFamilySettingsRow({ |
| 1369 | title, | 1397 | title, |
| 1370 | description, | 1398 | description, |
| 1371 | defaultFamily, | 1399 | defaultFamily, |
| | 1400 | defaultValue, |
| 1372 | preview, | 1401 | preview, |
| 1373 | value, | 1402 | value, |
| 1374 | onValueChange, | 1403 | onValueChange, |
| | 1404 | onReset, |
| 1375 | requireMonospace = false, | 1405 | requireMonospace = false, |
| 1376 | size, | 1406 | size, |
| 1377 | }: { | 1407 | }: { |
| ... | @@ -1380,11 +1410,21 @@ function FontFamilySettingsRow({ | ... | @@ -1380,11 +1410,21 @@ function FontFamilySettingsRow({ |
| 1380 | description: string; | 1410 | description: string; |
| 1381 | /** What an unset preference renders as, e.g. "Menlo". */ | 1411 | /** What an unset preference renders as, e.g. "Menlo". */ |
| 1382 | defaultFamily: string; | 1412 | defaultFamily: string; |
| | 1413 | /** The persisted family value supplied by the unified settings defaults. */ |
| | 1414 | defaultValue: string; |
| 1383 | preview?: ReactNode; | 1415 | preview?: ReactNode; |
| 1384 | value: string; | 1416 | value: string; |
| 1385 | onValueChange: (value: string) => void; | 1417 | onValueChange: (value: string) => void; |
| | 1418 | onReset: () => void; |
| 1386 | requireMonospace?: boolean; | 1419 | requireMonospace?: boolean; |
| 1387 | size: { label: string; min: number; max: number; value: number; onChange: (v: number) => void }; | 1420 | size: { |
| | 1421 | label: string; |
| | 1422 | min: number; |
| | 1423 | max: number; |
| | 1424 | value: number; |
| | 1425 | defaultValue: number; |
| | 1426 | onChange: (v: number) => void; |
| | 1427 | }; |
| 1388 | }) { | 1428 | }) { |
| 1389 | const trimmed = value.trim(); | 1429 | const trimmed = value.trim(); |
| 1390 | // The fallback input edits a draft; the preference only commits once typing | 1430 | // The fallback input edits a draft; the preference only commits once typing |
| ... | @@ -1431,12 +1471,18 @@ function FontFamilySettingsRow({ | ... | @@ -1431,12 +1471,18 @@ function FontFamilySettingsRow({ |
| 1431 | // Flag an unknown name only once typing pauses, and never for an empty | 1471 | // Flag an unknown name only once typing pauses, and never for an empty |
| 1432 | // field - that is the starting state, not a rejected entry. | 1472 | // field - that is the starting state, not a rejected entry. |
| 1433 | const draftPending = draftSettled && draftTrimmed.length > 0 && draftTrimmed !== trimmed; | 1473 | const draftPending = draftSettled && draftTrimmed.length > 0 && draftTrimmed !== trimmed; |
| | 1474 | const resetToDefault = () => { |
| | 1475 | if (commitTimerRef.current !== null) { |
| | 1476 | window.clearTimeout(commitTimerRef.current); |
| | 1477 | commitTimerRef.current = null; |
| | 1478 | } |
| | 1479 | setDraft(defaultValue); |
| | 1480 | setDraftSettled(true); |
| | 1481 | onReset(); |
| | 1482 | }; |
| 1434 | const resetAction = | 1483 | const resetAction = |
| 1435 | trimmed.length > 0 ? ( | 1484 | value !== defaultValue || size.value !== size.defaultValue ? ( |
| 1436 | <SettingResetButton | 1485 | <SettingResetButton label={title.toLowerCase()} onClick={resetToDefault} /> |
| 1437 | label={`${title.toLowerCase()} family`} | | |
| 1438 | onClick={() => onValueChange("")} | | |
| 1439 | /> | | |
| 1440 | ) : null; | 1486 | ) : null; |
| 1441 | const fontEnumeration = useFontEnumeration(); | 1487 | const fontEnumeration = useFontEnumeration(); |
| 1442 | // Everyone starts on the plain input; focusing it is the user gesture that | 1488 | // Everyone starts on the plain input; focusing it is the user gesture that |