Additional experimenting on Windows shows that if there is not caret window, then ShowCaret, HideCaret, SetCaretPos and DestroyCaret fail with ERROR_ACCESS_DENIED. This is true even though the caret position is preserved and returned by GetCaretPos.
The current Wine implementation causes calls such as ShowCaret(0) to proceed as if a caret window would exist. This is an issue because the call leaks a timer when the hide count has its initial value 1 since SetSystemTimer( hwnd, TIMERID, Caret.timeout, CARET_Callback ); (user32/caret.c) does not use TIMERID if hwnd is null. This happens, for example, when a menu is closing (see MENU_ExitTracking() in user32/menu.c).
The patch makes the set_caret_info request fail (except for GetCaretPos) if there is no caret window so that the caret functions do not manipulate timers and properly return failure. This patch supersedes the patch with ID 178871.
Signed-off-by: Robert Schlicht patch@rschlicht.eu --- server/queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/server/queue.c b/server/queue.c index b5e17be18f..07f43d2c82 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3025,9 +3025,9 @@ DECL_HANDLER(set_caret_info) reply->old_hide = input->caret_hide; reply->old_state = input->caret_state;
- if (req->handle && get_user_full_handle(req->handle) != input->caret) + if (!input->caret || (req->handle && get_user_full_handle(req->handle) != input->caret)) { - set_error( STATUS_ACCESS_DENIED ); + if (req->flags) set_error( STATUS_ACCESS_DENIED ); return; } if (req->flags & SET_CARET_POS)