I invoked both goto declaration and goto definition in both .hpp and .cpp, always got .hpp in the list.
But you invoked it on the line where the symbol was defined already, so it swapped to the other search. If you invoked it on the _call_ of that function, it would behave the way you expected.
This behavior isn't anything new and dates back to https://github.com/geany/geany/commit/c61a189c00fca689f6f047c7d9c108a807aa14...
The current "source of the problem" looks this way:
https://github.com/geany/geany/blob/c46ffb0dcdf50760b362c076922bdc747be24937...
I kind of like how it behaves as when you already are on the definition, you don't really need to get to the definition again but rather to the declaration. And as @kugel-, I also use the Ctrl+click version of this feature.