aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2017-04-11 12:37:26 +0200
committerMartin Rudalics2017-04-11 12:37:26 +0200
commitea6c880aa68bcc8f0e388ecbd8c552392488b38f (patch)
treec4da212b292347d6668dc6283f8444fc795f6e2c /src
parent0eef8e9af7707b7bd01243033b9a48cb74fb8672 (diff)
downloademacs-ea6c880aa68bcc8f0e388ecbd8c552392488b38f.tar.gz
emacs-ea6c880aa68bcc8f0e388ecbd8c552392488b38f.zip
Frame movement, focus and hook related changes
New hook `move-frame-functions'. Run `focus-in-hook' after switching to frame that gets focus. Don't run XMoveWindow for GTK. * lisp/frame.el (handle-move-frame, frame-size-changed-p): New functions. * src/frame.c (do_switch_frame): Simplify code. (Fhandle_switch_frame): Switch frame before running `handle-focus-in'. (Vfocus_in_hook, Vfocus_out_hook): Clarify doc-strings. (Vmove_frame_functions): New hook variable. * src/keyboard.c (kbd_buffer_get_event): Handle MOVE_FRAME_EVENT. Handle SELECT_WINDOW_EVENT separately. (head_table): Add Qmove_frame entry. (syms_of_keyboard): Add Qmove_frame. (keys_of_keyboard): Define key for `move-frame'. * src/termhooks.h (event_kind): Add MOVE_FRAME_EVENT. * src/w32term.c (w32_read_socket): Create MOVE_FRAME_EVENT. * src/window.c (run_window_size_change_functions): Record size of FRAME's minibuffer window too. * src/xterm.c (handle_one_xevent): Create MOVE_FRAME_EVENT. (x_set_offset): For GTK call gtk_widget_move instead of XMoveWindow.
Diffstat (limited to 'src')
-rw-r--r--src/frame.c37
-rw-r--r--src/keyboard.c17
-rw-r--r--src/termhooks.h3
-rw-r--r--src/w32term.c6
-rw-r--r--src/window.c9
-rw-r--r--src/xterm.c24
6 files changed, 77 insertions, 19 deletions
diff --git a/src/frame.c b/src/frame.c
index d873147fc8b..5f57d4a0c24 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1107,7 +1107,7 @@ affects all frames on the same terminal device. */)
1107Lisp_Object 1107Lisp_Object
1108do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord) 1108do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord)
1109{ 1109{
1110 struct frame *sf = SELECTED_FRAME (); 1110 struct frame *sf = SELECTED_FRAME (), *f;
1111 1111
1112 /* If FRAME is a switch-frame event, extract the frame we should 1112 /* If FRAME is a switch-frame event, extract the frame we should
1113 switch to. */ 1113 switch to. */
@@ -1120,10 +1120,10 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1120 a switch-frame event to arrive after a frame is no longer live, 1120 a switch-frame event to arrive after a frame is no longer live,
1121 especially when deleting the initial frame during startup. */ 1121 especially when deleting the initial frame during startup. */
1122 CHECK_FRAME (frame); 1122 CHECK_FRAME (frame);
1123 if (! FRAME_LIVE_P (XFRAME (frame))) 1123 f = XFRAME (frame);
1124 if (!FRAME_LIVE_P (f))
1124 return Qnil; 1125 return Qnil;
1125 1126 else if (f == sf)
1126 if (sf == XFRAME (frame))
1127 return frame; 1127 return frame;
1128 1128
1129 /* If a frame's focus has been redirected toward the currently 1129 /* If a frame's focus has been redirected toward the currently
@@ -1156,11 +1156,11 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1156#else /* ! 0 */ 1156#else /* ! 0 */
1157 /* Instead, apply it only to the frame we're pointing to. */ 1157 /* Instead, apply it only to the frame we're pointing to. */
1158#ifdef HAVE_WINDOW_SYSTEM 1158#ifdef HAVE_WINDOW_SYSTEM
1159 if (track && FRAME_WINDOW_P (XFRAME (frame))) 1159 if (track && FRAME_WINDOW_P (f))
1160 { 1160 {
1161 Lisp_Object focus, xfocus; 1161 Lisp_Object focus, xfocus;
1162 1162
1163 xfocus = x_get_focus_frame (XFRAME (frame)); 1163 xfocus = x_get_focus_frame (f);
1164 if (FRAMEP (xfocus)) 1164 if (FRAMEP (xfocus))
1165 { 1165 {
1166 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus)); 1166 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
@@ -1168,8 +1168,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1168 /* Redirect frame focus also when FRAME has its minibuffer 1168 /* Redirect frame focus also when FRAME has its minibuffer
1169 window on the selected frame (see Bug#24500). */ 1169 window on the selected frame (see Bug#24500). */
1170 || (NILP (focus) 1170 || (NILP (focus)
1171 && EQ (FRAME_MINIBUF_WINDOW (XFRAME (frame)), 1171 && EQ (FRAME_MINIBUF_WINDOW (f), sf->selected_window)))
1172 sf->selected_window)))
1173 Fredirect_frame_focus (xfocus, frame); 1172 Fredirect_frame_focus (xfocus, frame);
1174 } 1173 }
1175 } 1174 }
@@ -1179,9 +1178,8 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1179 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf)) 1178 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
1180 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1); 1179 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
1181 1180
1182 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame))) 1181 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
1183 { 1182 {
1184 struct frame *f = XFRAME (frame);
1185 struct tty_display_info *tty = FRAME_TTY (f); 1183 struct tty_display_info *tty = FRAME_TTY (f);
1186 Lisp_Object top_frame = tty->top_frame; 1184 Lisp_Object top_frame = tty->top_frame;
1187 1185
@@ -1209,7 +1207,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1209 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame))) 1207 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
1210 last_nonminibuf_frame = XFRAME (selected_frame); 1208 last_nonminibuf_frame = XFRAME (selected_frame);
1211 1209
1212 Fselect_window (XFRAME (frame)->selected_window, norecord); 1210 Fselect_window (f->selected_window, norecord);
1213 1211
1214 /* We want to make sure that the next event generates a frame-switch 1212 /* We want to make sure that the next event generates a frame-switch
1215 event to the appropriate frame. This seems kludgy to me, but 1213 event to the appropriate frame. This seems kludgy to me, but
@@ -1253,12 +1251,15 @@ If EVENT is frame object, handle it as if it were a switch-frame event
1253to that frame. */) 1251to that frame. */)
1254 (Lisp_Object event) 1252 (Lisp_Object event)
1255{ 1253{
1254 Lisp_Object value;
1255
1256 /* Preserve prefix arg that the command loop just cleared. */ 1256 /* Preserve prefix arg that the command loop just cleared. */
1257 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); 1257 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
1258 run_hook (Qmouse_leave_buffer_hook); 1258 run_hook (Qmouse_leave_buffer_hook);
1259 /* `switch-frame' implies a focus in. */ 1259 /* `switch-frame' implies a focus in. */
1260 value = do_switch_frame (event, 0, 0, Qnil);
1260 call1 (intern ("handle-focus-in"), event); 1261 call1 (intern ("handle-focus-in"), event);
1261 return do_switch_frame (event, 0, 0, Qnil); 1262 return value;
1262} 1263}
1263 1264
1264DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0, 1265DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
@@ -1709,8 +1710,6 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1709 promise that the terminal of the frame must be valid until we 1710 promise that the terminal of the frame must be valid until we
1710 have called the window-system-dependent frame destruction 1711 have called the window-system-dependent frame destruction
1711 routine. */ 1712 routine. */
1712
1713
1714 { 1713 {
1715 struct terminal *terminal; 1714 struct terminal *terminal;
1716 block_input (); 1715 block_input ();
@@ -5121,13 +5120,19 @@ The pointer becomes visible again when the mouse is moved. */);
5121 Vmake_pointer_invisible = Qt; 5120 Vmake_pointer_invisible = Qt;
5122 5121
5123 DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook, 5122 DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook,
5124 doc: /* Normal hook run when a frame gains input focus. */); 5123 doc: /* Normal hook run when a frame gains input focus.
5124The frame gaining focus is selected at the time this hook is run. */);
5125 Vfocus_in_hook = Qnil; 5125 Vfocus_in_hook = Qnil;
5126 5126
5127 DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook, 5127 DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook,
5128 doc: /* Normal hook run when a frame loses input focus. */); 5128 doc: /* Normal hook run when all frames lost input focus. */);
5129 Vfocus_out_hook = Qnil; 5129 Vfocus_out_hook = Qnil;
5130 5130
5131 DEFVAR_LISP ("move-frame-functions", Vmove_frame_functions,
5132 doc: /* Functions run after a frame was moved.
5133The functions are run with one arg, the frame that moved. */);
5134 Vmove_frame_functions = Qnil;
5135
5131 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions, 5136 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
5132 doc: /* Functions run before deleting a frame. 5137 doc: /* Functions run before deleting a frame.
5133The functions are run with one arg, the frame to be deleted. 5138The functions are run with one arg, the frame to be deleted.
diff --git a/src/keyboard.c b/src/keyboard.c
index 2e0a813bb08..3e50142f7c1 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4056,6 +4056,14 @@ kbd_buffer_get_event (KBOARD **kbp,
4056 kbd_fetch_ptr = event + 1; 4056 kbd_fetch_ptr = event + 1;
4057 } 4057 }
4058#endif 4058#endif
4059#if defined (HAVE_X11) || defined (HAVE_NTGUI)
4060 else if (event->kind == MOVE_FRAME_EVENT)
4061 {
4062 /* Make an event (move-frame (FRAME)). */
4063 obj = list2 (Qmove_frame, list1 (event->ie.frame_or_window));
4064 kbd_fetch_ptr = event + 1;
4065 }
4066#endif
4059#ifdef HAVE_XWIDGETS 4067#ifdef HAVE_XWIDGETS
4060 else if (event->kind == XWIDGET_EVENT) 4068 else if (event->kind == XWIDGET_EVENT)
4061 { 4069 {
@@ -4068,6 +4076,11 @@ kbd_buffer_get_event (KBOARD **kbp,
4068 obj = make_lispy_event (&event->ie); 4076 obj = make_lispy_event (&event->ie);
4069 kbd_fetch_ptr = event + 1; 4077 kbd_fetch_ptr = event + 1;
4070 } 4078 }
4079 else if (event->kind == SELECT_WINDOW_EVENT)
4080 {
4081 obj = list2 (Qselect_window, list1 (event->ie.frame_or_window));
4082 kbd_fetch_ptr = event + 1;
4083 }
4071 else 4084 else
4072 { 4085 {
4073 /* If this event is on a different frame, return a switch-frame this 4086 /* If this event is on a different frame, return a switch-frame this
@@ -10977,6 +10990,7 @@ static const struct event_head head_table[] = {
10977 10990
10978 {SYMBOL_INDEX (Qfocus_in), SYMBOL_INDEX (Qfocus_in)}, 10991 {SYMBOL_INDEX (Qfocus_in), SYMBOL_INDEX (Qfocus_in)},
10979 {SYMBOL_INDEX (Qfocus_out), SYMBOL_INDEX (Qfocus_out)}, 10992 {SYMBOL_INDEX (Qfocus_out), SYMBOL_INDEX (Qfocus_out)},
10993 {SYMBOL_INDEX (Qmove_frame), SYMBOL_INDEX (Qmove_frame)},
10980 {SYMBOL_INDEX (Qdelete_frame), SYMBOL_INDEX (Qdelete_frame)}, 10994 {SYMBOL_INDEX (Qdelete_frame), SYMBOL_INDEX (Qdelete_frame)},
10981 {SYMBOL_INDEX (Qiconify_frame), SYMBOL_INDEX (Qiconify_frame)}, 10995 {SYMBOL_INDEX (Qiconify_frame), SYMBOL_INDEX (Qiconify_frame)},
10982 {SYMBOL_INDEX (Qmake_frame_visible), SYMBOL_INDEX (Qmake_frame_visible)}, 10996 {SYMBOL_INDEX (Qmake_frame_visible), SYMBOL_INDEX (Qmake_frame_visible)},
@@ -11149,6 +11163,7 @@ syms_of_keyboard (void)
11149 DEFSYM (Qswitch_frame, "switch-frame"); 11163 DEFSYM (Qswitch_frame, "switch-frame");
11150 DEFSYM (Qfocus_in, "focus-in"); 11164 DEFSYM (Qfocus_in, "focus-in");
11151 DEFSYM (Qfocus_out, "focus-out"); 11165 DEFSYM (Qfocus_out, "focus-out");
11166 DEFSYM (Qmove_frame, "move-frame");
11152 DEFSYM (Qdelete_frame, "delete-frame"); 11167 DEFSYM (Qdelete_frame, "delete-frame");
11153 DEFSYM (Qiconify_frame, "iconify-frame"); 11168 DEFSYM (Qiconify_frame, "iconify-frame");
11154 DEFSYM (Qmake_frame_visible, "make-frame-visible"); 11169 DEFSYM (Qmake_frame_visible, "make-frame-visible");
@@ -11895,6 +11910,8 @@ keys_of_keyboard (void)
11895 "handle-focus-in"); 11910 "handle-focus-in");
11896 initial_define_lispy_key (Vspecial_event_map, "focus-out", 11911 initial_define_lispy_key (Vspecial_event_map, "focus-out",
11897 "handle-focus-out"); 11912 "handle-focus-out");
11913 initial_define_lispy_key (Vspecial_event_map, "move-frame",
11914 "handle-move-frame");
11898} 11915}
11899 11916
11900/* Mark the pointers in the kboard objects. 11917/* Mark the pointers in the kboard objects.
diff --git a/src/termhooks.h b/src/termhooks.h
index 3b1b4959b1d..14ec397346a 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -202,6 +202,9 @@ enum event_kind
202 202
203 FOCUS_OUT_EVENT, 203 FOCUS_OUT_EVENT,
204 204
205 /* Generated when a frame is moved. */
206 MOVE_FRAME_EVENT,
207
205 /* Generated when mouse moves over window not currently selected. */ 208 /* Generated when mouse moves over window not currently selected. */
206 SELECT_WINDOW_EVENT, 209 SELECT_WINDOW_EVENT,
207 210
diff --git a/src/w32term.c b/src/w32term.c
index 81666f5bc47..31f0b4a2fa0 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5038,7 +5038,11 @@ w32_read_socket (struct terminal *terminal,
5038 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 5038 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
5039 5039
5040 if (f && !FRAME_ICONIFIED_P (f)) 5040 if (f && !FRAME_ICONIFIED_P (f))
5041 x_real_positions (f, &f->left_pos, &f->top_pos); 5041 {
5042 x_real_positions (f, &f->left_pos, &f->top_pos);
5043 inev.kind = MOVE_FRAME_EVENT;
5044 XSETFRAME (inev.frame_or_window, f);
5045 }
5042 5046
5043 check_visibility = 1; 5047 check_visibility = 1;
5044 break; 5048 break;
diff --git a/src/window.c b/src/window.c
index 95690443f8e..58c0c33cbb0 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3314,6 +3314,9 @@ run_window_size_change_functions (Lisp_Object frame)
3314 Lisp_Object functions = Vwindow_size_change_functions; 3314 Lisp_Object functions = Vwindow_size_change_functions;
3315 3315
3316 if (FRAME_WINDOW_CONFIGURATION_CHANGED (f) 3316 if (FRAME_WINDOW_CONFIGURATION_CHANGED (f)
3317 /* Here we implicitly exclude the possibility that the height of
3318 FRAME and its minibuffer window both change leaving the height
3319 of FRAME's root window alone. */
3317 || window_size_changed (r)) 3320 || window_size_changed (r))
3318 { 3321 {
3319 while (CONSP (functions)) 3322 while (CONSP (functions))
@@ -3324,6 +3327,12 @@ run_window_size_change_functions (Lisp_Object frame)
3324 } 3327 }
3325 3328
3326 window_set_before_size_change_sizes (r); 3329 window_set_before_size_change_sizes (r);
3330
3331 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
3332 /* Record size of FRAME's minibuffer window too. */
3333 window_set_before_size_change_sizes
3334 (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
3335
3327 FRAME_WINDOW_CONFIGURATION_CHANGED (f) = false; 3336 FRAME_WINDOW_CONFIGURATION_CHANGED (f) = false;
3328 } 3337 }
3329} 3338}
diff --git a/src/xterm.c b/src/xterm.c
index 08ccac07005..1d14407aa43 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8614,7 +8614,22 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8614 if (FRAME_GTK_OUTER_WIDGET (f) 8614 if (FRAME_GTK_OUTER_WIDGET (f)
8615 && gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f))) 8615 && gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
8616#endif 8616#endif
8617 x_real_positions (f, &f->left_pos, &f->top_pos); 8617 {
8618 int old_left = f->left_pos;
8619 int old_top = f->top_pos;
8620 Lisp_Object frame = Qnil;
8621
8622 XSETFRAME (frame, f);
8623
8624 x_real_positions (f, &f->left_pos, &f->top_pos);
8625
8626 if (old_left != f->left_pos || old_top != f->top_pos)
8627 {
8628 inev.ie.kind = MOVE_FRAME_EVENT;
8629 XSETFRAME (inev.ie.frame_or_window, f);
8630 }
8631 }
8632
8618 8633
8619#ifdef HAVE_X_I18N 8634#ifdef HAVE_X_I18N
8620 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) 8635 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
@@ -10088,8 +10103,13 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
10088 modified_top += FRAME_X_OUTPUT (f)->move_offset_top; 10103 modified_top += FRAME_X_OUTPUT (f)->move_offset_top;
10089 } 10104 }
10090 10105
10106#ifdef USE_GTK
10107 gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
10108 modified_left, modified_top);
10109#else
10091 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 10110 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
10092 modified_left, modified_top); 10111 modified_left, modified_top);
10112#endif
10093 10113
10094 x_sync_with_move (f, f->left_pos, f->top_pos, 10114 x_sync_with_move (f, f->left_pos, f->top_pos,
10095 FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN); 10115 FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);