diff --git a/res/about/ios-version.gmi b/res/about/ios-version.gmi index d5861544..209268c4 100644 --- a/res/about/ios-version.gmi +++ b/res/about/ios-version.gmi @@ -11,6 +11,7 @@ * Added setting for hiding the tab bar. You can manage open tabs in the toolbar "Tabs" tab. * Added settings to choose which toolbar tabs are shown. * Modernized appearance of UI widgets and layout. +* Fixed saving history (i.e., feed entry read status) when app goes to background. * Fixed updating the page context menu so it reflects the state of the current page. * Fixed minor UI glitches.  diff --git a/src/app.c b/src/app.c index 173161de..cd54779d 100644 --- a/src/app.c +++ b/src/app.c @@ -179,6 +179,7 @@ struct Impl_App { iBool isFinishedLaunching; iTime lastDropTime; /* for detecting drops of multiple items */ uint32_t lastVisitedSaveTime; + iBool pendingVisitedSave; /* need to save visited URLs soon */ int autoReloadTimer; /* TODO: only start this when tabs are autoreloading */ iPeriodic periodic; int warmupFrames; /* forced refresh just after resuming from background; FIXME: shouldn't be needed */ @@ -1052,6 +1053,34 @@ void commitFile_App(const char *path, const char *tempPathWithNewContents) { remove(cstr_String(oldPath)); }  + void deferVisitedSave_App(void) { + iApp *d = &app_; + /* This gets called after the visited URLs have changed, but we want to avoid + writing them constantly to the file. */ + const uint32_t now = SDL_GetTicks(); + const uint32_t seconds = (now - d->lastVisitedSaveTime) / 1000; + iRoot **roots = d->window->roots; + if (seconds >= 60) { + d->lastVisitedSaveTime = now; + if (d->pendingVisitedSave) { + d->pendingVisitedSave = iFalse; + save_Visited(d->visited, dataDir_App_()); + } + } + else if (d->pendingVisitedSave) { + /* Do it later. */ + addDelay_Periodic(&d->periodic, + (60 - seconds) * 1000, roots[0]->widget, + "visited.save"); + return; + } + iForIndices(i, roots) { + if (roots[i]) { + remove_Periodic(&d->periodic, roots[i]->widget); + } + } +} + #if defined (LAGRANGE_ENABLE_IDLE_SLEEP) static uint32_t checkAsleep_App_(uint32_t interval, void *param) { iApp *d = param; @@ -1396,6 +1425,7 @@ static void init_App_(iApp *d, int argc, char **argv) { d->visited = new_Visited(); d->bookmarks = new_Bookmarks(); d->lastVisitedSaveTime = 0; + d->pendingVisitedSave = iFalse; /* Dumping requested pages. */ if (doDump) { const iGmIdentity *ident = NULL; @@ -2046,13 +2076,16 @@ void processEvents_App(enum iAppEventMode eventMode) { #endif switch (ev.type) { case SDL_QUIT: - d->isRunning = iFalse; - if (findWidget_App("prefs")) { - /* Make sure changed preferences get saved. */ - postCommand_Root(NULL, "prefs.dismiss"); - processEvents_App(postedEventsOnly_AppEventMode); + if (!isMobile_Platform()) { + d->isRunning = iFalse; + if (findWidget_App("prefs")) { + /* Make sure changed preferences get saved. */ + postCommand_Root(NULL, "prefs.dismiss"); + processEvents_App(postedEventsOnly_AppEventMode); + } + goto backToMainLoop; } - goto backToMainLoop; + break; case SDL_APP_TERMINATING: { iForEach(PtrArray, i, &d->mainWindows) { setFreezeDraw_MainWindow(*i.value, iTrue); @@ -2099,6 +2132,10 @@ void processEvents_App(enum iAppEventMode eventMode) { iForEach(PtrArray, i, &d->mainWindows) { setFreezeDraw_MainWindow(*i.value, iTrue); } + if (d->pendingVisitedSave) { + save_Visited(visited_App(), dataDir_App_()); + d->pendingVisitedSave = iFalse; + } savePrefs_App_(d); saveState_App_(d, iTrue); d->isSuspended = iTrue; @@ -4385,12 +4422,8 @@ static iBool handleNonWindowRelatedCommand_App_(iApp *d, const char *cmd) { } else if (equal_Command(cmd, "visited.changed")) { /* The visited file can grow large, so don't keep rewriting it after every navigation. */ - const uint32_t now = SDL_GetTicks(); - unsigned seconds = (now - d->lastVisitedSaveTime) / 1000; - if (seconds > 60) { - d->lastVisitedSaveTime = now; - save_Visited(d->visited, dataDir_App_()); - } + d->pendingVisitedSave = iTrue; + deferVisitedSave_App(); return iFalse; } else if (equal_Command(cmd, "idents.changed")) { diff --git a/src/app.h b/src/app.h index cc995e6f..7b92239a 100644 --- a/src/app.h +++ b/src/app.h @@ -138,6 +138,7 @@ iDocumentWidget * newTab_App (const iDocumentWidget *duplicat void trimCache_App (void); void trimMemory_App (void); void saveStateQuickly_App (void); +void deferVisitedSave_App (void); void setTextInputActive_App (iBool);  const iStringArray *recentlySubmittedInput_App (void); diff --git a/src/ui/root.c b/src/ui/root.c index 283604ed..4c00fc71 100644 --- a/src/ui/root.c +++ b/src/ui/root.c @@ -760,6 +760,10 @@ iBool handleRootCommands_Widget(iWidget *root, const char *cmd) { refresh_Widget(findWidget_App("toolbar")); return iFalse; } + else if (equal_Command(cmd, "visited.save")) { + deferVisitedSave_App(); + return iTrue; + } return iFalse; }  diff --git a/src/ui/util.c b/src/ui/util.c index 0845b5c6..0a546bcb 100644 --- a/src/ui/util.c +++ b/src/ui/util.c @@ -794,6 +794,7 @@ static iBool isCommandIgnoredByMenus_(const char *cmd) { equal_Command(cmd, "android.input.selrange") || equal_Command(cmd, "scrollbar.fade") || equal_Command(cmd, "visited.changed") || + equal_Command(cmd, "visited.save") || (deviceType_App() == desktop_AppDeviceType && equal_Command(cmd, "window.resized")) || equal_Command(cmd, "widget.overflow") || equal_Command(cmd, "metrics.changed") || @@ -2814,6 +2815,7 @@ static iBool messageHandler_(iWidget *msg, const char *cmd) { equal_Command(cmd, "menu.opened") || equal_Command(cmd, "menu.closed") || equal_Command(cmd, "input.backup") || + startsWith_CStr(cmd, "visited.") || startsWith_CStr(cmd, "cancel menu:") || startsWith_CStr(cmd, "feeds.update.") || startsWith_CStr(cmd, "window."))) { diff --git a/src/ui/window.c b/src/ui/window.c index c48a10e5..78dc1412 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -917,7 +917,6 @@ iBool isFullscreen_MainWindow(const iMainWindow *d) { }  iRoot *findRoot_Window(const iWindow *d, const iWidget *widget) { - while (widget->parent) { widget = widget->parent; }