Lagrange [work/v1.17]

Improved context menus: use submenus and dynamic updates

=> 26330fd2ea529ce1e1a5774149870f97226faee7

diff --git a/src/app.c b/src/app.c
index cedbdbd0..29faa161 100644
--- a/src/app.c
+++ b/src/app.c
@@ -4989,6 +4989,14 @@ iBool handleCommand_App(const char *cmd) {
         }
         return iTrue;
     }
+    else if (equal_Command(cmd, "snippet.add")) {
+        iWidget *dlg = makeSnippetCreation_Widget();
+        if (hasLabel_Command(cmd, "content")) {
+            setTextCStr_InputWidget(findChild_Widget(dlg, "snip.content"),
+                                    suffixPtr_Command(cmd, "content"));
+        }
+        return iTrue;
+    }
     else {
         return iFalse;
     }
diff --git a/src/defs.h b/src/defs.h
index fd916845..20898327 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -270,6 +270,7 @@ iLocalDef int acceptKeyMod_ReturnKeyBehavior(int behavior) {
 #define unhappy_Icon        "\U0001f641"
 #define globe_Icon          "\U0001f310"
 #define envelope_Icon       "\U0001f4e7"
+#define hammer_Icon         "\U0001f528"
 #define magnifyingGlass_Icon "\U0001f50d"
 #define midEllipsis_Icon    "\u2022\u2022\u2022"
 #define return_Icon         "\u23ce"
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index c15164a9..4229989d 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -2026,12 +2026,56 @@ static iBool setUrl_DocumentWidget_(iDocumentWidget *d, const iString *url) {
     return iFalse;
 }
 
-static void updateInputPromptMenuItems_(iWidget *menu) {
-    setMenuItemLabelByIndex_Widget(menu,
-                                   2,
-                                   !isPromptUrl_SiteSpec(&menu->data)
-                                       ? "${menu.input.setprompt}"
-                                       : "${menu.input.unsetprompt}");
+static const iArray *updateInputPromptMenuItems_(iWidget *menu) {
+    const char     *context       = cstr_String(&menu->data);
+    const iWidget  *buttons       = pointerLabel_Command(context, "buttons");
+    const iString  *url           = string_Command(context, "url");
+    const char     *precedingLine = suffixPtr_Command(context, "preceding");
+    const iBinding *bind          = findCommand_Keys("input.precedingline");
+    /* Compose new menu items. */
+    iArray *items = collectNew_Array(sizeof(iMenuItem));
+    pushBackN_Array(
+        items,
+        (iMenuItem[]){
+            { "${menu.input.precedingline}",
+              bind->key,
+              bind->mods,
+              format_CStr("!valueinput.set ptr:%p text:%s", buttons, precedingLine) },
+            { "---" },
+            { !isPromptUrl_SiteSpec(url) ? "${menu.input.setprompt}" : "${menu.input.unsetprompt}",
+              0,
+              0,
+              format_CStr("!prompturl.toggle url:%s", cstr_String(url)) } },
+        3);
+    /* Recently submitted input texts can be restored. */ {
+        const iStringArray *recentInput = recentlySubmittedInput_App();
+        if (!isEmpty_StringArray(recentInput)) {
+            pushBack_Array(items, &(iMenuItem){ "---" });
+            pushBack_Array(items,
+                           &(iMenuItem){ "${menu.input.clear}", 0, 0, "!recentinput.clear" });
+            pushBack_Array(items, &(iMenuItem){ "```${menu.input.restore}" });
+            iReverseConstForEach(StringArray, i, recentInput) {
+                iString *label = collect_String(copy_String(i.value));
+                replace_String(label, "\n\n", " ");
+                replace_String(label, "\n", " ");
+                trim_String(label);
+                const size_t maxLen = 45;
+                if (length_String(label) > maxLen) {
+                    truncate_String(label, maxLen);
+                    trim_String(label);
+                    appendCStr_String(label, "...");
+                }
+                pushBack_Array(items,
+                               &(iMenuItem){ cstr_String(label),
+                                             0,
+                                             0,
+                                             format_CStr("!valueinput.set ptr:%p text:%s",
+                                                         buttons,
+                                                         cstr_String(i.value)) });
+            }
+        }
+    }
+    return items;
 }
 
 iWidget *makeInputPrompt_DocumentWidget(iDocumentWidget *d, const iString *url, iBool isSensitive,
@@ -2080,55 +2124,21 @@ iWidget *makeInputPrompt_DocumentWidget(iDocumentWidget *d, const iString *url,
         addChildPos_Widget(buttons, iClob(lineBreak), front_WidgetAddPos);
     }
     /* Menu for additional actions, past entries. */ {
-        const iBinding *bind = findCommand_Keys("input.precedingline");
-        iArray *items = collectNew_Array(sizeof(iMenuItem));
-        pushBackN_Array(
-            items,
-            (iMenuItem[]){
-                { "${menu.input.precedingline}",
-                  bind->key,
-                  bind->mods,
-                  format_CStr("!valueinput.set ptr:%p text:%s",
-                              buttons,
-                              cstr_String(&d->linePrecedingLink)) },
-                { "---" },
-                { "", 0, 0, format_CStr("!prompturl.toggle url:%s", cstr_String(url)) } },
-            3);
-        /* Recently submitted input texts can be restored. */ {
-            const iStringArray *recentInput = recentlySubmittedInput_App();
-            if (!isEmpty_StringArray(recentInput)) {
-                pushBack_Array(items, &(iMenuItem){ "---" });
-                pushBack_Array(items,
-                               &(iMenuItem){ "${menu.input.clear}", 0, 0, "!recentinput.clear" });
-                pushBack_Array(items, &(iMenuItem){ "```${menu.input.restore}" });
-                iReverseConstForEach(StringArray, i, recentInput) {
-                    iString *label = collect_String(copy_String(i.value));
-                    replace_String(label, "\n\n", " ");
-                    replace_String(label, "\n", " ");
-                    trim_String(label);
-                    const size_t maxLen = 45;
-                    if (length_String(label) > maxLen) {
-                        truncate_String(label, maxLen);
-                        trim_String(label);
-                        appendCStr_String(label, "...");
-                    }
-                    pushBack_Array(items,
-                                   &(iMenuItem){ cstr_String(label),
-                                                 0,
-                                                 0,
-                                                 format_CStr("!valueinput.set ptr:%p text:%s",
-                                                             buttons,
-                                                             cstr_String(i.value)) });
-                }
-            }
-        }
+
         iLabelWidget *ellipsisButton =
-            makeMenuButton_LabelWidget(midEllipsis_Icon, data_Array(items), size_Array(items));
-        /* When opening, update the items to reflect the site-specific settings. */ {
-            iWidget *menu = findChild_Widget(as_Widget(ellipsisButton), "menu");
-            menu->updateMenuItems = updateInputPromptMenuItems_;
-            set_String(&menu->data, url); /* needed when updating items */
-        }
+            makeMenuButton_LabelWidget(midEllipsis_Icon, NULL, 0);
+        iWidget *menu = findChild_Widget(as_Widget(ellipsisButton), "menu");
+        /* When opening, update the items to reflect the site-specific settings. */
+        menu->updateMenuItems = updateInputPromptMenuItems_;
+        set_String(&menu->data,
+                   collectNewFormat_String("context buttons:%p url:%s preceding:%s",
+                                           buttons,
+                                           cstr_String(canonicalUrl_String(url)),
+                                           cstr_String(&d->linePrecedingLink)));
+        // iWidget *menu = findChild_Widget(as_Widget(ellipsisButton), "menu");
+        // menu->updateMenuItems = updateInputPromptMenuItems_;
+        // set_String(&menu->data, url); /* needed when updating items */
+        //}
         if (deviceType_App() == desktop_AppDeviceType) {
             addChildPos_Widget(buttons, iClob(ellipsisButton), front_WidgetAddPos);
         }
@@ -4162,17 +4172,15 @@ static iWidget *makeLinkContextMenu_DocumentWidget_(iDocumentWidget *d, const iG
         (iMenuItem[]){
             { "---" },
             { "${link.copy}", 0, 0, "document.copylink" },
-            { bookmark_Icon " ${link.bookmark}",
-              0,
-              0,
-              format_CStr(
-                  "!bookmark.add title:%s url:%s", cstr_String(linkLabel), cstr_String(linkUrl)) },
+            { bookmark_Icon " ${link.bookmark}", 0, 0,
+              format_CStr("!bookmark.add title:%s url:%s", cstr_String(linkLabel), cstr_String(linkUrl)) },
+            { clipboard_Icon " ${link.snippet}", 0, 0,
+              format_CStr("!snippet.add content:%s", cstr_String(linkUrl)) },
             { "---" },
-            { magnifyingGlass_Icon " ${link.searchurl}",
-              0, 0,
+            { magnifyingGlass_Icon " ${link.searchurl}", 0, 0,
               format_CStr("!searchurl address:%s", cstr_String(linkUrl)) },
         },
-        5);
+        6);
     if (isNative && link->mediaType != download_MediaType && !equalCase_Rangecc(scheme, "file")) {
         pushBackN_Array(items,
                         (iMenuItem[]){
@@ -4411,13 +4419,14 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
                                 &items,
                                 (iMenuItem[]){
                                     { "${menu.copy}", 0, 0, "copy" },
-                                    { "${menu.search}",
-                                      0,
-                                      0,
+                                    { "${menu.search}", 0, 0,
                                       format_CStr("search newtab:1 query:%s",
                                                   cstr_String(selectedText_DocumentWidget_(d))) },
+                                    { "${menu.snippet.add}", 0, 0,
+                                      format_CStr("!snippet.add content:%s",
+                                                  cstr_String(selectedText_DocumentWidget_(d))) },
                                     { "---", 0, 0, NULL } },
-                                3);
+                                4);
                     }
 #if defined (iPlatformApple) && defined (LAGRANGE_ENABLE_MAC_MENUS)
                     pushBackN_Array(
@@ -4444,27 +4453,23 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
                             (iMenuItem[]){
                                 { "---" },
                                 { reload_Icon " ${menu.reload}", reload_KeyShortcut, "navigate.reload" },
-                                { timer_Icon " ${menu.autoreload}", 0, 0, "document.autoreload.menu" },
                                 { "---" },
                                 { bookmark_Icon " ${menu.page.bookmark}", bookmarkPage_KeyShortcut, "bookmark.add" },
                                 { star_Icon " ${menu.page.subscribe}", subscribeToPage_KeyShortcut, "feeds.subscribe" },
                                 { "---" },
-                                { globe_Icon " ${menu.page.translate}", 0, 0, "document.translate" },
-                                { upload_Icon " ${menu.page.upload}", 0, 0, "document.upload" },
-                                { "${menu.page.upload.edit}", 0, 0, "document.upload copy:1" },
-                                { book_Icon " ${menu.page.import}", 0, 0, "bookmark.links confirm:1" },
                                 { d->flags & viewSource_DocumentWidgetFlag ? "${menu.viewformat.gemini}"
                                                                            : "${menu.viewformat.plain}",
                                   0, 0, "document.viewformat" },
+                                { hammer_Icon " ${menu.tools}", 0, 0, "submenu id:toolsmenu" },
                                 { "---" },
                                 { "${menu.page.copyurl}", 0, 0, "document.copylink" }, },
-                            14);
+                            10);
                         if (isEmpty_Range(&d->selectMark)) {
                             pushBackN_Array(
                                 &items,
                                 (iMenuItem[]){
-                                               { "${menu.page.copysource}", 'c', KMOD_PRIMARY, "copy" },
-                                               { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" } },
+                                    { "${menu.page.copysource}", 'c', KMOD_PRIMARY, "copy" },
+                                    { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" } },
                                 2);
                         }
                     }
@@ -4479,7 +4484,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
                                 { "${menu.select.par}", 0, 0, "document.select arg:3" },
                             },
                             3);
-    #endif
+#endif
                         postCommand_Root(w->root, "document.select arg:1");
                         return iTrue;
                     }
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index 962376ee..bf68bfc1 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -1868,7 +1868,7 @@ static void markWordAtCursor_InputWidget_(iInputWidget *d) {
 }
 
 static void showClipMenu_InputWidget_(const iInputWidget *d, iInt2 coord) {
-    iWidget *clipMenu = findWidget_App("clipmenu");
+    iWidget *clipMenu = findChild_Widget(root_Widget(constAs_Widget(d)), "clipmenu");
     if (isVisible_Widget(clipMenu)) {
         closeMenu_Widget(clipMenu);
     }
@@ -2379,6 +2379,13 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
         copy_InputWidget_(d, argLabel_Command(command_UserEvent(ev), "cut"));
         return iTrue;
     }
+    else if (isCommand_UserEvent(ev, "input.delete") && isEditing_InputWidget_(d)) {
+        pushUndo_InputWidget_(d);
+        if (deleteMarked_InputWidget_(d)) {
+            contentsWereChanged_InputWidget_(d);
+        }
+        return iTrue;
+    }
 //    else if (isFocused_Widget(d) && isCommand_UserEvent(ev, "copy")) {
 //        copy_InputWidget_(d, iFalse);
 //        return iTrue;
@@ -2419,6 +2426,10 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
         selectAll_InputWidget(d);
         return iTrue;
     }
+    else if (isCommand_UserEvent(ev, "input.deselect") && isEditing_InputWidget_(d)) {
+        deselect_InputWidget(d);
+        return iTrue;
+    }
     else if (isCommand_UserEvent(ev, "theme.changed")) {
         if (d->buffered) {
             d->inFlags |= needUpdateBuffer_InputWidgetFlag;
diff --git a/src/ui/root.c b/src/ui/root.c
index 228bc39f..afbcd29a 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -65,14 +65,12 @@ static const iMenuItem desktopNavMenuItems_[] = {
     { "---" },
     { leftHalf_Icon " ${menu.sidebar.left}", leftSidebar_KeyShortcut, "sidebar.toggle" },
     { rightHalf_Icon " ${menu.sidebar.right}", rightSidebar_KeyShortcut, "sidebar2.toggle" },
-    { "${menu.view.split}", SDLK_j, KMOD_PRIMARY, "submenu id:splitmenu" },
     { "${menu.zoom.in}", SDLK_EQUALS, KMOD_PRIMARY, "zoom.delta arg:10" },
     { "${menu.zoom.out}", SDLK_MINUS, KMOD_PRIMARY, "zoom.delta arg:-10" },
     { "${menu.zoom.reset}", SDLK_0, KMOD_PRIMARY, "zoom.set arg:100" },
+    { "${menu.view.split}", SDLK_j, KMOD_PRIMARY, "submenu id:splitmenu" },
     { "---" },
-    { "${menu.feeds.entrylist}", 0, 0, "!open url:about:feeds" },
-    { "${menu.downloads}", 0, 0, "downloads.open" },
-    { export_Icon " ${menu.export}", 0, 0, "export" },
+    { package_Icon " ${menu.userdata}", 0, 0, "submenu id:userdatamenu" },
     { "---" },
     { gear_Icon " ${menu.preferences}", preferences_KeyShortcut, "preferences" },
  #if defined (LAGRANGE_ENABLE_WINSPARKLE)
@@ -85,6 +83,19 @@ static const iMenuItem desktopNavMenuItems_[] = {
     { NULL }
 };
 
+static const iMenuItem userDataMenuItems_[] = {
+    { "${menu.bookmarks.list}", 0, 0, "!open url:about:bookmarks" },
+    { "${menu.bookmarks.bytag}", 0, 0, "!open url:about:bookmarks?tags" },
+    { "${menu.bookmarks.bytime}", 0, 0, "!open url:about:bookmarks?created" },
+    { "---" },
+    { "${menu.feeds.entrylist}", 0, 0, "!open url:about:feeds" },
+    { "---" },
+    { "${menu.downloads}", 0, 0, "downloads.open" },
+    { "---" },
+    { "${menu.export}", 0, 0, "export" },
+    { NULL }
+};
+
 static const iMenuItem tabletNavMenuItems_[] = {
     { add_Icon " ${menu.newtab}", SDLK_t, KMOD_PRIMARY, "tabs.new append:1" },
     { folder_Icon " ${menu.openfile}", SDLK_o, KMOD_PRIMARY, "file.open" },
@@ -1566,6 +1577,43 @@ static iBool updateMobilePageMenuItems_(iWidget *menu, const char *cmd) {
     return handleMenuCommand_Widget(menu, cmd);
 }
 
+void createClipMenu_Root(iRoot *d) {
+    iWidget *clipMenu = makeMenu_Widget(d->widget,
+#if defined (iPlatformMobile)
+        (iMenuItem[]){
+            { ">>>" scissor_Icon " ${menu.cut}", 0, 0, "input.copy cut:1" },
+            { ">>>" clipCopy_Icon " ${menu.copy}", 0, 0, "input.copy" },
+            { ">>>" clipboard_Icon " ${menu.paste}", 0, 0, "input.paste" },
+            { "---" },
+            { ">>>" delete_Icon " " uiTextCaution_ColorEscape "${menu.delete}", 0, 0, "input.delete" },
+            { ">>>" select_Icon " ${menu.selectall}", 0, 0, "input.selectall" },
+            { ">>>" undo_Icon " ${menu.undo}", 0, 0, "input.undo" },
+            { "---" },
+            { "${menu.paste.snippet}", 0, 0, "snippetmenu" },
+        }, 9);
+#else
+        (iMenuItem[]){
+            { scissor_Icon " ${menu.cut}", 0, 0, "input.copy cut:1" },
+            { clipCopy_Icon " ${menu.copy}", 0, 0, "input.copy" },
+            { clipboard_Icon " ${menu.paste}", 0, 0, "input.paste" },
+            { return_Icon " ${menu.paste.go}", 0, 0, "input.paste enter:1" },
+            { "${menu.paste.snippet}", 0, 0, "submenu id:snippetmenu" },
+            { "---" },
+            { delete_Icon " " uiTextCaution_ColorEscape "${menu.delete}", 0, 0, "input.delete" },
+            { undo_Icon " ${menu.undo}", 0, 0, "input.undo" },
+            { "---" },
+            { select_Icon " ${menu.selectall}", 0, 0, "input.selectall" },
+        }, 10);
+#endif
+    setId_Widget(clipMenu, "clipmenu");
+    if (deviceType_App() == phone_AppDeviceType) {
+        /* Small screen; conserve space by removing the Cancel item. */
+        iRelease(removeChild_Widget(clipMenu, lastChild_Widget(clipMenu)));
+        iRelease(removeChild_Widget(clipMenu, lastChild_Widget(clipMenu)));
+        iRelease(removeChild_Widget(clipMenu, lastChild_Widget(clipMenu)));
+    }
+}
+
 void recreateSnippetMenu_Root(iRoot *d) {
     const iStringArray *snipNames = names_Snippets();
     iArray *items = collectNew_Array(sizeof(iMenuItem));
@@ -1868,6 +1916,8 @@ void createUserInterface_Root(iRoot *d) {
                                               home_Icon, 0, 0, "navigate.home")),
                                           collapse_WidgetFlag),
                      "navbar.action4");
+        setId_Widget(makeMenu_Widget(root, userDataMenuItems_, iElemCount(userDataMenuItems_)),
+                     "userdatamenu");
 #if !defined (LAGRANGE_MAC_MENUBAR)
         /* Hamburger menu. */ {
             iLabelWidget *navMenu = makeMenuButton_LabelWidget(
@@ -2076,40 +2126,8 @@ void createUserInterface_Root(iRoot *d) {
                                 { rightHalf_Icon " ${menu.sidebar.right}", 0, 0, "sidebar2.toggle" },
                             },
                             deviceType_App() == phone_AppDeviceType ? 1 : 2);
-        iWidget *clipMenu = makeMenu_Widget(root,
-#if defined (iPlatformMobile)
-            (iMenuItem[]){
-                { ">>>" scissor_Icon " ${menu.cut}", 0, 0, "input.copy cut:1" },
-                { ">>>" clipCopy_Icon " ${menu.copy}", 0, 0, "input.copy" },
-                { ">>>" clipboard_Icon " ${menu.paste}", 0, 0, "input.paste" },
-                { "---" },
-                { ">>>" delete_Icon " " uiTextCaution_ColorEscape "${menu.delete}", 0, 0, "input.delete" },
-                { ">>>" select_Icon " ${menu.selectall}", 0, 0, "input.selectall" },
-                { ">>>" undo_Icon " ${menu.undo}", 0, 0, "input.undo" },
-                { "---" },
-                { "${menu.paste.snippet}", 0, 0, "snippetmenu" },
-            }, 9);
-#else
-            (iMenuItem[]){
-                { scissor_Icon " ${menu.cut}", 0, 0, "input.copy cut:1" },
-                { clipCopy_Icon " ${menu.copy}", 0, 0, "input.copy" },
-                { clipboard_Icon " ${menu.paste}", 0, 0, "input.paste" },
-                { return_Icon " ${menu.paste.go}", 0, 0, "input.paste enter:1" },
-                { "${menu.paste.snippet}", 0, 0, "submenu id:snippetmenu" },
-                { "---" },
-                { delete_Icon " " uiTextCaution_ColorEscape "${menu.delete}", 0, 0, "input.delete" },
-                { undo_Icon " ${menu.undo}", 0, 0, "input.undo" },
-                { "---" },
-                { select_Icon " ${menu.selectall}", 0, 0, "input.selectall" },
-            }, 10);
-#endif
+        createClipMenu_Root(d);
         recreateSnippetMenu_Root(d);
-        if (deviceType_App() == phone_AppDeviceType) {
-            /* Small screen; conserve space by removing the Cancel item. */
-            iRelease(removeChild_Widget(clipMenu, lastChild_Widget(clipMenu)));
-            iRelease(removeChild_Widget(clipMenu, lastChild_Widget(clipMenu)));
-            iRelease(removeChild_Widget(clipMenu, lastChild_Widget(clipMenu)));
-        }
         iWidget *splitMenu = makeMenu_Widget(root, (iMenuItem[]){
             { "${menu.split.merge}", '1', 0, "ui.split arg:0" },
             { "${menu.split.swap}", SDLK_x, 0, "ui.split swap:1" },
@@ -2122,11 +2140,18 @@ void createUserInterface_Root(iRoot *d) {
             { "${menu.split.vertical} 1:2", SDLK_f, 0, "ui.split arg:1 axis:1" },
             { "${menu.split.vertical} 2:1", SDLK_r, 0, "ui.split arg:2 axis:1" },
         }, 10);
+        iWidget *toolsMenu = makeMenu_Widget(root, (iMenuItem[]) {
+           { globe_Icon " ${menu.page.translate}", 0, 0, "document.translate" },
+           { upload_Icon " ${menu.page.upload}", 0, 0, "document.upload" },
+           { edit_Icon " ${menu.page.upload.edit}", 0, 0, "document.upload copy:1" },
+           { book_Icon " ${menu.page.import}", 0, 0, "bookmark.links confirm:1" },
+           { timer_Icon " ${menu.autoreload}", 0, 0, "document.autoreload.menu" }
+        }, 5);
         setFlags_Widget(splitMenu, disabledWhenHidden_WidgetFlag, iTrue); /* enabled when open */
         setId_Widget(tabsMenu, "doctabs.menu");
         setId_Widget(barMenu, "barmenu");
-        setId_Widget(clipMenu, "clipmenu");
         setId_Widget(splitMenu, "splitmenu");
+        setId_Widget(toolsMenu, "toolsmenu");
     }
     /* Global keyboard shortcuts. */ {
         addAction_Widget(root, SDLK_h, KMOD_PRIMARY | KMOD_SHIFT, "navigate.home");
diff --git a/src/ui/root.h b/src/ui/root.h
index 9618d1b0..501123fc 100644
--- a/src/ui/root.h
+++ b/src/ui/root.h
@@ -35,6 +35,7 @@ iDeclareTypeConstruction(Root)
 /*----------------------------------------------------------------------------------------------*/
 
 void        createUserInterface_Root            (iRoot *);
+void        createClipMenu_Root                 (iRoot *);
 void        recreateSnippetMenu_Root            (iRoot *);
 
 void        setCurrent_Root                     (iRoot *);
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c
index c956e38a..f48e91e0 100644
--- a/src/ui/sidebarwidget.c
+++ b/src/ui/sidebarwidget.c
@@ -276,11 +276,10 @@ static const iPtrArray *listFeedEntries_SidebarWidget_(const iSidebarWidget *d)
 static const iMenuItem bookmarkModeMenuItems_[] = {
     { bookmark_Icon " ${menu.page.bookmark}", SDLK_d, KMOD_PRIMARY, "bookmark.add" },
     { "---" },
-    { add_Icon " ${menu.newfolder}", 0, 0, "bookmark.addfolder" },
-    { upDownArrow_Icon " ${menu.sort.alpha}", 0, 0, "bookmark.sortfolder" },
-    { "---" },
     { rightAngle_Icon " ${menu.foldall}", 0, 0, "bookmark.foldall arg:1" },
     { downAngle_Icon " ${menu.unfoldall}", 0, 0, "bookmark.foldall arg:0" },
+    { upDownArrow_Icon " ${menu.sort.alpha}", 0, 0, "bookmark.sortfolder" },
+    { folder_Icon " ${menu.newfolder}", 0, 0, "bookmark.addfolder" },
     { "---" },
     { reload_Icon " ${bookmarks.reload}", 0, 0, "bookmarks.reload.remote" }
 };
diff --git a/src/ui/window.c b/src/ui/window.c
index 480ef4bb..473215ef 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -2272,6 +2272,8 @@ iWindow *newExtra_Window(iWidget *rootWidget) {
     rootWidget->rect.pos = zero_I2();
     setDrawBufferEnabled_Widget(frameRoot, iFalse);
     setDrawBufferEnabled_Widget(rootWidget, iFalse);
+    createClipMenu_Root(root); /* needed for input widgets */
+    recreateSnippetMenu_Root(root);
     setCurrent_Window(oldWin);
     return win;
 }
Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/work%2Fv1.17/cdiff/26330fd2ea529ce1e1a5774149870f97226faee7
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
76.44803 milliseconds
Gemini-to-HTML Time
0.930303 milliseconds

This content has been proxied by September (ba2dc).