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.
This commit is contained in:
parent
203ee33980
commit
483c5e953c
1 changed files with 50 additions and 24 deletions
74
src/xterm.c
74
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue