summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGlenn Morris <rgm@gnu.org>2020-04-11 07:50:12 -0700
committerGlenn Morris <rgm@gnu.org>2020-04-11 07:50:12 -0700
commit1988ffbaed709dfc71126efbf06644476830f07e (patch)
treefdc98855a3ab7bf6d6cb4c8826ec4a9dfc603d33 /src
parentb902d7c9d07b2cc951fa5c789d585d65366d19d2 (diff)
parentfd27685c1e68e742abf1698573dac53743f15e48 (diff)
Merge from origin/emacs-27
fd27685c1e (origin/emacs-27) ; * doc/lispref/keymaps.texi (Extended M... 6057d79a4e * doc/lispref/keymaps.texi (Extended Menu Items): Tweak :k... 17a1bb5a03 Fix redisplay when scrolling under redisplay-dont-pause 90321f595c Fix face extension in pulse.el 36c42d2a30 * doc/misc/tramp.texi (Bug Reports): Avoid line breaks in ... d5750af151 Avoid assertion violation in intervals.c 18d1bc0a09 Improve documentation of 'jit-lock-contextually' 08486f4cae Speed up 'resize-mode' child frames a little f451ef9308 ; * etc/NEWS: Mention 'executing-macro' in removed vars. c49d379f17 Fix some problems with moving and resizing child frames # Conflicts: # etc/NEWS
Diffstat (limited to 'src')
-rw-r--r--src/dispnew.c4
-rw-r--r--src/frame.c1
-rw-r--r--src/gtkutil.c41
-rw-r--r--src/intervals.c2
-rw-r--r--src/xfns.c56
-rw-r--r--src/xterm.c37
6 files changed, 118 insertions, 23 deletions
diff --git a/src/dispnew.c b/src/dispnew.c
index d79ae836c56..5b6fa51a563 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3683,6 +3683,10 @@ update_window (struct window *w, bool force_p)
W->output_cursor doesn't contain the cursor location. */
gui_update_window_end (w, !paused_p, mouse_face_overwritten_p);
#endif
+ /* If the update wasn't interrupted, this window has been
+ completely updated. */
+ if (!paused_p)
+ w->must_be_updated_p = false;
}
else
paused_p = 1;
diff --git a/src/frame.c b/src/frame.c
index 884de2f5349..c871e4fd994 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -5930,6 +5930,7 @@ syms_of_frame (void)
DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1");
DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2");
DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3");
+ DEFSYM (Qxg_frame_set_char_size_4, "xg-frame-set-char-size-4");
DEFSYM (Qx_set_window_size_1, "x-set-window-size-1");
DEFSYM (Qx_set_window_size_2, "x-set-window-size-2");
DEFSYM (Qx_set_window_size_3, "x-set-window-size-3");
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 338c6036c2c..681f86f51ba 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -941,9 +941,8 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
}
}
-/* Resize the outer window of frame F after changing the height.
- COLUMNS/ROWS is the size the edit area shall have after the resize. */
-
+/** Resize the outer window of frame F. WIDTH and HEIGHT are the new
+ pixel sizes of F's text area. */
void
xg_frame_set_char_size (struct frame *f, int width, int height)
{
@@ -954,6 +953,8 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
int totalheight
= pixelheight + FRAME_TOOLBAR_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
int totalwidth = pixelwidth + FRAME_TOOLBAR_WIDTH (f);
+ bool was_visible = false;
+ bool hide_child_frame;
if (FRAME_PIXEL_HEIGHT (f) == 0)
return;
@@ -996,12 +997,42 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
totalwidth, gheight);
}
+ else if (FRAME_PARENT_FRAME (f) && FRAME_VISIBLE_P (f))
+ {
+ was_visible = true;
+ hide_child_frame = EQ (x_gtk_resize_child_frames, Qhide);
+
+ if (totalwidth != gwidth || totalheight != gheight)
+ {
+ frame_size_history_add
+ (f, Qxg_frame_set_char_size_4, width, height,
+ list2i (totalwidth, totalheight));
+
+ if (hide_child_frame)
+ {
+ block_input ();
+ gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
+ unblock_input ();
+ }
+
+ gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ totalwidth, totalheight);
+
+ if (hide_child_frame)
+ {
+ block_input ();
+ gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+ unblock_input ();
+ }
+
+ fullscreen = Qnil;
+ }
+ }
else
{
frame_size_history_add
(f, Qxg_frame_set_char_size_3, width, height,
list2i (totalwidth, totalheight));
-
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
totalwidth, totalheight);
fullscreen = Qnil;
@@ -1017,7 +1048,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
size as fast as possible.
For unmapped windows, we can set rows/cols. When
the frame is mapped again we will (hopefully) get the correct size. */
- if (FRAME_VISIBLE_P (f))
+ if (FRAME_VISIBLE_P (f) && !was_visible)
{
/* Must call this to flush out events */
(void)gtk_events_pending ();
diff --git a/src/intervals.c b/src/intervals.c
index 594d8924ebc..d4a734c923c 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -1187,7 +1187,7 @@ delete_interval (register INTERVAL i)
register INTERVAL parent;
ptrdiff_t amt = LENGTH (i);
- eassert (amt == 0); /* Only used on zero-length intervals now. */
+ eassert (amt <= 0); /* Only used on zero total-length intervals now. */
if (ROOT_INTERVAL_P (i))
{
diff --git a/src/xfns.c b/src/xfns.c
index ebe51b70a56..10e1b5e58c2 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -861,6 +861,12 @@ x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
(FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
p ? FRAME_X_WINDOW (p) : DefaultRootWindow (FRAME_X_DISPLAY (f)),
f->left_pos, f->top_pos);
+#ifdef USE_GTK
+ if (EQ (x_gtk_resize_child_frames, Qresize_mode))
+ gtk_container_set_resize_mode
+ (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)),
+ p ? GTK_RESIZE_IMMEDIATE : GTK_RESIZE_QUEUE);
+#endif
unblock_input ();
fset_parent_frame (f, new_value);
@@ -4078,6 +4084,11 @@ This function is an internal primitive--use `make-frame' instead. */)
block_input ();
XReparentWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
FRAME_X_WINDOW (p), f->left_pos, f->top_pos);
+#ifdef USE_GTK
+ if (EQ (x_gtk_resize_child_frames, Qresize_mode))
+ gtk_container_set_resize_mode
+ (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)), GTK_RESIZE_IMMEDIATE);
+#endif
unblock_input ();
}
@@ -7734,6 +7745,22 @@ Note: Text drawn with the `x' font backend is shown with hollow boxes. */)
#endif /* USE_GTK */
#endif /* USE_CAIRO */
+#ifdef USE_GTK
+#ifdef HAVE_GTK3
+DEFUN ("x-gtk-debug", Fx_gtk_debug, Sx_gtk_debug, 1, 1, 0,
+ doc: /* Toggle interactive GTK debugging. */)
+ (Lisp_Object enable)
+{
+ gboolean enable_debug = !NILP (enable);
+
+ block_input ();
+ gtk_window_set_interactive_debugging (enable_debug);
+ unblock_input ();
+
+ return NILP (enable) ? Qnil : Qt;
+}
+#endif /* HAVE_GTK3 */
+#endif /* USE_GTK */
/***********************************************************************
Initialization
@@ -7802,6 +7829,8 @@ syms_of_xfns (void)
DEFSYM (Qfont_parameter, "font-parameter");
DEFSYM (Qmono, "mono");
DEFSYM (Qassq_delete_all, "assq-delete-all");
+ DEFSYM (Qhide, "hide");
+ DEFSYM (Qresize_mode, "resize-mode");
#ifdef USE_CAIRO
DEFSYM (Qpdf, "pdf");
@@ -7978,6 +8007,28 @@ Otherwise use Emacs own tooltip implementation.
When using Gtk+ tooltips, the tooltip face is not used. */);
x_gtk_use_system_tooltips = true;
+ DEFVAR_LISP ("x-gtk-resize-child-frames", x_gtk_resize_child_frames,
+ doc: /* If non-nil, resize child frames specially with GTK builds.
+If this is nil, resize child frames like any other frames. This is the
+default and usually works with most desktops. Some desktop environments
+(GNOME shell in particular when using the mutter window manager),
+however, may refuse to resize a child frame when Emacs is built with
+GTK3. For those environments, the two settings below are provided.
+
+If this equals the symbol 'hide', Emacs temporarily hides the child
+frame during resizing. This approach seems to work reliably, may
+however induce some flicker when the frame is made visible again.
+
+If this equals the symbol 'resize-mode', Emacs uses GTK's resize mode to
+always trigger an immediate resize of the child frame. This method is
+deprecated by GTK and may not work in future versions of that toolkit.
+It also may freeze Emacs when used with other desktop environments. It
+avoids, however, the unpleasent flicker induced by the hiding approach.
+
+This variable is considered a temporary workaround and will be hopefully
+eliminated in future versions of Emacs. */);
+ x_gtk_resize_child_frames = Qnil;
+
/* Tell Emacs about this window system. */
Fprovide (Qx, Qnil);
@@ -8093,4 +8144,9 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
defsubr (&Sx_print_frames_dialog);
#endif
#endif
+#ifdef USE_GTK
+#ifdef HAVE_GTK3
+ defsubr (&Sx_gtk_debug);
+#endif
+#endif
}
diff --git a/src/xterm.c b/src/xterm.c
index bd9688fda81..ae5dad92897 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10613,26 +10613,29 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
modified_left, modified_top);
#endif
- x_sync_with_move (f, f->left_pos, f->top_pos,
- FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
+ /* 'x_sync_with_move' is too costly for dragging child frames. */
+ if (!FRAME_PARENT_FRAME (f))
+ {
+ x_sync_with_move (f, f->left_pos, f->top_pos,
+ FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
- /* change_gravity is non-zero when this function is called from Lisp to
- programmatically move a frame. In that case, we call
- x_check_expected_move to discover if we have a "Type A" or "Type B"
- window manager, and, for a "Type A" window manager, adjust the position
- of the frame.
+ /* change_gravity is non-zero when this function is called from Lisp to
+ programmatically move a frame. In that case, we call
+ x_check_expected_move to discover if we have a "Type A" or "Type B"
+ window manager, and, for a "Type A" window manager, adjust the position
+ of the frame.
- We call x_check_expected_move if a programmatic move occurred, and
- either the window manager type (A/B) is unknown or it is Type A but we
- need to compute the top/left offset adjustment for this frame. */
+ We call x_check_expected_move if a programmatic move occurred, and
+ either the window manager type (A/B) is unknown or it is Type A but we
+ need to compute the top/left offset adjustment for this frame. */
- if (change_gravity != 0
- && !FRAME_PARENT_FRAME (f)
- && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
- || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
- && (FRAME_X_OUTPUT (f)->move_offset_left == 0
- && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
- x_check_expected_move (f, modified_left, modified_top);
+ if (change_gravity != 0
+ && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
+ || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
+ && (FRAME_X_OUTPUT (f)->move_offset_left == 0
+ && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
+ x_check_expected_move (f, modified_left, modified_top);
+ }
unblock_input ();
}