Fix multi-client server suspend
This commit is contained in:
parent
f43ac3d78b
commit
006083c6f8
35
src/main.cc
35
src/main.cc
|
@ -477,7 +477,6 @@ void register_options()
|
||||||
|
|
||||||
static Client* local_client = nullptr;
|
static Client* local_client = nullptr;
|
||||||
static int local_client_exit = 0;
|
static int local_client_exit = 0;
|
||||||
static UserInterface* local_ui = nullptr;
|
|
||||||
static bool convert_to_client_pending = false;
|
static bool convert_to_client_pending = false;
|
||||||
|
|
||||||
enum class UIType
|
enum class UIType
|
||||||
|
@ -550,26 +549,10 @@ std::unique_ptr<UserInterface> create_local_ui(UIType ui_type)
|
||||||
{
|
{
|
||||||
LocalUI()
|
LocalUI()
|
||||||
{
|
{
|
||||||
kak_assert(not local_ui);
|
set_signal_handler(SIGTSTP, [](int) {
|
||||||
local_ui = this;
|
|
||||||
|
|
||||||
m_old_sigtstp = set_signal_handler(SIGTSTP, [](int) {
|
|
||||||
if (ClientManager::instance().count() == 1 and
|
if (ClientManager::instance().count() == 1 and
|
||||||
*ClientManager::instance().begin() == local_client)
|
*ClientManager::instance().begin() == local_client)
|
||||||
{
|
NCursesUI::instance().suspend();
|
||||||
// Suspend normally if we are the only client
|
|
||||||
auto current = set_signal_handler(SIGTSTP, static_cast<LocalUI*>(local_ui)->m_old_sigtstp);
|
|
||||||
|
|
||||||
sigset_t unblock_sigtstp, old_mask;
|
|
||||||
sigemptyset(&unblock_sigtstp);
|
|
||||||
sigaddset(&unblock_sigtstp, SIGTSTP);
|
|
||||||
sigprocmask(SIG_UNBLOCK, &unblock_sigtstp, &old_mask);
|
|
||||||
|
|
||||||
raise(SIGTSTP);
|
|
||||||
|
|
||||||
set_signal_handler(SIGTSTP, current);
|
|
||||||
sigprocmask(SIG_SETMASK, &old_mask, nullptr);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
convert_to_client_pending = true;
|
convert_to_client_pending = true;
|
||||||
});
|
});
|
||||||
|
@ -577,23 +560,17 @@ std::unique_ptr<UserInterface> create_local_ui(UIType ui_type)
|
||||||
|
|
||||||
~LocalUI() override
|
~LocalUI() override
|
||||||
{
|
{
|
||||||
set_signal_handler(SIGTSTP, m_old_sigtstp);
|
|
||||||
local_client = nullptr;
|
local_client = nullptr;
|
||||||
local_ui = nullptr;
|
if (convert_to_client_pending or
|
||||||
if (not convert_to_client_pending and
|
ClientManager::instance().empty())
|
||||||
not ClientManager::instance().empty())
|
return;
|
||||||
{
|
|
||||||
if (fork_server_to_background())
|
if (fork_server_to_background())
|
||||||
{
|
{
|
||||||
this->NCursesUI::~NCursesUI();
|
this->NCursesUI::~NCursesUI();
|
||||||
exit(local_client_exit);
|
exit(local_client_exit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
using SigHandler = void (*)(int);
|
|
||||||
SigHandler m_old_sigtstp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (not isatty(1))
|
if (not isatty(1))
|
||||||
|
|
|
@ -373,6 +373,7 @@ NCursesUI::NCursesUI()
|
||||||
|
|
||||||
set_signal_handler(SIGWINCH, &signal_handler<&resize_pending>);
|
set_signal_handler(SIGWINCH, &signal_handler<&resize_pending>);
|
||||||
set_signal_handler(SIGHUP, &signal_handler<&sighup_raised>);
|
set_signal_handler(SIGHUP, &signal_handler<&sighup_raised>);
|
||||||
|
set_signal_handler(SIGTSTP, [](int){ NCursesUI::instance().suspend(); });
|
||||||
|
|
||||||
check_resize(true);
|
check_resize(true);
|
||||||
redraw(false);
|
redraw(false);
|
||||||
|
@ -390,6 +391,29 @@ NCursesUI::~NCursesUI()
|
||||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &m_original_termios);
|
tcsetattr(STDIN_FILENO, TCSAFLUSH, &m_original_termios);
|
||||||
set_signal_handler(SIGWINCH, SIG_DFL);
|
set_signal_handler(SIGWINCH, SIG_DFL);
|
||||||
set_signal_handler(SIGCONT, SIG_DFL);
|
set_signal_handler(SIGCONT, SIG_DFL);
|
||||||
|
set_signal_handler(SIGTSTP, SIG_DFL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NCursesUI::suspend()
|
||||||
|
{
|
||||||
|
bool mouse_enabled = m_mouse_enabled;
|
||||||
|
enable_mouse(false);
|
||||||
|
tcsetattr(STDIN_FILENO, TCSAFLUSH, &m_original_termios);
|
||||||
|
|
||||||
|
auto current = set_signal_handler(SIGTSTP, SIG_DFL);
|
||||||
|
sigset_t unblock_sigtstp, old_mask;
|
||||||
|
sigemptyset(&unblock_sigtstp);
|
||||||
|
sigaddset(&unblock_sigtstp, SIGTSTP);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &unblock_sigtstp, &old_mask);
|
||||||
|
|
||||||
|
raise(SIGTSTP); // suspend here
|
||||||
|
|
||||||
|
set_signal_handler(SIGTSTP, current);
|
||||||
|
sigprocmask(SIG_SETMASK, &old_mask, nullptr);
|
||||||
|
|
||||||
|
check_resize(true);
|
||||||
|
set_raw_mode();
|
||||||
|
enable_mouse(mouse_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCursesUI::set_raw_mode() const
|
void NCursesUI::set_raw_mode() const
|
||||||
|
@ -612,15 +636,7 @@ Optional<Key> NCursesUI::get_next_key()
|
||||||
return {Key::Backspace};
|
return {Key::Backspace};
|
||||||
if (c == control('z'))
|
if (c == control('z'))
|
||||||
{
|
{
|
||||||
bool mouse_enabled = m_mouse_enabled;
|
|
||||||
enable_mouse(false);
|
|
||||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &m_original_termios);
|
|
||||||
|
|
||||||
kill(0, SIGTSTP); // We suspend at this line
|
kill(0, SIGTSTP); // We suspend at this line
|
||||||
|
|
||||||
check_resize(true);
|
|
||||||
set_raw_mode();
|
|
||||||
enable_mouse(mouse_enabled);
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (c < 27)
|
if (c < 27)
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Kakoune
|
||||||
|
|
||||||
struct NCursesWin;
|
struct NCursesWin;
|
||||||
|
|
||||||
class NCursesUI : public UserInterface
|
class NCursesUI : public UserInterface, public Singleton<NCursesUI>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NCursesUI();
|
NCursesUI();
|
||||||
|
@ -57,6 +57,8 @@ public:
|
||||||
|
|
||||||
static void abort();
|
static void abort();
|
||||||
|
|
||||||
|
void suspend();
|
||||||
|
|
||||||
struct Rect
|
struct Rect
|
||||||
{
|
{
|
||||||
DisplayCoord pos;
|
DisplayCoord pos;
|
||||||
|
@ -117,7 +119,7 @@ private:
|
||||||
Window m_window;
|
Window m_window;
|
||||||
|
|
||||||
DisplayCoord m_dimensions;
|
DisplayCoord m_dimensions;
|
||||||
termios m_original_termios;
|
termios m_original_termios{};
|
||||||
|
|
||||||
void set_raw_mode() const;
|
void set_raw_mode() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user