diff --git a/src/gtkutil.c b/src/gtkutil.c index d57627f152f..1496b761550 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1129,11 +1129,59 @@ xg_set_geometry (struct frame *f) } } +#ifndef HAVE_PGTK +static struct frame *last_resize_frame = NULL; +static int last_resize_height = -1; +static int last_resize_width = -1; +static bool last_resize_insist = false; +#endif + /** Function to handle resize of native frame F to WIDTH and HEIGHT pixels after we got a ConfigureNotify event. */ void xg_frame_resized (struct frame *f, int width, int height) { +#ifndef HAVE_PGTK + bool reject = false; + + if (last_resize_insist && f == last_resize_frame) + { + int expected_width = ((last_resize_width * xg_get_scale (f)) + - FRAME_TOOLBAR_WIDTH (f)); + int expected_height = ((last_resize_height * xg_get_scale (f)) + - FRAME_MENUBAR_HEIGHT (f) + - FRAME_TOOLBAR_HEIGHT (f)); + + /* Fuzzyness: Reject the new size if the deviation is more than + two pixels in either direction. */ + if (width > expected_width + 2 + || width < expected_width - 2 + || height > expected_height + 2 + || height < expected_height - 2) + /* We did not get what we wanted, retry. */ + { + if (CONSP (frame_size_history)) + frame_size_history_extra + (f, build_string ("xg_frame_resized, rejected"), + FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height, + last_resize_width, last_resize_height); + + /* Resend the previous request. */ + gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), + last_resize_width, last_resize_height); + reject = true; + } + + /* Reset the insistence values. */ + last_resize_frame = NULL; + last_resize_height = -1; + last_resize_width = -1; + last_resize_insist = false; + + if (reject) + return; + } +#endif /* Ignore case where size of native rectangle didn't change. */ if (width != FRAME_PIXEL_WIDTH (f) || height != FRAME_PIXEL_HEIGHT (f) @@ -1297,19 +1345,23 @@ xg_frame_set_char_size (struct frame *f, int width, int height) else { #ifndef HAVE_PGTK + if (x_gtk_insist_on_requested_size) + { + last_resize_frame = f; + last_resize_width = outer_width; + last_resize_height = outer_height; + last_resize_insist = true; + } + gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), outer_width, outer_height); #else if (FRAME_GTK_OUTER_WIDGET (f)) - { - gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - outer_width, outer_height); - } + gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), + outer_width, outer_height); else - { - gtk_widget_set_size_request (FRAME_GTK_WIDGET (f), - outer_width, outer_height); - } + gtk_widget_set_size_request (FRAME_GTK_WIDGET (f), + outer_width, outer_height); #endif fullscreen = Qnil; } diff --git a/src/xterm.c b/src/xterm.c index 0c20d38b0f7..00dc976e2ff 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -32762,6 +32762,23 @@ syms_of_xterm (void) always uses gtk_window_move and ignores the value of this variable. */); x_gtk_use_window_move = true; +#if defined USE_GTK && !defined HAVE_PGTK + DEFVAR_BOOL ("x-gtk-insist-on-requested-size", x_gtk_insist_on_requested_size, + doc: /* Non-nil means try harder to obtain requested size for new frames. +If this variable is non-nil, a GTK build on X will reject once a frame +size it is offered that does not match the one previously requested by +Emacs. Rather, Emacs will reissue the previous request to size the +frame. If this variable is nil, Emacs will accept any frame size it is +offered. + +Setting this to a non-nil value can be necessary when running on a GNOME +desktop with the mutter window manager under GTK3. These may offer +Emacs a much smaller frame size for the initial as well as for any +additional frames. For the initial frame it will be necessary to set +this in the `early-init.el' file. */); + x_gtk_insist_on_requested_size = false; +#endif + DEFVAR_LISP ("x-scroll-event-delta-factor", Vx_scroll_event_delta_factor, doc: /* A scale to apply to pixel deltas reported in scroll events. This option is only effective when Emacs is built with XInput 2