diff options
| author | Jan Djärv | 2002-06-28 19:42:48 +0000 |
|---|---|---|
| committer | Jan Djärv | 2002-06-28 19:42:48 +0000 |
| commit | cab34f502151e68c823be6242044d77c4f2e5f8b (patch) | |
| tree | 3f36f2d9c0b50d42ebf1102026d9b2d49a92d9c0 /src | |
| parent | e5cd5390a3133b14355949b5f154def83a078861 (diff) | |
| download | emacs-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.c | 204 |
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 *)); | |||
| 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 *)); |
| @@ -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 | |||
| 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 | |||
| 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 |
| @@ -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 | ||