[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master ea6c880: Frame movement, focus and hook related cha
From: |
Martin Rudalics |
Subject: |
[Emacs-diffs] master ea6c880: Frame movement, focus and hook related changes |
Date: |
Tue, 11 Apr 2017 06:41:12 -0400 (EDT) |
branch: master
commit ea6c880aa68bcc8f0e388ecbd8c552392488b38f
Author: Martin Rudalics <address@hidden>
Commit: Martin Rudalics <address@hidden>
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.
---
lisp/frame.el | 30 ++++++++++++++++++++++++++++++
src/frame.c | 37 +++++++++++++++++++++----------------
src/keyboard.c | 17 +++++++++++++++++
src/termhooks.h | 3 +++
src/w32term.c | 6 +++++-
src/window.c | 9 +++++++++
src/xterm.c | 24 ++++++++++++++++++++++--
7 files changed, 107 insertions(+), 19 deletions(-)
diff --git a/lisp/frame.el b/lisp/frame.el
index 0a35b71..4768b5b 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -144,6 +144,13 @@ Focus-out events occur when no frame has focus.
This function runs the hook `focus-out-hook'."
(interactive "e")
(run-hooks 'focus-out-hook))
+
+(defun handle-move-frame (event)
+ "Handle a move-frame event.
+This function runs the abnormal hook `move-frame-functions'."
+ (interactive "e")
+ (let ((frame (posn-window (event-start event))))
+ (run-hook-with-args 'move-frame-functions frame)))
;;;; Arrangement of frames at startup
@@ -1483,6 +1490,29 @@ keys and their meanings."
for frames = (cdr (assq 'frames attributes))
if (memq frame frames) return attributes))
+(defun frame-size-changed-p (&optional frame)
+ "Return non-nil when the size of FRAME has changed.
+More precisely, return non-nil when the inner width or height of
+FRAME has changed since `window-size-change-functions' was run
+for FRAME."
+ (let* ((frame (window-normalize-frame frame))
+ (root (frame-root-window frame))
+ (mini (minibuffer-window frame))
+ (mini-height-before-size-change 0)
+ (mini-height 0))
+ ;; FRAME's minibuffer window counts iff it's on FRAME and FRAME is
+ ;; not a minibuffer-only frame.
+ (when (and (eq (window-frame mini) frame) (not (eq mini root)))
+ (setq mini-height-before-size-change
+ (window-pixel-height-before-size-change mini))
+ (setq mini-height (window-pixel-height mini)))
+ ;; Return non-nil when either the width of the root or the sum of
+ ;; the heights of root and minibuffer window changed.
+ (or (/= (window-pixel-width-before-size-change root)
+ (window-pixel-width root))
+ (/= (+ (window-pixel-height-before-size-change root)
+ mini-height-before-size-change)
+ (+ (window-pixel-height root) mini-height)))))
;;;; Frame/display capabilities.
diff --git a/src/frame.c b/src/frame.c
index d873147..5f57d4a 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1107,7 +1107,7 @@ affects all frames on the same terminal device. */)
Lisp_Object
do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object
norecord)
{
- struct frame *sf = SELECTED_FRAME ();
+ struct frame *sf = SELECTED_FRAME (), *f;
/* If FRAME is a switch-frame event, extract the frame we should
switch to. */
@@ -1120,10 +1120,10 @@ do_switch_frame (Lisp_Object frame, int track, int
for_deletion, Lisp_Object nor
a switch-frame event to arrive after a frame is no longer live,
especially when deleting the initial frame during startup. */
CHECK_FRAME (frame);
- if (! FRAME_LIVE_P (XFRAME (frame)))
+ f = XFRAME (frame);
+ if (!FRAME_LIVE_P (f))
return Qnil;
-
- if (sf == XFRAME (frame))
+ else if (f == sf)
return frame;
/* 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
#else /* ! 0 */
/* Instead, apply it only to the frame we're pointing to. */
#ifdef HAVE_WINDOW_SYSTEM
- if (track && FRAME_WINDOW_P (XFRAME (frame)))
+ if (track && FRAME_WINDOW_P (f))
{
Lisp_Object focus, xfocus;
- xfocus = x_get_focus_frame (XFRAME (frame));
+ xfocus = x_get_focus_frame (f);
if (FRAMEP (xfocus))
{
focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
@@ -1168,8 +1168,7 @@ do_switch_frame (Lisp_Object frame, int track, int
for_deletion, Lisp_Object nor
/* Redirect frame focus also when FRAME has its minibuffer
window on the selected frame (see Bug#24500). */
|| (NILP (focus)
- && EQ (FRAME_MINIBUF_WINDOW (XFRAME (frame)),
- sf->selected_window)))
+ && EQ (FRAME_MINIBUF_WINDOW (f), sf->selected_window)))
Fredirect_frame_focus (xfocus, frame);
}
}
@@ -1179,9 +1178,8 @@ do_switch_frame (Lisp_Object frame, int track, int
for_deletion, Lisp_Object nor
if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
- if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
+ if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
{
- struct frame *f = XFRAME (frame);
struct tty_display_info *tty = FRAME_TTY (f);
Lisp_Object top_frame = tty->top_frame;
@@ -1209,7 +1207,7 @@ do_switch_frame (Lisp_Object frame, int track, int
for_deletion, Lisp_Object nor
if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
last_nonminibuf_frame = XFRAME (selected_frame);
- Fselect_window (XFRAME (frame)->selected_window, norecord);
+ Fselect_window (f->selected_window, norecord);
/* We want to make sure that the next event generates a frame-switch
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
to that frame. */)
(Lisp_Object event)
{
+ Lisp_Object value;
+
/* Preserve prefix arg that the command loop just cleared. */
kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
run_hook (Qmouse_leave_buffer_hook);
/* `switch-frame' implies a focus in. */
+ value = do_switch_frame (event, 0, 0, Qnil);
call1 (intern ("handle-focus-in"), event);
- return do_switch_frame (event, 0, 0, Qnil);
+ return value;
}
DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
@@ -1709,8 +1710,6 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
promise that the terminal of the frame must be valid until we
have called the window-system-dependent frame destruction
routine. */
-
-
{
struct terminal *terminal;
block_input ();
@@ -5121,13 +5120,19 @@ The pointer becomes visible again when the mouse is
moved. */);
Vmake_pointer_invisible = Qt;
DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook,
- doc: /* Normal hook run when a frame gains input focus. */);
+ doc: /* Normal hook run when a frame gains input focus.
+The frame gaining focus is selected at the time this hook is run. */);
Vfocus_in_hook = Qnil;
DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook,
- doc: /* Normal hook run when a frame loses input focus. */);
+ doc: /* Normal hook run when all frames lost input focus. */);
Vfocus_out_hook = Qnil;
+ DEFVAR_LISP ("move-frame-functions", Vmove_frame_functions,
+ doc: /* Functions run after a frame was moved.
+The functions are run with one arg, the frame that moved. */);
+ Vmove_frame_functions = Qnil;
+
DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
doc: /* Functions run before deleting a frame.
The functions are run with one arg, the frame to be deleted.
diff --git a/src/keyboard.c b/src/keyboard.c
index 2e0a813..3e50142 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4056,6 +4056,14 @@ kbd_buffer_get_event (KBOARD **kbp,
kbd_fetch_ptr = event + 1;
}
#endif
+#if defined (HAVE_X11) || defined (HAVE_NTGUI)
+ else if (event->kind == MOVE_FRAME_EVENT)
+ {
+ /* Make an event (move-frame (FRAME)). */
+ obj = list2 (Qmove_frame, list1 (event->ie.frame_or_window));
+ kbd_fetch_ptr = event + 1;
+ }
+#endif
#ifdef HAVE_XWIDGETS
else if (event->kind == XWIDGET_EVENT)
{
@@ -4068,6 +4076,11 @@ kbd_buffer_get_event (KBOARD **kbp,
obj = make_lispy_event (&event->ie);
kbd_fetch_ptr = event + 1;
}
+ else if (event->kind == SELECT_WINDOW_EVENT)
+ {
+ obj = list2 (Qselect_window, list1 (event->ie.frame_or_window));
+ kbd_fetch_ptr = event + 1;
+ }
else
{
/* If this event is on a different frame, return a switch-frame this
@@ -10977,6 +10990,7 @@ static const struct event_head head_table[] = {
{SYMBOL_INDEX (Qfocus_in), SYMBOL_INDEX (Qfocus_in)},
{SYMBOL_INDEX (Qfocus_out), SYMBOL_INDEX (Qfocus_out)},
+ {SYMBOL_INDEX (Qmove_frame), SYMBOL_INDEX (Qmove_frame)},
{SYMBOL_INDEX (Qdelete_frame), SYMBOL_INDEX (Qdelete_frame)},
{SYMBOL_INDEX (Qiconify_frame), SYMBOL_INDEX (Qiconify_frame)},
{SYMBOL_INDEX (Qmake_frame_visible), SYMBOL_INDEX (Qmake_frame_visible)},
@@ -11149,6 +11163,7 @@ syms_of_keyboard (void)
DEFSYM (Qswitch_frame, "switch-frame");
DEFSYM (Qfocus_in, "focus-in");
DEFSYM (Qfocus_out, "focus-out");
+ DEFSYM (Qmove_frame, "move-frame");
DEFSYM (Qdelete_frame, "delete-frame");
DEFSYM (Qiconify_frame, "iconify-frame");
DEFSYM (Qmake_frame_visible, "make-frame-visible");
@@ -11895,6 +11910,8 @@ keys_of_keyboard (void)
"handle-focus-in");
initial_define_lispy_key (Vspecial_event_map, "focus-out",
"handle-focus-out");
+ initial_define_lispy_key (Vspecial_event_map, "move-frame",
+ "handle-move-frame");
}
/* Mark the pointers in the kboard objects.
diff --git a/src/termhooks.h b/src/termhooks.h
index 3b1b495..14ec397 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -202,6 +202,9 @@ enum event_kind
FOCUS_OUT_EVENT,
+ /* Generated when a frame is moved. */
+ MOVE_FRAME_EVENT,
+
/* Generated when mouse moves over window not currently selected. */
SELECT_WINDOW_EVENT,
diff --git a/src/w32term.c b/src/w32term.c
index 81666f5..31f0b4a 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5038,7 +5038,11 @@ w32_read_socket (struct terminal *terminal,
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f && !FRAME_ICONIFIED_P (f))
- x_real_positions (f, &f->left_pos, &f->top_pos);
+ {
+ x_real_positions (f, &f->left_pos, &f->top_pos);
+ inev.kind = MOVE_FRAME_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ }
check_visibility = 1;
break;
diff --git a/src/window.c b/src/window.c
index 9569044..58c0c33 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3314,6 +3314,9 @@ run_window_size_change_functions (Lisp_Object frame)
Lisp_Object functions = Vwindow_size_change_functions;
if (FRAME_WINDOW_CONFIGURATION_CHANGED (f)
+ /* Here we implicitly exclude the possibility that the height of
+ FRAME and its minibuffer window both change leaving the height
+ of FRAME's root window alone. */
|| window_size_changed (r))
{
while (CONSP (functions))
@@ -3324,6 +3327,12 @@ run_window_size_change_functions (Lisp_Object frame)
}
window_set_before_size_change_sizes (r);
+
+ if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
+ /* Record size of FRAME's minibuffer window too. */
+ window_set_before_size_change_sizes
+ (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
+
FRAME_WINDOW_CONFIGURATION_CHANGED (f) = false;
}
}
diff --git a/src/xterm.c b/src/xterm.c
index 08ccac0..1d14407 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8614,7 +8614,22 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (FRAME_GTK_OUTER_WIDGET (f)
&& gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
#endif
- x_real_positions (f, &f->left_pos, &f->top_pos);
+ {
+ int old_left = f->left_pos;
+ int old_top = f->top_pos;
+ Lisp_Object frame = Qnil;
+
+ XSETFRAME (frame, f);
+
+ x_real_positions (f, &f->left_pos, &f->top_pos);
+
+ if (old_left != f->left_pos || old_top != f->top_pos)
+ {
+ inev.ie.kind = MOVE_FRAME_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
+ }
+
#ifdef HAVE_X_I18N
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_
modified_top += FRAME_X_OUTPUT (f)->move_offset_top;
}
+#ifdef USE_GTK
+ gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ modified_left, modified_top);
+#else
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
- modified_left, modified_top);
+ modified_left, modified_top);
+#endif
x_sync_with_move (f, f->left_pos, f->top_pos,
FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master ea6c880: Frame movement, focus and hook related changes,
Martin Rudalics <=