diff --git a/lisp/window.el b/lisp/window.el index a11293d372..706c988b2e 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -10596,6 +10596,21 @@ window-prefix-map "0" #'delete-windows-on) (define-key ctl-x-map "w" window-prefix-map) +(defun foo-it (&rest rest) + (with-current-buffer (get-buffer-create "*foo*") + (goto-char (point-max)) + (when rest + (if (consp (car rest)) + (insert (format "%sx%s" (caar rest) (cdar rest))) + (insert (format "%s" (car rest)))) + (setq rest (cdr rest)) + (while rest + (if (consp (car rest)) + (insert (format " %sx%s" (caar rest) (cdar rest))) + (insert (format " %s" (car rest)))) + (setq rest (cdr rest))) + (insert "\n")))) + (provide 'window) ;;; window.el ends here diff --git a/src/frame.c b/src/frame.c index b57b296be5..d7d069d908 100644 --- a/src/frame.c +++ b/src/frame.c @@ -906,6 +906,32 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height, unblock_input (); + if (old_native_width != new_native_width + || old_native_height != new_native_height + || old_text_width != new_text_width + || old_text_height != new_text_height + || old_text_cols != new_text_cols + || old_text_lines != new_text_lines) + CALLN (Ffuncall, Qfoo_it, intern ("adjust_frame_size"), + intern ("old native pixels"), + Fcons (make_fixnum (old_native_width), + make_fixnum (old_native_height)), + intern ("new native pixels"), + Fcons (make_fixnum (new_native_width), + make_fixnum (new_native_height)), + intern ("old text pixels"), + Fcons (make_fixnum (old_text_width), + make_fixnum (old_text_height)), + intern ("new text pixels"), + Fcons (make_fixnum (new_text_width), + make_fixnum (new_text_height)), + intern ("old text chars"), + Fcons (make_fixnum (old_text_cols), + make_fixnum (old_text_lines)), + intern ("new text chars"), + Fcons (make_fixnum (new_text_cols), + make_fixnum (new_text_lines))); + #ifdef HAVE_WINDOW_SYSTEM { /* Adjust size of F's child frames. */ diff --git a/src/gtkutil.c b/src/gtkutil.c index a6bba096a4..00ece49bad 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1149,6 +1149,14 @@ xg_frame_resized (struct frame *f, int width, int height) f->new_size_p ? f->new_height : -1); FRAME_RIF (f)->clear_under_internal_border (f); + + CALLN (Ffuncall, Qfoo_it, intern ("xg_frame_resized"), + intern ("old native pixels"), + Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)), + make_fixnum (FRAME_PIXEL_HEIGHT (f))), + intern ("new native pixels"), + Fcons (make_fixnum (width), make_fixnum (height))); + change_frame_size (f, width, height, false, true, false); SET_FRAME_GARBAGED (f); cancel_mouse_face (f); @@ -1174,6 +1182,8 @@ xg_frame_set_char_size (struct frame *f, int width, int height) int outer_width = width + FRAME_TOOLBAR_WIDTH (f); bool was_visible = false; bool hide_child_frame; + int scale = xg_get_scale (f); + GdkGeometry size_hints = f->output_data.xp->size_hints; #ifndef HAVE_PGTK gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), @@ -1196,10 +1206,42 @@ xg_frame_set_char_size (struct frame *f, int width, int height) /* Do this before resize, as we don't know yet if we will be resized. */ FRAME_RIF (f)->clear_under_internal_border (f); - outer_height /= xg_get_scale (f); - outer_width /= xg_get_scale (f); + if (scale != 1 && !frame_resize_pixelwise + /* Don't bother the WM when the number of text columns or text + lines wouldn't change and only the pixel sizes would. But make + sure first that these sizes are "out of synch" due to a + preceding "imprecise by scaling" operation like a mouse drag. + Otherwise, we might end up with a frame that doesn't get a + suitable initial size. */ + && (FRAME_PIXEL_TO_TEXT_WIDTH (f, width) / FRAME_COLS (f) + == FRAME_TEXT_WIDTH (f) / FRAME_COLS (f)) + && FRAME_TEXT_WIDTH (f) != FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f) + && (FRAME_PIXEL_TO_TEXT_HEIGHT (f, height) / FRAME_LINES (f) + == FRAME_TEXT_HEIGHT (f) / FRAME_LINES (f)) + && FRAME_TEXT_HEIGHT (f) != FRAME_LINES (f) * FRAME_LINE_HEIGHT (f)) + { + CALLN (Ffuncall, Qfoo_it, intern ("xg_frame_set_char_size_return"), + intern ("char size"), + Fcons (make_fixnum (FRAME_COLUMN_WIDTH (f)), + make_fixnum (FRAME_LINE_HEIGHT (f))), + intern ("text columns/lines"), + Fcons (make_fixnum (FRAME_COLS (f)), + make_fixnum (FRAME_LINES (f))), + intern ("pixels to text width/height"), + Fcons (make_fixnum (FRAME_PIXEL_TO_TEXT_WIDTH (f, width)), + make_fixnum (FRAME_PIXEL_TO_TEXT_HEIGHT (f, height))), + intern ("text width/height"), + Fcons (make_fixnum (FRAME_TEXT_WIDTH (f)), + make_fixnum (FRAME_TEXT_HEIGHT (f)))); + + return; + } + + outer_height /= scale; + outer_width /= scale; - xg_wm_set_size_hint (f, 0, 0); + xg_wm_set_size_hint (f, 0, 0, FRAME_PIXEL_TO_TEXT_WIDTH (f, width), + FRAME_PIXEL_TO_TEXT_HEIGHT (f, height)); /* Resize the top level widget so rows and columns remain constant. @@ -1317,6 +1359,33 @@ xg_frame_set_char_size (struct frame *f, int width, int height) SET_FRAME_GARBAGED (f); cancel_mouse_face (f); + size_hints = f->output_data.xp->size_hints; + if (outer_width > 0 && size_hints.base_width > 0 + && size_hints.width_inc > 0 && outer_height > 0 + && size_hints.base_height > 0 && size_hints.height_inc > 0) + CALLN (Ffuncall, Qfoo_it, intern ("xg_frame_set_char_size"), + intern ("old native pixels"), + Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)), + make_fixnum (FRAME_PIXEL_HEIGHT (f))), + intern ("new native pixels"), + Fcons (make_fixnum (width), make_fixnum (height)), + intern ("outer pixels"), + Fcons (make_fixnum (outer_width), make_fixnum (outer_height)), + intern ("outer rest"), + Fcons (make_fixnum ((outer_width - size_hints.base_width) + % size_hints.width_inc), + make_fixnum ((outer_height - size_hints.base_height) + % size_hints.height_inc))); + else + CALLN (Ffuncall, Qfoo_it, intern ("xg_frame_set_char_size"), + intern ("old native pixels"), + Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)), + make_fixnum (FRAME_PIXEL_HEIGHT (f))), + intern ("new native pixels"), + Fcons (make_fixnum (width), make_fixnum (height)), + intern ("outer pixels"), + Fcons (make_fixnum (outer_width), make_fixnum (outer_height))); + /* We can not call change_frame_size for a mapped frame, we can not set pixel width/height either. The window manager may override our resize request, XMonad does this all the time. @@ -1360,21 +1429,6 @@ xg_frame_set_char_size (struct frame *f, int width, int height) } } -/* Handle height/width changes (i.e. add/remove/move menu/toolbar). - The policy is to keep the number of editable lines. */ - -#if 0 -static void -xg_height_or_width_changed (struct frame *f) -{ - gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - FRAME_TOTAL_PIXEL_WIDTH (f), - FRAME_TOTAL_PIXEL_HEIGHT (f)); - f->output_data.xp->hint_flags = 0; - x_wm_set_size_hint (f, 0, 0); -} -#endif - #ifndef HAVE_PGTK /* Convert an X Window WSESC on display DPY to its corresponding GtkWidget. Must be done like this, because GtkWidget:s can have "hidden" @@ -1917,7 +1971,8 @@ xg_free_frame_widgets (struct frame *f) flag (this is useful when FLAGS is 0). */ void -xg_wm_set_size_hint (struct frame *f, long int flags, bool user_position) +xg_wm_set_size_hint (struct frame *f, long int flags, bool user_position, + int text_width, int text_height) { /* Must use GTK routines here, otherwise GTK resets the size hints to its own defaults. */ @@ -1964,21 +2019,33 @@ xg_wm_set_size_hint (struct frame *f, long int flags, bool user_position) hint_flags = f->output_data.xp->hint_flags; hint_flags |= GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE; - size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f); - size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f); + size_hints.width_inc + = frame_resize_pixelwise ? 1 : (FRAME_COLUMN_WIDTH (f) / scale); + size_hints.height_inc + = frame_resize_pixelwise ? 1 : (FRAME_LINE_HEIGHT (f) / scale); hint_flags |= GDK_HINT_BASE_SIZE; /* Use one row/col here so base_height/width does not become zero. Gtk+ and/or Unity on Ubuntu 12.04 can't handle it. Obviously this makes the row/col value displayed off by 1. */ - base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 1) + FRAME_TOOLBAR_WIDTH (f); - base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1) - + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); + base_width = ((FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 1) + + FRAME_TOOLBAR_WIDTH (f)) / scale); + base_height = ((FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1) + + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) + / scale); + + if (text_width < 0) + text_width = FRAME_TEXT_WIDTH (f); + text_width /= scale; + + if (text_height < 0) + text_height = FRAME_TEXT_HEIGHT (f); + text_height /= scale; - size_hints.base_width = base_width; - size_hints.base_height = base_height; - size_hints.min_width = base_width; - size_hints.min_height = base_height; + size_hints.base_width = base_width + (text_width % size_hints.width_inc); + size_hints.base_height = base_height + (text_height % size_hints.height_inc); + size_hints.min_width = size_hints.base_width; + size_hints.min_height = size_hints.base_height; /* These currently have a one to one mapping with the X values, but I don't think we should rely on that. */ @@ -2018,16 +2085,31 @@ xg_wm_set_size_hint (struct frame *f, long int flags, bool user_position) hint_flags |= GDK_HINT_USER_POS; } - size_hints.base_width /= scale; - size_hints.base_height /= scale; - size_hints.width_inc /= scale; - size_hints.height_inc /= scale; - if (hint_flags != f->output_data.xp->hint_flags || memcmp (&size_hints, &f->output_data.xp->size_hints, sizeof (size_hints)) != 0) { + CALLN (Ffuncall, Qfoo_it, intern ("xg_wm_set_size_hint"), + intern ("scale"), make_fixnum (scale), + intern ("char width"), make_fixnum (FRAME_COLUMN_WIDTH (f)), + intern ("toolbar"), make_fixnum (FRAME_TOOLBAR_WIDTH (f)), + intern ("vscroll"), make_fixnum (FRAME_SCROLL_BAR_AREA_WIDTH (f)), + intern ("fringes"), make_fixnum (FRAME_TOTAL_FRINGE_WIDTH (f)), + intern ("borders"), make_fixnum (2 * FRAME_INTERNAL_BORDER_WIDTH (f)), + intern ("text width"), make_fixnum (text_width), + intern ("base width"), make_fixnum (size_hints.base_width), + intern ("width inc"), make_fixnum (size_hints.width_inc)); + CALLN (Ffuncall, Qfoo_it, intern (" "), + intern ("char height"), make_fixnum (FRAME_LINE_HEIGHT (f)), + intern ("menubar"), make_fixnum (FRAME_MENUBAR_HEIGHT (f)), + intern ("toolbar"), make_fixnum (FRAME_TOOLBAR_HEIGHT (f)), + intern ("hscroll"), make_fixnum (FRAME_SCROLL_BAR_AREA_HEIGHT (f)), + intern ("borders"), make_fixnum (2 * FRAME_INTERNAL_BORDER_WIDTH (f)), + intern ("text height"), make_fixnum (text_height), + intern ("base height"), make_fixnum (size_hints.base_height), + intern ("height inc"), make_fixnum (size_hints.height_inc)); + block_input (); gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL, &size_hints, hint_flags); diff --git a/src/gtkutil.h b/src/gtkutil.h index 190d662831..21245dde5f 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h @@ -153,7 +153,7 @@ #define XG_ITEM_DATA "emacs_menuitem" extern int xg_get_default_scrollbar_width (struct frame *f); extern int xg_get_default_scrollbar_height (struct frame *f); -extern void xg_wm_set_size_hint (struct frame *, long int, bool); +extern void xg_wm_set_size_hint (struct frame *, long int, bool, int, int); extern void update_frame_tool_bar (struct frame *f); extern void free_frame_tool_bar (struct frame *f); diff --git a/src/pgtkfns.c b/src/pgtkfns.c index a32067af81..a391541e10 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -1662,7 +1662,8 @@ #define INSTALL_CURSOR(FIELD, NAME) \ badly we want them. This should be done after we have the menu bar so that its size can be taken into account. */ block_input (); - xg_wm_set_size_hint (f, window_prompting, false); + xg_wm_set_size_hint (f, window_prompting, false, + FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f)); unblock_input (); adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 13f6c6c3c4..8b077be178 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -658,7 +658,7 @@ pgtk_set_offset (struct frame *f, int xoff, int yoff, int change_gravity) pgtk_calc_absolute_position (f); block_input (); - xg_wm_set_size_hint (f, 0, false); + xg_wm_set_size_hint (f, 0, false, -1, -1); if (change_gravity != 0) { @@ -705,7 +705,8 @@ pgtk_set_window_size (struct frame *f, bool change_gravity, f->output_data.pgtk->preferred_width = pixelwidth; f->output_data.pgtk->preferred_height = pixelheight; - xg_wm_set_size_hint (f, 0, 0); + xg_wm_set_size_hint (f, 0, 0, FRAME_PIXEL_TO_TEXT_WIDTH (pixelwidth), + FRAME_PIXEL_TO_TEXT_HEIGHT (pixelheight)); xg_frame_set_char_size (f, pixelwidth, pixelheight); gtk_widget_queue_resize (FRAME_WIDGET (f)); @@ -993,7 +994,10 @@ pgtk_set_parent_frame (struct frame *f, Lisp_Object new_value, fixed, TRUE, TRUE, 0); f->output_data.pgtk->preferred_width = alloc.width; f->output_data.pgtk->preferred_height = alloc.height; - xg_wm_set_size_hint (f, 0, 0); + xg_wm_set_size_hint (f, 0, 0, FRAME_PIXEL_TO_TEXT_WIDTH (alloc.width), + FRAME_PIXEL_TO_TEXT_HEIGHT (alloc.height)); + /* Why convert here? xg_frame_set_char_size wants native + pixels. */ xg_frame_set_char_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, alloc.width), FRAME_PIXEL_TO_TEXT_HEIGHT (f, alloc.height)); gtk_widget_queue_resize (FRAME_WIDGET (f)); diff --git a/src/widget.c b/src/widget.c index aaab33b6d8..7468bf63fc 100644 --- a/src/widget.c +++ b/src/widget.c @@ -32,6 +32,7 @@ #include "sysstdio.h" #include "xterm.h" #include "frame.h" +#include "blockinput.h" #include #include @@ -154,15 +155,6 @@ emacsFrameClass (void) return (WidgetClass) &emacsFrameClassRec; } -static void -get_default_char_pixel_size (EmacsFrame ew, int *pixel_width, int *pixel_height) -{ - struct frame *f = ew->emacs_frame.frame; - - *pixel_width = FRAME_COLUMN_WIDTH (f); - *pixel_height = FRAME_LINE_HEIGHT (f); -} - static void pixel_to_char_size (EmacsFrame ew, Dimension pixel_width, Dimension pixel_height, int *char_width, int *char_height) @@ -207,120 +199,97 @@ get_wm_shell (Widget w) return (WMShellWidget) wmshell; } -#if 0 /* Currently not used. */ - -static void -mark_shell_size_user_specified (Widget wmshell) -{ - if (! XtIsWMShell (wmshell)) emacs_abort (); - /* This is kind of sleazy, but I can't see how else to tell it to make it - mark the WM_SIZE_HINTS size as user specified when appropriate. */ - ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize; -} - -#endif - - static void set_frame_size (EmacsFrame ew) { - /* The widget hierarchy is - - argv[0] emacsShell pane Frame-NAME - ApplicationShell EmacsShell Paned EmacsFrame - - We accept geometry specs in this order: - - *Frame-NAME.geometry - *EmacsFrame.geometry - Emacs.geometry - - Other possibilities for widget hierarchies might be - - argv[0] frame pane Frame-NAME - ApplicationShell EmacsShell Paned EmacsFrame - or - argv[0] Frame-NAME pane Frame-NAME - ApplicationShell EmacsShell Paned EmacsFrame - or - argv[0] Frame-NAME pane emacsTextPane - ApplicationShell EmacsFrame Paned EmacsTextPane - - With the current setup, the text-display-area is the part which is - an emacs "frame", since that's the only part managed by emacs proper - (the menubar and the parent of the menubar and all that sort of thing - are managed by lwlib.) - - The EmacsShell widget is simply a replacement for the Shell widget - which is able to deal with using an externally-supplied window instead - of always creating its own. It is not actually emacs specific, and - should possibly have class "Shell" instead of "EmacsShell" to simplify - the resources. - - */ - struct frame *f = ew->emacs_frame.frame; ew->core.width = FRAME_PIXEL_WIDTH (f); ew->core.height = FRAME_PIXEL_HEIGHT (f); - if (CONSP (frame_size_history)) - frame_size_history_plain - (f, build_string ("set_frame_size")); + CALLN (Ffuncall, Qfoo_it, build_string ("set_frame_size"), + build_string ("native pixels"), + Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)), + make_fixnum (FRAME_PIXEL_HEIGHT (f)))); } static bool -update_wm_hints (WMShellWidget wmshell, EmacsFrame ew) +update_wm_hints (WMShellWidget wmshell, EmacsFrame ew, int width, int height) { - int cw; - int ch; - Dimension rounded_width; - Dimension rounded_height; - int char_width; - int char_height; - int base_width; - int base_height; - char buffer[sizeof wmshell->wm.size_hints]; - char *hints_ptr; - - /* Copy the old size hints to the buffer. */ - memcpy (buffer, &wmshell->wm.size_hints, - sizeof wmshell->wm.size_hints); - - pixel_to_char_size (ew, ew->core.width, ew->core.height, - &char_width, &char_height); - char_to_pixel_size (ew, char_width, char_height, - &rounded_width, &rounded_height); - get_default_char_pixel_size (ew, &cw, &ch); - - base_width = (wmshell->core.width - ew->core.width - + (rounded_width - (char_width * cw))); - base_height = (wmshell->core.height - ew->core.height - + (rounded_height - (char_height * ch))); + struct frame *f = ew->emacs_frame.frame; + int char_width = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f); + int char_height = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f); + int base_width + = (FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 1) + + (((width < 0) ? FRAME_TEXT_WIDTH (f) : width) % char_width)); + int base_height + = (FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1) + + FRAME_MENUBAR_HEIGHT (f) + + (((height < 0) ? FRAME_TEXT_HEIGHT (f) : height) % char_height)); + int min_width = base_width; + int min_height = base_height; + bool value; + + int old_base_width, old_base_height; + int old_char_width, old_char_height; + int old_min_width, old_min_height; + + block_input (); + XtVaGetValues ((Widget) wmshell, + XtNbaseWidth, &old_base_width, + XtNbaseHeight, &old_base_height, + XtNwidthInc, &old_char_width, + XtNheightInc, &old_char_height, + XtNminWidth, &old_min_width, + XtNminHeight, &old_min_height, + NULL); + unblock_input (); XtVaSetValues ((Widget) wmshell, XtNbaseWidth, (XtArgVal) base_width, XtNbaseHeight, (XtArgVal) base_height, - XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw), - XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch), - XtNminWidth, (XtArgVal) base_width, - XtNminHeight, (XtArgVal) base_height, + XtNwidthInc, (XtArgVal) char_width, + XtNheightInc, (XtArgVal) char_height, + XtNminWidth, (XtArgVal) min_width, + XtNminHeight, (XtArgVal) min_height, NULL); - /* Return if size hints really changed. If they did not, then Xt - probably didn't set them either (or take the flags into - account.) */ - hints_ptr = (char *) &wmshell->wm.size_hints; + value = (base_width != old_base_width || base_height != old_base_height + || char_width != old_char_width || char_height != old_char_height + || min_width != old_min_width || min_height != old_min_height); - /* Skip flags, which is unsigned long. */ - return memcmp (hints_ptr + sizeof (long), buffer + sizeof (long), - sizeof wmshell->wm.wm_hints - sizeof (long)); + if (value) + { + CALLN (Ffuncall, Qfoo_it, build_string ("update_wm_hints"), + build_string ("char width"), make_fixnum (FRAME_COLUMN_WIDTH (f)), + build_string ("old char width"), make_fixnum (old_char_width), + build_string ("vscroll"), make_fixnum (FRAME_SCROLL_BAR_AREA_WIDTH (f)), + build_string ("fringes"), make_fixnum (FRAME_TOTAL_FRINGE_WIDTH (f)), + build_string ("borders"), make_fixnum (2 * FRAME_INTERNAL_BORDER_WIDTH (f)), + build_string ("base width"), make_fixnum (base_width), + build_string ("old_base width"), make_fixnum (old_base_width), + build_string ("min width"), make_fixnum (min_width), + build_string ("old min width"), make_fixnum (old_min_width)); + CALLN (Ffuncall, Qfoo_it, build_string (" "), + build_string ("char height"), make_fixnum (FRAME_LINE_HEIGHT (f)), + build_string ("old char height"), make_fixnum (old_char_height), + build_string ("menubar"), make_fixnum (FRAME_MENUBAR_HEIGHT (f)), + build_string ("hscroll"), make_fixnum (FRAME_SCROLL_BAR_AREA_HEIGHT (f)), + build_string ("borders"), make_fixnum (2 * FRAME_INTERNAL_BORDER_WIDTH (f)), + build_string ("base height"), make_fixnum (base_height), + build_string ("old base height"), make_fixnum (old_base_height), + build_string ("min height"), make_fixnum (min_height), + build_string ("old min height"), make_fixnum (old_min_height)); + } + + return value; } bool -widget_update_wm_size_hints (Widget widget, Widget frame) +widget_update_wm_size_hints (Widget widget, Widget frame, int width, int height) { - return update_wm_hints ((WMShellWidget) widget, (EmacsFrame) frame); + return update_wm_hints ((WMShellWidget) widget, (EmacsFrame) frame, + width, height); } static void @@ -337,7 +306,7 @@ update_from_various_frame_slots (EmacsFrame ew) struct frame *f = ew->emacs_frame.frame; struct x_output *x = f->output_data.x; - ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height; + ew->core.height = FRAME_PIXEL_HEIGHT (f); // - x->menubar_height; ew->core.width = FRAME_PIXEL_WIDTH (f); ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f); ew->emacs_frame.internal_border_width = f->internal_border_width; @@ -345,12 +314,11 @@ update_from_various_frame_slots (EmacsFrame ew) ew->emacs_frame.cursor_color = x->cursor_pixel; ew->core.border_pixel = x->border_pixel; - if (CONSP (frame_size_history)) - frame_size_history_extra - (f, build_string ("update_from_various_frame_slots"), - FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), - ew->core.width, ew->core.height, - f->new_width, f->new_height); + CALLN (Ffuncall, Qfoo_it, + build_string ("update_from_various_frame_slots"), + build_string ("native pixels"), + (Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)), + make_fixnum (FRAME_PIXEL_HEIGHT (f))))); } static void @@ -384,7 +352,6 @@ EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs) { EmacsFrame ew = (EmacsFrame) widget; - struct frame *f = ew->emacs_frame.frame; /* This used to contain SubstructureRedirectMask, but this turns out to be a problem with XIM on Solaris, and events from that mask @@ -399,12 +366,8 @@ EmacsFrameRealize (Widget widget, XtValueMask *mask, make sure we get them all. Seen with xfcwm4 for example. */ XtAddRawEventHandler (widget, StructureNotifyMask, False, resize_cb, NULL); - if (CONSP (frame_size_history)) - frame_size_history_plain - (f, build_string ("EmacsFrameRealize")); - if (get_wm_shell (widget)) - update_wm_hints (get_wm_shell (widget), ew); + update_wm_hints (get_wm_shell (widget), ew, -1, -1); } static void @@ -419,18 +382,23 @@ EmacsFrameResize (Widget widget) EmacsFrame ew = (EmacsFrame) widget; struct frame *f = ew->emacs_frame.frame; - if (CONSP (frame_size_history)) - frame_size_history_extra - (f, build_string ("EmacsFrameResize"), - FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), - ew->core.width, ew->core.height, - f->new_width, f->new_height); + if (FRAME_PIXEL_WIDTH (f) != ew->core.width + || FRAME_PIXEL_HEIGHT (f) != ew->core.height) + CALLN (Ffuncall, Qfoo_it, build_string ("EmacsFrameResize"), + build_string ("old native pixels"), + Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)), + make_fixnum (FRAME_PIXEL_HEIGHT (f))), + build_string ("new native pixels"), + Fcons (make_fixnum (ew->core.width), + make_fixnum (ew->core.height))); change_frame_size (f, ew->core.width, ew->core.height, false, true, false); if (get_wm_shell (widget)) - update_wm_hints (get_wm_shell (widget), ew); + update_wm_hints (get_wm_shell (widget), ew, + FRAME_PIXEL_TO_TEXT_WIDTH (f, ew->core.width), + FRAME_PIXEL_TO_TEXT_HEIGHT (f, ew->core.height)); update_various_frame_slots (ew); cancel_mouse_face (f); @@ -472,13 +440,6 @@ EmacsFrameSetCharSize (Widget widget, int columns, int rows) EmacsFrame ew = (EmacsFrame) widget; struct frame *f = ew->emacs_frame.frame; - if (CONSP (frame_size_history)) - frame_size_history_extra - (f, build_string ("EmacsFrameSetCharSize"), - FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), - columns, rows, - f->new_width, f->new_height); - if (!frame_inhibit_resize (f, 0, Qfont) && !frame_inhibit_resize (f, 1, Qfont)) x_set_window_size (f, 0, columns * FRAME_COLUMN_WIDTH (f), diff --git a/src/widget.h b/src/widget.h index cf83cb1078..03bc809c41 100644 --- a/src/widget.h +++ b/src/widget.h @@ -97,6 +97,6 @@ #define XtCInitialGeometry "InitialGeometry" /* Special entry points */ void EmacsFrameSetCharSize (Widget, int, int); void widget_store_internal_border (Widget widget); -bool widget_update_wm_size_hints (Widget widget, Widget frame); +bool widget_update_wm_size_hints (Widget widget, Widget frame, int width, int height); #endif /* _EmacsFrame_h */ diff --git a/src/window.c b/src/window.c index f116b9a9d7..c090f29461 100644 --- a/src/window.c +++ b/src/window.c @@ -8394,6 +8394,7 @@ syms_of_window (void) DEFSYM (Qheader_line_format, "header-line-format"); DEFSYM (Qtab_line_format, "tab-line-format"); DEFSYM (Qno_other_window, "no-other-window"); + DEFSYM (Qfoo_it, "foo-it"); DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function, doc: /* Non-nil means call as function to display a help buffer. diff --git a/src/xfns.c b/src/xfns.c index 36b51a3011..25e1af279d 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4575,7 +4575,7 @@ DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint, struct frame *f = decode_window_system_frame (frame); block_input (); - x_wm_set_size_hint (f, 0, false); + x_wm_set_size_hint (f, 0, false, -1, -1); unblock_input (); return Qnil; } @@ -5097,7 +5097,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, badly we want them. This should be done after we have the menu bar so that its size can be taken into account. */ block_input (); - x_wm_set_size_hint (f, window_prompting, false); + x_wm_set_size_hint (f, window_prompting, false, + FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f)); unblock_input (); adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), diff --git a/src/xterm.c b/src/xterm.c index 7eaf59d54b..b1d65ce59d 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -26160,6 +26160,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) { struct font *font = XFONT_OBJECT (font_object); int unit, font_ascent, font_descent; + int old_width = FRAME_COLUMN_WIDTH (f); + int old_height = FRAME_LINE_HEIGHT (f); if (fontset < 0) fontset = fontset_from_font (font_object); @@ -26197,9 +26199,27 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) because it's done in Fx_show_tip, and it leads to problems because the tip frame has no widget. */ if (FRAME_X_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f)) - adjust_frame_size - (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), - FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont); + { + CALLN (Ffuncall, Qfoo_it, intern ("\nx_new_font"), + intern ("old char size"), + Fcons (make_fixnum (old_width), make_fixnum (old_height)), + intern ("new char size"), + Fcons (make_fixnum (FRAME_COLUMN_WIDTH (f)), + make_fixnum (FRAME_LINE_HEIGHT (f))), + intern ("text chars"), + Fcons (make_fixnum (FRAME_COLS (f)), + make_fixnum (FRAME_LINES (f))), + intern ("old text pixels"), + Fcons (make_fixnum (FRAME_TEXT_WIDTH (f)), + make_fixnum (FRAME_TEXT_HEIGHT (f))), + intern ("new text pixels"), + Fcons (make_fixnum (FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f)), + make_fixnum (FRAME_LINES (f) * FRAME_LINE_HEIGHT (f)))); + + adjust_frame_size + (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont); + } #ifdef HAVE_X_I18N if (FRAME_XIC (f) @@ -26589,7 +26609,7 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity) x_calc_absolute_position (f); block_input (); - x_wm_set_size_hint (f, 0, false); + x_wm_set_size_hint (f, 0, false, -1, -1); #ifdef USE_GTK if (x_gtk_use_window_move) @@ -27279,7 +27299,7 @@ x_check_fullscreen (struct frame *f) emacs_abort (); } - x_wm_set_size_hint (f, 0, false); + x_wm_set_size_hint (f, 0, false, -1, -1); XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), width, height); @@ -27453,7 +27473,8 @@ x_set_window_size_1 (struct frame *f, bool change_gravity, { if (change_gravity) f->win_gravity = NorthWestGravity; - x_wm_set_size_hint (f, 0, false); + x_wm_set_size_hint (f, 0, false, FRAME_PIXEL_TO_TEXT_WIDTH (f, width), + FRAME_PIXEL_TO_TEXT_HEIGHT (f, height)); XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), width, height + FRAME_MENUBAR_HEIGHT (f)); @@ -28243,7 +28264,7 @@ x_make_frame_invisible (struct frame *f) program-specified, so that when the window is mapped again, it will be placed at the same location, without forcing the user to position it by hand again (they have already done that once for this window.) */ - x_wm_set_size_hint (f, 0, true); + x_wm_set_size_hint (f, 0, true, -1, -1); #ifdef USE_GTK if (FRAME_GTK_OUTER_WIDGET (f)) @@ -28896,7 +28917,8 @@ x_embed_frame (struct x_display_info *dpyinfo, struct frame *f) The GTK version is in gtkutils.c. */ void -x_wm_set_size_hint (struct frame *f, long flags, bool user_position) +x_wm_set_size_hint (struct frame *f, long flags, bool user_position, + int width, int height) { #ifndef USE_GTK XSizeHints size_hints; @@ -28935,10 +28957,12 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) #ifndef USE_MOTIF hints_changed = widget_update_wm_size_hints (f->output_data.x->widget, - f->output_data.x->edit_widget); + f->output_data.x->edit_widget, + width, height); #else widget_update_wm_size_hints (f->output_data.x->widget, - f->output_data.x->edit_widget); + f->output_data.x->edit_widget, + width, height); /* Do this all over again for the benefit of Motif, which always knows better than the programmer. */ @@ -29012,8 +29036,16 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) { int base_width, base_height; - base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); - base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); + if (width == -1) + width = FRAME_TEXT_WIDTH (f); + + if (height == -1) + height = FRAME_TEXT_HEIGHT (f); + + base_width = (FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0) + + width % FRAME_COLUMN_WIDTH (f)); + base_height = (FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0) + + height % FRAME_LINE_HEIGHT (f)); /* The window manager uses the base width hints to calculate the current number of rows and columns in the frame while @@ -29075,7 +29107,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position) XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints); #else - xg_wm_set_size_hint (f, flags, user_position); + xg_wm_set_size_hint (f, flags, user_position, width, height); #endif /* USE_GTK */ } diff --git a/src/xterm.h b/src/xterm.h index ee429e9c68..61512f1117 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1653,7 +1653,7 @@ #define SELECTION_EVENT_TIME(eventp) \ extern void x_make_frame_invisible (struct frame *); extern void x_iconify_frame (struct frame *); extern void x_free_frame_resources (struct frame *); -extern void x_wm_set_size_hint (struct frame *, long, bool); +extern void x_wm_set_size_hint (struct frame *, long, bool, int, int); #if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK \ && defined HAVE_CLOCK_GETTIME extern void x_sync_init_fences (struct frame *);