From 41c4248c0bdb582df012a81022dcbcc30780c1cb Mon Sep 17 00:00:00 2001 From: cos Date: Fri, 24 May 2013 18:55:31 +0200 Subject: Adapt group bar to be updated on group number or name change. --- src/actions.c | 79 ++++++++++++++++++----------------------------------------- src/bar.c | 52 ++++++++++++++++++++++++++++++++++++++- src/bar.h | 2 ++ src/group.c | 45 ++++++++++++++++++++++++++++++++++ src/group.h | 2 ++ 5 files changed, 124 insertions(+), 56 deletions(-) diff --git a/src/actions.c b/src/actions.c index 72d1507..1a12d96 100644 --- a/src/actions.c +++ b/src/actions.c @@ -5131,9 +5131,8 @@ cmd_gnumber (int interactive UNUSED, struct cmdarg **args) /* resort the the window in the list */ group_resort_group (g); -/* FIXME Implement updating of groups bar. */ -// /* Update the window list. */ -// update_window_names (win->win->scr, defaults.window_fmt); + /* Update the group list. */ + update_group_names (current_screen()); } return cmdret_new (RET_SUCCESS, NULL); @@ -5145,6 +5144,10 @@ cmd_grename (int interactive UNUSED, struct cmdarg **args) if (groups_find_group_by_name (ARG_STRING (0), 1)) return cmdret_new (RET_FAILURE, "grename: duplicate group name"); group_rename (rp_current_group, ARG_STRING(0)); + + /* Update the group list. */ + update_group_names (current_screen()); + return cmdret_new (RET_SUCCESS, NULL); } @@ -5167,65 +5170,31 @@ cmd_gselect (int interactive, struct cmdarg **args) cmdret * cmd_groups (int interactive, struct cmdarg **args UNUSED) { - rp_group *cur; - int mark_start = 0, mark_end = 0; - struct sbuf *buffer; - rp_group *last; - - last = group_last_group (); - buffer = sbuf_new (0); - - /* Generate the string. */ - list_for_each_entry (cur, &rp_groups, node) - { - char *fmt; - char separator; - - if (cur == rp_current_group) - mark_start = strlen (sbuf_get (buffer)); - - /* Pad start of group name with a space for row - style. non-Interactive always gets a column.*/ - if (defaults.window_list_style == STYLE_ROW && interactive) - sbuf_concat (buffer, " "); - - if(cur == rp_current_group) - separator = '*'; - else if(cur == last) - separator = '+'; - else - separator = '-'; - - fmt = xsprintf ("%d%c%s", cur->number, separator, cur->name); - sbuf_concat (buffer, fmt); - free (fmt); - - /* Pad end of group name with a space for row style. */ - if (defaults.window_list_style == STYLE_ROW && interactive) - { - sbuf_concat (buffer, " "); - } - else - { - if (cur->node.next != &rp_groups) - sbuf_concat (buffer, "\n"); - } - - if (cur == rp_current_group) - mark_end = strlen (sbuf_get (buffer)); - } + struct sbuf *group_list = NULL; + int dummy; + rp_screen *s; - /* Display it or return it. */ if (interactive) { - marked_message (sbuf_get (buffer), mark_start, mark_end); - sbuf_free (buffer); + s = current_screen (); + /* This is a yukky hack. If the bar already hidden then show the + bar. This handles the case when msgwait is 0 (the bar sticks) + and the user uses this command to toggle the bar on and + off. OR the timeout is >0 then show the bar. Which means, + always show the bar if msgwait is >0 which fixes the case + when a command in the prefix hook displays the bar. */ + if (!hide_bar (s) || defaults.bar_timeout > 0) show_group_bar (s); + return cmdret_new (RET_SUCCESS, NULL); } else { - cmdret *ret = cmdret_new (RET_SUCCESS, "%s", sbuf_get(buffer)); - sbuf_free(buffer); + cmdret *ret; + + group_list = sbuf_new (0); + get_group_list ("\n", group_list, &dummy, &dummy); + ret = cmdret_new (RET_SUCCESS, "%s", sbuf_get (group_list)); + sbuf_free (group_list); return ret; } } diff --git a/src/bar.c b/src/bar.c index 4ec3e19..e81d9ae 100644 --- a/src/bar.c +++ b/src/bar.c @@ -41,7 +41,8 @@ /* Possible values for bar_is_raised status. */ #define BAR_IS_HIDDEN 0 #define BAR_IS_WINDOW_LIST 1 -#define BAR_IS_MESSAGE 2 +#define BAR_IS_GROUP_LIST 2 +#define BAR_IS_MESSAGE 3 /* A copy of the last message displayed in the message bar. */ static char *last_msg = NULL; @@ -105,6 +106,31 @@ show_bar (rp_screen *s, char *fmt) return 0; } +/* Show group listing in bar. */ +int +show_group_bar (rp_screen *s) +{ + if (!s->bar_is_raised) + { + s->bar_is_raised = BAR_IS_GROUP_LIST; + XMapRaised (dpy, s->bar_window); + update_group_names (s); + + /* Switch to the default colormap */ + if (current_window()) + XUninstallColormap (dpy, current_window()->colormap); + XInstallColormap (dpy, s->def_cmap); + + reset_alarm(); + return 1; + } + + /* If the bar is raised we still need to display the window + names. */ + update_group_names (s); + return 0; +} + int bar_x (rp_screen *s, int width) { @@ -173,6 +199,11 @@ update_bar (rp_screen *s) return; } + if (s->bar_is_raised == BAR_IS_GROUP_LIST) { + update_group_names (s); + return; + } + if (s->bar_is_raised == BAR_IS_HIDDEN) return; @@ -210,6 +241,25 @@ update_window_names (rp_screen *s, char *fmt) sbuf_free (bar_buffer); } +/* Note that we use marked_message_internal to avoid resetting the + alarm. */ +void +update_group_names (rp_screen *s) +{ + struct sbuf *bar_buffer; + int mark_start = 0; + int mark_end = 0; + + if (s->bar_is_raised != BAR_IS_GROUP_LIST) return; + + bar_buffer = sbuf_new (0); + + get_group_list ("\n", bar_buffer, &mark_start, &mark_end); + marked_message_internal (sbuf_get (bar_buffer), mark_start, mark_end); + + sbuf_free (bar_buffer); +} + void message (char *s) { diff --git a/src/bar.h b/src/bar.h index 2156802..0d70644 100644 --- a/src/bar.h +++ b/src/bar.h @@ -23,8 +23,10 @@ #define _RATPOISON_BAR_H 1 void update_window_names (rp_screen *s, char *fmt); +void update_group_names (rp_screen *s); void update_bar (rp_screen *s); int show_bar (rp_screen *s, char *fmt); +int show_group_bar (rp_screen *s); int hide_bar (rp_screen *s); int bar_y (rp_screen *s, int height); int bar_x (rp_screen *s, int width); diff --git a/src/group.c b/src/group.c index cca95a2..f45877f 100644 --- a/src/group.c +++ b/src/group.c @@ -66,6 +66,51 @@ group_get_numset() return group_numset; } +/* get the group list and store it in buffer delimiting each window + with delim. mark_start and mark_end will be filled with the text + positions for the start and end of the current window. */ +void +get_group_list (char *delim, struct sbuf *buffer, + int *mark_start, int *mark_end) +{ + rp_group *cur; + + if (buffer == NULL) return; + + sbuf_clear (buffer); + + rp_group *last; + + last = group_last_group (); + + /* Generate the string. */ + list_for_each_entry (cur, &rp_groups, node) + { + char *fmt; + char separator; + + if (cur == rp_current_group) + *mark_start = strlen (sbuf_get (buffer)); + + if(cur == rp_current_group) + separator = '*'; + else if(cur == last) + separator = '+'; + else + separator = '-'; + + fmt = xsprintf ("%d%c%s", cur->number, separator, cur->name); + sbuf_concat (buffer, fmt); + free (fmt); + + if (cur->node.next != &rp_groups) + sbuf_concat (buffer, delim); + + if (cur == rp_current_group) + *mark_end = strlen (sbuf_get (buffer)); + } +} + rp_group * group_new (int number, char *name) { diff --git a/src/group.h b/src/group.h index e725208..7687dcb 100644 --- a/src/group.h +++ b/src/group.h @@ -40,6 +40,8 @@ void group_unmap_window (rp_group *g, rp_window *win); void groups_unmap_window (rp_window *win); struct numset *group_get_numset (); +void get_group_list (char *delim, struct sbuf *buffer, int *mark_start, + int *mark_end); rp_window *group_prev_window (rp_group *g, rp_window *win); rp_window *group_next_window (rp_group *g, rp_window *win); -- cgit v1.2.3