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.
 <w32_system_caret_window, w32_system_caret_hdr_height>:
 <w32_system_caret_mode_height>: New variables.
 src/w32term.h: Declare them.
This commit is contained in:
Eli Zaretskii 2013-06-20 20:36:24 +03:00
parent 5013fc0876
commit b932cad712
4 changed files with 43 additions and 5 deletions

View file

@ -1,3 +1,16 @@
2013-06-20 Eli Zaretskii <eliz@gnu.org>
* 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.
<w32_system_caret_window, w32_system_caret_hdr_height>:
<w32_system_caret_mode_height>: New variables.
* w32term.h: Declare them.
2013-06-20 Paul Eggert <eggert@cs.ucla.edu>
* alloc.c (die): Move "assertion failed" string here ...

View file

@ -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);

View file

@ -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);

View file

@ -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