Make the URL highlight color configurable

This commit is contained in:
Kovid Goyal 2017-09-15 07:15:16 +05:30
parent 53ea5c678d
commit 9989363ecd
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 42 additions and 26 deletions

View File

@ -4,6 +4,7 @@ uniform vec4 steps; // xstart, ystart, dx, dy
uniform vec2 sprite_layout; // dx, dy
uniform ivec2 color_indices; // which color to use as fg and which as bg
uniform uvec4 default_colors; // The default colors
uniform uint url_color; // The color to use for the URL highlight
uniform uvec4 url_range; // The range for the currently highlighted URL (start_x, end_x, start_y, end_y)
uniform ColorTable {
uint color_table[256]; // The color table
@ -30,6 +31,7 @@ const uint BYTE_MASK = uint(0xFF);
const uint SHORT_MASK = uint(0xFFFF);
const uint ZERO = uint(0);
const uint ONE = uint(1);
const uint TWO = uint(2);
const uint THREE = uint(3);
const uint DECORATION_MASK = uint(3);
const uint STRIKE_MASK = uint(1);
@ -72,16 +74,19 @@ vec3 apply_selection(vec3 color, uint which) {
return is_selected * color_to_vec(which) + (1.0 - is_selected) * color;
}
uint in_range(uvec4 range, uint x, uint y) {
if (range[0] <= x && x <= range[1] && range[2] <= y && y <= range[3]) return ONE;
return ZERO;
vec3 mix_vecs(float q, vec3 a, vec3 b) {
return q * a + (1.0 - q) * b;
}
float in_range(uvec4 range, uint x, uint y) {
if (range[2] == y && range[0] <= x && x <= range[1]) return 1.0;
return 0.0;
}
void main() {
uint instance_id = uint(gl_InstanceID);
uint r = instance_id / dimensions.x;
uint c = instance_id - r * dimensions.x;
uint in_url = in_range(url_range, c, r);
float left = steps[0] + c * steps[2];
float top = steps[1] - r * steps[3];
vec2 xpos = vec2(left, left + steps[2]);
@ -94,11 +99,10 @@ void main() {
uint fg = colors[color_indices[reverse]];
uint bg = colors[color_indices[ONE - reverse]];
uint resolved_fg = as_color(fg, default_colors[color_indices[0]]);
uint underline;
foreground = apply_selection(color_to_vec(resolved_fg), default_colors[2]);
background = apply_selection(to_color(bg, default_colors[color_indices[1]]), default_colors[3]);
if (in_url == ONE) { underline = ONE; decoration_fg = color_to_vec(uint(255)); }
else { underline = (text_attrs >> 26) & DECORATION_MASK; decoration_fg = to_color(colors[2], resolved_fg); }
underline_pos = to_sprite_pos(pos, underline, ZERO, ZERO);
float in_url = in_range(url_range, c, r);
decoration_fg = mix_vecs(in_url, color_to_vec(url_color), to_color(colors[2], resolved_fg));
underline_pos = mix_vecs(in_url, to_sprite_pos(pos, TWO, ZERO, ZERO), to_sprite_pos(pos, (text_attrs >> 26) & DECORATION_MASK, ZERO, ZERO));
strike_pos = to_sprite_pos(pos, ((text_attrs >> 31) & STRIKE_MASK) * THREE, ZERO, ZERO);
}

View File

@ -235,7 +235,7 @@ type_map = {
for name in (
'foreground background cursor active_border_color inactive_border_color'
' selection_foreground selection_background'
' selection_foreground selection_background url_color'
).split():
type_map[name] = lambda x: to_color(x, validate=True)
for i in range(16):

View File

@ -45,6 +45,9 @@ selection_foreground #000000
# The background for selections
selection_background #FFFACD
# The color for highlighting URLs on mouse-over
url_color #0087BD
# The cursor color
cursor #ffffff

View File

@ -552,7 +552,7 @@ destroy_sprite_map() {
// Cell {{{
enum CellUniforms { CELL_dimensions, CELL_default_colors, CELL_color_indices, CELL_steps, CELL_sprites, CELL_sprite_layout, CELL_url_range, CELL_color_table, NUM_CELL_UNIFORMS };
enum CellUniforms { CELL_dimensions, CELL_default_colors, CELL_color_indices, CELL_steps, CELL_sprites, CELL_sprite_layout, CELL_url_color, CELL_url_range, CELL_color_table, NUM_CELL_UNIFORMS };
static GLint cell_uniform_locations[NUM_CELL_UNIFORMS] = {0};
static GLint cell_color_table_stride = 0, cell_color_table_offset = 0, cell_color_table_size = 0, cell_color_table_block_index = 0;
@ -570,6 +570,7 @@ init_cell_program() {
else SET_LOC(sprites);
else SET_LOC(sprite_layout);
else SET_LOC(url_range);
else SET_LOC(url_color);
else if (strcmp(p->uniforms[i].name, "color_table[0]") == 0) { ctable_idx = i; cell_uniform_locations[CELL_color_table] = p->uniforms[i].location; }
else { fatal("Unknown uniform in cell program: %s", p->uniforms[i].name); }
}
@ -601,6 +602,8 @@ create_cell_vao() {
#undef A1
}
static bool cell_constants_sent = false;
static void
draw_cells_impl(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen) {
size_t sz;
@ -628,29 +631,25 @@ draw_cells_impl(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLf
#define UL(name) cell_uniform_locations[CELL_##name]
bind_program(CELL_PROGRAM);
bind_vao_uniform_buffer(vao_idx, 2, cell_color_table_block_index);
glUniform2ui(UL(dimensions), screen->columns, screen->lines);
check_gl();
glUniform4f(UL(steps), xstart, ystart, dx, dy);
check_gl();
glUniform2i(UL(color_indices), inverted & 1, 1 - (inverted & 1));
check_gl();
glUniform2ui(UL(dimensions), screen->columns, screen->lines); check_gl();
glUniform4f(UL(steps), xstart, ystart, dx, dy); check_gl();
glUniform2i(UL(color_indices), inverted & 1, 1 - (inverted & 1)); check_gl();
#define COLOR(name) colorprofile_to_color(screen->color_profile, screen->color_profile->overridden.name, screen->color_profile->configured.name)
glUniform4ui(UL(default_colors), COLOR(default_fg), COLOR(default_bg), COLOR(highlight_fg), COLOR(highlight_bg));
check_gl();
glUniform4ui(UL(default_colors), COLOR(default_fg), COLOR(default_bg), COLOR(highlight_fg), COLOR(highlight_bg)); check_gl();
#undef COLOR
GLuint start_x, start_y, end_x, end_y;
screen_url_range(screen, &start_x, &start_y, &end_x, &end_y);
glUniform4ui(UL(url_range), start_x, end_x, start_y, end_y);
check_gl();
glUniform1i(UL(sprites), sprite_map_unit);
check_gl();
glUniform4ui(UL(url_range), start_x, end_x, start_y, end_y); check_gl();
glUniform1i(UL(sprites), sprite_map_unit); check_gl();
unsigned int x, y, z;
sprite_map_current_layout(&x, &y, &z);
glUniform2f(UL(sprite_layout), 1.0 / (float)x, 1.0 / (float)y);
check_gl();
glUniform2f(UL(sprite_layout), 1.0 / (float)x, 1.0 / (float)y); check_gl();
if (!cell_constants_sent) {
glUniform1ui(UL(url_color), OPT(url_color)); check_gl();
cell_constants_sent = true;
}
bind_vertex_array(vao_idx);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
check_gl();
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); check_gl();
unbind_vertex_array();
unbind_program();
unbind_sprite_map();

View File

@ -118,6 +118,14 @@ swap_windows(unsigned int tab_id, unsigned int a, unsigned int b) {
#define TWO_UINT(name) PYWRAP1(name) { unsigned int a, b; PA("II", &a, &b); name(a, b); Py_RETURN_NONE; }
#define THREE_UINT(name) PYWRAP1(name) { unsigned int a, b, c; PA("III", &a, &b, &c); name(a, b, c); Py_RETURN_NONE; }
static inline color_type
color_as_int(PyObject *color) {
if (!PyTuple_Check(color)) { PyErr_SetString(PyExc_TypeError, "Not a color tuple"); return 0; }
#define I(n, s) ((PyLong_AsUnsignedLong(PyTuple_GET_ITEM(color, n)) & 0xff) << s)
return (I(0, 16) | I(1, 8) | I(2, 0)) & 0xffffff;
#undef I
}
PYWRAP1(set_options) {
#define S(name, convert) { PyObject *ret = PyObject_GetAttrString(args, #name); if (ret == NULL) return NULL; global_state.opts.name = convert(ret); Py_DECREF(ret); if (PyErr_Occurred()) return NULL; }
S(visual_bell_duration, PyFloat_AsDouble);
@ -130,6 +138,7 @@ PYWRAP1(set_options) {
S(wheel_scroll_multiplier, PyFloat_AsDouble);
S(open_url_modifiers, PyLong_AsUnsignedLong);
S(click_interval, PyFloat_AsDouble);
S(url_color, color_as_int);
PyObject *chars = PyObject_GetAttrString(args, "select_by_word_characters");
if (chars == NULL) return NULL;
for (size_t i = 0; i < MIN((size_t)PyUnicode_GET_LENGTH(chars), sizeof(OPT(select_by_word_characters))/sizeof(OPT(select_by_word_characters[0]))); i++) {

View File

@ -15,6 +15,7 @@ typedef struct {
CursorShape cursor_shape;
unsigned int open_url_modifiers;
char_type select_by_word_characters[256]; size_t select_by_word_characters_count;
color_type url_color;
} Options;
typedef struct {