Mercurial > emacs
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 { |