aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv2002-06-28 19:42:48 +0000
committerJan Djärv2002-06-28 19:42:48 +0000
commitcab34f502151e68c823be6242044d77c4f2e5f8b (patch)
tree3f36f2d9c0b50d42ebf1102026d9b2d49a92d9c0 /src
parente5cd5390a3133b14355949b5f154def83a078861 (diff)
downloademacs-cab34f502151e68c823be6242044d77c4f2e5f8b.tar.gz
emacs-cab34f502151e68c823be6242044d77c4f2e5f8b.zip
(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')
-rw-r--r--src/xterm.c204
1 files changed, 156 insertions, 48 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 6f314ae9d54..b523cdd6ba3 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -466,6 +466,16 @@ static void x_clear_cursor P_ ((struct window *));
466static void frame_highlight P_ ((struct frame *)); 466static void frame_highlight P_ ((struct frame *));
467static void frame_unhighlight P_ ((struct frame *)); 467static void frame_unhighlight P_ ((struct frame *));
468static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); 468static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
469static int x_focus_changed P_ ((int,
470 int,
471 struct x_display_info *,
472 struct frame *,
473 struct input_event *,
474 int));
475static int x_detect_focus_change P_ ((struct x_display_info *,
476 XEvent *,
477 struct input_event *,
478 int));
469static void XTframe_rehighlight P_ ((struct frame *)); 479static void XTframe_rehighlight P_ ((struct frame *));
470static void x_frame_rehighlight P_ ((struct x_display_info *)); 480static void x_frame_rehighlight P_ ((struct x_display_info *));
471static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); 481static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
@@ -6291,6 +6301,121 @@ x_new_focus_frame (dpyinfo, frame)
6291 x_frame_rehighlight (dpyinfo); 6301 x_frame_rehighlight (dpyinfo);
6292} 6302}
6293 6303
6304/* Handle FocusIn and FocusOut state changes for FRAME.
6305 If FRAME has focus and there exists more than one frame, puts
6306 an FOCUS_IN_EVENT into BUFP.
6307 Returns number of events inserted into BUFP. */
6308
6309static int
6310x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
6311 int type;
6312 int state;
6313 struct x_display_info *dpyinfo;
6314 struct frame *frame;
6315 struct input_event *bufp;
6316 int numchars;
6317{
6318 int nr_events = 0;
6319
6320 if (type == FocusIn)
6321 {
6322 if (dpyinfo->x_focus_event_frame != frame)
6323 {
6324 x_new_focus_frame (dpyinfo, frame);
6325 dpyinfo->x_focus_event_frame = frame;
6326
6327 /* Don't stop displaying the initial startup message
6328 for a switch-frame event we don't need. */
6329 if (numchars > 0
6330 && GC_NILP (Vterminal_frame)
6331 && GC_CONSP (Vframe_list)
6332 && !GC_NILP (XCDR (Vframe_list)))
6333 {
6334 bufp->kind = FOCUS_IN_EVENT;
6335 XSETFRAME (bufp->frame_or_window, frame);
6336 bufp->arg = Qnil;
6337 ++bufp;
6338 numchars--;
6339 ++nr_events;
6340 }
6341 }
6342
6343 frame->output_data.x->focus_state |= state;
6344
6345#ifdef HAVE_X_I18N
6346 if (FRAME_XIC (frame))
6347 XSetICFocus (FRAME_XIC (frame));
6348#endif
6349 }
6350 else if (type == FocusOut)
6351 {
6352 frame->output_data.x->focus_state &= ~state;
6353
6354 if (dpyinfo->x_focus_event_frame == frame)
6355 {
6356 dpyinfo->x_focus_event_frame = 0;
6357 x_new_focus_frame (dpyinfo, 0);
6358 }
6359
6360#ifdef HAVE_X_I18N
6361 if (FRAME_XIC (frame))
6362 XUnsetICFocus (FRAME_XIC (frame));
6363#endif
6364 }
6365
6366 return nr_events;
6367}
6368
6369/* The focus may have changed. Figure out if it is a real focus change,
6370 by checking both FocusIn/Out and Enter/LeaveNotify events.
6371
6372 Returns number of events inserted into BUFP. */
6373
6374static int
6375x_detect_focus_change (dpyinfo, event, bufp, numchars)
6376 struct x_display_info *dpyinfo;
6377 XEvent *event;
6378 struct input_event *bufp;
6379 int numchars;
6380{
6381 struct frame *frame;
6382 int nr_events = 0;
6383
6384 frame = x_top_window_to_frame (dpyinfo, event->xany.window);
6385 if (! frame) return nr_events;
6386
6387 switch (event->type)
6388 {
6389 case EnterNotify:
6390 case LeaveNotify:
6391 if (event->xcrossing.detail != NotifyInferior
6392 && event->xcrossing.focus
6393 && ! (frame->output_data.x->focus_state & FOCUS_EXPLICIT))
6394 nr_events = x_focus_changed ((event->type == EnterNotify
6395 ? FocusIn : FocusOut),
6396 FOCUS_IMPLICIT,
6397 dpyinfo,
6398 frame,
6399 bufp,
6400 numchars);
6401 break;
6402
6403 case FocusIn:
6404 case FocusOut:
6405 nr_events = x_focus_changed (event->type,
6406 (event->xfocus.detail == NotifyPointer
6407 ? FOCUS_IMPLICIT : FOCUS_EXPLICIT),
6408 dpyinfo,
6409 frame,
6410 bufp,
6411 numchars);
6412 break;
6413 }
6414
6415 return nr_events;
6416}
6417
6418
6294/* Handle an event saying the mouse has moved out of an Emacs frame. */ 6419/* Handle an event saying the mouse has moved out of an Emacs frame. */
6295 6420
6296void 6421void
@@ -10751,15 +10876,16 @@ XTread_socket (sd, bufp, numchars, expected)
10751 goto OTHER; 10876 goto OTHER;
10752#endif 10877#endif
10753 10878
10754 /* Here's a possible interpretation of the whole
10755 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
10756 you get a FocusIn event, you have to get a FocusOut
10757 event before you relinquish the focus. If you
10758 haven't received a FocusIn event, then a mere
10759 LeaveNotify is enough to free you. */
10760
10761 case EnterNotify: 10879 case EnterNotify:
10762 { 10880 {
10881 int n;
10882
10883 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
10884 if (n > 0)
10885 {
10886 bufp += n, count += n, numchars -= n;
10887 }
10888
10763 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); 10889 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
10764 10890
10765#if 0 10891#if 0
@@ -10786,34 +10912,29 @@ XTread_socket (sd, bufp, numchars, expected)
10786 } 10912 }
10787 10913
10788 case FocusIn: 10914 case FocusIn:
10789 f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
10790 if (event.xfocus.detail != NotifyPointer)
10791 dpyinfo->x_focus_event_frame = f;
10792 if (f)
10793 { 10915 {
10794 x_new_focus_frame (dpyinfo, f); 10916 int n;
10795 10917
10796 /* Don't stop displaying the initial startup message 10918 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
10797 for a switch-frame event we don't need. */ 10919 if (n > 0)
10798 if (GC_NILP (Vterminal_frame)
10799 && GC_CONSP (Vframe_list)
10800 && !GC_NILP (XCDR (Vframe_list)))
10801 { 10920 {
10802 bufp->kind = FOCUS_IN_EVENT; 10921 bufp += n, count += n, numchars -= n;
10803 XSETFRAME (bufp->frame_or_window, f);
10804 bufp->arg = Qnil;
10805 ++bufp, ++count, --numchars;
10806 } 10922 }
10807 } 10923 }
10808 10924
10809#ifdef HAVE_X_I18N
10810 if (f && FRAME_XIC (f))
10811 XSetICFocus (FRAME_XIC (f));
10812#endif
10813
10814 goto OTHER; 10925 goto OTHER;
10815 10926
10816 case LeaveNotify: 10927 case LeaveNotify:
10928 {
10929 int n;
10930
10931 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
10932 if (n > 0)
10933 {
10934 bufp += n, count += n, numchars -= n;
10935 }
10936 }
10937
10817 f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); 10938 f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
10818 if (f) 10939 if (f)
10819 { 10940 {
@@ -10841,32 +10962,19 @@ XTread_socket (sd, bufp, numchars, expected)
10841 bufp += n, count += n, numchars -= n; 10962 bufp += n, count += n, numchars -= n;
10842 } 10963 }
10843 10964
10844#if 0
10845 if (event.xcrossing.focus)
10846 x_mouse_leave (dpyinfo);
10847 else
10848 {
10849 if (f == dpyinfo->x_focus_event_frame)
10850 dpyinfo->x_focus_event_frame = 0;
10851 if (f == dpyinfo->x_focus_frame)
10852 x_new_focus_frame (dpyinfo, 0);
10853 }
10854#endif
10855 } 10965 }
10856 goto OTHER; 10966 goto OTHER;
10857 10967
10858 case FocusOut: 10968 case FocusOut:
10859 f = x_any_window_to_frame (dpyinfo, event.xfocus.window); 10969 {
10860 if (event.xfocus.detail != NotifyPointer 10970 int n;
10861 && f == dpyinfo->x_focus_event_frame) 10971
10862 dpyinfo->x_focus_event_frame = 0; 10972 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
10863 if (f && f == dpyinfo->x_focus_frame) 10973 if (n > 0)
10864 x_new_focus_frame (dpyinfo, 0); 10974 {
10865 10975 bufp += n, count += n, numchars -= n;
10866#ifdef HAVE_X_I18N 10976 }
10867 if (f && FRAME_XIC (f)) 10977 }
10868 XUnsetICFocus (FRAME_XIC (f));
10869#endif
10870 10978
10871 goto OTHER; 10979 goto OTHER;
10872 10980