aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2021-05-12 09:44:02 +0200
committerMartin Rudalics2021-05-12 09:44:02 +0200
commitb41f39d22cdb921fe88311f4fd113cbb9c2f0c76 (patch)
tree6bdb2ec7ead4dace5a00914a12b2b90e3a7921f9 /src
parent47070ed39eda524d334e5f82dc7f4a50b8d3252c (diff)
downloademacs-b41f39d22cdb921fe88311f4fd113cbb9c2f0c76.tar.gz
emacs-b41f39d22cdb921fe88311f4fd113cbb9c2f0c76.zip
Handle Bug#24526 without breaking Emacs on tiling WMs (Bug#48268)
Since tiling window managers may react allergically to resize requests immediately following MapNotify events on X, make sure that such requests are issued only when a new frame should not become visible and a size has been explicitly requested for it. * lisp/faces.el (x-create-frame-with-faces): Mark frame as 'was-invisible' if it should be initially invisible or iconified and has its size specified explicitly. * src/frame.c (make_frame): Initialize new frame's was_invisible flag. (Fframe__set_was_invisible): New internal function. * src/frame.h (struct frame): Specify size of new_size_p slot. New flag was_invisible. * src/w32fns.c (Fx_create_frame) * src/nsfns.m (Fx_create_frame) * src/xfns.c (Fx_create_frame): Set new frame's was_invisible flag. * src/xterm.c (handle_one_xevent): Call xg_frame_set_char_size after a PropertyNotify or MapNotify event only if F's was_invisible flag was set.
Diffstat (limited to 'src')
-rw-r--r--src/frame.c13
-rw-r--r--src/frame.h6
-rw-r--r--src/nsfns.m1
-rw-r--r--src/w32fns.c2
-rw-r--r--src/xfns.c20
-rw-r--r--src/xterm.c16
6 files changed, 52 insertions, 6 deletions
diff --git a/src/frame.c b/src/frame.c
index cb9d4f52109..e3d65dd28f3 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -971,6 +971,7 @@ make_frame (bool mini_p)
971 f->no_accept_focus = false; 971 f->no_accept_focus = false;
972 f->z_group = z_group_none; 972 f->z_group = z_group_none;
973 f->tooltip = false; 973 f->tooltip = false;
974 f->was_invisible = false;
974 f->child_frame_border_width = -1; 975 f->child_frame_border_width = -1;
975 f->last_tab_bar_item = -1; 976 f->last_tab_bar_item = -1;
976#ifndef HAVE_EXT_TOOL_BAR 977#ifndef HAVE_EXT_TOOL_BAR
@@ -5855,7 +5856,18 @@ selected frame. This is useful when `make-pointer-invisible' is set. */)
5855 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt; 5856 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
5856} 5857}
5857 5858
5859DEFUN ("frame--set-was-invisible", Fframe__set_was_invisible,
5860 Sframe__set_was_invisible, 2, 2, 0,
5861 doc: /* Set FRAME's was-invisible flag if WAS-INVISIBLE is non-nil.
5862This function is for internal use only. */)
5863 (Lisp_Object frame, Lisp_Object was_invisible)
5864{
5865 struct frame *f = decode_live_frame (frame);
5858 5866
5867 f->was_invisible = !NILP (was_invisible);
5868
5869 return f->was_invisible ? Qt : Qnil;
5870}
5859 5871
5860/*********************************************************************** 5872/***********************************************************************
5861 Multimonitor data 5873 Multimonitor data
@@ -6495,6 +6507,7 @@ iconify the top level frame instead. */);
6495 defsubr (&Sframe_position); 6507 defsubr (&Sframe_position);
6496 defsubr (&Sset_frame_position); 6508 defsubr (&Sset_frame_position);
6497 defsubr (&Sframe_pointer_visible_p); 6509 defsubr (&Sframe_pointer_visible_p);
6510 defsubr (&Sframe__set_was_invisible);
6498 defsubr (&Sframe_window_state_change); 6511 defsubr (&Sframe_window_state_change);
6499 defsubr (&Sset_frame_window_state_change); 6512 defsubr (&Sset_frame_window_state_change);
6500 defsubr (&Sframe_scale_factor); 6513 defsubr (&Sframe_scale_factor);
diff --git a/src/frame.h b/src/frame.h
index 744b95e1e04..75a0b184c19 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -456,7 +456,11 @@ struct frame
456 /* True when new_width or new_height were set by change_frame_size, 456 /* True when new_width or new_height were set by change_frame_size,
457 false when they were set by adjust_frame_size internally or not 457 false when they were set by adjust_frame_size internally or not
458 set. */ 458 set. */
459 bool_bf new_size_p; 459 bool_bf new_size_p : 1;
460
461 /* True when frame was invisible before first MapNotify event. Used
462 in X builds only. */
463 bool_bf was_invisible : 1;
460 464
461 /* Bitfield area ends here. */ 465 /* Bitfield area ends here. */
462 466
diff --git a/src/nsfns.m b/src/nsfns.m
index 1f281f75fd4..d14f7b51eaf 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1404,6 +1404,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1404 else 1404 else
1405 { 1405 {
1406 /* Must have been Qnil. */ 1406 /* Must have been Qnil. */
1407 f->was_invisible = true;
1407 } 1408 }
1408 } 1409 }
1409 1410
diff --git a/src/w32fns.c b/src/w32fns.c
index 66baeaecbdb..e5edd62abbc 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6107,6 +6107,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
6107 6107
6108 if (!NILP (visibility)) 6108 if (!NILP (visibility))
6109 w32_make_frame_visible (f); 6109 w32_make_frame_visible (f);
6110 else
6111 f->was_invisible = true;
6110 } 6112 }
6111 6113
6112 store_frame_param (f, Qvisibility, visibility); 6114 store_frame_param (f, Qvisibility, visibility);
diff --git a/src/xfns.c b/src/xfns.c
index 782e0a483c4..e46616e6d66 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4127,12 +4127,21 @@ This function is an internal primitive--use `make-frame' instead. */)
4127 cannot control visibility, so don't try. */ 4127 cannot control visibility, so don't try. */
4128 if (!f->output_data.x->explicit_parent) 4128 if (!f->output_data.x->explicit_parent)
4129 { 4129 {
4130 /* When called from `x-create-frame-with-faces' visibility is
4131 always explicitly nil. */
4130 Lisp_Object visibility 4132 Lisp_Object visibility
4131 = gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0, 4133 = gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
4132 RES_TYPE_SYMBOL); 4134 RES_TYPE_SYMBOL);
4135 Lisp_Object height
4136 = gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4137 Lisp_Object width
4138 = gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4133 4139
4134 if (EQ (visibility, Qicon)) 4140 if (EQ (visibility, Qicon))
4135 x_iconify_frame (f); 4141 {
4142 f->was_invisible = true;
4143 x_iconify_frame (f);
4144 }
4136 else 4145 else
4137 { 4146 {
4138 if (EQ (visibility, Qunbound)) 4147 if (EQ (visibility, Qunbound))
@@ -4140,8 +4149,17 @@ This function is an internal primitive--use `make-frame' instead. */)
4140 4149
4141 if (!NILP (visibility)) 4150 if (!NILP (visibility))
4142 x_make_frame_visible (f); 4151 x_make_frame_visible (f);
4152 else
4153 f->was_invisible = true;
4143 } 4154 }
4144 4155
4156 /* Leave f->was_invisible true only if height or width were
4157 specified too. This takes effect only when we are not called
4158 from `x-create-frame-with-faces' (see above comment). */
4159 f->was_invisible
4160 = (f->was_invisible
4161 && (!EQ (height, Qunbound) || !EQ (width, Qunbound)));
4162
4145 store_frame_param (f, Qvisibility, visibility); 4163 store_frame_param (f, Qvisibility, visibility);
4146 } 4164 }
4147 4165
diff --git a/src/xterm.c b/src/xterm.c
index 9edaed9a34b..a663a0f1844 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8181,8 +8181,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8181#if defined USE_GTK && defined HAVE_GTK3 8181#if defined USE_GTK && defined HAVE_GTK3
8182 /* If GTK3 wants to impose some old size here (Bug#24526), 8182 /* If GTK3 wants to impose some old size here (Bug#24526),
8183 tell it that the current size is what we want. */ 8183 tell it that the current size is what we want. */
8184 xg_frame_set_char_size 8184 if (f->was_invisible)
8185 (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); 8185 {
8186 xg_frame_set_char_size
8187 (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
8188 f->was_invisible = false;
8189 }
8186#endif 8190#endif
8187 XSETFRAME (inev.ie.frame_or_window, f); 8191 XSETFRAME (inev.ie.frame_or_window, f);
8188 } 8192 }
@@ -8443,8 +8447,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8443#if defined USE_GTK && defined HAVE_GTK3 8447#if defined USE_GTK && defined HAVE_GTK3
8444 /* If GTK3 wants to impose some old size here (Bug#24526), 8448 /* If GTK3 wants to impose some old size here (Bug#24526),
8445 tell it that the current size is what we want. */ 8449 tell it that the current size is what we want. */
8446 xg_frame_set_char_size 8450 if (f->was_invisible)
8447 (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f)); 8451 {
8452 xg_frame_set_char_size
8453 (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
8454 f->was_invisible = false;
8455 }
8448#endif 8456#endif
8449 f->output_data.x->has_been_visible = true; 8457 f->output_data.x->has_been_visible = true;
8450 } 8458 }