aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Colascione2018-06-11 14:58:09 -0700
committerDaniel Colascione2018-06-11 16:10:34 -0700
commit2f6c682061a281dc3e397ff4727a164880e86e7b (patch)
treef5990303d483f7d80e1aa1e80a19dc64a6325b66 /src
parenta20fe5a7e3577f9b9ad5e88006962966240d9b0c (diff)
downloademacs-2f6c682061a281dc3e397ff4727a164880e86e7b.tar.gz
emacs-2f6c682061a281dc3e397ff4727a164880e86e7b.zip
New focus management interface
focus-in-hook and focus-out-hook don't accurately reflect actual user-visible focus states. Add a new focus interface and mark the old one obsolete. * doc/lispref/frames.texi (Input Focus): Document new focus functions. Remove references to the now-obsolete focus hooks. * lisp/frame.el (frame-focus-state): New function. (after-focus-change-function): New variable. (focus-in-hook, focus-out-hook): Move to lisp from C; mark obsolete. * lisp/term/xterm.el (xterm-translate-focus-in) (xterm-translate-focus-out): Track tty focus in `tty-focus-state' terminal parameter; call `after-focus-change-function'. (xterm--suspend-tty-function): New function. * src/frame.c (Fhandle_switch_frame): Update docstring; don't call focus hooks. (focus-in-hook, focus-out-hook): Remove: moved to lisp. (syms_of_frame): Remove unread_switch_frame; add Vunread_switch_frame. * src/keyboard.c: (Finternal_handle_focus_in): New function. (make_lispy_event): Always report focus events to lisp; don't translate them to switch events sometimes. Lisp can take care of creating synthetic switch-frame events via `internal-handle-focus-in'. * src/w32term.c (x_focus_changed): Remove switch-avoidance logic: just directly report focus changes to lisp. * src/xterm.c (x_focus_changed): Remove switch-avoidance logic: just directly report focus changes to lisp.
Diffstat (limited to 'src')
-rw-r--r--src/frame.c25
-rw-r--r--src/keyboard.c65
-rw-r--r--src/w32term.c14
-rw-r--r--src/xterm.c10
4 files changed, 32 insertions, 82 deletions
diff --git a/src/frame.c b/src/frame.c
index da82621b8a0..bf0269292d6 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1455,23 +1455,15 @@ This function returns FRAME, or nil if FRAME has been deleted. */)
1455DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "^e", 1455DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "^e",
1456 doc: /* Handle a switch-frame event EVENT. 1456 doc: /* Handle a switch-frame event EVENT.
1457Switch-frame events are usually bound to this function. 1457Switch-frame events are usually bound to this function.
1458A switch-frame event tells Emacs that the window manager has requested 1458A switch-frame event is an event Emacs sends itself to
1459that the user's events be directed to the frame mentioned in the event. 1459indicate that input is arriving in a new frame. It does not
1460This function selects the selected window of the frame of EVENT. 1460necessarily represent user-visible input focus. */)
1461
1462If EVENT is frame object, handle it as if it were a switch-frame event
1463to that frame. */)
1464 (Lisp_Object event) 1461 (Lisp_Object event)
1465{ 1462{
1466 Lisp_Object value;
1467
1468 /* Preserve prefix arg that the command loop just cleared. */ 1463 /* Preserve prefix arg that the command loop just cleared. */
1469 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); 1464 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
1470 run_hook (Qmouse_leave_buffer_hook); 1465 run_hook (Qmouse_leave_buffer_hook);
1471 /* `switch-frame' implies a focus in. */ 1466 return do_switch_frame (event, 0, 0, Qnil);
1472 value = do_switch_frame (event, 0, 0, Qnil);
1473 call1 (intern ("handle-focus-in"), event);
1474 return value;
1475} 1467}
1476 1468
1477DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0, 1469DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
@@ -5888,15 +5880,6 @@ when the mouse is over clickable text. */);
5888The pointer becomes visible again when the mouse is moved. */); 5880The pointer becomes visible again when the mouse is moved. */);
5889 Vmake_pointer_invisible = Qt; 5881 Vmake_pointer_invisible = Qt;
5890 5882
5891 DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook,
5892 doc: /* Normal hook run when a frame gains input focus.
5893The frame gaining focus is selected at the time this hook is run. */);
5894 Vfocus_in_hook = Qnil;
5895
5896 DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook,
5897 doc: /* Normal hook run when all frames lost input focus. */);
5898 Vfocus_out_hook = Qnil;
5899
5900 DEFVAR_LISP ("move-frame-functions", Vmove_frame_functions, 5883 DEFVAR_LISP ("move-frame-functions", Vmove_frame_functions,
5901 doc: /* Functions run after a frame was moved. 5884 doc: /* Functions run after a frame was moved.
5902The functions are run with one arg, the frame that moved. */); 5885The functions are run with one arg, the frame that moved. */);
diff --git a/src/keyboard.c b/src/keyboard.c
index c9e069c8653..84acb247228 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5331,45 +5331,10 @@ make_lispy_event (struct input_event *event)
5331 } 5331 }
5332 5332
5333 case FOCUS_IN_EVENT: 5333 case FOCUS_IN_EVENT:
5334 { 5334 return make_lispy_focus_in (event->frame_or_window);
5335 /* Notification of a FocusIn event. The frame receiving the
5336 focus is in event->frame_or_window. Generate a
5337 switch-frame event if necessary. */
5338
5339 Lisp_Object frame = event->frame_or_window;
5340 Lisp_Object focus = FRAME_FOCUS_FRAME (XFRAME (frame));
5341 if (FRAMEP (focus))
5342 frame = focus;
5343 bool switching
5344 = (
5345#ifdef HAVE_X11
5346 ! NILP (event->arg)
5347 &&
5348#endif
5349 !EQ (frame, internal_last_event_frame)
5350 && !EQ (frame, selected_frame));
5351 internal_last_event_frame = frame;
5352
5353 return (switching ? make_lispy_switch_frame (frame)
5354 : make_lispy_focus_in (frame));
5355 }
5356 5335
5357 case FOCUS_OUT_EVENT: 5336 case FOCUS_OUT_EVENT:
5358 { 5337 return make_lispy_focus_out (event->frame_or_window);
5359#ifdef HAVE_WINDOW_SYSTEM
5360
5361 Display_Info *di;
5362 Lisp_Object frame = event->frame_or_window;
5363 bool focused = false;
5364
5365 for (di = x_display_list; di && ! focused; di = di->next)
5366 focused = di->x_highlight_frame != 0;
5367
5368 return focused ? Qnil
5369 : make_lispy_focus_out (frame);
5370
5371#endif /* HAVE_WINDOW_SYSTEM */
5372 }
5373 5338
5374 /* A simple keystroke. */ 5339 /* A simple keystroke. */
5375 case ASCII_KEYSTROKE_EVENT: 5340 case ASCII_KEYSTROKE_EVENT:
@@ -6637,6 +6602,31 @@ has the same base event type and all the specified modifiers. */)
6637 error ("Invalid base event"); 6602 error ("Invalid base event");
6638} 6603}
6639 6604
6605DEFUN ("internal-handle-focus-in", Finternal_handle_focus_in,
6606 Sinternal_handle_focus_in, 1, 1, 0,
6607 doc: /* Internally handle focus-in events, possibly generating
6608an artifical switch-frame event. */)
6609 (Lisp_Object event)
6610{
6611 Lisp_Object frame;
6612 if (!EQ (CAR_SAFE (event), Qfocus_in) ||
6613 !CONSP (XCDR (event)) ||
6614 !FRAMEP ((frame = XCAR (XCDR (event)))))
6615 error ("invalid focus-in event");
6616
6617 /* Conceptually, the concept of window manager focus on a particular
6618 frame and the Emacs selected frame shouldn't be related, but for a
6619 long time, we automatically switched the selected frame in response
6620 to focus events, so let's keep doing that. */
6621 bool switching = (!EQ (frame, internal_last_event_frame)
6622 && !EQ (frame, selected_frame));
6623 internal_last_event_frame = frame;
6624 if (switching || !NILP (unread_switch_frame))
6625 unread_switch_frame = make_lispy_switch_frame (frame);
6626
6627 return Qnil;
6628}
6629
6640/* Try to recognize SYMBOL as a modifier name. 6630/* Try to recognize SYMBOL as a modifier name.
6641 Return the modifier flag bit, or 0 if not recognized. */ 6631 Return the modifier flag bit, or 0 if not recognized. */
6642 6632
@@ -11277,6 +11267,7 @@ syms_of_keyboard (void)
11277 defsubr (&Scurrent_idle_time); 11267 defsubr (&Scurrent_idle_time);
11278 defsubr (&Sevent_symbol_parse_modifiers); 11268 defsubr (&Sevent_symbol_parse_modifiers);
11279 defsubr (&Sevent_convert_list); 11269 defsubr (&Sevent_convert_list);
11270 defsubr (&Sinternal_handle_focus_in);
11280 defsubr (&Sread_key_sequence); 11271 defsubr (&Sread_key_sequence);
11281 defsubr (&Sread_key_sequence_vector); 11272 defsubr (&Sread_key_sequence_vector);
11282 defsubr (&Srecursive_edit); 11273 defsubr (&Srecursive_edit);
diff --git a/src/w32term.c b/src/w32term.c
index 24950dd25ec..ff0d2bf5ddb 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2886,20 +2886,6 @@ x_focus_changed (int type, int state, struct w32_display_info *dpyinfo,
2886 { 2886 {
2887 x_new_focus_frame (dpyinfo, frame); 2887 x_new_focus_frame (dpyinfo, frame);
2888 dpyinfo->w32_focus_event_frame = frame; 2888 dpyinfo->w32_focus_event_frame = frame;
2889
2890 /* Don't stop displaying the initial startup message
2891 for a switch-frame event we don't need. */
2892 if (NILP (Vterminal_frame)
2893 && CONSP (Vframe_list)
2894 && !NILP (XCDR (Vframe_list)))
2895 {
2896 bufp->arg = Qt;
2897 }
2898 else
2899 {
2900 bufp->arg = Qnil;
2901 }
2902
2903 bufp->kind = FOCUS_IN_EVENT; 2889 bufp->kind = FOCUS_IN_EVENT;
2904 XSETFRAME (bufp->frame_or_window, frame); 2890 XSETFRAME (bufp->frame_or_window, frame);
2905 } 2891 }
diff --git a/src/xterm.c b/src/xterm.c
index eb299c36759..decaa33670b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -4387,16 +4387,6 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
4387 { 4387 {
4388 x_new_focus_frame (dpyinfo, frame); 4388 x_new_focus_frame (dpyinfo, frame);
4389 dpyinfo->x_focus_event_frame = frame; 4389 dpyinfo->x_focus_event_frame = frame;
4390
4391 /* Don't stop displaying the initial startup message
4392 for a switch-frame event we don't need. */
4393 /* When run as a daemon, Vterminal_frame is always NIL. */
4394 bufp->arg = (((NILP (Vterminal_frame)
4395 || ! FRAME_X_P (XFRAME (Vterminal_frame))
4396 || EQ (Fdaemonp (), Qt))
4397 && CONSP (Vframe_list)
4398 && !NILP (XCDR (Vframe_list)))
4399 ? Qt : Qnil);
4400 bufp->kind = FOCUS_IN_EVENT; 4390 bufp->kind = FOCUS_IN_EVENT;
4401 XSETFRAME (bufp->frame_or_window, frame); 4391 XSETFRAME (bufp->frame_or_window, frame);
4402 } 4392 }