Commit graph

1547 commits

Author SHA1 Message Date
Alexsander Falcucci 09dd277429
fix: treat clipboard failure as a state, not as fatal (#3454)
previously we assumed that clipboard support was always there, so
unwrap() was inappropriate meaning that if the clipboard provider failed to
initialize, we panicked.

todo: in fact we should ERASE all unwrap() from the codebase if not tests.

so to model the thing we actually have:

  - a clipboard provider that *can* be available
  - or it can be unavailable, with a reason

x11 PRIMARY vs CLIPBOARD selections
see https://specifications.freedesktop.org/clipboard-spec/1.0

x11 display connection is explicit and may fail
see https://www.x.org/archive/X11R7.5/doc/man/man3/XOpenDisplay.3.html

wayland display is an explicit compositor connection and connect can fail
see https://wayland.freedesktop.org/docs/html/apb.html
2026-04-04 05:17:43 +02:00
Alexsander Falcucci 3b5062625a
fix: split startup preflight from runtime setup (#3453) 2026-04-04 01:02:31 +02:00
Alexsander Falcucci 0d7483c8f0
fix: apply neovide_scale_factor at startup and on updates correctly (#3451)
see: https://github.com/neovide/neovide/issues/3447

after the multi-window refactor, the renderer can be created before
neovim initial globals are ready.

the runtime path had a second bug:
scale factor updates through settings updates stored the new user scale
and then recomputed the grid scale with the old one. so scale changes were
always one step behind also reported at
https://github.com/neovide/neovide/issues/3447
2026-04-02 22:59:42 +02:00
Alexsander Falcucci 4ca822524e
fix: expand tilde in chdir on config (#3449)
the bug is that the common startup path that picks the child cwd was assuming
that every caller had already normalized the path.
2026-04-02 02:17:25 +02:00
Alexsander Falcucci 4a954a4958
fix: defer cold-start file drops until ui_attach completes (#3448)
the real problem is that neovim handle wasnt really ready yet. The queued file-open events
e.g from finder were being flushed as soon as the first handler registered,
but the handler registration happens before ui_attach and in embedded mode neovim
does not finish startup until the UI attaches.

we were replaying `:drop` into an instance that had not finished loading a bunch of
of things like filetype detection, syntax setup or user startup scripts.

see: https://github.com/neovide/neovide/issues/3444
2026-04-02 01:24:13 +02:00
Ryan Patterson 9d8e9317eb
fix: reintroduce error window for launch failures (#3445)
* reintroduce error window for launch failures

* fix: high cpu usage launch-error windows

just adding some control flow for the eventloop scheduler to avoid it
to wake up immediately when the only remaining window is an error
dialog, or if it is an error window in general.

---------

Co-authored-by: Alexsander Falcucci <alex.falcucci@gmail.com>
2026-04-01 19:48:47 +02:00
Alexsander Falcucci 32f223ae75
fix: update neovim listen_addr restart protocol and keep open args per route (#3441)
the old :restart progpath/argv payload is not the protocol anymore
see: https://github.com/neovim/neovim/pull/35223

the contract is now simpler:

  - the server starts the new neovim instance
  - the UI gets a restart event with the new listen address
  - the UI follows that address instead of rebuilding argv

impl the new protocol exposes the second bug. if a reused Neovide process
opens a new embedded window, that route has to start with the files it was
actually asked to open, otherwise :restart will attempt to restart the
process startup args from the first window, or an empty session.
2026-03-31 22:03:25 +02:00
Alexsander Falcucci 458bfd0578
docs: update nightly references to 0.16 (#3435) 2026-03-30 21:04:58 +02:00
Alexsander Falcucci e636e9091f
chore: prepare release 0.16.0 (#3434) 2026-03-30 19:39:35 +02:00
Alexsander Falcucci a76304c7ec
fix: render the correct message window geometry (#3430)
note: neovim reports message grids with the full default-grid height even when only
the bottom few rows are actually on screen.

f2d0b06ecb/src/nvim/message.c?plain=1#L205-L254

we were already compensating for that in one place when clamping the target
position, but then we turned around and used the full backing-grid size for
pixel_region()

that means the renderer still treated the message window as if
all rows were visible, which is wrong.

https://github.com/neovide/neovide/issues/3427
2026-03-30 14:06:06 +02:00
Alexsander Falcucci b943884298
fix: remove theme option from config file (#3433)
we mistakenly added a theme option to the config file, but it is not
actually used anywhere, must be impl in the future.

let g:neovide_theme has no changes.
2026-03-30 13:39:54 +02:00
Alexsander Falcucci 12c2a97a94
fix: rename macos-* to system-* for multi-window settings (#3432)
naming it for a target OS is not correct, lets keep it generic.
2026-03-30 01:42:39 +02:00
Alexsander Falcucci 20cf79ebb3
bump time = "0.3.47" (#3426) 2026-03-25 22:42:18 +01:00
Alexsander Falcucci 6cac6da20a
docs: --new-window handoff (#3425)
just a simple documentation atm.
2026-03-25 15:30:52 +01:00
Alexsander Falcucci a3fa12ee74
docs: --reuse-instance handoff (#3424)
just a simple documentation for now.
2026-03-25 15:28:08 +01:00
Alexsander Falcucci 75be80885e
handoff: return the listener version in responses (#3423)
when we are debugging the reuse-instance behavior, the version is
helpful to troubleshoot.
2026-03-25 13:33:37 +01:00
Alexsander Falcucci 5c4054db46
fix: split route cwd from caller cwd on handoffs (#3422)
the mistake here was treating --chdir and a relative file arg as if
they described the same directory.

they don't.

For a handoff like

  cd ~/neovide
  neovide --reuse-instance --new-window src/main.rs --chdir ~

the file comes from the caller shell cwd, so it should still mean ~/neovide/src/main.rs
but the new neovim route itself should start with cwd ~

now we take both meanings explicitly through the handoff path:
- cwd: the per-route startup cwd
- caller_cwd: the base directory for resolving relative file drops
2026-03-25 00:20:53 +01:00
Alexsander Falcucci dccbae41fc
feat: add --new-window cli option (#3420)
we simply create a new window and then activate the route that is now focused.
2026-03-24 00:33:33 +01:00
Alexsander Falcucci 1c562b8b86
utils: expand tilde before rebasing paths on cwd (#3419)
we were treating anything non-absolute as relative to the caller cwd 
so we ended up resolving wrong paths like /path/to/user/~/project 
instead of $HOME/project
2026-03-23 20:58:38 +01:00
Alexsander Falcucci 87430a11e7
intro: ignore padding changes to support banner on nightly release changes (#3418)
neovim changed the intro line at https://github.com/neovim/neovim/pull/38378

we improve how we compare and detect the final line to support both
stable|nightly versions.
2026-03-23 19:48:24 +01:00
Alexsander Falcucci 30b3737931
macos: improve handoff resolved cwd from chdir if needed (#3417)
this is actually an improvement to the --reuse-instance handoff case.

we should follow the cwd semantics of the request the user actually
dispatched, not whatever happened to be loaded.

we split the problem properly.

this helps us to keep the it simple and visible at the handoff level:
only the chdir option for this invocation gets to override the cwd sent
to the already-running instance.
2026-03-23 18:36:59 +01:00
Alexsander Falcucci e5ca795064
ipc: make handoff requests tolerant of protocol changes (#3416)
outdated neovide versions could be denied and become a blocker to the 
user.
2026-03-23 16:44:15 +01:00
Alexsander Falcucci 97f948041b
remove comment from rustfmt.toml (#3415) 2026-03-23 16:20:22 +01:00
Alexsander Falcucci bfc05c598b
macos: preserve caller cwd for --reuse-instance requests (#3414)
the handoff path was forwarding files, but not its context.
as current cwd for the request.

- absolute paths stay unchanged
- relative paths are joined against the caller cwd
- otherwise relative paths are preserved as-is

(also needed for the future smart routing matching path)
2026-03-23 15:33:42 +01:00
Alexsander Falcucci 3be76227df
macos: focus the reused window (#3413)
reusing an existing instance but leaving the app in the background is not
correct for a default workflow, so if --reuse-instance succeeds we activate
the target window.
2026-03-22 00:43:45 +01:00
Alexsander Falcucci a5e7870143
macos: add --reuse-instance through the handoff path (#3412)
this turns the handoff transport into an actual startup path instead of
just a socket we can reproduce calling the IPC by hand.

we now accept it from the cli. if there is no listener, startup should continue.
if the request is rejected or the transport fails, we return an explicit startup
outcome.

the other important fix here is tabs handling. The original file-drop
path always read `CmdLineSettings.tabs` from the running instance. That
would have made `neovide --reuse-instance --no-tabs file.txt` silently use
whatever tab setting the runtime uses, which is wrong.

An optional `tabs` override through the existing file-drop pipeline.
2026-03-22 00:33:39 +01:00
Alexsander Falcucci c31fae34a5
macos: forward handoff file-open requests (#3411)
here we add `files_to_open` to `HandoffRequest` and introduce `UserEvent::OpenFiles`
meaning that we can already use the IPC transport to receive file-open
requests from the listener and actually open them.

once the listener send that event to the main thread we handle it by marking
the focused route active when one exists, then forward each path through
`send_or_queue_file_drop()`

- IPC transport: receive and forward requests
- event loop: decide where the request lands
- file-drop: actually open the paths
2026-03-22 00:03:23 +01:00
Alexsander Falcucci 5986e4d00c
macos: add a bedside handoff IPC transport for instances (#3410)
here we add a small IPC layer to enable cross communication.

this is the very first bedside work forward to make reusable neovide instances 
possible. first on macOS only since it is my primary development platform,
but the design is not macOS-specific. we will acomplish some of the features
by having the new handoff listener to be cross-platform in the future.

the request currently have a BUILD_VERSION for identity/debugging,
but it's important to say that we *do not reject* on protocol version mismatch.
that kind of check sounds cleaner than it is. In a daily basis it can
lead into incompatible transports when an older Neovide process is still running.

^ this can be rethinked in the future. but there is no need for a real securit
boundary anyway right now. The real problem is silent schema drift, so the wire
structs use `deny_unknown_fields` and the transport stays small enough to reason
about directly.

route requests into a window or open files request are not implemented
yet, but the transport is ready to be used for that.

As I said, it's a bedside work.
2026-03-21 23:46:53 +01:00
Amanda Graven fd89a37167
Implement corner preference (#2825)
* Implement corner preference

* finish the corner preference support

---------

Co-authored-by: Alexsander Falcucci <alex.falcucci@gmail.com>
2026-03-19 18:03:27 +01:00
Alexsander Falcucci 1f8c082f39
hotreload: support idle config option (#3409)
simple support for the `idle` setting.
2026-03-18 23:11:44 +01:00
Alexsander Falcucci 05c4ef98ce
fix: regression doing extra render work when a frame is already late (#3408)
the multi-window refactor changed the render loop in two ways,
but they both push work into the path where we already know the
compositor is behind.

mainly Windows users were seeing a regression on nightly such as
typing latency, slow animations.

first, the schedule_render() stopped checking out on skipped_frame.

that means we can still request another redraw even after deciding that
the current frame was missed. That is backwards. A skipped frame is not
a signal to queue more work, it is a signal to get out of the way and
let the already scheduled render finish.

second, ResumeTimeReached started calling prepare_and_animate(),
even though about_to_wait() already does the exact same work. So the
loop grew a second preparation fraction for no real gain. that is just extra
churn and on throttled backends it makes missed-frame recovery noisier
than it needs to be.

here we now put the frame preparation back in one place, as before and avoids
re-arming redraws for frames that we already know they are late. we also match
the pre-refactor control flow that did not exhibit the Windows
typing-latency regression.
2026-03-18 11:12:51 +01:00
Alexsander Falcucci 26ea47b0f3
hotreload: treat window geometry as one setting (#3407)
size and grid are not independent runtime options. together with
`maximized` they define one mutually exclusive geometry choice,
so we don't model them as separate hot reload events.

todo: we need to improve how we declare mutually exclusive config
options in the config file.

if reload emitted a size/grid independently, then a transition like size -> grid
would depend on event order and could briefly drive invalid state.

in the end, we make geometry hot reload work, but we do it in a way that preserves the
actual model. One geometry setting, one parser, one reload event, one place to
apply it.
2026-03-17 21:27:30 +01:00
Alexsander Falcucci 55f3d65fd9
hotreload: add mouse-cursor-icon support (#3406)
simple hotreload for mouse-cursor-icon support
2026-03-16 23:47:43 +01:00
Alexsander Falcucci 272f398768
hotreload: support title-hidden and add a minimal split for renderer/window configs (#3405)
we had a single `HotReloadConfigs` and a dispatch path that made every config type
go through. That worked but the "hot reload" was just meant to "renderer properties"
at the moment. so we added a window-level option as well to act as a
bedside for the other properties like window.

Now the watcher emits categorized reload events, the renderer only accepts
renderer configs and the window wrapper owns window-level application of
window config.
2026-03-16 22:01:38 +01:00
Alexsander Falcucci 09ba278bcd
fix: don't clear hidden window titles (#3403)
First, we now set a sane default window title

we already handle title updates from nvim, but the default startup
behavior was still effectively "call everything Neovide" until
otherwise.

that's not very useful.

now, if the user hasn't configured either 'title' or 'titlestring', we enable
titles and use "%F" so the window follows the current path. *but we don't
override user configuration. if either option was already set, we leave it alone.

---

The second, "title-hidden" means "don't show the title", not "make the window
stop having one"

On macOS we got that wrong. when title hiding was enabled, we hid the
title visually and then also **cleared** the underlying NSWindow title by
setting it to an empty string.

That broke the native bookkeeping for secondary windows. The window itself
was created fine and the native tab showed up, but AppKit no longer had
a real title to use for the Window menu entry. So the second window
ended up effectively unnamed there.

we fix it by leaving the NSWindow title alone. keep the title hidden from
the titlebar, but preserve it for the platform APIs that actually need
it.
2026-03-15 21:06:07 +01:00
Alexsander Falcucci 1e06dcd06d
feat: add opt-in cell color fallback on cursor (#3402)
we already know the style of the cell under the cursor. Not using the cell color
fallback when `guicursor` leaves fg/bg unset, not falling back means the block
cursor ignores the actual colors being shown in that cell.

In fact instead, neovim ui protocol leave this responsability up the client to impl,
which is reasonable.

we also add `neovide_cursor_cell_color_fallback` as an opt-in. If enabled, the cursor falls
back to the covered cell colors, while explicit cursor colors still override them.

the trail vfx now keep a stable per-particle emission color. each particle captures the
cursor color when it is spawned, and rendering uses that stored color instead of
re-resolving from the current cursor position.
2026-03-14 00:38:17 +01:00
Alexsander Falcucci aa8f82e02c
bump winit 0.30.13 (#3401) 2026-03-13 18:16:28 +01:00
Alexsander Falcucci 2d37b79e3f
ci: retry hdiutil during dmg creation (#3400)
macOS runners occasionally fails due to resource busy while create-dmg
is building the image.

```
Creating disk image...
hdiutil: create failed - Resource busy
Error: Process completed with exit code 1.
```
2026-03-12 19:53:06 +01:00
Alexsander Falcucci a4fad9d89e
versioning: generate nightly versions from git describe (#3399)
we introduce NEOVIDE_BUILD_VERSION in build.rs from `git describe` so tagged builds keep the
package version and non-tagged builds report `nightly-<count>+g<sha>` with `-dirty`
preserved when applicable.

we kinda of follow the neovim pattern for nightly versions since the target users are used to it.

we also add cargo rerun tracking for git metadata and tracked files, and use the generated version
for the CLI `--version` output, startup version logging and `g:neovide_version`
consecutively.

note: bundles will not be affected since they have its own limited versioning scheme.
2026-03-12 17:44:31 +01:00
Alexsander Falcucci eaf32cf110
fix: preserve terminal launch context on --fork (#3398)
when a TTY launch respawns after --fork on macOS, the new process can look like
a desktop launch and route Neovim through /usr/bin/login. That breaks
terminal-originated launches.

the bug made neovide ignore the files and open an empty buffer, for example

NEOVIDE_FORK=1 cargo run -- ./Cargo.lock

or 

env -u TMUX tmux new 'cargo run -- ./Cargo.toml --fork; sleep 3'
2026-03-12 01:05:47 +01:00
Alexsander Falcucci 17df3e16c2
fix: --embed append only regression (#3397)
this fix a regression introduced at https://github.com/neovide/neovide/pull/3393

appending --embed to the end of the fully merged argv was the wrong fix.

It solved the ssh first-start, but it also turned

nvim --embed -p file1 file2

        into

nvim -p file1 file2 --embed

which breaks the normal tabbed startup path.
2026-03-11 18:30:32 +01:00
Alexsander Falcucci 7e6da1d5b2
nightly: don't rebuild the same artifacts every day (#3395)
the old workflow deleted and recreated the nightly release on every scheduled
run, even when the nightly tag already pointed to HEAD. that's just CI churn
and it republishes identical artifacts for no real reason.

we keep the daily schedule, but compare HEAD against the current nightly tag
first and skip the release jobs when they match.

manual dispatch gets a force flag for the rare case where rebuilding the same
commit is actually intended.
2026-03-10 22:08:27 +01:00
Alexsander Falcucci b66b8f7187
fmt: standardize rustfmt style_edition = 2024 (#3394) 2026-03-10 21:19:40 +01:00
Ashley Hauck 4b8d6f3423
move --embed to be last argument (#3393)
* move --embed to be last argument

* add helper fn to build neovim restart command parts

---------

Co-authored-by: Alexsander Falcucci <alex.falcucci@gmail.com>
2026-03-10 18:18:28 +01:00
Alexsander Falcucci bf6d3341c5
bump skia-safe to 0.93.1 (#3392) 2026-03-10 15:09:17 +01:00
Alexsander Falcucci d24d1c7632
fix: fill the trailing right-edge gap (#3387)
this is a very specific bug - if we can consider it as one.
when the content width is not an exact multiple of the grid cell width,
we can end up with a tiny strip to the right of the last column.

Fullscreen tends to hide it because the geometry lines up differently,
but in a normal window the seam is visible as soon as the trailing cell
background is not the default one.

Note: this is not really a grid sizing bug. The grid still has to snap to
whole cells. The actual problem is that we were leaving the fractional
remainder completely unpainted.

So we fix it in the renderer instead. Extend the trailing background
slightly into that remainder and cap the fill to a few cell widths so we
do not visibly stretch the last column if the grid briefly lags a
resize.
2026-03-09 19:50:38 +01:00
Alexsander Falcucci 6dca86689a
add sponsorship link in nightly releases (#3391) 2026-03-09 18:06:01 +01:00
Alexsander Falcucci 1f376b7a03
fix: queue file drops until handler exists on macOS (#3384)
The multi-window refactor made macOS openFiles depend on the active
handler. On a cold start there is no handler yet, so for example 
situation like the Finder 'Open With' drops the files and
neovide opens an empty window.

Now we bring back the old behavior by buffering file drops until the first
route handler registers, then flushing keeping warm starts going
straight to the active handler.
2026-03-05 10:53:16 +01:00
Alexsander Falcucci 9aeabd64f0
fix: carry font-changed across first draw (#3381)
the new multi-window refactor creates the window only after the first
draw batch, but that batch was handled in the route-core and the
font-changed flag got lost probably resolving a conflict.
That made the initial grid sizing skip the first resize,
leaving the UI at the default attach size.

we now track and pass through the font-changed flag from the route-core
into the route state so the first frame forces a grid sync just like
before.
2026-03-04 09:54:09 +01:00
Alexsander Falcucci b3a68695ea
docs: add nightly tag for multi-window (#3378) 2026-02-28 08:16:37 +01:00