From b932cad7124e7c1a20fc2b127201b7dee15a142f Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 20 Jun 2013 20:36:24 +0300 Subject: [PATCH] Yet another attempt at fixing bugs #14602, 14630, 14669. src/w32fns.c (w32_wnd_proc): Don't compute the header line and mode line dimensions here, to avoid race conditions with the main thread. src/w32term.c (w32_draw_window_cursor): Compute the header line and mode line dimensions here. : : New variables. src/w32term.h: Declare them. --- src/ChangeLog | 13 +++++++++++++ src/w32fns.c | 26 +++++++++++++++++++++----- src/w32term.c | 6 ++++++ src/w32term.h | 3 +++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 82856eb91a8..2aeccc222cf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2013-06-20 Eli Zaretskii + + * w32fns.c (w32_wnd_proc): Don't compute the header line and mode + line dimensions here, to avoid race conditions with the main + thread. (Bug#14062, bug#14630, bug#14669) + + * w32term.c (w32_draw_window_cursor): Compute the header line and + mode line dimensions here. + : + : New variables. + + * w32term.h: Declare them. + 2013-06-20 Paul Eggert * alloc.c (die): Move "assertion failed" string here ... diff --git a/src/w32fns.c b/src/w32fns.c index 970c44ce264..46fb02d96a1 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -3175,23 +3175,39 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) HIMC context; struct window *w; + /* Implementation note: The code below does something that + one shouldn't do: it accesses the window object from a + separate thread, while the main (a.k.a. "Lisp") thread + runs and can legitimately delete and even GC it. That is + why we are extra careful not to futz with a window that + is different from the one recorded when the system caret + coordinates were last modified. That is also why we are + careful not to move the IME window if the window + described by W was deleted, as indicated by its buffer + field being reset to nil. */ f = x_window_to_frame (dpyinfo, hwnd); w = XWINDOW (FRAME_SELECTED_WINDOW (f)); + /* Punt if someone changed the frame's selected window + behind our back. */ + if (w != w32_system_caret_window) + break; form.dwStyle = CFS_RECT; form.ptCurrentPos.x = w32_system_caret_x; form.ptCurrentPos.y = w32_system_caret_y; form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0); - form.rcArea.top = WINDOW_TOP_EDGE_Y (w); - if (BUFFERP (w->contents) - && FRAMEP (WINDOW_FRAME (w))) - form.rcArea.top += WINDOW_HEADER_LINE_HEIGHT (w); + form.rcArea.top = (WINDOW_TOP_EDGE_Y (w) + + w32_system_caret_hdr_height); form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w) - WINDOW_RIGHT_MARGIN_WIDTH (w) - WINDOW_RIGHT_FRINGE_WIDTH (w)); form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w) - - WINDOW_MODE_LINE_HEIGHT (w)); + - w32_system_caret_mode_height); + + /* Punt if the window was deleted behind our back. */ + if (!BUFFERP (w->contents)) + break; context = get_ime_context_fn (hwnd); diff --git a/src/w32term.c b/src/w32term.c index 617492e189f..d3174c65bf0 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -151,6 +151,9 @@ HWND w32_system_caret_hwnd; int w32_system_caret_height; int w32_system_caret_x; int w32_system_caret_y; +struct window *w32_system_caret_window; +int w32_system_caret_hdr_height; +int w32_system_caret_mode_height; DWORD dwWindowsThreadId = 0; HANDLE hWindowsThread = NULL; DWORD dwMainThreadId = 0; @@ -5328,6 +5331,9 @@ w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, w32_system_caret_y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y) + glyph_row->ascent - w->phys_cursor_ascent); + w32_system_caret_window = w; + w32_system_caret_hdr_height = WINDOW_HEADER_LINE_HEIGHT (w); + w32_system_caret_mode_height = WINDOW_MODE_LINE_HEIGHT (w); PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0); diff --git a/src/w32term.h b/src/w32term.h index be0b4a6f350..ace58758302 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -750,6 +750,9 @@ extern HWND w32_system_caret_hwnd; extern int w32_system_caret_height; extern int w32_system_caret_x; extern int w32_system_caret_y; +extern struct window *w32_system_caret_window; +extern int w32_system_caret_hdr_height; +extern int w32_system_caret_mode_height; #ifdef _MSC_VER #ifndef EnumSystemLocales -- 2.39.2