diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 59 | ||||
-rw-r--r-- | src/dispnew.c | 2 | ||||
-rw-r--r-- | src/frame.c | 160 | ||||
-rw-r--r-- | src/frame.h | 9 | ||||
-rw-r--r-- | src/gtkutil.c | 26 | ||||
-rw-r--r-- | src/nsfns.m | 6 | ||||
-rw-r--r-- | src/w32fns.c | 181 | ||||
-rw-r--r-- | src/w32menu.c | 2 | ||||
-rw-r--r-- | src/w32term.c | 2 | ||||
-rw-r--r-- | src/widget.c | 3 | ||||
-rw-r--r-- | src/window.c | 2 | ||||
-rw-r--r-- | src/xfns.c | 150 | ||||
-rw-r--r-- | src/xmenu.c | 37 | ||||
-rw-r--r-- | src/xterm.c | 5 |
14 files changed, 524 insertions, 120 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 6b62a60f7b0..c46d23dd82e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,62 @@ +2014-11-07 Martin Rudalics <rudalics@gmx.at> + + * dispnew.c (change_frame_size_1): Fix call of + adjust_frame_size. + * frame.c (Qsize, Qframe_position, Qframe_outer_size) + (Qframe_inner_size, Qexternal_border_size, Qtitle_height) + (Qmenu_bar_external, Qmenu_bar_size, Qtool_bar_external) + (Qtool_bar_size): New constants. + (frame_inhibit_resize, adjust_frame_size): New argument to + handle case where frame_inhibit_implied_resize is a list. + (Fmake_terminal_frame, Fset_frame_height, Fset_frame_width) + (Fset_frame_size, x_set_left_fringe, x_set_right_fringe) + (x_set_right_divider_width, x_set_bottom_divider_width) + (x_set_vertical_scroll_bars, x_set_horizontal_scroll_bars) + (x_set_scroll_bar_width, x_set_scroll_bar_height): Update + callers. + (frame-inhibit-implied-resize): Rewrite doc-string. + * frame.h (frame_inhibit_resize, adjust_frame_size): Fix + external declarations. + (Qframe_position, Qframe_outer_size) + (Qframe_inner_size, Qexternal_border_size, Qtitle_height) + (Qmenu_bar_external, Qmenu_bar_size, Qtool_bar_external) + (Qtool_bar_size): Extern them. + * gtkutil.c (FRAME_TOTAL_PIXEL_HEIGHT, FRAME_TOTAL_PIXEL_WIDTH) + (xg_height_or_width_changed): Remove. + (xg_frame_set_char_size): Adjust adjust_frame_size calls. + (menubar_map_cb, xg_update_frame_menubar, free_frame_menubar) + (tb_size_cb, update_frame_tool_bar, free_frame_tool_bar) + (xg_change_toolbar_position): Call adjust_frame_size directly. + * nsfns.m (x_set_internal_border_width, Fx_create_frame): Fix + calls of adjust_frame_size. + * w32fns.c (x_set_internal_border_width, x_set_menu_bar_lines) + (Fx_create_frame, x_create_tip_frame): Adjust adjust_frame_size + calls. + (x_set_tool_bar_lines, x_change_tool_bar_height): Make sure that + frame can get resized when tool-bar-lines parameter changes from + or to zero. + (Fw32_frame_menu_bar_size): Return fourth value. + (Fw32_frame_rect): Block input around system calls + (Fx_frame_geometry): New function. + * w32menu.c (set_frame_menubar): Adjust adjust_frame_size call. + * w32term.c (x_new_font): Adjust adjust_frame_size call. + * widget.c (EmacsFrameSetCharSize): Adjust frame_inhibit_resize + call. + * window.c (Fset_window_configuration): Adjust adjust_frame_size + call. + * xfns.c (x_set_menu_bar_lines, x_set_internal_border_width) + (Fx_create_frame): Adjust adjust_frame_size calls. + (x_set_tool_bar_lines, x_change_tool_bar_height): Make sure that + frame can get resized when tool-bar-lines parameter changes from + or to zero. + (Fx_frame_geometry): New function. + * xmenu.c (update_frame_menubar): On Lucid call + adjust_frame_size with one pixel less height to avoid that + repeatedly adding/removing the menu bar grows the frame. + (free_frame_menubar): On Motif arrange to optionally preserve + the old frame height when removing the menu bar. + * xterm.c (x_new_font): Adjust adjust_frame_size call. + 2014-11-03 Eli Zaretskii <eliz@gnu.org> * xdisp.c (Fdump_glyph_matrix, Fdump_frame_glyph_matrix): Doc fix. diff --git a/src/dispnew.c b/src/dispnew.c index 900912d9d97..d50d06f2d47 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5528,7 +5528,7 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height, /* Adjust frame size but make sure x_set_window_size does not get called. */ - adjust_frame_size (f, new_width, new_height, 5, pretend); + adjust_frame_size (f, new_width, new_height, 5, pretend, Qnil); } } diff --git a/src/frame.c b/src/frame.c index d1acb73b926..5bb2c831c20 100644 --- a/src/frame.c +++ b/src/frame.c @@ -77,7 +77,7 @@ Lisp_Object Qterminal; Lisp_Object Qauto_raise, Qauto_lower; Lisp_Object Qborder_color, Qborder_width; Lisp_Object Qcursor_color, Qcursor_type; -Lisp_Object Qheight, Qwidth; +Lisp_Object Qheight, Qwidth, Qsize; Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name; Lisp_Object Qtooltip; Lisp_Object Qinternal_border_width; @@ -120,6 +120,11 @@ static Lisp_Object Qdelete_frame_functions; static Lisp_Object Qframe_windows_min_size; static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource; +Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size; +Lisp_Object Qexternal_border_size, Qtitle_height; +Lisp_Object Qmenu_bar_external, Qmenu_bar_size; +Lisp_Object Qtool_bar_external, Qtool_bar_size; + /* The currently selected frame. */ Lisp_Object selected_frame; @@ -209,12 +214,14 @@ get_frame_param (register struct frame *frame, Lisp_Object prop) /* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen state of frame F would be affected by a vertical (horizontal if - HORIZONTAL is true) resize. */ + HORIZONTAL is true) resize. PARAMETER is the symbol of the frame + parameter that is changed. */ bool -frame_inhibit_resize (struct frame *f, bool horizontal) +frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter) { - - return (frame_inhibit_implied_resize + return (EQ (frame_inhibit_implied_resize, Qt) + || (CONSP (frame_inhibit_implied_resize) + && !NILP (Fmemq (parameter, frame_inhibit_implied_resize))) || !NILP (get_frame_param (f, Qfullscreen)) || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); } @@ -337,40 +344,46 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object p /* Make sure windows sizes of frame F are OK. new_width and new_height are in pixels. A value of -1 means no change is requested for that size (but the frame may still have to be resized to accommodate - windows with their minimum sizes. + windows with their minimum sizes). This can either issue a request + to resize the frame externally (via x_set_window_size), to resize the + frame internally (via resize_frame_windows) or do nothing at all. The argument INHIBIT can assume the following values: 0 means to unconditionally call x_set_window_size even if sizes - apparently do not change. Fx_create_frame uses this to pass the - initial size to the window manager. + apparently do not change. Fx_create_frame uses this to pass the + initial size to the window manager. - 1 means to call x_set_window_size iff the pixel size really changes. - Fset_frame_size, Fset_frame_height, ... use this. + 1 means to call x_set_window_size if the outer frame size really + changes. Fset_frame_size, Fset_frame_height, ... use this. - 2 means to unconditionally call x_set_window_size provided - frame_inhibit_resize allows it. The menu bar code uses this. + 2 means to call x_set_window_size provided frame_inhibit_resize + allows it. The menu and tool bar code use this ("3" won't work + here in general because menu and tool bar are often not counted in + the frame's text height). - 3 means call x_set_window_size iff window minimum sizes must be - preserved or frame_inhibit_resize allows it, x_set_left_fringe, - x_set_scroll_bar_width, ... use this. + 3 means call x_set_window_size if window minimum sizes must be + preserved or frame_inhibit_resize allows it. x_set_left_fringe, + x_set_scroll_bar_width, x_new_font ... use (or should use) this. - 4 means call x_set_window_size iff window minimum sizes must be - preserved. x_set_tool_bar_lines, x_set_right_divider_width, ... use - this. BUT maybe the toolbar code shouldn't .... + 4 means call x_set_window_size only if window minimum sizes must be + preserved. x_set_right_divider_width, x_set_border_width and the + code responsible for wrapping the tool bar use this. 5 means to never call x_set_window_size. change_frame_size uses - this. + this. - For 2 and 3 note that if frame_inhibit_resize inhibits resizing and - minimum sizes are not violated no internal resizing takes place - either. For 2, 3, 4 and 5 note that even if no x_set_window_size - call is issued, window sizes may have to be adjusted in order to - support minimum size constraints for the frame's windows. + Note that even when x_set_window_size is not called, individual + windows may have to be resized (via `window--sanitize-window-sizes') + in order to support minimum size constraints. - PRETEND is as for change_frame_size. */ + PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the + symbol of the parameter changed (like `menu-bar-lines', `font', ...). + This is passed on to frame_inhibit_resize to let the latter decide on + a case-by-case basis whether the frame may be resized externally. */ void -adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, bool pretend) +adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, + bool pretend, Lisp_Object parameter) { int unit_width = FRAME_COLUMN_WIDTH (f); int unit_height = FRAME_LINE_HEIGHT (f); @@ -415,10 +428,12 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, so or INHIBIT equals 4. */ { inhibit_horizontal = ((windows_width >= min_windows_width - && (inhibit == 4 || frame_inhibit_resize (f, true))) + && (inhibit == 4 + || frame_inhibit_resize (f, true, parameter))) ? true : false); inhibit_vertical = ((windows_height >= min_windows_height - && (inhibit == 4 || frame_inhibit_resize (f, false))) + && (inhibit == 4 + || frame_inhibit_resize (f, false, parameter))) ? true : false); } else @@ -1004,7 +1019,7 @@ affects all frames on the same terminal device. */) { int width, height; get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height); - adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0); + adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0, Qnil); } adjust_frame_glyphs (f); @@ -2848,7 +2863,7 @@ multiple of the default frame font height. */) ? XINT (height) : XINT (height) * FRAME_LINE_HEIGHT (f)); if (pixel_height != FRAME_TEXT_HEIGHT (f)) - adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend)); + adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend), Qheight); return Qnil; } @@ -2874,7 +2889,7 @@ multiple of the default frame font width. */) ? XINT (width) : XINT (width) * FRAME_COLUMN_WIDTH (f)); if (pixel_width != FRAME_TEXT_WIDTH (f)) - adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend)); + adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend), Qwidth); return Qnil; } @@ -2903,7 +2918,7 @@ font height. */) if (pixel_width != FRAME_TEXT_WIDTH (f) || pixel_height != FRAME_TEXT_HEIGHT (f)) - adjust_frame_size (f, pixel_width, pixel_height, 1, 0); + adjust_frame_size (f, pixel_width, pixel_height, 1, 0, Qsize); return Qnil; } @@ -3627,7 +3642,7 @@ x_set_left_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value = (new_width + FRAME_RIGHT_FRINGE_WIDTH (f) + unit - 1) / unit; if (FRAME_X_WINDOW (f) != 0) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qleft_fringe); SET_FRAME_GARBAGED (f); } @@ -3651,7 +3666,7 @@ x_set_right_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu = (new_width + FRAME_LEFT_FRINGE_WIDTH (f) + unit - 1) / unit; if (FRAME_X_WINDOW (f) != 0) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qright_fringe); SET_FRAME_GARBAGED (f); } @@ -3683,7 +3698,7 @@ x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) FRAME_RIGHT_DIVIDER_WIDTH (f) = 0; if (FRAME_RIGHT_DIVIDER_WIDTH (f) != old) { - adjust_frame_size (f, -1, -1, 4, 0); + adjust_frame_size (f, -1, -1, 4, 0, Qright_divider_width); adjust_frame_glyphs (f); SET_FRAME_GARBAGED (f); } @@ -3701,7 +3716,7 @@ x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0; if (FRAME_BOTTOM_DIVIDER_WIDTH (f) != old) { - adjust_frame_size (f, -1, -1, 4, 0); + adjust_frame_size (f, -1, -1, 4, 0, Qbottom_divider_width); adjust_frame_glyphs (f); SET_FRAME_GARBAGED (f); } @@ -3765,7 +3780,7 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval However, if the window hasn't been created yet, we shouldn't call x_set_window_size. */ if (FRAME_X_WINDOW (f)) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qvertical_scroll_bars); SET_FRAME_GARBAGED (f); } @@ -3785,7 +3800,7 @@ x_set_horizontal_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldv However, if the window hasn't been created yet, we shouldn't call x_set_window_size. */ if (FRAME_X_WINDOW (f)) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qhorizontal_scroll_bars); SET_FRAME_GARBAGED (f); } @@ -3802,7 +3817,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) x_set_scroll_bar_default_width (f); if (FRAME_X_WINDOW (f)) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_width); SET_FRAME_GARBAGED (f); } @@ -3812,7 +3827,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg); FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit; if (FRAME_X_WINDOW (f)) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_width); SET_FRAME_GARBAGED (f); } @@ -3832,7 +3847,7 @@ x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval) x_set_scroll_bar_default_height (f); if (FRAME_X_WINDOW (f)) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_height); SET_FRAME_GARBAGED (f); } @@ -3842,7 +3857,7 @@ x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval) FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = XFASTINT (arg); FRAME_CONFIG_SCROLL_BAR_LINES (f) = (XFASTINT (arg) + unit - 1) / unit; if (FRAME_X_WINDOW (f)) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qscroll_bar_height); SET_FRAME_GARBAGED (f); } @@ -4785,12 +4800,21 @@ syms_of_frame (void) DEFSYM (Qterminal, "terminal"); - DEFSYM (Qgeometry, "geometry"); DEFSYM (Qworkarea, "workarea"); DEFSYM (Qmm_size, "mm-size"); DEFSYM (Qframes, "frames"); DEFSYM (Qsource, "source"); + DEFSYM (Qframe_position, "frame-position"); + DEFSYM (Qframe_outer_size, "frame-outer-size"); + DEFSYM (Qexternal_border_size, "external-border-size"); + DEFSYM (Qtitle_height, "title-height"); + DEFSYM (Qmenu_bar_external, "menu-bar-external"); + DEFSYM (Qmenu_bar_size, "menu-bar-size"); + DEFSYM (Qtool_bar_external, "tool-bar-external"); + DEFSYM (Qtool_bar_size, "tool-bar-size"); + DEFSYM (Qframe_inner_size, "frame-inner-size"); + #ifdef HAVE_NS DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); #endif @@ -4985,13 +5009,49 @@ fullscreen. To resize your initial frame pixelwise, set this option to a non-nil value in your init file. */); frame_resize_pixelwise = 0; - DEFVAR_BOOL ("frame-inhibit-implied-resize", frame_inhibit_implied_resize, - doc: /* Non-nil means do not resize frames implicitly. -If this option is nil, setting default font, menubar mode, fringe width, -or scroll bar mode of a specific frame may resize the frame in order to -preserve the number of columns or lines it displays. If this option is -non-nil, no such resizing is done. */); - frame_inhibit_implied_resize = 0; + DEFVAR_LISP ("frame-inhibit-implied-resize", frame_inhibit_implied_resize, + doc: /* Whether frames should be resized implicitly. +If this option is nil, setting font, menu bar, tool bar, internal +borders, fringes or scroll bars of a specific frame may resize the frame +in order to preserve the number of columns or lines it displays. If +this option is `t', no such resizing is done. Note that the size of +fullscreen and maximized frames, the height of fullheight frames and the +width of fullwidth frames never change implicitly. + +The value of this option can be also be a list of frame parameters. In +this case, resizing is inhibited when changing a parameter that appears +in that list. The parameters currently handled by this option include +`font', `font-backend', `internal-border-width', `menu-bar-lines' and +`tool-bar-lines'. + +Changing any of the parameters `scroll-bar-width', `scroll-bar-height', +`vertical-scroll-bars', `horizontal-scroll-bars', `left-fringe' and +`right-fringe' is handled as if the frame contained just one live +window. This means, for example, that removing vertical scroll bars on +a frame containing several side by side windows will shrink the frame +width by the width of one scroll bar provided this option is nil and +keep it unchanged if this option is either `t' or a list containing +`vertical-scroll-bars'. + +The default value is '(tool-bar-lines) on Lucid, Motif and Windows +(which means that adding/removing a tool bar does not change the frame +height), nil on all other window systems including GTK+ (which means +that changing any of the parameters listed above may change the size of +the frame), and `t' otherwise (which means the frame size never changes +implicitly when there's no window system support). + +Note that when a frame is not large enough to accommodate a change of +any of the parameters listed above, Emacs may try to enlarge the frame +even if this option is non-nil. */); +#if defined (HAVE_WINDOW_SYSTEM) +#if defined (USE_LUCID) || defined (USE_MOTIF) || defined (HAVE_NTGUI) + frame_inhibit_implied_resize = list1 (Qtool_bar_lines); +#else + frame_inhibit_implied_resize = Qnil; +#endif +#else + frame_inhibit_implied_resize = Qt; +#endif staticpro (&Vframe_list); diff --git a/src/frame.h b/src/frame.h index 22f2fa7a24c..b5d3bbb5b11 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1117,8 +1117,8 @@ extern void check_window_system (struct frame *); extern void frame_make_pointer_invisible (struct frame *); extern void frame_make_pointer_visible (struct frame *); extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object); -extern bool frame_inhibit_resize (struct frame *, bool); -extern void adjust_frame_size (struct frame *, int, int, int, bool); +extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object); +extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object); extern Lisp_Object Vframe_list; @@ -1380,6 +1380,11 @@ extern Lisp_Object Qx_resource_name; extern Lisp_Object Qtop, Qbox, Qbottom; extern Lisp_Object Qdisplay; +extern Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size; +extern Lisp_Object Qexternal_border_size, Qtitle_height; +extern Lisp_Object Qmenu_bar_external, Qmenu_bar_size; +extern Lisp_Object Qtool_bar_external, Qtool_bar_size; + extern Lisp_Object Qrun_hook_with_args; #ifdef HAVE_WINDOW_SYSTEM diff --git a/src/gtkutil.c b/src/gtkutil.c index 01360244c2e..6db8858923d 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -50,11 +50,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "emacsgtkfixed.h" #endif -#define FRAME_TOTAL_PIXEL_HEIGHT(f) \ - (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) +/** #define FRAME_TOTAL_PIXEL_HEIGHT(f) \ **/ +/** (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) **/ -#define FRAME_TOTAL_PIXEL_WIDTH(f) \ - (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f)) +/** #define FRAME_TOTAL_PIXEL_WIDTH(f) \ **/ +/** (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f)) **/ #ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW #define gtk_widget_set_has_window(w, b) \ @@ -940,12 +940,13 @@ xg_frame_set_char_size (struct frame *f, int width, int height) x_wait_for_event (f, ConfigureNotify); } else - adjust_frame_size (f, -1, -1, 5, 0); + adjust_frame_size (f, -1, -1, 5, 0, Qnil); } /* 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) { @@ -955,6 +956,7 @@ xg_height_or_width_changed (struct frame *f) f->output_data.x->hint_flags = 0; x_wm_set_size_hint (f, 0, 0); } +#endif /* Convert an X Window WSESC on display DPY to its corresponding GtkWidget. Must be done like this, because GtkWidget:s can have "hidden" @@ -3241,7 +3243,7 @@ menubar_map_cb (GtkWidget *w, gpointer user_data) if (FRAME_MENUBAR_HEIGHT (f) != req.height) { FRAME_MENUBAR_HEIGHT (f) = req.height; - xg_height_or_width_changed (f); + adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines); } } @@ -3273,7 +3275,7 @@ xg_update_frame_menubar (struct frame *f) if (FRAME_MENUBAR_HEIGHT (f) != req.height) { FRAME_MENUBAR_HEIGHT (f) = req.height; - xg_height_or_width_changed (f); + adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines); } unblock_input (); } @@ -3295,7 +3297,7 @@ free_frame_menubar (struct frame *f) the container. */ x->menubar_widget = 0; FRAME_MENUBAR_HEIGHT (f) = 0; - xg_height_or_width_changed (f); + adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines); unblock_input (); } } @@ -4219,7 +4221,7 @@ tb_size_cb (GtkWidget *widget, size hints if tool bar size changes. Seen on Fedora 18 at least. */ struct frame *f = user_data; if (xg_update_tool_bar_sizes (f)) - xg_height_or_width_changed (f); + adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); } /* Create a tool bar for frame F. */ @@ -4819,7 +4821,7 @@ update_frame_tool_bar (struct frame *f) xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f)); gtk_widget_show_all (x->toolbar_widget); if (xg_update_tool_bar_sizes (f)) - xg_height_or_width_changed (f); + adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); } unblock_input (); @@ -4867,7 +4869,7 @@ free_frame_tool_bar (struct frame *f) NULL); } - xg_height_or_width_changed (f); + adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); unblock_input (); } @@ -4897,7 +4899,7 @@ xg_change_toolbar_position (struct frame *f, Lisp_Object pos) xg_pack_tool_bar (f, pos); g_object_unref (top_widget); if (xg_update_tool_bar_sizes (f)) - xg_height_or_width_changed (f); + adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); unblock_input (); } diff --git a/src/nsfns.m b/src/nsfns.m index 1537adbc56d..16f4ba3b579 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -731,7 +731,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva return; if (FRAME_X_WINDOW (f) != 0) - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width); SET_FRAME_GARBAGED (f); } @@ -1275,7 +1275,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* Read comment about this code in corresponding place in xfns.c. */ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), - FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1); + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil); /* The resources controlling the menu-bar and tool-bar are processed specially at startup, and reflected in the mode @@ -1349,7 +1349,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* Consider frame official, now. */ f->official = true; - adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1); + adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil); if (! f->output_data.ns->explicit_parent) { diff --git a/src/w32fns.c b/src/w32fns.c index 829347b2c6c..95821df6c61 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1645,7 +1645,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva if (FRAME_X_WINDOW (f) != 0) { - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width); if (FRAME_VISIBLE_P (f)) x_clear_under_internal_border (f); @@ -1691,7 +1691,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) of the outer rectangle (including decorations) unchanged, and a second time because we want to keep the height of the inner rectangle (without the decorations unchanged). */ - adjust_frame_size (f, -1, -1, 2, 1); + adjust_frame_size (f, -1, -1, 2, 1, Qmenu_bar_lines); /* Not sure whether this is needed. */ x_clear_under_internal_border (f); @@ -1721,7 +1721,15 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) else nlines = 0; - x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); + if (nlines == 0) + x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); + else + { + f->n_tool_bar_rows = 0; + FRAME_TOOL_BAR_LINES (f) = nlines; + adjust_frame_glyphs (f); + SET_FRAME_GARBAGED (f); + } } @@ -1741,10 +1749,10 @@ x_change_tool_bar_height (struct frame *f, int height) /* Recalculate tool bar and frame text sizes. */ FRAME_TOOL_BAR_HEIGHT (f) = height; FRAME_TOOL_BAR_LINES (f) = lines; - FRAME_TEXT_HEIGHT (f) - = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); - FRAME_LINES (f) - = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); +/** FRAME_TEXT_HEIGHT (f) **/ +/** = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); **/ +/** FRAME_LINES (f) **/ +/** = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); **/ /* Store the `tool-bar-lines' and `height' frame parameters. */ store_frame_param (f, Qtool_bar_lines, make_number (lines)); store_frame_param (f, Qheight, make_number (FRAME_LINES (f))); @@ -1761,7 +1769,8 @@ x_change_tool_bar_height (struct frame *f, int height) /* Recalculate toolbar height. */ f->n_tool_bar_rows = 0; - adjust_frame_size (f, -1, -1, 4, 0); + adjust_frame_size (f, -1, -1, (old_height == 0 || height == 0) ? 2 : 4, 0, + Qtool_bar_lines); if (FRAME_X_WINDOW (f)) x_clear_under_internal_border (f); @@ -4629,7 +4638,7 @@ This function is an internal primitive--use `make-frame' instead. */) had one frame line vs one toolbar line which left us with a zero root window height which was obviously wrong as well ... */ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), - FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1); + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil); /* The X resources controlling the menu-bar and tool-bar are processed specially at startup, and reflected in the mode @@ -4697,7 +4706,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* Consider frame official, now. */ f->official = true; - adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1); + adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil); /* Tell the server what size and position, etc, we want, and how badly we want them. This should be done after we have the menu @@ -5797,7 +5806,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, SET_FRAME_COLS (f, 0); SET_FRAME_LINES (f, 0); adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f), - height * FRAME_LINE_HEIGHT (f), 0, 1); + height * FRAME_LINE_HEIGHT (f), 0, 1, Qnil); /* Add `tooltip' frame parameter's default value. */ if (NILP (Fframe_parameter (frame, Qtooltip))) @@ -7368,30 +7377,33 @@ This is a direct interface to the Windows API FindWindow function. */) DEFUN ("w32-frame-menu-bar-size", Fw32_frame_menu_bar_size, Sw32_frame_menu_bar_size, 0, 1, 0, doc: /* Return sizes of menu bar on frame FRAME. -The return value is a list of three elements: The current width and -height of FRAME's menu bar in pixels and the default height of the menu -bar in pixels. If FRAME is omitted or nil, the selected frame is -used. */) +The return value is a list of four elements: The current width and +height of FRAME's menu bar in pixels, the height of one menu bar line in +a wrapped menu bar in pixels, and the height of a single line menu bar +in pixels. + +If FRAME is omitted or nil, the selected frame is used. */) (Lisp_Object frame) { struct frame *f = decode_any_frame (frame); - MENUBARINFO info; - int width, height, default_height; + MENUBARINFO menu_bar; + int width, height, single_height, wrapped_height; block_input (); - default_height = GetSystemMetrics (SM_CYMENUSIZE); - info.cbSize = sizeof (info); - info.rcBar.right = info.rcBar.left = 0; - info.rcBar.top = info.rcBar.bottom = 0; - GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info); - width = info.rcBar.right - info.rcBar.left; - height = info.rcBar.bottom - info.rcBar.top; + single_height = GetSystemMetrics (SM_CYMENU); + wrapped_height = GetSystemMetrics (SM_CYMENUSIZE); + menu_bar.cbSize = sizeof (menu_bar); + menu_bar.rcBar.right = menu_bar.rcBar.left = 0; + menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0; + GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar); + width = menu_bar.rcBar.right - menu_bar.rcBar.left; + height = menu_bar.rcBar.bottom - menu_bar.rcBar.top; unblock_input (); - return list3 (make_number (width), make_number (height), - make_number (default_height)); + return list4 (make_number (width), make_number (height), + make_number (wrapped_height), make_number (single_height)); } DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0, @@ -7408,15 +7420,131 @@ title bar and decorations. */) struct frame *f = decode_live_frame (frame); RECT rect; + block_input (); + if (!NILP (client)) GetClientRect (FRAME_W32_WINDOW (f), &rect); else GetWindowRect (FRAME_W32_WINDOW (f), &rect); + unblock_input (); + return list4 (make_number (rect.left), make_number (rect.top), make_number (rect.right), make_number (rect.bottom)); } +DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0, + doc: /* Return geometric atributes of frame FRAME. +FRAME must be a live frame and defaults to the selected one. + +The return value is an association list containing the following +elements (all size values are in pixels). + +- `frame-outer-size' is a cons of the outer width and height of FRAME. + The outer size includes the title bar and the external borders as well + as any menu and/or tool bar of frame. + +- `border' is a cons of the horizontal and vertical width of FRAME's + external borders. + +- `title-bar-height' is the height of the title bar of FRAME. + +- `menu-bar-external' if `t' means the menu bar is by default external + (not included in the inner size of FRAME). + +- `menu-bar-size' is a cons of the width and height of the menu bar of + FRAME. + +- `tool-bar-external' if `t' means the tool bar is by default external + (not included in the inner size of FRAME). + +- `tool-bar-side' tells tells on which side the tool bar on FRAME is by + default and can be one of `left', `top', `right' or `bottom'. + +- `tool-bar-size' is a cons of the width and height of the tool bar of + FRAME. + +- `frame-inner-size' is a cons of the inner width and height of FRAME. + This excludes FRAME's title bar and external border as well as any + external menu and/or tool bar. */) + (Lisp_Object frame) +{ + struct frame *f = decode_live_frame (frame); + Lisp_Object geometry = Qnil; + RECT frame_outer_edges, frame_inner_edges; + MENUBARINFO menu_bar; + int border_width, border_height, title_height; + int single_bar_height, wrapped_bar_height, menu_bar_height; + Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen); + + block_input (); + + /* Outer frame rectangle, including outer borders and title bar. */ + GetWindowRect (FRAME_W32_WINDOW (f), &frame_outer_edges); + /* Inner frame rectangle, excluding borders and title bar. */ + GetClientRect (FRAME_W32_WINDOW (f), &frame_inner_edges); + /* Outer border. */ + border_width = GetSystemMetrics (SM_CXFRAME); + border_height = GetSystemMetrics (SM_CYFRAME); + /* Title bar. */ + title_height = GetSystemMetrics (SM_CYCAPTION); + /* Menu bar. */ + menu_bar.cbSize = sizeof (menu_bar); + menu_bar.rcBar.right = menu_bar.rcBar.left = 0; + menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0; + GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar); + single_bar_height = GetSystemMetrics (SM_CYMENU); + wrapped_bar_height = GetSystemMetrics (SM_CYMENUSIZE); + unblock_input (); + + menu_bar_height = menu_bar.rcBar.bottom - menu_bar.rcBar.top; + /* Fix menu bar height reported by GetMenuBarInfo. */ + if (menu_bar_height > single_bar_height) + /* A wrapped menu bar. */ + menu_bar_height += single_bar_height - wrapped_bar_height; + else if (menu_bar_height > 0) + /* A single line menu bar. */ + menu_bar_height = single_bar_height; + + return + listn (CONSTYPE_PURE, 10, + Fcons (Qframe_position, + Fcons (make_number (frame_outer_edges.left), + make_number (frame_outer_edges.top))), + Fcons (Qframe_outer_size, + Fcons (make_number + (frame_outer_edges.right - frame_outer_edges.left), + make_number + (frame_outer_edges.bottom - frame_outer_edges.top))), + Fcons (Qexternal_border_size, + ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen)) + ? Fcons (make_number (0), make_number (0)) + : Fcons (make_number (border_width), + make_number (border_height)))), + Fcons (Qtitle_height, + ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen)) + ? make_number (0) + : make_number (title_height))), + Fcons (Qmenu_bar_external, Qt), + Fcons (Qmenu_bar_size, + Fcons (make_number + (menu_bar.rcBar.right - menu_bar.rcBar.left), + make_number (menu_bar_height))), + Fcons (Qtool_bar_external, Qnil), + Fcons (Qtool_bar_position, Qtop), + Fcons (Qtool_bar_size, + Fcons (make_number (FRAME_TOOL_BAR_LINES (f) + ? (FRAME_PIXEL_WIDTH (f) + - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) + : 0), + make_number (FRAME_TOOL_BAR_HEIGHT (f)))), + Fcons (Qframe_inner_size, + Fcons (make_number + (frame_inner_edges.right - frame_inner_edges.left), + make_number + (frame_inner_edges.bottom - frame_inner_edges.top)))); +} + DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0, doc: /* Get power status information from Windows system. @@ -8411,6 +8539,7 @@ only be necessary if the default setting causes problems. */); defsubr (&Sx_open_connection); defsubr (&Sx_close_connection); defsubr (&Sx_display_list); + defsubr (&Sx_frame_geometry); defsubr (&Sx_synchronize); /* W32 specific functions */ diff --git a/src/w32menu.c b/src/w32menu.c index 9f777167bf0..6633ffddbcf 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -504,7 +504,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p) area remains the same, if menubar has just been created. */ if (old_widget == NULL) adjust_frame_size (f, FRAME_TEXT_WIDTH (f), - FRAME_TEXT_HEIGHT (f), 2, 0); + FRAME_TEXT_HEIGHT (f), 2, 0, Qmenu_bar_lines); } unblock_input (); diff --git a/src/w32term.c b/src/w32term.c index 4cffa3818ce..c2a37d078a8 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -5843,7 +5843,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) problems because the tip frame has no widget. */ if (NILP (tip_frame) || XFRAME (tip_frame) != f) adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), - FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0); + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0, Qfont); } /* X version sets font of input methods here also. */ diff --git a/src/widget.c b/src/widget.c index baa6a2ab917..ecf145199f2 100644 --- a/src/widget.c +++ b/src/widget.c @@ -644,7 +644,8 @@ EmacsFrameSetCharSize (Widget widget, int columns, int rows) EmacsFrame ew = (EmacsFrame) widget; struct frame *f = ew->emacs_frame.frame; - if (!frame_inhibit_resize (f, 0) && !frame_inhibit_resize (f, 1)) + if (!frame_inhibit_resize (f, 0, Qfont) + && !frame_inhibit_resize (f, 1, Qfont)) x_set_window_size (f, 0, columns, rows, 0); } diff --git a/src/window.c b/src/window.c index 2c9292d5b02..168ef1e3b9d 100644 --- a/src/window.c +++ b/src/window.c @@ -6417,7 +6417,7 @@ the return value is nil. Otherwise the value is t. */) /* Make frame official again and apply frame size changes if needed. */ f->official = true; - adjust_frame_size (f, -1, -1, 1, 0); + adjust_frame_size (f, -1, -1, 1, 0, Qnil); adjust_frame_glyphs (f); unblock_input (); diff --git a/src/xfns.c b/src/xfns.c index 8f5a06c0330..10eb3336fad 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1009,7 +1009,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) #else /* not USE_X_TOOLKIT && not USE_GTK */ FRAME_MENU_BAR_LINES (f) = nlines; FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); - adjust_frame_size (f, -1, -1, 2, 1); + adjust_frame_size (f, -1, -1, 2, 1, Qmenu_bar_lines); if (FRAME_X_WINDOW (f)) x_clear_under_internal_border (f); @@ -1075,7 +1075,19 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) else nlines = 0; +#ifdef USE_GTK x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); +#else /* !USE_GTK */ + if (nlines == 0) + x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f)); + else + { + f->n_tool_bar_rows = 0; + FRAME_TOOL_BAR_LINES (f) = nlines; + adjust_frame_glyphs (f); + SET_FRAME_GARBAGED (f); + } +#endif /* USE_GTK */ } @@ -1112,10 +1124,10 @@ x_change_tool_bar_height (struct frame *f, int height) /* Recalculate tool bar and frame text sizes. */ FRAME_TOOL_BAR_HEIGHT (f) = height; FRAME_TOOL_BAR_LINES (f) = lines; - FRAME_TEXT_HEIGHT (f) - = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); - FRAME_LINES (f) - = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); +/** FRAME_TEXT_HEIGHT (f) **/ +/** = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f)); **/ +/** FRAME_LINES (f) **/ +/** = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f)); **/ /* Store the `tool-bar-lines' and `height' frame parameters. */ store_frame_param (f, Qtool_bar_lines, make_number (lines)); store_frame_param (f, Qheight, make_number (FRAME_LINES (f))); @@ -1138,7 +1150,8 @@ x_change_tool_bar_height (struct frame *f, int height) /* Recalculate toolbar height. */ f->n_tool_bar_rows = 0; - adjust_frame_size (f, -1, -1, 4, 0); + adjust_frame_size (f, -1, -1, (old_height == 0 || height == 0) ? 2 : 4, 0, + Qtool_bar_lines); if (FRAME_X_WINDOW (f)) x_clear_under_internal_border (f); @@ -1166,7 +1179,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva if (FRAME_X_WINDOW (f) != 0) { - adjust_frame_size (f, -1, -1, 3, 0); + adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width); #ifdef USE_GTK xg_clear_under_internal_border (f); @@ -3163,7 +3176,7 @@ This function is an internal primitive--use `make-frame' instead. */) had one frame line vs one toolbar line which left us with a zero root window height which was obviously wrong as well ... */ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), - FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1); + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil); /* Set the menu-bar-lines and tool-bar-lines parameters. We don't look up the X resources controlling the menu-bar and tool-bar @@ -3237,7 +3250,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* Consider frame official, now. */ f->official = true; - adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1); + adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil); #if defined (USE_X_TOOLKIT) || defined (USE_GTK) /* Create the menu bar. */ @@ -4221,6 +4234,124 @@ Internal use only, use `display-monitor-attributes-list' instead. */) return attributes_list; } +DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0, + doc: /* Return geometric atributes of frame FRAME. + +FRAME must be a live frame and defaults to the selected one. + +The return value is an association list containing the following +elements (all size values are in pixels). + +- `frame-outer-size' is a cons of the outer width and height of FRAME. + The outer size include the title bar and the external borders as well + as any menu and/or tool bar of frame. + +- `border' is a cons of the horizontal and vertical width of FRAME's + external borders. + +- `title-bar-height' is the height of the title bar of FRAME. + +- `menu-bar-external' if `t' means the menu bar is external (not + included in the inner edges of FRAME). + +- `menu-bar-size' is a cons of the width and height of the menu bar of + FRAME. + +- `tool-bar-external' if `t' means the tool bar is external (not + included in the inner edges of FRAME). + +- `tool-bar-side' tells tells on which side the tool bar on FRAME is and + can be one of `left', `top', `right' or `bottom'. + +- `tool-bar-size' is a cons of the width and height of the tool bar of + FRAME. + +- `frame-inner-size' is a cons of the inner width and height of FRAME. + This excludes FRAME's title bar and external border as well as any + external menu and/or tool bar. */) + (Lisp_Object frame) +{ + struct frame *f = decode_live_frame (frame); + int inner_width = FRAME_PIXEL_WIDTH (f); + int inner_height = FRAME_PIXEL_HEIGHT (f); + int outer_width, outer_height, border, title; + Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen); + int menu_bar_height, menu_bar_width, tool_bar_height, tool_bar_width; + + border = FRAME_OUTER_TO_INNER_DIFF_X (f); + title = FRAME_X_OUTPUT (f)->y_pixels_outer_diff - border; + + outer_width = FRAME_PIXEL_WIDTH (f) + 2 * border; + outer_height = (FRAME_PIXEL_HEIGHT (f) + + FRAME_OUTER_TO_INNER_DIFF_Y (f) + + FRAME_OUTER_TO_INNER_DIFF_X (f)); + +#if defined (USE_GTK) + { + bool tool_bar_left_right = (EQ (FRAME_TOOL_BAR_POSITION (f), Qleft) + || EQ (FRAME_TOOL_BAR_POSITION (f), Qright)); + + tool_bar_width = (tool_bar_left_right + ? FRAME_TOOLBAR_WIDTH (f) + : FRAME_PIXEL_WIDTH (f)); + tool_bar_height = (tool_bar_left_right + ? FRAME_PIXEL_HEIGHT (f) + : FRAME_TOOLBAR_HEIGHT (f)); + if (tool_bar_left_right) + /* For some reason FRAME_OUTER_TO_INNER_DIFF_X does not count the + width of a tool bar. */ + outer_width += FRAME_TOOLBAR_WIDTH (f); + } +#else + tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); + tool_bar_width = ((tool_bar_height > 0) + ? outer_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f) + : 0); +#endif + +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) + menu_bar_height = FRAME_MENUBAR_HEIGHT (f); +#else + menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); +#endif + + menu_bar_width = ((menu_bar_height > 0) + ? outer_width - 2 * border + : 0); + + if (!FRAME_EXTERNAL_MENU_BAR (f)) + inner_height -= menu_bar_height; + if (!FRAME_EXTERNAL_TOOL_BAR (f)) + inner_height -= tool_bar_height; + + return + listn (CONSTYPE_PURE, 10, + Fcons (Qframe_position, + Fcons (make_number (f->left_pos), make_number (f->top_pos))), + Fcons (Qframe_outer_size, + Fcons (make_number (outer_width), make_number (outer_height))), + Fcons (Qexternal_border_size, + ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen)) + ? Fcons (make_number (0), make_number (0)) + : Fcons (make_number (border), make_number (border)))), + Fcons (Qtitle_height, + ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen)) + ? make_number (0) + : make_number (title))), + Fcons (Qmenu_bar_external, FRAME_EXTERNAL_MENU_BAR (f) ? Qt : Qnil), + Fcons (Qmenu_bar_size, + Fcons (make_number (menu_bar_width), + make_number (menu_bar_height))), + Fcons (Qtool_bar_external, FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil), + Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)), + Fcons (Qtool_bar_size, + Fcons (make_number (tool_bar_width), + make_number (tool_bar_height))), + Fcons (Qframe_inner_size, + Fcons (make_number (inner_width), + make_number (inner_height)))); +} + /************************************************************************ X Displays ************************************************************************/ @@ -6224,6 +6355,7 @@ When using Gtk+ tooltips, the tooltip face is not used. */); defsubr (&Sx_display_backing_store); defsubr (&Sx_display_save_under); defsubr (&Sx_display_monitor_attributes_list); + defsubr (&Sx_frame_geometry); defsubr (&Sx_wm_set_size_hint); defsubr (&Sx_create_frame); defsubr (&Sx_open_connection); diff --git a/src/xmenu.c b/src/xmenu.c index eb783fe5070..0f69ee28e84 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -657,9 +657,15 @@ update_frame_menubar (struct frame *f) lw_refigure_widget (x->column_widget, True); /* Force the pane widget to resize itself. */ - adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 2, 0); +#ifdef USE_LUCID + /* For reasons I don't know Lucid wants to add one pixel to the frame + height when adding the menu bar. Compensate that here. */ + adjust_frame_size (f, -1, FRAME_TEXT_HEIGHT (f) - 1, 2, 0, Qmenu_bar_lines); +#else + adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines); +#endif /* USE_LUCID */ unblock_input (); -#endif +#endif /* USE_GTK */ } #ifdef USE_LUCID @@ -1050,6 +1056,12 @@ void free_frame_menubar (struct frame *f) { Widget menubar_widget; +#ifdef USE_MOTIF + /* Motif automatically shrinks the frame in lw_destroy_all_widgets. + If we want to preserve the old height, calculate it now so we can + restore it below. */ + int old_height = FRAME_TEXT_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f); +#endif eassert (FRAME_X_P (f)); @@ -1087,17 +1099,20 @@ free_frame_menubar (struct frame *f) XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL); if (x1 == 0 && y1 == 0) XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL); -#endif - adjust_frame_size (f, FRAME_TEXT_WIDTH (f), - FRAME_TEXT_HEIGHT (f), 2, 0); - /* - if (frame_inhibit_resize (f, 0)) - change_frame_size (f, 0, 0, 0, 0, 0, 1); + if (frame_inhibit_resize (f, 0, Qmenu_bar_lines)) + adjust_frame_size (f, -1, old_height, 1, 0, Qmenu_bar_lines); else - x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), - FRAME_TEXT_HEIGHT (f), 1); - */ +#endif /* USE_MOTIF */ + adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines); } + else + { +#ifdef USE_MOTIF + if (frame_inhibit_resize (f, 0, Qmenu_bar_lines)) + adjust_frame_size (f, -1, old_height, 1, 0, Qmenu_bar_lines); +#endif + } + unblock_input (); } } diff --git a/src/xterm.c b/src/xterm.c index 53eb7b3625d..98f2a27c1ce 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -8662,8 +8662,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) doing it because it's done in Fx_show_tip, and it leads to problems because the tip frame has no widget. */ if (NILP (tip_frame) || XFRAME (tip_frame) != f) - x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), - FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1); + adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, + 0, Qfont); } #ifdef HAVE_X_I18N |