emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master b41f39d: Handle Bug#24526 without breaking Emacs on tiling WMs (B


From: Martin Rudalics
Subject: master b41f39d: Handle Bug#24526 without breaking Emacs on tiling WMs (Bug#48268)
Date: Wed, 12 May 2021 03:45:26 -0400 (EDT)

branch: master
commit b41f39d22cdb921fe88311f4fd113cbb9c2f0c76
Author: Martin Rudalics <rudalics@gmx.at>
Commit: Martin Rudalics <rudalics@gmx.at>

    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.
---
 lisp/faces.el | 18 +++++++++++++++++-
 src/frame.c   | 13 +++++++++++++
 src/frame.h   |  6 +++++-
 src/nsfns.m   |  1 +
 src/w32fns.c  |  2 ++
 src/xfns.c    | 20 +++++++++++++++++++-
 src/xterm.c   | 16 ++++++++++++----
 7 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/lisp/faces.el b/lisp/faces.el
index 68bfbba..9969140 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2118,7 +2118,23 @@ the X resource \"reverseVideo\" is present, handle that."
          (x-handle-reverse-video frame parameters)
          (frame-set-background-mode frame t)
          (face-set-after-frame-default frame parameters)
-         (if (null visibility-spec)
+          ;; Mark frame as 'was-invisible' when it was created as
+          ;; invisible or iconified and PARAMETERS contains either a
+          ;; width or height specification.  This should be sufficient
+          ;; to handle Bug#24526 (where a frame is initially iconified
+          ;; to allow manipulating its size in a non-obtrusive way) and
+          ;; avoid that a tiling window manager for GTK3 gets a resize
+          ;; request it cannot handle (Bug#48268).  The 'was-invisible'
+          ;; flag is eventually processed in xterm.c after we receive a
+          ;; MapNotify event; non-X builds ignore it.
+          (frame--set-was-invisible
+           frame
+           (and visibility-spec
+                (memq (cdr visibility-spec) '(nil icon))
+                (or (assq 'width parameters)
+                    (assq 'height parameters))))
+
+          (if (null visibility-spec)
              (make-frame-visible frame)
            (modify-frame-parameters frame (list visibility-spec)))
          (setq success t))
diff --git a/src/frame.c b/src/frame.c
index cb9d4f5..e3d65dd 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -971,6 +971,7 @@ make_frame (bool mini_p)
   f->no_accept_focus = false;
   f->z_group = z_group_none;
   f->tooltip = false;
+  f->was_invisible = false;
   f->child_frame_border_width = -1;
   f->last_tab_bar_item = -1;
 #ifndef HAVE_EXT_TOOL_BAR
@@ -5855,7 +5856,18 @@ selected frame.  This is useful when 
`make-pointer-invisible' is set.  */)
   return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
 }
 
+DEFUN ("frame--set-was-invisible", Fframe__set_was_invisible,
+       Sframe__set_was_invisible, 2, 2, 0,
+       doc: /* Set FRAME's was-invisible flag if WAS-INVISIBLE is non-nil.
+This function is for internal use only.  */)
+  (Lisp_Object frame, Lisp_Object was_invisible)
+{
+  struct frame *f = decode_live_frame (frame);
 
+  f->was_invisible = !NILP (was_invisible);
+
+  return f->was_invisible ? Qt : Qnil;
+}
 
 /***********************************************************************
                        Multimonitor data
@@ -6495,6 +6507,7 @@ iconify the top level frame instead.  */);
   defsubr (&Sframe_position);
   defsubr (&Sset_frame_position);
   defsubr (&Sframe_pointer_visible_p);
+  defsubr (&Sframe__set_was_invisible);
   defsubr (&Sframe_window_state_change);
   defsubr (&Sset_frame_window_state_change);
   defsubr (&Sframe_scale_factor);
diff --git a/src/frame.h b/src/frame.h
index 744b95e..75a0b18 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -456,7 +456,11 @@ struct frame
   /* True when new_width or new_height were set by change_frame_size,
      false when they were set by adjust_frame_size internally or not
      set.  */
-  bool_bf new_size_p;
+  bool_bf new_size_p : 1;
+
+  /* True when frame was invisible before first MapNotify event.  Used
+     in X builds only.  */
+  bool_bf was_invisible : 1;
 
   /* Bitfield area ends here.  */
 
diff --git a/src/nsfns.m b/src/nsfns.m
index 1f281f7..d14f7b5 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1404,6 +1404,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
       else
         {
          /* Must have been Qnil.  */
+         f->was_invisible = true;
         }
     }
 
diff --git a/src/w32fns.c b/src/w32fns.c
index 66baeae..e5edd62 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6107,6 +6107,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
          if (!NILP (visibility))
            w32_make_frame_visible (f);
+         else
+           f->was_invisible = true;
        }
 
       store_frame_param (f, Qvisibility, visibility);
diff --git a/src/xfns.c b/src/xfns.c
index 782e0a4..e46616e 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4127,12 +4127,21 @@ This function is an internal primitive--use 
`make-frame' instead.  */)
      cannot control visibility, so don't try.  */
   if (!f->output_data.x->explicit_parent)
     {
+      /* When called from `x-create-frame-with-faces' visibility is
+        always explicitly nil.  */
       Lisp_Object visibility
        = gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
                                RES_TYPE_SYMBOL);
+      Lisp_Object height
+       = gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
+      Lisp_Object width
+       = gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
 
       if (EQ (visibility, Qicon))
-       x_iconify_frame (f);
+       {
+         f->was_invisible = true;
+         x_iconify_frame (f);
+       }
       else
        {
          if (EQ (visibility, Qunbound))
@@ -4140,8 +4149,17 @@ This function is an internal primitive--use `make-frame' 
instead.  */)
 
          if (!NILP (visibility))
            x_make_frame_visible (f);
+         else
+           f->was_invisible = true;
        }
 
+      /* Leave f->was_invisible true only if height or width were
+        specified too.  This takes effect only when we are not called
+        from `x-create-frame-with-faces' (see above comment).  */
+      f->was_invisible
+       = (f->was_invisible
+          && (!EQ (height, Qunbound) || !EQ (width, Qunbound)));
+
       store_frame_param (f, Qvisibility, visibility);
     }
 
diff --git a/src/xterm.c b/src/xterm.c
index 9edaed9..a663a0f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8181,8 +8181,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #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));
+             if (f->was_invisible)
+               {
+                 xg_frame_set_char_size
+                   (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+                 f->was_invisible = false;
+               }
 #endif
              XSETFRAME (inev.ie.frame_or_window, f);
            }
@@ -8443,8 +8447,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #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));
+             if (f->was_invisible)
+               {
+                 xg_frame_set_char_size
+                   (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+                 f->was_invisible = false;
+               }
 #endif
              f->output_data.x->has_been_visible = true;
            }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]