[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;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master b41f39d: Handle Bug#24526 without breaking Emacs on tiling WMs (Bug#48268),
Martin Rudalics <=