diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 25 | ||||
-rw-r--r-- | src/frame.c | 23 | ||||
-rw-r--r-- | src/keyboard.c | 68 | ||||
-rw-r--r-- | src/nsterm.m | 7 | ||||
-rw-r--r-- | src/termhooks.h | 2 | ||||
-rw-r--r-- | src/xterm.c | 13 |
6 files changed, 123 insertions, 15 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4d819413b42..7c3548c4f84 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,28 @@ +2013-07-16 Jan Djärv <jan.h.d@swipnet.se> + + * xterm.c (x_focus_changed): Always generate FOCUS_IN_EVENT. + Set event->arg to Qt if switch-event shall be generated. + Generate FOCUS_OUT_EVENT for FocusOut if this is the focused frame. + + * termhooks.h (enum event_kind): Add FOCUS_OUT_EVENT. + + * nsterm.m (windowDidResignKey): If this is the focused frame, generate + FOCUS_OUT_EVENT. + + * keyboard.c (Qfocus_in, Qfocus_out): New static objects. + (make_lispy_focus_in, make_lispy_focus_out): Declare and define. + (kbd_buffer_get_event): For FOCUS_IN, make a focus_in event if no + switch frame event is made. Check ! NILP (event->arg) if X11 (moved + from xterm.c). Make focus_out event for FOCUS_OUT_EVENT if NS or X11 + and there is a focused frame. + (head_table): Add focus-in and focus-out. + (keys_of_keyboard): Add focus-in and focus-out to Vspecial_event_map, + bind to handle-focus-in/out. + + * frame.c (Fhandle_focus_in, Fhandle_focus_out): New functions. + (Fhandle_switch_frame): Call Fhandle_focus_in. + (syms_of_frame): defsubr handle-focus-in/out. + 2013-07-16 Paul Eggert <eggert@cs.ucla.edu> Fix porting bug to older POSIXish platforms (Bug#14862). diff --git a/src/frame.c b/src/frame.c index f2cbfaa321f..5bd9f777755 100644 --- a/src/frame.c +++ b/src/frame.c @@ -887,6 +887,26 @@ This function returns FRAME, or nil if FRAME has been deleted. */) return do_switch_frame (frame, 1, 0, norecord); } +DEFUN ("handle-focus-in", Fhandle_focus_in, Shandle_focus_in, 1, 1, "e", + doc: /* Handle a focus-in event. +Focus in events are usually bound to this function. +Focus in events occur when a frame has focus, but a switch-frame event +is not generated. +This function checks if blink-cursor timers should be turned on again. */) + (Lisp_Object event) +{ + call0 (intern ("blink-cursor-check")); +} + +DEFUN ("handle-focus-out", Fhandle_focus_out, Shandle_focus_out, 1, 1, "e", + doc: /* Handle a focus-out event. +Focus out events are usually bound to this function. +Focus out events occur when no frame has focus. +This function checks if blink-cursor timers should be turned off. */) + (Lisp_Object event) +{ + call0 (intern ("blink-cursor-suspend")); +} DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e", doc: /* Handle a switch-frame event EVENT. @@ -902,6 +922,7 @@ to that frame. */) /* Preserve prefix arg that the command loop just cleared. */ kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); Frun_hooks (1, &Qmouse_leave_buffer_hook); + Fhandle_focus_in (event); // switch-frame implies a focus in. return do_switch_frame (event, 0, 0, Qnil); } @@ -4449,6 +4470,8 @@ automatically. See also `mouse-autoselect-window'. */); defsubr (&Swindow_system); defsubr (&Smake_terminal_frame); defsubr (&Shandle_switch_frame); + defsubr (&Shandle_focus_in); + defsubr (&Shandle_focus_out); defsubr (&Sselect_frame); defsubr (&Sselected_frame); defsubr (&Sframe_list); diff --git a/src/keyboard.c b/src/keyboard.c index f6bc7f308e6..5cdb87818ca 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -295,6 +295,7 @@ static struct input_event * volatile kbd_store_ptr; static Lisp_Object Qmouse_movement; static Lisp_Object Qscroll_bar_movement; Lisp_Object Qswitch_frame; +static Lisp_Object Qfocus_in, Qfocus_out; static Lisp_Object Qdelete_frame; static Lisp_Object Qiconify_frame; static Lisp_Object Qmake_frame_visible; @@ -420,6 +421,8 @@ static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object, Lisp_Object, const char *const *, Lisp_Object *, ptrdiff_t); static Lisp_Object make_lispy_switch_frame (Lisp_Object); +static Lisp_Object make_lispy_focus_in (Lisp_Object); +static Lisp_Object make_lispy_focus_out (Lisp_Object); static bool help_char_p (Lisp_Object); static void save_getcjmp (sys_jmp_buf); static void restore_getcjmp (sys_jmp_buf); @@ -4061,17 +4064,45 @@ kbd_buffer_get_event (KBOARD **kbp, switch-frame event if necessary. */ Lisp_Object frame, focus; - frame = event->frame_or_window; - focus = FRAME_FOCUS_FRAME (XFRAME (frame)); - if (FRAMEP (focus)) - frame = focus; + frame = event->frame_or_window; + focus = FRAME_FOCUS_FRAME (XFRAME (frame)); + if (FRAMEP (focus)) + frame = focus; - if (!EQ (frame, internal_last_event_frame) - && !EQ (frame, selected_frame)) - obj = make_lispy_switch_frame (frame); - internal_last_event_frame = frame; - kbd_fetch_ptr = event + 1; - } + if ( +#ifdef HAVE_X11 + ! NILP (event->arg) + && +#endif + !EQ (frame, internal_last_event_frame) + && !EQ (frame, selected_frame)) + obj = make_lispy_switch_frame (frame); + else + obj = make_lispy_focus_in (frame); + + internal_last_event_frame = frame; + kbd_fetch_ptr = event + 1; + } + else if (event->kind == FOCUS_OUT_EVENT) + { +#if defined(HAVE_NS) || defined (HAVE_X11) + +#ifdef HAVE_NS + struct ns_display_info *di; +#else + struct x_display_info *di; +#endif + Lisp_Object rest, frame = event->frame_or_window; + bool focused = false; + + for (di = x_display_list; di && ! focused; di = di->next) + focused = di->x_highlight_frame != 0; + + if (! focused) obj = make_lispy_focus_out (frame); +#endif /* HAVE_NS || HAVE_X11 */ + + kbd_fetch_ptr = event + 1; + } #ifdef HAVE_DBUS else if (event->kind == DBUS_EVENT) { @@ -6052,6 +6083,17 @@ make_lispy_switch_frame (Lisp_Object frame) { return list2 (Qswitch_frame, frame); } + +static Lisp_Object +make_lispy_focus_in (Lisp_Object frame) +{ + return list2 (Qfocus_in, frame); +} +static Lisp_Object +make_lispy_focus_out (Lisp_Object frame) +{ + return list2 (Qfocus_out, frame); +} /* Manipulating modifiers. */ @@ -10911,6 +10953,8 @@ static const struct event_head head_table[] = { {&Qmouse_movement, "mouse-movement", &Qmouse_movement}, {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement}, {&Qswitch_frame, "switch-frame", &Qswitch_frame}, + {&Qfocus_in, "focus-in", &Qfocus_in}, + {&Qfocus_out, "focus-out", &Qfocus_out}, {&Qdelete_frame, "delete-frame", &Qdelete_frame}, {&Qiconify_frame, "iconify-frame", &Qiconify_frame}, {&Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible}, @@ -11725,6 +11769,10 @@ keys_of_keyboard (void) initial_define_lispy_key (Vspecial_event_map, "language-change", "ignore"); #endif + initial_define_lispy_key (Vspecial_event_map, "focus-in", + "handle-focus-in"); + initial_define_lispy_key (Vspecial_event_map, "focus-out", + "handle-focus-out"); } /* Mark the pointers in the kboard objects. diff --git a/src/nsterm.m b/src/nsterm.m index 340ef3b00a2..c91e68f37a9 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -5746,9 +5746,10 @@ not_in_argv (NSString *arg) /* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ { struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); + BOOL is_focus_frame = dpyinfo->x_focus_frame == emacsframe; NSTRACE (windowDidResignKey); - if (dpyinfo->x_focus_frame == emacsframe) + if (is_focus_frame) dpyinfo->x_focus_frame = 0; ns_frame_rehighlight (emacsframe); @@ -5761,10 +5762,10 @@ not_in_argv (NSString *arg) x_set_frame_alpha (emacsframe); } - if (emacs_event) + if (emacs_event && is_focus_frame) { [self deleteWorkingText]; - emacs_event->kind = FOCUS_IN_EVENT; + emacs_event->kind = FOCUS_OUT_EVENT; EV_TRAILER ((id)nil); } } diff --git a/src/termhooks.h b/src/termhooks.h index 0190478c254..b49a7bc706b 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -172,6 +172,8 @@ enum event_kind `switch-frame' events in kbd_buffer_get_event, if necessary. */ FOCUS_IN_EVENT, + FOCUS_OUT_EVENT, + /* Generated when mouse moves over window not currently selected. */ SELECT_WINDOW_EVENT, diff --git a/src/xterm.c b/src/xterm.c index f1a18d3bf37..74e495e5645 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3439,9 +3439,15 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra && CONSP (Vframe_list) && !NILP (XCDR (Vframe_list))) { - bufp->kind = FOCUS_IN_EVENT; - XSETFRAME (bufp->frame_or_window, frame); + bufp->arg = Qt; } + else + { + bufp->arg = Qnil; + } + + bufp->kind = FOCUS_IN_EVENT; + XSETFRAME (bufp->frame_or_window, frame); } frame->output_data.x->focus_state |= state; @@ -3459,6 +3465,9 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra { dpyinfo->x_focus_event_frame = 0; x_new_focus_frame (dpyinfo, 0); + + bufp->kind = FOCUS_OUT_EVENT; + XSETFRAME (bufp->frame_or_window, frame); } #ifdef HAVE_X_I18N |