Skip to content

Commit 2fadfbb

Browse files
committed
fix sometimes losing tab state (fixes #5236)
1 parent 5a178c1 commit 2fadfbb

File tree

6 files changed

+64
-30
lines changed

6 files changed

+64
-30
lines changed

src/AppSettings.cpp

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -296,48 +296,80 @@ bool LoadSettings() {
296296
return true;
297297
}
298298

299+
static TabState* CloneTabState(const TabState* src) {
300+
TabState* dst = (TabState*)AllocStruct<TabState>();
301+
dst->filePath = str::Dup(src->filePath);
302+
dst->displayMode = str::Dup(src->displayMode);
303+
dst->pageNo = src->pageNo;
304+
dst->zoom = str::Dup(src->zoom);
305+
dst->rotation = src->rotation;
306+
dst->scrollPos = src->scrollPos;
307+
dst->showToc = src->showToc;
308+
dst->tocState = new Vec<int>(*src->tocState);
309+
return dst;
310+
}
311+
312+
Vec<SessionData*>* gInitialSessionData = nullptr;
313+
299314
static void RememberSessionState() {
300-
Vec<SessionData*>* sessionData = gGlobalPrefs->sessionData;
301-
ResetSessionState(sessionData);
315+
Vec<SessionData*>* sessionState = gGlobalPrefs->sessionData;
316+
FreeSessionState(sessionState);
302317

303318
if (!gGlobalPrefs->rememberOpenedFiles) {
304319
return;
305320
}
306321

307-
if (gWindows.size() == 0) {
308-
return;
309-
}
310-
311322
for (auto* win : gWindows) {
312-
SessionData* data = NewSessionData();
323+
SessionData* windowState = NewSessionData();
313324
for (WindowTab* tab : win->Tabs()) {
314-
if (tab->IsAboutTab()) {
325+
if (!tab->filePath) {
326+
// home page tab
315327
continue;
316328
}
317329
const char* fp = tab->filePath;
318-
FileState* fs = NewDisplayState(fp);
319-
if (tab->ctrl) {
320-
tab->ctrl->GetDisplayState(fs);
330+
if (!tab->ctrl) {
331+
// lazy loading, file not loaded into a tab
332+
// use the saved state from previous session
333+
// note: might stil have issues if multiple tabs with same file
334+
bool didFind = false;
335+
int nWindows = gInitialSessionData->Size();
336+
for (int i = 0; i < nWindows; i++) {
337+
SessionData* psd = gInitialSessionData->At(i);
338+
int nTabs = psd->tabStates->Size();
339+
for (int j = 0; j < nTabs; j++) {
340+
TabState* pts = psd->tabStates->At(j);
341+
if (str::Eq(pts->filePath, fp)) {
342+
TabState* ts = CloneTabState(pts);
343+
windowState->tabStates->Append(ts);
344+
didFind = true;
345+
break;
346+
}
347+
}
348+
}
349+
ReportIf(!didFind);
350+
continue;
321351
}
352+
FileState* fs = NewDisplayState(fp);
353+
tab->ctrl->GetDisplayState(fs);
322354
fs->showToc = tab->showToc;
323355
*fs->tocState = tab->tocState;
324356
TabState* ts = NewTabState(fs);
325-
data->tabStates->Append(ts);
357+
windowState->tabStates->Append(ts);
326358
DeleteDisplayState(fs);
327359
}
328-
if (data->tabStates->Size() == 0) {
360+
if (windowState->tabStates->Size() == 0) {
329361
continue;
330362
}
331-
data->tabIndex = win->GetTabIdx(win->CurrentTab()) + 1;
332-
if (data->tabIndex < 0) {
333-
data->tabIndex = 0;
363+
windowState->tabIndex = win->GetTabIdx(win->CurrentTab()) + 1;
364+
if (windowState->tabIndex < 0) {
365+
windowState->tabIndex = 0;
334366
}
335367
// TODO: allow recording this state without changing gGlobalPrefs
336368
RememberDefaultWindowPosition(win);
337-
data->windowState = gGlobalPrefs->windowState;
338-
data->windowPos = gGlobalPrefs->windowPos;
339-
data->sidebarDx = gGlobalPrefs->sidebarDx;
340-
sessionData->Append(data);
369+
windowState->windowState = gGlobalPrefs->windowState;
370+
windowState->windowPos = gGlobalPrefs->windowPos;
371+
windowState->sidebarDx = gGlobalPrefs->sidebarDx;
372+
sessionState->Append(windowState);
341373
}
342374
}
343375

src/AppSettings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ enum {
1111

1212
extern bool gDontSaveSettings;
1313

14+
extern Vec<SessionData*>* gInitialSessionData;
15+
1416
TempStr GetSettingsPathTemp();
1517
TempStr GetSettingsFileNameTemp();
1618

src/GlobalPrefs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ TabState* NewTabState(FileState* fs) {
9999
return state;
100100
}
101101

102-
void ResetSessionState(Vec<SessionData*>* sessionData) {
102+
void FreeSessionState(Vec<SessionData*>* sessionData) {
103103
ReportIf(!sessionData);
104104
if (!sessionData) {
105105
return;

src/GlobalPrefs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void DeleteGlobalPrefs(GlobalPrefs* gp);
1515

1616
SessionData* NewSessionData();
1717
TabState* NewTabState(FileState* fs);
18-
void ResetSessionState(Vec<SessionData*>* sessionData);
18+
void FreeSessionState(Vec<SessionData*>* sessionData);
1919
ParsedColor* GetParsedColor(const char* s, ParsedColor& parsed);
2020
COLORREF GetParsedCOLORREF(const char* s, ParsedColor& parsed, COLORREF def);
2121

src/Installer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
#include "wingui/WinGui.h"
2121

2222
#include "resource.h"
23-
#include "AppSettings.h"
2423
#include "Settings.h"
24+
#include "AppSettings.h"
2525
#include "Flags.h"
2626
#include "Version.h"
2727
#include "Annotation.h"

src/SumatraStartup.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,6 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) {
937937
HWND existingHwnd = nullptr;
938938
WindowTab* tabToSelect = nullptr;
939939
const char* logFilePath = nullptr;
940-
Vec<SessionData*>* sessionData = nullptr;
941940

942941
supressThrowFromNew();
943942

@@ -1260,10 +1259,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) {
12601259
// keep this data alive until the end of program and ensure it's not
12611260
// over-written by re-loading settings file while we're using it
12621261
// and also to keep TabState forever for lazy loading of tabs
1263-
sessionData = gGlobalPrefs->sessionData;
1262+
gInitialSessionData = gGlobalPrefs->sessionData;
12641263
gGlobalPrefs->sessionData = new Vec<SessionData*>();
12651264

1266-
restoreSession = gGlobalPrefs->restoreSession && (sessionData->size() > 0) && !gPluginMode;
1265+
restoreSession = gGlobalPrefs->restoreSession && (gInitialSessionData->Size() > 0) && !gPluginMode;
12671266
if (!gGlobalPrefs->useTabs && (existingInstanceHwnd != nullptr)) {
12681267
// do not restore a session if tabs are disabled and SumatraPDF is already running
12691268
// TODO: maybe disable restoring if tabs are disabled?
@@ -1283,7 +1282,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) {
12831282
}
12841283

12851284
if (restoreSession) {
1286-
for (SessionData* data : *sessionData) {
1285+
for (SessionData* data : *gInitialSessionData) {
12871286
win = CreateAndShowMainWindow(data);
12881287
for (TabState* state : *data->tabStates) {
12891288
if (str::IsEmpty(state->filePath)) {
@@ -1421,9 +1420,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) {
14211420
}
14221421
str::Free(logFilePath);
14231422

1424-
if (sessionData) {
1425-
DeleteVecMembers(*sessionData);
1426-
delete sessionData;
1423+
if (gInitialSessionData) {
1424+
FreeSessionState(gInitialSessionData);
1425+
delete gInitialSessionData;
1426+
gInitialSessionData = nullptr;
14271427
}
14281428
FreeExternalViewers();
14291429
while (gWindows.size() > 0) {

0 commit comments

Comments
 (0)