Discussion:
patch for setting pane background color
J Raynor
2015-02-11 06:57:22 UTC
Permalink
I’ve attached a patch that allows you to set the foreground and
background color for a pane. The way it works is that, when tmux
writes to the screen, if it would have written with the terminal’s
default color, but you’ve set the pane’s default color option, then
it’ll use that color instead. Doing it this way means this feature
won’t interfere with terminal applications that use setab/setaf.
Also, when you set the background color with this patch, it changes
the background for the whole pane, and not just for the parts of the
pane that have text on them, which is how tmux’s current
implementation of setab behaves.

The patch adds a colour-pane command (note the spelling), with an
alias of colourp. You specify colors with the style syntax, though
only the fg/bg parts of a style are used. Attributes like dim,
underline, etc. are ignored. Here’s a brief usage description:

#Set the default fg/bg colors for existing and new panes in this window
colourp -W bg=red,fg=white

#Whenever a pane becomes the active pane, make its background green
colourp -A bg=green

#Explicitly set the colors for a pane, overriding anything set with -W or -A
colourp -P bg=colour113,fg=black

#Use the empty string to unset a style
colourp -W “"

#See what colors are set
colourp -g


The command also takes the usual -t flag so you can specify a
different window/pane besides the current one.

If you have a lot of windows and panes, being able to set a color can
help distinguish what the window/pane is for as you switch between
them. Being able to set a color for the active pane makes it much
clearer which pane is active.

I don’t think I’ve seen anyone request this feature, but I thought I’d
submit it anyway to see what others thought.
Thomas Adam
2015-02-11 10:15:15 UTC
Permalink
I’ve attached a patch that allows you to set the foreground and
background color for a pane. The way it works is that, when tmux
writes to the screen, if it would have written with the terminal’s
default color, but you’ve set the pane’s default color option, then
it’ll use that color instead. Doing it this way means this feature
won’t interfere with terminal applications that use setab/setaf.
But might make tmux flicker quite a bit over SSH or on slower terminals.
The patch adds a colour-pane command (note the spelling), with an
It should be that; I'm British, and that's the current spelling of the other
tmux commands which have colour in their name.
alias of colourp. You specify colors with the style syntax, though
only the fg/bg parts of a style are used. Attributes like dim,
Not speaking for the impetus of this change, I don't see that we need a
separate command for this; it should work like any other setting.
+ str = args->argv[0];
+ if (*str == '\0')
+ gc = NULL;
+ else {
+ gc = xmalloc(sizeof *gc);
+ memcpy(gc, &grid_default_cell, sizeof *gc);
+ ret = style_parse(&grid_default_cell, gc, str);
I wouldn't bother allocating gc on the heap here. Just pass it through as
&gc.

-- Thomas Adam
J Raynor
2015-02-12 01:09:05 UTC
Permalink
Post by Thomas Adam
But might make tmux flicker quite a bit over SSH or on slower terminals.
I don't think it'll cause flicker. Tmux tries to limit how much needs
to be written to the terminal. I did a quick login test with trickle,
setting upload/download speeds to 1K, 2K, 8K, and 16K. I don't see
any flickering. Redrawing the screen is slow at those speeds, but
that's true even if you don't use colored panes. But once the screen
is redrawn, such as when you complete switching panes, it appears to
behave well.
Post by Thomas Adam
Post by J Raynor
The patch adds a colour-pane command (note the spelling), with an
It should be that; I'm British, and that's the current spelling of the other
tmux commands which have colour in their name.
Right. I chose that spelling for consistency with the rest of tmux.
Post by Thomas Adam
Not speaking for the impetus of this change, I don't see that we need a
separate command for this; it should work like any other setting.
I thought so too, initially. But tmux doesn't have options for panes,
right? Just server, session, and window? It didn't seem to make
sense to try to cram pane-specific behavior into a window option. The
window and active-pane colors could be options, but if you've got to
add a command anyway for the pane...
Post by Thomas Adam
I wouldn't bother allocating gc on the heap here. Just pass it through as
&gc.
I need to allocate it from the heap because gc will get assigned to a
window or pane later on, so it needs to outlast the stack.
Thomas Sattler
2015-02-11 10:54:43 UTC
Permalink
Also, when you set the background color with this patch,
it changes the background for the whole pane, and not
just for the parts of the pane that have text on them
This seems not to be true when using colors like #c0c0c0
(I tested with latest tmux-git with tmux-colour.patch and
tmux-panecolors.patch applied).

$ tmux colourp -g
active-pane fg=red,bg=colour250
pane ""
window ""
I don’t think I’ve seen anyone request this feature, but
I thought I’d submit it anyway to see what others thought.
I did miss "colouring the active pane", I simply was to
lazy to ask. I like it!

Thomas
J Raynor
2015-02-11 18:31:20 UTC
Permalink
I was able to reproduce the problem. If you start tmux with the -2
flag, does the problem go away?

I've attached a new patch that fixes this problem without having to
pass the -2 flag.


On Wed, Feb 11, 2015 at 4:54 AM, Thomas Sattler
Post by Thomas Sattler
Also, when you set the background color with this patch,
it changes the background for the whole pane, and not
just for the parts of the pane that have text on them
This seems not to be true when using colors like #c0c0c0
(I tested with latest tmux-git with tmux-colour.patch and
tmux-panecolors.patch applied).
$ tmux colourp -g
active-pane fg=red,bg=colour250
pane ""
window ""
I don’t think I’ve seen anyone request this feature, but
I thought I’d submit it anyway to see what others thought.
I did miss "colouring the active pane", I simply was to
lazy to ask. I like it!
Thomas
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
Thomas Adam
2015-02-11 15:31:44 UTC
Permalink
I’ve attached a patch that allows you to set the foreground and
background color for a pane. The way it works is that, when tmux
writes to the screen, if it would have written with the terminal’s
default color, but you’ve set the pane’s default color option, then
it’ll use that color instead. Doing it this way means this feature
won’t interfere with terminal applications that use setab/setaf.
Also, when you set the background color with this patch, it changes
the background for the whole pane, and not just for the parts of the
pane that have text on them, which is how tmux’s current
implementation of setab behaves.
I've taken a very quick look at this over lunch, and have put additional
fixes/suggestions on top of your patch. The branch is here:

https://github.com/ThomasAdam/tmux/commits/jr/pane-colours

Have a look, tell me what you think. The cleanups are pretty trivial, but
reduces some of the copy/paste code churn.

-- Thomas Adam
John Krueger
2015-02-11 16:18:44 UTC
Permalink
I'm typically a lurker on this list, but this is something I'm
definitely excited to see get added!
--
John Krueger
Post by Thomas Adam
I’ve attached a patch that allows you to set the foreground and
background color for a pane. The way it works is that, when tmux
writes to the screen, if it would have written with the terminal’s
default color, but you’ve set the pane’s default color option, then
it’ll use that color instead. Doing it this way means this feature
won’t interfere with terminal applications that use setab/setaf.
Also, when you set the background color with this patch, it changes
the background for the whole pane, and not just for the parts of the
pane that have text on them, which is how tmux’s current
implementation of setab behaves.
I've taken a very quick look at this over lunch, and have put additional
https://github.com/ThomasAdam/tmux/commits/jr/pane-colours
Have a look, tell me what you think. The cleanups are pretty trivial, but
reduces some of the copy/paste code churn.
-- Thomas Adam
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is
your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take
a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
J Raynor
2015-02-12 05:17:24 UTC
Permalink
Post by Thomas Adam
I've taken a very quick look at this over lunch, and have put additional
https://github.com/ThomasAdam/tmux/commits/jr/pane-colours
Have a look, tell me what you think. The cleanups are pretty trivial, but
reduces some of the copy/paste code churn.
I took a look at your changes, and I think they do make things more
concise. I've updated my original patch since you made these updates,
so I can't take your changes as they are.

I'll work on an updated patch that incorporates essentially what
you've done, and I'll extend the idea to also simplify the BCE stuff I
recently added.
Nicholas Marriott
2015-02-11 17:33:57 UTC
Permalink
This will not work as it is on terminals which do not support BCE. To
make it do so you will pretty much have to make tmux support BCE :-).
I???ve attached a patch that allows you to set the foreground and
background color for a pane. The way it works is that, when tmux
writes to the screen, if it would have written with the terminal???s
default color, but you???ve set the pane???s default color option, then
it???ll use that color instead. Doing it this way means this feature
won???t interfere with terminal applications that use setab/setaf.
Also, when you set the background color with this patch, it changes
the background for the whole pane, and not just for the parts of the
pane that have text on them, which is how tmux???s current
implementation of setab behaves.
The patch adds a colour-pane command (note the spelling), with an
alias of colourp. You specify colors with the style syntax, though
only the fg/bg parts of a style are used. Attributes like dim,
#Set the default fg/bg colors for existing and new panes in this window
colourp -W bg=red,fg=white
#Whenever a pane becomes the active pane, make its background green
colourp -A bg=green
#Explicitly set the colors for a pane, overriding anything set with -W or -A
colourp -P bg=colour113,fg=black
#Use the empty string to unset a style
colourp -W ???"
#See what colors are set
colourp -g
The command also takes the usual -t flag so you can specify a
different window/pane besides the current one.
If you have a lot of windows and panes, being able to set a color can
help distinguish what the window/pane is for as you switch between
them. Being able to set a color for the active pane makes it much
clearer which pane is active.
I don???t think I???ve seen anyone request this feature, but I thought I???d
submit it anyway to see what others thought.
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..054447d 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,14 +18,28 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
* Display panes on a client.
+ *
+ * Set or get pane default fg/bg colours.
*/
+enum cmd_retval cmd_colour_pane_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
+const struct cmd_entry cmd_colour_pane_entry = {
+ "colour-pane", "colourp",
+ "gt:APW", 0, 1,
+ CMD_TARGET_PANE_USAGE " [-A|P|W] colour-style",
+ 0,
+ cmd_colour_pane_exec
+};
+
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
"t:", 0, 0,
@@ -47,3 +61,105 @@ cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL);
}
+
+enum cmd_retval
+cmd_colour_pane_exec(struct cmd *self, struct cmd_q *cmdq)
+{
+ struct args *args = self->args;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ int ret, nflags = 0;
+ struct grid_cell *gc;
+ const char *str;
+
+
+
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ if (args_has(args, 'g')) nflags++;
+ if (args_has(args, 'A')) nflags++;
+ if (args_has(args, 'P')) nflags++;
+ if (args_has(args, 'W')) nflags++;
+
+ if (nflags == 0 || nflags > 1) {
+ cmdq_error(cmdq, "need exactly 1 of -g, -A, -P, or -W");
+ return (CMD_RETURN_ERROR);
+ }
+
+ if (args_has(args, 'g')) {
+ if (args->argc > 0) {
+ cmdq_error(cmdq, "don't specify style with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ gc = wp->window->apcolgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "active-pane %s", str);
+
+
+ gc = wp->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "pane %s", str);
+
+
+ gc = wp->window->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "window %s", str);
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args->argc == 0) {
+ cmdq_error(cmdq, "need a style argument");
+ return (CMD_RETURN_ERROR);
+ }
+
+ str = args->argv[0];
+ if (*str == '\0')
+ gc = NULL;
+ else {
+ gc = xmalloc(sizeof *gc);
+ memcpy(gc, &grid_default_cell, sizeof *gc);
+ ret = style_parse(&grid_default_cell, gc, str);
+
+ if (ret == -1) {
+ free(gc);
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ }
+
+ if (args_has(args, 'A')) {
+ free(wp->window->apcolgc);
+ wp->window->apcolgc = gc;
+ server_redraw_window(wp->window);
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'P')) {
+ free(wp->colgc);
+ wp->colgc = gc;
+ wp->flags |= PANE_REDRAW;
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'W')) {
+ free(wp->window->colgc);
+ wp->window->colgc = gc;
+ server_redraw_window(wp->window);
+ return (CMD_RETURN_NORMAL);
+ }
+
+ return (CMD_RETURN_NORMAL);
+}
diff --git a/cmd.c b/cmd.c
index eeffe4c..e54b23e 100644
--- a/cmd.c
+++ b/cmd.c
@@ -39,6 +39,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_choose_window_entry,
&cmd_clear_history_entry,
&cmd_clock_mode_entry,
+ &cmd_colour_pane_entry,
&cmd_command_prompt_entry,
&cmd_confirm_before_entry,
&cmd_copy_mode_entry,
diff --git a/colour.c b/colour.c
index 9e90596..eeb6625 100644
--- a/colour.c
+++ b/colour.c
@@ -287,3 +287,16 @@ colour_256to16(u_char c)
return (table[c]);
}
+
+const struct grid_cell *
+get_wp_default_grid_colours(const struct window_pane *wp)
+{
+ if (wp->colgc != NULL)
+ return (wp->colgc);
+
+ if (wp == wp->window->active && wp->window->apcolgc != NULL)
+ return (wp->window->apcolgc);
+
+
+ return (wp->window->colgc);
+}
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..4a780f6 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -266,7 +266,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff,
+ get_wp_default_grid_colours(wp));
tty_reset(&c->tty);
}
@@ -354,7 +355,8 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff,
+ get_wp_default_grid_colours(wp));
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +369,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
diff --git a/tmux.h b/tmux.h
index e296ac7..28a1b62 100644
--- a/tmux.h
+++ b/tmux.h
@@ -900,6 +900,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell *colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -953,6 +956,10 @@ struct window {
struct options options;
+ /* Default fg/bg grid cell colours for window and active pane */
+ struct grid_cell *colgc;
+ struct grid_cell *apcolgc;
+
u_int references;
};
ARRAY_DECL(windows, struct window *);
@@ -1628,7 +1635,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct grid_cell *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
@@ -1739,6 +1747,7 @@ extern const struct cmd_entry cmd_choose_tree_entry;
extern const struct cmd_entry cmd_choose_window_entry;
extern const struct cmd_entry cmd_clear_history_entry;
extern const struct cmd_entry cmd_clock_mode_entry;
+extern const struct cmd_entry cmd_colour_pane_entry;
extern const struct cmd_entry cmd_command_prompt_entry;
extern const struct cmd_entry cmd_confirm_before_entry;
extern const struct cmd_entry cmd_copy_mode_entry;
@@ -1956,6 +1965,7 @@ void colour_set_bg(struct grid_cell *, int);
const char *colour_tostring(int);
int colour_fromstring(const char *);
u_char colour_256to16(u_char);
+const struct grid_cell *get_wp_default_grid_colours(const struct window_pane *);
/* attributes.c */
const char *attributes_tostring(u_char);
diff --git a/tty.c b/tty.c
index 1bb8981..ffc25e2 100644
--- a/tty.c
+++ b/tty.c
@@ -604,22 +604,26 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff,
+ get_wp_default_grid_colours(wp));
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff,
+ get_wp_default_grid_colours(wp));
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct grid_cell *colgc)
{
const struct grid_cell *gc;
struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, colourgc;
struct utf8_data ud;
u_int i, sx;
+
tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s);
sx = screen_size_x(s);
@@ -628,6 +632,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
if (sx > tty->sx)
sx = tty->sx;
+
/*
* Don't move the cursor to the start permission if it will wrap there
* itself.
@@ -642,17 +647,28 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
+ memcpy(&colourgc, gc, sizeof *gc);
+ if (colgc != NULL && colourgc.fg == 8) {
+ colourgc.fg = colgc->fg;
+ colourgc.flags &= ~GRID_FLAG_FG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (colgc != NULL && colourgc.bg == 8) {
+ colourgc.bg = colgc->bg;
+ colourgc.flags &= ~GRID_FLAG_BG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
if (screen_check_selection(s, i, py)) {
memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
- grid_cell_get(gc, &ud);
+ grid_cell_get(&colourgc, &ud);
grid_cell_set(&tmpgc, &ud);
- tmpgc.flags = gc->flags &
+ tmpgc.flags = colourgc.flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
tty_cell(tty, &tmpgc);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, &colourgc);
}
if (sx >= tty->sx) {
@@ -660,6 +676,9 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
return;
}
tty_reset(tty);
+ if (colgc != NULL && colgc->bg != 8)
+ tty_colours(tty, colgc);
+
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
@@ -668,6 +687,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
else
tty_repeat_space(tty, screen_size_x(s) - sx);
tty_update_mode(tty, tty->mode, s);
+
}
void
@@ -711,13 +731,19 @@ void
tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ colgc);
return;
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -725,22 +751,29 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_ICH1))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ get_wp_default_grid_colours(wp));
}
void
tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
if (!tty_pane_full_width(tty, ctx) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ colgc);
return;
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -753,8 +786,14 @@ void
tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -769,6 +808,11 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
+
if (!tty_pane_full_width(tty, ctx) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1)) {
@@ -777,6 +821,8 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -787,6 +833,11 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
+
if (!tty_pane_full_width(tty, ctx) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1)) {
@@ -795,6 +846,8 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -807,8 +860,13 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
@@ -823,8 +881,13 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -837,7 +900,14 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
+
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -851,6 +921,11 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
+
if (ctx->ocy != ctx->orupper)
return;
@@ -862,6 +937,8 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -873,6 +950,9 @@ void
tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
if (ctx->ocy != ctx->orlower)
return;
@@ -895,6 +975,8 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
return;
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -908,8 +990,13 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
u_int i, j;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -941,8 +1028,13 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
u_int i, j;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -968,8 +1060,13 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
u_int i, j;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -996,8 +1093,13 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
u_int i, j;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1015,6 +1117,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int cx;
u_int width;
+ struct grid_cell tmpgc;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
@@ -1043,19 +1149,37 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+
+ memcpy(&tmpgc, ctx->cell, sizeof tmpgc);
+ if (colgc != NULL) {
+ if (ctx->cell->fg == 8) {
+ tmpgc.fg = colgc->fg;
+ tmpgc.flags &= ~GRID_FLAG_FG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (ctx->cell->bg == 8) {
+ tmpgc.bg = colgc->bg;
+ tmpgc.flags &= ~GRID_FLAG_BG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
+ }
+
+ tty_cell(tty, &tmpgc);
}
void
tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
/*
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, colgc);
}
void
@@ -1079,6 +1203,11 @@ tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
+
u_int i;
u_char *str = ctx->ptr;
@@ -1089,6 +1218,8 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->rupper = tty->rlower = UINT_MAX;
tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);
tty_cursor(tty, 0, 0);
}
diff --git a/window.c b/window.c
index 5412963..ca44cbe 100644
--- a/window.c
+++ b/window.c
@@ -288,6 +288,9 @@ window_create1(u_int sx, u_int sy)
w->sx = sx;
w->sy = sy;
+ w->colgc = NULL;
+ w->apcolgc = NULL;
+
options_init(&w->options, &global_w_options);
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
@@ -357,6 +360,8 @@ window_destroy(struct window *w)
window_destroy_panes(w);
free(w->name);
+ free(w->colgc);
+ free(w->apcolgc);
free(w);
}
@@ -704,6 +709,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ wp->colgc = NULL;
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
@@ -742,6 +749,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
close(wp->cwd);
+ free(wp->colgc);
free(wp->shell);
cmd_free_argv(wp->argc, wp->argv);
free(wp);
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
J Raynor
2015-02-12 04:03:21 UTC
Permalink
Post by Nicholas Marriott
This will not work as it is on terminals which do not support BCE. To
make it do so you will pretty much have to make tmux support BCE :-).
Ok, it now works on systems that don't support BCE. I've attached a new patch.
Nicholas Marriott
2015-02-12 08:37:09 UTC
Permalink
Hi

Looks like the right idea - please break the BCE stuff out into a
separate diff and we can check it separately. I suggest adding a flag
TTY_NOBCE rather than looking up TTYC_BCE every time.

Also I don't want a new command, so this will need to be a flag (or two:
one for fg, one for for bg) on another command. Perhaps select-pane or
resize-pane? Or just display-panes?

I think you should do the default colour changes in tty_reset or perhaps
tty_colours rather than everywhere it gets passed in.

Thanks
Post by J Raynor
Post by Nicholas Marriott
This will not work as it is on terminals which do not support BCE. To
make it do so you will pretty much have to make tmux support BCE :-).
Ok, it now works on systems that don't support BCE. I've attached a new patch.
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..150b6f4 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,14 +18,28 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
* Display panes on a client.
+ *
+ * Set or get pane default fg/bg colours.
*/
+enum cmd_retval cmd_colour_pane_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
+const struct cmd_entry cmd_colour_pane_entry = {
+ "colour-pane", "colourp",
+ "gt:APW", 0, 1,
+ CMD_TARGET_PANE_USAGE " [-A|P|W] colour-style",
+ 0,
+ cmd_colour_pane_exec
+};
+
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
"t:", 0, 0,
@@ -47,3 +61,107 @@ cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL);
}
+
+enum cmd_retval
+cmd_colour_pane_exec(struct cmd *self, struct cmd_q *cmdq)
+{
+ struct args *args = self->args;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ int ret, nflags = 0;
+ struct grid_cell *gc;
+ const char *str;
+
+
+
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ if (args_has(args, 'g')) nflags++;
+ if (args_has(args, 'A')) nflags++;
+ if (args_has(args, 'P')) nflags++;
+ if (args_has(args, 'W')) nflags++;
+
+ if (nflags == 0 || nflags > 1) {
+ cmdq_error(cmdq, "need exactly 1 of -g, -A, -P, or -W");
+ return (CMD_RETURN_ERROR);
+ }
+
+ if (args_has(args, 'g')) {
+ if (args->argc > 0) {
+ cmdq_error(cmdq, "don't specify style with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ gc = wp->window->apcolgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "active-pane %s", str);
+
+
+ gc = wp->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "pane %s", str);
+
+
+ gc = wp->window->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "window %s", str);
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args->argc == 0) {
+ cmdq_error(cmdq, "need a style argument");
+ return (CMD_RETURN_ERROR);
+ }
+
+ str = args->argv[0];
+ if (*str == '\0')
+ gc = NULL;
+ else {
+ gc = xmalloc(sizeof *gc);
+ memcpy(gc, &grid_default_cell, sizeof *gc);
+ ret = style_parse(&grid_default_cell, gc, str);
+
+ if (ret == -1) {
+ free(gc);
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+
+ gc->attr = grid_default_cell.attr;
+ }
+
+ if (args_has(args, 'A')) {
+ free(wp->window->apcolgc);
+ wp->window->apcolgc = gc;
+ server_redraw_window(wp->window);
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'P')) {
+ free(wp->colgc);
+ wp->colgc = gc;
+ wp->flags |= PANE_REDRAW;
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'W')) {
+ free(wp->window->colgc);
+ wp->window->colgc = gc;
+ server_redraw_window(wp->window);
+ return (CMD_RETURN_NORMAL);
+ }
+
+ return (CMD_RETURN_NORMAL);
+}
diff --git a/cmd.c b/cmd.c
index eeffe4c..e54b23e 100644
--- a/cmd.c
+++ b/cmd.c
@@ -39,6 +39,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_choose_window_entry,
&cmd_clear_history_entry,
&cmd_clock_mode_entry,
+ &cmd_colour_pane_entry,
&cmd_command_prompt_entry,
&cmd_confirm_before_entry,
&cmd_copy_mode_entry,
diff --git a/colour.c b/colour.c
index 9e90596..eeb6625 100644
--- a/colour.c
+++ b/colour.c
@@ -287,3 +287,16 @@ colour_256to16(u_char c)
return (table[c]);
}
+
+const struct grid_cell *
+get_wp_default_grid_colours(const struct window_pane *wp)
+{
+ if (wp->colgc != NULL)
+ return (wp->colgc);
+
+ if (wp == wp->window->active && wp->window->apcolgc != NULL)
+ return (wp->window->apcolgc);
+
+
+ return (wp->window->colgc);
+}
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..4a780f6 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -266,7 +266,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff,
+ get_wp_default_grid_colours(wp));
tty_reset(&c->tty);
}
@@ -354,7 +355,8 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff,
+ get_wp_default_grid_colours(wp));
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +369,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
diff --git a/tmux.h b/tmux.h
index e296ac7..0f32777 100644
--- a/tmux.h
+++ b/tmux.h
@@ -154,6 +154,7 @@ enum key_code {
enum tty_code_code {
TTYC_AX = 0,
TTYC_ACSC, /* acs_chars, ac */
+ TTYC_BCE,
TTYC_BEL, /* bell, bl */
TTYC_BLINK, /* enter_blink_mode, mb */
TTYC_BOLD, /* enter_bold_mode, md */
@@ -900,6 +901,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell *colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -953,6 +957,10 @@ struct window {
struct options options;
+ /* Default fg/bg grid cell colours for window and active pane */
+ struct grid_cell *colgc;
+ struct grid_cell *apcolgc;
+
u_int references;
};
ARRAY_DECL(windows, struct window *);
@@ -1628,7 +1636,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct grid_cell *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
@@ -1739,6 +1748,7 @@ extern const struct cmd_entry cmd_choose_tree_entry;
extern const struct cmd_entry cmd_choose_window_entry;
extern const struct cmd_entry cmd_clear_history_entry;
extern const struct cmd_entry cmd_clock_mode_entry;
+extern const struct cmd_entry cmd_colour_pane_entry;
extern const struct cmd_entry cmd_command_prompt_entry;
extern const struct cmd_entry cmd_confirm_before_entry;
extern const struct cmd_entry cmd_copy_mode_entry;
@@ -1956,6 +1966,7 @@ void colour_set_bg(struct grid_cell *, int);
const char *colour_tostring(int);
int colour_fromstring(const char *);
u_char colour_256to16(u_char);
+const struct grid_cell *get_wp_default_grid_colours(const struct window_pane *);
/* attributes.c */
const char *attributes_tostring(u_char);
diff --git a/tty-term.c b/tty-term.c
index 365da5f..456f81e 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -38,6 +38,7 @@ struct tty_terms tty_terms = LIST_HEAD_INITIALIZER(tty_terms);
const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_ACSC, TTYCODE_STRING, "acsc" },
{ TTYC_AX, TTYCODE_FLAG, "AX" },
+ { TTYC_BCE, TTYCODE_STRING, "bce" },
{ TTYC_BEL, TTYCODE_STRING, "bel" },
{ TTYC_BLINK, TTYCODE_STRING, "blink" },
{ TTYC_BOLD, TTYCODE_STRING, "bold" },
diff --git a/tty.c b/tty.c
index 1bb8981..63ce2eb 100644
--- a/tty.c
+++ b/tty.c
@@ -604,21 +604,25 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff,
+ get_wp_default_grid_colours(wp));
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff,
+ get_wp_default_grid_colours(wp));
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct grid_cell *colgc)
{
const struct grid_cell *gc;
struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, colourgc;
struct utf8_data ud;
- u_int i, sx;
+ u_int i, sx, fake_bce = 0;
+
tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s);
@@ -628,6 +632,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
if (sx > tty->sx)
sx = tty->sx;
+
/*
* Don't move the cursor to the start permission if it will wrap there
* itself.
@@ -642,17 +647,28 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
+ memcpy(&colourgc, gc, sizeof *gc);
+ if (colgc != NULL && colourgc.fg == 8) {
+ colourgc.fg = colgc->fg;
+ colourgc.flags &= ~GRID_FLAG_FG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (colgc != NULL && colourgc.bg == 8) {
+ colourgc.bg = colgc->bg;
+ colourgc.flags &= ~GRID_FLAG_BG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
if (screen_check_selection(s, i, py)) {
memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
- grid_cell_get(gc, &ud);
+ grid_cell_get(&colourgc, &ud);
grid_cell_set(&tmpgc, &ud);
- tmpgc.flags = gc->flags &
+ tmpgc.flags = colourgc.flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
tty_cell(tty, &tmpgc);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, &colourgc);
}
if (sx >= tty->sx) {
@@ -660,14 +676,21 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
return;
}
tty_reset(tty);
+ if (colgc != NULL && colgc->bg != 8) {
+ tty_attributes(tty, colgc);
+ if (!tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+ }
+
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
- tty_term_has(tty->term, TTYC_EL))
+ tty_term_has(tty->term, TTYC_EL) && !fake_bce)
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - sx);
tty_update_mode(tty, tty->mode, s);
+
}
void
@@ -711,36 +734,56 @@ void
tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ colgc);
return;
}
tty_reset(tty);
+ if (colgc != NULL) {
+ tty_attributes(tty, colgc);
+ if (!tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+ }
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_term_has(tty->term, TTYC_ICH) ||
- tty_term_has(tty->term, TTYC_ICH1))
+ if (!fake_bce && (tty_term_has(tty->term, TTYC_ICH) ||
+ tty_term_has(tty->term, TTYC_ICH1)))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ get_wp_default_grid_colours(wp));
}
void
tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
- if (!tty_pane_full_width(tty, ctx) ||
+ colgc = get_wp_default_grid_colours(wp);
+ if (colgc != NULL && !tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+
+ if (!tty_pane_full_width(tty, ctx) || fake_bce ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ colgc);
return;
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -753,12 +796,22 @@ void
tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL) {
+ tty_attributes(tty, colgc);
+ if (!tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+ }
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_term_has(tty->term, TTYC_ECH))
+ if (tty_term_has(tty->term, TTYC_ECH) && !fake_bce)
tty_putcode1(tty, TTYC_ECH, ctx->num);
else {
for (i = 0; i < ctx->num; i++)
@@ -769,7 +822,15 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
+ if (colgc != NULL && !tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+
+ if (!tty_pane_full_width(tty, ctx) || fake_bce ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1)) {
tty_redraw_region(tty, ctx);
@@ -777,6 +838,8 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -787,7 +850,15 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
+ if (colgc != NULL && !tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+
+ if (!tty_pane_full_width(tty, ctx) || fake_bce ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1)) {
tty_redraw_region(tty, ctx);
@@ -795,6 +866,8 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -807,12 +880,22 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL) {
+ tty_attributes(tty, colgc);
+ if (!tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+ }
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx)
+ && tty_term_has(tty->term, TTYC_EL) && !fake_bce)
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
@@ -823,12 +906,22 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL) {
+ tty_attributes(tty, colgc);
+ if (!tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+ }
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !fake_bce)
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
@@ -837,9 +930,21 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
+
tty_reset(tty);
+ if (colgc != NULL) {
+ tty_attributes(tty, colgc);
+ if (!tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+ }
- if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
+ if (ctx->xoff == 0 &&
+ tty_term_has(tty->term, TTYC_EL1) && !fake_bce) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_putcode(tty, TTYC_EL1);
} else {
@@ -851,10 +956,18 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
+ if (colgc != NULL && !tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+
if (ctx->ocy != ctx->orupper)
return;
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || fake_bce ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_RI)) {
tty_redraw_region(tty, ctx);
@@ -862,6 +975,8 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
}
tty_reset(tty);
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -873,11 +988,17 @@ void
tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
+ if (colgc != NULL && !tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
if (ctx->ocy != ctx->orlower)
return;
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || fake_bce ||
!tty_term_has(tty->term, TTYC_CSR)) {
if (tty_large_region(tty, ctx))
wp->flags |= PANE_REDRAW;
@@ -895,6 +1016,8 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
return;
tty_reset(tty);
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -908,13 +1031,23 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
u_int i, j;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL) {
+ tty_attributes(tty, colgc);
+ if (!tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+ }
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !fake_bce) {
tty_putcode(tty, TTYC_EL);
if (ctx->ocy != screen_size_y(s) - 1) {
tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
@@ -941,13 +1074,23 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
u_int i, j;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL) {
+ tty_attributes(tty, colgc);
+ if (!tty_term_has(tty->term, TTYC_BCE))
+ fake_bce = 1;
+ }
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !fake_bce) {
for (i = 0; i < ctx->ocy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
@@ -968,13 +1111,20 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
u_int i, j;
+ const struct grid_cell *colgc;
+ int fake_bce = 0;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !fake_bce) {
for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1) {
@@ -996,8 +1146,13 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
u_int i, j;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_reset(tty);
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1015,6 +1170,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int cx;
u_int width;
+ struct grid_cell tmpgc;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
@@ -1043,19 +1202,37 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+
+ memcpy(&tmpgc, ctx->cell, sizeof tmpgc);
+ if (colgc != NULL) {
+ if (ctx->cell->fg == 8) {
+ tmpgc.fg = colgc->fg;
+ tmpgc.flags &= ~GRID_FLAG_FG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (ctx->cell->bg == 8) {
+ tmpgc.bg = colgc->bg;
+ tmpgc.flags &= ~GRID_FLAG_BG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
+ }
+
+ tty_cell(tty, &tmpgc);
}
void
tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
/*
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, colgc);
}
void
@@ -1079,6 +1256,11 @@ tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct window_pane *wp = ctx->wp;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
+
u_int i;
u_char *str = ctx->ptr;
@@ -1089,6 +1271,8 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->rupper = tty->rlower = UINT_MAX;
tty_reset(tty);
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
tty_cursor(tty, 0, 0);
}
diff --git a/window.c b/window.c
index 5412963..ca44cbe 100644
--- a/window.c
+++ b/window.c
@@ -288,6 +288,9 @@ window_create1(u_int sx, u_int sy)
w->sx = sx;
w->sy = sy;
+ w->colgc = NULL;
+ w->apcolgc = NULL;
+
options_init(&w->options, &global_w_options);
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
@@ -357,6 +360,8 @@ window_destroy(struct window *w)
window_destroy_panes(w);
free(w->name);
+ free(w->colgc);
+ free(w->apcolgc);
free(w);
}
@@ -704,6 +709,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ wp->colgc = NULL;
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
@@ -742,6 +749,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
close(wp->cwd);
+ free(wp->colgc);
free(wp->shell);
cmd_free_argv(wp->argc, wp->argv);
free(wp);
J Raynor
2015-02-14 00:50:55 UTC
Permalink
I've attached a new patch for pane colors. You use the display-panes
command to set the colors now, and the color changes take place in
tty_reset.

There's no bce stuff in this patch.

For bce, you mentioned a TTY_NOBCE flag. Could you give a little more
detail about what you're looking for? Where would this flag be set or
passed in?

For functions that need to check for bce support, like
tty_cmd_insertcharacter, the function needs to check whether there's
bce support, but also whether a default color has been set, unless you
want a tty without bce support to always fake things like ICH, EL, and
DCH, even if no color has been set. If you don't want to always fake
bce, then it seems a single flag won't work.

If you're just looking to keep things concise, there could be a
function that returns whether bce needs to be faked. For example, if
the patch attached to this email has been applied, here's a diff for
what tty_cmd_clearline would look like with this proposed function:

--- tty.c 2015-02-13 16:37:48.000000000 -0600
+++ tty.c.new 2015-02-13 18:34:49.000000000 -0600
@@ -830,7 +830,9 @@

tty_cursor_pane(tty, ctx, 0, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) &&
+ !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));



No need to declare and set a fake_bce variable, or to do a color
check. The need_fake_bce function would take care of returning the
right info. Should I pursue a patch with bce support implemented
using that function?
Nicholas Marriott
2015-02-14 09:16:35 UTC
Permalink
I was thinking that you do this in tty_open:

if (!tty_term_has(tty->term, TTYC_BCE)
tty->flags |= TTY_NOBCE;

And use that instead of calling tty_term_has all the time. But actually
it probably makes little difference, just using tty_term_has is probably
fine.

As far as the diff below goes:

- I don't think you need to allocate the gc with malloc, just put it
inside the wp directly and initialize it to grid_default_cell.

- You only need to swap it in if the current fg == 8 || bg == 8. You can
do this just in tty_reset and tty_attributes and it should catch
everything. You shouldn't need to change tty_draw_line except to take
a struct window_pane argument.

- I think the window colour can still be a window option but I would
drop it (or drop the pane colours and just do the window) for now and
add it as a separate change after one is working.

- I would drop get_wp_default_grid_colours in favour of a function in
tty.c that did something like:

void
tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
{
if (wp == NULL)
return;

if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
gc.fg = wp->colgc.fg;
gc.flags &= ~GRID_FLAG_FG256;
gc.flags |= (wp->colgc.flags & GRID_FLAG_FG256);
}
/* same for bg, you get the idea */
}

This relies on BCE working properly so you can set the cell defaults to
anything of course.
Post by J Raynor
I've attached a new patch for pane colors. You use the display-panes
command to set the colors now, and the color changes take place in
tty_reset.
There's no bce stuff in this patch.
For bce, you mentioned a TTY_NOBCE flag. Could you give a little more
detail about what you're looking for? Where would this flag be set or
passed in?
For functions that need to check for bce support, like
tty_cmd_insertcharacter, the function needs to check whether there's
bce support, but also whether a default color has been set, unless you
want a tty without bce support to always fake things like ICH, EL, and
DCH, even if no color has been set. If you don't want to always fake
bce, then it seems a single flag won't work.
If you're just looking to keep things concise, there could be a
function that returns whether bce needs to be faked. For example, if
the patch attached to this email has been applied, here's a diff for
--- tty.c 2015-02-13 16:37:48.000000000 -0600
+++ tty.c.new 2015-02-13 18:34:49.000000000 -0600
@@ -830,7 +830,9 @@
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) &&
+ !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
No need to declare and set a fake_bce variable, or to do a color
check. The need_fake_bce function would take care of returning the
right info. Should I pursue a patch with bce support implemented
using that function?
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..1994aa4 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,18 +18,23 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
- * Display panes on a client.
+ * Display panes on a client, or get/set pane default fg/bg colours.
*/
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
+int cmd_display_panes_initgc(const char *, struct grid_cell **);
+
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "gt:A:P:W:", 0, 0,
+ "[-g] [-A style] [-P style] [-W style] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
};
@@ -37,13 +42,120 @@ const struct cmd_entry cmd_display_panes_entry = {
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ int nflags = 0;
+ struct grid_cell *gc;
+ const char *str;
+
+ if (args_has(args, 'g')) nflags++;
+ if (args_has(args, 'A')) nflags++;
+ if (args_has(args, 'P')) nflags++;
+ if (args_has(args, 'W')) nflags++;
+
+ if (nflags == 0) {
+
+ if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ server_set_identify(c);
+
+ return (CMD_RETURN_NORMAL);
+ }
- if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
- server_set_identify(c);
+ if (args_has(args, 'g')) {
+
+ if (nflags > 1) {
+ cmdq_error(cmdq, "don't use -A, -P, or -W with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ gc = wp->window->apcolgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "active-pane %s", str);
+
+
+ gc = wp->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "pane %s", str);
+
+
+ gc = wp->window->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "window %s", str);
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+
+ if (args_has(args, 'A')) {
+ if (cmd_display_panes_initgc(args_get(args, 'A'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->window->apcolgc);
+ wp->window->apcolgc = gc;
+ server_redraw_window(wp->window);
+ }
+
+ if (args_has(args, 'P')) {
+ if (cmd_display_panes_initgc(args_get(args, 'P'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->colgc);
+ wp->colgc = gc;
+ wp->flags |= PANE_REDRAW;
+ }
+
+ if (args_has(args, 'W')) {
+ if (cmd_display_panes_initgc(args_get(args, 'W'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->window->colgc);
+ wp->window->colgc = gc;
+ server_redraw_window(wp->window);
+ }
return (CMD_RETURN_NORMAL);
}
+
+int
+cmd_display_panes_initgc(const char *str, struct grid_cell **gcp)
+{
+ int ret;
+
+ if (*str == '\0')
+ *gcp = NULL;
+ else {
+ *gcp = xmalloc(sizeof **gcp);
+ memcpy(*gcp, &grid_default_cell, sizeof **gcp);
+ ret = style_parse(&grid_default_cell, *gcp, str);
+
+ if (ret == -1) {
+ free(*gcp);
+ return (ret);
+ }
+
+ (*gcp)->attr = grid_default_cell.attr;
+ }
+
+ return (0);
+}
diff --git a/colour.c b/colour.c
index 9e90596..eeb6625 100644
--- a/colour.c
+++ b/colour.c
@@ -287,3 +287,16 @@ colour_256to16(u_char c)
return (table[c]);
}
+
+const struct grid_cell *
+get_wp_default_grid_colours(const struct window_pane *wp)
+{
+ if (wp->colgc != NULL)
+ return (wp->colgc);
+
+ if (wp == wp->window->active && wp->window->apcolgc != NULL)
+ return (wp->window->apcolgc);
+
+
+ return (wp->window->colgc);
+}
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..9b1bb83 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -249,7 +249,7 @@ screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
screen_redraw_draw_panes(c, top);
if (draw_status)
screen_redraw_draw_status(c, top);
- tty_reset(tty);
+ tty_reset(tty, NULL);
}
/* Draw a single pane. */
@@ -266,8 +266,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
- tty_reset(&c->tty);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff, wp);
+ tty_reset(&c->tty, NULL);
}
/* Draw the borders. */
@@ -354,7 +354,7 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff, wp);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +367,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
diff --git a/server-client.c b/server-client.c
index 3ca9907..3206b6e 100644
--- a/server-client.c
+++ b/server-client.c
@@ -691,7 +691,7 @@ server_client_reset_state(struct client *c)
/* Set the terminal mode and reset attributes. */
tty_update_mode(&c->tty, mode, s);
- tty_reset(&c->tty);
+ tty_reset(&c->tty, NULL);
}
/* Repeat time callback. */
diff --git a/tmux.1 b/tmux.1
index f615dd0..ec13752 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1305,9 +1305,16 @@ flag, see the
.Sx FORMATS
section.
This command works only if at least one client is attached.
-.It Ic display-panes Op Fl t Ar target-client
+.It Xo Ic display-panes
+.Op Fl g
+.Op Fl A Ar style
+.Op Fl P Ar style
+.Op Fl W Ar style
+.Op Fl t Ar target-client
+.Xc
.D1 (alias: Ic displayp )
-Display a visible indicator of each pane shown by
+If no flags have been specified, display a visible indicator of
+each pane shown by
.Ar target-client .
See the
.Ic display-panes-time ,
@@ -1320,6 +1327,29 @@ While the indicator is on screen, a pane may be selected with the
to
.Ql 9
keys.
+.Pp
+With
+.Fl A
+,
+.Fl P
+, or
+.Fl W
+a style argument can be passed to change a window or pane's
+default foreground and background colour. The
+.Fl W
+flag will set the default colour style for panes in the window. The
+.Fl A
+flag will set the colour style a pane will have whenever it becomes the
+active pane in the window. The
+.Fl P
+flag will set the colour style for a pane, overriding whatever
+style has been set with
+.Fl W
+or
+.Fl A
+\&. To clear a style, specify the empty string. The
+.Fl g
+flag will show what colour styles have been set.
.It Xo Ic find-window
.Op Fl CNT
.Op Fl F Ar format
diff --git a/tmux.h b/tmux.h
index e296ac7..7635de7 100644
--- a/tmux.h
+++ b/tmux.h
@@ -900,6 +900,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell *colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -953,6 +956,10 @@ struct window {
struct options options;
+ /* Default fg/bg grid cell colours for window and active pane */
+ struct grid_cell *colgc;
+ struct grid_cell *apcolgc;
+
u_int references;
};
ARRAY_DECL(windows, struct window *);
@@ -1605,7 +1612,7 @@ void environ_push(struct environ *);
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
void tty_attributes(struct tty *, const struct grid_cell *);
-void tty_reset(struct tty *);
+void tty_reset(struct tty *, const struct window_pane *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
void tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
@@ -1628,7 +1635,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct window_pane *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
@@ -1956,6 +1964,7 @@ void colour_set_bg(struct grid_cell *, int);
const char *colour_tostring(int);
int colour_fromstring(const char *);
u_char colour_256to16(u_char);
+const struct grid_cell *get_wp_default_grid_colours(const struct window_pane *);
/* attributes.c */
const char *attributes_tostring(u_char);
diff --git a/tty.c b/tty.c
index 1bb8981..da1010e 100644
--- a/tty.c
+++ b/tty.c
@@ -604,19 +604,20 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct window_pane *wp)
{
- const struct grid_cell *gc;
+ const struct grid_cell *gc, *colgc = NULL;
struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, colourgc;
struct utf8_data ud;
u_int i, sx;
@@ -640,26 +641,40 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
(oy + py != tty->cy + 1 && tty->cy != s->rlower + oy))
tty_cursor(tty, ox, oy + py);
+ if (wp != NULL)
+ colgc = get_wp_default_grid_colours(wp);
+
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
+ memcpy(&colourgc, gc, sizeof *gc);
+ if (colgc != NULL && colourgc.fg == 8) {
+ colourgc.fg = colgc->fg;
+ colourgc.flags &= ~GRID_FLAG_FG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (colgc != NULL && colourgc.bg == 8) {
+ colourgc.bg = colgc->bg;
+ colourgc.flags &= ~GRID_FLAG_BG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
if (screen_check_selection(s, i, py)) {
memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
- grid_cell_get(gc, &ud);
+ grid_cell_get(&colourgc, &ud);
grid_cell_set(&tmpgc, &ud);
- tmpgc.flags = gc->flags &
+ tmpgc.flags = colourgc.flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
tty_cell(tty, &tmpgc);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, &colourgc);
}
if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
@@ -713,11 +728,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -725,7 +741,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_ICH1))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
}
void
@@ -736,11 +753,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
if (!tty_pane_full_width(tty, ctx) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -754,7 +772,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -776,7 +794,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -794,7 +812,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,7 +826,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
@@ -824,7 +842,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -837,7 +855,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -861,7 +879,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -894,7 +912,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,7 +927,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -942,7 +960,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -969,7 +987,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -997,7 +1015,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1015,6 +1033,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int cx;
u_int width;
+ struct grid_cell tmpgc;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
@@ -1043,7 +1065,22 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+
+ memcpy(&tmpgc, ctx->cell, sizeof tmpgc);
+ if (colgc != NULL) {
+ if (ctx->cell->fg == 8) {
+ tmpgc.fg = colgc->fg;
+ tmpgc.flags &= ~GRID_FLAG_FG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (ctx->cell->bg == 8) {
+ tmpgc.bg = colgc->bg;
+ tmpgc.flags &= ~GRID_FLAG_BG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
+ }
+
+ tty_cell(tty, &tmpgc);
}
void
@@ -1055,7 +1092,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, wp);
}
void
@@ -1088,7 +1125,7 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor(tty, 0, 0);
}
@@ -1131,17 +1168,26 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
}
void
-tty_reset(struct tty *tty)
+tty_reset(struct tty *tty, const struct window_pane *wp)
{
struct grid_cell *gc = &tty->cell;
+ const struct grid_cell *colgc = NULL;
- if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
+ if (wp != NULL)
+ colgc = get_wp_default_grid_colours(wp);
+
+ if (colgc == NULL &&
+ memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
return;
if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0);
memcpy(gc, &grid_default_cell, sizeof *gc);
+
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
+
}
/* Set region inside pane. */
@@ -1340,7 +1386,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc)
/* If any bits are being cleared, reset everything. */
if (tc->attr & ~gc2.attr)
- tty_reset(tty);
+ tty_reset(tty, NULL);
/*
* Set the colours. This may call tty_reset() (so it comes next) and
@@ -1409,7 +1455,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
*/
have_ax = tty_term_has(tty->term, TTYC_AX);
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
- tty_reset(tty);
+ tty_reset(tty, NULL);
else {
if (fg_default &&
(tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
diff --git a/window.c b/window.c
index 5412963..ca44cbe 100644
--- a/window.c
+++ b/window.c
@@ -288,6 +288,9 @@ window_create1(u_int sx, u_int sy)
w->sx = sx;
w->sy = sy;
+ w->colgc = NULL;
+ w->apcolgc = NULL;
+
options_init(&w->options, &global_w_options);
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
@@ -357,6 +360,8 @@ window_destroy(struct window *w)
window_destroy_panes(w);
free(w->name);
+ free(w->colgc);
+ free(w->apcolgc);
free(w);
}
@@ -704,6 +709,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ wp->colgc = NULL;
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
@@ -742,6 +749,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
close(wp->cwd);
+ free(wp->colgc);
free(wp->shell);
cmd_free_argv(wp->argc, wp->argv);
free(wp);
Nicholas Marriott
2015-02-14 09:28:17 UTC
Permalink
In fact, since you will need to change tty_reset to call
tty_attributes(&grid_default_cell) instead of sending SGR0, you will
only need to check the default colours in tty_attributes itself.
Post by J Raynor
if (!tty_term_has(tty->term, TTYC_BCE)
tty->flags |= TTY_NOBCE;
And use that instead of calling tty_term_has all the time. But actually
it probably makes little difference, just using tty_term_has is probably
fine.
- I don't think you need to allocate the gc with malloc, just put it
inside the wp directly and initialize it to grid_default_cell.
- You only need to swap it in if the current fg == 8 || bg == 8. You can
do this just in tty_reset and tty_attributes and it should catch
everything. You shouldn't need to change tty_draw_line except to take
a struct window_pane argument.
- I think the window colour can still be a window option but I would
drop it (or drop the pane colours and just do the window) for now and
add it as a separate change after one is working.
- I would drop get_wp_default_grid_colours in favour of a function in
void
tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
{
if (wp == NULL)
return;
if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
gc.fg = wp->colgc.fg;
gc.flags &= ~GRID_FLAG_FG256;
gc.flags |= (wp->colgc.flags & GRID_FLAG_FG256);
}
/* same for bg, you get the idea */
}
This relies on BCE working properly so you can set the cell defaults to
anything of course.
Post by J Raynor
I've attached a new patch for pane colors. You use the display-panes
command to set the colors now, and the color changes take place in
tty_reset.
There's no bce stuff in this patch.
For bce, you mentioned a TTY_NOBCE flag. Could you give a little more
detail about what you're looking for? Where would this flag be set or
passed in?
For functions that need to check for bce support, like
tty_cmd_insertcharacter, the function needs to check whether there's
bce support, but also whether a default color has been set, unless you
want a tty without bce support to always fake things like ICH, EL, and
DCH, even if no color has been set. If you don't want to always fake
bce, then it seems a single flag won't work.
If you're just looking to keep things concise, there could be a
function that returns whether bce needs to be faked. For example, if
the patch attached to this email has been applied, here's a diff for
--- tty.c 2015-02-13 16:37:48.000000000 -0600
+++ tty.c.new 2015-02-13 18:34:49.000000000 -0600
@@ -830,7 +830,9 @@
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) &&
+ !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
No need to declare and set a fake_bce variable, or to do a color
check. The need_fake_bce function would take care of returning the
right info. Should I pursue a patch with bce support implemented
using that function?
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..1994aa4 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,18 +18,23 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
- * Display panes on a client.
+ * Display panes on a client, or get/set pane default fg/bg colours.
*/
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
+int cmd_display_panes_initgc(const char *, struct grid_cell **);
+
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "gt:A:P:W:", 0, 0,
+ "[-g] [-A style] [-P style] [-W style] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
};
@@ -37,13 +42,120 @@ const struct cmd_entry cmd_display_panes_entry = {
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ int nflags = 0;
+ struct grid_cell *gc;
+ const char *str;
+
+ if (args_has(args, 'g')) nflags++;
+ if (args_has(args, 'A')) nflags++;
+ if (args_has(args, 'P')) nflags++;
+ if (args_has(args, 'W')) nflags++;
+
+ if (nflags == 0) {
+
+ if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ server_set_identify(c);
+
+ return (CMD_RETURN_NORMAL);
+ }
- if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
- server_set_identify(c);
+ if (args_has(args, 'g')) {
+
+ if (nflags > 1) {
+ cmdq_error(cmdq, "don't use -A, -P, or -W with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ gc = wp->window->apcolgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "active-pane %s", str);
+
+
+ gc = wp->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "pane %s", str);
+
+
+ gc = wp->window->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "window %s", str);
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+
+ if (args_has(args, 'A')) {
+ if (cmd_display_panes_initgc(args_get(args, 'A'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->window->apcolgc);
+ wp->window->apcolgc = gc;
+ server_redraw_window(wp->window);
+ }
+
+ if (args_has(args, 'P')) {
+ if (cmd_display_panes_initgc(args_get(args, 'P'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->colgc);
+ wp->colgc = gc;
+ wp->flags |= PANE_REDRAW;
+ }
+
+ if (args_has(args, 'W')) {
+ if (cmd_display_panes_initgc(args_get(args, 'W'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->window->colgc);
+ wp->window->colgc = gc;
+ server_redraw_window(wp->window);
+ }
return (CMD_RETURN_NORMAL);
}
+
+int
+cmd_display_panes_initgc(const char *str, struct grid_cell **gcp)
+{
+ int ret;
+
+ if (*str == '\0')
+ *gcp = NULL;
+ else {
+ *gcp = xmalloc(sizeof **gcp);
+ memcpy(*gcp, &grid_default_cell, sizeof **gcp);
+ ret = style_parse(&grid_default_cell, *gcp, str);
+
+ if (ret == -1) {
+ free(*gcp);
+ return (ret);
+ }
+
+ (*gcp)->attr = grid_default_cell.attr;
+ }
+
+ return (0);
+}
diff --git a/colour.c b/colour.c
index 9e90596..eeb6625 100644
--- a/colour.c
+++ b/colour.c
@@ -287,3 +287,16 @@ colour_256to16(u_char c)
return (table[c]);
}
+
+const struct grid_cell *
+get_wp_default_grid_colours(const struct window_pane *wp)
+{
+ if (wp->colgc != NULL)
+ return (wp->colgc);
+
+ if (wp == wp->window->active && wp->window->apcolgc != NULL)
+ return (wp->window->apcolgc);
+
+
+ return (wp->window->colgc);
+}
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..9b1bb83 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -249,7 +249,7 @@ screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
screen_redraw_draw_panes(c, top);
if (draw_status)
screen_redraw_draw_status(c, top);
- tty_reset(tty);
+ tty_reset(tty, NULL);
}
/* Draw a single pane. */
@@ -266,8 +266,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
- tty_reset(&c->tty);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff, wp);
+ tty_reset(&c->tty, NULL);
}
/* Draw the borders. */
@@ -354,7 +354,7 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff, wp);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +367,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
diff --git a/server-client.c b/server-client.c
index 3ca9907..3206b6e 100644
--- a/server-client.c
+++ b/server-client.c
@@ -691,7 +691,7 @@ server_client_reset_state(struct client *c)
/* Set the terminal mode and reset attributes. */
tty_update_mode(&c->tty, mode, s);
- tty_reset(&c->tty);
+ tty_reset(&c->tty, NULL);
}
/* Repeat time callback. */
diff --git a/tmux.1 b/tmux.1
index f615dd0..ec13752 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1305,9 +1305,16 @@ flag, see the
.Sx FORMATS
section.
This command works only if at least one client is attached.
-.It Ic display-panes Op Fl t Ar target-client
+.It Xo Ic display-panes
+.Op Fl g
+.Op Fl A Ar style
+.Op Fl P Ar style
+.Op Fl W Ar style
+.Op Fl t Ar target-client
+.Xc
.D1 (alias: Ic displayp )
-Display a visible indicator of each pane shown by
+If no flags have been specified, display a visible indicator of
+each pane shown by
.Ar target-client .
See the
.Ic display-panes-time ,
@@ -1320,6 +1327,29 @@ While the indicator is on screen, a pane may be selected with the
to
.Ql 9
keys.
+.Pp
+With
+.Fl A
+,
+.Fl P
+, or
+.Fl W
+a style argument can be passed to change a window or pane's
+default foreground and background colour. The
+.Fl W
+flag will set the default colour style for panes in the window. The
+.Fl A
+flag will set the colour style a pane will have whenever it becomes the
+active pane in the window. The
+.Fl P
+flag will set the colour style for a pane, overriding whatever
+style has been set with
+.Fl W
+or
+.Fl A
+\&. To clear a style, specify the empty string. The
+.Fl g
+flag will show what colour styles have been set.
.It Xo Ic find-window
.Op Fl CNT
.Op Fl F Ar format
diff --git a/tmux.h b/tmux.h
index e296ac7..7635de7 100644
--- a/tmux.h
+++ b/tmux.h
@@ -900,6 +900,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell *colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -953,6 +956,10 @@ struct window {
struct options options;
+ /* Default fg/bg grid cell colours for window and active pane */
+ struct grid_cell *colgc;
+ struct grid_cell *apcolgc;
+
u_int references;
};
ARRAY_DECL(windows, struct window *);
@@ -1605,7 +1612,7 @@ void environ_push(struct environ *);
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
void tty_attributes(struct tty *, const struct grid_cell *);
-void tty_reset(struct tty *);
+void tty_reset(struct tty *, const struct window_pane *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
void tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
@@ -1628,7 +1635,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct window_pane *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
@@ -1956,6 +1964,7 @@ void colour_set_bg(struct grid_cell *, int);
const char *colour_tostring(int);
int colour_fromstring(const char *);
u_char colour_256to16(u_char);
+const struct grid_cell *get_wp_default_grid_colours(const struct window_pane *);
/* attributes.c */
const char *attributes_tostring(u_char);
diff --git a/tty.c b/tty.c
index 1bb8981..da1010e 100644
--- a/tty.c
+++ b/tty.c
@@ -604,19 +604,20 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct window_pane *wp)
{
- const struct grid_cell *gc;
+ const struct grid_cell *gc, *colgc = NULL;
struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, colourgc;
struct utf8_data ud;
u_int i, sx;
@@ -640,26 +641,40 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
(oy + py != tty->cy + 1 && tty->cy != s->rlower + oy))
tty_cursor(tty, ox, oy + py);
+ if (wp != NULL)
+ colgc = get_wp_default_grid_colours(wp);
+
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
+ memcpy(&colourgc, gc, sizeof *gc);
+ if (colgc != NULL && colourgc.fg == 8) {
+ colourgc.fg = colgc->fg;
+ colourgc.flags &= ~GRID_FLAG_FG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (colgc != NULL && colourgc.bg == 8) {
+ colourgc.bg = colgc->bg;
+ colourgc.flags &= ~GRID_FLAG_BG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
if (screen_check_selection(s, i, py)) {
memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
- grid_cell_get(gc, &ud);
+ grid_cell_get(&colourgc, &ud);
grid_cell_set(&tmpgc, &ud);
- tmpgc.flags = gc->flags &
+ tmpgc.flags = colourgc.flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
tty_cell(tty, &tmpgc);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, &colourgc);
}
if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
@@ -713,11 +728,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -725,7 +741,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_ICH1))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
}
void
@@ -736,11 +753,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
if (!tty_pane_full_width(tty, ctx) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -754,7 +772,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -776,7 +794,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -794,7 +812,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,7 +826,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
@@ -824,7 +842,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -837,7 +855,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -861,7 +879,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -894,7 +912,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,7 +927,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -942,7 +960,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -969,7 +987,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -997,7 +1015,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1015,6 +1033,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int cx;
u_int width;
+ struct grid_cell tmpgc;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
@@ -1043,7 +1065,22 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+
+ memcpy(&tmpgc, ctx->cell, sizeof tmpgc);
+ if (colgc != NULL) {
+ if (ctx->cell->fg == 8) {
+ tmpgc.fg = colgc->fg;
+ tmpgc.flags &= ~GRID_FLAG_FG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (ctx->cell->bg == 8) {
+ tmpgc.bg = colgc->bg;
+ tmpgc.flags &= ~GRID_FLAG_BG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
+ }
+
+ tty_cell(tty, &tmpgc);
}
void
@@ -1055,7 +1092,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, wp);
}
void
@@ -1088,7 +1125,7 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor(tty, 0, 0);
}
@@ -1131,17 +1168,26 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
}
void
-tty_reset(struct tty *tty)
+tty_reset(struct tty *tty, const struct window_pane *wp)
{
struct grid_cell *gc = &tty->cell;
+ const struct grid_cell *colgc = NULL;
- if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
+ if (wp != NULL)
+ colgc = get_wp_default_grid_colours(wp);
+
+ if (colgc == NULL &&
+ memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
return;
if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0);
memcpy(gc, &grid_default_cell, sizeof *gc);
+
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
+
}
/* Set region inside pane. */
@@ -1340,7 +1386,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc)
/* If any bits are being cleared, reset everything. */
if (tc->attr & ~gc2.attr)
- tty_reset(tty);
+ tty_reset(tty, NULL);
/*
* Set the colours. This may call tty_reset() (so it comes next) and
@@ -1409,7 +1455,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
*/
have_ax = tty_term_has(tty->term, TTYC_AX);
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
- tty_reset(tty);
+ tty_reset(tty, NULL);
else {
if (fg_default &&
(tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
diff --git a/window.c b/window.c
index 5412963..ca44cbe 100644
--- a/window.c
+++ b/window.c
@@ -288,6 +288,9 @@ window_create1(u_int sx, u_int sy)
w->sx = sx;
w->sy = sy;
+ w->colgc = NULL;
+ w->apcolgc = NULL;
+
options_init(&w->options, &global_w_options);
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
@@ -357,6 +360,8 @@ window_destroy(struct window *w)
window_destroy_panes(w);
free(w->name);
+ free(w->colgc);
+ free(w->apcolgc);
free(w);
}
@@ -704,6 +709,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ wp->colgc = NULL;
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
@@ -742,6 +749,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
close(wp->cwd);
+ free(wp->colgc);
free(wp->shell);
cmd_free_argv(wp->argc, wp->argv);
free(wp);
Nicholas Marriott
2015-02-14 09:36:16 UTC
Permalink
Well, it's complicated a bit because tty_attributes calls tty_reset.

So perhaps it is better to check it in two places - tty_attributes and
tty_reset. tty_reset can send SETAB/SETAF after SGR0 if either fg or bg
is not 8.

Or the call to tty_reset in tty_attributes could become a different
function or just happen inside tty_attributes.

The idea I am going for is that you should replace fg=8 or bg=8 with the
wp colours at the bottom level, tty_attributes and tty_reset only.
Post by Nicholas Marriott
In fact, since you will need to change tty_reset to call
tty_attributes(&grid_default_cell) instead of sending SGR0, you will
only need to check the default colours in tty_attributes itself.
Post by J Raynor
if (!tty_term_has(tty->term, TTYC_BCE)
tty->flags |= TTY_NOBCE;
And use that instead of calling tty_term_has all the time. But actually
it probably makes little difference, just using tty_term_has is probably
fine.
- I don't think you need to allocate the gc with malloc, just put it
inside the wp directly and initialize it to grid_default_cell.
- You only need to swap it in if the current fg == 8 || bg == 8. You can
do this just in tty_reset and tty_attributes and it should catch
everything. You shouldn't need to change tty_draw_line except to take
a struct window_pane argument.
- I think the window colour can still be a window option but I would
drop it (or drop the pane colours and just do the window) for now and
add it as a separate change after one is working.
- I would drop get_wp_default_grid_colours in favour of a function in
void
tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
{
if (wp == NULL)
return;
if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
gc.fg = wp->colgc.fg;
gc.flags &= ~GRID_FLAG_FG256;
gc.flags |= (wp->colgc.flags & GRID_FLAG_FG256);
}
/* same for bg, you get the idea */
}
This relies on BCE working properly so you can set the cell defaults to
anything of course.
Post by J Raynor
I've attached a new patch for pane colors. You use the display-panes
command to set the colors now, and the color changes take place in
tty_reset.
There's no bce stuff in this patch.
For bce, you mentioned a TTY_NOBCE flag. Could you give a little more
detail about what you're looking for? Where would this flag be set or
passed in?
For functions that need to check for bce support, like
tty_cmd_insertcharacter, the function needs to check whether there's
bce support, but also whether a default color has been set, unless you
want a tty without bce support to always fake things like ICH, EL, and
DCH, even if no color has been set. If you don't want to always fake
bce, then it seems a single flag won't work.
If you're just looking to keep things concise, there could be a
function that returns whether bce needs to be faked. For example, if
the patch attached to this email has been applied, here's a diff for
--- tty.c 2015-02-13 16:37:48.000000000 -0600
+++ tty.c.new 2015-02-13 18:34:49.000000000 -0600
@@ -830,7 +830,9 @@
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) &&
+ !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
No need to declare and set a fake_bce variable, or to do a color
check. The need_fake_bce function would take care of returning the
right info. Should I pursue a patch with bce support implemented
using that function?
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..1994aa4 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,18 +18,23 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
- * Display panes on a client.
+ * Display panes on a client, or get/set pane default fg/bg colours.
*/
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
+int cmd_display_panes_initgc(const char *, struct grid_cell **);
+
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "gt:A:P:W:", 0, 0,
+ "[-g] [-A style] [-P style] [-W style] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
};
@@ -37,13 +42,120 @@ const struct cmd_entry cmd_display_panes_entry = {
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ int nflags = 0;
+ struct grid_cell *gc;
+ const char *str;
+
+ if (args_has(args, 'g')) nflags++;
+ if (args_has(args, 'A')) nflags++;
+ if (args_has(args, 'P')) nflags++;
+ if (args_has(args, 'W')) nflags++;
+
+ if (nflags == 0) {
+
+ if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ server_set_identify(c);
+
+ return (CMD_RETURN_NORMAL);
+ }
- if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
- server_set_identify(c);
+ if (args_has(args, 'g')) {
+
+ if (nflags > 1) {
+ cmdq_error(cmdq, "don't use -A, -P, or -W with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ gc = wp->window->apcolgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "active-pane %s", str);
+
+
+ gc = wp->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "pane %s", str);
+
+
+ gc = wp->window->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "window %s", str);
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+
+ if (args_has(args, 'A')) {
+ if (cmd_display_panes_initgc(args_get(args, 'A'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->window->apcolgc);
+ wp->window->apcolgc = gc;
+ server_redraw_window(wp->window);
+ }
+
+ if (args_has(args, 'P')) {
+ if (cmd_display_panes_initgc(args_get(args, 'P'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->colgc);
+ wp->colgc = gc;
+ wp->flags |= PANE_REDRAW;
+ }
+
+ if (args_has(args, 'W')) {
+ if (cmd_display_panes_initgc(args_get(args, 'W'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->window->colgc);
+ wp->window->colgc = gc;
+ server_redraw_window(wp->window);
+ }
return (CMD_RETURN_NORMAL);
}
+
+int
+cmd_display_panes_initgc(const char *str, struct grid_cell **gcp)
+{
+ int ret;
+
+ if (*str == '\0')
+ *gcp = NULL;
+ else {
+ *gcp = xmalloc(sizeof **gcp);
+ memcpy(*gcp, &grid_default_cell, sizeof **gcp);
+ ret = style_parse(&grid_default_cell, *gcp, str);
+
+ if (ret == -1) {
+ free(*gcp);
+ return (ret);
+ }
+
+ (*gcp)->attr = grid_default_cell.attr;
+ }
+
+ return (0);
+}
diff --git a/colour.c b/colour.c
index 9e90596..eeb6625 100644
--- a/colour.c
+++ b/colour.c
@@ -287,3 +287,16 @@ colour_256to16(u_char c)
return (table[c]);
}
+
+const struct grid_cell *
+get_wp_default_grid_colours(const struct window_pane *wp)
+{
+ if (wp->colgc != NULL)
+ return (wp->colgc);
+
+ if (wp == wp->window->active && wp->window->apcolgc != NULL)
+ return (wp->window->apcolgc);
+
+
+ return (wp->window->colgc);
+}
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..9b1bb83 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -249,7 +249,7 @@ screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
screen_redraw_draw_panes(c, top);
if (draw_status)
screen_redraw_draw_status(c, top);
- tty_reset(tty);
+ tty_reset(tty, NULL);
}
/* Draw a single pane. */
@@ -266,8 +266,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
- tty_reset(&c->tty);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff, wp);
+ tty_reset(&c->tty, NULL);
}
/* Draw the borders. */
@@ -354,7 +354,7 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff, wp);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +367,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
diff --git a/server-client.c b/server-client.c
index 3ca9907..3206b6e 100644
--- a/server-client.c
+++ b/server-client.c
@@ -691,7 +691,7 @@ server_client_reset_state(struct client *c)
/* Set the terminal mode and reset attributes. */
tty_update_mode(&c->tty, mode, s);
- tty_reset(&c->tty);
+ tty_reset(&c->tty, NULL);
}
/* Repeat time callback. */
diff --git a/tmux.1 b/tmux.1
index f615dd0..ec13752 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1305,9 +1305,16 @@ flag, see the
.Sx FORMATS
section.
This command works only if at least one client is attached.
-.It Ic display-panes Op Fl t Ar target-client
+.It Xo Ic display-panes
+.Op Fl g
+.Op Fl A Ar style
+.Op Fl P Ar style
+.Op Fl W Ar style
+.Op Fl t Ar target-client
+.Xc
.D1 (alias: Ic displayp )
-Display a visible indicator of each pane shown by
+If no flags have been specified, display a visible indicator of
+each pane shown by
.Ar target-client .
See the
.Ic display-panes-time ,
@@ -1320,6 +1327,29 @@ While the indicator is on screen, a pane may be selected with the
to
.Ql 9
keys.
+.Pp
+With
+.Fl A
+,
+.Fl P
+, or
+.Fl W
+a style argument can be passed to change a window or pane's
+default foreground and background colour. The
+.Fl W
+flag will set the default colour style for panes in the window. The
+.Fl A
+flag will set the colour style a pane will have whenever it becomes the
+active pane in the window. The
+.Fl P
+flag will set the colour style for a pane, overriding whatever
+style has been set with
+.Fl W
+or
+.Fl A
+\&. To clear a style, specify the empty string. The
+.Fl g
+flag will show what colour styles have been set.
.It Xo Ic find-window
.Op Fl CNT
.Op Fl F Ar format
diff --git a/tmux.h b/tmux.h
index e296ac7..7635de7 100644
--- a/tmux.h
+++ b/tmux.h
@@ -900,6 +900,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell *colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -953,6 +956,10 @@ struct window {
struct options options;
+ /* Default fg/bg grid cell colours for window and active pane */
+ struct grid_cell *colgc;
+ struct grid_cell *apcolgc;
+
u_int references;
};
ARRAY_DECL(windows, struct window *);
@@ -1605,7 +1612,7 @@ void environ_push(struct environ *);
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
void tty_attributes(struct tty *, const struct grid_cell *);
-void tty_reset(struct tty *);
+void tty_reset(struct tty *, const struct window_pane *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
void tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
@@ -1628,7 +1635,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct window_pane *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
@@ -1956,6 +1964,7 @@ void colour_set_bg(struct grid_cell *, int);
const char *colour_tostring(int);
int colour_fromstring(const char *);
u_char colour_256to16(u_char);
+const struct grid_cell *get_wp_default_grid_colours(const struct window_pane *);
/* attributes.c */
const char *attributes_tostring(u_char);
diff --git a/tty.c b/tty.c
index 1bb8981..da1010e 100644
--- a/tty.c
+++ b/tty.c
@@ -604,19 +604,20 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct window_pane *wp)
{
- const struct grid_cell *gc;
+ const struct grid_cell *gc, *colgc = NULL;
struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, colourgc;
struct utf8_data ud;
u_int i, sx;
@@ -640,26 +641,40 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
(oy + py != tty->cy + 1 && tty->cy != s->rlower + oy))
tty_cursor(tty, ox, oy + py);
+ if (wp != NULL)
+ colgc = get_wp_default_grid_colours(wp);
+
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
+ memcpy(&colourgc, gc, sizeof *gc);
+ if (colgc != NULL && colourgc.fg == 8) {
+ colourgc.fg = colgc->fg;
+ colourgc.flags &= ~GRID_FLAG_FG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (colgc != NULL && colourgc.bg == 8) {
+ colourgc.bg = colgc->bg;
+ colourgc.flags &= ~GRID_FLAG_BG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
if (screen_check_selection(s, i, py)) {
memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
- grid_cell_get(gc, &ud);
+ grid_cell_get(&colourgc, &ud);
grid_cell_set(&tmpgc, &ud);
- tmpgc.flags = gc->flags &
+ tmpgc.flags = colourgc.flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
tty_cell(tty, &tmpgc);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, &colourgc);
}
if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
@@ -713,11 +728,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -725,7 +741,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_ICH1))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
}
void
@@ -736,11 +753,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
if (!tty_pane_full_width(tty, ctx) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -754,7 +772,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -776,7 +794,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -794,7 +812,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,7 +826,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
@@ -824,7 +842,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -837,7 +855,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -861,7 +879,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -894,7 +912,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,7 +927,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -942,7 +960,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -969,7 +987,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -997,7 +1015,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1015,6 +1033,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int cx;
u_int width;
+ struct grid_cell tmpgc;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
@@ -1043,7 +1065,22 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+
+ memcpy(&tmpgc, ctx->cell, sizeof tmpgc);
+ if (colgc != NULL) {
+ if (ctx->cell->fg == 8) {
+ tmpgc.fg = colgc->fg;
+ tmpgc.flags &= ~GRID_FLAG_FG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (ctx->cell->bg == 8) {
+ tmpgc.bg = colgc->bg;
+ tmpgc.flags &= ~GRID_FLAG_BG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
+ }
+
+ tty_cell(tty, &tmpgc);
}
void
@@ -1055,7 +1092,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, wp);
}
void
@@ -1088,7 +1125,7 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor(tty, 0, 0);
}
@@ -1131,17 +1168,26 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
}
void
-tty_reset(struct tty *tty)
+tty_reset(struct tty *tty, const struct window_pane *wp)
{
struct grid_cell *gc = &tty->cell;
+ const struct grid_cell *colgc = NULL;
- if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
+ if (wp != NULL)
+ colgc = get_wp_default_grid_colours(wp);
+
+ if (colgc == NULL &&
+ memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
return;
if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0);
memcpy(gc, &grid_default_cell, sizeof *gc);
+
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
+
}
/* Set region inside pane. */
@@ -1340,7 +1386,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc)
/* If any bits are being cleared, reset everything. */
if (tc->attr & ~gc2.attr)
- tty_reset(tty);
+ tty_reset(tty, NULL);
/*
* Set the colours. This may call tty_reset() (so it comes next) and
@@ -1409,7 +1455,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
*/
have_ax = tty_term_has(tty->term, TTYC_AX);
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
- tty_reset(tty);
+ tty_reset(tty, NULL);
else {
if (fg_default &&
(tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
diff --git a/window.c b/window.c
index 5412963..ca44cbe 100644
--- a/window.c
+++ b/window.c
@@ -288,6 +288,9 @@ window_create1(u_int sx, u_int sy)
w->sx = sx;
w->sy = sy;
+ w->colgc = NULL;
+ w->apcolgc = NULL;
+
options_init(&w->options, &global_w_options);
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
@@ -357,6 +360,8 @@ window_destroy(struct window *w)
window_destroy_panes(w);
free(w->name);
+ free(w->colgc);
+ free(w->apcolgc);
free(w);
}
@@ -704,6 +709,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ wp->colgc = NULL;
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
@@ -742,6 +749,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
close(wp->cwd);
+ free(wp->colgc);
free(wp->shell);
cmd_free_argv(wp->argc, wp->argv);
free(wp);
Nicholas Marriott
2015-02-14 09:46:50 UTC
Permalink
Almost all of the tty_reset will need to become tty_attributes for BCE
anyway so probably best to see where you are after that before worrying
too much about this anyway...
Post by Nicholas Marriott
Well, it's complicated a bit because tty_attributes calls tty_reset.
So perhaps it is better to check it in two places - tty_attributes and
tty_reset. tty_reset can send SETAB/SETAF after SGR0 if either fg or bg
is not 8.
Or the call to tty_reset in tty_attributes could become a different
function or just happen inside tty_attributes.
The idea I am going for is that you should replace fg=8 or bg=8 with the
wp colours at the bottom level, tty_attributes and tty_reset only.
Post by Nicholas Marriott
In fact, since you will need to change tty_reset to call
tty_attributes(&grid_default_cell) instead of sending SGR0, you will
only need to check the default colours in tty_attributes itself.
Post by J Raynor
if (!tty_term_has(tty->term, TTYC_BCE)
tty->flags |= TTY_NOBCE;
And use that instead of calling tty_term_has all the time. But actually
it probably makes little difference, just using tty_term_has is probably
fine.
- I don't think you need to allocate the gc with malloc, just put it
inside the wp directly and initialize it to grid_default_cell.
- You only need to swap it in if the current fg == 8 || bg == 8. You can
do this just in tty_reset and tty_attributes and it should catch
everything. You shouldn't need to change tty_draw_line except to take
a struct window_pane argument.
- I think the window colour can still be a window option but I would
drop it (or drop the pane colours and just do the window) for now and
add it as a separate change after one is working.
- I would drop get_wp_default_grid_colours in favour of a function in
void
tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
{
if (wp == NULL)
return;
if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
gc.fg = wp->colgc.fg;
gc.flags &= ~GRID_FLAG_FG256;
gc.flags |= (wp->colgc.flags & GRID_FLAG_FG256);
}
/* same for bg, you get the idea */
}
This relies on BCE working properly so you can set the cell defaults to
anything of course.
Post by J Raynor
I've attached a new patch for pane colors. You use the display-panes
command to set the colors now, and the color changes take place in
tty_reset.
There's no bce stuff in this patch.
For bce, you mentioned a TTY_NOBCE flag. Could you give a little more
detail about what you're looking for? Where would this flag be set or
passed in?
For functions that need to check for bce support, like
tty_cmd_insertcharacter, the function needs to check whether there's
bce support, but also whether a default color has been set, unless you
want a tty without bce support to always fake things like ICH, EL, and
DCH, even if no color has been set. If you don't want to always fake
bce, then it seems a single flag won't work.
If you're just looking to keep things concise, there could be a
function that returns whether bce needs to be faked. For example, if
the patch attached to this email has been applied, here's a diff for
--- tty.c 2015-02-13 16:37:48.000000000 -0600
+++ tty.c.new 2015-02-13 18:34:49.000000000 -0600
@@ -830,7 +830,9 @@
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) &&
+ !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
No need to declare and set a fake_bce variable, or to do a color
check. The need_fake_bce function would take care of returning the
right info. Should I pursue a patch with bce support implemented
using that function?
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..1994aa4 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,18 +18,23 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
- * Display panes on a client.
+ * Display panes on a client, or get/set pane default fg/bg colours.
*/
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
+int cmd_display_panes_initgc(const char *, struct grid_cell **);
+
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "gt:A:P:W:", 0, 0,
+ "[-g] [-A style] [-P style] [-W style] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
};
@@ -37,13 +42,120 @@ const struct cmd_entry cmd_display_panes_entry = {
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ int nflags = 0;
+ struct grid_cell *gc;
+ const char *str;
+
+ if (args_has(args, 'g')) nflags++;
+ if (args_has(args, 'A')) nflags++;
+ if (args_has(args, 'P')) nflags++;
+ if (args_has(args, 'W')) nflags++;
+
+ if (nflags == 0) {
+
+ if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ server_set_identify(c);
+
+ return (CMD_RETURN_NORMAL);
+ }
- if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
- server_set_identify(c);
+ if (args_has(args, 'g')) {
+
+ if (nflags > 1) {
+ cmdq_error(cmdq, "don't use -A, -P, or -W with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ gc = wp->window->apcolgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "active-pane %s", str);
+
+
+ gc = wp->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "pane %s", str);
+
+
+ gc = wp->window->colgc;
+ if (gc == NULL)
+ str = "\"\"";
+ else
+ str = style_tostring(gc);
+ cmdq_print(cmdq, "window %s", str);
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+
+ if (args_has(args, 'A')) {
+ if (cmd_display_panes_initgc(args_get(args, 'A'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->window->apcolgc);
+ wp->window->apcolgc = gc;
+ server_redraw_window(wp->window);
+ }
+
+ if (args_has(args, 'P')) {
+ if (cmd_display_panes_initgc(args_get(args, 'P'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->colgc);
+ wp->colgc = gc;
+ wp->flags |= PANE_REDRAW;
+ }
+
+ if (args_has(args, 'W')) {
+ if (cmd_display_panes_initgc(args_get(args, 'W'), &gc) == -1) {
+ cmdq_error(cmdq, "bad colour style");
+ return (CMD_RETURN_ERROR);
+ }
+ free(wp->window->colgc);
+ wp->window->colgc = gc;
+ server_redraw_window(wp->window);
+ }
return (CMD_RETURN_NORMAL);
}
+
+int
+cmd_display_panes_initgc(const char *str, struct grid_cell **gcp)
+{
+ int ret;
+
+ if (*str == '\0')
+ *gcp = NULL;
+ else {
+ *gcp = xmalloc(sizeof **gcp);
+ memcpy(*gcp, &grid_default_cell, sizeof **gcp);
+ ret = style_parse(&grid_default_cell, *gcp, str);
+
+ if (ret == -1) {
+ free(*gcp);
+ return (ret);
+ }
+
+ (*gcp)->attr = grid_default_cell.attr;
+ }
+
+ return (0);
+}
diff --git a/colour.c b/colour.c
index 9e90596..eeb6625 100644
--- a/colour.c
+++ b/colour.c
@@ -287,3 +287,16 @@ colour_256to16(u_char c)
return (table[c]);
}
+
+const struct grid_cell *
+get_wp_default_grid_colours(const struct window_pane *wp)
+{
+ if (wp->colgc != NULL)
+ return (wp->colgc);
+
+ if (wp == wp->window->active && wp->window->apcolgc != NULL)
+ return (wp->window->apcolgc);
+
+
+ return (wp->window->colgc);
+}
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..9b1bb83 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -249,7 +249,7 @@ screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
screen_redraw_draw_panes(c, top);
if (draw_status)
screen_redraw_draw_status(c, top);
- tty_reset(tty);
+ tty_reset(tty, NULL);
}
/* Draw a single pane. */
@@ -266,8 +266,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
- tty_reset(&c->tty);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff, wp);
+ tty_reset(&c->tty, NULL);
}
/* Draw the borders. */
@@ -354,7 +354,7 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff, wp);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +367,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
diff --git a/server-client.c b/server-client.c
index 3ca9907..3206b6e 100644
--- a/server-client.c
+++ b/server-client.c
@@ -691,7 +691,7 @@ server_client_reset_state(struct client *c)
/* Set the terminal mode and reset attributes. */
tty_update_mode(&c->tty, mode, s);
- tty_reset(&c->tty);
+ tty_reset(&c->tty, NULL);
}
/* Repeat time callback. */
diff --git a/tmux.1 b/tmux.1
index f615dd0..ec13752 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1305,9 +1305,16 @@ flag, see the
.Sx FORMATS
section.
This command works only if at least one client is attached.
-.It Ic display-panes Op Fl t Ar target-client
+.It Xo Ic display-panes
+.Op Fl g
+.Op Fl A Ar style
+.Op Fl P Ar style
+.Op Fl W Ar style
+.Op Fl t Ar target-client
+.Xc
.D1 (alias: Ic displayp )
-Display a visible indicator of each pane shown by
+If no flags have been specified, display a visible indicator of
+each pane shown by
.Ar target-client .
See the
.Ic display-panes-time ,
@@ -1320,6 +1327,29 @@ While the indicator is on screen, a pane may be selected with the
to
.Ql 9
keys.
+.Pp
+With
+.Fl A
+,
+.Fl P
+, or
+.Fl W
+a style argument can be passed to change a window or pane's
+default foreground and background colour. The
+.Fl W
+flag will set the default colour style for panes in the window. The
+.Fl A
+flag will set the colour style a pane will have whenever it becomes the
+active pane in the window. The
+.Fl P
+flag will set the colour style for a pane, overriding whatever
+style has been set with
+.Fl W
+or
+.Fl A
+\&. To clear a style, specify the empty string. The
+.Fl g
+flag will show what colour styles have been set.
.It Xo Ic find-window
.Op Fl CNT
.Op Fl F Ar format
diff --git a/tmux.h b/tmux.h
index e296ac7..7635de7 100644
--- a/tmux.h
+++ b/tmux.h
@@ -900,6 +900,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell *colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -953,6 +956,10 @@ struct window {
struct options options;
+ /* Default fg/bg grid cell colours for window and active pane */
+ struct grid_cell *colgc;
+ struct grid_cell *apcolgc;
+
u_int references;
};
ARRAY_DECL(windows, struct window *);
@@ -1605,7 +1612,7 @@ void environ_push(struct environ *);
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
void tty_attributes(struct tty *, const struct grid_cell *);
-void tty_reset(struct tty *);
+void tty_reset(struct tty *, const struct window_pane *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
void tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
@@ -1628,7 +1635,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct window_pane *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
@@ -1956,6 +1964,7 @@ void colour_set_bg(struct grid_cell *, int);
const char *colour_tostring(int);
int colour_fromstring(const char *);
u_char colour_256to16(u_char);
+const struct grid_cell *get_wp_default_grid_colours(const struct window_pane *);
/* attributes.c */
const char *attributes_tostring(u_char);
diff --git a/tty.c b/tty.c
index 1bb8981..da1010e 100644
--- a/tty.c
+++ b/tty.c
@@ -604,19 +604,20 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct window_pane *wp)
{
- const struct grid_cell *gc;
+ const struct grid_cell *gc, *colgc = NULL;
struct grid_line *gl;
- struct grid_cell tmpgc;
+ struct grid_cell tmpgc, colourgc;
struct utf8_data ud;
u_int i, sx;
@@ -640,26 +641,40 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
(oy + py != tty->cy + 1 && tty->cy != s->rlower + oy))
tty_cursor(tty, ox, oy + py);
+ if (wp != NULL)
+ colgc = get_wp_default_grid_colours(wp);
+
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
+ memcpy(&colourgc, gc, sizeof *gc);
+ if (colgc != NULL && colourgc.fg == 8) {
+ colourgc.fg = colgc->fg;
+ colourgc.flags &= ~GRID_FLAG_FG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (colgc != NULL && colourgc.bg == 8) {
+ colourgc.bg = colgc->bg;
+ colourgc.flags &= ~GRID_FLAG_BG256;
+ colourgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
if (screen_check_selection(s, i, py)) {
memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
- grid_cell_get(gc, &ud);
+ grid_cell_get(&colourgc, &ud);
grid_cell_set(&tmpgc, &ud);
- tmpgc.flags = gc->flags &
+ tmpgc.flags = colourgc.flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
tty_cell(tty, &tmpgc);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, &colourgc);
}
if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
@@ -713,11 +728,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -725,7 +741,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_ICH1))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
}
void
@@ -736,11 +753,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
if (!tty_pane_full_width(tty, ctx) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -754,7 +772,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -776,7 +794,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -794,7 +812,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,7 +826,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
@@ -824,7 +842,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -837,7 +855,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -861,7 +879,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -894,7 +912,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,7 +927,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -942,7 +960,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -969,7 +987,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -997,7 +1015,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1015,6 +1033,10 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int cx;
u_int width;
+ struct grid_cell tmpgc;
+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
@@ -1043,7 +1065,22 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+
+ memcpy(&tmpgc, ctx->cell, sizeof tmpgc);
+ if (colgc != NULL) {
+ if (ctx->cell->fg == 8) {
+ tmpgc.fg = colgc->fg;
+ tmpgc.flags &= ~GRID_FLAG_FG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_FG256);
+ }
+ if (ctx->cell->bg == 8) {
+ tmpgc.bg = colgc->bg;
+ tmpgc.flags &= ~GRID_FLAG_BG256;
+ tmpgc.flags |= (colgc->flags & GRID_FLAG_BG256);
+ }
+ }
+
+ tty_cell(tty, &tmpgc);
}
void
@@ -1055,7 +1092,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, wp);
}
void
@@ -1088,7 +1125,7 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor(tty, 0, 0);
}
@@ -1131,17 +1168,26 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
}
void
-tty_reset(struct tty *tty)
+tty_reset(struct tty *tty, const struct window_pane *wp)
{
struct grid_cell *gc = &tty->cell;
+ const struct grid_cell *colgc = NULL;
- if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
+ if (wp != NULL)
+ colgc = get_wp_default_grid_colours(wp);
+
+ if (colgc == NULL &&
+ memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
return;
if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0);
memcpy(gc, &grid_default_cell, sizeof *gc);
+
+ if (colgc != NULL)
+ tty_attributes(tty, colgc);
+
}
/* Set region inside pane. */
@@ -1340,7 +1386,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc)
/* If any bits are being cleared, reset everything. */
if (tc->attr & ~gc2.attr)
- tty_reset(tty);
+ tty_reset(tty, NULL);
/*
* Set the colours. This may call tty_reset() (so it comes next) and
@@ -1409,7 +1455,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
*/
have_ax = tty_term_has(tty->term, TTYC_AX);
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
- tty_reset(tty);
+ tty_reset(tty, NULL);
else {
if (fg_default &&
(tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
diff --git a/window.c b/window.c
index 5412963..ca44cbe 100644
--- a/window.c
+++ b/window.c
@@ -288,6 +288,9 @@ window_create1(u_int sx, u_int sy)
w->sx = sx;
w->sy = sy;
+ w->colgc = NULL;
+ w->apcolgc = NULL;
+
options_init(&w->options, &global_w_options);
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
@@ -357,6 +360,8 @@ window_destroy(struct window *w)
window_destroy_panes(w);
free(w->name);
+ free(w->colgc);
+ free(w->apcolgc);
free(w);
}
@@ -704,6 +709,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ wp->colgc = NULL;
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
@@ -742,6 +749,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
close(wp->cwd);
+ free(wp->colgc);
free(wp->shell);
cmd_free_argv(wp->argc, wp->argv);
free(wp);
J Raynor
2015-02-14 21:50:11 UTC
Permalink
Post by Nicholas Marriott
- I don't think you need to allocate the gc with malloc, just put it
inside the wp directly and initialize it to grid_default_cell.
I do need to allocate it with malloc. If I don't, it's always there
(not NULL), so it'll always have some value. That makes it impossible
to tell what to do when wp->colgc == 8. Does that mean the pane's
background should be the terminal default, or does that mean the user
wanted this option unset, so that it takes the window's bg value?

Note that wp->colgc does not always exist. It only exists (isn't
NULL) if a user has explicitly set a color for a particular pane.
Otherwise, it will be NULL, and the pane will get its color from the
window, either w->apcolgc if the pane is the active pane and
w->apcolgc isn't NULL, or just the window's default color (w->colgc),
or the default terminal colors if w->colgc is NULL.
Post by Nicholas Marriott
You shouldn't need to change tty_draw_line except to take
a struct window_pane argument.
No, I need the loop in tty_draw_line to modify the cells it pulls from
grid_view_peek to have the pane's default colors. Otherwise, after a
redraw, the text on a pane will have the terminal's default colors,
and just the EL would get the pane's defaults.
Post by Nicholas Marriott
- I think the window colour can still be a window option but I would
drop it (or drop the pane colours and just do the window) for now and
add it as a separate change after one is working.
Well, I suppose the window's color could be a window option. But the
pane's color can't be, and it would be awkward for the active-pane's
color to be one since it couldn't be a style. It'd have to be a
string so you could set it to the empty string, otherwise it'd look
like a style was always set. It seems odd to have different ways of
setting the colors.
Post by Nicholas Marriott
- I would drop get_wp_default_grid_colours in favour of a function in
Your function would only work if someone had set an explicit color for
the pane. And to get it to take the window's color and active-pane
color into account would make it look much like
get_wp_default_grid_colours.

Based on what you've written, I wonder if you've got a different idea
in mind on how setting a color works. Another way to do it (maybe
what you had in mind?) would be to set the color for a pane when it is
created. This way, a pane would always need wp->colgc, so it wouldn't
make sense to malloc it. This could be updated when a user switches
which pane is active, or explicitly sets a color. Also, if the pane
stores its current color, you wouldn't have to figure it out with a
function like get_wp_default_grid_colours. But you would need a flag
to tell if the user had explicitly set the color or not, otherwise you
wouldn't know if it was ok to update it when the window or active-pane
colors were changed.

Is that the model you had in mind? I think we have to make sure we're
on the same page about this before I can proceed.
Nicholas Marriott
2015-02-14 23:36:58 UTC
Permalink
Post by J Raynor
Post by Nicholas Marriott
- I don't think you need to allocate the gc with malloc, just put it
inside the wp directly and initialize it to grid_default_cell.
I do need to allocate it with malloc. If I don't, it's always there
(not NULL), so it'll always have some value. That makes it impossible
to tell what to do when wp->colgc == 8. Does that mean the pane's
background should be the terminal default, or does that mean the user
wanted this option unset, so that it takes the window's bg value?
Note that wp->colgc does not always exist. It only exists (isn't
NULL) if a user has explicitly set a color for a particular pane.
Otherwise, it will be NULL, and the pane will get its color from the
window, either w->apcolgc if the pane is the active pane and
w->apcolgc isn't NULL, or just the window's default color (w->colgc),
or the default terminal colors if w->colgc is NULL.
Yes panes should always have colours. If the pane is set to 8, it uses
the window, if the window is 8, it uses the default. It isn't necessary
to have a way to set the pane directly to default, we don't have that
for any other style - it always follows the hierarchy (like eg the status
line options).
Post by J Raynor
Post by Nicholas Marriott
You shouldn't need to change tty_draw_line except to take
a struct window_pane argument.
No, I need the loop in tty_draw_line to modify the cells it pulls from
grid_view_peek to have the pane's default colors. Otherwise, after a
redraw, the text on a pane will have the terminal's default colors,
and just the EL would get the pane's defaults.
No, I think you don't - tty_draw_line draws on screen using tty_cell and
that calls tty_attributes. There should be no way to get stuff on screen
that doesn't set colours via either tty_reset or tty_attributes. If you
change those two, it should be enough.
Post by J Raynor
Post by Nicholas Marriott
- I think the window colour can still be a window option but I would
drop it (or drop the pane colours and just do the window) for now and
add it as a separate change after one is working.
Well, I suppose the window's color could be a window option. But the
pane's color can't be, and it would be awkward for the active-pane's
color to be one since it couldn't be a style. It'd have to be a
string so you could set it to the empty string, otherwise it'd look
like a style was always set. It seems odd to have different ways of
setting the colors.
We have window options and I'd prefer to use them. Panes are a special
case, windows do not need to be.
Post by J Raynor
Post by Nicholas Marriott
- I would drop get_wp_default_grid_colours in favour of a function in
Your function would only work if someone had set an explicit color for
the pane. And to get it to take the window's color and active-pane
color into account would make it look much like
get_wp_default_grid_colours.
Not quite. get_wp_default_grid_colours returns a gc which you then apply
in the caller. I think you should have a function that updates a gc if
its fg or bg is set to 8.
Post by J Raynor
Based on what you've written, I wonder if you've got a different idea
in mind on how setting a color works. Another way to do it (maybe
what you had in mind?) would be to set the color for a pane when it is
created. This way, a pane would always need wp->colgc, so it wouldn't
make sense to malloc it. This could be updated when a user switches
which pane is active, or explicitly sets a color. Also, if the pane
stores its current color, you wouldn't have to figure it out with a
function like get_wp_default_grid_colours. But you would need a flag
to tell if the user had explicitly set the color or not, otherwise you
wouldn't know if it was ok to update it when the window or active-pane
colors were changed.
Almost. Panes should always have two colours - one for normal, one for
active. They may be 8 for the default colour. Both colours should start
with grid_default_cell and the user can change with display-panes. You
don't need a flag, the pane's colours are always there, the user sets
them to default to use the window's colours instead.

So your function actually looks something like:

void
tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
{
const struct grid_cell *pgc, *wgc;

if (wp == NULL)
return;

if (wp == wp->window->active)
pgc = &wp->active_colgc;
else
pgc = &wp->colgc;
wgc = options_get_style(&wp->window->options, "window-style");

if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
gc.flags &= ~GRID_FLAG_FG256;
if (pgc->fg == 8 && !(pgc->flags & GRID_FLAG_FG256)) {
gc.fg = wgc->fg;
gc.flags |= (wgc->flags & GRID_FLAG_FG256);
} else {
gc.fg = pgc->fg;
gc.flags |= (pgc->flags & GRID_FLAG_FG256);
}
}
if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) {
gc.flags &= ~GRID_FLAG_BG256;
if (pgc->bg == 8 && !(pgc->flags & GRID_FLAG_BG256)) {
gc.bg = wgc->bg;
gc.flags |= (wgc->flags & GRID_FLAG_BG256);
} else {
gc.bg = pgc->bg;
gc.flags |= (pgc->flags & GRID_FLAG_BG256);
}
}
}

Then you can call this from tty_attributes and also change it to send
SGR0 directly rather than use tty_reset. After that, tty_reset can call
tty_attributes.
Post by J Raynor
Is that the model you had in mind? I think we have to make sure we're
on the same page about this before I can proceed.
J Raynor
2015-02-16 06:26:44 UTC
Permalink
Post by Nicholas Marriott
Yes panes should always have colours. If the pane is set to 8, it uses
the window, if the window is 8, it uses the default. It isn't necessary
to have a way to set the pane directly to default, we don't have that
for any other style - it always follows the hierarchy (like eg the status
line options).
You'd still be following the hierarchy by allowing users to set a
pane's color to the terminal default. Note that in this case, the
word "default" is referring to the terminal emulator's color, the
actual color used by the terminal emulator window. It doesn't refer
to the "default" option that would be set in options-table.c, so you
aren't bypassing the hierarchy.

I suppose I just see this as 1 more color. You can set a pane's bg to
blue, or colour133, or "terminal default". Users might like the
ability to refer to the terminal's default color since the emulator
isn't limited to the 256 colors that the tty is. Still against it?
Post by Nicholas Marriott
No, I think you don't - tty_draw_line draws on screen using tty_cell and
that calls tty_attributes. There should be no way to get stuff on screen
that doesn't set colours via either tty_reset or tty_attributes. If you
change those two, it should be enough.
You really do. I have tested this. The color option doesn't change
what gets stored in the grid lines, it just changes what gets
displayed when tmux is going to write a cell that would have been
written with the terminal's default colors. Assuming the user didn't
use setaf/setab, then the colors stored in the grid lines will be 8.
Yes, tty_draw_line calls tty_cell, and that calls tty_attributes, but
if you don't fix up the grid_cell returned by grid_view_peek, then the
grid cell that gets passed to tty_attributes will have fg/bg set to 8.
Post by Nicholas Marriott
We have window options and I'd prefer to use them. Panes are a special
case, windows do not need to be.
I think the active-pane color setting could also be a window option if
we don't allow a user to specify "terminal default" as a color option,
as I talked about regarding panes in the first 2 paragraphs of this
email. Should it be a window option? If so, this would change how
your tty_default_colours function is implemented slightly.
Nicholas Marriott
2015-02-16 08:28:23 UTC
Permalink
Post by J Raynor
Post by Nicholas Marriott
Yes panes should always have colours. If the pane is set to 8, it uses
the window, if the window is 8, it uses the default. It isn't necessary
to have a way to set the pane directly to default, we don't have that
for any other style - it always follows the hierarchy (like eg the status
line options).
You'd still be following the hierarchy by allowing users to set a
pane's color to the terminal default. Note that in this case, the
word "default" is referring to the terminal emulator's color, the
actual color used by the terminal emulator window. It doesn't refer
to the "default" option that would be set in options-table.c, so you
aren't bypassing the hierarchy.
I suppose I just see this as 1 more color. You can set a pane's bg to
blue, or colour133, or "terminal default". Users might like the
ability to refer to the terminal's default color since the emulator
isn't limited to the 256 colors that the tty is. Still against it?
Yes. When the pane background is set to colour 8, it should use the
window background. Only if the window background is set to colour 8 too
should it send an actual default colour \033[49m to the terminal. There
is no need to allow people to set a pane background directly to colour
8. This is how window-status-style etc works, they apply on top of
status-style.
Post by J Raynor
Post by Nicholas Marriott
No, I think you don't - tty_draw_line draws on screen using tty_cell and
that calls tty_attributes. There should be no way to get stuff on screen
that doesn't set colours via either tty_reset or tty_attributes. If you
change those two, it should be enough.
You really do. I have tested this. The color option doesn't change
what gets stored in the grid lines, it just changes what gets
displayed when tmux is going to write a cell that would have been
written with the terminal's default colors. Assuming the user didn't
use setaf/setab, then the colors stored in the grid lines will be 8.
Yes, tty_draw_line calls tty_cell, and that calls tty_attributes, but
if you don't fix up the grid_cell returned by grid_view_peek, then the
grid cell that gets passed to tty_attributes will have fg/bg set to 8.
You don't need to change tty_draw_line IF you change tty_attributes
instead. You WANT the grid cell that gets passed to tty_attributes to
have colour 8. Then tty_attributes knows it wants the pane colour. If
you change tty_attributes, you should never need to change the grid cell
in any caller of tty_attributes, including tty_draw_line.

Colour 8 means whatever the user has set to the pane background, nothing
except tty_attributes and friends should need to know what the actual
colour will be.

We don't have tty_draw_line convert background colour 8 to 0 if the
terminal doesn't support default colours - it is done in tty_colours via
tty_attributes - and it should not do this either.

You may end up actually changing tty_colours, not tty_attributes, but
the point is the same. All the places in your diff where you do:

+ const struct grid_cell *colgc;
+
+ colgc = get_wp_default_grid_colours(wp);

tty_reset(tty);
+ if (colgc != NULL)
+ tty_colours(tty, colgc);

You can just change the entire section including tty_reset into:

tty_attributes(tty, &grid_default_cell, wp);

Or if you do all the work in tty_colours:

tty_colours(tty, wp);

tty_draw_line will get it for free when tty_attributes does it, because
tty_cell calls tty_attributes. All you will need to do is change it to
pass the wp into tty_cell.
Post by J Raynor
Post by Nicholas Marriott
We have window options and I'd prefer to use them. Panes are a special
case, windows do not need to be.
I think the active-pane color setting could also be a window option if
we don't allow a user to specify "terminal default" as a color option,
as I talked about regarding panes in the first 2 paragraphs of this
email. Should it be a window option? If so, this would change how
your tty_default_colours function is implemented slightly.
J Raynor
2015-02-19 07:49:14 UTC
Permalink
I've attached a new patch. There are 2 new window options,
window-style and window-active-style, that allow you to set the
window's color and the window's active pane color. The display-panes
command can still be used to set an explicit pane color with -P.

tty_attributes now takes a window pane argument, and tty_draw_lines
doesn't mess with the grid cells itself. tty_reset calls
tty_attributes, but I'm not sure I understood exactly what you were
looking for here.
Thomas Adam
2015-02-19 08:27:57 UTC
Permalink
Post by J Raynor
I've attached a new patch. There are 2 new window options,
window-style and window-active-style, that allow you to set the
window's color and the window's active pane color. The display-panes
command can still be used to set an explicit pane color with -P.
tty_attributes now takes a window pane argument, and tty_draw_lines
doesn't mess with the grid cells itself. tty_reset calls
tty_attributes, but I'm not sure I understood exactly what you were
looking for here.
It's _still_ missing a fix in server-client. See the following:


diff --git a/server-client.c b/server-client.c
index 3ca9907..a847777 100644
--- a/server-client.c
+++ b/server-client.c
@@ -329,6 +329,7 @@ server_client_check_mouse(struct client *c, struct window_pane *wp)
(m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
window_set_active_at(wp->window, m->x, m->y);
server_status_window(wp->window);
+ server_redraw_window(wp->window);
server_redraw_window_borders(wp->window);
wp = wp->window->active; /* may have changed */
}

-- Thomas Adam
Nicholas Marriott
2015-02-19 10:35:59 UTC
Permalink
screen_redraw_window implies status and borders, so can remove those.
Post by J Raynor
Post by J Raynor
I've attached a new patch. There are 2 new window options,
window-style and window-active-style, that allow you to set the
window's color and the window's active pane color. The display-panes
command can still be used to set an explicit pane color with -P.
tty_attributes now takes a window pane argument, and tty_draw_lines
doesn't mess with the grid cells itself. tty_reset calls
tty_attributes, but I'm not sure I understood exactly what you were
looking for here.
diff --git a/server-client.c b/server-client.c
index 3ca9907..a847777 100644
--- a/server-client.c
+++ b/server-client.c
@@ -329,6 +329,7 @@ server_client_check_mouse(struct client *c, struct window_pane *wp)
(m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
window_set_active_at(wp->window, m->x, m->y);
server_status_window(wp->window);
+ server_redraw_window(wp->window);
server_redraw_window_borders(wp->window);
wp = wp->window->active; /* may have changed */
}
-- Thomas Adam
J Raynor
2015-02-19 18:21:37 UTC
Permalink
I checked back over the emails for my patch, but I don't see any
mention of mouse events. Was there a discussion off list? If so,
I'll need to know what else you've found wrong. I can't fix it if I
don't know about it.
Post by J Raynor
diff --git a/server-client.c b/server-client.c
index 3ca9907..a847777 100644
--- a/server-client.c
+++ b/server-client.c
@@ -329,6 +329,7 @@ server_client_check_mouse(struct client *c, struct window_pane *wp)
(m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
window_set_active_at(wp->window, m->x, m->y);
server_status_window(wp->window);
+ server_redraw_window(wp->window);
server_redraw_window_borders(wp->window);
wp = wp->window->active; /* may have changed */
}
-- Thomas Adam
Thomas Adam
2015-02-19 21:36:36 UTC
Permalink
Post by J Raynor
I checked back over the emails for my patch, but I don't see any
mention of mouse events. Was there a discussion off list? If so,
I'll need to know what else you've found wrong. I can't fix it if I
don't know about it.
I mentioned it to you. You said you'd incorporate those things into
subsequent patches. The diff is here:

https://github.com/ThomasAdam/tmux/commit/f85a0fcfe9cc54aecdca205e2f2c93cce2235d47.patch

-- Thomas Adam
--
"Deep in my heart I wish I was wrong. But deep in my heart I know I am
not." -- Morrissey ("Girl Least Likely To" -- off of Viva Hate.)
J Raynor
2015-02-19 23:26:46 UTC
Permalink
Sorry. I looked at your larger patch, but the brief summary of the
other one (update window on mouse-select-pane) seemed unrelated, like
it was for something else you were working on, so I didn't look at it.

But I've seen it now, and I'll add it to the next patch.
Post by Thomas Adam
Post by J Raynor
I checked back over the emails for my patch, but I don't see any
mention of mouse events. Was there a discussion off list? If so,
I'll need to know what else you've found wrong. I can't fix it if I
don't know about it.
I mentioned it to you. You said you'd incorporate those things into
https://github.com/ThomasAdam/tmux/commit/f85a0fcfe9cc54aecdca205e2f2c93cce2235d47.patch
-- Thomas Adam
--
"Deep in my heart I wish I was wrong. But deep in my heart I know I am
not." -- Morrissey ("Girl Least Likely To" -- off of Viva Hate.)
Nicholas Marriott
2015-02-19 10:31:26 UTC
Permalink
This looks pretty good.

tty_reset is not right. I've had another look and I don't think you need
to change the function itself, just the tty_cmd_* calls.

There are three reasons to call tty_reset:

1) It is called by, for example, tty_cmd_insertline, to set the colours
and attributes to OUR pane defaults.

2) It is called by tty_attributes to reset the attributes.

3) It is called by server_client_reset_state to reset everything to the
terminal defaults in case tmux is killed abruptly.

I think that it is enough to change all of case (1) just to:

tty_attributes(tty, &grid_default_cell, wp);

Which should leave the terminal with the attributes reset and the
colours set to our defaults (pane, window, whatever tty_default_colours
decides)

And then leave cases (2) and (3) calling the original, unchanged
tty_reset itself.

It'll be important to remember that in all grid_cells colour 8 means our
default EXCEPT for tty->cell where it means the terminal default.

Does this make sense?

Also a couple of minor nits:

- I think cmd_display_panes_exec would be clearer without nflags now, it
can just call args_has in the if statements.

- memcpy should always use the size of the destination not the source or
you are asking for overruns. There is only one that is wrong, in
window.c
Post by J Raynor
I've attached a new patch. There are 2 new window options,
window-style and window-active-style, that allow you to set the
window's color and the window's active pane color. The display-panes
command can still be used to set an explicit pane color with -P.
tty_attributes now takes a window pane argument, and tty_draw_lines
doesn't mess with the grid cells itself. tty_reset calls
tty_attributes, but I'm not sure I understood exactly what you were
looking for here.
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..9d87893 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,18 +18,21 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
- * Display panes on a client.
+ * Display panes on a client, or get/set pane default fg/bg colours.
*/
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "gt:P:", 0, 0,
+ "[-g] [-P style] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
};
@@ -37,13 +40,52 @@ const struct cmd_entry cmd_display_panes_entry = {
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ int nflags = 0;
+ const char *str;
+
+ if (args_has(args, 'g')) nflags++;
+ if (args_has(args, 'P')) nflags++;
+
+ if (nflags == 0) {
+
+ if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ server_set_identify(c);
+
+ return (CMD_RETURN_NORMAL);
+ }
- if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
- server_set_identify(c);
+ if (args_has(args, 'g')) {
+
+ if (nflags > 1) {
+ cmdq_error(cmdq, "don't use -P with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'P')) {
+ str = args_get(args, 'P');
+ if (style_parse(&grid_default_cell, &wp->colgc, str) == -1) {
+ cmdq_error(cmdq, "bad style: %s", str);
+ return (CMD_RETURN_ERROR);
+ }
+
+ wp->flags |= PANE_REDRAW;
+ }
return (CMD_RETURN_NORMAL);
}
diff --git a/options-table.c b/options-table.c
index 2bcf29b..d7057bf 100644
--- a/options-table.c
+++ b/options-table.c
@@ -667,6 +667,16 @@ const struct options_table_entry window_options_table[] = {
.default_num = 0 /* overridden in main() */
},
+ { .name = "window-active-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
+ { .name = "window-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
{ .name = "window-status-activity-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE,
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..ab0b4b3 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -249,7 +249,7 @@ screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
screen_redraw_draw_panes(c, top);
if (draw_status)
screen_redraw_draw_status(c, top);
- tty_reset(tty);
+ tty_reset(tty, NULL);
}
/* Draw a single pane. */
@@ -266,8 +266,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
- tty_reset(&c->tty);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff, wp);
+ tty_reset(&c->tty, NULL);
}
/* Draw the borders. */
@@ -323,9 +323,9 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top)
small && i > msgx && j == msgy)
continue;
if (screen_redraw_check_active(i, j, type, w, wp))
- tty_attributes(tty, &active_gc);
+ tty_attributes(tty, &active_gc, wp);
else
- tty_attributes(tty, &other_gc);
+ tty_attributes(tty, &other_gc, wp);
tty_cursor(tty, i, top + j);
tty_putc(tty, CELL_BORDERS[type]);
}
@@ -333,7 +333,7 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top)
if (small) {
memcpy(&msg_gc, &grid_default_cell, sizeof msg_gc);
- tty_attributes(tty, &msg_gc);
+ tty_attributes(tty, &msg_gc, wp);
tty_cursor(tty, msgx, msgy);
tty_puts(tty, msg);
}
@@ -354,7 +354,7 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff, wp);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +367,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
@@ -411,7 +411,7 @@ screen_redraw_draw_number(struct client *c, struct window_pane *wp)
colour_set_bg(&gc, active_colour);
else
colour_set_bg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
for (ptr = buf; *ptr != '\0'; ptr++) {
if (*ptr < '0' || *ptr > '9')
continue;
colour_set_fg(&gc, active_colour);
else
colour_set_fg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
tty_puts(tty, buf);
tty_cursor(tty, 0, 0);
diff --git a/server-client.c b/server-client.c
index 3ca9907..3206b6e 100644
--- a/server-client.c
+++ b/server-client.c
@@ -691,7 +691,7 @@ server_client_reset_state(struct client *c)
/* Set the terminal mode and reset attributes. */
tty_update_mode(&c->tty, mode, s);
- tty_reset(&c->tty);
+ tty_reset(&c->tty, NULL);
}
/* Repeat time callback. */
diff --git a/tmux.h b/tmux.h
index e296ac7..3bd781a 100644
--- a/tmux.h
+++ b/tmux.h
@@ -900,6 +900,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -1604,8 +1607,9 @@ void environ_push(struct environ *);
/* tty.c */
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
-void tty_attributes(struct tty *, const struct grid_cell *);
-void tty_reset(struct tty *);
+void tty_attributes(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
+void tty_reset(struct tty *, const struct window_pane *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
void tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
@@ -1628,7 +1632,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct window_pane *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
diff --git a/tty.c b/tty.c
index 1bb8981..a3f7c83 100644
--- a/tty.c
+++ b/tty.c
@@ -47,7 +47,9 @@ void tty_redraw_region(struct tty *, const struct tty_ctx *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_repeat_space(struct tty *, u_int);
-void tty_cell(struct tty *, const struct grid_cell *);
+void tty_cell(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
+void tty_default_colours(struct grid_cell *, const struct window_pane *);
#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -604,15 +606,16 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct window_pane *wp)
{
const struct grid_cell *gc;
struct grid_line *gl;
@@ -650,16 +653,16 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
- tty_cell(tty, &tmpgc);
+ tty_cell(tty, &tmpgc, wp);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, gc, wp);
}
if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
@@ -713,11 +716,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -725,7 +729,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_ICH1))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
}
void
@@ -736,11 +741,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
if (!tty_pane_full_width(tty, ctx) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -754,7 +760,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -776,7 +782,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -794,7 +800,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,7 +814,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
@@ -824,7 +830,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -837,7 +843,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -861,7 +867,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -894,7 +900,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,7 +915,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -942,7 +948,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -969,7 +975,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -997,7 +1003,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1038,12 +1044,12 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
*/
cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
tty_cursor_pane(tty, ctx, cx, ctx->ocy);
- tty_cell(tty, &ctx->last_cell);
+ tty_cell(tty, &ctx->last_cell, wp);
}
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+ tty_cell(tty, ctx->cell, wp);
}
void
@@ -1055,7 +1061,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, wp);
}
void
@@ -1088,12 +1094,13 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor(tty, 0, 0);
}
void
-tty_cell(struct tty *tty, const struct grid_cell *gc)
+tty_cell(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct utf8_data ud;
u_int i;
@@ -1108,7 +1115,7 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
return;
/* Set the attributes. */
- tty_attributes(tty, gc);
+ tty_attributes(tty, gc, wp);
/* Get the cell and if ASCII write with putc to do ACS translation. */
grid_cell_get(gc, &ud);
@@ -1131,17 +1138,22 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
}
void
-tty_reset(struct tty *tty)
+tty_reset(struct tty *tty, const struct window_pane *wp)
{
struct grid_cell *gc = &tty->cell;
+ struct grid_cell colgc;
- if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
+ memcpy(&colgc, &grid_default_cell, sizeof colgc);
+ tty_default_colours(&colgc, wp);
+
+ if (memcmp(gc, &colgc, sizeof *gc) == 0)
return;
if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0);
memcpy(gc, &grid_default_cell, sizeof *gc);
+ tty_attributes(tty, &colgc, wp);
}
/* Set region inside pane. */
}
void
-tty_attributes(struct tty *tty, const struct grid_cell *gc)
+tty_attributes(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct grid_cell *tc = &tty->cell, gc2;
u_char changed;
memcpy(&gc2, gc, sizeof gc2);
+ tty_default_colours(&gc2, wp);
/*
* If no setab, try to use the reverse attribute as a best-effort for a
@@ -1340,7 +1354,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc)
/* If any bits are being cleared, reset everything. */
if (tc->attr & ~gc2.attr)
- tty_reset(tty);
+ tty_reset(tty, wp);
/*
* Set the colours. This may call tty_reset() (so it comes next) and
@@ -1409,7 +1423,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
*/
have_ax = tty_term_has(tty->term, TTYC_AX);
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
- tty_reset(tty);
+ tty_reset(tty, NULL);
else {
if (fg_default &&
(tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
@@ -1614,3 +1628,44 @@ tty_bell(struct tty *tty)
{
tty_putcode(tty, TTYC_BEL);
}
+
+void
+tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
+{
+ const struct grid_cell *agc, *pgc, *wgc;
+
+ if (wp == NULL)
+ return;
+
+ pgc = &wp->colgc;
+ agc = options_get_style(&wp->window->options, "window-active-style");
+ wgc = options_get_style(&wp->window->options, "window-style");
+
+ if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
+ if (pgc->fg != 8 || (pgc->flags & GRID_FLAG_FG256)) {
+ gc->fg = pgc->fg;
+ gc->flags |= (pgc->flags & GRID_FLAG_FG256);
+ } else if (wp == wp->window->active &&
+ (agc->fg != 8 || (agc->flags & GRID_FLAG_FG256))) {
+ gc->fg = agc->fg;
+ gc->flags |= (agc->flags & GRID_FLAG_FG256);
+ } else {
+ gc->fg = wgc->fg;
+ gc->flags |= (wgc->flags & GRID_FLAG_FG256);
+ }
+ }
+
+ if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) {
+ if (pgc->bg != 8 || (pgc->flags & GRID_FLAG_BG256)) {
+ gc->bg = pgc->bg;
+ gc->flags |= (pgc->flags & GRID_FLAG_BG256);
+ } else if (wp == wp->window->active &&
+ (agc->bg != 8 || (agc->flags & GRID_FLAG_BG256))) {
+ gc->bg = agc->bg;
+ gc->flags |= (agc->flags & GRID_FLAG_BG256);
+ } else {
+ gc->bg = wgc->bg;
+ gc->flags |= (wgc->flags & GRID_FLAG_BG256);
+ }
+ }
+}
diff --git a/window.c b/window.c
index fff2cfc..cc1377f 100644
--- a/window.c
+++ b/window.c
@@ -704,6 +704,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ memcpy(&wp->colgc, &grid_default_cell, sizeof grid_default_cell);
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
J Raynor
2015-02-20 05:26:58 UTC
Permalink
I've attached a new patch. This patch:

* Adds Thomas's fix for pane selection via the mouse
* Gets rid of nflags in cmd_display_panes_exec
* Fixes the usage of memcpy in window.c
* Leaves tty_reset unchanged
* Has the tty_cmd_* functions call tty_attributes instead of tty_reset
* Includes updates to the man page
Nicholas Marriott
2015-02-22 06:52:11 UTC
Permalink
This looks good now, thanks, although I will need to find some time to
play with it a bit. We still have the question of terminals without
BCE. You can try to make tmux itself support BCE if you like which would
be nice and have a bit of overlap with this diff, or add BCE support
back on top of this like you had before.
Post by J Raynor
* Adds Thomas's fix for pane selection via the mouse
* Gets rid of nflags in cmd_display_panes_exec
* Fixes the usage of memcpy in window.c
* Leaves tty_reset unchanged
* Has the tty_cmd_* functions call tty_attributes instead of tty_reset
* Includes updates to the man page
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..2cc29e4 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,18 +18,21 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
- * Display panes on a client.
+ * Display panes on a client, or get/set pane default fg/bg colours.
*/
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "gt:P:", 0, 0,
+ "[-g] [-P style] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
};
@@ -37,13 +40,48 @@ const struct cmd_entry cmd_display_panes_entry = {
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ const char *str;
+
+ if (!args_has(args, 'g') && !args_has(args, 'P')) {
+
+ if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ server_set_identify(c);
+
+ return (CMD_RETURN_NORMAL);
+ }
+
- if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
- server_set_identify(c);
+ if (args_has(args, 'g')) {
+
+ if (args_has(args, 'P')) {
+ cmdq_error(cmdq, "don't use -P with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'P')) {
+ str = args_get(args, 'P');
+ if (style_parse(&grid_default_cell, &wp->colgc, str) == -1) {
+ cmdq_error(cmdq, "bad style: %s", str);
+ return (CMD_RETURN_ERROR);
+ }
+
+ wp->flags |= PANE_REDRAW;
+ }
return (CMD_RETURN_NORMAL);
}
diff --git a/options-table.c b/options-table.c
index 2bcf29b..d7057bf 100644
--- a/options-table.c
+++ b/options-table.c
@@ -667,6 +667,16 @@ const struct options_table_entry window_options_table[] = {
.default_num = 0 /* overridden in main() */
},
+ { .name = "window-active-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
+ { .name = "window-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
{ .name = "window-status-activity-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE,
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..c718609 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -266,7 +266,7 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff, wp);
tty_reset(&c->tty);
}
@@ -323,9 +323,9 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top)
small && i > msgx && j == msgy)
continue;
if (screen_redraw_check_active(i, j, type, w, wp))
- tty_attributes(tty, &active_gc);
+ tty_attributes(tty, &active_gc, wp);
else
- tty_attributes(tty, &other_gc);
+ tty_attributes(tty, &other_gc, wp);
tty_cursor(tty, i, top + j);
tty_putc(tty, CELL_BORDERS[type]);
}
@@ -333,7 +333,7 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top)
if (small) {
memcpy(&msg_gc, &grid_default_cell, sizeof msg_gc);
- tty_attributes(tty, &msg_gc);
+ tty_attributes(tty, &msg_gc, wp);
tty_cursor(tty, msgx, msgy);
tty_puts(tty, msg);
}
@@ -354,7 +354,7 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff, wp);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +367,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
@@ -411,7 +411,7 @@ screen_redraw_draw_number(struct client *c, struct window_pane *wp)
colour_set_bg(&gc, active_colour);
else
colour_set_bg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
for (ptr = buf; *ptr != '\0'; ptr++) {
if (*ptr < '0' || *ptr > '9')
continue;
colour_set_fg(&gc, active_colour);
else
colour_set_fg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
tty_puts(tty, buf);
tty_cursor(tty, 0, 0);
diff --git a/server-client.c b/server-client.c
index 3ca9907..f234f50 100644
--- a/server-client.c
+++ b/server-client.c
@@ -328,8 +328,7 @@ server_client_check_mouse(struct client *c, struct window_pane *wp)
if (options_get_number(oo, "mouse-select-pane") &&
(m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
window_set_active_at(wp->window, m->x, m->y);
- server_status_window(wp->window);
- server_redraw_window_borders(wp->window);
+ server_redraw_window(wp->window);
wp = wp->window->active; /* may have changed */
}
diff --git a/tmux.1 b/tmux.1
index f615dd0..656a2a7 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1305,9 +1305,14 @@ flag, see the
.Sx FORMATS
section.
This command works only if at least one client is attached.
-.It Ic display-panes Op Fl t Ar target-client
+.It Xo Ic display-panes
+.Op Fl g
+.Op Fl P Ar style
+.Op Fl t Ar target-client
+.Xc
.D1 (alias: Ic displayp )
-Display a visible indicator of each pane shown by
+If no flags have been specified, display a visible indicator of
+each pane shown by
.Ar target-client .
See the
.Ic display-panes-time ,
@@ -1320,6 +1325,15 @@ While the indicator is on screen, a pane may be selected with the
to
.Ql 9
keys.
+.Pp
+With
+.Fl P,
+a style argument can be passed to set a pane's foreground and
+background colour. The style will override any style that
+has been set with the window-style or window-active-style options.
+The
+.Fl g
+flag will show what colour style has been set for the pane.
.It Xo Ic find-window
.Op Fl CNT
.Op Fl F Ar format
@@ -2928,6 +2942,15 @@ Instructs
.Nm
to expect UTF-8 sequences to appear in this window.
.Pp
+.It Ic window-active-style Ar style
+Set the default foreground and background colours for the active pane in the
+window via a style argument.
+For how to specify
+.Ar style ,
+see the
+.Ic message-command-style
+option.
+.Pp
.It Ic window-status-activity-style Ar style
Set status line style for windows with an activity alert.
For how to specify
@@ -2985,6 +3008,14 @@ see the
.Ic message-command-style
option.
.Pp
+.It Ic window-style Ar style
+Set the default window foreground and background colours via a style argument.
+For how to specify
+.Ar style ,
+see the
+.Ic message-command-style
+option.
+.Pp
.It Xo Ic xterm-keys
.Op Ic on | off
.Xc
diff --git a/tmux.h b/tmux.h
index e296ac7..4751cbd 100644
--- a/tmux.h
+++ b/tmux.h
@@ -900,6 +900,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -1604,7 +1607,8 @@ void environ_push(struct environ *);
/* tty.c */
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
-void tty_attributes(struct tty *, const struct grid_cell *);
+void tty_attributes(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
void tty_reset(struct tty *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
@@ -1628,7 +1632,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct window_pane *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
diff --git a/tty.c b/tty.c
index 1bb8981..257ebf8 100644
--- a/tty.c
+++ b/tty.c
@@ -47,7 +47,9 @@ void tty_redraw_region(struct tty *, const struct tty_ctx *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_repeat_space(struct tty *, u_int);
-void tty_cell(struct tty *, const struct grid_cell *);
+void tty_cell(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
+void tty_default_colours(struct grid_cell *, const struct window_pane *);
#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -604,15 +606,16 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct window_pane *wp)
{
const struct grid_cell *gc;
struct grid_line *gl;
@@ -650,16 +653,16 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
- tty_cell(tty, &tmpgc);
+ tty_cell(tty, &tmpgc, wp);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, gc, wp);
}
if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
@@ -713,11 +716,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -725,7 +729,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_ICH1))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
}
void
@@ -736,11 +741,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
if (!tty_pane_full_width(tty, ctx) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -754,7 +760,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -776,7 +782,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -794,7 +800,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,7 +814,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
@@ -824,7 +830,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -837,7 +843,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -861,7 +867,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -894,7 +900,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,7 +915,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -942,7 +948,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -969,7 +975,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -997,7 +1003,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1038,12 +1044,12 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
*/
cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
tty_cursor_pane(tty, ctx, cx, ctx->ocy);
- tty_cell(tty, &ctx->last_cell);
+ tty_cell(tty, &ctx->last_cell, wp);
}
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+ tty_cell(tty, ctx->cell, wp);
}
void
@@ -1055,7 +1061,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, wp);
}
void
@@ -1088,12 +1094,13 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
tty_cursor(tty, 0, 0);
}
void
-tty_cell(struct tty *tty, const struct grid_cell *gc)
+tty_cell(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct utf8_data ud;
u_int i;
@@ -1108,7 +1115,7 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
return;
/* Set the attributes. */
- tty_attributes(tty, gc);
+ tty_attributes(tty, gc, wp);
/* Get the cell and if ASCII write with putc to do ACS translation. */
grid_cell_get(gc, &ud);
}
void
-tty_attributes(struct tty *tty, const struct grid_cell *gc)
+tty_attributes(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct grid_cell *tc = &tty->cell, gc2;
u_char changed;
memcpy(&gc2, gc, sizeof gc2);
+ tty_default_colours(&gc2, wp);
/*
* If no setab, try to use the reverse attribute as a best-effort for a
@@ -1614,3 +1623,44 @@ tty_bell(struct tty *tty)
{
tty_putcode(tty, TTYC_BEL);
}
+
+void
+tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
+{
+ const struct grid_cell *agc, *pgc, *wgc;
+
+ if (wp == NULL)
+ return;
+
+ pgc = &wp->colgc;
+ agc = options_get_style(&wp->window->options, "window-active-style");
+ wgc = options_get_style(&wp->window->options, "window-style");
+
+ if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
+ if (pgc->fg != 8 || (pgc->flags & GRID_FLAG_FG256)) {
+ gc->fg = pgc->fg;
+ gc->flags |= (pgc->flags & GRID_FLAG_FG256);
+ } else if (wp == wp->window->active &&
+ (agc->fg != 8 || (agc->flags & GRID_FLAG_FG256))) {
+ gc->fg = agc->fg;
+ gc->flags |= (agc->flags & GRID_FLAG_FG256);
+ } else {
+ gc->fg = wgc->fg;
+ gc->flags |= (wgc->flags & GRID_FLAG_FG256);
+ }
+ }
+
+ if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) {
+ if (pgc->bg != 8 || (pgc->flags & GRID_FLAG_BG256)) {
+ gc->bg = pgc->bg;
+ gc->flags |= (pgc->flags & GRID_FLAG_BG256);
+ } else if (wp == wp->window->active &&
+ (agc->bg != 8 || (agc->flags & GRID_FLAG_BG256))) {
+ gc->bg = agc->bg;
+ gc->flags |= (agc->flags & GRID_FLAG_BG256);
+ } else {
+ gc->bg = wgc->bg;
+ gc->flags |= (wgc->flags & GRID_FLAG_BG256);
+ }
+ }
+}
diff --git a/window.c b/window.c
index fff2cfc..7a06470 100644
--- a/window.c
+++ b/window.c
@@ -704,6 +704,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ memcpy(&wp->colgc, &grid_default_cell, sizeof wp->colgc);
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
J Raynor
2015-02-22 07:45:38 UTC
Permalink
You can try to make tmux itself support BCE ... or add BCE support
back on top of this like you had before.
I don't know how to make tmux support terminals without BCE besides
what I already did. Can you give me some detail for what you mean by
"make tmux itself support BCE"?
Nicholas Marriott
2015-02-22 10:13:53 UTC
Permalink
Post by J Raynor
You can try to make tmux itself support BCE ... or add BCE support
back on top of this like you had before.
I don't know how to make tmux support terminals without BCE besides
what I already did. Can you give me some detail for what you mean by
"make tmux itself support BCE"?
It needs to handle three cases:

1) Drawing something new from an application on a BCE terminal. This is
handled by the tty_attributes changes for tty_cmd_* in the pane colour
diff, except it will need to use the tty->cell bg colour not the default
bg colour.

2) Drawing something new from an application on a non-BCE terminal. This
is the BCE bits you did before.

3) Redrawing an existing line from the grid. When tmux does an erase, it
will need to use the background colour for the grid if it is not
default, so that tty_draw_line redraws it correctly. This will mostly
mean changing grid_clear_* and possibly grid_move_* (not sure what BCE
terminals do there, will need to test) to take a grid_cell for the bg
colour and fill it in instead of grid_default_cell. It would be best if
as much as possible it preserves the ability for tmux to issue EL to
erase a line in tty_draw_line rather than forcing it to always draw the
whole lot with spaces. So it may mean generating lines that are just a
single space long in, for example, grid_clear and grid_clear_lines. Then
tty_draw_line will also need to change so that the EL bit at the end
uses the last set colour, but if we can guarantee lines will always
either all default bg or at least 1 char long, that should be simple.
J Raynor
2015-02-24 04:33:51 UTC
Permalink
I've attached a patch that adds the BCE functionality I did before.
It's more concise this time. You have to apply the other patch first,
the one that does pane colors for bce terminals.

As for the other stuff, I misunderstood what you were referring to. I
thought you were looking for a different implementation of bce support
for what I had already done. I'll take a look at getting full
support.
Nicholas Marriott
2015-03-02 15:02:53 UTC
Permalink
Ok thanks. I will look at these diffs (or any new ones if you've sent
them) again after OpenBSD unlocks which I guess will probably be a few
weeks.
Post by J Raynor
I've attached a patch that adds the BCE functionality I did before.
It's more concise this time. You have to apply the other patch first,
the one that does pane colors for bce terminals.
As for the other stuff, I misunderstood what you were referring to. I
thought you were looking for a different implementation of bce support
for what I had already done. I'll take a look at getting full
support.
diff --git a/tmux.h b/tmux.h
index 4751cbd..c21fbb4 100644
--- a/tmux.h
+++ b/tmux.h
@@ -154,6 +154,7 @@ enum key_code {
enum tty_code_code {
TTYC_AX = 0,
TTYC_ACSC, /* acs_chars, ac */
+ TTYC_BCE, /* background colour erase */
TTYC_BEL, /* bell, bl */
TTYC_BLINK, /* enter_blink_mode, mb */
TTYC_BOLD, /* enter_bold_mode, md */
diff --git a/tty-term.c b/tty-term.c
index 365da5f..456f81e 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -38,6 +38,7 @@ struct tty_terms tty_terms = LIST_HEAD_INITIALIZER(tty_terms);
const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_ACSC, TTYCODE_STRING, "acsc" },
{ TTYC_AX, TTYCODE_FLAG, "AX" },
+ { TTYC_BCE, TTYCODE_STRING, "bce" },
{ TTYC_BEL, TTYCODE_STRING, "bel" },
{ TTYC_BLINK, TTYCODE_STRING, "blink" },
{ TTYC_BOLD, TTYCODE_STRING, "bold" },
diff --git a/tty.c b/tty.c
index 257ebf8..0f33f15 100644
--- a/tty.c
+++ b/tty.c
@@ -50,6 +50,7 @@ void tty_repeat_space(struct tty *, u_int);
void tty_cell(struct tty *, const struct grid_cell *,
const struct window_pane *);
void tty_default_colours(struct grid_cell *, const struct window_pane *);
+int need_fake_bce(const struct tty *, const struct window_pane *);
#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -666,7 +667,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
- tty_term_has(tty->term, TTYC_EL))
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - sx);
@@ -725,8 +726,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_term_has(tty->term, TTYC_ICH) ||
- tty_term_has(tty->term, TTYC_ICH1))
+ if (!need_fake_bce(tty, wp) && (tty_term_has(tty->term, TTYC_ICH) ||
+ tty_term_has(tty->term, TTYC_ICH1)))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
@@ -738,7 +739,7 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, wp) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
@@ -764,7 +765,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_term_has(tty->term, TTYC_ECH))
+ if (tty_term_has(tty->term, TTYC_ECH) && !need_fake_bce(tty, ctx->wp))
tty_putcode1(tty, TTYC_ECH, ctx->num);
else {
for (i = 0; i < ctx->num; i++)
@@ -775,7 +776,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1)) {
tty_redraw_region(tty, ctx);
@@ -793,7 +794,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1)) {
tty_redraw_region(tty, ctx);
@@ -818,7 +819,8 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) && !need_fake_bce(tty, wp) &&
+ tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
@@ -834,7 +836,8 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
@@ -845,7 +848,8 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
tty_attributes(tty, &grid_default_cell, ctx->wp);
- if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
+ if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) &&
+ !need_fake_bce(tty, ctx->wp)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_putcode(tty, TTYC_EL1);
} else {
@@ -860,7 +864,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy != ctx->orupper)
return;
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_RI)) {
tty_redraw_region(tty, ctx);
@@ -883,7 +887,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy != ctx->orlower)
return;
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, wp) ||
!tty_term_has(tty->term, TTYC_CSR)) {
if (tty_large_region(tty, ctx))
wp->flags |= PANE_REDRAW;
@@ -920,7 +924,8 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp)) {
tty_putcode(tty, TTYC_EL);
if (ctx->ocy != screen_size_y(s) - 1) {
tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
@@ -953,7 +958,8 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp)) {
for (i = 0; i < ctx->ocy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
@@ -980,7 +986,8 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp)) {
for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1) {
@@ -1664,3 +1671,17 @@ tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
}
}
}
+
+int
+need_fake_bce(const struct tty *tty, const struct window_pane *wp)
+{
+ struct grid_cell gc;
+
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ tty_default_colours(&gc, wp);
+
+ if (gc.bg == 8 && !(gc.flags & GRID_FLAG_BG256))
+ return (0);
+ else
+ return (!tty_term_has(tty->term, TTYC_BCE));
+}
Nicholas Marriott
2015-04-01 20:33:01 UTC
Permalink
Hi

This looks good. I've made a few changes, notably adding a tty_draw_pane
wrapper around tty_draw_line since it is mostly called with wp->screen.

Also I think there is no reason -g and -P can't be used together.

We'll need both these diffs together or it won't work in tmux itself so
I've put them together.

On thing that occurred to me now is that display-panes uses a
target-client but this diff makes it need a target-pane sometimes which
is an issue for hooks command parsing. Not sure if we can workaround it
easily enough with extra flags for hooks or if we should try to find a
different command to add this to.

Anyway I will look at this further when I have time but here's the
latest diff with my changes.


Index: cmd-display-panes.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/cmd-display-panes.c,v
retrieving revision 1.8
diff -u -p -r1.8 cmd-display-panes.c
--- cmd-display-panes.c 20 Oct 2014 22:29:25 -0000 1.8
+++ cmd-display-panes.c 1 Apr 2015 20:30:58 -0000
@@ -18,18 +18,21 @@

#include <sys/types.h>

+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"

/*
- * Display panes on a client.
+ * Display panes on a client or change pane default colours.
*/

enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);

const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "gt:P:", 0, 0,
+ "[-g] [-P style] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
};
@@ -37,13 +40,34 @@ const struct cmd_entry cmd_display_panes
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ const char *style;
+
+ if (!args_has(args, 'g') && !args_has(args, 'P')) {
+ if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ server_set_identify(c);
+ return (CMD_RETURN_NORMAL);
+ }

- if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);

- server_set_identify(c);
+ if (args_has(args, 'P')) {
+ style = args_get(args, 'P');
+ if (style_parse(&grid_default_cell, &wp->colgc, style) == -1) {
+ cmdq_error(cmdq, "bad style: %s", style);
+ return (CMD_RETURN_ERROR);
+ }
+ wp->flags |= PANE_REDRAW;
+ }
+ if (args_has(args, 'g'))
+ cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));

return (CMD_RETURN_NORMAL);
}
Index: options-table.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/options-table.c,v
retrieving revision 1.53
diff -u -p -r1.53 options-table.c
--- options-table.c 6 Feb 2015 15:09:34 -0000 1.53
+++ options-table.c 1 Apr 2015 20:30:58 -0000
@@ -668,6 +668,16 @@ const struct options_table_entry window_
.default_num = 0 /* overridden in main() */
},

+ { .name = "window-active-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
+ { .name = "window-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
{ .name = "window-status-activity-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE,
Index: screen-redraw.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/screen-redraw.c,v
retrieving revision 1.29
diff -u -p -r1.29 screen-redraw.c
--- screen-redraw.c 6 Feb 2015 15:09:34 -0000 1.29
+++ screen-redraw.c 1 Apr 2015 20:30:59 -0000
@@ -266,7 +266,7 @@ screen_redraw_pane(struct client *c, str
yoff++;

for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
+ tty_draw_pane(&c->tty, wp, i, wp->xoff, yoff);
tty_reset(&c->tty);
}

@@ -323,9 +323,9 @@ screen_redraw_draw_borders(struct client
small && i > msgx && j == msgy)
continue;
if (screen_redraw_check_active(i, j, type, w, wp))
- tty_attributes(tty, &active_gc);
+ tty_attributes(tty, &active_gc, wp);
else
- tty_attributes(tty, &other_gc);
+ tty_attributes(tty, &other_gc, wp);
tty_cursor(tty, i, top + j);
tty_putc(tty, CELL_BORDERS[type]);
}
@@ -333,7 +333,7 @@ screen_redraw_draw_borders(struct client

if (small) {
memcpy(&msg_gc, &grid_default_cell, sizeof msg_gc);
- tty_attributes(tty, &msg_gc);
+ tty_attributes(tty, &msg_gc, wp);
tty_cursor(tty, msgx, msgy);
tty_puts(tty, msg);
}
@@ -346,15 +346,13 @@ screen_redraw_draw_panes(struct client *
struct window *w = c->session->curw->window;
struct tty *tty = &c->tty;
struct window_pane *wp;
- struct screen *s;
u_int i;

TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_visible(wp))
continue;
- s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_pane(tty, wp, i, wp->xoff, top + wp->yoff);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +365,9 @@ screen_redraw_draw_status(struct client
struct tty *tty = &c->tty;

if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, NULL, &c->status, 0, 0, 0);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, NULL, &c->status, 0, 0, tty->sy - 1);
}

/* Draw number on a pane. */
@@ -411,7 +409,7 @@ screen_redraw_draw_number(struct client
colour_set_bg(&gc, active_colour);
else
colour_set_bg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
for (ptr = buf; *ptr != '\0'; ptr++) {
if (*ptr < '0' || *ptr > '9')
continue;
@@ -438,7 +436,7 @@ draw_text:
colour_set_fg(&gc, active_colour);
else
colour_set_fg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
tty_puts(tty, buf);

tty_cursor(tty, 0, 0);
Index: server-client.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/server-client.c,v
retrieving revision 1.129
diff -u -p -r1.129 server-client.c
--- server-client.c 31 Mar 2015 17:45:10 -0000 1.129
+++ server-client.c 1 Apr 2015 20:30:59 -0000
@@ -329,8 +329,7 @@ server_client_check_mouse(struct client
if (options_get_number(oo, "mouse-select-pane") &&
(m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
window_set_active_at(wp->window, m->x, m->y);
- server_status_window(wp->window);
- server_redraw_window_borders(wp->window);
+ server_redraw_window(wp->window);
wp = wp->window->active; /* may have changed */
}

Index: tmux.1
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.1,v
retrieving revision 1.415
diff -u -p -r1.415 tmux.1
--- tmux.1 31 Mar 2015 17:58:36 -0000 1.415
+++ tmux.1 1 Apr 2015 20:31:00 -0000
@@ -1301,9 +1301,13 @@ flag, see the
.Sx FORMATS
section.
This command works only if at least one client is attached.
-.It Ic display-panes Op Fl t Ar target-client
+.It Xo Ic display-panes
+.Op Fl g
+.Op Fl P Ar style
+.Op Fl t Ar target-client
+.Xc
.D1 (alias: Ic displayp )
-Display a visible indicator of each pane shown by
+With no flags, display a visible indicator of each pane shown by
.Ar target-client .
See the
.Ic display-panes-time ,
@@ -1316,6 +1320,16 @@ While the indicator is on screen, a pane
to
.Ql 9
keys.
+.Pp
+With
+.Fl P,
+set the pane style (overriding the
+.Ic window-style
+and
+.Ic window-active-style
+options).
+.Fl g
+shows the current pane style.
.It Xo Ic find-window
.Op Fl CNT
.Op Fl F Ar format
@@ -2924,6 +2938,14 @@ Instructs
.Nm
to expect UTF-8 sequences to appear in this window.
.Pp
+.It Ic window-active-style Ar style
+Set the style for the window's active pane.
+For how to specify
+.Ar style ,
+see the
+.Ic message-command-style
+option.
+.Pp
.It Ic window-status-activity-style Ar style
Set status line style for windows with an activity alert.
For how to specify
@@ -2975,6 +2997,14 @@ The default is a single space character.
.Pp
.It Ic window-status-style Ar style
Set status line style for a single window.
+For how to specify
+.Ar style ,
+see the
+.Ic message-command-style
+option.
+.Pp
+.It Ic window-style Ar style
+Set the default window style.
For how to specify
.Ar style ,
see the
Index: tmux.h
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.h,v
retrieving revision 1.490
diff -u -p -r1.490 tmux.h
--- tmux.h 6 Feb 2015 17:21:08 -0000 1.490
+++ tmux.h 1 Apr 2015 20:31:01 -0000
@@ -156,6 +156,7 @@ enum key_code {
enum tty_code_code {
TTYC_AX = 0,
TTYC_ACSC, /* acs_chars, ac */
+ TTYC_BCE, /* back_color_erase, ut */
TTYC_BEL, /* bell, bl */
TTYC_BLINK, /* enter_blink_mode, mb */
TTYC_BOLD, /* enter_bold_mode, md */
@@ -902,6 +903,8 @@ struct window_pane {

struct input_ctx ictx;

+ struct grid_cell colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -1606,7 +1609,8 @@ void environ_push(struct environ *);
/* tty.c */
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
-void tty_attributes(struct tty *, const struct grid_cell *);
+void tty_attributes(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
void tty_reset(struct tty *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
@@ -1630,7 +1634,10 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_pane(struct tty *, const struct window_pane *, u_int, u_int,
+ u_int);
+void tty_draw_line(struct tty *, const struct window_pane *, struct screen *,
+ u_int, u_int, u_int);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
Index: tty-term.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tty-term.c,v
retrieving revision 1.36
diff -u -p -r1.36 tty-term.c
--- tty-term.c 20 Jan 2015 08:18:04 -0000 1.36
+++ tty-term.c 1 Apr 2015 20:31:01 -0000
@@ -35,6 +35,7 @@ struct tty_terms tty_terms = LIST_HEAD_I
const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_ACSC, TTYCODE_STRING, "acsc" },
{ TTYC_AX, TTYCODE_FLAG, "AX" },
+ { TTYC_BCE, TTYCODE_STRING, "bce" },
{ TTYC_BEL, TTYCODE_STRING, "bel" },
{ TTYC_BLINK, TTYCODE_STRING, "blink" },
{ TTYC_BOLD, TTYCODE_STRING, "bold" },
Index: tty.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tty.c,v
retrieving revision 1.173
diff -u -p -r1.173 tty.c
--- tty.c 5 Feb 2015 11:46:57 -0000 1.173
+++ tty.c 1 Apr 2015 20:31:01 -0000
@@ -43,11 +43,14 @@ void tty_colours_fg(struct tty *, const
void tty_colours_bg(struct tty *, const struct grid_cell *);

int tty_large_region(struct tty *, const struct tty_ctx *);
+int tty_fake_bce(const struct tty *, const struct window_pane *);
void tty_redraw_region(struct tty *, const struct tty_ctx *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_repeat_space(struct tty *, u_int);
-void tty_cell(struct tty *, const struct grid_cell *);
+void tty_cell(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
+void tty_default_colours(struct grid_cell *, const struct window_pane *);

#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -582,6 +585,23 @@ tty_large_region(unused struct tty *tty,
}

/*
+ * Return if BCE is needed but the terminal doesn't have it - it'll need to be
+ * emulated.
+ */
+int
+tty_fake_bce(const struct tty *tty, const struct window_pane *wp)
+{
+ struct grid_cell gc;
+
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ tty_default_colours(&gc, wp);
+
+ if (gc.bg == 8 && !(gc.flags & GRID_FLAG_BG256))
+ return (0);
+ return (!tty_term_has(tty->term, TTYC_BCE));
+}
+
+/*
* Redraw scroll region using data from screen (already updated). Used when
* CSR not supported, or window is a pane that doesn't take up the full
* width of the terminal.
@@ -604,15 +624,23 @@ tty_redraw_region(struct tty *tty, const

if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff);
}
}

void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox,
+ u_int oy)
+{
+ tty_draw_line(tty, wp, wp->screen, py, ox, oy);
+}
+
+void
+tty_draw_line(struct tty *tty, const struct window_pane *wp,
+ struct screen *s, u_int py, u_int ox, u_int oy)
{
const struct grid_cell *gc;
struct grid_line *gl;
@@ -650,20 +678,20 @@ tty_draw_line(struct tty *tty, struct sc
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
- tty_cell(tty, &tmpgc);
+ tty_cell(tty, &tmpgc, wp);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, gc, wp);
}

if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
- tty_term_has(tty->term, TTYC_EL))
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - sx);
@@ -713,19 +741,19 @@ tty_cmd_insertcharacter(struct tty *tty,
struct window_pane *wp = ctx->wp;

if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_term_has(tty->term, TTYC_ICH) ||
- tty_term_has(tty->term, TTYC_ICH1))
+ if (!tty_fake_bce(tty, wp) && (tty_term_has(tty->term, TTYC_ICH) ||
+ tty_term_has(tty->term, TTYC_ICH1)))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
}

void
@@ -733,14 +761,14 @@ tty_cmd_deletecharacter(struct tty *tty,
{
struct window_pane *wp = ctx->wp;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

@@ -754,11 +782,11 @@ tty_cmd_clearcharacter(struct tty *tty,
{
u_int i;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_term_has(tty->term, TTYC_ECH))
+ if (tty_term_has(tty->term, TTYC_ECH) && !tty_fake_bce(tty, ctx->wp))
tty_putcode1(tty, TTYC_ECH, ctx->num);
else {
for (i = 0; i < ctx->num; i++)
@@ -769,14 +797,14 @@ tty_cmd_clearcharacter(struct tty *tty,
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -787,14 +815,14 @@ tty_cmd_insertline(struct tty *tty, cons
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,11 +836,12 @@ tty_cmd_clearline(struct tty *tty, const
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, 0, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) && !tty_fake_bce(tty, wp) &&
+ tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
@@ -824,11 +853,12 @@ tty_cmd_clearendofline(struct tty *tty,
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
@@ -837,9 +867,10 @@ tty_cmd_clearendofline(struct tty *tty,
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

- if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
+ if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) &&
+ !tty_fake_bce(tty, ctx->wp)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_putcode(tty, TTYC_EL1);
} else {
@@ -854,14 +885,14 @@ tty_cmd_reverseindex(struct tty *tty, co
if (ctx->ocy != ctx->orupper)
return;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_RI)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -877,7 +908,7 @@ tty_cmd_linefeed(struct tty *tty, const
if (ctx->ocy != ctx->orlower)
return;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) ||
!tty_term_has(tty->term, TTYC_CSR)) {
if (tty_large_region(tty, ctx))
wp->flags |= PANE_REDRAW;
@@ -894,7 +925,7 @@ tty_cmd_linefeed(struct tty *tty, const
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,12 +940,13 @@ tty_cmd_clearendofscreen(struct tty *tty
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
tty_putcode(tty, TTYC_EL);
if (ctx->ocy != screen_size_y(s) - 1) {
tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
@@ -942,12 +974,13 @@ tty_cmd_clearstartofscreen(struct tty *t
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
for (i = 0; i < ctx->ocy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
@@ -969,12 +1002,13 @@ tty_cmd_clearscreen(struct tty *tty, con
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1) {
@@ -997,7 +1031,7 @@ tty_cmd_alignmenttest(struct tty *tty, c
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);

@@ -1038,12 +1072,12 @@ tty_cmd_cell(struct tty *tty, const stru
*/
cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
tty_cursor_pane(tty, ctx, cx, ctx->ocy);
- tty_cell(tty, &ctx->last_cell);
+ tty_cell(tty, &ctx->last_cell, wp);
}
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- tty_cell(tty, ctx->cell);
+ tty_cell(tty, ctx->cell, wp);
}

void
@@ -1055,7 +1089,7 @@ tty_cmd_utf8character(struct tty *tty, c
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
}

void
@@ -1088,12 +1122,13 @@ tty_cmd_rawstring(struct tty *tty, const
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
tty_cursor(tty, 0, 0);
}

void
-tty_cell(struct tty *tty, const struct grid_cell *gc)
+tty_cell(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct utf8_data ud;
u_int i;
@@ -1108,7 +1143,7 @@ tty_cell(struct tty *tty, const struct g
return;

/* Set the attributes. */
- tty_attributes(tty, gc);
+ tty_attributes(tty, gc, wp);

/* Get the cell and if ASCII write with putc to do ACS translation. */
grid_cell_get(gc, &ud);
@@ -1312,12 +1347,14 @@ out:
}

void
-tty_attributes(struct tty *tty, const struct grid_cell *gc)
+tty_attributes(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct grid_cell *tc = &tty->cell, gc2;
u_char changed;

memcpy(&gc2, gc, sizeof gc2);
+ tty_default_colours(&gc2, wp);

/*
* If no setab, try to use the reverse attribute as a best-effort for a
@@ -1607,6 +1644,47 @@ tty_try_256(struct tty *tty, u_char colo
}

return (-1);
+}
+
+void
+tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
+{
+ const struct grid_cell *agc, *pgc, *wgc;
+
+ if (wp == NULL)
+ return;
+
+ pgc = &wp->colgc;
+ agc = options_get_style(&wp->window->options, "window-active-style");
+ wgc = options_get_style(&wp->window->options, "window-style");
+
+ if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
+ if (pgc->fg != 8 || (pgc->flags & GRID_FLAG_FG256)) {
+ gc->fg = pgc->fg;
+ gc->flags |= (pgc->flags & GRID_FLAG_FG256);
+ } else if (wp == wp->window->active &&
+ (agc->fg != 8 || (agc->flags & GRID_FLAG_FG256))) {
+ gc->fg = agc->fg;
+ gc->flags |= (agc->flags & GRID_FLAG_FG256);
+ } else {
+ gc->fg = wgc->fg;
+ gc->flags |= (wgc->flags & GRID_FLAG_FG256);
+ }
+ }
+
+ if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) {
+ if (pgc->bg != 8 || (pgc->flags & GRID_FLAG_BG256)) {
+ gc->bg = pgc->bg;
+ gc->flags |= (pgc->flags & GRID_FLAG_BG256);
+ } else if (wp == wp->window->active &&
+ (agc->bg != 8 || (agc->flags & GRID_FLAG_BG256))) {
+ gc->bg = agc->bg;
+ gc->flags |= (agc->flags & GRID_FLAG_BG256);
+ } else {
+ gc->bg = wgc->bg;
+ gc->flags |= (wgc->flags & GRID_FLAG_BG256);
+ }
+ }
}

void
Index: window.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/window.c,v
retrieving revision 1.116
diff -u -p -r1.116 window.c
--- window.c 9 Feb 2015 12:47:18 -0000 1.116
+++ window.c 1 Apr 2015 20:31:01 -0000
@@ -705,6 +705,8 @@ window_pane_create(struct window *w, u_i

wp->saved_grid = NULL;

+ memcpy(&wp->colgc, &grid_default_cell, sizeof wp->colgc);
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
Post by J Raynor
I've attached a patch that adds the BCE functionality I did before.
It's more concise this time. You have to apply the other patch first,
the one that does pane colors for bce terminals.
As for the other stuff, I misunderstood what you were referring to. I
thought you were looking for a different implementation of bce support
for what I had already done. I'll take a look at getting full
support.
diff --git a/tmux.h b/tmux.h
index 4751cbd..c21fbb4 100644
--- a/tmux.h
+++ b/tmux.h
@@ -154,6 +154,7 @@ enum key_code {
enum tty_code_code {
TTYC_AX = 0,
TTYC_ACSC, /* acs_chars, ac */
+ TTYC_BCE, /* background colour erase */
TTYC_BEL, /* bell, bl */
TTYC_BLINK, /* enter_blink_mode, mb */
TTYC_BOLD, /* enter_bold_mode, md */
diff --git a/tty-term.c b/tty-term.c
index 365da5f..456f81e 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -38,6 +38,7 @@ struct tty_terms tty_terms = LIST_HEAD_INITIALIZER(tty_terms);
const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_ACSC, TTYCODE_STRING, "acsc" },
{ TTYC_AX, TTYCODE_FLAG, "AX" },
+ { TTYC_BCE, TTYCODE_STRING, "bce" },
{ TTYC_BEL, TTYCODE_STRING, "bel" },
{ TTYC_BLINK, TTYCODE_STRING, "blink" },
{ TTYC_BOLD, TTYCODE_STRING, "bold" },
diff --git a/tty.c b/tty.c
index 257ebf8..0f33f15 100644
--- a/tty.c
+++ b/tty.c
@@ -50,6 +50,7 @@ void tty_repeat_space(struct tty *, u_int);
void tty_cell(struct tty *, const struct grid_cell *,
const struct window_pane *);
void tty_default_colours(struct grid_cell *, const struct window_pane *);
+int need_fake_bce(const struct tty *, const struct window_pane *);
#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -666,7 +667,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
- tty_term_has(tty->term, TTYC_EL))
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - sx);
@@ -725,8 +726,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_term_has(tty->term, TTYC_ICH) ||
- tty_term_has(tty->term, TTYC_ICH1))
+ if (!need_fake_bce(tty, wp) && (tty_term_has(tty->term, TTYC_ICH) ||
+ tty_term_has(tty->term, TTYC_ICH1)))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
@@ -738,7 +739,7 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, wp) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
@@ -764,7 +765,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_term_has(tty->term, TTYC_ECH))
+ if (tty_term_has(tty->term, TTYC_ECH) && !need_fake_bce(tty, ctx->wp))
tty_putcode1(tty, TTYC_ECH, ctx->num);
else {
for (i = 0; i < ctx->num; i++)
@@ -775,7 +776,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1)) {
tty_redraw_region(tty, ctx);
@@ -793,7 +794,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1)) {
tty_redraw_region(tty, ctx);
@@ -818,7 +819,8 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) && !need_fake_bce(tty, wp) &&
+ tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
@@ -834,7 +836,8 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
@@ -845,7 +848,8 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
tty_attributes(tty, &grid_default_cell, ctx->wp);
- if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
+ if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) &&
+ !need_fake_bce(tty, ctx->wp)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_putcode(tty, TTYC_EL1);
} else {
@@ -860,7 +864,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy != ctx->orupper)
return;
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_RI)) {
tty_redraw_region(tty, ctx);
@@ -883,7 +887,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy != ctx->orlower)
return;
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || need_fake_bce(tty, wp) ||
!tty_term_has(tty->term, TTYC_CSR)) {
if (tty_large_region(tty, ctx))
wp->flags |= PANE_REDRAW;
@@ -920,7 +924,8 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp)) {
tty_putcode(tty, TTYC_EL);
if (ctx->ocy != screen_size_y(s) - 1) {
tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
@@ -953,7 +958,8 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp)) {
for (i = 0; i < ctx->ocy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
@@ -980,7 +986,8 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !need_fake_bce(tty, wp)) {
for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1) {
@@ -1664,3 +1671,17 @@ tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
}
}
}
+
+int
+need_fake_bce(const struct tty *tty, const struct window_pane *wp)
+{
+ struct grid_cell gc;
+
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ tty_default_colours(&gc, wp);
+
+ if (gc.bg == 8 && !(gc.flags & GRID_FLAG_BG256))
+ return (0);
+ else
+ return (!tty_term_has(tty->term, TTYC_BCE));
+}
J Raynor
2015-04-11 05:57:00 UTC
Permalink
Post by Nicholas Marriott
On thing that occurred to me now is that display-panes uses a
target-client but this diff makes it need a target-pane sometimes which
is an issue for hooks command parsing. Not sure if we can workaround it
easily enough with extra flags for hooks or if we should try to find a
different command to add this to.
The functionality could be moved to select-pane, which takes a
target-pane. Selectp could then be used to select a pane, or to
select a pane's color.
Nicholas Marriott
2015-04-11 18:18:41 UTC
Permalink
Post by J Raynor
Post by Nicholas Marriott
On thing that occurred to me now is that display-panes uses a
target-client but this diff makes it need a target-pane sometimes which
is an issue for hooks command parsing. Not sure if we can workaround it
easily enough with extra flags for hooks or if we should try to find a
different command to add this to.
The functionality could be moved to select-pane, which takes a
target-pane. Selectp could then be used to select a pane, or to
select a pane's color.
good idea

Index: cmd-select-pane.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/cmd-select-pane.c,v
retrieving revision 1.20
diff -u -p -r1.20 cmd-select-pane.c
--- cmd-select-pane.c 21 Oct 2014 22:22:04 -0000 1.20
+++ cmd-select-pane.c 11 Apr 2015 18:18:01 -0000
@@ -28,8 +28,8 @@ enum cmd_retval cmd_select_pane_exec(st

const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
- "DdeLlRt:U", 0, 0,
- "[-DdeLlRU] " CMD_TARGET_PANE_USAGE,
+ "DdegLlP:Rt:U", 0, 0,
+ "[-DdegLlRU] [-P style] " CMD_TARGET_PANE_USAGE,
0,
cmd_select_pane_exec
};
@@ -48,6 +48,7 @@ cmd_select_pane_exec(struct cmd *self, s
struct args *args = self->args;
struct winlink *wl;
struct window_pane *wp;
+ const char *style;

if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
@@ -80,6 +81,21 @@ cmd_select_pane_exec(struct cmd *self, s
if (!window_pane_visible(wp)) {
cmdq_error(cmdq, "pane not visible");
return (CMD_RETURN_ERROR);
+ }
+
+ if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
+ if (args_has(args, 'P')) {
+ style = args_get(args, 'P');
+ if (style_parse(&grid_default_cell, &wp->colgc,
+ style) == -1) {
+ cmdq_error(cmdq, "bad style: %s", style);
+ return (CMD_RETURN_ERROR);
+ }
+ wp->flags |= PANE_REDRAW;
+ }
+ if (args_has(self->args, 'g'))
+ cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));
+ return (CMD_RETURN_NORMAL);
}

if (args_has(self->args, 'L'))
Index: options-table.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/options-table.c,v
retrieving revision 1.53
diff -u -p -r1.53 options-table.c
--- options-table.c 6 Feb 2015 15:09:34 -0000 1.53
+++ options-table.c 11 Apr 2015 18:18:01 -0000
@@ -668,6 +668,16 @@ const struct options_table_entry window_
.default_num = 0 /* overridden in main() */
},

+ { .name = "window-active-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
+ { .name = "window-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
{ .name = "window-status-activity-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE,
Index: screen-redraw.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/screen-redraw.c,v
retrieving revision 1.29
diff -u -p -r1.29 screen-redraw.c
--- screen-redraw.c 6 Feb 2015 15:09:34 -0000 1.29
+++ screen-redraw.c 11 Apr 2015 18:18:01 -0000
@@ -266,7 +266,7 @@ screen_redraw_pane(struct client *c, str
yoff++;

for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
+ tty_draw_pane(&c->tty, wp, i, wp->xoff, yoff);
tty_reset(&c->tty);
}

@@ -323,9 +323,9 @@ screen_redraw_draw_borders(struct client
small && i > msgx && j == msgy)
continue;
if (screen_redraw_check_active(i, j, type, w, wp))
- tty_attributes(tty, &active_gc);
+ tty_attributes(tty, &active_gc, wp);
else
- tty_attributes(tty, &other_gc);
+ tty_attributes(tty, &other_gc, wp);
tty_cursor(tty, i, top + j);
tty_putc(tty, CELL_BORDERS[type]);
}
@@ -333,7 +333,7 @@ screen_redraw_draw_borders(struct client

if (small) {
memcpy(&msg_gc, &grid_default_cell, sizeof msg_gc);
- tty_attributes(tty, &msg_gc);
+ tty_attributes(tty, &msg_gc, wp);
tty_cursor(tty, msgx, msgy);
tty_puts(tty, msg);
}
@@ -346,15 +346,13 @@ screen_redraw_draw_panes(struct client *
struct window *w = c->session->curw->window;
struct tty *tty = &c->tty;
struct window_pane *wp;
- struct screen *s;
u_int i;

TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_visible(wp))
continue;
- s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_pane(tty, wp, i, wp->xoff, top + wp->yoff);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +365,9 @@ screen_redraw_draw_status(struct client
struct tty *tty = &c->tty;

if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, NULL, &c->status, 0, 0, 0);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, NULL, &c->status, 0, 0, tty->sy - 1);
}

/* Draw number on a pane. */
@@ -411,7 +409,7 @@ screen_redraw_draw_number(struct client
colour_set_bg(&gc, active_colour);
else
colour_set_bg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
for (ptr = buf; *ptr != '\0'; ptr++) {
if (*ptr < '0' || *ptr > '9')
continue;
@@ -438,7 +436,7 @@ draw_text:
colour_set_fg(&gc, active_colour);
else
colour_set_fg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
tty_puts(tty, buf);

tty_cursor(tty, 0, 0);
Index: server-client.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/server-client.c,v
retrieving revision 1.129
diff -u -p -r1.129 server-client.c
--- server-client.c 31 Mar 2015 17:45:10 -0000 1.129
+++ server-client.c 11 Apr 2015 18:18:02 -0000
@@ -329,8 +329,7 @@ server_client_check_mouse(struct client
if (options_get_number(oo, "mouse-select-pane") &&
(m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
window_set_active_at(wp->window, m->x, m->y);
- server_status_window(wp->window);
- server_redraw_window_borders(wp->window);
+ server_redraw_window(wp->window);
wp = wp->window->active; /* may have changed */
}

Index: tmux.1
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.1,v
retrieving revision 1.417
diff -u -p -r1.417 tmux.1
--- tmux.1 10 Apr 2015 16:00:08 -0000 1.417
+++ tmux.1 11 Apr 2015 18:18:03 -0000
@@ -1730,14 +1730,17 @@ and
.Ic previous-layout
commands.
.It Xo Ic select-pane
-.Op Fl DdeLlRU
+.Op Fl DdegLlRU
+.Op Fl P Ar style
.Op Fl t Ar target-pane
.Xc
.D1 (alias: Ic selectp )
Make pane
.Ar target-pane
the active pane in window
-.Ar target-window .
+.Ar target-window ,
+or set it's style (with
+.Fl P ).
If one of
.Fl D ,
.Fl L ,
@@ -1754,6 +1757,22 @@ command.
enables or
.Fl d
disables input to the pane.
+.Pp
+Each pane has a style: by default the
+.Ic window-style
+and
+.Ic window-active-style
+options are used,
+.Ic select-pane
+.Fl P
+sets the style for a single pane.
+For example, to set the pane 1 background to red:
+.Bd -literal -offset indent
+select-pane -t:.1 -P 'bg=red'
+.Ed
+.Pp
+.Fl g
+shows the current pane style.
.It Xo Ic select-window
.Op Fl lnpT
.Op Fl t Ar target-window
@@ -2070,7 +2089,7 @@ also supports user options which are pre
User options may have any name, so long as they are prefixed with
.Ql \&@ ,
and be set to any string.
-For example
+For example:
.Bd -literal -offset indent
$ tmux setw -q @foo "abc123"
$ tmux showw -v @foo
@@ -2936,6 +2955,14 @@ Instructs
.Nm
to expect UTF-8 sequences to appear in this window.
.Pp
+.It Ic window-active-style Ar style
+Set the style for the window's active pane.
+For how to specify
+.Ar style ,
+see the
+.Ic message-command-style
+option.
+.Pp
.It Ic window-status-activity-style Ar style
Set status line style for windows with an activity alert.
For how to specify
@@ -2987,6 +3014,14 @@ The default is a single space character.
.Pp
.It Ic window-status-style Ar style
Set status line style for a single window.
+For how to specify
+.Ar style ,
+see the
+.Ic message-command-style
+option.
+.Pp
+.It Ic window-style Ar style
+Set the default window style.
For how to specify
.Ar style ,
see the
Index: tmux.h
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.h,v
retrieving revision 1.490
diff -u -p -r1.490 tmux.h
--- tmux.h 6 Feb 2015 17:21:08 -0000 1.490
+++ tmux.h 11 Apr 2015 18:18:03 -0000
@@ -156,6 +156,7 @@ enum key_code {
enum tty_code_code {
TTYC_AX = 0,
TTYC_ACSC, /* acs_chars, ac */
+ TTYC_BCE, /* back_color_erase, ut */
TTYC_BEL, /* bell, bl */
TTYC_BLINK, /* enter_blink_mode, mb */
TTYC_BOLD, /* enter_bold_mode, md */
@@ -902,6 +903,8 @@ struct window_pane {

struct input_ctx ictx;

+ struct grid_cell colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -1606,7 +1609,8 @@ void environ_push(struct environ *);
/* tty.c */
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
-void tty_attributes(struct tty *, const struct grid_cell *);
+void tty_attributes(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
void tty_reset(struct tty *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
@@ -1630,7 +1634,10 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_pane(struct tty *, const struct window_pane *, u_int, u_int,
+ u_int);
+void tty_draw_line(struct tty *, const struct window_pane *, struct screen *,
+ u_int, u_int, u_int);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
Index: tty-term.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tty-term.c,v
retrieving revision 1.36
diff -u -p -r1.36 tty-term.c
--- tty-term.c 20 Jan 2015 08:18:04 -0000 1.36
+++ tty-term.c 11 Apr 2015 18:18:04 -0000
@@ -35,6 +35,7 @@ struct tty_terms tty_terms = LIST_HEAD_I
const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_ACSC, TTYCODE_STRING, "acsc" },
{ TTYC_AX, TTYCODE_FLAG, "AX" },
+ { TTYC_BCE, TTYCODE_STRING, "bce" },
{ TTYC_BEL, TTYCODE_STRING, "bel" },
{ TTYC_BLINK, TTYCODE_STRING, "blink" },
{ TTYC_BOLD, TTYCODE_STRING, "bold" },
Index: tty.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tty.c,v
retrieving revision 1.173
diff -u -p -r1.173 tty.c
--- tty.c 5 Feb 2015 11:46:57 -0000 1.173
+++ tty.c 11 Apr 2015 18:18:04 -0000
@@ -43,11 +43,14 @@ void tty_colours_fg(struct tty *, const
void tty_colours_bg(struct tty *, const struct grid_cell *);

int tty_large_region(struct tty *, const struct tty_ctx *);
+int tty_fake_bce(const struct tty *, const struct window_pane *);
void tty_redraw_region(struct tty *, const struct tty_ctx *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_repeat_space(struct tty *, u_int);
-void tty_cell(struct tty *, const struct grid_cell *);
+void tty_cell(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
+void tty_default_colours(struct grid_cell *, const struct window_pane *);

#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -582,6 +585,23 @@ tty_large_region(unused struct tty *tty,
}

/*
+ * Return if BCE is needed but the terminal doesn't have it - it'll need to be
+ * emulated.
+ */
+int
+tty_fake_bce(const struct tty *tty, const struct window_pane *wp)
+{
+ struct grid_cell gc;
+
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ tty_default_colours(&gc, wp);
+
+ if (gc.bg == 8 && !(gc.flags & GRID_FLAG_BG256))
+ return (0);
+ return (!tty_term_has(tty->term, TTYC_BCE));
+}
+
+/*
* Redraw scroll region using data from screen (already updated). Used when
* CSR not supported, or window is a pane that doesn't take up the full
* width of the terminal.
@@ -604,15 +624,23 @@ tty_redraw_region(struct tty *tty, const

if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff);
}
}

void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox,
+ u_int oy)
+{
+ tty_draw_line(tty, wp, wp->screen, py, ox, oy);
+}
+
+void
+tty_draw_line(struct tty *tty, const struct window_pane *wp,
+ struct screen *s, u_int py, u_int ox, u_int oy)
{
const struct grid_cell *gc;
struct grid_line *gl;
@@ -650,20 +678,20 @@ tty_draw_line(struct tty *tty, struct sc
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
- tty_cell(tty, &tmpgc);
+ tty_cell(tty, &tmpgc, wp);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, gc, wp);
}

if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
- tty_term_has(tty->term, TTYC_EL))
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - sx);
@@ -713,19 +741,19 @@ tty_cmd_insertcharacter(struct tty *tty,
struct window_pane *wp = ctx->wp;

if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_term_has(tty->term, TTYC_ICH) ||
- tty_term_has(tty->term, TTYC_ICH1))
+ if (!tty_fake_bce(tty, wp) && (tty_term_has(tty->term, TTYC_ICH) ||
+ tty_term_has(tty->term, TTYC_ICH1)))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
}

void
@@ -733,14 +761,14 @@ tty_cmd_deletecharacter(struct tty *tty,
{
struct window_pane *wp = ctx->wp;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

@@ -754,11 +782,11 @@ tty_cmd_clearcharacter(struct tty *tty,
{
u_int i;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_term_has(tty->term, TTYC_ECH))
+ if (tty_term_has(tty->term, TTYC_ECH) && !tty_fake_bce(tty, ctx->wp))
tty_putcode1(tty, TTYC_ECH, ctx->num);
else {
for (i = 0; i < ctx->num; i++)
@@ -769,14 +797,14 @@ tty_cmd_clearcharacter(struct tty *tty,
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -787,14 +815,14 @@ tty_cmd_insertline(struct tty *tty, cons
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,11 +836,12 @@ tty_cmd_clearline(struct tty *tty, const
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, 0, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) && !tty_fake_bce(tty, wp) &&
+ tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
@@ -824,11 +853,12 @@ tty_cmd_clearendofline(struct tty *tty,
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
@@ -837,9 +867,10 @@ tty_cmd_clearendofline(struct tty *tty,
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

- if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
+ if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) &&
+ !tty_fake_bce(tty, ctx->wp)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_putcode(tty, TTYC_EL1);
} else {
@@ -854,14 +885,14 @@ tty_cmd_reverseindex(struct tty *tty, co
if (ctx->ocy != ctx->orupper)
return;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_RI)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -877,7 +908,7 @@ tty_cmd_linefeed(struct tty *tty, const
if (ctx->ocy != ctx->orlower)
return;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) ||
!tty_term_has(tty->term, TTYC_CSR)) {
if (tty_large_region(tty, ctx))
wp->flags |= PANE_REDRAW;
@@ -894,7 +925,7 @@ tty_cmd_linefeed(struct tty *tty, const
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,12 +940,13 @@ tty_cmd_clearendofscreen(struct tty *tty
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
tty_putcode(tty, TTYC_EL);
if (ctx->ocy != screen_size_y(s) - 1) {
tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
@@ -942,12 +974,13 @@ tty_cmd_clearstartofscreen(struct tty *t
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
for (i = 0; i < ctx->ocy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
@@ -969,12 +1002,13 @@ tty_cmd_clearscreen(struct tty *tty, con
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1) {
@@ -997,7 +1031,7 @@ tty_cmd_alignmenttest(struct tty *tty, c
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);

@@ -1038,12 +1072,12 @@ tty_cmd_cell(struct tty *tty, const stru
*/
cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
tty_cursor_pane(tty, ctx, cx, ctx->ocy);
- tty_cell(tty, &ctx->last_cell);
+ tty_cell(tty, &ctx->last_cell, wp);
}
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- tty_cell(tty, ctx->cell);
+ tty_cell(tty, ctx->cell, wp);
}

void
@@ -1055,7 +1089,7 @@ tty_cmd_utf8character(struct tty *tty, c
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
}

void
@@ -1088,12 +1122,13 @@ tty_cmd_rawstring(struct tty *tty, const
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
tty_cursor(tty, 0, 0);
}

void
-tty_cell(struct tty *tty, const struct grid_cell *gc)
+tty_cell(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct utf8_data ud;
u_int i;
@@ -1108,7 +1143,7 @@ tty_cell(struct tty *tty, const struct g
return;

/* Set the attributes. */
- tty_attributes(tty, gc);
+ tty_attributes(tty, gc, wp);

/* Get the cell and if ASCII write with putc to do ACS translation. */
grid_cell_get(gc, &ud);
@@ -1312,12 +1347,14 @@ out:
}

void
-tty_attributes(struct tty *tty, const struct grid_cell *gc)
+tty_attributes(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct grid_cell *tc = &tty->cell, gc2;
u_char changed;

memcpy(&gc2, gc, sizeof gc2);
+ tty_default_colours(&gc2, wp);

/*
* If no setab, try to use the reverse attribute as a best-effort for a
@@ -1607,6 +1644,47 @@ tty_try_256(struct tty *tty, u_char colo
}

return (-1);
+}
+
+void
+tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
+{
+ const struct grid_cell *agc, *pgc, *wgc;
+
+ if (wp == NULL)
+ return;
+
+ pgc = &wp->colgc;
+ agc = options_get_style(&wp->window->options, "window-active-style");
+ wgc = options_get_style(&wp->window->options, "window-style");
+
+ if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
+ if (pgc->fg != 8 || (pgc->flags & GRID_FLAG_FG256)) {
+ gc->fg = pgc->fg;
+ gc->flags |= (pgc->flags & GRID_FLAG_FG256);
+ } else if (wp == wp->window->active &&
+ (agc->fg != 8 || (agc->flags & GRID_FLAG_FG256))) {
+ gc->fg = agc->fg;
+ gc->flags |= (agc->flags & GRID_FLAG_FG256);
+ } else {
+ gc->fg = wgc->fg;
+ gc->flags |= (wgc->flags & GRID_FLAG_FG256);
+ }
+ }
+
+ if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) {
+ if (pgc->bg != 8 || (pgc->flags & GRID_FLAG_BG256)) {
+ gc->bg = pgc->bg;
+ gc->flags |= (pgc->flags & GRID_FLAG_BG256);
+ } else if (wp == wp->window->active &&
+ (agc->bg != 8 || (agc->flags & GRID_FLAG_BG256))) {
+ gc->bg = agc->bg;
+ gc->flags |= (agc->flags & GRID_FLAG_BG256);
+ } else {
+ gc->bg = wgc->bg;
+ gc->flags |= (wgc->flags & GRID_FLAG_BG256);
+ }
+ }
}

void
Index: window.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/window.c,v
retrieving revision 1.116
diff -u -p -r1.116 window.c
--- window.c 9 Feb 2015 12:47:18 -0000 1.116
+++ window.c 11 Apr 2015 18:18:04 -0000
@@ -705,6 +705,8 @@ window_pane_create(struct window *w, u_i

wp->saved_grid = NULL;

+ memcpy(&wp->colgc, &grid_default_cell, sizeof wp->colgc);
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
J Raynor
2015-04-13 00:25:43 UTC
Permalink
This line in the patch for tmux.1 looks wrong:

+.Fl P ).

I think there has to be a space between the parenthesis and the
period. Without it, the parenthesis gets treated as a flag and a dash
is put before it.

If -g or -P is passed to selectp, other flags are ignored. Is that
the intended behavior?
Nicholas Marriott
2015-04-13 06:57:59 UTC
Permalink
Post by Nicholas Marriott
+.Fl P ).
I think there has to be a space between the parenthesis and the
period. Without it, the parenthesis gets treated as a flag and a dash
is put before it.
Whoops, yes, I had it like that and must have changed it back by
accident.
Post by Nicholas Marriott
If -g or -P is passed to selectp, other flags are ignored. Is that
the intended behavior?
Yes I think that is more useful than doing both.
Nicholas Marriott
2015-04-15 22:14:10 UTC
Permalink
Couple of fixes. BCE is a FLAG not a STRING, and we need to check with
tty_term_flag not tty_term_has (so it wasn't actually making use of BCE
at all even if the terminal supported it). Also don't use the pane
colours for the borders.

I like this, don't see any other problems so far.


Index: cmd-select-pane.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/cmd-select-pane.c,v
retrieving revision 1.20
diff -u -p -r1.20 cmd-select-pane.c
--- cmd-select-pane.c 21 Oct 2014 22:22:04 -0000 1.20
+++ cmd-select-pane.c 15 Apr 2015 22:12:41 -0000
@@ -28,8 +28,8 @@ enum cmd_retval cmd_select_pane_exec(st

const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
- "DdeLlRt:U", 0, 0,
- "[-DdeLlRU] " CMD_TARGET_PANE_USAGE,
+ "DdegLlP:Rt:U", 0, 0,
+ "[-DdegLlRU] [-P style] " CMD_TARGET_PANE_USAGE,
0,
cmd_select_pane_exec
};
@@ -48,6 +48,7 @@ cmd_select_pane_exec(struct cmd *self, s
struct args *args = self->args;
struct winlink *wl;
struct window_pane *wp;
+ const char *style;

if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
@@ -80,6 +81,21 @@ cmd_select_pane_exec(struct cmd *self, s
if (!window_pane_visible(wp)) {
cmdq_error(cmdq, "pane not visible");
return (CMD_RETURN_ERROR);
+ }
+
+ if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
+ if (args_has(args, 'P')) {
+ style = args_get(args, 'P');
+ if (style_parse(&grid_default_cell, &wp->colgc,
+ style) == -1) {
+ cmdq_error(cmdq, "bad style: %s", style);
+ return (CMD_RETURN_ERROR);
+ }
+ wp->flags |= PANE_REDRAW;
+ }
+ if (args_has(self->args, 'g'))
+ cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));
+ return (CMD_RETURN_NORMAL);
}

if (args_has(self->args, 'L'))
Index: options-table.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/options-table.c,v
retrieving revision 1.53
diff -u -p -r1.53 options-table.c
--- options-table.c 6 Feb 2015 15:09:34 -0000 1.53
+++ options-table.c 15 Apr 2015 22:12:41 -0000
@@ -668,6 +668,16 @@ const struct options_table_entry window_
.default_num = 0 /* overridden in main() */
},

+ { .name = "window-active-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
+ { .name = "window-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
{ .name = "window-status-activity-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE,
Index: screen-redraw.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/screen-redraw.c,v
retrieving revision 1.29
diff -u -p -r1.29 screen-redraw.c
--- screen-redraw.c 6 Feb 2015 15:09:34 -0000 1.29
+++ screen-redraw.c 15 Apr 2015 22:12:41 -0000
@@ -266,7 +266,7 @@ screen_redraw_pane(struct client *c, str
yoff++;

for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
+ tty_draw_pane(&c->tty, wp, i, wp->xoff, yoff);
tty_reset(&c->tty);
}

@@ -323,9 +323,9 @@ screen_redraw_draw_borders(struct client
small && i > msgx && j == msgy)
continue;
if (screen_redraw_check_active(i, j, type, w, wp))
- tty_attributes(tty, &active_gc);
+ tty_attributes(tty, &active_gc, NULL);
else
- tty_attributes(tty, &other_gc);
+ tty_attributes(tty, &other_gc, NULL);
tty_cursor(tty, i, top + j);
tty_putc(tty, CELL_BORDERS[type]);
}
@@ -333,7 +333,7 @@ screen_redraw_draw_borders(struct client

if (small) {
memcpy(&msg_gc, &grid_default_cell, sizeof msg_gc);
- tty_attributes(tty, &msg_gc);
+ tty_attributes(tty, &msg_gc, NULL);
tty_cursor(tty, msgx, msgy);
tty_puts(tty, msg);
}
@@ -346,15 +346,13 @@ screen_redraw_draw_panes(struct client *
struct window *w = c->session->curw->window;
struct tty *tty = &c->tty;
struct window_pane *wp;
- struct screen *s;
u_int i;

TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_visible(wp))
continue;
- s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_pane(tty, wp, i, wp->xoff, top + wp->yoff);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +365,9 @@ screen_redraw_draw_status(struct client
struct tty *tty = &c->tty;

if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, NULL, &c->status, 0, 0, 0);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, NULL, &c->status, 0, 0, tty->sy - 1);
}

/* Draw number on a pane. */
@@ -411,7 +409,7 @@ screen_redraw_draw_number(struct client
colour_set_bg(&gc, active_colour);
else
colour_set_bg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
for (ptr = buf; *ptr != '\0'; ptr++) {
if (*ptr < '0' || *ptr > '9')
continue;
@@ -438,7 +436,7 @@ draw_text:
colour_set_fg(&gc, active_colour);
else
colour_set_fg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
tty_puts(tty, buf);

tty_cursor(tty, 0, 0);
Index: server-client.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/server-client.c,v
retrieving revision 1.129
diff -u -p -r1.129 server-client.c
--- server-client.c 31 Mar 2015 17:45:10 -0000 1.129
+++ server-client.c 15 Apr 2015 22:12:42 -0000
@@ -329,8 +329,7 @@ server_client_check_mouse(struct client
if (options_get_number(oo, "mouse-select-pane") &&
(m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
window_set_active_at(wp->window, m->x, m->y);
- server_status_window(wp->window);
- server_redraw_window_borders(wp->window);
+ server_redraw_window(wp->window);
wp = wp->window->active; /* may have changed */
}

Index: tmux.1
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.1,v
retrieving revision 1.417
diff -u -p -r1.417 tmux.1
--- tmux.1 10 Apr 2015 16:00:08 -0000 1.417
+++ tmux.1 15 Apr 2015 22:12:43 -0000
@@ -1730,14 +1730,17 @@ and
.Ic previous-layout
commands.
.It Xo Ic select-pane
-.Op Fl DdeLlRU
+.Op Fl DdegLlRU
+.Op Fl P Ar style
.Op Fl t Ar target-pane
.Xc
.D1 (alias: Ic selectp )
Make pane
.Ar target-pane
the active pane in window
-.Ar target-window .
+.Ar target-window ,
+or set it's style (with
+.Fl P ) .
If one of
.Fl D ,
.Fl L ,
@@ -1754,6 +1757,22 @@ command.
enables or
.Fl d
disables input to the pane.
+.Pp
+Each pane has a style: by default the
+.Ic window-style
+and
+.Ic window-active-style
+options are used,
+.Ic select-pane
+.Fl P
+sets the style for a single pane.
+For example, to set the pane 1 background to red:
+.Bd -literal -offset indent
+select-pane -t:.1 -P 'bg=red'
+.Ed
+.Pp
+.Fl g
+shows the current pane style.
.It Xo Ic select-window
.Op Fl lnpT
.Op Fl t Ar target-window
@@ -2070,7 +2089,7 @@ also supports user options which are pre
User options may have any name, so long as they are prefixed with
.Ql \&@ ,
and be set to any string.
-For example
+For example:
.Bd -literal -offset indent
$ tmux setw -q @foo "abc123"
$ tmux showw -v @foo
@@ -2936,6 +2955,14 @@ Instructs
.Nm
to expect UTF-8 sequences to appear in this window.
.Pp
+.It Ic window-active-style Ar style
+Set the style for the window's active pane.
+For how to specify
+.Ar style ,
+see the
+.Ic message-command-style
+option.
+.Pp
.It Ic window-status-activity-style Ar style
Set status line style for windows with an activity alert.
For how to specify
@@ -2987,6 +3014,14 @@ The default is a single space character.
.Pp
.It Ic window-status-style Ar style
Set status line style for a single window.
+For how to specify
+.Ar style ,
+see the
+.Ic message-command-style
+option.
+.Pp
+.It Ic window-style Ar style
+Set the default window style.
For how to specify
.Ar style ,
see the
Index: tmux.h
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.h,v
retrieving revision 1.490
diff -u -p -r1.490 tmux.h
--- tmux.h 6 Feb 2015 17:21:08 -0000 1.490
+++ tmux.h 15 Apr 2015 22:12:44 -0000
@@ -156,6 +156,7 @@ enum key_code {
enum tty_code_code {
TTYC_AX = 0,
TTYC_ACSC, /* acs_chars, ac */
+ TTYC_BCE, /* back_color_erase, ut */
TTYC_BEL, /* bell, bl */
TTYC_BLINK, /* enter_blink_mode, mb */
TTYC_BOLD, /* enter_bold_mode, md */
@@ -902,6 +903,8 @@ struct window_pane {

struct input_ctx ictx;

+ struct grid_cell colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -1606,7 +1609,8 @@ void environ_push(struct environ *);
/* tty.c */
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
-void tty_attributes(struct tty *, const struct grid_cell *);
+void tty_attributes(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
void tty_reset(struct tty *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
@@ -1630,7 +1634,10 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_pane(struct tty *, const struct window_pane *, u_int, u_int,
+ u_int);
+void tty_draw_line(struct tty *, const struct window_pane *, struct screen *,
+ u_int, u_int, u_int);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
Index: tty-term.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tty-term.c,v
retrieving revision 1.36
diff -u -p -r1.36 tty-term.c
--- tty-term.c 20 Jan 2015 08:18:04 -0000 1.36
+++ tty-term.c 15 Apr 2015 22:12:44 -0000
@@ -35,6 +35,7 @@ struct tty_terms tty_terms = LIST_HEAD_I
const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_ACSC, TTYCODE_STRING, "acsc" },
{ TTYC_AX, TTYCODE_FLAG, "AX" },
+ { TTYC_BCE, TTYCODE_FLAG, "bce" },
{ TTYC_BEL, TTYCODE_STRING, "bel" },
{ TTYC_BLINK, TTYCODE_STRING, "blink" },
{ TTYC_BOLD, TTYCODE_STRING, "bold" },
Index: tty.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tty.c,v
retrieving revision 1.174
diff -u -p -r1.174 tty.c
--- tty.c 15 Apr 2015 22:10:13 -0000 1.174
+++ tty.c 15 Apr 2015 22:12:44 -0000
@@ -43,11 +43,14 @@ void tty_colours_fg(struct tty *, const
void tty_colours_bg(struct tty *, const struct grid_cell *);

int tty_large_region(struct tty *, const struct tty_ctx *);
+int tty_fake_bce(const struct tty *, const struct window_pane *);
void tty_redraw_region(struct tty *, const struct tty_ctx *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_repeat_space(struct tty *, u_int);
-void tty_cell(struct tty *, const struct grid_cell *);
+void tty_cell(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
+void tty_default_colours(struct grid_cell *, const struct window_pane *);

#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -582,6 +585,23 @@ tty_large_region(unused struct tty *tty,
}

/*
+ * Return if BCE is needed but the terminal doesn't have it - it'll need to be
+ * emulated.
+ */
+int
+tty_fake_bce(const struct tty *tty, const struct window_pane *wp)
+{
+ struct grid_cell gc;
+
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ tty_default_colours(&gc, wp);
+
+ if (gc.bg == 8 && !(gc.flags & GRID_FLAG_BG256))
+ return (0);
+ return (!tty_term_flag(tty->term, TTYC_BCE));
+}
+
+/*
* Redraw scroll region using data from screen (already updated). Used when
* CSR not supported, or window is a pane that doesn't take up the full
* width of the terminal.
@@ -604,15 +624,23 @@ tty_redraw_region(struct tty *tty, const

if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff);
}
}

void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox,
+ u_int oy)
+{
+ tty_draw_line(tty, wp, wp->screen, py, ox, oy);
+}
+
+void
+tty_draw_line(struct tty *tty, const struct window_pane *wp,
+ struct screen *s, u_int py, u_int ox, u_int oy)
{
const struct grid_cell *gc;
struct grid_line *gl;
@@ -650,20 +678,20 @@ tty_draw_line(struct tty *tty, struct sc
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
- tty_cell(tty, &tmpgc);
+ tty_cell(tty, &tmpgc, wp);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, gc, wp);
}

if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
- tty_term_has(tty->term, TTYC_EL))
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - sx);
@@ -713,19 +741,19 @@ tty_cmd_insertcharacter(struct tty *tty,
struct window_pane *wp = ctx->wp;

if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_term_has(tty->term, TTYC_ICH) ||
- tty_term_has(tty->term, TTYC_ICH1))
+ if (!tty_fake_bce(tty, wp) && (tty_term_has(tty->term, TTYC_ICH) ||
+ tty_term_has(tty->term, TTYC_ICH1)))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
}

void
@@ -733,14 +761,14 @@ tty_cmd_deletecharacter(struct tty *tty,
{
struct window_pane *wp = ctx->wp;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

@@ -754,11 +782,11 @@ tty_cmd_clearcharacter(struct tty *tty,
{
u_int i;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_term_has(tty->term, TTYC_ECH))
+ if (tty_term_has(tty->term, TTYC_ECH) && !tty_fake_bce(tty, ctx->wp))
tty_putcode1(tty, TTYC_ECH, ctx->num);
else {
for (i = 0; i < ctx->num; i++)
@@ -769,14 +797,14 @@ tty_cmd_clearcharacter(struct tty *tty,
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -787,14 +815,14 @@ tty_cmd_insertline(struct tty *tty, cons
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,11 +836,12 @@ tty_cmd_clearline(struct tty *tty, const
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, 0, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) && !tty_fake_bce(tty, wp) &&
+ tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s));
@@ -824,11 +853,12 @@ tty_cmd_clearendofline(struct tty *tty,
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp))
tty_putcode(tty, TTYC_EL);
else
tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
@@ -837,9 +867,10 @@ tty_cmd_clearendofline(struct tty *tty,
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

- if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
+ if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) &&
+ !tty_fake_bce(tty, ctx->wp)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_putcode(tty, TTYC_EL1);
} else {
@@ -854,14 +885,14 @@ tty_cmd_reverseindex(struct tty *tty, co
if (ctx->ocy != ctx->orupper)
return;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_RI)) {
tty_redraw_region(tty, ctx);
return;
}

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -877,7 +908,7 @@ tty_cmd_linefeed(struct tty *tty, const
if (ctx->ocy != ctx->orlower)
return;

- if (!tty_pane_full_width(tty, ctx) ||
+ if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) ||
!tty_term_has(tty->term, TTYC_CSR)) {
if (tty_large_region(tty, ctx))
wp->flags |= PANE_REDRAW;
@@ -894,7 +925,7 @@ tty_cmd_linefeed(struct tty *tty, const
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,12 +940,13 @@ tty_cmd_clearendofscreen(struct tty *tty
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
tty_putcode(tty, TTYC_EL);
if (ctx->ocy != screen_size_y(s) - 1) {
tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
@@ -942,12 +974,13 @@ tty_cmd_clearstartofscreen(struct tty *t
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
for (i = 0; i < ctx->ocy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
@@ -969,12 +1002,13 @@ tty_cmd_clearscreen(struct tty *tty, con
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);

- if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) {
+ if (tty_pane_full_width(tty, ctx) &&
+ tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) {
for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1) {
@@ -997,7 +1031,7 @@ tty_cmd_alignmenttest(struct tty *tty, c
struct screen *s = wp->screen;
u_int i, j;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, wp);

tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);

@@ -1038,12 +1072,12 @@ tty_cmd_cell(struct tty *tty, const stru
*/
cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
tty_cursor_pane(tty, ctx, cx, ctx->ocy);
- tty_cell(tty, &ctx->last_cell);
+ tty_cell(tty, &ctx->last_cell, wp);
}
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);

- tty_cell(tty, ctx->cell);
+ tty_cell(tty, ctx->cell, wp);
}

void
@@ -1055,7 +1089,7 @@ tty_cmd_utf8character(struct tty *tty, c
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
}

void
@@ -1088,12 +1122,13 @@ tty_cmd_rawstring(struct tty *tty, const
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;

- tty_reset(tty);
+ tty_attributes(tty, &grid_default_cell, ctx->wp);
tty_cursor(tty, 0, 0);
}

void
-tty_cell(struct tty *tty, const struct grid_cell *gc)
+tty_cell(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct utf8_data ud;
u_int i;
@@ -1108,7 +1143,7 @@ tty_cell(struct tty *tty, const struct g
return;

/* Set the attributes. */
- tty_attributes(tty, gc);
+ tty_attributes(tty, gc, wp);

/* Get the cell and if ASCII write with putc to do ACS translation. */
grid_cell_get(gc, &ud);
@@ -1312,12 +1347,14 @@ out:
}

void
-tty_attributes(struct tty *tty, const struct grid_cell *gc)
+tty_attributes(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct grid_cell *tc = &tty->cell, gc2;
u_char changed;

memcpy(&gc2, gc, sizeof gc2);
+ tty_default_colours(&gc2, wp);

/*
* If no setab, try to use the reverse attribute as a best-effort for a
@@ -1607,6 +1644,47 @@ tty_try_256(struct tty *tty, u_char colo
}

return (-1);
+}
+
+void
+tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
+{
+ const struct grid_cell *agc, *pgc, *wgc;
+
+ if (wp == NULL)
+ return;
+
+ pgc = &wp->colgc;
+ agc = options_get_style(&wp->window->options, "window-active-style");
+ wgc = options_get_style(&wp->window->options, "window-style");
+
+ if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
+ if (pgc->fg != 8 || (pgc->flags & GRID_FLAG_FG256)) {
+ gc->fg = pgc->fg;
+ gc->flags |= (pgc->flags & GRID_FLAG_FG256);
+ } else if (wp == wp->window->active &&
+ (agc->fg != 8 || (agc->flags & GRID_FLAG_FG256))) {
+ gc->fg = agc->fg;
+ gc->flags |= (agc->flags & GRID_FLAG_FG256);
+ } else {
+ gc->fg = wgc->fg;
+ gc->flags |= (wgc->flags & GRID_FLAG_FG256);
+ }
+ }
+
+ if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) {
+ if (pgc->bg != 8 || (pgc->flags & GRID_FLAG_BG256)) {
+ gc->bg = pgc->bg;
+ gc->flags |= (pgc->flags & GRID_FLAG_BG256);
+ } else if (wp == wp->window->active &&
+ (agc->bg != 8 || (agc->flags & GRID_FLAG_BG256))) {
+ gc->bg = agc->bg;
+ gc->flags |= (agc->flags & GRID_FLAG_BG256);
+ } else {
+ gc->bg = wgc->bg;
+ gc->flags |= (wgc->flags & GRID_FLAG_BG256);
+ }
+ }
}

void
Index: window.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/window.c,v
retrieving revision 1.116
diff -u -p -r1.116 window.c
--- window.c 9 Feb 2015 12:47:18 -0000 1.116
+++ window.c 15 Apr 2015 22:12:44 -0000
@@ -705,6 +705,8 @@ window_pane_create(struct window *w, u_i

wp->saved_grid = NULL;

+ memcpy(&wp->colgc, &grid_default_cell, sizeof wp->colgc);
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
Post by Nicholas Marriott
Post by Nicholas Marriott
+.Fl P ).
I think there has to be a space between the parenthesis and the
period. Without it, the parenthesis gets treated as a flag and a dash
is put before it.
Whoops, yes, I had it like that and must have changed it back by
accident.
Post by Nicholas Marriott
If -g or -P is passed to selectp, other flags are ignored. Is that
the intended behavior?
Yes I think that is more useful than doing both.
J Raynor
2015-04-17 02:59:49 UTC
Permalink
Post by Nicholas Marriott
I like this, don't see any other problems so far.
I applied your patch and looked it over. I don't see any problems, either.
Nicholas Marriott
2015-04-19 21:47:12 UTC
Permalink
I've applied this to OpenBSD now, thanks!
Post by J Raynor
Post by Nicholas Marriott
I like this, don't see any other problems so far.
I applied your patch and looked it over. I don't see any problems, either.
Loading...