Allow centering the background image

Fixes #5525
This commit is contained in:
Kovid Goyal 2022-10-04 08:26:28 +05:30
parent c8d18ffe26
commit ae8f3de070
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
9 changed files with 40 additions and 22 deletions

View File

@ -38,10 +38,10 @@ Detailed list of changes
0.26.4 [future]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Update to Unicode 15.0 (:pull:`5542`)
- macOS: Allow changing the kitty icon by placing a custom icon in the kitty config folder (:pull:`5464`)
- Allow centering the :opt:`background_image` (:iss:`5525`)
- X11: Fix a regression in the previous release that caused pasting from GTK based applications to have extra newlines (:iss:`5528`)
- Tab bar: Improve empty space management when some tabs have short titles, allocate the saved space to the active tab (:iss:`5548`)
@ -50,6 +50,8 @@ Detailed list of changes
- Wayland: Fix background image scaling using tiled mode on high DPI screens
- Update to Unicode 15.0 (:pull:`5542`)
0.26.3 [2022-09-22]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,8 +1,8 @@
#version GLSL_VERSION
#define left -1.0f
#define top 1.0f
#define right 1.0f
#define bottom -1.0f
#define left 0
#define top 1
#define right 2
#define bottom 3
#define tex_left 0
#define tex_top 0
#define tex_right 1
@ -14,15 +14,10 @@
uniform float tiled;
uniform vec4 sizes; // [ window_width, window_height, image_width, image_height ]
uniform vec4 positions; // [ left, top, right, bottom ]
out vec2 texcoord;
const vec2 pos_map[] = vec2[4](
vec2(left, top),
vec2(left, bottom),
vec2(right, bottom),
vec2(right, top)
);
const vec2 tex_map[] = vec2[4](
vec2(tex_left, tex_top),
vec2(tex_left, tex_bottom),
@ -39,6 +34,12 @@ float tiling_factor(int i) {
}
void main() {
vec2 pos_map[] = vec2[4](
vec2(positions[left], positions[top]),
vec2(positions[left], positions[bottom]),
vec2(positions[right], positions[bottom]),
vec2(positions[right], positions[top])
);
vec2 tex_coords = tex_map[gl_VertexID];
texcoord = vec2(
tex_coords[x_axis] * tiling_factor(x_axis),

View File

@ -65,7 +65,7 @@ typedef enum MouseTrackingModes { NO_TRACKING, BUTTON_MODE, MOTION_MODE, ANY_MOD
typedef enum MouseTrackingProtocols { NORMAL_PROTOCOL, UTF8_PROTOCOL, SGR_PROTOCOL, URXVT_PROTOCOL, SGR_PIXEL_PROTOCOL} MouseTrackingProtocol;
typedef enum MouseShapes { BEAM, HAND, ARROW } MouseShape;
typedef enum { NONE, MENUBAR, WINDOW, ALL } WindowTitleIn;
typedef enum { TILING, SCALED, MIRRORED, CLAMPED } BackgroundImageLayout;
typedef enum { TILING, SCALED, MIRRORED, CLAMPED, CENTER_CLAMPED } BackgroundImageLayout;
typedef struct ImageAnchorPosition {
float canvas_x, canvas_y, image_x, image_y;
} ImageAnchorPosition;

View File

@ -1285,10 +1285,10 @@ opt('background_image', 'none',
)
opt('background_image_layout', 'tiled',
choices=('mirror-tiled', 'scaled', 'tiled', 'clamped'), ctype='bglayout',
choices=('mirror-tiled', 'scaled', 'tiled', 'clamped', 'centered'), ctype='bglayout',
long_text='''
Whether to tile, scale or clamp the background image. The value can be one of
:code:`tiled`, :code:`mirror-tiled`, :code:`scaled`, :code:`clamped`.
:code:`tiled`, :code:`mirror-tiled`, :code:`scaled`, :code:`clamped` or :code:`centered`.
'''
)

View File

@ -73,7 +73,7 @@ class Parser:
raise ValueError(f"The value {val} is not a valid choice for background_image_layout")
ans["background_image_layout"] = val
choices_for_background_image_layout = frozenset(('mirror-tiled', 'scaled', 'tiled', 'clamped'))
choices_for_background_image_layout = frozenset(('mirror-tiled', 'scaled', 'tiled', 'clamped', 'centered'))
def background_image_linear(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['background_image_linear'] = to_bool(val)

View File

@ -64,7 +64,9 @@ bglayout(PyObject *layout_name) {
case 't': return TILING;
case 'm': return MIRRORED;
case 's': return SCALED;
case 'c': return CLAMPED;
case 'c': {
return name[1] == 'l' ? CLAMPED : CENTER_CLAMPED;
}
default: break;
}
return TILING;

View File

@ -15,7 +15,7 @@ import kitty.types
if typing.TYPE_CHECKING:
choices_for_allow_cloning = typing.Literal['yes', 'y', 'true', 'no', 'n', 'false', 'ask']
choices_for_allow_remote_control = typing.Literal['password', 'socket-only', 'socket', 'no', 'n', 'false', 'yes', 'y', 'true']
choices_for_background_image_layout = typing.Literal['mirror-tiled', 'scaled', 'tiled', 'clamped']
choices_for_background_image_layout = typing.Literal['mirror-tiled', 'scaled', 'tiled', 'clamped', 'centered']
choices_for_default_pointer_shape = typing.Literal['arrow', 'beam', 'hand']
choices_for_linux_display_server = typing.Literal['auto', 'wayland', 'x11']
choices_for_macos_colorspace = typing.Literal['srgb', 'default', 'displayp3']

View File

@ -184,7 +184,7 @@ typedef struct {
static CellProgramLayout cell_program_layouts[NUM_PROGRAMS];
static ssize_t blit_vertex_array;
typedef struct {
GLint image_location, tiled_location, sizes_location, opacity_location, premult_location;
GLint image_location, tiled_location, sizes_location, positions_location, opacity_location, premult_location;
} BGImageProgramLayout;
static BGImageProgramLayout bgimage_program_layout = {0};
typedef struct {
@ -212,6 +212,7 @@ init_cell_program(void) {
bgimage_program_layout.image_location = get_uniform_location(BGIMAGE_PROGRAM, "image");
bgimage_program_layout.opacity_location = get_uniform_location(BGIMAGE_PROGRAM, "opacity");
bgimage_program_layout.sizes_location = get_uniform_location(BGIMAGE_PROGRAM, "sizes");
bgimage_program_layout.positions_location = get_uniform_location(BGIMAGE_PROGRAM, "positions");
bgimage_program_layout.tiled_location = get_uniform_location(BGIMAGE_PROGRAM, "tiled");
bgimage_program_layout.premult_location = get_uniform_location(BGIMAGE_PROGRAM, "premult");
tint_program_layout.tint_color_location = get_uniform_location(TINT_PROGRAM, "tint_color");
@ -428,13 +429,26 @@ draw_bg(OSWindow *w) {
(GLfloat)w->viewport_width, (GLfloat)w->viewport_height, (GLfloat)w->bgimage->width, (GLfloat)w->bgimage->height);
glUniform1f(bgimage_program_layout.premult_location, w->is_semi_transparent ? 1.f : 0.f);
GLfloat tiled = 0.f;;
GLfloat left = -1.0, top = 1.0, right = 1.0, bottom = -1.0;
switch (OPT(background_image_layout)) {
case TILING: case MIRRORED: case CLAMPED:
tiled = 1.f; break;
case SCALED:
tiled = 0.f; break;
case CENTER_CLAMPED:
tiled = 1.f;
if (w->viewport_width > (int)w->bgimage->width) {
GLfloat frac = (w->viewport_width - w->bgimage->width) / (GLfloat)w->viewport_width;
left += frac; right += frac;
}
if (w->viewport_height > (int)w->bgimage->height) {
GLfloat frac = (w->viewport_height - w->bgimage->height) / (GLfloat)w->viewport_height;
top -= frac; bottom -= frac;
}
break;
}
glUniform1f(bgimage_program_layout.tiled_location, tiled);
glUniform4f(bgimage_program_layout.positions_location, left, top, right, bottom);
glActiveTexture(GL_TEXTURE0 + BGIMAGE_UNIT);
glBindTexture(GL_TEXTURE_2D, w->bgimage->texture_id);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

View File

@ -134,15 +134,14 @@ window_for_window_id(id_type kitty_window_id) {
static void
send_bgimage_to_gpu(BackgroundImageLayout layout, BackgroundImage *bgimage) {
RepeatStrategy r;
RepeatStrategy r = REPEAT_DEFAULT;
switch (layout) {
case SCALED:
case CLAMPED:
case CLAMPED: case CENTER_CLAMPED:
r = REPEAT_CLAMP; break;
case MIRRORED:
r = REPEAT_MIRROR; break;
case TILING:
default:
r = REPEAT_DEFAULT; break;
}
bgimage->texture_id = 0;