MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "module.h"
#include "commands.h"
#include "misc.h"
#include "servers.h"
+#include "settings.h"
#include "levels.h"
type = module_find_id_str("WINDOW ITEM TYPE", item->type);
printformat_window(win, MSGLEVEL_CLIENTCRAP,
TXT_WINDOW_INFO_ITEM,
- type == NULL ? "??" : type, item->name,
+ type == NULL ? "??" : type,
+ item->visible_name,
item->server == NULL ? "" :
item->server->tag);
}
command_runsub("window", data, server, item);
}
-/* SYNTAX: WINDOW NEW [hide] */
+/* SYNTAX: WINDOW NEW [HIDDEN|SPLIT] */
static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item)
{
WINDOW_REC *window;
g_return_if_fail(data != NULL);
- type = (g_strncasecmp(data, "hid", 3) == 0 || g_strcasecmp(data, "tab") == 0) ? 1 :
- (g_strcasecmp(data, "split") == 0 ? 2 : 0);
+ type = (g_ascii_strncasecmp(data, "hid", 3) == 0 || g_ascii_strcasecmp(data, "tab") == 0) ? 1 :
+ (g_ascii_strcasecmp(data, "split") == 0 ? 2 : 0);
signal_emit("gui window create override", 1, GINT_TO_POINTER(type));
window = window_create(NULL, FALSE);
window_change_server(window, server);
}
-/* SYNTAX: WINDOW CLOSE [<first> [<last>] */
+/* SYNTAX: WINDOW CLOSE [<first> [<last>]] */
static void cmd_window_close(const char *data)
{
GSList *tmp, *destroys;
window_set_active(window);
}
-/* return the first window number with the highest activity */
-static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
+/**
+ * return the window with the highest activity
+ *
+ * If ignore_refnum is true, the most recently active window with the highest
+ * activity will be returned. If ignore_refnum is false, the refnum will be used
+ * to break ties between windows with equally high activity.
+ */
+static WINDOW_REC *window_highest_activity(WINDOW_REC *window,
+ int ignore_refnum)
{
WINDOW_REC *rec, *max_win;
GSList *tmp;
- int max_act, through;
+ int max_act, max_ref, through;
g_return_val_if_fail(window != NULL, NULL);
- max_win = NULL; max_act = 0; through = FALSE;
+ max_win = NULL; max_act = 0; max_ref = 0; through = FALSE;
tmp = g_slist_find(windows, window);
for (;; tmp = tmp->next) {
rec = tmp->data;
- if (rec->data_level > 0 && max_act < rec->data_level) {
+ /* ignore refnum */
+ if (ignore_refnum &&
+ rec->data_level > 0 && max_act < rec->data_level) {
max_act = rec->data_level;
max_win = rec;
}
+
+ /* windows with lower refnums break ties */
+ else if (!ignore_refnum &&
+ rec->data_level > 0 &&
+ (rec->data_level > max_act ||
+ (rec->data_level == max_act && rec->refnum < max_ref))) {
+ max_act = rec->data_level;
+ max_win = rec;
+ max_ref = rec->refnum;
+ }
}
return max_win;
}
+static inline int is_nearer(int r1, int r2)
+{
+ int a = r2 < active_win->refnum;
+ int b = r1 < r2;
+
+ if (r1 > active_win->refnum)
+ return a || b;
+ else
+ return a && b;
+}
+
+static WINDOW_REC *window_find_item_cycle(SERVER_REC *server, const char *name)
+{
+ WINDOW_REC *rec, *win;
+ GSList *tmp;
+
+ win = NULL;
+
+ tmp = g_slist_find(windows, active_win);
+ tmp = tmp->next;
+ for (;; tmp = tmp->next) {
+ if (tmp == NULL)
+ tmp = windows;
+
+ if (tmp->data == active_win)
+ break;
+
+ rec = tmp->data;
+
+ if (window_item_find_window(rec, server, name) != NULL &&
+ (win == NULL || is_nearer(rec->refnum, win->refnum))) {
+ win = rec;
+ if (server != NULL) break;
+ }
+ }
+
+ return win;
+}
+
/* SYNTAX: WINDOW GOTO active|<number>|<name> */
static void cmd_window_goto(const char *data)
{
WINDOW_REC *window;
+ char *target;
+ void *free_arg;
g_return_if_fail(data != NULL);
return;
}
- if (g_strcasecmp(data, "active") == 0)
- window = window_highest_activity(active_win);
- else
- window = window_find_item(active_win->active_server, data);
+ if (!cmd_get_params(data, &free_arg, 1, &target))
+ return;
+
+ if (g_ascii_strcasecmp(target, "active") == 0)
+ window = window_highest_activity(active_win,
+ settings_get_bool("active_window_ignore_refnum"));
+ else {
+ window = window_find_name(target);
+ if (window == NULL && active_win->active_server != NULL)
+ window = window_find_item_cycle(active_win->active_server, target);
+ if (window == NULL)
+ window = window_find_item_cycle(NULL, target);
+ }
if (window != NULL)
window_set_active(window);
+
+ cmd_params_free(free_arg);
}
/* SYNTAX: WINDOW NEXT */
if (*data == '\0')
set = active_win->immortal;
- else if (g_strcasecmp(data, "ON") == 0)
+ else if (g_ascii_strcasecmp(data, "ON") == 0)
set = TRUE;
- else if (g_strcasecmp(data, "OFF") == 0)
+ else if (g_ascii_strcasecmp(data, "OFF") == 0)
set = FALSE;
- else if (g_strcasecmp(data, "TOGGLE") == 0)
+ else if (g_ascii_strcasecmp(data, "TOGGLE") == 0)
set = !active_win->immortal;
else {
printformat_window(active_win, MSGLEVEL_CLIENTERROR,
if (*tag == '\0')
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
server = server_find_tag(tag);
+ if (server == NULL)
+ server = server_find_lookup_tag(tag);
if (g_hash_table_lookup(optlist, "unsticky") != NULL &&
active_win->servertag != NULL) {
{
WI_ITEM_REC *item;
GSList *tmp;
+ void *free_arg;
+ char *target;
+
+ if (!cmd_get_params(data, &free_arg, 1, &target))
+ return;
- if (is_numeric(data, '\0')) {
+ if (is_numeric(target, '\0')) {
/* change to specified number */
- tmp = g_slist_nth(active_win->items, atoi(data)-1);
+ tmp = g_slist_nth(active_win->items, atoi(target)-1);
item = tmp == NULL ? NULL : tmp->data;
} else {
- item = window_item_find_window(active_win, server, data);
+ item = window_item_find_window(active_win, server, target);
}
if (item != NULL)
window_item_set_active(active_win, item);
+
+ cmd_params_free(free_arg);
}
/* SYNTAX: WINDOW ITEM MOVE <number>|<name> */
/* SYNTAX: WINDOW NAME <name> */
static void cmd_window_name(const char *data)
{
- if (window_find_name(data) == NULL)
+ WINDOW_REC *win;
+
+ win = window_find_name(data);
+ if (win == NULL || win == active_win)
window_set_name(active_win, data);
else if (active_win->name == NULL ||
strcmp(active_win->name, data) != 0) {
window_refnums_move_right(active_win);
}
-/* SYNTAX: WINDOW MOVE <number>|<direction> */
-static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+static void active_window_move_to(int new_refnum)
{
- int new_refnum, refnum;
-
- if (!is_numeric(data, 0)) {
- command_runsub("window move", data, server, item);
- return;
- }
+ int refnum;
- new_refnum = atoi(data);
if (new_refnum > active_win->refnum) {
for (;;) {
refnum = window_refnum_next(active_win->refnum, FALSE);
}
}
+/* SYNTAX: WINDOW MOVE FIRST */
+static void cmd_window_move_first(void)
+{
+ active_window_move_to(1);
+}
+
+/* SYNTAX: WINDOW MOVE LAST */
+static void cmd_window_move_last(void)
+{
+ active_window_move_to(windows_refnum_last());
+}
+
+/* SYNTAX: WINDOW MOVE <number>|<direction> */
+static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+ if (!is_numeric(data, 0)) {
+ command_runsub("window move", data, server, item);
+ return;
+ }
+
+ active_window_move_to(atoi(data));
+}
+
/* SYNTAX: WINDOW LIST */
static void cmd_window_list(void)
{
levelstr = bits2level(rec->level);
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_WINDOWLIST_LINE,
rec->refnum, rec->name == NULL ? "" : rec->name,
- rec->active == NULL ? "" : rec->active->name,
+ rec->active == NULL ? "" : rec->active->visible_name,
rec->active_server == NULL ? "" : ((SERVER_REC *) rec->active_server)->tag,
levelstr);
g_free(levelstr);
list = g_slist_remove(list, list->data);
}
- active_win = old;
+ if (g_slist_find(windows, old) != NULL)
+ active_win = old;
}
void window_commands_init(void)
{
+ settings_add_bool("lookandfeel", "active_window_ignore_refnum", TRUE);
+
command_bind("window", NULL, (SIGNAL_FUNC) cmd_window);
command_bind("window new", NULL, (SIGNAL_FUNC) cmd_window_new);
command_bind("window close", NULL, (SIGNAL_FUNC) cmd_window_close);
command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move);
command_bind("window move prev", NULL, (SIGNAL_FUNC) cmd_window_move_prev);
command_bind("window move next", NULL, (SIGNAL_FUNC) cmd_window_move_next);
+ command_bind("window move first", NULL, (SIGNAL_FUNC) cmd_window_move_first);
+ command_bind("window move last", NULL, (SIGNAL_FUNC) cmd_window_move_last);
command_bind("window list", NULL, (SIGNAL_FUNC) cmd_window_list);
command_bind("window theme", NULL, (SIGNAL_FUNC) cmd_window_theme);
command_bind("layout", NULL, (SIGNAL_FUNC) cmd_layout);
command_unbind("window move", (SIGNAL_FUNC) cmd_window_move);
command_unbind("window move prev", (SIGNAL_FUNC) cmd_window_move_prev);
command_unbind("window move next", (SIGNAL_FUNC) cmd_window_move_next);
+ command_unbind("window move first", (SIGNAL_FUNC) cmd_window_move_first);
+ command_unbind("window move last", (SIGNAL_FUNC) cmd_window_move_last);
command_unbind("window list", (SIGNAL_FUNC) cmd_window_list);
command_unbind("window theme", (SIGNAL_FUNC) cmd_window_theme);
command_unbind("layout", (SIGNAL_FUNC) cmd_layout);