aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
authorJan Djärv <[email protected]>2002-06-28 19:42:48 +0000
committerJan Djärv <[email protected]>2002-06-28 19:42:48 +0000
commitcab34f502151e68c823be6242044d77c4f2e5f8b (patch)
tree3f36f2d9c0b50d42ebf1102026d9b2d49a92d9c0 /src/xterm.c
parente5cd5390a3133b14355949b5f154def83a078861 (diff)
(x_focus_changed): New function.
(x_detect_focus_change): New function. (XTread_socket): Call x_detect_focus_change for FocusIn/FocusOut EnterNotify and LeaveNotify to track X focus changes.
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c204
1 files changed, 156 insertions, 48 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 6f314ae9d5..b523cdd6ba 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -466,6 +466,16 @@ static void x_clear_cursor P_ ((struct window *));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
+static int x_focus_changed P_ ((int,
+ int,
+ struct x_display_info *,
+ struct frame *,
+ struct input_event *,
+ int));
+static int x_detect_focus_change P_ ((struct x_display_info *,
+ XEvent *,
+ struct input_event *,
+ int));
static void XTframe_rehighlight P_ ((struct frame *));
static void x_frame_rehighlight P_ ((struct x_display_info *));
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
@@ -6291,6 +6301,121 @@ x_new_focus_frame (dpyinfo, frame)
x_frame_rehighlight (dpyinfo);
}
+/* Handle FocusIn and FocusOut state changes for FRAME.
+ If FRAME has focus and there exists more than one frame, puts
+ an FOCUS_IN_EVENT into BUFP.
+ Returns number of events inserted into BUFP. */
+
+static int
+x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
+ int type;
+ int state;
+ struct x_display_info *dpyinfo;
+ struct frame *frame;
+ struct input_event *bufp;
+ int numchars;
+{
+ int nr_events = 0;
+
+ if (type == FocusIn)
+ {
+ if (dpyinfo->x_focus_event_frame != frame)
+ {
+ x_new_focus_frame (dpyinfo, frame);
+ dpyinfo->x_focus_event_frame = frame;
+
+ /* Don't stop displaying the initial startup message
+ for a switch-frame event we don't need. */
+ if (numchars > 0
+ && GC_NILP (Vterminal_frame)
+ && GC_CONSP (Vframe_list)
+ && !GC_NILP (XCDR (Vframe_list)))
+ {
+ bufp->kind = FOCUS_IN_EVENT;
+ XSETFRAME (bufp->frame_or_window, frame);
+ bufp->arg = Qnil;
+ ++bufp;
+ numchars--;
+ ++nr_events;
+ }
+ }
+
+ frame->output_data.x->focus_state |= state;
+
+#ifdef HAVE_X_I18N
+ if (FRAME_XIC (frame))
+ XSetICFocus (FRAME_XIC (frame));
+#endif
+ }
+ else if (type == FocusOut)
+ {
+ frame->output_data.x->focus_state &= ~state;
+
+ if (dpyinfo->x_focus_event_frame == frame)
+ {
+ dpyinfo->x_focus_event_frame = 0;
+ x_new_focus_frame (dpyinfo, 0);
+ }
+
+#ifdef HAVE_X_I18N
+ if (FRAME_XIC (frame))
+ XUnsetICFocus (FRAME_XIC (frame));
+#endif
+ }
+
+ return nr_events;
+}
+
+/* The focus may have changed. Figure out if it is a real focus change,
+ by checking both FocusIn/Out and Enter/LeaveNotify events.
+
+ Returns number of events inserted into BUFP. */
+
+static int
+x_detect_focus_change (dpyinfo, event, bufp, numchars)
+ struct x_display_info *dpyinfo;
+ XEvent *event;
+ struct input_event *bufp;
+ int numchars;
+{
+ struct frame *frame;
+ int nr_events = 0;
+
+ frame = x_top_window_to_frame (dpyinfo, event->xany.window);
+ if (! frame) return nr_events;
+
+ switch (event->type)
+ {
+ case EnterNotify:
+ case LeaveNotify:
+ if (event->xcrossing.detail != NotifyInferior
+ && event->xcrossing.focus
+ && ! (frame->output_data.x->focus_state & FOCUS_EXPLICIT))
+ nr_events = x_focus_changed ((event->type == EnterNotify
+ ? FocusIn : FocusOut),
+ FOCUS_IMPLICIT,
+ dpyinfo,
+ frame,
+ bufp,
+ numchars);
+ break;
+
+ case FocusIn:
+ case FocusOut:
+ nr_events = x_focus_changed (event->type,
+ (event->xfocus.detail == NotifyPointer
+ ? FOCUS_IMPLICIT : FOCUS_EXPLICIT),
+ dpyinfo,
+ frame,
+ bufp,
+ numchars);
+ break;
+ }
+
+ return nr_events;
+}
+
+
/* Handle an event saying the mouse has moved out of an Emacs frame. */
void
@@ -10751,15 +10876,16 @@ XTread_socket (sd, bufp, numchars, expected)
goto OTHER;
#endif
- /* Here's a possible interpretation of the whole
- FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
- you get a FocusIn event, you have to get a FocusOut
- event before you relinquish the focus. If you
- haven't received a FocusIn event, then a mere
- LeaveNotify is enough to free you. */
-
case EnterNotify:
{
+ int n;
+
+ n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+ if (n > 0)
+ {
+ bufp += n, count += n, numchars -= n;
+ }
+
f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
#if 0
@@ -10786,34 +10912,29 @@ XTread_socket (sd, bufp, numchars, expected)
}
case FocusIn:
- f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
- if (event.xfocus.detail != NotifyPointer)
- dpyinfo->x_focus_event_frame = f;
- if (f)
{
- x_new_focus_frame (dpyinfo, f);
+ int n;
- /* Don't stop displaying the initial startup message
- for a switch-frame event we don't need. */
- if (GC_NILP (Vterminal_frame)
- && GC_CONSP (Vframe_list)
- && !GC_NILP (XCDR (Vframe_list)))
+ n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+ if (n > 0)
{
- bufp->kind = FOCUS_IN_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- ++bufp, ++count, --numchars;
+ bufp += n, count += n, numchars -= n;
}
}
-#ifdef HAVE_X_I18N
- if (f && FRAME_XIC (f))
- XSetICFocus (FRAME_XIC (f));
-#endif
-
goto OTHER;
case LeaveNotify:
+ {
+ int n;
+
+ n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+ if (n > 0)
+ {
+ bufp += n, count += n, numchars -= n;
+ }
+ }
+
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
if (f)
{
@@ -10841,32 +10962,19 @@ XTread_socket (sd, bufp, numchars, expected)
bufp += n, count += n, numchars -= n;
}
-#if 0
- if (event.xcrossing.focus)
- x_mouse_leave (dpyinfo);
- else
- {
- if (f == dpyinfo->x_focus_event_frame)
- dpyinfo->x_focus_event_frame = 0;
- if (f == dpyinfo->x_focus_frame)
- x_new_focus_frame (dpyinfo, 0);
- }
-#endif
}
goto OTHER;
case FocusOut:
- f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
- if (event.xfocus.detail != NotifyPointer
- && f == dpyinfo->x_focus_event_frame)
- dpyinfo->x_focus_event_frame = 0;
- if (f && f == dpyinfo->x_focus_frame)
- x_new_focus_frame (dpyinfo, 0);
-
-#ifdef HAVE_X_I18N
- if (f && FRAME_XIC (f))
- XUnsetICFocus (FRAME_XIC (f));
-#endif
+ {
+ int n;
+
+ n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+ if (n > 0)
+ {
+ bufp += n, count += n, numchars -= n;
+ }
+ }
goto OTHER;