diff --git a/src/pane.vala b/src/pane.vala index 1916208..3475187 100644 --- a/src/pane.vala +++ b/src/pane.vala @@ -37,7 +37,8 @@ namespace Footerm { }); } - async void close () { + public async void close () { + yield this.terminal_pane.disconnect_from_server(); } } } diff --git a/src/terminalpane.vala b/src/terminalpane.vala index d0d43db..0573770 100644 --- a/src/terminalpane.vala +++ b/src/terminalpane.vala @@ -24,10 +24,13 @@ namespace Footerm { [GtkChild] private unowned Vte.Terminal terminal; - private SSH2.Session? session; - private SSH2.Channel? channel; - private SocketConnection socket; - private IOChannel slave_channel; + private SSH2.Session? session = null; + private SSH2.Channel? channel = null; + private SocketConnection? socket = null; + private IOChannel? slave_channel = null; + private SocketSource? socket_source = null; + + private Cancellable cancel = new Cancellable(); private Footerm.Model.Server? server; @@ -47,6 +50,32 @@ namespace Footerm { }); } + public async void disconnect_from_server() { + debug("Disconnecting ..."); + if (this.session != null) { + this.socket_source.destroy(); + this.socket_source = null; + + this.slave_channel.shutdown(true); + this.slave_channel = null; + + this.cancel.cancel(); + this.session.blocking = true; + + this.channel.close(); + this.channel = null; + + this.session.disconnect("Terminal pane was closed"); + this.session = null; + + yield this.socket.close_async(0, null); + + this.socket = null; + + this.server = null; + } + } + private void configure_terminal() { this.terminal.set_enable_sixel(true); this.terminal.char_size_changed.connect(() => { @@ -91,8 +120,7 @@ namespace Footerm { throw GLib.IOError.from_errno(Posix.errno); } - - var vte_pty = new Vte.Pty.foreign_sync(master_pty, null); + var vte_pty = new Vte.Pty.foreign_sync(master_pty, this.cancel); this.terminal.set_pty(vte_pty); this.slave_channel = new GLib.IOChannel.unix_new(slave_pty); @@ -157,9 +185,9 @@ namespace Footerm { this.create_pty(); var inner_socket = socket.get_socket(); - var source = inner_socket.create_source(GLib.IOCondition.IN, null); - source.set_callback(this.on_ssh_event); - source.attach(null); + this.socket_source = inner_socket.create_source(GLib.IOCondition.IN, this.cancel); + this.socket_source.set_callback(this.on_ssh_event); + this.socket_source.attach(null); slave_channel.add_watch(GLib.IOCondition.IN, this.on_slave_event); } @@ -171,6 +199,10 @@ namespace Footerm { return false; } + if (this.cancel.is_cancelled()) { + return false; + } + try { ssize_t size = 0; var buffer = new uint8[1024]; @@ -207,6 +239,7 @@ namespace Footerm { var res = this.channel.write((uint8[]) buffer[0 : size]); if (res < 0) { warning("Channel write failed with %zu", res); + return false; } return true; } catch (Error e) { diff --git a/src/window.vala b/src/window.vala index b1a957d..6d30fc6 100644 --- a/src/window.vala +++ b/src/window.vala @@ -42,9 +42,16 @@ namespace Footerm { } private bool close_page (Adw.TabView tab_view, Adw.TabPage page) { - // TODO CLOSE CONNEXION FOR PANE - debug ("Close pane"); - tab_view.close_page_finish (page, !page.get_pinned ()); + if (!page.get_pinned ()) { + var child = (Footerm.Pane) page.get_child (); + child.close.begin ((obj, res) => { + child.close.end (res); + tab_view.close_page_finish (page, true); + }); + } else { + tab_view.close_page_finish (page, false); + } + return Gdk.EVENT_STOP; } }