Preserve text size during live resize

This commit is contained in:
Kovid Goyal 2023-06-20 19:41:57 +05:30
parent 5c735c123a
commit c66e4ced56
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
7 changed files with 45 additions and 23 deletions

View file

@ -42,7 +42,7 @@ Detailed list of changes
- A new option :opt:`text_fg_override_threshold` to force text colors to have high contrast regardless of color scheme (:pull:`6283`)
- When resizing OS Windows make the animation less jerky on macOS and Wayland. Also always show the window size in cells during the resize and scale the window contents while the resize is in progress to give a visual indicator of the relative size change (:iss:`6341`)
- When resizing OS Windows make the animation less jerky. Also show the window size in cells during the resize (:iss:`6341`)
- unicode_input kitten: Fix a regression in 0.28.0 that caused the order of recent and favorites entries to not be respected (:iss:`6214`)

View file

@ -745,22 +745,20 @@ draw_resizing_text(OSWindow *w) {
}
}
static void
render_os_window(OSWindow *os_window, unsigned int active_window_id, color_type active_window_bg, unsigned int num_visible_windows, bool all_windows_have_same_bg) {
// ensure all pixels are cleared to background color at least once in every buffer
if (os_window->clear_count++ < 3) blank_os_window(os_window);
Tab *tab = os_window->tabs + os_window->active_tab;
BorderRects *br = &tab->border_rects;
static const float x_ratio = 1, y_ratio = 1;
draw_borders(br->vao_idx, br->num_border_rects, br->rect_buf, br->is_dirty, os_window->viewport_width, os_window->viewport_height, active_window_bg, num_visible_windows, all_windows_have_same_bg, os_window);
br->is_dirty = false;
if (TD.screen && os_window->num_tabs >= OPT(tab_bar_min_tabs)) draw_cells(TD.vao_idx, 0, &TD, x_ratio, y_ratio, os_window, true, false, NULL);
if (TD.screen && os_window->num_tabs >= OPT(tab_bar_min_tabs)) draw_cells(TD.vao_idx, 0, &TD, os_window, true, false, NULL);
for (unsigned int i = 0; i < tab->num_windows; i++) {
Window *w = tab->windows + i;
if (w->visible && WD.screen) {
bool is_active_window = i == tab->active_window;
draw_cells(WD.vao_idx, WD.gvao_idx, &WD, x_ratio, y_ratio, os_window, is_active_window, true, w);
draw_cells(WD.vao_idx, WD.gvao_idx, &WD, os_window, is_active_window, true, w);
if (WD.screen->start_visual_bell_at != 0) {
set_maximum_wait(OPT(repaint_delay));
}

View file

@ -39,6 +39,14 @@ static GLFWcursor *standard_cursor = NULL, *click_cursor = NULL, *arrow_cursor =
static void set_os_window_dpi(OSWindow *w);
static void
apply_swap_interval(int val) {
(void)val;
#ifndef __APPLE__
if (val < 0) val = OPT(sync_to_monitor) && !global_state.is_wayland ? 1 : 0;
glfwSwapInterval(val);
#endif
}
void
get_platform_dependent_config_values(void *glfw_window) {
@ -285,11 +293,19 @@ window_iconify_callback(GLFWwindow *window, int iconified) {
global_state.callback_os_window = NULL;
}
void
change_live_resize_state(OSWindow *w, bool in_progress) {
if (in_progress != w->live_resize.in_progress) {
w->live_resize.in_progress = in_progress;
apply_swap_interval(in_progress ? 0 : -1);
}
}
static void
live_resize_callback(GLFWwindow *w, bool started) {
if (!set_callback_window(w)) return;
global_state.callback_os_window->live_resize.from_os_notification = true;
global_state.callback_os_window->live_resize.in_progress = true;
change_live_resize_state(global_state.callback_os_window, true);
global_state.has_pending_resizes = true;
if (!started) {
global_state.callback_os_window->live_resize.os_says_resize_complete = true;
@ -305,7 +321,7 @@ framebuffer_size_callback(GLFWwindow *w, int width, int height) {
if (width >= min_width && height >= min_height) {
OSWindow *window = global_state.callback_os_window;
global_state.has_pending_resizes = true;
window->live_resize.in_progress = true;
change_live_resize_state(global_state.callback_os_window, true);
window->live_resize.last_resize_event_at = monotonic();
window->live_resize.width = MAX(0, width); window->live_resize.height = MAX(0, height);
window->live_resize.num_of_resize_events++;
@ -322,7 +338,8 @@ dpi_change_callback(GLFWwindow *w, float x_scale UNUSED, float y_scale UNUSED) {
// Ensure update_os_window_viewport() is called in the near future, it will
// take care of DPI changes.
OSWindow *window = global_state.callback_os_window;
window->live_resize.in_progress = true; global_state.has_pending_resizes = true;
change_live_resize_state(global_state.callback_os_window, true);
global_state.has_pending_resizes = true;
window->live_resize.last_resize_event_at = monotonic();
global_state.callback_os_window = NULL;
request_tick_callback();
@ -940,9 +957,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
// blank the window once so that there is no initial flash of color
// changing, in case the background color is not black
blank_canvas(is_semi_transparent ? OPT(background_opacity) : 1.0f, OPT(background));
#ifndef __APPLE__
glfwSwapInterval(OPT(sync_to_monitor) && !global_state.is_wayland ? 1 : 0);
#endif
apply_swap_interval(-1);
// On Wayland the initial swap is allowed only after the first XDG configure event
if (glfwAreSwapsAllowed(glfw_window)) glfwSwapBuffers(glfw_window);
glfwSetInputMode(glfw_window, GLFW_LOCK_KEY_MODS, true);

View file

@ -916,14 +916,6 @@ gpu_data_for_image(ImageRenderData *ans, float left, float top, float right, flo
ans->group_count = 1;
}
void
gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height) {
float width_frac = 2 * MIN(1, width / (float)screen_width_px), height_frac = 2 * MIN(1, height / (float)screen_height_px);
float hmargin = (2 - width_frac) / 2;
float vmargin = (2 - height_frac) / 2;
gpu_data_for_image(ans, -1 + hmargin, 1 - vmargin, -1 + hmargin + width_frac, 1 - vmargin - height_frac);
}
bool
grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float screen_left, float screen_top, float dx, float dy, unsigned int num_cols, unsigned int num_rows, CellPixelSize cell) {
if (self->last_scrolled_by != scrolled_by) self->layers_dirty = true;

View file

@ -169,7 +169,6 @@ void grman_rescale(GraphicsManager *self, CellPixelSize fg);
void grman_remove_cell_images(GraphicsManager *self, int32_t top, int32_t bottom);
void grman_remove_all_cell_images(GraphicsManager *self);
void gpu_data_for_image(ImageRenderData *ans, float left, float top, float right, float bottom);
void gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height);
bool png_from_file_pointer(FILE* fp, const char *path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz);
bool png_path_to_bitmap(const char *path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz);
bool scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap, bool os_window_context_set);

View file

@ -191,6 +191,7 @@ typedef struct CellRenderData {
GLint xstart, ystart;
GLsizei width, height;
} px;
float x_ratio, y_ratio;
} CellRenderData;
typedef struct {
@ -510,6 +511,15 @@ load_alpha_mask_texture(size_t width, size_t height, uint8_t *canvas) {
return &data;
}
static void
gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height) {
float width_frac = 2 * MIN(1, width / (float)screen_width_px), height_frac = 2 * MIN(1, height / (float)screen_height_px);
float hmargin = (2 - width_frac) / 2;
float vmargin = (2 - height_frac) / 2;
gpu_data_for_image(ans, -1 + hmargin, 1 - vmargin, -1 + hmargin + width_frac, 1 - vmargin - height_frac);
}
void
draw_centered_alpha_mask(OSWindow *os_window, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas) {
ImageRenderData *data = load_alpha_mask_texture(width, height, canvas);
@ -930,11 +940,19 @@ get_visual_bell_intensity(Screen *screen) {
}
void
draw_cells(ssize_t vao_idx, ssize_t gvao_idx, const ScreenRenderData *srd, float x_ratio, float y_ratio, OSWindow *os_window, bool is_active_window, bool can_be_focused, Window *window) {
draw_cells(ssize_t vao_idx, ssize_t gvao_idx, const ScreenRenderData *srd, OSWindow *os_window, bool is_active_window, bool can_be_focused, Window *window) {
float x_ratio = 1., y_ratio = 1.;
if (os_window->live_resize.in_progress) {
x_ratio = (float) os_window->viewport_width / (float) os_window->live_resize.width;
y_ratio = (float) os_window->viewport_height / (float) os_window->live_resize.height;
}
Screen *screen = srd->screen;
CELL_BUFFERS;
bool inverted = screen_invert_colors(screen);
CellRenderData crd = {.gl={.xstart = srd->xstart, .ystart = srd->ystart, .dx = srd->dx * x_ratio, .dy = srd->dy * y_ratio} };
CellRenderData crd = {
.gl={.xstart = srd->xstart, .ystart = srd->ystart, .dx = srd->dx * x_ratio, .dy = srd->dy * y_ratio},
.x_ratio=x_ratio, .y_ratio=y_ratio
};
crd.gl.width = crd.gl.dx * screen->columns; crd.gl.height = crd.gl.dy * screen->lines;
// The scissor limits below are calculated to ensure that they do not
// overlap with the pixels outside the draw area. We can't use the actual pixel window dimensions

View file

@ -293,7 +293,7 @@ ssize_t create_cell_vao(void);
ssize_t create_graphics_vao(void);
ssize_t create_border_vao(void);
bool send_cell_data_to_gpu(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *);
void draw_cells(ssize_t, ssize_t, const ScreenRenderData*, float, float, OSWindow *, bool, bool, Window*);
void draw_cells(ssize_t, ssize_t, const ScreenRenderData*, OSWindow *, bool, bool, Window*);
void draw_centered_alpha_mask(OSWindow *w, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas);
void update_surface_size(int, int, uint32_t);
void free_texture(uint32_t*);