@@ -207,11 +207,24 @@ local function create_popup_window_opts(opts, sizes_only)
207207 return popup_layout
208208end
209209
210+ local function create_backdrop_window_opts ()
211+ return {
212+ relative = " editor" ,
213+ width = vim .o .columns ,
214+ height = vim .o .lines ,
215+ row = 0 ,
216+ col = 0 ,
217+ style = " minimal" ,
218+ focusable = false ,
219+ zindex = 44 ,
220+ }
221+ end
222+
210223--- @param name string Human readable identifier.
211224--- @param filetype string
212225function M .new_view_only_win (name , filetype )
213226 local namespace = vim .api .nvim_create_namespace ((" installer_%s" ):format (name ))
214- local bufnr , renderer , mutate_state , get_state , unsubscribe , win_id , window_mgmt_augroup , autoclose_augroup , registered_keymaps , registered_keybinds , registered_effect_handlers , sticky_cursor
227+ local bufnr , backdrop_bufnr , renderer , mutate_state , get_state , unsubscribe , win_id , backdrop_win_id , window_mgmt_augroup , autoclose_augroup , registered_keymaps , registered_keybinds , registered_effect_handlers , sticky_cursor
215228 local has_initiated = false
216229 --- @type WindowOpts
217230 local window_opts = {}
@@ -228,7 +241,7 @@ function M.new_view_only_win(name, filetype)
228241 virtual_lines = false ,
229242 }, namespace )
230243
231- local function delete_win_buf ()
244+ local function close_window ()
232245 -- We queue the win_buf to be deleted in a schedule call, otherwise when used with folke/which-key (and
233246 -- set timeoutlen=0) we run into a weird segfault.
234247 -- It should probably be unnecessary once https://github.com/neovim/neovim/issues/15548 is resolved
@@ -237,10 +250,6 @@ function M.new_view_only_win(name, filetype)
237250 log .trace " Deleting window"
238251 vim .api .nvim_win_close (win_id , true )
239252 end
240- if bufnr and vim .api .nvim_buf_is_valid (bufnr ) then
241- log .trace " Deleting buffer"
242- vim .api .nvim_buf_delete (bufnr , { force = true })
243- end
244253 end )
245254 end
246255
@@ -373,6 +382,21 @@ function M.new_view_only_win(name, filetype)
373382 bufnr = vim .api .nvim_create_buf (false , true )
374383 win_id = vim .api .nvim_open_win (bufnr , true , create_popup_window_opts (window_opts , false ))
375384
385+ local normal_hl = vim .api .nvim_get_hl and vim .api .nvim_get_hl (0 , { name = " Normal" })
386+ local is_nvim_transparent = normal_hl and normal_hl .bg == nil
387+
388+ if settings .current .ui .backdrop ~= 100 and vim .o .termguicolors and not is_nvim_transparent then
389+ backdrop_bufnr = vim .api .nvim_create_buf (false , true )
390+ backdrop_win_id = vim .api .nvim_open_win (backdrop_bufnr , false , create_backdrop_window_opts ())
391+
392+ vim .wo [backdrop_win_id ].winhighlight = " Normal:MasonBackdrop"
393+ vim .wo [backdrop_win_id ].winblend = settings .current .ui .backdrop
394+ vim .bo [backdrop_bufnr ].buftype = " nofile"
395+ -- https://github.com/folke/lazy.nvim/issues/1399
396+ vim .bo [backdrop_bufnr ].filetype = " mason_backdrop"
397+ vim .bo [backdrop_bufnr ].bufhidden = " wipe"
398+ end
399+
376400 vim .api .nvim_create_autocmd (" CmdLineEnter" , {
377401 buffer = bufnr ,
378402 callback = function ()
@@ -440,27 +464,36 @@ function M.new_view_only_win(name, filetype)
440464 group = window_mgmt_augroup ,
441465 buffer = bufnr ,
442466 callback = function ()
443- if vim .api .nvim_win_is_valid (win_id ) then
467+ if win_id and vim .api .nvim_win_is_valid (win_id ) then
444468 draw (renderer (get_state ()))
445469 vim .api .nvim_win_set_config (win_id , create_popup_window_opts (window_opts , true ))
446470 end
471+ if backdrop_win_id and vim .api .nvim_win_is_valid (backdrop_win_id ) then
472+ vim .api .nvim_win_set_config (backdrop_win_id , create_backdrop_window_opts ())
473+ end
474+ end ,
475+ })
476+
477+ vim .api .nvim_create_autocmd ({ " WinClosed" }, {
478+ once = true ,
479+ pattern = tostring (win_id ),
480+ callback = function ()
481+ if backdrop_win_id and vim .api .nvim_win_is_valid (backdrop_win_id ) then
482+ vim .api .nvim_win_close (backdrop_win_id , true )
483+ end
447484 end ,
448485 })
449486
450487 vim .api .nvim_create_autocmd ({ " BufHidden" , " BufUnload" }, {
451488 group = autoclose_augroup ,
452489 buffer = bufnr ,
453- callback = function ()
454- -- Schedule is done because otherwise the window won't actually close in some cases (for example if
455- -- you're loading another buffer into it)
456- vim .schedule (function ()
457- if vim .api .nvim_win_is_valid (win_id ) then
458- vim .api .nvim_win_close (win_id , true )
459- end
460- end )
461- end ,
490+ -- This is for instances where the window remains but the buffer is no longer visible, for example when
491+ -- loading another buffer into it (this is basically imitating 'winfixbuf', which was added in 0.10.0).
492+ callback = close_window ,
462493 })
463494
495+ -- This autocmd is responsible for closing the Mason window(s) when the user focuses another window. It
496+ -- essentially behaves as WinLeave except it keeps the Mason window(s) open under certain circumstances.
464497 local win_enter_aucmd
465498 win_enter_aucmd = vim .api .nvim_create_autocmd ({ " WinEnter" }, {
466499 group = autoclose_augroup ,
@@ -469,7 +502,7 @@ function M.new_view_only_win(name, filetype)
469502 local buftype = vim .api .nvim_buf_get_option (0 , " buftype" )
470503 -- This allows us to keep the floating window open for things like diagnostic popups, UI inputs á la dressing.nvim, etc.
471504 if buftype ~= " prompt" and buftype ~= " nofile" then
472- delete_win_buf ()
505+ close_window ()
473506 vim .api .nvim_del_autocmd (win_enter_aucmd )
474507 end
475508 end ,
@@ -527,7 +560,7 @@ function M.new_view_only_win(name, filetype)
527560 assert (has_initiated , " Display has not been initiated, cannot close." )
528561 unsubscribe (true )
529562 log .fmt_trace (" Closing window win_id=%s, bufnr=%s" , win_id , bufnr )
530- delete_win_buf ()
563+ close_window ()
531564 vim .api .nvim_del_augroup_by_id (window_mgmt_augroup )
532565 vim .api .nvim_del_augroup_by_id (autoclose_augroup )
533566 end ),
0 commit comments