Make the URL highlight color configurable
This commit is contained in:
parent
53ea5c678d
commit
9989363ecd
@ -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);
|
||||
}
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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++) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user