[1mdiff --git a/src/app.c b/src/app.c[m
[1mindex 2f4b4fb8..2bad3cb6 100644[m
[1m--- a/src/app.c[m
[1m+++ b/src/app.c[m
[36m@@ -425,12 +425,22 @@[m [mstatic iBool loadState_App_(iApp *d) {[m
readf_Stream(stream_File(f)),[m
readf_Stream(stream_File(f))[m
};[m
[32m+[m[32m iIntSet *closedFolders[2] = {[m
[32m+[m[32m collectNew_IntSet(),[m
[32m+[m[32m collectNew_IntSet()[m
[32m+[m[32m };[m
[32m+[m[32m if (version >= bookmarkFolderState_FileVersion) {[m
[32m+[m[32m deserialize_IntSet(closedFolders[0], stream_File(f));[m
[32m+[m[32m deserialize_IntSet(closedFolders[1], stream_File(f));[m
[32m+[m[32m }[m
const uint8_t rootIndex = bits & 0xff;[m
const uint8_t flags = bits >> 8;[m
iRoot *root = d->window->base.roots[rootIndex];[m
if (root) {[m
iSidebarWidget *sidebar = findChild_Widget(root->widget, "sidebar");[m
iSidebarWidget *sidebar2 = findChild_Widget(root->widget, "sidebar2");[m
[32m+[m[32m setClosedFolders_SidebarWidget(sidebar, closedFolders[0]);[m
[32m+[m[32m setClosedFolders_SidebarWidget(sidebar2, closedFolders[1]);[m
postCommandf_Root(root, "sidebar.mode arg:%u", modes & 0xf);[m
postCommandf_Root(root, "sidebar2.mode arg:%u", modes >> 4);[m
if (deviceType_App() != phone_AppDeviceType) {[m
[36m@@ -513,6 +523,8 @@[m [mstatic void saveState_App_(const iApp *d) {[m
(mode_SidebarWidget(sidebar2) << 4));[m
writef_Stream(stream_File(f), width_SidebarWidget(sidebar));[m
writef_Stream(stream_File(f), width_SidebarWidget(sidebar2));[m
[32m+[m[32m serialize_IntSet(closedFolders_SidebarWidget(sidebar), stream_File(f));[m
[32m+[m[32m serialize_IntSet(closedFolders_SidebarWidget(sidebar2), stream_File(f));[m
}[m
}[m
}[m
[1mdiff --git a/src/defs.h b/src/defs.h[m
[1mindex a81d57f1..e1c0a125 100644[m
[1m--- a/src/defs.h[m
[1m+++ b/src/defs.h[m
[36m@@ -36,9 +36,10 @@[m [menum iFileVersion {[m
multipleRoots_FileVersion = 2,[m
serializedSidebarState_FileVersion = 3,[m
addedRecentUrlFlags_FileVersion = 4,[m
[32m+[m[32m bookmarkFolderState_FileVersion = 5,[m
/* meta */[m
idents_FileVersion = 1, /* version used by GmCerts/idents.lgr */[m
[31m- latest_FileVersion = 4,[m
[32m+[m[32m latest_FileVersion = 5,[m
};[m
[m
enum iImageStyle {[m
[1mdiff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c[m
[1mindex 8e38dcb8..3018f16d 100644[m
[1m--- a/src/ui/sidebarwidget.c[m
[1m+++ b/src/ui/sidebarwidget.c[m
[36m@@ -108,7 +108,7 @@[m [mstruct Impl_SidebarWidget {[m
iWidget * menu;[m
iSidebarItem * contextItem; /* list item accessed in the context menu */[m
size_t contextIndex; /* index of list item accessed in the context menu */[m
[31m- iIntSet closedFolders; /* otherwise open */[m
[32m+[m[32m iIntSet * closedFolders; /* otherwise open */[m
};[m
[m
iDefineObjectConstructionArgs(SidebarWidget, (enum iSidebarSide side), side)[m
[36m@@ -255,7 +255,7 @@[m [mstatic void updateContextMenu_SidebarWidget_(iSidebarWidget *d) {[m
[m
static iBool isBookmarkFolded_SidebarWidget_(const iSidebarWidget *d, const iBookmark *bm) {[m
while (bm->parentId) {[m
[31m- if (contains_IntSet(&d->closedFolders, bm->parentId)) {[m
[32m+[m[32m if (contains_IntSet(d->closedFolders, bm->parentId)) {[m
return iTrue;[m
}[m
bm = get_Bookmarks(bookmarks_App(), bm->parentId);[m
[36m@@ -397,7 +397,7 @@[m [mstatic void updateItems_SidebarWidget_(iSidebarWidget *d) {[m
item->id = id_Bookmark(bm);[m
item->indent = depth_Bookmark(bm);[m
if (isFolder_Bookmark(bm)) {[m
[31m- item->icon = contains_IntSet(&d->closedFolders, item->id) ? 0x27e9 : 0xfe40;[m
[32m+[m[32m item->icon = contains_IntSet(d->closedFolders, item->id) ? 0x27e9 : 0xfe40;[m
}[m
else {[m
item->icon = bm->icon;[m
[36m@@ -655,6 +655,11 @@[m [miBool setMode_SidebarWidget(iSidebarWidget *d, enum iSidebarMode mode) {[m
return iTrue;[m
}[m
[m
[32m+[m[32mvoid setClosedFolders_SidebarWidget(iSidebarWidget *d, const iIntSet *closedFolders) {[m
[32m+[m[32m delete_IntSet(d->closedFolders);[m
[32m+[m[32m d->closedFolders = copy_IntSet(closedFolders);[m
[32m+[m[32m}[m
[32m+[m
enum iSidebarMode mode_SidebarWidget(const iSidebarWidget *d) {[m
return d ? d->mode : 0;[m
}[m
[36m@@ -663,6 +668,10 @@[m [mfloat width_SidebarWidget(const iSidebarWidget *d) {[m
return d ? d->widthAsGaps : 0;[m
}[m
[m
[32m+[m[32mconst iIntSet *closedFolders_SidebarWidget(const iSidebarWidget *d) {[m
[32m+[m[32m return d->closedFolders;[m
[32m+[m[32m}[m
[32m+[m
static const char *normalModeLabels_[max_SidebarMode] = {[m
book_Icon " ${sidebar.bookmarks}",[m
star_Icon " ${sidebar.feeds}",[m
[36m@@ -736,7 +745,7 @@[m [mvoid init_SidebarWidget(iSidebarWidget *d, enum iSidebarSide side) {[m
d->resizer = NULL;[m
d->list = NULL;[m
d->actions = NULL;[m
[31m- init_IntSet(&d->closedFolders);[m
[32m+[m[32m d->closedFolders = new_IntSet();[m
/* On a phone, the right sidebar is used exclusively for Identities. */[m
const iBool isPhone = deviceType_App() == phone_AppDeviceType;[m
if (!isPhone || d->side == left_SidebarSide) {[m
[36m@@ -820,7 +829,7 @@[m [mvoid init_SidebarWidget(iSidebarWidget *d, enum iSidebarSide side) {[m
[m
void deinit_SidebarWidget(iSidebarWidget *d) {[m
deinit_String(&d->cmdPrefix);[m
[31m- deinit_IntSet(&d->closedFolders);[m
[32m+[m[32m delete_IntSet(d->closedFolders);[m
}[m
[m
iBool setButtonFont_SidebarWidget(iSidebarWidget *d, int font) {[m
[36m@@ -869,11 +878,11 @@[m [mstatic void itemClicked_SidebarWidget_(iSidebarWidget *d, iSidebarItem *item, si[m
}[m
case bookmarks_SidebarMode:[m
if (isEmpty_String(&item->url)) /* a folder */ {[m
[31m- if (contains_IntSet(&d->closedFolders, item->id)) {[m
[31m- remove_IntSet(&d->closedFolders, item->id);[m
[32m+[m[32m if (contains_IntSet(d->closedFolders, item->id)) {[m
[32m+[m[32m remove_IntSet(d->closedFolders, item->id);[m
}[m
else {[m
[31m- insert_IntSet(&d->closedFolders, item->id);[m
[32m+[m[32m insert_IntSet(d->closedFolders, item->id);[m
}[m
updateItems_SidebarWidget_(d);[m
break;[m
[36m@@ -956,8 +965,8 @@[m [mvoid setWidth_SidebarWidget(iSidebarWidget *d, float widthAsGaps) {[m
int width = widthAsGaps * gap_UI; /* in pixels */[m
if (!isFixedWidth) {[m
/* Even less space if the other sidebar is visible, too. */[m
[31m- const int otherWidth =[m
[31m- width_Widget(findWidget_App(d->side == left_SidebarSide ? "sidebar2" : "sidebar"));[m
[32m+[m[32m const iWidget *other = findWidget_App(d->side == left_SidebarSide ? "sidebar2" : "sidebar");[m
[32m+[m[32m const int otherWidth = isVisible_Widget(other) ? width_Widget(other) : 0;[m
width = iClamp(width, 30 * gap_UI, size_Root(w->root).x - 50 * gap_UI - otherWidth);[m
}[m
d->widthAsGaps = (float) width / (float) gap_UI;[m
[36m@@ -1328,6 +1337,8 @@[m [mstatic iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)[m
if (isFolder_Bookmark(bm)) {[m
const iPtrArray *list = list_Bookmarks(bookmarks_App(), NULL,[m
filterInsideFolder_Bookmark, bm);[m
[32m+[m[32m /* Folder deletion requires confirmation because folders can contain[m
[32m+[m[32m any number of bookmarks and other folders. */[m
if (argLabel_Command(cmd, "confirmed") || isEmpty_PtrArray(list)) {[m
iConstForEach(PtrArray, i, list) {[m
removeEntries_Feeds(id_Bookmark(i.ptr));[m
[1mdiff --git a/src/ui/sidebarwidget.h b/src/ui/sidebarwidget.h[m
[1mindex 2894a951..638a1f2f 100644[m
[1m--- a/src/ui/sidebarwidget.h[m
[1m+++ b/src/ui/sidebarwidget.h[m
[36m@@ -24,6 +24,8 @@[m [mSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */[m
[m
#include "widget.h"[m
[m
[32m+[m[32m#include <the_Foundation/intset.h>[m
[32m+[m
enum iSidebarMode {[m
bookmarks_SidebarMode,[m
feeds_SidebarMode,[m
[36m@@ -49,8 +51,10 @@[m [miDeclareWidgetClass(SidebarWidget)[m
iDeclareObjectConstructionArgs(SidebarWidget, enum iSidebarSide side)[m
[m
iBool setMode_SidebarWidget (iSidebarWidget *, enum iSidebarMode mode);[m
[32m+[m[32mvoid setWidth_SidebarWidget (iSidebarWidget *, float widthAsGaps);[m
iBool setButtonFont_SidebarWidget (iSidebarWidget *, int font);[m
[32m+[m[32mvoid setClosedFolders_SidebarWidget (iSidebarWidget *, const iIntSet *closedFolders);[m
[m
enum iSidebarMode mode_SidebarWidget (const iSidebarWidget *);[m
float width_SidebarWidget (const iSidebarWidget *);[m
[31m-void setWidth_SidebarWidget (iSidebarWidget *, float widthAsGaps);[m
[32m+[m[32mconst iIntSet * closedFolders_SidebarWidget (const iSidebarWidget *);[m
[1mdiff --git a/src/ui/window.c b/src/ui/window.c[m
[1mindex 5941ef5f..066ea102 100644[m
[1m--- a/src/ui/window.c[m
[1m+++ b/src/ui/window.c[m
[36m@@ -30,6 +30,7 @@[m [mSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */[m
#include "keys.h"[m
#include "labelwidget.h"[m
#include "documentwidget.h"[m
[32m+[m[32m#include "sidebarwidget.h"[m
#include "paint.h"[m
#include "root.h"[m
#include "touch.h"[m
[36m@@ -1421,6 +1422,15 @@[m [mvoid setSplitMode_MainWindow(iMainWindow *d, int splitFlags) {[m
w->keyRoot->window = w;[m
setCurrent_Root(w->roots[newRootIndex]);[m
createUserInterface_Root(w->roots[newRootIndex]);[m
[32m+[m[32m /* Bookmark folder state will match the old root's state. */ {[m
[32m+[m[32m for (int sb = 0; sb < 2; sb++) {[m
[32m+[m[32m const char *sbId = (sb == 0 ? "sidebar" : "sidebar2");[m
[32m+[m[32m setClosedFolders_SidebarWidget([m
[32m+[m[32m findChild_Widget(w->roots[newRootIndex]->widget, sbId),[m
[32m+[m[32m closedFolders_SidebarWidget([m
[32m+[m[32m findChild_Widget(w->roots[newRootIndex ^ 1]->widget, sbId)));[m
[32m+[m[32m }[m
[32m+[m[32m }[m
if (!isEmpty_String(d->pendingSplitUrl)) {[m
postCommandf_Root(w->roots[newRootIndex], "open url:%s",[m
cstr_String(d->pendingSplitUrl));[m
text/plain
This content has been proxied by September (3851b).