diff --git a/src/terminalwindow.cpp b/src/terminalwindow.cpp index 455620c..b5ee675 100644 --- a/src/terminalwindow.cpp +++ b/src/terminalwindow.cpp @@ -666,6 +666,10 @@ void TerminalWindow::closeOtherTabs(int index) others.push_back(page); } confirmClose(others, [this, keep, others] { + // The kept tab's shell may have ended while the dialog was open; the + // other tabs then stay rather than leave the window empty. + if (indexOfPage(keep) < 0) + return; for (TerminalPage* page : others) closeTab(indexOfPage(page)); showPage(indexOfPage(keep)); diff --git a/tests/window_test.cpp b/tests/window_test.cpp index b1fc3c4..18aad12 100644 --- a/tests/window_test.cpp +++ b/tests/window_test.cpp @@ -11,12 +11,16 @@ #include "base/event_loop.h" #include "base/file.h" #include "base/timer.h" +#include "ui/application.h" #include "ui/glyph_run.h" +#include "ui/keys.h" #include "ui/painter.h" +#include "ui/test_input.h" #include "ui/view.h" #include "ui/window.h" #include "TerminalFont.h" +#include "TerminalSession.h" #include "tools.h" #include "terminalpage.h" @@ -104,6 +108,51 @@ TEST_F(WindowTest, ShellExitClosesItsTab) EXPECT_TRUE(waitFor([&] { return window->tabCount() == 1; })); } +// The confirmation the window shows last, as a key press answers it. +static void confirmLastDialog(TerminalWindow* window) +{ + ui::Window* dialog = ui::Application::instance()->windows().back(); + ASSERT_NE(dialog, &window->window()); + dialog->grab(); + ui::TestInput::setKeyboardFocus(*dialog, true); + ui::TestInput::typeKey(*dialog, ui::key::Return); +} + +TEST_F(WindowTest, CloseOtherTabsKeepsTheChosenTab) +{ + Windows windows(m_settings); + TerminalWindow* window = windows.create(shell()); + TerminalPage* busy = window->currentPage(); + window->openTab(m_directory.path(), {"/bin/sh"}); + ASSERT_EQ(window->tabCount(), 2); + busy->session().sendText("sleep 30\n"); + ASSERT_TRUE(waitFor([&] { return busy->session().hasActiveProcess(); })); + + window->closeOtherTabs(1); + confirmLastDialog(window); + ASSERT_EQ(window->tabCount(), 1); + ASSERT_NE(window->currentPage(), nullptr); + EXPECT_TRUE(window->currentPage()->isVisible()); +} + +TEST_F(WindowTest, CloseOtherTabsAfterTheKeptTabEnded) +{ + Windows windows(m_settings); + TerminalWindow* window = windows.create(shell()); + TerminalPage* busy = window->currentPage(); + window->openTab(m_directory.path(), {"/bin/sh", "-c", "sleep 1"}); + ASSERT_EQ(window->tabCount(), 2); + busy->session().sendText("sleep 30\n"); + ASSERT_TRUE(waitFor([&] { return busy->session().hasActiveProcess(); })); + + window->closeOtherTabs(1); + ASSERT_TRUE(waitFor([&] { return window->tabCount() == 1; })); + confirmLastDialog(window); + ASSERT_EQ(window->tabCount(), 1); + EXPECT_EQ(window->currentPage(), busy); + EXPECT_TRUE(busy->isVisible()); +} + namespace { class Canvas : public ui::View