summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcos <cos>2013-05-24 18:55:31 +0200
committercos <cos>2013-05-26 20:31:42 +0200
commitd3793dba2a57d2512ca0a7987b3385986ec2c9ea (patch)
tree953a2510d92495a9625878c7954d9d6c7af4b3d7
parent472a958a2ce149313239fb5eb4244f7607887b31 (diff)
downloadratpoison-cr/implement_gnumber-with_winliststyle.zip
Adapt group bar to be updated on group number or name change.cr/implement_gnumber-with_winliststyle
-rw-r--r--src/actions.c79
-rw-r--r--src/bar.c60
-rw-r--r--src/bar.h2
-rw-r--r--src/group.c55
-rw-r--r--src/group.h2
5 files changed, 142 insertions, 56 deletions
diff --git a/src/actions.c b/src/actions.c
index 20f4063..3f9691e 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -5118,9 +5118,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);
@@ -5132,6 +5131,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);
}
@@ -5154,65 +5157,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 25d9a46..d9982c2 100644
--- a/src/bar.c
+++ b/src/bar.c
@@ -40,7 +40,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;
@@ -104,6 +105,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)
{
@@ -172,6 +198,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;
@@ -207,6 +238,33 @@ 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);
+
+ if (defaults.window_list_style == STYLE_ROW)
+ {
+ get_group_list (NULL, bar_buffer, &mark_start, &mark_end);
+ marked_message_internal (sbuf_get (bar_buffer), mark_start, mark_end);
+ }
+ else
+ {
+ 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 e882e8d..2bbfead 100644
--- a/src/group.c
+++ b/src/group.c
@@ -66,6 +66,61 @@ group_get_numset(void)
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 = '-';
+
+ /* A hack, pad the group with a space at the beginning and end
+ if there is no delimiter. */
+ if (!delim)
+ sbuf_concat (buffer, " ");
+
+ fmt = xsprintf ("%d%c%s", cur->number, separator, cur->name);
+ sbuf_concat (buffer, fmt);
+ free (fmt);
+
+ /* A hack, pad the group with a space at the beginning and end
+ if there is no delimiter. */
+ if (!delim)
+ sbuf_concat (buffer, " ");
+
+ /* Only put the delimiter between the group, and not after the the last
+ group. */
+ if (delim && 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 015bbac..1081043 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);
+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);