comparison src/xterm.c @ 46076:819af351608b

(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.
author Jan Djärv <jan.h.d@swipnet.se>
date Fri, 28 Jun 2002 19:42:48 +0000
parents 8554a859e957
children b0eec47a28f2
comparison
equal deleted inserted replaced
46075:39e3c9d9b655 46076:819af351608b
464 static void x_clear_frame P_ ((void)); 464 static void x_clear_frame P_ ((void));
465 static void x_clear_cursor P_ ((struct window *)); 465 static void x_clear_cursor P_ ((struct window *));
466 static void frame_highlight P_ ((struct frame *)); 466 static void frame_highlight P_ ((struct frame *));
467 static void frame_unhighlight P_ ((struct frame *)); 467 static void frame_unhighlight P_ ((struct frame *));
468 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); 468 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
469 static int x_focus_changed P_ ((int,
470 int,
471 struct x_display_info *,
472 struct frame *,
473 struct input_event *,
474 int));
475 static int x_detect_focus_change P_ ((struct x_display_info *,
476 XEvent *,
477 struct input_event *,
478 int));
469 static void XTframe_rehighlight P_ ((struct frame *)); 479 static void XTframe_rehighlight P_ ((struct frame *));
470 static void x_frame_rehighlight P_ ((struct x_display_info *)); 480 static void x_frame_rehighlight P_ ((struct x_display_info *));
471 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); 481 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
472 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, 482 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
473 enum text_cursor_kinds)); 483 enum text_cursor_kinds));
6288 pending_autoraise_frame = 0; 6298 pending_autoraise_frame = 0;
6289 } 6299 }
6290 6300
6291 x_frame_rehighlight (dpyinfo); 6301 x_frame_rehighlight (dpyinfo);
6292 } 6302 }
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
6309 static int
6310 x_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
6374 static int
6375 x_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
6293 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
6296 void 6421 void
6297 x_mouse_leave (dpyinfo) 6422 x_mouse_leave (dpyinfo)
10749 break; 10874 break;
10750 #else 10875 #else
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
10766 if (event.xcrossing.focus) 10892 if (event.xcrossing.focus)
10767 { 10893 {
10784 note_mouse_movement (f, &event.xmotion); 10910 note_mouse_movement (f, &event.xmotion);
10785 goto OTHER; 10911 goto OTHER;
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 {
10820 if (f == dpyinfo->mouse_face_mouse_frame) 10941 if (f == dpyinfo->mouse_face_mouse_frame)
10821 { 10942 {
10839 n = gen_help_event (bufp, numchars, 10960 n = gen_help_event (bufp, numchars,
10840 Qnil, frame, Qnil, Qnil, 0); 10961 Qnil, frame, Qnil, Qnil, 0);
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
10873 case MotionNotify: 10981 case MotionNotify:
10874 { 10982 {