Fix X event waiting to handle multiple frames.

* frame.h (struct frame) [HAVE_X_WINDOWS]: New member wait_event_type.
* xterm.c (pending_event_wait): Remove.  Adjust users.
(x_detect_focus_change): Pass frame arg.
(handle_one_xevent): Find related frame early and clear per-frame
wait_event_type only if this is an event for the relevant frame.
(x_wait_for_event): Use per-frame wait_event_type.
This commit is contained in:
Dmitry Antipov 2013-09-16 11:27:51 +04:00
parent 578c21bc03
commit f8eb15727a
3 changed files with 42 additions and 40 deletions

View file

@ -1,3 +1,13 @@
2013-09-16 Dmitry Antipov <dmantipov@yandex.ru>
Fix X event waiting to handle multiple frames.
* frame.h (struct frame) [HAVE_X_WINDOWS]: New member wait_event_type.
* xterm.c (pending_event_wait): Remove. Adjust users.
(x_detect_focus_change): Pass frame arg.
(handle_one_xevent): Find related frame early and clear per-frame
wait_event_type only if this is an event for the relevant frame.
(x_wait_for_event): Use per-frame wait_event_type.
2013-09-15 Jan Djärv <jan.h.d@swipnet.se>
* nsfns.m (Fx_create_frame): Fix font driver registration for

View file

@ -328,6 +328,11 @@ struct frame
unsigned int external_menu_bar : 1;
#endif
#if defined (HAVE_X_WINDOWS)
/* Used by x_wait_for_event when watching for an X event on this frame. */
int wait_event_type;
#endif
/* Next two bitfields are mutually exclusive. They might both be
zero if the frame has been made invisible without an icon. */

View file

@ -159,13 +159,6 @@ Lisp_Object x_display_name_list;
static struct frame *pending_autoraise_frame;
/* This is a frame waiting for an event matching mask, within XTread_socket. */
static struct {
struct frame *f;
int eventtype;
} pending_event_wait;
#ifdef USE_X_TOOLKIT
/* The application context for Xt use. */
XtAppContext Xt_app_con;
@ -293,8 +286,6 @@ static void frame_unhighlight (struct frame *);
static void x_new_focus_frame (struct x_display_info *, struct frame *);
static void x_focus_changed (int, int, struct x_display_info *,
struct frame *, struct input_event *);
static void x_detect_focus_change (struct x_display_info *,
XEvent *, struct input_event *);
static void XTframe_rehighlight (struct frame *);
static void x_frame_rehighlight (struct x_display_info *);
static void x_draw_hollow_cursor (struct window *, struct glyph_row *);
@ -3549,12 +3540,10 @@ x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
Returns FOCUS_IN_EVENT event in *BUFP. */
static void
x_detect_focus_change (struct x_display_info *dpyinfo, XEvent *event, struct input_event *bufp)
x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
XEvent *event, struct input_event *bufp)
{
struct frame *frame;
frame = x_any_window_to_frame (dpyinfo, event->xany.window);
if (! frame)
if (!frame)
return;
switch (event->type)
@ -5883,7 +5872,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
int count = 0;
int do_help = 0;
ptrdiff_t nbytes = 0;
struct frame *f = NULL;
struct frame *any, *f = NULL;
struct coding_system coding;
XEvent event = *eventptr;
Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
@ -5901,8 +5890,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
inev.ie.kind = NO_EVENT;
inev.ie.arg = Qnil;
if (pending_event_wait.eventtype == event.type)
pending_event_wait.eventtype = 0; /* Indicates we got it. */
any = x_any_window_to_frame (dpyinfo, event.xany.window);
if (any && any->wait_event_type == event.type)
any->wait_event_type = 0; /* Indicates we got it. */
switch (event.type)
{
@ -5915,10 +5906,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
if (event.xclient.data.l[0]
== dpyinfo->Xatom_wm_take_focus)
{
/* Use x_any_window_to_frame because this
could be the shell widget window
if the frame has no title bar. */
f = x_any_window_to_frame (dpyinfo, event.xclient.window);
/* Use the value returned by x_any_window_to_frame
because this could be the shell widget window
if the frame has no title bar. */
f = any;
#ifdef HAVE_X_I18N
/* Not quite sure this is needed -pd */
if (f && FRAME_XIC (f))
@ -5995,8 +5986,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
if (event.xclient.data.l[0]
== dpyinfo->Xatom_wm_delete_window)
{
f = x_any_window_to_frame (dpyinfo,
event.xclient.window);
f = any;
if (!f)
goto OTHER; /* May be a dialog that is to be removed */
@ -6035,7 +6025,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
if (event.xclient.message_type
== dpyinfo->Xatom_editres)
{
f = x_any_window_to_frame (dpyinfo, event.xclient.window);
f = any;
if (f)
_XEditResCheckMessages (f->output_data.x->widget, NULL,
&event, NULL);
@ -6079,7 +6069,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
{
enum xembed_message msg = event.xclient.data.l[1];
if (msg == XEMBED_FOCUS_IN || msg == XEMBED_FOCUS_OUT)
x_detect_focus_change (dpyinfo, &event, &inev.ie);
x_detect_focus_change (dpyinfo, any, &event, &inev.ie);
*finish = X_EVENT_GOTO_OUT;
goto done;
@ -6087,7 +6077,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
xft_settings_event (dpyinfo, &event);
f = x_any_window_to_frame (dpyinfo, event.xclient.window);
f = any;
if (!f)
goto OTHER;
if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie))
@ -6349,7 +6339,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
goto OTHER;
#endif
f = x_any_window_to_frame (dpyinfo, event.xkey.window);
f = any;
#if ! defined (USE_GTK)
/* If mouse-highlight is an integer, input clears out
@ -6683,9 +6673,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
case EnterNotify:
dpyinfo->last_user_time = event.xcrossing.time;
x_detect_focus_change (dpyinfo, &event, &inev.ie);
x_detect_focus_change (dpyinfo, any, &event, &inev.ie);
f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
f = any;
if (f && x_mouse_click_focus_ignore_position)
ignore_next_mouse_click_timeout = event.xmotion.time + 200;
@ -6703,12 +6693,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
goto OTHER;
case FocusIn:
x_detect_focus_change (dpyinfo, &event, &inev.ie);
x_detect_focus_change (dpyinfo, any, &event, &inev.ie);
goto OTHER;
case LeaveNotify:
dpyinfo->last_user_time = event.xcrossing.time;
x_detect_focus_change (dpyinfo, &event, &inev.ie);
x_detect_focus_change (dpyinfo, any, &event, &inev.ie);
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
if (f)
@ -6736,7 +6726,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
goto OTHER;
case FocusOut:
x_detect_focus_change (dpyinfo, &event, &inev.ie);
x_detect_focus_change (dpyinfo, any, &event, &inev.ie);
goto OTHER;
case MotionNotify:
@ -6822,7 +6812,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
f = x_top_window_to_frame (dpyinfo, event.xconfigure.window);
#ifdef USE_GTK
if (!f
&& (f = x_any_window_to_frame (dpyinfo, event.xconfigure.window))
&& (f = any)
&& event.xconfigure.window == FRAME_X_WINDOW (f))
{
xg_frame_resized (f, event.xconfigure.width,
@ -8733,15 +8723,14 @@ x_wait_for_event (struct frame *f, int eventtype)
struct timespec tmo, tmo_at, time_now;
int fd = ConnectionNumber (FRAME_X_DISPLAY (f));
pending_event_wait.f = f;
pending_event_wait.eventtype = eventtype;
f->wait_event_type = eventtype;
/* Set timeout to 0.1 second. Hopefully not noticeable.
Maybe it should be configurable. */
tmo = make_timespec (0, 100 * 1000 * 1000);
tmo_at = timespec_add (current_timespec (), tmo);
while (pending_event_wait.eventtype)
while (f->wait_event_type)
{
pending_signals = 1;
totally_unblock_input ();
@ -8760,8 +8749,8 @@ x_wait_for_event (struct frame *f, int eventtype)
if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
break; /* Timeout */
}
pending_event_wait.f = 0;
pending_event_wait.eventtype = 0;
f->wait_event_type = 0;
}
@ -10684,8 +10673,6 @@ x_initialize (void)
#endif
pending_autoraise_frame = 0;
pending_event_wait.f = 0;
pending_event_wait.eventtype = 0;
/* Note that there is no real way portable across R3/R4 to get the
original error handler. */