I don't know an automated solution, but in the code below I define a macro \wdoublehat
with optional argument a math glue and \wdoublehat[1.5mu]{X}
appears to be somewhat satisfactory, as it would be for letter Z
as well, but for other letters you should adjust the 1.5mu
, and for Y
not use optional argument.
The screenshot shows that the root cause is the position of the letter inside its bounding box. The placement (and size) of the external \widehat
clearly depends on this bounding box (the first \widehat
seems to know more, perhaps some italic correction thing or other data associated to the glyph that it queries; but the external one appears to use only the bounding box of its (now not a letter) argument). The problem with X
is that relative to the mid point of the bounding box the (top) of the letter is far more to the right than is the case with Y
.
\documentclass{article}
\usepackage{amsmath}
%\usepackage{mathtools}
\begin{document}
\makeatletter
\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{{\fboxsep-\fboxrule\fbox{$\x$}} }
\makeatother
\makeatletter
\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{{\fboxsep-\fboxrule\fbox{$\widehat{\x}$}} }
\makeatother
\makeatletter
\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{$\widehat{\hbox{\fboxsep-\fboxrule\fbox{$\widehat{\x}$}}}$ }
\makeatother
\makeatletter
\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{$\widehat{\widehat{\x}}$ }
\makeatother
\newcommand\wdoublehat[2][0mu]{\mskip#1\widehat{\mskip-#1\widehat{#2}\mskip#1}\mskip-#1\relax}
\makeatletter
\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{$\wdoublehat[1.5mu]{\x}$ }
\makeatother
\end{document}
output (the next to last line show nested \widehat
, the last line shows using \wdoublehat
and 1.5mu
shift)

Again:
\documentclass{article}
\usepackage{amsmath}
\newcommand\wdoublehat[2][0mu]{\mskip#1\widehat{\mskip-#1\widehat{#2}\mskip#1}\mskip-#1\relax}
\begin{document}
\makeatletter
$\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{\widehat{\widehat{\x}}}$ (nested, no shift)
\makeatother
\makeatletter
$\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{\wdoublehat[1.5mu]{\x}}$ (1.5mu shift)
\makeatother
\makeatletter
$\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{\wdoublehat[2mu]{\x}}$ (2mu shift)
\makeatother
\makeatletter
$\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{\wdoublehat[2.5mu]{\x}}$ (2.5mu shift)
\makeatother
\makeatletter
$\@tfor\x:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\do{\wdoublehat[3mu]{\x}}$ (3mu shift)
\makeatother
\end{document}

(there is in this screenshot some ink above left of X on first line which is a Q descender from the full document from which I took screenshot: don't go get a scrub-sponge to clean your screen!)
It is possible to store in an array like structure the per-letter needed shifts and then the usage would be automatic. But this is better left to user to define in preamble once and for all such \doublehatX
etc... commands using suitably the \wdoublehat[<mu shift>]
from this answer.
amsmath
per se, it shows without it. It is coremath-mode
issue so probably tag should be edited.unicode-math
(and use lualatex/xelatex), it might be an option, since there it looks better.