Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Implement smooth and precise scrolling #1454

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Luflosi
Copy link
Contributor

@Luflosi Luflosi commented Mar 10, 2019

I started to implement smooth and precise scrolling, see #1123. My plan is to render to some kind of buffer (I'm currently using a texture) and then copy the right part of that buffer to the normal framebuffer to allow pixel-precise scrolling. This is still very much a WIP, my code currently doesn't even do anything with scrolling. The code is also very hacky with some of it copied straight from learnopengl.com, that I don't even know exactly what it does. A lot of the new code for example in init_cell_program() should probably be somewhere else. I also hardcoded the size of the texture. This also literally the first time I've done anything with OpenGL, so this will be difficult for me and probably take a while to finish implementing.
My current problem is getting the information that tells the shader by how much to shift the content up and down from after_render() into the shader. I'm currently just using 0.1 as a constant. I think you're doing something like that in create_cell_vao() with the A1 define but I don't know how that works. Could you help me with that please?
Any other feedback is also welcome.

@kovidgoyal
Copy link
Owner

Dont worry about the awkwardness of your OpenGL code -- OpenGL is a pain to use. I will help you clean up your code after you have something working.

As for your question: If you want to convert a pixel scroll offset into an OpenGL offset, you basically divide the pixel scroll offset by the viewport height (os_window->viewport_height). Then divide that by 2 because the opengl co-ord system goes from -1 to 1 which means the full screen has length 2.

Some general comments. This will as far as I can see render blank at the bottom line when scrolling. If that is all you want to do, you could simply offset the rendering of the main shader and then draw a blank rectangle at the bottom. No need to use framebuffers at all.

@Luflosi
Copy link
Contributor Author

Luflosi commented Mar 11, 2019

I didn't ask about converting the offset from pixels to OpenGL but thank you anyways because I'll need that info later. But first I need to actually copy that offset from the C code to the shader and I don't know how to do that.

As for the blank sections, my first proof of concept will have those, yes. But it won't be the same as drawing a blank rectangle at the bottom or the top because the content will be shifted by a specific number of pixels. I also plan to render more than what is currently visible on screen and then keep what was rendered as a sort of cache. This will allow me to pre-render parts that are not yet visible. It should also save a little bit of GPU time and power because I don't have to render the whole screen on every frame. This will become more important than it currently is because kitty currently only needs to render one frame per line scrolled and the user doesn't scroll 60 lines per second (or whatever FPS their monitor has) most of the time while 60 pixels per second is going to be a lot more likely, at least with high resolution input devices.

@Luflosi
Copy link
Contributor Author

Luflosi commented Mar 11, 2019

you could simply offset the rendering of the main shader and then...

Oh, I missed that. But my other reason for doing it like this, still applies.

@kovidgoyal
Copy link
Owner

Use a uniform to pass values from C to the shader. See glUniform

@Luflosi
Copy link
Contributor Author

Luflosi commented Mar 11, 2019

Your tip was very helpful.
My first prototype is sort of working, here is a short video: https://youtu.be/6n31SO1HJAI.

@Luflosi
Copy link
Contributor Author

Luflosi commented Mar 11, 2019

@maximbaz

if you ever get to implementing improvements for scrolling, be sure to ping me for testing

Doing it now 😁🎉

@maximbaz
Copy link
Contributor

maximbaz commented Mar 12, 2019

Nice contribution, I've been following this PR 😝 The demo on the video is awesome!

I don't have high hopes as I assume it won't work on X (since it doesn't even have precise scrolling), but I just tried anyway — when kitty opens from your branch, all I see is black screen.

I'm launching via $ PATH= /usr/bin/python . /usr/bin/bash, to avoid #1406 and to make sure my zsh config is not causing any trouble, and here's what I see in the console:

❯ PATH= /usr/bin/python . /usr/bin/bash
[071 00:59:12.726902] Failed to run kitty for update check, with error: [Errno 13] Permission denied: 'kitty'
1899 2044
0.000000
0.000000
0.000000
0.000000
0.000000

Does it give you any clue?

In the meantime, I'll quickly install sway and try it out there 😉

UPDATE: having the same behavior on sway, and this command opens kitty fine on master branch.

@Luflosi
Copy link
Contributor Author

Luflosi commented Mar 12, 2019

Yeah, it won't work on X but no idea why there is a black screen. But I'd consider this code pre-alpha and to be honest I'm almost surprised it worked for me 😅.
#1406 should be fixed by #1408.

@Luflosi
Copy link
Contributor Author

Luflosi commented Mar 12, 2019

@maximbaz the black background was probably caused by the hardcoded size. It's still not very good, resizing the window or opening a tab so that the tab bar is shown doesn't adjust the size of the texture but that will have to wait a bit...

@maximbaz
Copy link
Contributor

At least the black background issue is fixed now, kitty launches fine on X11 😉 👍

I also wanted to try on sway, but for unknown to me reasons kitty doesn't work there, even on master branch, kitty's window opens but remains empty. If I provide KITTY_DISABLE_WAYLAND=1, then it launches fine (and is blurry, indication of it being running via XWayland). Might be something wrong with sway on my side, I don't usually use it.

Anyway, good job once again, I'll go back now to crying about the absence of smooth scrolling for X11 in glfw 😢

@Luflosi
Copy link
Contributor Author

Luflosi commented Mar 13, 2019

@kovidgoyal what do prepare_to_render_os_window() and render_os_window() do?

@kovidgoyal
Copy link
Owner

prepare_to_render() updates all the window global state and checks if the
window needs to be rendered (i.e. if anything has changed since the last
time it was rendered). render_os_window() actually renders the window by
calling various functions from shaders.c

@Luflosi Luflosi force-pushed the smooth_and_precise_scrolling branch from 294ba21 to 6427384 Compare April 8, 2020 20:02
@Luflosi
Copy link
Contributor Author

Luflosi commented Apr 9, 2020

Where is screen_resize() from kitty/screen.c called? If I search for it, that's the only occurrence in the entire source tree.

@maximbaz
Copy link
Contributor

maximbaz commented Apr 9, 2020

Just to give you some input, this is really nice work @Luflosi! I'm testing on sway, and although there are some grey artifacts, in general the code works, and smooth scrolling is very pleasant! 🙂

Do let me know when you want a more thorough testing / feedback!

record_1586431224

@Luflosi
Copy link
Contributor Author

Luflosi commented Apr 9, 2020

Thanks for the nice words @maximbaz. The grey artefacts are there because I didn't manage to make the rendered region bigger than the window yet. It needs to be at least one line taller to fill the grey regions. Basically everything else is still broken, like resizing, OS windows, tabs, kitty windows, background images, selections, ... This will need a lot more work and while I haven't done much for the past year, I now want to work on it again.

@kovidgoyal
Copy link
Owner

kovidgoyal commented Apr 9, 2020 via email

@jclsn
Copy link

jclsn commented May 2, 2022

Pity that this features seems to have been abandoned. It would be really nice for Vim.

@serhez
Copy link

serhez commented Aug 12, 2022

@jclsn I think this wouldn't work for vim as it takes over the terminal and performs its own scrolling simulation AFAIK, but I'm not 100% sure.

@jclsn
Copy link

jclsn commented Aug 13, 2022

@serhez Yeah, probably not

@Akari202
Copy link

@serhez there is vim-smoothie that adds smooth scrolling to navigation via ctrl-f and ctrl-d

@serhez
Copy link

serhez commented Aug 13, 2022

@serhez there is vim-smoothie that adds smooth scrolling to navigation via ctrl-f and ctrl-d

There are many such plugins but they do not implement pixel-wise scrolling, the do smooth scrolling in the sense that they use a non-constant (mostly non-linear too) function to calculate the delay between each line being scrolled, I think. But it's still line-wise scrolling.

@kovidgoyal kovidgoyal force-pushed the master branch 2 times, most recently from f5a18f5 to 2bb42e6 Compare August 19, 2022 08:22
@alba4k
Copy link

alba4k commented Sep 22, 2022

@Luflosi Is this 100% abbandoned? it would be one of the biggest features for quality of life, especially with trackpads

@NeilGirdhar
Copy link

@jclsn Per your comment: neovim/neovim#27583

@jclsn
Copy link

jclsn commented Feb 23, 2024

@NeilGirdhar I am one of these guys who refuses to use Neovim 😉

It's also been five years. I reckon @Luflosi has two kids and other priorities by now!

@simonlearnscoding
Copy link

looks like this won't be pursued any further? too bad, now that there is a smooth cursor animation, smooth scrolling is the only thing that separates neovide from kitty

@hernancerm
Copy link

+1. Buttery smooth scrolling like in Neovide would be a very significant quality of life improvement, as it makes navigation in Vim/Neovim much less disorienting. The cursor animation is cool, but I'd say less practical than smooth scrolling.

I don't even know if having a scroll as smooth as Neovide is possible in kitty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants