diff --git a/po/en.po b/po/en.po

index e9bdd590..37777559 100644

--- a/po/en.po

+++ b/po/en.po

@@ -154,6 +154,9 @@ msgstr "New Window"

msgid "menu.newtab"

msgstr "New Tab"



+msgid "menu.reopentab"

+msgstr "Reopen Last Closed Tab"

+

msgid "menu.closetab"

msgstr "Close Tab"



diff --git a/src/app.c b/src/app.c

index 89c60698..4055916a 100644

--- a/src/app.c

+++ b/src/app.c

@@ -134,6 +134,7 @@ struct Impl_App {

 iCommandLine args;

 iString *    execPath;

 iStringSet * tempFilesPendingDeletion;

+ iStringList recentlyClosedTabUrls; / for reopening, like an undo stack */

 iMimeHooks * mimehooks;

 iGmCerts *   certs;

 iVisited *   visited;

@@ -168,7 +169,6 @@ struct Impl_App {

 /* Preferences: */

 iBool        commandEcho;         /* --echo */

 iBool        forceSoftwareRender; /* --sw */

- //iRect initialWindowRect;

 iArray       initialWindowRects; /* one per window */

 iPrefs       prefs;

};

@@ -907,7 +907,8 @@ static void init_App_(iApp *d, int argc, char **argv) {

 d->isDarkSystemTheme = iTrue; /* will be updated by system later on, if supported */

 d->isSuspended = iFalse;

 d->tempFilesPendingDeletion = new_StringSet();

- init_Array(&d->initialWindowRects, sizeof(iRect));

+ d->recentlyClosedTabUrls = new_StringList();

+ init_Array(&d->initialWindowRects, sizeof(iRect)); 

 init_CommandLine(&d->args, argc, argv);

 /* Where was the app started from? We ask SDL first because the command line alone

    cannot be relied on (behavior differs depending on OS). */ {

@@ -1211,6 +1212,7 @@ static void deinit_App(iApp *d) {

     remove(cstr_String(tmp.value));

 }

 deinit_Array(&d->initialWindowRects);

+ iRelease(d->recentlyClosedTabUrls);

 iRelease(d->tempFilesPendingDeletion);

}



@@ -2616,6 +2618,20 @@ static void invalidateCachedDocuments_App_(void) {

 }

}



+static void pushClosedTabUrl_App_(iApp *d, const iString *url) {

+ pushBack_StringList(d->recentlyClosedTabUrls, url);

+ if (size_StringList(d->recentlyClosedTabUrls) > 50) { /* not an infinite number */

+ popFront_StringList(d->recentlyClosedTabUrls);

+ }

+}

+

+static const iString *popClosedTabUrl_App_(iApp *d) {

+ if (isEmpty_StringList(d->recentlyClosedTabUrls)) {

+ return NULL;

+ }

+ return collect_String(takeLast_StringList(d->recentlyClosedTabUrls)); 

+}

+

static iBool handleNonWindowRelatedCommand_App_(iApp *d, const char *cmd) {

 const iBool isFrozen = !d->window || d->window->isDrawFrozen;

 /* Commands related to preferences. */

@@ -3524,8 +3540,16 @@ iBool handleCommand_App(const char *cmd) {

     return iFalse;

 }

 else if (equal_Command(cmd, "tabs.new")) {

+ if (argLabel_Command(cmd, "reopen")) {

+ const iString *reopenUrl = popClosedTabUrl_App_(d);

+ if (reopenUrl) {

+ newTab_App(NULL, iTrue);

+ postCommandf_App("open url:%s", cstr_String(reopenUrl));

+ }

+ return iTrue;

+ }

     const iBool isDuplicate = argLabel_Command(cmd, "duplicate") != 0;

- newTab_App(isDuplicate ? document_App() : NULL, iTrue);

+ newTab_App(isDuplicate ? document_App() : NULL, iTrue); 

     if (!isDuplicate) {

         postCommandf_App("navigate.home focus:%d", deviceType_App() == desktop_AppDeviceType);

     }

@@ -3549,13 +3573,19 @@ iBool handleCommand_App(const char *cmd) {

     postCommand_App("document.openurls.changed");

     if (argLabel_Command(cmd, "toright")) {

         while (tabCount_Widget(tabs) > index + 1) {

- destroy_Widget(removeTabPage_Widget(tabs, index + 1));

+ iDocumentWidget *closed = (iDocumentWidget *) removeTabPage_Widget(tabs, index + 1);

+ pushClosedTabUrl_App_(d, url_DocumentWidget(closed));

+ cancelAllRequests_DocumentWidget(closed);

+ destroy_Widget(as_Widget(closed));

         }

         wasClosed = iTrue;

     }

     if (argLabel_Command(cmd, "toleft")) {

         while (index-- > 0) {

- destroy_Widget(removeTabPage_Widget(tabs, 0));

+ iDocumentWidget *closed = (iDocumentWidget *) removeTabPage_Widget(tabs, 0);

+ pushClosedTabUrl_App_(d, url_DocumentWidget(closed));

+ cancelAllRequests_DocumentWidget(closed);

+ destroy_Widget(as_Widget(closed));

         }

         postCommandf_App("tabs.switch page:%p", tabPage_Widget(tabs, 0));

         wasClosed = iTrue;

@@ -3566,9 +3596,10 @@ iBool handleCommand_App(const char *cmd) {

     }

     const iBool isSplit = numRoots_Window(get_Window()) > 1;

     if (tabCount_Widget(tabs) > 1 || isSplit) {

- iWidget *closed = removeTabPage_Widget(tabs, index);

- cancelAllRequests_DocumentWidget((iDocumentWidget *) closed);

- destroy_Widget(closed); /* released later */

+ iDocumentWidget *closed = (iDocumentWidget *) removeTabPage_Widget(tabs, index);

+ pushClosedTabUrl_App_(d, url_DocumentWidget(closed));

+ cancelAllRequests_DocumentWidget(closed);

+ destroy_Widget(as_Widget(closed)); /* released later */

         if (index == tabCount_Widget(tabs)) {

             index--;

         }

diff --git a/src/app.h b/src/app.h

index 60421e2b..98d49fbb 100644

--- a/src/app.h

+++ b/src/app.h

@@ -126,6 +126,7 @@ iAny * findWidget_App (const char *id);

void addTicker_App (iTickerFunc ticker, iAny *context);

void addTickerRoot_App (iTickerFunc ticker, iRoot *root, iAny *context);

void removeTicker_App (iTickerFunc ticker, iAny *context);

+

void addWindow_App (iMainWindow *win);

void removeWindow_App (iMainWindow *win);

void setActiveWindow_App (iMainWindow *win);

@@ -134,8 +135,11 @@ size_t numWindows_App (void);

size_t windowIndex_App (const iMainWindow *win);

iMainWindow *newMainWindow_App (void);

const iPtrArray *mainWindows_App(void);

+iMainWindow * mainWindow_App (void); /* currently active main window */

void addPopup_App (iWindow *popup);

void removePopup_App (iWindow *popup);

+void closePopups_App (iBool doForce);

+

void postRefresh_App (void);

void postCommand_Root (iRoot *, const char *command);

void postCommandf_Root (iRoot *, const char *command, ...);

@@ -156,6 +160,3 @@ void openInDefaultBrowser_App(const iString *url);

void revealPath_App (const iString *path);

void resetFonts_App (void);

void availableFontsChanged_App(void);

-

-iMainWindow * mainWindow_App (void);

-void closePopups_App (iBool doForce);

diff --git a/src/ui/keys.c b/src/ui/keys.c

index 6a12b5e7..c3b68316 100644

--- a/src/ui/keys.c

+++ b/src/ui/keys.c

@@ -227,7 +227,8 @@ static const struct { int id; iMenuItem bind; int flags; } defaultBindings_[] =

#endif

 { 76, { "${keys.tab.new}",              newTab_KeyShortcut,             "tabs.new"                          }, 0 },

 { 77, { "${keys.tab.close}",            closeTab_KeyShortcut,           "tabs.close"                        }, 0 },

- { 78, { "${keys.tab.close.other}", SDLK_w, KMOD_SECONDARY, "tabs.close toleft:1 toright:1" }, 0 },

+ { 78, { "${keys.tab.close.other}", SDLK_w, KMOD_SECONDARY, "tabs.close toleft:1 toright:1" }, 0 },

+ { 79, { "${LC:menu.reopentab}", SDLK_t, KMOD_SECONDARY, "tabs.new reopen:1" }, 0 }, 

 { 80, { "${keys.tab.prev}",             prevTab_KeyShortcut,            "tabs.prev"                         }, 0 },

 { 81, { "${keys.tab.next}",             nextTab_KeyShortcut,            "tabs.next"                         }, 0 },

 { 90, { "${keys.split.menu}",           SDLK_j, KMOD_PRIMARY,           "splitmenu.open"                    }, 0 },

diff --git a/src/ui/window.c b/src/ui/window.c

index 0d1923c6..c773bc96 100644

--- a/src/ui/window.c

+++ b/src/ui/window.c

@@ -73,6 +73,7 @@ iDefineTypeConstructionArgs(MainWindow, (iRect rect), rect)

static const iMenuItem fileMenuItems_[] = {

 { "${menu.newwindow}", SDLK_n, KMOD_PRIMARY, "window.new" },

 { "${menu.newtab}", SDLK_t, KMOD_PRIMARY, "tabs.new" },

+ { "${menu.reopentab}", SDLK_t, KMOD_SECONDARY, "tabs.new reopen:1" },

 { "${menu.openlocation}", SDLK_l, KMOD_PRIMARY, "navigate.focus" },

 { "---" },

 { saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" },

Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/work%2Fv1.13/pcdiff/b854a7677bb1f72b77f9d8fcbbc481f368949680
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
70.121457 milliseconds
Gemini-to-HTML Time
2.340392 milliseconds

This content has been proxied by September (ba2dc).