diff --git a/src/w32term.c b/src/w32term.c index ad4d1a3282..a1b20236d8 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -6903,11 +6903,6 @@ w32_make_frame_invisible (struct frame *f) my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE); - /* We can't distinguish this from iconification - just by the event that we get from the server. - So we can't win using the usual strategy of letting - FRAME_SAMPLE_VISIBILITY set this. So do it by hand, - and synchronize with the server to make sure we agree. */ SET_FRAME_VISIBLE (f, 0); SET_FRAME_ICONIFIED (f, false); diff --git a/src/xdisp.c b/src/xdisp.c index e853c8c223..66535109b2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -15675,9 +15675,6 @@ redisplay_internal (void) FRAME_TTY (sf)->previous_frame = sf; } - /* Set the visible flags for all frames. Do this before checking for - resized or garbaged frames; they want to know if their frames are - visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */ number_of_visible_frames = 0; FOR_EACH_FRAME (tail, frame) diff --git a/src/xterm.c b/src/xterm.c index 1887c3255d..0de6be762c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -8239,12 +8239,33 @@ handle_one_xevent (struct x_display_info *dpyinfo, f = x_window_to_frame (dpyinfo, event->xexpose.window); if (f) { + if (CONSP (frame_size_history)) + { + frame_size_history_extra + (f, + FRAME_VISIBLE_P (f) + ? build_string ("Expose, visible") + : build_string ("Expose, not visible"), + FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), + -1, -1, event->xexpose.width, event->xexpose.height); + } + if (!FRAME_VISIBLE_P (f)) { block_input (); /* The following two are commented out to avoid that a plain invisible frame gets reported as iconified. That - problem occurred first for Emacs 26 and is described in + problem occurred first for Emacs 26 with GTK3 and is + the result of the following actions: + + (1) x_make_frame_invisible sets f->visible to 0. + + (2) We get an (unexpected) Expose event for f and here + set f->visible to 1. + + (3) The subsequent UnmapNotify event finds f->visible + is 1 and sets f->iconified true. + https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. */ /** SET_FRAME_VISIBLE (f, 1); **/ /** SET_FRAME_ICONIFIED (f, false); **/ @@ -8835,26 +8856,24 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; case FocusIn: -#ifndef USE_GTK /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap minimized/iconified windows; thus, for those WMs we won't get a MapNotify when unminimizing/deconifying. Check here if we - are deiconizing a window (Bug42655). - - But don't do that on GTK since it may cause a plain invisible - frame get reported as iconified, compare - https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. - That is fixed above but bites us here again. */ + are deiconifying a window (Bug42655). */ f = any; + /* Should we handle invisible frames here too? */ if (f && FRAME_ICONIFIED_P (f)) { + if (CONSP (frame_size_history)) + frame_size_history_plain + (f, build_string ("FocusIn, was iconified")); + SET_FRAME_VISIBLE (f, 1); SET_FRAME_ICONIFIED (f, false); f->output_data.x->has_been_visible = true; inev.ie.kind = DEICONIFY_EVENT; XSETFRAME (inev.ie.frame_or_window, f); } -#endif /* USE_GTK */ x_detect_focus_change (dpyinfo, any, event, &inev.ie); goto OTHER; @@ -9344,9 +9363,24 @@ handle_one_xevent (struct x_display_info *dpyinfo, case VisibilityNotify: f = x_top_window_to_frame (dpyinfo, event->xvisibility.window); - if (f && (event->xvisibility.state == VisibilityUnobscured - || event->xvisibility.state == VisibilityPartiallyObscured)) - SET_FRAME_VISIBLE (f, 1); + if (f) + { + if (event->xvisibility.state == VisibilityUnobscured + || event->xvisibility.state == VisibilityPartiallyObscured) + { + if (CONSP (frame_size_history)) + frame_size_history_plain + (f, build_string ("VisibilityNotify, visible")); + + SET_FRAME_VISIBLE (f, 1); + } + else + { + if (CONSP (frame_size_history)) + frame_size_history_plain + (f, build_string ("VisibilityNotify, invisible")); + } + } goto OTHER; @@ -11918,11 +11952,6 @@ x_make_frame_invisible (struct frame *f) x_sync (f); - /* We can't distinguish this from iconification - just by the event that we get from the server. - So we can't win using the usual strategy of letting - FRAME_SAMPLE_VISIBILITY set this. So do it by hand, - and synchronize with the server to make sure we agree. */ SET_FRAME_VISIBLE (f, 0); SET_FRAME_ICONIFIED (f, false); @@ -11937,7 +11966,18 @@ x_make_frame_invisible (struct frame *f) x_make_frame_visible_invisible (struct frame *f, bool visible) { if (visible) +#if defined (USE_GTK) + if (FRAME_ICONIFIED_P (f)) + { + x_make_frame_visible (f); + x_make_frame_invisible (f); + x_make_frame_visible (f); + } + else x_make_frame_visible (f); +#else + x_make_frame_visible (f); +#endif else x_make_frame_invisible (f); }