Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 63 additions & 30 deletions autoload/vimtex/view/_template.vim
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,20 @@ endfunction
function! s:viewer.xdo_get_id() dict abort " {{{1
if !self.xdo_check() | return 0 | endif

if self.xwin_id <= 0
" Allow some time for the viewer to start properly
sleep 500m
if self.xwin_id > 0 | return self.xwin_id | endif

let l:xwin_ids = vimtex#jobs#capture('xdotool search --class ' . self.name)
if len(l:xwin_ids) == 0
call vimtex#log#warning('Viewer cannot find ' . self.name . ' window ID!')
let self.xwin_id = 0
else
let self.xwin_id = l:xwin_ids[-1]
endif
" Allow some time for the viewer to start properly
sleep 500m

" Try finding viewer's window ID, first attempting search by PID, then by
" window name, and finally, as a fallback, by window class.
for l:method in ['pid', 'name', 'class']
execute "let self.xwin_id = self.xdo_find_win_id_by_" . l:method . "()"
if self.xwin_id > 0 | break | endif
endfor

if self.xwin_id <= 0
call vimtex#log#warning('Viewer cannot find ' . self.name . ' window ID!')
endif

return self.xwin_id
Expand All @@ -152,7 +155,7 @@ endfunction
function! s:viewer.xdo_exists() dict abort " {{{1
if !self.xdo_check() | return v:false | endif

" If xwin_id is already set, check if it still exists
" If xwin_id is already set, check if a matching viewer window still exists
if self.xwin_id > 0
let xwin_ids = vimtex#jobs#capture('xdotool search --class ' . self.name)
if index(xwin_ids, self.xwin_id) < 0
Expand All @@ -162,31 +165,61 @@ function! s:viewer.xdo_exists() dict abort " {{{1

" If xwin_id is unset, check if matching viewer windows exist
if self.xwin_id == 0
let l:pid = has_key(self, 'get_pid') ? self.get_pid() : 0
if l:pid > 0
let xwin_ids = vimtex#jobs#capture(
\ 'xdotool search --all --pid ' . l:pid
\ . ' --name ' . fnamemodify(self.out(), ':t'))
let self.xwin_id = get(xwin_ids, 0)
else
let xwin_ids = vimtex#jobs#capture(
\ 'xdotool search --name ' . fnamemodify(self.out(), ':t'))
let ids_already_used = filter(map(
\ deepcopy(vimtex#state#list_all()),
\ {_, x -> get(get(x, 'viewer', {}), 'xwin_id')}),
\ 'v:val > 0')
for id in xwin_ids
if index(ids_already_used, id) < 0
let self.xwin_id = id
break
endif
endfor

" First try searching for window ID by viewer PID...
let self.xwin_id = self.xdo_find_win_id_by_pid()

" ...then potentially search by the viewer's window name as a fallback.
if self.xwin_id > 0
let self.xwin_id = self.xdo_find_win_id_by_name()
endif
endif

return self.xwin_id > 0
endfunction

" }}}1
function! s:viewer.xdo_find_win_id_by_class() dict abort " {{{1
" Attempts to find the viewer's X window ID using `xdotool` search by window
" class. Returns the viewer's window ID if one is found, and `0` otherwise.
let l:xwin_ids = vimtex#jobs#capture('xdotool search --class ' . self.name)
return empty(l:xwin_ids) ? 0 : l:xwin_ids[-1]
endfunction

" }}}1
function! s:viewer.xdo_find_win_id_by_name() dict abort " {{{1
" Attempts to find the viewer's X window ID using `xdotool` search by window
" name (i.e. the string in the window titlebar). Returns the viewer's window
" ID if one is found, and `0` otherwise.
let l:xwin_ids = vimtex#jobs#capture(
\ 'xdotool search --name ' . fnamemodify(self.out(), ':t'))
let ids_already_used = filter(map(
\ deepcopy(vimtex#state#list_all()),
\ {_, x -> get(get(x, 'viewer', {}), 'xwin_id')}),
\ 'v:val > 0')
for id in l:xwin_ids
if index(ids_already_used, id) < 0
return id
endif
endfor
" If loop exits with no window ID found
return 0
endfunction

" }}}1
function! s:viewer.xdo_find_win_id_by_pid() dict abort " {{{1
" Attempts to find the viewer's X window ID using `xdotool` search by the
" viewer's process ID. Returns the viewer's window ID if one is found, and `0`
" otherwise.
let l:pid = has_key(self, 'get_pid') ? self.get_pid() : 0
if l:pid <= 0 | return 0 | endif

let xwin_ids = vimtex#jobs#capture(
\ 'xdotool search --all --pid ' . l:pid
\ . ' --name ' . fnamemodify(self.out(), ':t'))
return get(xwin_ids, 0)
endfunction

" }}}1
function! s:viewer.xdo_send_keys(keys) dict abort " {{{1
if !self.xdo_check() || empty(a:keys) || self.xwin_id <= 0 | return | endif
Expand Down