diff --git a/src/terminal.cpp b/src/terminal.cpp index 52cf6e5..e7d3592 100644 --- a/src/terminal.cpp +++ b/src/terminal.cpp @@ -76,6 +76,7 @@ Terminal::Terminal() : Source::SearchView() { } int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) { + perform_scroll_to_bottom = true; std::unique_ptr process; if(use_pipes) process = std::make_unique(command, path.string(), [this](const char *bytes, size_t n) { @@ -95,6 +96,7 @@ int Terminal::process(const std::string &command, const boost::filesystem::path } int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path, std::ostream *stderr_stream) { + perform_scroll_to_bottom = true; TinyProcessLib::Process process(command, path.string(), [&stdout_stream](const char *bytes, size_t n) { Glib::ustring umessage(std::string(bytes, n)); Glib::ustring::iterator iter; @@ -133,6 +135,7 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c void Terminal::async_process(const std::string &command, const boost::filesystem::path &path, const std::function &callback, bool quiet) { std::thread async_execute_thread([this, command, path, callback, quiet]() { + perform_scroll_to_bottom = true; LockGuard lock(processes_mutex); stdin_buffer.clear(); auto process = std::make_shared(command, path.string(), [this, quiet](const char *bytes, size_t n) { @@ -265,6 +268,10 @@ void Terminal::print(std::string message, bool bold) { if(auto parent = get_parent()) { if(!parent->is_visible()) parent->show(); + + bool expected = true; + if(perform_scroll_to_bottom.compare_exchange_strong(expected, false) && scroll_to_bottom) + scroll_to_bottom(); } #ifdef _WIN32 diff --git a/src/terminal.hpp b/src/terminal.hpp index 2f23372..d27d1bd 100644 --- a/src/terminal.hpp +++ b/src/terminal.hpp @@ -32,6 +32,8 @@ public: void clear(); + std::function scroll_to_bottom; + protected: bool on_motion_notify_event(GdkEventMotion *motion_event) override; bool on_button_press_event(GdkEventButton *button_event) override; @@ -55,4 +57,6 @@ private: Mutex processes_mutex; std::vector> processes GUARDED_BY(processes_mutex); Glib::ustring stdin_buffer; + + std::atomic perform_scroll_to_bottom = {false}; }; diff --git a/src/window.cpp b/src/window.cpp index 7a0cf60..bb4b5dc 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1794,12 +1794,15 @@ void Window::add_widgets() { if(adjustment->get_value() == adjustment->get_upper() - adjustment->get_page_size()) // If for instance the terminal has been cleared *scrolled_to_bottom = true; }); - Terminal::get().signal_size_allocate().connect([this, scrolled_to_bottom](Gtk::Allocation &allocation) mutable { + Terminal::get().scroll_to_bottom = [this, scrolled_to_bottom] { + auto adjustment = terminal_scrolled_window.get_vadjustment(); + adjustment->set_value(adjustment->get_upper() - adjustment->get_page_size()); + *scrolled_to_bottom = true; + Terminal::get().queue_draw(); + }; + Terminal::get().signal_size_allocate().connect([scrolled_to_bottom](Gtk::Allocation & /*allocation*/) { if(*scrolled_to_bottom) { - auto adjustment = terminal_scrolled_window.get_vadjustment(); - adjustment->set_value(adjustment->get_upper() - adjustment->get_page_size()); - *scrolled_to_bottom = true; - Terminal::get().queue_draw(); + Terminal::get().scroll_to_bottom(); } });