diff options
| author | Martin Rudalics | 2017-04-30 10:02:53 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2017-04-30 10:02:53 +0200 |
| commit | 0943cc18b18e2df90c7aa0fbc4dab72d418aa700 (patch) | |
| tree | 5cc55eb8a9da33426e488b3f8a413185d60ec187 /src | |
| parent | 7e4dae99d619315179a90461b42ae8d734c5bb45 (diff) | |
| download | emacs-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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame.c | 46 | ||||
| -rw-r--r-- | src/w32term.c | 2 |
2 files changed, 23 insertions, 25 deletions
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 | */ | ||
| 1570 | static bool | 1571 | static bool |
| 1571 | other_frames (struct frame *f, bool invisible) | 1572 | other_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; |