From: Martin Rudalics Date: Wed, 5 May 2021 08:26:32 +0000 (+0200) Subject: Fix two GTK3 event handling issues X-Git-Tag: emacs-28.0.90~2610 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=483c5e953c12a95382bef4a3b6769a680c32fe86;p=emacs.git Fix two GTK3 event handling issues * src/xterm.c (handle_one_xevent): For GTK3 PropertyNotify and MapNotify events explicitly request the stored frame sizes when the frame changes from iconified to a non-hidden state (Bug#24526). For Expose events do not change the frame's visibility or iconified state. For FocusIn events on GTK3 do not apply the fix for Bug#42655. The latter two changes are to avoid that plain invisible frames get reported as iconified. --- diff --git a/src/xterm.c b/src/xterm.c index 88a393cc6c2..9edaed9a34b 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -8178,6 +8178,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, f->output_data.x->has_been_visible = true; inev.ie.kind = DEICONIFY_EVENT; +#if defined USE_GTK && defined HAVE_GTK3 + /* If GTK3 wants to impose some old size here (Bug#24526), + tell it that the current size is what we want. */ + xg_frame_set_char_size + (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); +#endif XSETFRAME (inev.ie.frame_or_window, f); } else if (!not_hidden && !FRAME_ICONIFIED_P (f)) @@ -8232,33 +8238,36 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!FRAME_VISIBLE_P (f)) { block_input (); - SET_FRAME_VISIBLE (f, 1); - SET_FRAME_ICONIFIED (f, false); - if (FRAME_X_DOUBLE_BUFFERED_P (f)) + /* 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 + https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. */ +/** SET_FRAME_VISIBLE (f, 1); **/ +/** SET_FRAME_ICONIFIED (f, false); **/ + + if (FRAME_X_DOUBLE_BUFFERED_P (f)) font_drop_xrender_surfaces (f); f->output_data.x->has_been_visible = true; SET_FRAME_GARBAGED (f); unblock_input (); } else if (FRAME_GARBAGED_P (f)) - { + { #ifdef USE_GTK - /* Go around the back buffer and manually clear the - window the first time we show it. This way, we avoid - showing users the sanity-defying horror of whatever - GtkWindow is rendering beneath us. We've garbaged - the frame, so we'll redraw the whole thing on next - redisplay anyway. Yuck. */ - x_clear_area1 ( - FRAME_X_DISPLAY (f), - FRAME_X_WINDOW (f), - event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height, - 0); + /* Go around the back buffer and manually clear the + window the first time we show it. This way, we avoid + showing users the sanity-defying horror of whatever + GtkWindow is rendering beneath us. We've garbaged + the frame, so we'll redraw the whole thing on next + redisplay anyway. Yuck. */ + x_clear_area1 (FRAME_X_DISPLAY (f), + FRAME_X_WINDOW (f), + event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height, + 0); x_clear_under_internal_border (f); #endif - } - + } if (!FRAME_GARBAGED_P (f)) { @@ -8351,7 +8360,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, the frame was deleted. */ { bool visible = FRAME_VISIBLE_P (f); - /* While a frame is unmapped, display generation is + + /* While a frame is unmapped, display generation is disabled; you don't want to spend time updating a display that won't ever be seen. */ SET_FRAME_VISIBLE (f, 0); @@ -8426,11 +8436,20 @@ handle_one_xevent (struct x_display_info *dpyinfo, x_set_z_group (f, Qbelow, Qnil); } - SET_FRAME_VISIBLE (f, 1); - SET_FRAME_ICONIFIED (f, false); - f->output_data.x->has_been_visible = true; + if (not_hidden) + { + SET_FRAME_VISIBLE (f, 1); + SET_FRAME_ICONIFIED (f, false); +#if defined USE_GTK && defined HAVE_GTK3 + /* If GTK3 wants to impose some old size here (Bug#24526), + tell it that the current size is what we want. */ + xg_frame_set_char_size + (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); +#endif + f->output_data.x->has_been_visible = true; + } - if (iconified) + if (not_hidden && iconified) { inev.ie.kind = DEICONIFY_EVENT; XSETFRAME (inev.ie.frame_or_window, f); @@ -8808,10 +8827,16 @@ 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 deconizing a window (Bug42655). */ + 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. */ f = any; if (f && FRAME_ICONIFIED_P (f)) { @@ -8821,6 +8846,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, 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;