Skip to content

Commit 9aa2cd9

Browse files
kjkclaude
andcommitted
Style the AI chat as message boxes (fixes #6309)
The chat page was raw text: bold "You:" lines and replies with no spacing, hard to scan in a long session. Questions now sit in a tinted box on the right, replies in a bordered card on the left, tool calls as small italic lines, with proper Markdown typography for headings, lists, tables, quotes and code. A new AIChat settings section (FontName, FontSize, LineSpacing, MessagePadding, Bubbles) lets users tune it; Bubbles = false keeps the plain look. Saving settings rebuilds open chat pages, which also makes the per-backend BgColor apply without reopening the panel. prompt: implement #6309: improve ui design of ai chat sidebar Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 7c1dcef commit 9aa2cd9

12 files changed

Lines changed: 273 additions & 46 deletions

‎cmd/gen-settings.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,24 @@ const antiGravity: Field[] = [
676676
field("BgColor", Color, "#ffffff", "background color of the Antigravity chat panel"),
677677
];
678678

679+
const aiChat: Field[] = [
680+
field("FontName", Str, "", "font of the chat messages; empty uses Segoe UI"),
681+
field("FontSize", Int, 0, "font size of the chat messages in pixels; 0 means the default (13)"),
682+
field(
683+
"LineSpacing",
684+
Float,
685+
0,
686+
"line-height multiplier for chat text (e.g. 1.6); 0 means the default (1.5). values from 1 to 3 are accepted",
687+
),
688+
field("MessagePadding", Int, -1, "space inside a message box in pixels; -1 means the default (8)"),
689+
field(
690+
"Bubbles",
691+
Bool,
692+
true,
693+
"if true, your questions and the replies are shown in message boxes; if false, as plain text separated by lines",
694+
),
695+
];
696+
679697
const readingBar: Field[] = [
680698
field(
681699
"Background",
@@ -1912,6 +1930,8 @@ const globalPrefs: Field[] = [
19121930
emptyLine(),
19131931
struct("AntiGravity", antiGravity, "settings for the Antigravity chat sidebar").ver("3.7"),
19141932
emptyLine(),
1933+
struct("AIChat", aiChat, "appearance of the AI chat sidebar, shared by all backends").ver("3.7"),
1934+
emptyLine(),
19151935
field(
19161936
"AIChatSidebarDx",
19171937
Int,
@@ -2115,6 +2135,7 @@ const globalPrefsLayout = [
21152135
"GrokBuild",
21162136
"CodexBuild",
21172137
"AntiGravity",
2138+
"AIChat",
21182139
"EBookUI",
21192140
"ComicBookUI",
21202141
"FixedPageUI",

‎cmd/ng-gen-settings.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,24 @@ const antiGravity: Field[] = [
676676
field("BgColor", Color, "#ffffff", "background color of the Antigravity chat panel"),
677677
];
678678

679+
const aiChat: Field[] = [
680+
field("FontName", Str, "", "font of the chat messages; empty uses Segoe UI"),
681+
field("FontSize", Int, 0, "font size of the chat messages in pixels; 0 means the default (13)"),
682+
field(
683+
"LineSpacing",
684+
Float,
685+
0,
686+
"line-height multiplier for chat text (e.g. 1.6); 0 means the default (1.5). values from 1 to 3 are accepted",
687+
),
688+
field("MessagePadding", Int, -1, "space inside a message box in pixels; -1 means the default (8)"),
689+
field(
690+
"Bubbles",
691+
Bool,
692+
true,
693+
"if true, your questions and the replies are shown in message boxes; if false, as plain text separated by lines",
694+
),
695+
];
696+
679697
const readingBar: Field[] = [
680698
field(
681699
"Background",
@@ -1881,6 +1899,8 @@ const globalPrefs: Field[] = [
18811899
emptyLine(),
18821900
struct("AntiGravity", antiGravity, "settings for the Antigravity chat sidebar").ver("3.7"),
18831901
emptyLine(),
1902+
struct("AIChat", aiChat, "appearance of the AI chat sidebar, shared by all backends").ver("3.7"),
1903+
emptyLine(),
18841904
field(
18851905
"AIChatSidebarDx",
18861906
Int,
@@ -2076,6 +2096,7 @@ const globalPrefsLayout = [
20762096
"GrokBuild",
20772097
"CodexBuild",
20782098
"AntiGravity",
2099+
"AIChat",
20792100
"EBookUI",
20802101
"ComicBookUI",
20812102
"FixedPageUI",

‎src/Settings.cpp‎

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,24 @@ static const StructInfo gAntiGravityInfo = {
332332
"(agy cannot prompt for permissions with -p)\0background color of the Antigravity chat panel",
333333
false};
334334

335+
static const FieldInfo gAIChatFields[] = {
336+
{offsetof(AIChat, fontName), SettingType::String, (intptr_t)""},
337+
{offsetof(AIChat, fontSize), SettingType::Int, 0},
338+
{offsetof(AIChat, lineSpacing), SettingType::Float, (intptr_t)"0"},
339+
{offsetof(AIChat, messagePadding), SettingType::Int, -1},
340+
{offsetof(AIChat, bubbles), SettingType::Bool, true},
341+
};
342+
static const StructInfo gAIChatInfo = {
343+
sizeof(AIChat),
344+
5,
345+
gAIChatFields,
346+
"FontName\0FontSize\0LineSpacing\0MessagePadding\0Bubbles",
347+
"font of the chat messages; empty uses Segoe UI\0font size of the chat messages in pixels; 0 means the default "
348+
"(13)\0line-height multiplier for chat text (e.g. 1.6); 0 means the default (1.5). values from 1 to 3 are "
349+
"accepted\0space inside a message box in pixels; -1 means the default (8)\0if true, your questions and the replies "
350+
"are shown in message boxes; if false, as plain text separated by lines",
351+
false};
352+
335353
static const FieldInfo gAnnotationsFields[] = {
336354
{offsetof(Annotations, highlightColor), SettingType::Color, (intptr_t)"#ffff00"},
337355
{offsetof(Annotations, underlineColor), SettingType::Color, (intptr_t)"#8bf05d"},
@@ -997,6 +1015,8 @@ static const FieldInfo gSettingsFields[] = {
9971015
{(size_t)-1, SettingType::Comment, 0},
9981016
{offsetof(Settings, antiGravity), SettingType::Struct, (intptr_t)&gAntiGravityInfo},
9991017
{(size_t)-1, SettingType::Comment, 0},
1018+
{offsetof(Settings, aiChat), SettingType::Struct, (intptr_t)&gAIChatInfo},
1019+
{(size_t)-1, SettingType::Comment, 0},
10001020
{offsetof(Settings, aiChatSidebarDx), SettingType::Int, 0, true},
10011021
{(size_t)-1, SettingType::Comment, 0},
10021022
{offsetof(Settings, translateToLang), SettingType::String, (intptr_t)"", true},
@@ -1046,7 +1066,7 @@ static const FieldInfo gSettingsFields[] = {
10461066
};
10471067
const StructInfo gSettingsInfo = {
10481068
sizeof(Settings),
1049-
165,
1069+
167,
10501070
gSettingsFields,
10511071
"\0\0DefaultDisplayMode\0DefaultZoom\0DisableJavaScript\0AllowExternalImages\0EnableTeXEnhancements\0EscToExit\0Ful"
10521072
"lPathInTitle\0InverseSearchCmdLine\0LazyLoading\0MainWindowBackground\0NoHomeTab\0HomePageSortByFrequentlyRead\0Ho"
@@ -1064,11 +1084,11 @@ const StructInfo gSettingsInfo = {
10641084
"ntSize\0UIFontSize\0DisableAntiAlias\0EngineeringDrawingEnhance\0DisableAutoLinks\0UseSysColors\0UseTabs\0Selectio"
10651085
"nToolbar\0SelectionToolbarLayout\0TabsMru\0CtrlTabSimple\0ZoomLevels\0ZoomIncrement\0\0FixedPageUI\0\0EBookUI\0\0C"
10661086
"omicBookUI\0\0ImageUI\0\0ChmUI\0\0MarkdownUI\0\0HtmlUI\0\0ClaudeCode\0\0GrokBuild\0\0CodexBuild\0\0AntiGravity\0\0"
1067-
"AIChatSidebarDx\0\0TranslateToLang\0TranslateFromLang\0TranslateEngine\0\0Annotations\0\0ExternalViewers\0\0Forwar"
1068-
"dSearch\0\0PrinterDefaults\0\0Fullscreen\0\0SelectionHandlers\0\0TextSnippets\0\0Shortcuts\0\0Themes\0\0TabGroups"
1069-
"\0\0CustomScreenDPI\0\0\0DefaultPasswords\0UiLanguage\0VersionToSkip\0WindowState\0WindowPos\0SearchUIWindowPos\0A"
1070-
"nnotationsWindowShowNote\0HelpWindowPos\0FileStates\0SessionData\0ReopenOnce\0TimeOfLastUpdateCheck\0OpenCountWeek"
1071-
"\0PropWinPos\0CheckForUpdates\0\0",
1087+
"AIChat\0\0AIChatSidebarDx\0\0TranslateToLang\0TranslateFromLang\0TranslateEngine\0\0Annotations\0\0ExternalViewers"
1088+
"\0\0ForwardSearch\0\0PrinterDefaults\0\0Fullscreen\0\0SelectionHandlers\0\0TextSnippets\0\0Shortcuts\0\0Themes\0\0"
1089+
"TabGroups\0\0CustomScreenDPI\0\0\0DefaultPasswords\0UiLanguage\0VersionToSkip\0WindowState\0WindowPos\0SearchUIWin"
1090+
"dowPos\0AnnotationsWindowShowNote\0HelpWindowPos\0FileStates\0SessionData\0ReopenOnce\0TimeOfLastUpdateCheck\0Open"
1091+
"CountWeek\0PropWinPos\0CheckForUpdates\0\0",
10721092
"\0\0default layout of pages. valid values: automatic, single page, facing, book view, continuous, continuous "
10731093
"facing, continuous book view, page aspect. page aspect (3.7+): first open of a PDF, XPS, DjVu or PostScript file "
10741094
"uses page 1 — taller than wide is continuous + fit width, wider than tall is single page + fit page; a remembered "
@@ -1193,11 +1213,12 @@ const StructInfo gSettingsInfo = {
11931213
"otherwise WebView2 browser view is used when available\0\0customization options for HTML UI. If UseFixedPageUI is "
11941214
"true, MuPDF is used; otherwise WebView2 browser view is used when available\0\0settings for the Claude Code chat "
11951215
"sidebar\0\0settings for the Grok Build chat sidebar\0\0settings for the OpenAI Codex chat sidebar\0\0settings for "
1196-
"the Antigravity chat sidebar\0\0width of the AI chat sidebar (0 = use default); shared by Claude Code, Grok "
1197-
"Build, and OpenAI Codex (internal)\0\0remembered destination language for selection translation; empty uses OS UI "
1198-
"language\0remembered source language for selection translation; empty means Auto\0remembered engine for Translate "
1199-
"Selection: Google, DeepL, Grok Build, Claude Code, OpenAI Codex or Antigravity\0\0default values for annotations "
1200-
"in PDF documents\0\0list of additional external viewers for various file types. See [docs for more "
1216+
"the Antigravity chat sidebar\0\0appearance of the AI chat sidebar, shared by all backends\0\0width of the AI chat "
1217+
"sidebar (0 = use default); shared by Claude Code, Grok Build, and OpenAI Codex (internal)\0\0remembered "
1218+
"destination language for selection translation; empty uses OS UI language\0remembered source language for "
1219+
"selection translation; empty means Auto\0remembered engine for Translate Selection: Google, DeepL, Grok Build, "
1220+
"Claude Code, OpenAI Codex or Antigravity\0\0default values for annotations in PDF documents\0\0list of additional "
1221+
"external viewers for various file types. See [docs for more "
12011222
"information](https://www.sumatrapdfreader.org/docs/Customize-external-viewers)\0\0customization options for how "
12021223
"forward search results are shown (used from LaTeX editors)\0\0these override the default settings in the Print "
12031224
"dialog\0\0options for fullscreen mode\0\0list of handlers for selected text, shown in context menu when text "

‎src/Settings.h‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,22 @@ struct AntiGravity {
544544
ParsedColor bgColor;
545545
};
546546

547+
// appearance of the AI chat sidebar, shared by all backends
548+
struct AIChat {
549+
// font of the chat messages; empty uses Segoe UI
550+
Str fontName;
551+
// font size of the chat messages in pixels; 0 means the default (13)
552+
int fontSize;
553+
// line-height multiplier for chat text (e.g. 1.6); 0 means the default
554+
// (1.5). values from 1 to 3 are accepted
555+
float lineSpacing;
556+
// space inside a message box in pixels; -1 means the default (8)
557+
int messagePadding;
558+
// if true, your questions and the replies are shown in message boxes;
559+
// if false, as plain text separated by lines
560+
bool bubbles;
561+
};
562+
547563
// customization options for the ebook UI (EPUB, MOBI, FB2, PDB and
548564
// plain text)
549565
struct EBookUI {
@@ -1000,6 +1016,8 @@ struct Settings {
10001016
CodexBuild codexBuild;
10011017
// settings for the Antigravity chat sidebar
10021018
AntiGravity antiGravity;
1019+
// appearance of the AI chat sidebar, shared by all backends
1020+
AIChat aiChat;
10031021
// customization options for the ebook UI (EPUB, MOBI, FB2, PDB and
10041022
// plain text)
10051023
EBookUI eBookUI;

‎src/SumatraPDF.cpp‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9108,6 +9108,18 @@ void ApplyChangedSettingsAndRelayout(const SettingsApplyState& before) {
91089108
ReloadEbookLayoutDocs();
91099109
}
91109110

9111+
// the chat colors, font and layout are baked into the chat page: rebuild it
9112+
Str prevStyle = before.aiChatStyle;
9113+
Str nowStyle = AIChatStyleSnapshot();
9114+
bool aiChatStyleChanged = !str::Eq(prevStyle, nowStyle);
9115+
str::Free(prevStyle);
9116+
str::Free(nowStyle);
9117+
if (aiChatStyleChanged) {
9118+
for (MainWindow* w : gWindows) {
9119+
UpdateAIChatTheme(w);
9120+
}
9121+
}
9122+
91119123
// UseTabs converts existing windows <-> tabs (closes and reopens windows);
91129124
// post it so it runs after the settings dialog has been torn down
91139125
if (before.useTabs != p->useTabs) {

‎src/SumatraPDF.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ struct SettingsApplyState {
306306
bool explorerQuickLook = false;
307307
// owned copy of the ebook layout inputs; ApplyChangedSettingsAndRelayout frees it
308308
Str ebookLayout;
309+
// owned copy of the AI chat look (AIChat section, BgColor); freed the same way
310+
Str aiChatStyle;
309311
};
310312
SettingsApplyState GetSettingsApplyState();
311313
void ApplyChangedSettingsAndRelayout(const SettingsApplyState& before);

‎src/ng/Settings.h‎

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,22 @@ struct AntiGravity {
541541
ParsedColor bgColor;
542542
};
543543

544+
// appearance of the AI chat sidebar, shared by all backends
545+
struct AIChat {
546+
// font of the chat messages; empty uses Segoe UI
547+
Str fontName;
548+
// font size of the chat messages in pixels; 0 means the default (13)
549+
int fontSize;
550+
// line-height multiplier for chat text (e.g. 1.6); 0 means the default
551+
// (1.5). values from 1 to 3 are accepted
552+
float lineSpacing;
553+
// space inside a message box in pixels; -1 means the default (8)
554+
int messagePadding;
555+
// if true, your questions and the replies are shown in message boxes;
556+
// if false, as plain text separated by lines
557+
bool bubbles;
558+
};
559+
544560
// customization options for the ebook UI (EPUB, MOBI, FB2, PDB and
545561
// plain text)
546562
struct EBookUI {
@@ -1000,6 +1016,8 @@ struct Settings {
10001016
CodexBuild codexBuild;
10011017
// settings for the Antigravity chat sidebar
10021018
AntiGravity antiGravity;
1019+
// appearance of the AI chat sidebar, shared by all backends
1020+
AIChat aiChat;
10031021
// customization options for the ebook UI (EPUB, MOBI, FB2, PDB and
10041022
// plain text)
10051023
EBookUI eBookUI;
@@ -1610,6 +1628,24 @@ static const StructInfo gAntiGravityInfo = {
16101628
"(agy cannot prompt for permissions with -p)\0background color of the Antigravity chat panel",
16111629
false};
16121630

1631+
static const FieldInfo gAIChatFields[] = {
1632+
{offsetof(AIChat, fontName), SettingType::String, (intptr_t)""},
1633+
{offsetof(AIChat, fontSize), SettingType::Int, 0},
1634+
{offsetof(AIChat, lineSpacing), SettingType::Float, (intptr_t)"0"},
1635+
{offsetof(AIChat, messagePadding), SettingType::Int, -1},
1636+
{offsetof(AIChat, bubbles), SettingType::Bool, true},
1637+
};
1638+
static const StructInfo gAIChatInfo = {
1639+
sizeof(AIChat),
1640+
5,
1641+
gAIChatFields,
1642+
"FontName\0FontSize\0LineSpacing\0MessagePadding\0Bubbles",
1643+
"font of the chat messages; empty uses Segoe UI\0font size of the chat messages in pixels; 0 means the default "
1644+
"(13)\0line-height multiplier for chat text (e.g. 1.6); 0 means the default (1.5). values from 1 to 3 are "
1645+
"accepted\0space inside a message box in pixels; -1 means the default (8)\0if true, your questions and the replies "
1646+
"are shown in message boxes; if false, as plain text separated by lines",
1647+
false};
1648+
16131649
static const FieldInfo gAnnotationsFields[] = {
16141650
{offsetof(Annotations, highlightColor), SettingType::Color, (intptr_t)"#ffff00"},
16151651
{offsetof(Annotations, underlineColor), SettingType::Color, (intptr_t)"#8bf05d"},
@@ -2275,6 +2311,8 @@ static const FieldInfo gSettingsFields[] = {
22752311
{(size_t)-1, SettingType::Comment, 0},
22762312
{offsetof(Settings, antiGravity), SettingType::Struct, (intptr_t)&gAntiGravityInfo},
22772313
{(size_t)-1, SettingType::Comment, 0},
2314+
{offsetof(Settings, aiChat), SettingType::Struct, (intptr_t)&gAIChatInfo},
2315+
{(size_t)-1, SettingType::Comment, 0},
22782316
{offsetof(Settings, aiChatSidebarDx), SettingType::Int, 0, true},
22792317
{(size_t)-1, SettingType::Comment, 0},
22802318
{offsetof(Settings, translateToLang), SettingType::String, (intptr_t)"", true},
@@ -2324,7 +2362,7 @@ static const FieldInfo gSettingsFields[] = {
23242362
};
23252363
static const StructInfo gSettingsInfo = {
23262364
sizeof(Settings),
2327-
165,
2365+
167,
23282366
gSettingsFields,
23292367
"\0\0DefaultDisplayMode\0DefaultZoom\0DisableJavaScript\0AllowExternalImages\0EnableTeXEnhancements\0EscToExit\0Ful"
23302368
"lPathInTitle\0InverseSearchCmdLine\0LazyLoading\0MainWindowBackground\0NoHomeTab\0HomePageSortByFrequentlyRead\0Ho"
@@ -2342,11 +2380,11 @@ static const StructInfo gSettingsInfo = {
23422380
"ntSize\0UIFontSize\0DisableAntiAlias\0EngineeringDrawingEnhance\0DisableAutoLinks\0UseSysColors\0UseTabs\0Selectio"
23432381
"nToolbar\0SelectionToolbarLayout\0TabsMru\0CtrlTabSimple\0ZoomLevels\0ZoomIncrement\0\0FixedPageUI\0\0EBookUI\0\0C"
23442382
"omicBookUI\0\0ImageUI\0\0ChmUI\0\0MarkdownUI\0\0HtmlUI\0\0ClaudeCode\0\0GrokBuild\0\0CodexBuild\0\0AntiGravity\0\0"
2345-
"AIChatSidebarDx\0\0TranslateToLang\0TranslateFromLang\0TranslateEngine\0\0Annotations\0\0ExternalViewers\0\0Forwar"
2346-
"dSearch\0\0PrinterDefaults\0\0Fullscreen\0\0SelectionHandlers\0\0TextSnippets\0\0Shortcuts\0\0Themes\0\0TabGroups"
2347-
"\0\0CustomScreenDPI\0\0\0DefaultPasswords\0UiLanguage\0VersionToSkip\0WindowState\0WindowPos\0SearchUIWindowPos\0A"
2348-
"nnotationsWindowShowNote\0HelpWindowPos\0FileStates\0SessionData\0ReopenOnce\0TimeOfLastUpdateCheck\0OpenCountWeek"
2349-
"\0PropWinPos\0CheckForUpdates\0\0",
2383+
"AIChat\0\0AIChatSidebarDx\0\0TranslateToLang\0TranslateFromLang\0TranslateEngine\0\0Annotations\0\0ExternalViewers"
2384+
"\0\0ForwardSearch\0\0PrinterDefaults\0\0Fullscreen\0\0SelectionHandlers\0\0TextSnippets\0\0Shortcuts\0\0Themes\0\0"
2385+
"TabGroups\0\0CustomScreenDPI\0\0\0DefaultPasswords\0UiLanguage\0VersionToSkip\0WindowState\0WindowPos\0SearchUIWin"
2386+
"dowPos\0AnnotationsWindowShowNote\0HelpWindowPos\0FileStates\0SessionData\0ReopenOnce\0TimeOfLastUpdateCheck\0Open"
2387+
"CountWeek\0PropWinPos\0CheckForUpdates\0\0",
23502388
"\0\0default layout of pages. valid values: automatic, single page, facing, book view, continuous, continuous "
23512389
"facing, continuous book view, page aspect. page aspect (3.7+): first open of a PDF, XPS, DjVu, PostScript or DVI "
23522390
"file uses page 1 — taller than wide is continuous + fit width, wider than tall is single page + fit page; a "
@@ -2469,11 +2507,12 @@ static const StructInfo gSettingsInfo = {
24692507
"otherwise WebView2 browser view is used when available\0\0customization options for HTML UI. If UseFixedPageUI is "
24702508
"true, MuPDF is used; otherwise WebView2 browser view is used when available\0\0settings for the Claude Code chat "
24712509
"sidebar\0\0settings for the Grok Build chat sidebar\0\0settings for the OpenAI Codex chat sidebar\0\0settings for "
2472-
"the Antigravity chat sidebar\0\0width of the AI chat sidebar (0 = use default); shared by Claude Code, Grok "
2473-
"Build, and OpenAI Codex (internal)\0\0remembered destination language for selection translation; empty uses OS UI "
2474-
"language\0remembered source language for selection translation; empty means Auto\0remembered engine for Translate "
2475-
"Selection: Google, DeepL, Grok Build, Claude Code, OpenAI Codex or Antigravity\0\0default values for annotations "
2476-
"in PDF documents\0\0list of additional external viewers for various file types. See [docs for more "
2510+
"the Antigravity chat sidebar\0\0appearance of the AI chat sidebar, shared by all backends\0\0width of the AI chat "
2511+
"sidebar (0 = use default); shared by Claude Code, Grok Build, and OpenAI Codex (internal)\0\0remembered "
2512+
"destination language for selection translation; empty uses OS UI language\0remembered source language for "
2513+
"selection translation; empty means Auto\0remembered engine for Translate Selection: Google, DeepL, Grok Build, "
2514+
"Claude Code, OpenAI Codex or Antigravity\0\0default values for annotations in PDF documents\0\0list of additional "
2515+
"external viewers for various file types. See [docs for more "
24772516
"information](https://www.sumatrapdfreader.org/docs/Customize-external-viewers)\0\0customization options for how "
24782517
"forward search results are shown (used from LaTeX editors)\0\0these override the default settings in the Print "
24792518
"dialog\0\0options for fullscreen mode\0\0list of handlers for selected text, shown in context menu when text "

‎src/ng/SumatraPDF.cpp‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,18 @@ void ApplyChangedSettingsAndRelayout(const SettingsApplyState& before) {
389389
ReloadEbookLayoutDocs();
390390
}
391391

392+
// the chat colors, font and layout are baked into the chat page: rebuild it
393+
Str prevStyle = before.aiChatStyle;
394+
Str nowStyle = AIChatStyleSnapshot();
395+
bool aiChatStyleChanged = !str::Eq(prevStyle, nowStyle);
396+
str::Free(prevStyle);
397+
str::Free(nowStyle);
398+
if (aiChatStyleChanged) {
399+
for (MainWindow* w : gWindows) {
400+
UpdateAIChatTheme(w);
401+
}
402+
}
403+
392404
for (MainWindow* w : gWindows) {
393405
RebuildMenuBar(w);
394406
w->lastViewPortSize = Size{};

‎src/ng/SumatraPDF.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ struct SettingsApplyState {
198198
bool explorerQuickLook = false;
199199
// owned copy of the ebook layout inputs; ApplyChangedSettingsAndRelayout frees it
200200
Str ebookLayout;
201+
// owned copy of the AI chat look (AIChat section, BgColor); freed the same way
202+
Str aiChatStyle;
201203
};
202204
SettingsApplyState GetSettingsApplyState();
203205
void ApplyChangedSettingsAndRelayout(const SettingsApplyState& before);

0 commit comments

Comments
 (0)