aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2017-04-30 10:02:53 +0200
committerMartin Rudalics2017-04-30 10:02:53 +0200
commit0943cc18b18e2df90c7aa0fbc4dab72d418aa700 (patch)
tree5cc55eb8a9da33426e488b3f8a413185d60ec187
parent7e4dae99d619315179a90461b42ae8d734c5bb45 (diff)
downloademacs-0943cc18b18e2df90c7aa0fbc4dab72d418aa700.tar.gz
emacs-0943cc18b18e2df90c7aa0fbc4dab72d418aa700.zip
Fix `delete-frame' behavior including Bug#26682
* src/frame.c (other_frames): Accept two arguments now. Don't care about minibuffer window. Don't care about visibility when called from delete_frame with FORCE true (Bug#26682). (delete_frame, Fmake_frame_invisible): Adjust other_frames calls. * src/w32term.c (w32_read_socket): Don't add a move frame event for an invisible frame. * lisp/frame.el (handle-delete-frame): Don't kill Emacs when attempting to delete a surrogate minibuffer frame.
-rw-r--r--lisp/frame.el7
-rw-r--r--src/frame.c46
-rw-r--r--src/w32term.c2
3 files changed, 25 insertions, 30 deletions
diff --git a/lisp/frame.el b/lisp/frame.el
index cec262499d1..05db8cf6fd4 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -118,13 +118,10 @@ appended when the minibuffer frame is created."
118 (let* ((frame (posn-window (event-start event)))) 118 (let* ((frame (posn-window (event-start event))))
119 (if (catch 'other-frame 119 (if (catch 'other-frame
120 (dolist (frame-1 (frame-list)) 120 (dolist (frame-1 (frame-list))
121 ;; A valid "other" frame is visible, owns its minibuffer 121 ;; A valid "other" frame is visible, has its `delete-before'
122 ;; window, has its `delete-before' parameter unset and is 122 ;; parameter unset and is not a child frame.
123 ;; not a child frame.
124 (when (and (not (eq frame-1 frame)) 123 (when (and (not (eq frame-1 frame))
125 (frame-visible-p frame-1) 124 (frame-visible-p frame-1)
126 (window-live-p (minibuffer-window frame-1))
127 (eq (window-frame (minibuffer-window frame-1)) frame-1)
128 (not (frame-parent frame-1)) 125 (not (frame-parent frame-1))
129 (not (frame-parameter frame-1 'delete-before))) 126 (not (frame-parameter frame-1 'delete-before)))
130 (throw 'other-frame t)))) 127 (throw 'other-frame t))))
diff --git a/src/frame.c b/src/frame.c
index 681a245ee05..4d17a071dc7 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1560,15 +1560,16 @@ DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
1560 * Return true if there exists at least one visible or iconified frame 1560 * Return true if there exists at least one visible or iconified frame
1561 * but F. Return false otherwise. 1561 * but F. Return false otherwise.
1562 * 1562 *
1563 * Always return false when all remaining frames are either tooltip or 1563 * INVISIBLE true means we are called from make_frame_invisible where
1564 * child frames or frames with a non-nil `delete-before' parameter. If 1564 * such a frame must be visible or iconified. INVISIBLE nil means we
1565 * INVISIBLE is false, also return false when the minibuffer window of 1565 * are called from delete_frame. In that case FORCE true means that the
1566 * all remaining frames is on F. 1566 * visibility status of such a frame can be ignored.
1567 1567 *
1568 * If F is the terminal frame and we are using X, return true if at 1568 * If F is the terminal frame and we are using X, return true if at
1569 * least one X frame exists. */ 1569 * least one X frame exists.
1570 */
1570static bool 1571static bool
1571other_frames (struct frame *f, bool invisible) 1572other_frames (struct frame *f, bool invisible, bool force)
1572{ 1573{
1573 Lisp_Object frames, frame, frame1; 1574 Lisp_Object frames, frame, frame1;
1574 struct frame *f1; 1575 struct frame *f1;
@@ -1591,23 +1592,20 @@ other_frames (struct frame *f, bool invisible)
1591 x_sync (f1); 1592 x_sync (f1);
1592#endif 1593#endif
1593 if (NILP (Fframe_parameter (frame1, Qtooltip)) 1594 if (NILP (Fframe_parameter (frame1, Qtooltip))
1594 /* Tooltips and child frames don't count. */ 1595 /* Tooltips and child frames count neither for
1596 invisibility nor for deletions. */
1595 && !FRAME_PARENT_FRAME (f1) 1597 && !FRAME_PARENT_FRAME (f1)
1596 /* Frames with a non-nil `delete-before' parameter don't 1598 /* Frames with a non-nil `delete-before' parameter don't
1597 count - either they depend on us or they depend on a 1599 count for deletions. */
1598 frame that we will have to find right here. */ 1600 && (invisible || NILP (get_frame_param (f1, Qdelete_before)))
1599 && NILP (get_frame_param (f1, Qdelete_before)) 1601 /* For invisibility and normal deletions, at least one
1600 /* Frames whose minibuffer window is on F don't count 1602 visible or iconified frame must remain (Bug#26682). */
1601 unless INVISIBLE is set - in that case F is either made
1602 invisible and may be autoraised from such a frame or
1603 the FORCE argument of delete_frame was non-nil. */
1604 && (invisible || NILP (minibuffer_window)
1605 || !EQ (FRAME_MINIBUF_WINDOW (f1), minibuffer_window))
1606 /* At least one visible/iconified frame must remain. */
1607 && (FRAME_VISIBLE_P (f1) || FRAME_ICONIFIED_P (f1) 1603 && (FRAME_VISIBLE_P (f1) || FRAME_ICONIFIED_P (f1)
1608 /* Allow deleting the terminal frame when at least one 1604 || (!invisible
1609 X frame exists. */ 1605 && (force
1610 || (FRAME_WINDOW_P (f1) && !FRAME_WINDOW_P (f)))) 1606 /* Allow deleting the terminal frame when at
1607 least one X frame exists. */
1608 || (FRAME_WINDOW_P (f1) && !FRAME_WINDOW_P (f))))))
1611 return true; 1609 return true;
1612 } 1610 }
1613 } 1611 }
@@ -1680,7 +1678,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1680 1678
1681 if (!FRAME_LIVE_P (f)) 1679 if (!FRAME_LIVE_P (f))
1682 return Qnil; 1680 return Qnil;
1683 else if (!EQ (force, Qnoelisp) && !other_frames (f, !NILP (force))) 1681 else if (!EQ (force, Qnoelisp) && !other_frames (f, false, !NILP (force)))
1684 { 1682 {
1685 if (NILP (force)) 1683 if (NILP (force))
1686 error ("Attempt to delete the sole visible or iconified frame"); 1684 error ("Attempt to delete the sole visible or iconified frame");
@@ -1752,7 +1750,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1752 one. */ 1750 one. */
1753 if (!FRAME_LIVE_P (f)) 1751 if (!FRAME_LIVE_P (f))
1754 return Qnil; 1752 return Qnil;
1755 else if (!EQ (force, Qnoelisp) && !other_frames (f, !NILP (force))) 1753 else if (!EQ (force, Qnoelisp) && !other_frames (f, false, !NILP (force)))
1756 { 1754 {
1757 if (NILP (force)) 1755 if (NILP (force))
1758 error ("Attempt to delete the sole visible or iconified frame"); 1756 error ("Attempt to delete the sole visible or iconified frame");
@@ -2275,7 +2273,7 @@ displayed in the terminal. */)
2275{ 2273{
2276 struct frame *f = decode_live_frame (frame); 2274 struct frame *f = decode_live_frame (frame);
2277 2275
2278 if (NILP (force) && !other_frames (f, true)) 2276 if (NILP (force) && !other_frames (f, true, false))
2279 error ("Attempt to make invisible the sole visible or iconified frame"); 2277 error ("Attempt to make invisible the sole visible or iconified frame");
2280 2278
2281 /* Don't allow minibuf_window to remain on an invisible frame. */ 2279 /* Don't allow minibuf_window to remain on an invisible frame. */
diff --git a/src/w32term.c b/src/w32term.c
index 6b0da0cb3e9..b3608accb34 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5110,7 +5110,7 @@ w32_read_socket (struct terminal *terminal,
5110 case WM_MOVE: 5110 case WM_MOVE:
5111 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 5111 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
5112 5112
5113 if (f && !FRAME_ICONIFIED_P (f)) 5113 if (f && FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P(f))
5114 { 5114 {
5115 x_real_positions (f, &f->left_pos, &f->top_pos); 5115 x_real_positions (f, &f->left_pos, &f->top_pos);
5116 inev.kind = MOVE_FRAME_EVENT; 5116 inev.kind = MOVE_FRAME_EVENT;