Skip to content

Instantly share code, notes, and snippets.

@etrunko
Last active January 10, 2017 19:10
Show Gist options
  • Save etrunko/c6a38e5b84227e06e092a16e7df5fe67 to your computer and use it in GitHub Desktop.
Save etrunko/c6a38e5b84227e06e092a16e7df5fe67 to your computer and use it in GitHub Desktop.
From 3d54496e793d83cb501fbc50580b0232d5b1d59b Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <eblima@gmail.com>
Date: Thu, 7 Apr 2016 11:33:54 -0300
Subject: [PATCH] Implement undo tab close
Signed-off-by: Eduardo Lima (Etrunko) <eblima@gmail.com>
---
src/common/hexchat.h | 1 +
src/common/server.c | 3 +++
src/fe-gtk/fkeys.c | 18 ++++++++++++++++--
src/fe-gtk/maingui.c | 31 +++++++++++++++++++++++++++++++
src/fe-gtk/maingui.h | 1 +
5 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/src/common/hexchat.h b/src/common/hexchat.h
index 38a3e83..0f472e9 100644
--- a/src/common/hexchat.h
+++ b/src/common/hexchat.h
@@ -540,6 +540,7 @@ typedef struct server
GIConv write_converter; /* iconv converter for converting from UTF-8 to server encoding. */
GSList *favlist; /* list of channels & keys to join */
+ GQueue *closed_channels; /* keeps track of recently closed channels, to be reopened with Ctrl+Shift+Tab */
unsigned int motd_skipped:1;
unsigned int connected:1;
diff --git a/src/common/server.c b/src/common/server.c
index 1ed90d0..9427464 100644
--- a/src/common/server.c
+++ b/src/common/server.c
@@ -1892,6 +1892,9 @@ server_free (server *serv)
if (serv->favlist)
g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free);
+
+ if (serv->closed_channels)
+ g_queue_free_full (serv->closed_channels, g_free);
#ifdef USE_OPENSSL
if (serv->ctx)
_SSL_context_free (serv->ctx);
diff --git a/src/fe-gtk/fkeys.c b/src/fe-gtk/fkeys.c
index 7ed75b7..8814777 100644
--- a/src/fe-gtk/fkeys.c
+++ b/src/fe-gtk/fkeys.c
@@ -70,7 +70,7 @@ void key_action_tab_clean (void);
*/
/* Remember that the *number* of actions is this *plus* 1 --AGL */
-#define KEY_MAX_ACTIONS 14
+#define KEY_MAX_ACTIONS 15
struct key_binding
{
@@ -132,6 +132,9 @@ static int key_action_move_tab_family_right (GtkWidget * wid, GdkEventKey * evt,
static int key_action_put_history (GtkWidget * wid, GdkEventKey * evt,
char *d1, char *d2,
struct session *sess);
+static int key_action_undo_tab_close (GtkWidget * wid, GdkEventKey * evt,
+ char *d1, char *d2,
+ struct session *sess);
static GSList *keybind_list = NULL;
@@ -167,6 +170,8 @@ static const struct key_action key_actions[KEY_MAX_ACTIONS + 1] = {
N_("This command moves the current tab family to the right")},
{key_action_put_history, "Push input line into history",
N_("Push input line into history but doesn't send to server")},
+ {key_action_undo_tab_close, "Undo tab close",
+ N_("Undo tab close")},
};
#define default_kb_cfg \
@@ -208,7 +213,8 @@ static const struct key_action key_actions[KEY_MAX_ACTIONS + 1] = {
"ACCEL=<Alt>Right\nMove front tab right\nD1!\nD2!\n\n"\
"ACCEL=<Primary><Shift>Page_Up\nMove tab family left\nD1!\nD2!\n\n"\
"ACCEL=<Primary><Shift>Page_Down\nMove tab family right\nD1!\nD2!\n\n"\
- "ACCEL=F9\nRun Command\nD1:/GUI MENU TOGGLE\nD2!\n\n"
+ "ACCEL=F9\nRun Command\nD1:/GUI MENU TOGGLE\nD2!\n\n"\
+ "ACCEL=<Primary><Shift>t\nUndo tab close\nD1:!\nD2!\n\n"\
void
key_init ()
@@ -1769,6 +1775,14 @@ key_action_put_history (GtkWidget * wid, GdkEventKey * ent, char *d1,
return 2; /* -''- */
}
+static int
+key_action_undo_tab_close (GtkWidget * wid, GdkEventKey * ent, char *d1,
+ char *d2, struct session *sess)
+{
+ mg_undo_tab_close (sess);
+ return 2;
+}
+
/* -------- */
diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c
index 20edf1b..dec6f5e 100644
--- a/src/fe-gtk/maingui.c
+++ b/src/fe-gtk/maingui.c
@@ -1046,6 +1046,11 @@ mg_tab_close_cb (GtkWidget *dialog, gint arg1, session *sess)
}
}
+typedef struct closed_channel {
+ char channel[CHANLEN];
+ char key[64];
+} closed_channel;
+
void
mg_tab_close (session *sess)
{
@@ -1053,6 +1058,18 @@ mg_tab_close (session *sess)
GSList *list;
int i;
+ if (!hexchat_is_quitting && is_channel (sess->server, sess->channel))
+ {
+ closed_channel *chan = g_new0 (closed_channel, 1);
+ g_strlcpy (chan->channel, sess->channel, CHANLEN);
+ g_strlcpy (chan->key, sess->channelkey, 64);
+
+ if (!sess->server->closed_channels)
+ sess->server->closed_channels = g_queue_new();
+
+ g_queue_push_head (sess->server->closed_channels, chan);
+ }
+
if (chan_remove (sess->res->tab, FALSE))
{
sess->res->tab = NULL;
@@ -1084,6 +1101,20 @@ mg_tab_close (session *sess)
}
}
+void
+mg_undo_tab_close (session *sess)
+{
+ closed_channel *chan;
+
+ if (g_queue_is_empty (sess->server->closed_channels))
+ return;
+
+ chan = g_queue_pop_head (sess->server->closed_channels);
+ sess->server->p_join (sess->server, chan->channel, chan->key);
+
+ g_free(chan);
+}
+
static void
mg_menu_destroy (GtkWidget *menu, gpointer userdata)
{
diff --git a/src/fe-gtk/maingui.h b/src/fe-gtk/maingui.h
index 6099e6f..82ed6c1 100644
--- a/src/fe-gtk/maingui.h
+++ b/src/fe-gtk/maingui.h
@@ -39,6 +39,7 @@ void mg_set_access_icon (session_gui *gui, GdkPixbuf *pix, gboolean away);
void mg_apply_setup (void);
void mg_close_sess (session *);
void mg_tab_close (session *sess);
+void mg_undo_tab_close (session *sess);
void mg_detach (session *sess, int mode);
void mg_progressbar_create (session_gui *gui);
void mg_progressbar_destroy (session_gui *gui);
--
2.9.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment