Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Luflosi committed Apr 8, 2020
1 parent 4e7bf80 commit 6427384
Show file tree
Hide file tree
Showing 15 changed files with 163 additions and 30 deletions.
28 changes: 19 additions & 9 deletions kitty/child-monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ schedule_write_to_child(unsigned long id, unsigned int num, ...) {
}
screen->write_buf_sz = screen->write_buf_used + sz;
screen->write_buf = PyMem_RawRealloc(screen->write_buf, screen->write_buf_sz);
if (screen->write_buf == NULL) { fatal("Out of memory."); }
if (screen->write_buf == NULL) fatal("Out of memory.");
}
va_start(ap, num);
for (unsigned int i = 0; i < num; i++) {
Expand All @@ -259,7 +259,7 @@ schedule_write_to_child(unsigned long id, unsigned int num, ...) {
if (screen->write_buf_sz > BUFSIZ && screen->write_buf_used < BUFSIZ) {
screen->write_buf_sz = BUFSIZ;
screen->write_buf = PyMem_RawRealloc(screen->write_buf, screen->write_buf_sz);
if (screen->write_buf == NULL) { fatal("Out of memory."); }
if (screen->write_buf == NULL) fatal("Out of memory.");
}
if (screen->write_buf_used) wakeup_io_loop(self, false);
screen_mutex(unlock, write);
Expand Down Expand Up @@ -589,8 +589,13 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int *

static inline void
render_os_window(OSWindow *os_window, monotonic_t now, unsigned int active_window_id, color_type active_window_bg, unsigned int num_visible_windows, bool all_windows_have_same_bg) {
static bool first_time = true;
if (first_time) {
setup_scroll(os_window);
first_time = false;
}
// 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);
if (os_window->clear_count++ < 2) blank_os_window(os_window);
Tab *tab = os_window->tabs + os_window->active_tab;
BorderRects *br = &tab->border_rects;
bool static_live_resize_in_progress = os_window->live_resize.in_progress && OPT(resize_draw_strategy) == RESIZE_DRAW_STATIC;
Expand All @@ -603,19 +608,24 @@ render_os_window(OSWindow *os_window, monotonic_t now, unsigned int active_windo
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.xstart, TD.ystart, TD.dx * x_ratio, TD.dy * y_ratio, TD.screen, os_window, true, false);
for (unsigned int i = 0; i < tab->num_windows; i++) {
Window *w = tab->windows + i;
if (w->visible && WD.screen) {
before_render();
bool is_active_window = i == tab->active_window;
draw_cells(WD.vao_idx, WD.gvao_idx, WD.xstart, WD.ystart, WD.dx * x_ratio, WD.dy * y_ratio, WD.screen, os_window, is_active_window, true);
if (WD.screen->start_visual_bell_at != 0) {
monotonic_t bell_left = OPT(visual_bell_duration) - (now - WD.screen->start_visual_bell_at);
set_maximum_wait(bell_left);
if (WD.screen->render_not_only_pixel_scroll) {
WD.screen->render_not_only_pixel_scroll = false;
draw_cells(WD.vao_idx, WD.gvao_idx, WD.xstart, WD.ystart, WD.dx * x_ratio, WD.dy * y_ratio, WD.screen, os_window, is_active_window, true);
if (WD.screen->start_visual_bell_at != 0) {
monotonic_t bell_left = OPT(visual_bell_duration) - (now - WD.screen->start_visual_bell_at);
set_maximum_wait(bell_left);
}
}
after_render(os_window, (WD.screen->scrolled_by_pixels * 2.0) / os_window->viewport_height);
w->cursor_visible_at_last_render = WD.screen->cursor_render_info.is_visible; w->last_cursor_x = WD.screen->cursor_render_info.x; w->last_cursor_y = WD.screen->cursor_render_info.y; w->last_cursor_shape = WD.screen->cursor_render_info.shape;
}
}
if (TD.screen && os_window->num_tabs >= OPT(tab_bar_min_tabs)) draw_cells(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, os_window, true, false);
swap_window_buffers(os_window);
os_window->last_active_tab = os_window->active_tab; os_window->last_num_tabs = os_window->num_tabs; os_window->last_active_window_id = active_window_id;
os_window->focused_at_last_render = os_window->is_focused;
Expand Down Expand Up @@ -688,7 +698,7 @@ render(monotonic_t now, bool input_read) {
bool needs_render = w->is_damaged || w->live_resize.in_progress;
if (w->viewport_size_dirty) {
w->clear_count = 0;
update_surface_size(w->viewport_width, w->viewport_height, w->offscreen_texture_id);
update_surface_size(w->viewport_width, w->viewport_height, w->offscreen_texture_id, w->scroll_texture_id);
w->viewport_size_dirty = false;
needs_render = true;
}
Expand Down
2 changes: 1 addition & 1 deletion kitty/fonts.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ extract_cell_from_canvas(FontGroup *fg, unsigned int i, unsigned int num_cells)

static inline void
render_group(FontGroup *fg, unsigned int num_cells, unsigned int num_glyphs, CPUCell *cpu_cells, GPUCell *gpu_cells, hb_glyph_info_t *info, hb_glyph_position_t *positions, Font *font, glyph_index glyph, ExtraGlyphs *extra_glyphs, bool center_glyph) {
static SpritePosition* sprite_position[16];
static SpritePosition* sprite_position[16]; // TODO: Remove magic number
int error = 0;
num_cells = MIN(arraysz(sprite_position), num_cells);
for (unsigned int i = 0; i < num_cells; i++) {
Expand Down
6 changes: 5 additions & 1 deletion kitty/gl.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,12 @@ gl_init() {
}

void
update_surface_size(int w, int h, GLuint offscreen_texture_id) {
update_surface_size(int w, int h, GLuint offscreen_texture_id, GLuint scroll_texture_id) {
glViewport(0, 0, w, h);
if (scroll_texture_id) {
glBindTexture(GL_TEXTURE_2D, scroll_texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
if (offscreen_texture_id) {
glBindTexture(GL_TEXTURE_2D, offscreen_texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
Expand Down
2 changes: 1 addition & 1 deletion kitty/gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ typedef struct {


void gl_init(void);
void update_surface_size(int w, int h, GLuint offscreen_texture_id);
void update_surface_size(int w, int h, GLuint offscreen_texture_id, GLuint scroll_texture_id);
void free_texture(GLuint *tex_id);
void free_framebuffer(GLuint *fb_id);
void remove_vao(ssize_t vao_idx);
Expand Down
2 changes: 1 addition & 1 deletion kitty/glfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ framebuffer_size_callback(GLFWwindow *w, int width, int height) {
window->live_resize.width = MAX(0, width); window->live_resize.height = MAX(0, height);
window->live_resize.num_of_resize_events++;
make_os_window_context_current(window);
update_surface_size(width, height, window->offscreen_texture_id);
update_surface_size(width, height, window->offscreen_texture_id, window->scroll_texture_id);
request_tick_callback();
} else log_error("Ignoring resize request for tiny size: %dx%d", width, height);
global_state.callback_os_window = NULL;
Expand Down
1 change: 1 addition & 0 deletions kitty/keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ on_key_input(GLFWkeyevent *ev) {
}
if (screen->scrolled_by && action == GLFW_PRESS && !is_modifier_key(key)) {
screen_history_scroll(screen, SCROLL_FULL, false); // scroll back to bottom
pixel_scroll(screen, 0);
}
bool ok_to_send = action == GLFW_PRESS || action == GLFW_REPEAT || screen->modes.mEXTENDED_KEYBOARD;
if (ok_to_send) {
Expand Down
23 changes: 12 additions & 11 deletions kitty/mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ do_drag_scroll(Window *w, bool upwards) {
Screen *screen = w->render_data.screen;
if (screen->linebuf == screen->main_linebuf) {
screen_history_scroll(screen, SCROLL_LINE, upwards);
pixel_scroll(screen, 0);
update_drag(false, w, false, 0);
if (mouse_cursor_shape != ARROW) {
mouse_cursor_shape = ARROW;
Expand Down Expand Up @@ -651,18 +652,12 @@ scroll_event(double UNUSED xoffset, double yoffset, int flags) {
int s;
bool is_high_resolution = flags & 1;

double pixels = screen->pending_scroll_pixels;
if (is_high_resolution) {
yoffset *= OPT(touch_scroll_multiplier);
if (yoffset * screen->pending_scroll_pixels < 0) {
screen->pending_scroll_pixels = 0; // change of direction
}
double pixels = screen->pending_scroll_pixels + yoffset;
if (fabs(pixels) < global_state.callback_os_window->fonts_data->cell_height) {
screen->pending_scroll_pixels = pixels;
return;
}
pixels += yoffset;
s = (int)round(pixels) / (int)global_state.callback_os_window->fonts_data->cell_height;
screen->pending_scroll_pixels = pixels - s * (int) global_state.callback_os_window->fonts_data->cell_height;
pixels = pixels - s * (int) global_state.callback_os_window->fonts_data->cell_height;
} else {
if (screen->linebuf == screen->main_linebuf || !screen->modes.mouse_tracking_mode) {
// Only use wheel_scroll_multiplier if we are scrolling kitty scrollback or in mouse
Expand All @@ -677,13 +672,18 @@ scroll_event(double UNUSED xoffset, double yoffset, int flags) {
// apparently on cocoa some mice generate really small yoffset values
// when scrolling slowly https://github.com/kovidgoyal/kitty/issues/1238
if (s == 0 && yoffset != 0) s = yoffset > 0 ? 1 : -1;
screen->pending_scroll_pixels = 0;
}
if (s == 0) return;
bool upwards = s > 0;
//printf("asdf %f\n", pixels);
if (screen->linebuf == screen->main_linebuf) {
screen_history_scroll(screen, abs(s), upwards);
if (screen->scrolled_by == 0 && pixels < 0) pixels = 0;
if (screen->scrolled_by == screen->historybuf->count && pixels > 0) pixels = 0;
screen->pending_scroll_pixels = pixels;
pixel_scroll(screen, (int)pixels);
} else {
pixels = 0.0;
pixel_scroll(screen, (int)pixels);
if (screen->modes.mouse_tracking_mode) {
int sz = encode_mouse_event(w, upwards ? GLFW_MOUSE_BUTTON_4 : GLFW_MOUSE_BUTTON_5, PRESS, 0);
if (sz > 0) {
Expand All @@ -696,6 +696,7 @@ scroll_event(double UNUSED xoffset, double yoffset, int flags) {
fake_scroll(abs(s), upwards);
}
}
screen->pending_scroll_pixels = pixels;
}

static PyObject*
Expand Down
11 changes: 11 additions & 0 deletions kitty/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
self->modes = empty_modes;
self->is_dirty = true;
self->scroll_changed = false;
self->pixel_scroll_changed = false;
self->render_not_only_pixel_scroll = false;
self->margin_top = 0; self->margin_bottom = self->lines - 1;
self->history_line_added_count = 0;
RESET_CHARSETS;
Expand Down Expand Up @@ -657,6 +659,7 @@ screen_toggle_screen_buffer(Screen *self) {
self->grman = self->main_grman;
}
screen_history_scroll(self, SCROLL_FULL, false);
pixel_scroll(self, 0);
self->is_dirty = true;
self->selection = EMPTY_SELECTION;
}
Expand Down Expand Up @@ -1199,6 +1202,7 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
self->scrolled_by = 0;
self->scroll_changed = true;
}
pixel_scroll(self, 0);
}
}

Expand Down Expand Up @@ -2205,6 +2209,12 @@ screen_selection_range_for_word(Screen *self, const index_type x, const index_ty
#undef is_ok
}

void pixel_scroll(Screen *self, int amt) {
//printf("pixel_scroll(%d)\n", amt);
self->scrolled_by_pixels = amt;
self->pixel_scroll_changed = true;
}

bool
screen_history_scroll(Screen *self, int amt, bool upwards) {
switch(amt) {
Expand Down Expand Up @@ -2239,6 +2249,7 @@ static PyObject*
scroll(Screen *self, PyObject *args) {
int amt, upwards;
if (!PyArg_ParseTuple(args, "ip", &amt, &upwards)) return NULL;
pixel_scroll(self, 0);
if (screen_history_scroll(self, amt, upwards)) { Py_RETURN_TRUE; }
Py_RETURN_FALSE;
}
Expand Down
4 changes: 3 additions & 1 deletion kitty/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ typedef struct {
PyObject_HEAD

unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by;
int scrolled_by_pixels;
double pending_scroll_pixels;
CellPixelSize cell_size;
OverlayLine overlay_line;
Expand All @@ -87,7 +88,7 @@ typedef struct {
IterationData selection, url;
unsigned int cursor_x, cursor_y, scrolled_by;
} last_rendered;
bool use_latin1, is_dirty, scroll_changed, reload_all_gpu_data;
bool use_latin1, is_dirty, scroll_changed, pixel_scroll_changed, reload_all_gpu_data, render_not_only_pixel_scroll;
Cursor *cursor;
SavepointBuffer main_savepoints, alt_savepoints;
SavemodesBuffer modes_savepoints;
Expand Down Expand Up @@ -197,6 +198,7 @@ bool screen_selection_range_for_line(Screen *self, index_type y, index_type *sta
bool screen_selection_range_for_word(Screen *self, const index_type x, const index_type y, index_type *, index_type *, index_type *start, index_type *end, bool);
void screen_start_selection(Screen *self, index_type x, index_type y, bool, bool, SelectionExtendMode);
void screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_half, bool ended, bool start_extended_selection);
void pixel_scroll(Screen *self, int amt);
bool screen_history_scroll(Screen *self, int amt, bool upwards);
Line* screen_visual_line(Screen *self, index_type y);
unsigned long screen_current_char_width(Screen *self);
Expand Down
11 changes: 11 additions & 0 deletions kitty/scroll_fragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#version GLSL_VERSION
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D screenTexture;

void main()
{
FragColor = texture(screenTexture, TexCoords);
}
13 changes: 13 additions & 0 deletions kitty/scroll_vertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#version GLSL_VERSION
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;

uniform float offset;

out vec2 TexCoords;

void main()
{
gl_Position = vec4(aPos.x, aPos.y - offset, 0.0, 1.0);
TexCoords = aTexCoords;
}
Loading

0 comments on commit 6427384

Please sign in to comment.