Skip to content

Externalize handling of window layout and control (wincmds) to UIs #8707

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

Closed
wants to merge 12 commits into from

Conversation

coditva
Copy link
Contributor

@coditva coditva commented Jul 8, 2018

Nvim manages all the window layout by keeping a frame structure for it. UIs might want to take greater control over the layout and navigation which could not be provided in the current scenario.

This work delegates handling of these actions to external UIs (if they choose to by setting ext_windows) and gets rid of the frames internally. UIs have control over how to interpret wincmds which can be pretty useful to UI rich text editors like Oni.

This work build on top of previous work by @bfredl in #8221 and me in #8455. Ref #8320.

@bfredl
Copy link
Member

bfredl commented Aug 3, 2018

@utkarshme what is the status of this branch? Does all three modes (TUI/single-grid, ext_multigrid-but-not-ext_windows, ext_windows) work somewhat properly with this code? Does it contain all work relevant for the final GSOC submission ?

@bfredl bfredl added the gsoc community: Google Summer of Code project label Aug 3, 2018
@coditva
Copy link
Contributor Author

coditva commented Aug 5, 2018

This branch was kind of neglected because of getting #8455 to work. 😅 The ext-multigrid works but ext-windows is quite dicey. There is some little work to be done in window.c.

All in all, it contains all work done for GSoC so far and will be the branch that we will be submitting. ✌️

return 0;
}

if (!object_to_vim(result, &rettv, &error)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This convert is not needed, we can just check result.type == kObjectTypeInteger.

&error);

if (ERROR_SET(&error)) {
api_set_error(&error, kErrorTypeException, "%s", error.msg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this just self-assigns the error object, we want something like EMSG2(_("Error invoking win_move_cursor: %s"), error.msg);

@coditva
Copy link
Contributor Author

coditva commented Aug 16, 2018

At the end of the GSoC coding period, the state of this PR was this.

@megalithic

This comment has been minimized.

@coditva

This comment has been minimized.

@megalithic

This comment has been minimized.

@bfredl
Copy link
Member

bfredl commented Sep 16, 2018

@megalithic It will certainly be merged, but its hard to give a timetable. If this PR looks stale, it is because the focus is currently on #8455 which @utkarshme and I are working on to get it done for merging and which is the foundation this PR builds upon.

also, will this work with TUI nvim clients? e.g., not just onivim, but with neovim in terminal?

The more the TUI is just another GUI the better. There is no concrete plans for replacing the current TUI, but it would certainly be interesting project for someone to implement a new TUI based on the full external UI protocol.

@ghost
Copy link

ghost commented Dec 31, 2018

Now that #8221 and #8455 are merged, would it be possible to rebase this PR? I would like to begin playing around with this functionality. I tried merging myself but it was a bit beyond me.

No pressure, whenever is convenient. Thanks again for all the work on these awesome new features.

@bfredl
Copy link
Member

bfredl commented Dec 31, 2018

@Breja It is planned. BTW I just rebased #7466 on master, so it is possible to experiment with the combination multigrid+ext_messages in the meanwhile.

@ghost
Copy link

ghost commented Dec 31, 2018

@bfredl Sounds good!

I will check out latest ext_messages. Thanks!

@coditva
Copy link
Contributor Author

coditva commented Jan 1, 2019

@Breja You can experiment with this too now! 😄

@justinmk
Copy link
Member

Looks like some tests need to be adjusted/updated.

@hoschi
Copy link

hoschi commented Mar 27, 2020

I try to play around with this and got a bit confused about how the workflow should be between nvim and the UI. I'm pretty sure I miss something 😕

When I start up nvim, the first window created automatically has still the size of the main grid, like without ext_window set. There is also no win_resize event. I don't know if this is expected, because the docs say that when handling this event the GUI should use try_resize_grid to set the final size.
2020-03-27-163135_416x870_scrot

I started with implementing win_split to create a window in the UI and resize it if nvim fires win_resize or grid_resize. In the handler of win_resize I use ui_try_grid_resize to play back what I got from nvim at the moment. Is this correct? Now it gets even more confusing to me, because I expected to not get any size from nvim. I understood this PR to let the UI decide all the positioning and sizes. But in this example I get:

  • win_resize: width:116, height:1 116 is the whole width, idk why height is 1. UI calls ui_try_grid_resize with width:116, height:1
  • win_pos: width:116, height:62 so the height got magically increased. Should I just ignore win_pos?
  • grid_resize: with width:0, height:0 which gets ignored by me at the moment, I don't know what to do with this info
  • grid_resize: width:116, height:1 this is the answer of my ui_try_grid_resize, I guess

2020-03-27-164846_423x420_scrot

What I'm trying is to implement a layout with a global scrollbar and windows sized by their content: https://github.com/hoschi/yode have a look at the video or play with the demo :)
In short it would look like this:

  • give each created new empty split a default height and the width of the column
  • when there is content in a window, the height of the window is the content height

But I don't know where I should put this logic. Would this be autocmds to have access to the content? Splitting would work like this:

  • vsplit would create a new column and puts the window in there
  • split would create a window in the same column

But where is the positioning logic implemented? Is this done by the UI holding a representation of the current layout of the splits and never telling nvim something about it? The win_pos event confused me here. Also ui_try_grid_resize only sets size, not position, so I wouldn't even know how to tell nvim the position if I would need to do this.

Oooor did I get the intention of this PR completely wrong and it was never the idea to implement a layout where the splits can outgrow the main grid and a global scrollbar is needed?

I hope that probably @coditva can shed some light on my questions :)
The code is lying in this PR: hoschi/veonim#1

@bfredl
Copy link
Member

bfredl commented Mar 27, 2020

. Also ui_try_grid_resize only sets size, not position, so I wouldn't even know how to tell nvim the position if I would need to do this.

This function only sets the "inner" grid size, i e the number of text rows and colums that can be rendered inside the window. We would need a separate function for if nvim/plugins need to know the position and "outer" position (which depends on the font size of the window, and scrollbars and borders and such). Perhaps the ideas of #11943 could be extended also to windows when in ext_window mode.

@hoschi
Copy link

hoschi commented Mar 28, 2020

Do I get it right that it was not intended to let the UI control the position, size and layout of splits by this PR?
Can you explain or point me to the docs about that "inner vs outer" grid thing?

@bfredl
Copy link
Member

bfredl commented Mar 28, 2020

@hoschi The UI can control the size and position of splits, there is just no way (yet in this PR) for an UI to report the info back to neovim (for plugins who want to inspect the layout etc).

@hoschi
Copy link

hoschi commented Mar 28, 2020

@bfredl that "The UI can control the size and position of splits" is what I want to do 👍 I want to build a UI which controls the windows position/size which is not tied to the traditional frame structure fitting in a main grid size. 🙂

Do I need to report the position/size info back to neovim (which is not possible with this PR, yet) to achieve this goal? If no, meaning it should work with this PR, what did I do wrong in the workflow described above?

@glacambre
Copy link
Member

@hoschi Just wondering, have you considered using floating windows exclusively, one floating window per grid? Then you'd be free to position your windows as you wish.

@hoschi
Copy link

hoschi commented Mar 28, 2020

@glacambre thanks for the pointer! the last time I looked into the API for floating windows they were not suitable for my approach, because they had drawbacks (no number column, gutter for git info, ...) to be an alternative of normal windows. I had a very quick look again today and was also thinking if it would may sense to use only floating windows, but hadn't enough time to dive into this. Afaik, a floating window needs an anchor from a normal window, but this is not the case anymore? Because the windows I want to draw are not related to another window.

External GUIs could let floats hover outside of the main window like a tooltip, but this should not be used to specify arbitrary WM screen positions.

api: the second half of the sentence made my curious if this limitation would make problems for my use case.

I'll have a closer look tomorrow. Probably one main window plus all other windows are floats could be a way to implement the layout I want.

@bfredl
Copy link
Member

bfredl commented Mar 28, 2020

@hoschi I think ext_windows map much more closely to your use case, but floats of course have the benefit of already existing on master and releases.

(no number column, gutter for git info, ...)

Floats can actually have these, just don't set the "minimal" flag in nvim_win_open. The main thing floats lack is the statusline. Also ext_windows' will let the UI control wincmds directly, which floats do not.

@hoschi
Copy link

hoschi commented Mar 31, 2020

@bfredl I would also prefere ext_windows to be able to react on window comands. To use it, I still need your help to understand the workflow 😊

@glacambre glacambre mentioned this pull request Jun 3, 2020
@teto teto modified the milestones: 0.5, 0.5.1 Nov 1, 2020
@yatli
Copy link

yatli commented Dec 9, 2020

@coditva @bfredl I've rebased this branch to latest master, here: https://github.com/yatli/neovim/tree/ext-win
But I cannot send a PR to the source of this PR D:

@clason clason modified the milestones: 0.5.1, 0.6 Jul 6, 2021
@bfredl bfredl modified the milestones: 0.6, 0.7 Oct 30, 2021
@bfredl bfredl modified the milestones: 0.9, 0.10 Feb 2, 2023
@dundargoc dundargoc removed the WIP label Feb 7, 2023
@dundargoc dundargoc changed the title [WIP] Externalize handling of window layout and control (wincmds) to UIs Externalize handling of window layout and control (wincmds) to UIs Apr 2, 2023
@zeertzjq zeertzjq added the ui-extensibility UI extensibility, events, protocol, externalized UI label Jul 27, 2023
@theol0403

This comment was marked as off-topic.

@justinmk
Copy link
Member

justinmk commented Oct 9, 2023

Continued in #13504

@justinmk justinmk closed this Oct 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gsoc community: Google Summer of Code project ui-extensibility UI extensibility, events, protocol, externalized UI
Projects
None yet
Development

Successfully merging this pull request may close these issues.