Skip to content

Commit 6427384

Browse files
committed
WIP
1 parent 4e7bf80 commit 6427384

File tree

15 files changed

+163
-30
lines changed

15 files changed

+163
-30
lines changed

kitty/child-monitor.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ schedule_write_to_child(unsigned long id, unsigned int num, ...) {
246246
}
247247
screen->write_buf_sz = screen->write_buf_used + sz;
248248
screen->write_buf = PyMem_RawRealloc(screen->write_buf, screen->write_buf_sz);
249-
if (screen->write_buf == NULL) { fatal("Out of memory."); }
249+
if (screen->write_buf == NULL) fatal("Out of memory.");
250250
}
251251
va_start(ap, num);
252252
for (unsigned int i = 0; i < num; i++) {
@@ -259,7 +259,7 @@ schedule_write_to_child(unsigned long id, unsigned int num, ...) {
259259
if (screen->write_buf_sz > BUFSIZ && screen->write_buf_used < BUFSIZ) {
260260
screen->write_buf_sz = BUFSIZ;
261261
screen->write_buf = PyMem_RawRealloc(screen->write_buf, screen->write_buf_sz);
262-
if (screen->write_buf == NULL) { fatal("Out of memory."); }
262+
if (screen->write_buf == NULL) fatal("Out of memory.");
263263
}
264264
if (screen->write_buf_used) wakeup_io_loop(self, false);
265265
screen_mutex(unlock, write);
@@ -589,8 +589,13 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int *
589589

590590
static inline void
591591
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) {
592+
static bool first_time = true;
593+
if (first_time) {
594+
setup_scroll(os_window);
595+
first_time = false;
596+
}
592597
// ensure all pixels are cleared to background color at least once in every buffer
593-
if (os_window->clear_count++ < 3) blank_os_window(os_window);
598+
if (os_window->clear_count++ < 2) blank_os_window(os_window);
594599
Tab *tab = os_window->tabs + os_window->active_tab;
595600
BorderRects *br = &tab->border_rects;
596601
bool static_live_resize_in_progress = os_window->live_resize.in_progress && OPT(resize_draw_strategy) == RESIZE_DRAW_STATIC;
@@ -603,19 +608,24 @@ render_os_window(OSWindow *os_window, monotonic_t now, unsigned int active_windo
603608
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);
604609
br->is_dirty = false;
605610
}
606-
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);
607611
for (unsigned int i = 0; i < tab->num_windows; i++) {
608612
Window *w = tab->windows + i;
609613
if (w->visible && WD.screen) {
614+
before_render();
610615
bool is_active_window = i == tab->active_window;
611-
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);
612-
if (WD.screen->start_visual_bell_at != 0) {
613-
monotonic_t bell_left = OPT(visual_bell_duration) - (now - WD.screen->start_visual_bell_at);
614-
set_maximum_wait(bell_left);
616+
if (WD.screen->render_not_only_pixel_scroll) {
617+
WD.screen->render_not_only_pixel_scroll = false;
618+
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);
619+
if (WD.screen->start_visual_bell_at != 0) {
620+
monotonic_t bell_left = OPT(visual_bell_duration) - (now - WD.screen->start_visual_bell_at);
621+
set_maximum_wait(bell_left);
622+
}
615623
}
624+
after_render(os_window, (WD.screen->scrolled_by_pixels * 2.0) / os_window->viewport_height);
616625
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;
617626
}
618627
}
628+
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);
619629
swap_window_buffers(os_window);
620630
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;
621631
os_window->focused_at_last_render = os_window->is_focused;
@@ -688,7 +698,7 @@ render(monotonic_t now, bool input_read) {
688698
bool needs_render = w->is_damaged || w->live_resize.in_progress;
689699
if (w->viewport_size_dirty) {
690700
w->clear_count = 0;
691-
update_surface_size(w->viewport_width, w->viewport_height, w->offscreen_texture_id);
701+
update_surface_size(w->viewport_width, w->viewport_height, w->offscreen_texture_id, w->scroll_texture_id);
692702
w->viewport_size_dirty = false;
693703
needs_render = true;
694704
}

kitty/fonts.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ extract_cell_from_canvas(FontGroup *fg, unsigned int i, unsigned int num_cells)
720720

721721
static inline void
722722
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) {
723-
static SpritePosition* sprite_position[16];
723+
static SpritePosition* sprite_position[16]; // TODO: Remove magic number
724724
int error = 0;
725725
num_cells = MIN(arraysz(sprite_position), num_cells);
726726
for (unsigned int i = 0; i < num_cells; i++) {

kitty/gl.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ gl_init() {
6767
}
6868

6969
void
70-
update_surface_size(int w, int h, GLuint offscreen_texture_id) {
70+
update_surface_size(int w, int h, GLuint offscreen_texture_id, GLuint scroll_texture_id) {
7171
glViewport(0, 0, w, h);
72+
if (scroll_texture_id) {
73+
glBindTexture(GL_TEXTURE_2D, scroll_texture_id);
74+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
75+
}
7276
if (offscreen_texture_id) {
7377
glBindTexture(GL_TEXTURE_2D, offscreen_texture_id);
7478
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

kitty/gl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ typedef struct {
3333

3434

3535
void gl_init(void);
36-
void update_surface_size(int w, int h, GLuint offscreen_texture_id);
36+
void update_surface_size(int w, int h, GLuint offscreen_texture_id, GLuint scroll_texture_id);
3737
void free_texture(GLuint *tex_id);
3838
void free_framebuffer(GLuint *fb_id);
3939
void remove_vao(ssize_t vao_idx);

kitty/glfw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ framebuffer_size_callback(GLFWwindow *w, int width, int height) {
203203
window->live_resize.width = MAX(0, width); window->live_resize.height = MAX(0, height);
204204
window->live_resize.num_of_resize_events++;
205205
make_os_window_context_current(window);
206-
update_surface_size(width, height, window->offscreen_texture_id);
206+
update_surface_size(width, height, window->offscreen_texture_id, window->scroll_texture_id);
207207
request_tick_callback();
208208
} else log_error("Ignoring resize request for tiny size: %dx%d", width, height);
209209
global_state.callback_os_window = NULL;

kitty/keys.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ on_key_input(GLFWkeyevent *ev) {
187187
}
188188
if (screen->scrolled_by && action == GLFW_PRESS && !is_modifier_key(key)) {
189189
screen_history_scroll(screen, SCROLL_FULL, false); // scroll back to bottom
190+
pixel_scroll(screen, 0);
190191
}
191192
bool ok_to_send = action == GLFW_PRESS || action == GLFW_REPEAT || screen->modes.mEXTENDED_KEYBOARD;
192193
if (ok_to_send) {

kitty/mouse.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ do_drag_scroll(Window *w, bool upwards) {
192192
Screen *screen = w->render_data.screen;
193193
if (screen->linebuf == screen->main_linebuf) {
194194
screen_history_scroll(screen, SCROLL_LINE, upwards);
195+
pixel_scroll(screen, 0);
195196
update_drag(false, w, false, 0);
196197
if (mouse_cursor_shape != ARROW) {
197198
mouse_cursor_shape = ARROW;
@@ -651,18 +652,12 @@ scroll_event(double UNUSED xoffset, double yoffset, int flags) {
651652
int s;
652653
bool is_high_resolution = flags & 1;
653654

655+
double pixels = screen->pending_scroll_pixels;
654656
if (is_high_resolution) {
655657
yoffset *= OPT(touch_scroll_multiplier);
656-
if (yoffset * screen->pending_scroll_pixels < 0) {
657-
screen->pending_scroll_pixels = 0; // change of direction
658-
}
659-
double pixels = screen->pending_scroll_pixels + yoffset;
660-
if (fabs(pixels) < global_state.callback_os_window->fonts_data->cell_height) {
661-
screen->pending_scroll_pixels = pixels;
662-
return;
663-
}
658+
pixels += yoffset;
664659
s = (int)round(pixels) / (int)global_state.callback_os_window->fonts_data->cell_height;
665-
screen->pending_scroll_pixels = pixels - s * (int) global_state.callback_os_window->fonts_data->cell_height;
660+
pixels = pixels - s * (int) global_state.callback_os_window->fonts_data->cell_height;
666661
} else {
667662
if (screen->linebuf == screen->main_linebuf || !screen->modes.mouse_tracking_mode) {
668663
// Only use wheel_scroll_multiplier if we are scrolling kitty scrollback or in mouse
@@ -677,13 +672,18 @@ scroll_event(double UNUSED xoffset, double yoffset, int flags) {
677672
// apparently on cocoa some mice generate really small yoffset values
678673
// when scrolling slowly https://github.com/kovidgoyal/kitty/issues/1238
679674
if (s == 0 && yoffset != 0) s = yoffset > 0 ? 1 : -1;
680-
screen->pending_scroll_pixels = 0;
681675
}
682-
if (s == 0) return;
683676
bool upwards = s > 0;
677+
//printf("asdf %f\n", pixels);
684678
if (screen->linebuf == screen->main_linebuf) {
685679
screen_history_scroll(screen, abs(s), upwards);
680+
if (screen->scrolled_by == 0 && pixels < 0) pixels = 0;
681+
if (screen->scrolled_by == screen->historybuf->count && pixels > 0) pixels = 0;
682+
screen->pending_scroll_pixels = pixels;
683+
pixel_scroll(screen, (int)pixels);
686684
} else {
685+
pixels = 0.0;
686+
pixel_scroll(screen, (int)pixels);
687687
if (screen->modes.mouse_tracking_mode) {
688688
int sz = encode_mouse_event(w, upwards ? GLFW_MOUSE_BUTTON_4 : GLFW_MOUSE_BUTTON_5, PRESS, 0);
689689
if (sz > 0) {
@@ -696,6 +696,7 @@ scroll_event(double UNUSED xoffset, double yoffset, int flags) {
696696
fake_scroll(abs(s), upwards);
697697
}
698698
}
699+
screen->pending_scroll_pixels = pixels;
699700
}
700701

701702
static PyObject*

kitty/screen.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
9797
self->modes = empty_modes;
9898
self->is_dirty = true;
9999
self->scroll_changed = false;
100+
self->pixel_scroll_changed = false;
101+
self->render_not_only_pixel_scroll = false;
100102
self->margin_top = 0; self->margin_bottom = self->lines - 1;
101103
self->history_line_added_count = 0;
102104
RESET_CHARSETS;
@@ -657,6 +659,7 @@ screen_toggle_screen_buffer(Screen *self) {
657659
self->grman = self->main_grman;
658660
}
659661
screen_history_scroll(self, SCROLL_FULL, false);
662+
pixel_scroll(self, 0);
660663
self->is_dirty = true;
661664
self->selection = EMPTY_SELECTION;
662665
}
@@ -1199,6 +1202,7 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
11991202
self->scrolled_by = 0;
12001203
self->scroll_changed = true;
12011204
}
1205+
pixel_scroll(self, 0);
12021206
}
12031207
}
12041208

@@ -2205,6 +2209,12 @@ screen_selection_range_for_word(Screen *self, const index_type x, const index_ty
22052209
#undef is_ok
22062210
}
22072211

2212+
void pixel_scroll(Screen *self, int amt) {
2213+
//printf("pixel_scroll(%d)\n", amt);
2214+
self->scrolled_by_pixels = amt;
2215+
self->pixel_scroll_changed = true;
2216+
}
2217+
22082218
bool
22092219
screen_history_scroll(Screen *self, int amt, bool upwards) {
22102220
switch(amt) {
@@ -2239,6 +2249,7 @@ static PyObject*
22392249
scroll(Screen *self, PyObject *args) {
22402250
int amt, upwards;
22412251
if (!PyArg_ParseTuple(args, "ip", &amt, &upwards)) return NULL;
2252+
pixel_scroll(self, 0);
22422253
if (screen_history_scroll(self, amt, upwards)) { Py_RETURN_TRUE; }
22432254
Py_RETURN_FALSE;
22442255
}

kitty/screen.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ typedef struct {
7676
PyObject_HEAD
7777
7878
unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by;
79+
int scrolled_by_pixels;
7980
double pending_scroll_pixels;
8081
CellPixelSize cell_size;
8182
OverlayLine overlay_line;
@@ -87,7 +88,7 @@ typedef struct {
8788
IterationData selection, url;
8889
unsigned int cursor_x, cursor_y, scrolled_by;
8990
} last_rendered;
90-
bool use_latin1, is_dirty, scroll_changed, reload_all_gpu_data;
91+
bool use_latin1, is_dirty, scroll_changed, pixel_scroll_changed, reload_all_gpu_data, render_not_only_pixel_scroll;
9192
Cursor *cursor;
9293
SavepointBuffer main_savepoints, alt_savepoints;
9394
SavemodesBuffer modes_savepoints;
@@ -197,6 +198,7 @@ bool screen_selection_range_for_line(Screen *self, index_type y, index_type *sta
197198
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);
198199
void screen_start_selection(Screen *self, index_type x, index_type y, bool, bool, SelectionExtendMode);
199200
void screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_half, bool ended, bool start_extended_selection);
201+
void pixel_scroll(Screen *self, int amt);
200202
bool screen_history_scroll(Screen *self, int amt, bool upwards);
201203
Line* screen_visual_line(Screen *self, index_type y);
202204
unsigned long screen_current_char_width(Screen *self);

kitty/scroll_fragment.glsl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#version GLSL_VERSION
2+
out vec4 FragColor;
3+
4+
in vec2 TexCoords;
5+
6+
uniform sampler2D screenTexture;
7+
8+
void main()
9+
{
10+
FragColor = texture(screenTexture, TexCoords);
11+
}

0 commit comments

Comments
 (0)