From b37fe23b99be98955dd28cba054ed421a37d0e72 Mon Sep 17 00:00:00 2001 From: TingPing Date: Tue, 25 Dec 2012 00:33:57 -0500 Subject: Add last activity keybinding from fedora --- src/common/hexchat.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/common/hexchat.h | 13 +++++ src/common/hexchatc.h | 3 ++ src/common/inbound.c | 3 ++ 4 files changed, 150 insertions(+) (limited to 'src/common') diff --git a/src/common/hexchat.c b/src/common/hexchat.c index 1aa5fe54..d71a0daa 100644 --- a/src/common/hexchat.c +++ b/src/common/hexchat.c @@ -77,6 +77,24 @@ GSList *usermenu_list = 0; GSList *urlhandler_list = 0; GSList *tabmenu_list = 0; +/* + * This array contains 5 double linked lists, one for each priority in the + * "interesting session" queue ("channel" stands for everything but + * SESS_DIALOG): + * + * [0] queries with hilight + * [1] queries + * [2] channels with hilight + * [3] channels with dialogue + * [4] channels with other data + * + * Each time activity happens the corresponding session is put at the + * beginning of one of the lists. The aim is to be able to switch to the + * session with the most important/recent activity. + */ +GList *sess_list_by_lastact[5] = {NULL, NULL, NULL, NULL, NULL}; + + static int in_hexchat_exit = FALSE; int hexchat_is_quitting = FALSE; /* command-line args */ @@ -103,6 +121,106 @@ SSL_CTX *ctx = NULL; pxProxyFactory *libproxy_factory; #endif +/* + * Update the priority queue of the "interesting sessions" + * (sess_list_by_lastact). + */ +void +lastact_update(session *sess) +{ + int newidx; + + /* Find the priority (for the order see before) */ + if (sess->type == SESS_DIALOG) + { + if (sess->nick_said) + newidx = LACT_QUERY_HI; + else if (sess->msg_said) + newidx = LACT_QUERY; + else if (sess->new_data) + newidx = LACT_QUERY; + else + newidx = LACT_NONE; + } + else + { + if (sess->nick_said) + newidx = LACT_CHAN_HI; + else if (sess->msg_said) + newidx = LACT_CHAN; + else if (sess->new_data) + newidx = LACT_CHAN_DATA; + else + newidx = LACT_NONE; + } + + /* Check if this update is a no-op */ + if (sess->lastact_idx == newidx && + ((newidx != LACT_NONE && sess->lastact_elem == sess_list_by_lastact[newidx]) || + (newidx == LACT_NONE))) + return; + + /* Remove from the old position (and, if no new position, return */ + else if (sess->lastact_idx != LACT_NONE && sess->lastact_elem) + { + sess_list_by_lastact[sess->lastact_idx] = g_list_remove_link( + sess_list_by_lastact[sess->lastact_idx], + sess->lastact_elem); + if (newidx == LACT_NONE) + { + sess->lastact_idx = newidx; + return; + } + } + + /* No previous position, allocate new */ + else if (!sess->lastact_elem) + sess->lastact_elem = g_list_prepend(sess->lastact_elem, sess); + + sess->lastact_idx = newidx; + sess_list_by_lastact[newidx] = g_list_concat( + sess->lastact_elem, sess_list_by_lastact[newidx]); +} + +/* + * Extract the first session from the priority queue of sessions with recent + * activity. Return NULL if no such session can be found. + * + * If filter is specified, skip a session if filter(session) returns 0. This + * can be used for UI-specific needs, e.g. in fe-gtk we want to filter out + * detached sessions. + */ +session * +lastact_getfirst(int (*filter) (session *sess)) +{ + int i; + session *sess = NULL; + GList *curitem; + + /* 5 is the number of priority classes LACT_ */ + for (i = 0; i < 5 && !sess; i++) + { + curitem = sess_list_by_lastact[i]; + while (curitem && !sess) + { + sess = g_list_nth_data(curitem, 0); + if (!sess || (filter && !filter(sess))) + { + sess = NULL; + curitem = g_list_next(curitem); + } + } + + if (sess) + { + sess_list_by_lastact[i] = g_list_remove_link(sess_list_by_lastact[i], curitem); + sess->lastact_idx = LACT_NONE; + } + } + + return sess; +} + int is_session (session * sess) { @@ -372,6 +490,9 @@ session_new (server *serv, char *from, int type, int focus) sess->text_logging = SET_DEFAULT; sess->text_scrollback = SET_DEFAULT; + sess->lastact_elem = NULL; + sess->lastact_idx = LACT_NONE; + if (from != NULL) safe_strcpy (sess->channel, from, CHANLEN); @@ -525,6 +646,16 @@ session_free (session *killsess) if (killsess->type == SESS_CHANNEL) userlist_free (killsess); + if (killsess->lastact_elem) + { + if (killsess->lastact_idx != LACT_NONE) + sess_list_by_lastact[killsess->lastact_idx] = g_list_delete_link( + sess_list_by_lastact[killsess->lastact_idx], + killsess->lastact_elem); + else + g_list_free_1(killsess->lastact_elem); + } + exec_notify_kill (killsess); log_close (killsess); diff --git a/src/common/hexchat.h b/src/common/hexchat.h index d84e2761..010414fd 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -348,6 +348,15 @@ struct hexchatprefs #define SET_ON 1 #define SET_DEFAULT 2 /* use global setting */ +/* Priorities in the "interesting sessions" priority queue + * (see xchat.c:sess_list_by_lastact) */ +#define LACT_NONE -1 /* no queues */ +#define LACT_QUERY_HI 0 /* query with hilight */ +#define LACT_QUERY 1 /* query with messages */ +#define LACT_CHAN_HI 2 /* channel with hilight */ +#define LACT_CHAN 3 /* channel with messages */ +#define LACT_CHAN_DATA 4 /* channel with other data */ + /* Moved from fe-gtk for use in outbound.c as well -- */ typedef enum gtk_xtext_search_flags_e { case_match = 1, @@ -406,6 +415,10 @@ typedef struct session int type; /* SESS_* */ + GList *lastact_elem; /* our GList element in sess_list_by_lastact */ + int lastact_idx; /* the sess_list_by_lastact[] index of the list we're in. + * For valid values, see defines of LACT_*. */ + int new_data:1; /* new data avail? (purple tab) */ int nick_said:1; /* your nick mentioned? (blue tab) */ int msg_said:1; /* new msg available? (red tab) */ diff --git a/src/common/hexchatc.h b/src/common/hexchatc.h index 207a97cd..9650dc10 100644 --- a/src/common/hexchatc.h +++ b/src/common/hexchatc.h @@ -25,10 +25,13 @@ extern GSList *ignore_list; extern GSList *usermenu_list; extern GSList *urlhandler_list; extern GSList *tabmenu_list; +extern GList *sess_list_by_lastact[]; session * find_channel (server *serv, char *chan); session * find_dialog (server *serv, char *nick); session * new_ircwindow (server *serv, char *name, int type, int focus); +void lastact_update (session * sess); +session * lastact_getfirst (int (*filter) (session *sess)); int is_session (session * sess); void session_free (session *killsess); void lag_check (void); diff --git a/src/common/inbound.c b/src/common/inbound.c index 7b4c67e8..c86caf24 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -302,6 +302,7 @@ is_hilight (char *from, char *text, session *sess, server *serv) g_free (text); if (sess != current_tab) sess->nick_said = TRUE; + lastact_update (sess); fe_set_hilight (sess); return 1; } @@ -364,6 +365,7 @@ inbound_action (session *sess, char *chan, char *from, char *ip, char *text, int sess->msg_said = TRUE; sess->new_data = FALSE; } + lastact_update (sess); } user = userlist_find (sess, from); @@ -421,6 +423,7 @@ inbound_chanmsg (server *serv, session *sess, char *chan, char *from, char *text { sess->msg_said = TRUE; sess->new_data = FALSE; + lastact_update (sess); } user = userlist_find (sess, from); -- cgit 1.4.1 From 24ce347472942653f8a8f1828ea817498b54bfc6 Mon Sep 17 00:00:00 2001 From: TingPing Date: Sat, 5 Jan 2013 16:23:34 -0500 Subject: fix if statement --- src/common/inbound.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/common') diff --git a/src/common/inbound.c b/src/common/inbound.c index c86caf24..9d21e25a 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -301,8 +301,10 @@ is_hilight (char *from, char *text, session *sess, server *serv) { g_free (text); if (sess != current_tab) + { sess->nick_said = TRUE; lastact_update (sess); + } fe_set_hilight (sess); return 1; } -- cgit 1.4.1 From 2af44e02bfc211d281cc51a86d55032134e4da31 Mon Sep 17 00:00:00 2001 From: Richard Hitt Date: Mon, 7 Jan 2013 11:50:54 -0800 Subject: Simplification of new code -- eliminate member lastact_elem --- src/common/hexchat.c | 85 ++++++++++++++++------------------------------------ src/common/hexchat.h | 1 - src/fe-gtk/fkeys.c | 2 +- 3 files changed, 27 insertions(+), 61 deletions(-) (limited to 'src/common') diff --git a/src/common/hexchat.c b/src/common/hexchat.c index d71a0daa..4a3e7a47 100644 --- a/src/common/hexchat.c +++ b/src/common/hexchat.c @@ -128,58 +128,31 @@ pxProxyFactory *libproxy_factory; void lastact_update(session *sess) { - int newidx; - - /* Find the priority (for the order see before) */ - if (sess->type == SESS_DIALOG) - { - if (sess->nick_said) - newidx = LACT_QUERY_HI; - else if (sess->msg_said) - newidx = LACT_QUERY; - else if (sess->new_data) - newidx = LACT_QUERY; - else - newidx = LACT_NONE; - } - else - { - if (sess->nick_said) - newidx = LACT_CHAN_HI; - else if (sess->msg_said) - newidx = LACT_CHAN; - else if (sess->new_data) - newidx = LACT_CHAN_DATA; - else - newidx = LACT_NONE; - } - - /* Check if this update is a no-op */ - if (sess->lastact_idx == newidx && - ((newidx != LACT_NONE && sess->lastact_elem == sess_list_by_lastact[newidx]) || - (newidx == LACT_NONE))) + int oldidx = sess->lastact_idx; + int newidx = LACT_NONE; + int dia = (sess->type == SESS_DIALOG); + + if (sess->nick_said) + newidx = dia? LACT_QUERY_HI: LACT_CHAN_HI; + else if (sess->msg_said) + newidx = dia? LACT_QUERY: LACT_CHAN; + else if (sess->new_data) + newidx = dia? LACT_QUERY: LACT_CHAN_DATA; + + /* If already first at the right position, just return */ + if (oldidx == newidx && + (newidx == LACT_NONE || g_list_index(sess_list_by_lastact[newidx], sess) == 0)) return; - /* Remove from the old position (and, if no new position, return */ - else if (sess->lastact_idx != LACT_NONE && sess->lastact_elem) - { - sess_list_by_lastact[sess->lastact_idx] = g_list_remove_link( - sess_list_by_lastact[sess->lastact_idx], - sess->lastact_elem); - if (newidx == LACT_NONE) - { - sess->lastact_idx = newidx; - return; - } - } - - /* No previous position, allocate new */ - else if (!sess->lastact_elem) - sess->lastact_elem = g_list_prepend(sess->lastact_elem, sess); + /* Remove from the old position */ + if (oldidx != LACT_NONE) + sess_list_by_lastact[oldidx] = g_list_remove(sess_list_by_lastact[oldidx], sess); + /* Add at the new position */ sess->lastact_idx = newidx; - sess_list_by_lastact[newidx] = g_list_concat( - sess->lastact_elem, sess_list_by_lastact[newidx]); + if (newidx != LACT_NONE) + sess_list_by_lastact[newidx] = g_list_prepend(sess_list_by_lastact[newidx], sess); + return; } /* @@ -213,7 +186,7 @@ lastact_getfirst(int (*filter) (session *sess)) if (sess) { - sess_list_by_lastact[i] = g_list_remove_link(sess_list_by_lastact[i], curitem); + sess_list_by_lastact[i] = g_list_remove(sess_list_by_lastact[i], sess); sess->lastact_idx = LACT_NONE; } } @@ -490,7 +463,6 @@ session_new (server *serv, char *from, int type, int focus) sess->text_logging = SET_DEFAULT; sess->text_scrollback = SET_DEFAULT; - sess->lastact_elem = NULL; sess->lastact_idx = LACT_NONE; if (from != NULL) @@ -610,6 +582,7 @@ session_free (session *killsess) server *killserv = killsess->server; session *sess; GSList *list; + int oldidx; plugin_emit_dummy_print (killsess, "Close Context"); @@ -646,15 +619,9 @@ session_free (session *killsess) if (killsess->type == SESS_CHANNEL) userlist_free (killsess); - if (killsess->lastact_elem) - { - if (killsess->lastact_idx != LACT_NONE) - sess_list_by_lastact[killsess->lastact_idx] = g_list_delete_link( - sess_list_by_lastact[killsess->lastact_idx], - killsess->lastact_elem); - else - g_list_free_1(killsess->lastact_elem); - } + oldidx = killsess->lastact_idx; + if (oldidx != LACT_NONE) + sess_list_by_lastact[oldidx] = g_list_remove(sess_list_by_lastact[oldidx], killsess); exec_notify_kill (killsess); diff --git a/src/common/hexchat.h b/src/common/hexchat.h index 010414fd..b242ae87 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -415,7 +415,6 @@ typedef struct session int type; /* SESS_* */ - GList *lastact_elem; /* our GList element in sess_list_by_lastact */ int lastact_idx; /* the sess_list_by_lastact[] index of the list we're in. * For valid values, see defines of LACT_*. */ diff --git a/src/fe-gtk/fkeys.c b/src/fe-gtk/fkeys.c index 12db429f..3bcee665 100644 --- a/src/fe-gtk/fkeys.c +++ b/src/fe-gtk/fkeys.c @@ -1202,7 +1202,7 @@ key_action_handle_command (GtkWidget * wid, GdkEventKey * evt, char *d1, /* * Check if the given session is inside the main window. This predicate - * is passed to lastact_pop as a way to filter out detached sessions. + * is passed to lastact_getfirst() as a way to filter out detached sessions. * XXX: Consider moving this in a different file? */ static int -- cgit 1.4.1