#include "events-mod.h"
+void enqueue_focus_event (Widget wants_it, Lisp_Object frame, int in_p);
static void handle_focus_event_1 (struct frame *f, int in_p);
+static void handle_focus_event_2 (Window w, struct frame *f, int in_p);
static struct event_stream *Xt_event_stream;
int x_allow_sendevents;
#ifdef DEBUG_XEMACS
-int debug_x_events;
+Fixnum debug_x_events;
#endif
static int process_events_occurred;
{
extern Lisp_Object Vcurrent_global_map;
extern Lisp_Object Qascii_character;
- Fput (symbol, Qascii_character, character);
- if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil)))
- Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command);
+ if (NILP (Flookup_key (Vcurrent_global_map, symbol, Qnil)))
+ {
+ Fput (symbol, Qascii_character, character);
+ Fdefine_key (Vcurrent_global_map, symbol, Qself_insert_command);
+ }
}
}
static void
handle_focus_event_1 (struct frame *f, int in_p)
{
+ handle_focus_event_2 (XtWindow (FRAME_X_TEXT_WIDGET (f)), f, in_p);
+}
+
+static void
+handle_focus_event_2 (Window win, struct frame *f, int in_p)
+{
+ /* Although this treats focus differently for all widgets (including
+ the frame) it seems to work ok. */
+ Widget needs_it = XtWindowToWidget (FRAME_X_DISPLAY (f), win);
+
#if XtSpecificationRelease > 5
widget_with_focus = XtGetKeyboardFocusWidget (FRAME_X_TEXT_WIDGET (f));
#endif
click in the frame. Why is this? */
if (in_p
#if XtSpecificationRelease > 5
- && FRAME_X_TEXT_WIDGET (f) != widget_with_focus
+ && needs_it != widget_with_focus
#endif
)
{
- lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f),
- FRAME_X_TEXT_WIDGET (f));
+ lw_set_keyboard_focus (FRAME_X_SHELL_WIDGET (f), needs_it);
}
+ /* If we are focusing on a native widget then record and exit. */
+ if (needs_it != FRAME_X_TEXT_WIDGET (f)) {
+ widget_with_focus = needs_it;
+ return;
+ }
+
/* We have the focus now. See comment in
emacs_Xt_handle_widget_losing_focus (). */
if (in_p)
}
}
+/* Create a synthetic X focus event. */
+void
+enqueue_focus_event (Widget wants_it, Lisp_Object frame, int in_p)
+{
+ Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
+ Lisp_Event *ev = XEVENT (emacs_event);
+ XEvent *x_event = &ev->event.magic.underlying_x_event;
+
+ x_event->type = in_p ? FocusIn : FocusOut;
+ x_event->xfocus.window = XtWindow (wants_it);
+
+ ev->channel = frame;
+ ev->event_type = magic_event;
+
+ enqueue_Xt_dispatch_event (emacs_event);
+}
+
/* The idea here is that when a widget glyph gets unmapped we don't
want the focus to stay with it if it has focus - because it may
- well just get deleted next andthen we have lost the focus until the
+ well just get deleted next and then we have lost the focus until the
user does something. So handle_focus_event_1 records the widget
with keyboard focus when FocusOut is processed, and then, when a
widget gets unmapped, it calls this function to restore focus if
if (FRAME_X_EXTERNAL_WINDOW_P (f))
break;
#endif
- handle_focus_event_1 (f, event->type == FocusIn);
+ handle_focus_event_2 (event->xfocus.window, f, event->type == FocusIn);
break;
case ClientMessage:
static void
drain_X_queue (void)
{
+ Lisp_Object devcons, concons;
+ CONSOLE_LOOP (concons)
+ {
+ struct console *con = XCONSOLE (XCAR (concons));
+ if (!con->input_enabled)
+ continue;
+
+ /* sjt sez: Have you tried the loop over devices with XtAppPending(),
+ not XEventsQueued()?
+ Ben Sigelman sez: No.
+ sjt sez: I'm guessing that the reason that your patch "works" is this:
+
+ + struct device* d;
+ + Display* display;
+ + d = XDEVICE (XCAR (devcons));
+ + if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d)) {
+
+ Ie, if the device goes down, XEmacs detects that and deletes it.
+ Then the if() fails (DEVICE_X_DISPLAY(d) is NULL), and we don't go
+ into the Xlib-of-no-return. If you know different, I'd like to hear
+ about it. ;-)
+
+ These ideas haven't been tested; the code below works for Ben.
+ */
+ CONSOLE_DEVICE_LOOP (devcons, con)
+ {
+ struct device* d;
+ Display* display;
+ d = XDEVICE (XCAR (devcons));
+ if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d)) {
+ display = DEVICE_X_DISPLAY (d);
+ while (XEventsQueued (display, QueuedAfterReading))
+ XtAppProcessEvent (Xt_app_con, XtIMXEvent);
+ }
+ }
+ }
+ /* This is the old code, before Ben Sigelman's patch. */
+ /*
while (XtAppPending (Xt_app_con) & XtIMXEvent)
XtAppProcessEvent (Xt_app_con, XtIMXEvent);
+ */
}
static int