diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 126 | ||||
-rw-r--r-- | src/data.c | 5 | ||||
-rw-r--r-- | src/dispnew.c | 135 | ||||
-rw-r--r-- | src/eval.c | 22 | ||||
-rw-r--r-- | src/frame.c | 208 | ||||
-rw-r--r-- | src/frame.h | 13 | ||||
-rw-r--r-- | src/gtkutil.c | 118 | ||||
-rw-r--r-- | src/w32fns.c | 18 | ||||
-rw-r--r-- | src/w32term.c | 217 | ||||
-rw-r--r-- | src/widget.c | 39 | ||||
-rw-r--r-- | src/window.c | 2 | ||||
-rw-r--r-- | src/xdisp.c | 39 | ||||
-rw-r--r-- | src/xfns.c | 16 | ||||
-rw-r--r-- | src/xterm.c | 214 |
14 files changed, 743 insertions, 429 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 6b56abbafd1..56f88f5bec4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,117 @@ +2015-02-08 Paul Eggert <eggert@cs.ucla.edu> + + Minor tweaks to frame_size_history_add + * frame.c (frame_size_history_add): Don't assume length fits in 'int'. + Prefer XCAR and XCDR to Fcar and Fcdr when the arg is a cons. + (Fframe_after_make_frame): Simplify. + * gtkutil.c: Remove commented-out code. + * xfns.c (Fx_create_frame): Fix indenting. + +2015-02-08 Eli Zaretskii <eliz@gnu.org> + + * frame.c (Fframe_parameter): Don't replace a non-nil value of + foreground-color or background-color parameters with a nil value. + (Bug#19802) + +2015-02-08 Stefan Monnier <monnier@iro.umontreal.ca> + + * data.c (Findirect_function): Like `symbol-function', don't signal an + error for void functions any more. + +2015-02-07 Martin Rudalics <rudalics@gmx.at> + + * frame.c (frame_size_history_add): New function. + (frame_inhibit_resize): Consider frame_inhibit_implied_resize + only after frame's after_make_frame slot is true. + Inhibit resizing fullwidth-/height frames in one direction only. + Update frame_size_history. + (adjust_frame_size): Call frame_size_history_add. + (make_frame): Initalize after_make_frame slot. + (Fmake_terminal_frame): Adjust adjust_frame_size call. + (Fcan_run_window_configuration_change_hook): Rename to + Fframe_after_make_frame. Set after_make_frame slot. + Return second argument. + (x_set_frame_parameters): Postpone handling fullscreen parameter + until after width and height parameters have been set. + Apply width and height changes only if can_x_set_window_size is true. + Update frame_size_history. + (Qadjust_frame_size_1, Qadjust_frame_size_2) + (Qadjust_frame_size_3, QEmacsFrameResize, Qframe_inhibit_resize) + (Qx_set_fullscreen, Qx_check_fullscreen, Qx_set_window_size_1) + (Qxg_frame_resized, Qxg_frame_set_char_size_1) + (Qxg_frame_set_char_size_2, Qxg_frame_set_char_size_3) + (Qxg_change_toolbar_position, Qx_net_wm_state) + (Qx_handle_net_wm_state, Qtb_size_cb, Qupdate_frame_tool_bar) + (Qfree_frame_tool_bar): New symbol for updating frame_size_history. + (Qtip_frame, Qterminal_frame): New symbols. + (Vframe_adjust_size_history): Rename to frame_size_history. + * frame.h (struct frame): + Rename can_run_window_configuration_change_hook slot to + after_make_frame. + (frame_size_history_add): Extern. + * gtkutil.c (xg_frame_resized): Call frame_size_history_add. + Don't set FRAME_PIXEL_WIDTH and FRAME_PIXEL_HEIGHT here. + (xg_frame_set_char_size): Try to preserve the status of + fullwidth/-height frames. Call frame_size_history_add. + (tb_size_cb, update_frame_tool_bar, free_frame_tool_bar) + (xg_change_toolbar_position): Call frame_size_history_add. + * w32fns.c (x_change_tool_bar_height): Handle frame's fullscreen + status. + (Fx_create_frame): Process fullscreen parameter after frame has + been resized. + (x_create_tip_frame): Pass Qtip_frame to adjust_frame_size. + (Fx_frame_geometry): Don't pollute pure storage. + * w32term.c (w32_read_socket): For WM_WINDOWPOSCHANGED, + WM_ACTIVATE and WM_ACTIVATEAPP set frame's visibility before + calling w32fullscreen_hook. For WM_DISPLAYCHANGE call + w32fullscreen_hook immediately. + (x_fullscreen_adjust, x_check_fullscreen): Remove. + (w32fullscreen_hook): Call change_frame_size just as with a + "normal" frame resize operation. Call do_pending_window_change. + (x_set_window_size): Try to handle fullwidth and fullheight more + accurately. Don't rely on w32_enable_frame_resize_hack. + (w32_enable_frame_resize_hack): Remove variable. + * widget.c (EmacsFrameResize): Remove dead code. + Call frame_size_history_add + * window.c (run_window_configuration_change_hook): + Check f->after_make_frame instead of + f->can_run_window_configuration_change_hook. + * xfns.c (x_change_tool_bar_height): Handle frame's fullscreen status. + (Fx_create_frame): Process fullscreen parameter after frame has + been resized. + (Fx_frame_geometry): Don't pollute pure storage. + * xterm.c (x_net_wm_state, x_handle_net_wm_state): + Call frame_size_history_add. + (do_ewmh_fullscreen): Handle x_frame_normalize_before_maximize. + (x_check_fullscreen): Count in menubar when calling + XResizeWindow. Wait for ConfigureNotify event. + Call frame_size_history_add. + (x_set_window_size_1): Remove PIXELWISE argument. Try to handle + changing a fullheight frame's width or a fullwidth frame's + height. Call frame_size_history_add. + (x_set_window_size): Simplify xg_frame_set_char_size and + x_set_window_size_1 calls. + (x_frame_normalize_before_maximize): New variable. + +2015-02-07 Paul Eggert <eggert@cs.ucla.edu> + + Remove no-longer-used cursor_in_echo_area code + * dispnew.c (set_window_cursor_after_update, update_frame_1): + Remove checks for negative cursor_in_echo_area, since this var is + a boolean, and has been a boolean for some time. Simplify. + * dispnew.c (init_display): + * xdisp.c (message3_nolog, vmessage): Use bool for boolean. + +2015-02-05 Stefan Monnier <monnier@iro.umontreal.ca> + + * eval.c (Ffunction): Handle the new (:documentation ...) form. + (syms_of_eval): Declare `:documentation'. + +2015-02-05 Martin Rudalics <rudalics@gmx.at> + + * xdisp.c (Fwindow_text_pixel_size): Remove optional BUFFER + argument added on 2015-02-01. + 2015-02-04 Paul Eggert <eggert@cs.ucla.edu> Remove no-longer-used two_byte_p calculations @@ -224,8 +338,8 @@ (x_horizontal_scroll_bar_report_motion, w32_read_socket) (w32_set_vertical_scroll_bar, w32_set_horizontal_scroll_bar) (w32_draw_window_cursor, x_new_font, x_set_offset) - (x_set_window_size, x_make_frame_invisible, x_iconify_frame): Use - bool where appropriate. + (x_set_window_size, x_make_frame_invisible, x_iconify_frame): + Use bool where appropriate. Use bool for boolean in w32fns.c * w32fns.c (w32_defined_color, x_decode_color) @@ -694,8 +808,8 @@ Qx_create_frame_2 to adjust_frame_size. * w32menu.c (set_frame_menubar): Simplify adjust_frame_size call. - * window.c (Fset_window_configuration): Pass - Qset_window_configuration to adjust_frame_size. + * window.c (Fset_window_configuration): + Pass Qset_window_configuration to adjust_frame_size. * xdisp.c (redisplay_tool_bar): Assign new height to frame_default_tool_bar_height. (redisplay_internal): If we haven't redisplayed this frame's @@ -763,8 +877,8 @@ * w32fns.c (Fw32_register_hot_key): Use XINT instead of XLI. - * w32notify.c (Fw32notify_add_watch, w32_get_watch_object): Use - make_pointer_integer instead of XIL. + * w32notify.c (Fw32notify_add_watch, w32_get_watch_object): + Use make_pointer_integer instead of XIL. (Fw32notify_rm_watch): Use XINTPTR instead of XLI. * w32inevt.c (handle_file_notifications): Use make_pointer_integer diff --git a/src/data.c b/src/data.c index d06b9916b3a..47706584f5e 100644 --- a/src/data.c +++ b/src/data.c @@ -2125,8 +2125,6 @@ DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 2, 0, doc: /* Return the function at the end of OBJECT's function chain. If OBJECT is not a symbol, just return it. Otherwise, follow all function indirections to find the final function binding and return it. -If the final symbol in the chain is unbound, signal a void-function error. -Optional arg NOERROR non-nil means to return nil instead of signaling. Signal a cyclic-function-indirection error if there is a loop in the function chain of symbols. */) (register Lisp_Object object, Lisp_Object noerror) @@ -2141,9 +2139,6 @@ function chain of symbols. */) if (!NILP (result)) return result; - if (NILP (noerror)) - xsignal1 (Qvoid_function, object); - return Qnil; } diff --git a/src/dispnew.c b/src/dispnew.c index e614ceef122..6ee4ccedf0b 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3911,45 +3911,35 @@ set_window_cursor_after_update (struct window *w) { cx = cy = vpos = hpos = 0; - if (cursor_in_echo_area >= 0) + /* If the mini-buffer is several lines high, find the last + line that has any text on it. Note: either all lines + are enabled or none. Otherwise we wouldn't be able to + determine Y. */ + struct glyph_row *last_row = NULL; + int yb = window_text_bottom_y (w); + + for (struct glyph_row *row = w->current_matrix->rows; + row->enabled_p && (!last_row || MATRIX_ROW_BOTTOM_Y (row) <= yb); + row++) + if (row->used[TEXT_AREA] && row->glyphs[TEXT_AREA][0].charpos >= 0) + last_row = row; + + if (last_row) { - /* If the mini-buffer is several lines high, find the last - line that has any text on it. Note: either all lines - are enabled or none. Otherwise we wouldn't be able to - determine Y. */ - struct glyph_row *row, *last_row; - struct glyph *glyph; - int yb = window_text_bottom_y (w); - - last_row = NULL; - row = w->current_matrix->rows; - while (row->enabled_p - && (last_row == NULL - || MATRIX_ROW_BOTTOM_Y (row) <= yb)) - { - if (row->used[TEXT_AREA] - && row->glyphs[TEXT_AREA][0].charpos >= 0) - last_row = row; - ++row; - } + struct glyph *start = last_row->glyphs[TEXT_AREA]; + struct glyph *last = start + last_row->used[TEXT_AREA] - 1; - if (last_row) - { - struct glyph *start = last_row->glyphs[TEXT_AREA]; - struct glyph *last = start + last_row->used[TEXT_AREA] - 1; - - while (last > start && last->charpos < 0) - --last; + while (last > start && last->charpos < 0) + --last; - for (glyph = start; glyph < last; ++glyph) - { - cx += glyph->pixel_width; - ++hpos; - } - - cy = last_row->y; - vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix); + for (struct glyph *glyph = start; glyph < last; glyph++) + { + cx += glyph->pixel_width; + hpos++; } + + cy = last_row->y; + vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix); } } else @@ -4569,58 +4559,43 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p, && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)) { int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f))); - int row, col; + int col; - if (cursor_in_echo_area < 0) + /* Put cursor at the end of the prompt. If the mini-buffer + is several lines high, find the last line that has + any text on it. */ + int row = FRAME_TOTAL_LINES (f); + do { - /* Negative value of cursor_in_echo_area means put - cursor at beginning of line. */ - row = top; + row--; col = 0; - } - else - { - /* Positive value of cursor_in_echo_area means put - cursor at the end of the prompt. If the mini-buffer - is several lines high, find the last line that has - any text on it. */ - row = FRAME_TOTAL_LINES (f); - do - { - --row; - col = 0; - if (MATRIX_ROW_ENABLED_P (current_matrix, row)) - { - /* Frame rows are filled up with spaces that - must be ignored here. */ - struct glyph_row *r = MATRIX_ROW (current_matrix, - row); - struct glyph *start = r->glyphs[TEXT_AREA]; - struct glyph *last = start + r->used[TEXT_AREA]; - - while (last > start - && (last - 1)->charpos < 0) - --last; - - col = last - start; - } + if (MATRIX_ROW_ENABLED_P (current_matrix, row)) + { + /* Frame rows are filled up with spaces that + must be ignored here. */ + struct glyph_row *r = MATRIX_ROW (current_matrix, row); + struct glyph *start = r->glyphs[TEXT_AREA]; + + col = r->used[TEXT_AREA]; + while (0 < col && start[col - 1].charpos < 0) + col--; } - while (row > top && col == 0); + } + while (row > top && col == 0); - /* Make sure COL is not out of range. */ - if (col >= FRAME_CURSOR_X_LIMIT (f)) + /* Make sure COL is not out of range. */ + if (col >= FRAME_CURSOR_X_LIMIT (f)) + { + /* If we have another row, advance cursor into it. */ + if (row < FRAME_TOTAL_LINES (f) - 1) { - /* If we have another row, advance cursor into it. */ - if (row < FRAME_TOTAL_LINES (f) - 1) - { - col = FRAME_LEFT_SCROLL_BAR_COLS (f); - row++; - } - /* Otherwise move it back in range. */ - else - col = FRAME_CURSOR_X_LIMIT (f) - 1; + col = FRAME_LEFT_SCROLL_BAR_COLS (f); + row++; } + /* Otherwise move it back in range. */ + else + col = FRAME_CURSOR_X_LIMIT (f) - 1; } cursor_to (f, row, col); @@ -5966,7 +5941,7 @@ init_display (void) space_glyph.charpos = -1; inverse_video = 0; - cursor_in_echo_area = 0; + cursor_in_echo_area = false; /* Now is the time to initialize this; it's used by init_sys_modes during startup. */ diff --git a/src/eval.c b/src/eval.c index b98b224e622..e828da9288f 100644 --- a/src/eval.c +++ b/src/eval.c @@ -575,10 +575,23 @@ usage: (function ARG) */) if (!NILP (Vinternal_interpreter_environment) && CONSP (quoted) && EQ (XCAR (quoted), Qlambda)) - /* This is a lambda expression within a lexical environment; - return an interpreted closure instead of a simple lambda. */ - return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, - XCDR (quoted))); + { /* This is a lambda expression within a lexical environment; + return an interpreted closure instead of a simple lambda. */ + Lisp_Object cdr = XCDR (quoted); + Lisp_Object tmp = cdr; + if (CONSP (tmp) + && (tmp = XCDR (tmp), CONSP (tmp)) + && (tmp = XCAR (tmp), CONSP (tmp)) + && (EQ (QCdocumentation, XCAR (tmp)))) + { /* Handle the special (:documentation <form>) to build the docstring + dynamically. */ + Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp))); + CHECK_STRING (docstring); + cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr)))); + } + return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, + cdr)); + } else /* Simply quote the argument. */ return quoted; @@ -3668,6 +3681,7 @@ before making `inhibit-quit' nil. */); DEFSYM (Qand_rest, "&rest"); DEFSYM (Qand_optional, "&optional"); DEFSYM (Qclosure, "closure"); + DEFSYM (QCdocumentation, ":documentation"); DEFSYM (Qdebug, "debug"); DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger, diff --git a/src/frame.c b/src/frame.c index 890e8972617..92b6b7c73ba 100644 --- a/src/frame.c +++ b/src/frame.c @@ -149,6 +149,32 @@ get_frame_param (register struct frame *frame, Lisp_Object prop) return Fcdr (tem); } + +void +frame_size_history_add (struct frame *f, Lisp_Object fun_symbol, + int width, int height, Lisp_Object rest) +{ + Lisp_Object frame; + + XSETFRAME (frame, f); + if (CONSP (frame_size_history) + && INTEGERP (XCAR (frame_size_history)) + && 0 < XINT (XCAR (frame_size_history))) + frame_size_history = + Fcons (make_number (XINT (XCAR (frame_size_history)) - 1), + Fcons (list4 + (frame, fun_symbol, + ((width > 0) + ? list4 (make_number (FRAME_TEXT_WIDTH (f)), + make_number (FRAME_TEXT_HEIGHT (f)), + make_number (width), + make_number (height)) + : Qnil), + rest), + XCDR (frame_size_history))); +} + + /* 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. PARAMETER is the symbol of the frame @@ -156,11 +182,27 @@ get_frame_param (register struct frame *frame, Lisp_Object prop) bool frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter) { - 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)); + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + bool inhibit + = ((f->after_make_frame + && (EQ (frame_inhibit_implied_resize, Qt) + || (CONSP (frame_inhibit_implied_resize) + && !NILP (Fmemq (parameter, frame_inhibit_implied_resize))))) + || (horizontal + && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullheight)) + || (!horizontal + && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullwidth)) + || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); + + if (inhibit && !FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f)) + frame_size_history_add + (f, Qframe_inhibit_resize, 0, 0, + list5 (horizontal ? Qt : Qnil, parameter, + f->after_make_frame ? Qt : Qnil, + frame_inhibit_implied_resize, + fullscreen)); + + return inhibit; } static void @@ -369,18 +411,9 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, XSETFRAME (frame, f); - /* `make-frame' initializes Vframe_adjust_size_history to (Qt) and - strips its car when exiting. Just in case make sure its size never - exceeds 100. */ - if (!NILP (Fconsp (Vframe_adjust_size_history)) - && EQ (Fcar (Vframe_adjust_size_history), Qt) - && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100) - Vframe_adjust_size_history = - Fcons (Qt, Fcons (list5 (make_number (0), - make_number (new_text_width), - make_number (new_text_height), - make_number (inhibit), parameter), - Fcdr (Vframe_adjust_size_history))); + frame_size_history_add + (f, Qadjust_frame_size_1, new_text_width, new_text_height, + list2 (parameter, make_number (inhibit))); /* The following two values are calculated from the old window body sizes and any "new" settings for scroll bars, dividers, fringes and @@ -391,7 +424,7 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt); if (inhibit >= 2 && inhibit <= 4) - /* If INHIBIT is in [2..4] inhibit if the "old" window sizes stay + /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay within the limits and either frame_inhibit_resize tells us to do so or INHIBIT equals 4. */ { @@ -449,16 +482,10 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, else if (inhibit_vertical) new_text_height = old_text_height; - if (!NILP (Fconsp (Vframe_adjust_size_history)) - && EQ (Fcar (Vframe_adjust_size_history), Qt) - && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100) - Vframe_adjust_size_history = - Fcons (Qt, Fcons (list5 (make_number (1), - make_number (new_text_width), - make_number (new_text_height), - make_number (new_cols), - make_number (new_lines)), - Fcdr (Vframe_adjust_size_history))); + frame_size_history_add + (f, Qadjust_frame_size_2, new_text_width, new_text_height, + list2 (inhibit_horizontal ? Qt : Qnil, + inhibit_vertical ? Qt : Qnil)); x_set_window_size (f, 0, new_text_width, new_text_height, 1); f->resized_p = true; @@ -525,6 +552,11 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f); } + frame_size_history_add + (f, Qadjust_frame_size_3, new_text_width, new_text_height, + list4 (make_number (old_pixel_width), make_number (old_pixel_height), + make_number (new_pixel_width), make_number (new_pixel_height))); + /* Assign new sizes. */ FRAME_TEXT_WIDTH (f) = new_text_width; FRAME_TEXT_HEIGHT (f) = new_text_height; @@ -533,17 +565,6 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, SET_FRAME_COLS (f, new_cols); SET_FRAME_LINES (f, new_lines); - if (!NILP (Fconsp (Vframe_adjust_size_history)) - && EQ (Fcar (Vframe_adjust_size_history), Qt) - && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100) - Vframe_adjust_size_history = - Fcons (Qt, Fcons (list5 (make_number (2), - make_number (new_text_width), - make_number (new_text_height), - make_number (new_cols), - make_number (new_lines)), - Fcdr (Vframe_adjust_size_history))); - { struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); int text_area_x, text_area_y, text_area_width, text_area_height; @@ -608,7 +629,7 @@ make_frame (bool mini_p) f->redisplay = true; f->garbaged = true; f->can_x_set_window_size = false; - f->can_run_window_configuration_change_hook = false; + f->after_make_frame = false; f->tool_bar_redisplayed_once = false; f->column_width = 1; /* !FRAME_WINDOW_P value. */ f->line_height = 1; /* !FRAME_WINDOW_P value. */ @@ -1020,7 +1041,8 @@ 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, Qnil); + adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), + 5, 0, Qterminal_frame); } adjust_frame_glyphs (f); @@ -2260,24 +2282,23 @@ If there is no window system support, this function does nothing. */) return Qnil; } -DEFUN ("frame-can-run-window-configuration-change-hook", - Fcan_run_window_configuration_change_hook, - Scan_run_window_configuration_change_hook, 2, 2, 0, - doc: /* Whether `window-configuration-change-hook' is run for frame FRAME. -FRAME nil means use the selected frame. Second argument ALLOW non-nil +DEFUN ("frame-after-make-frame", + Fframe_after_make_frame, + Sframe_after_make_frame, 2, 2, 0, + doc: /* Mark FRAME as made. +FRAME nil means use the selected frame. Second argument MADE non-nil means functions on `window-configuration-change-hook' are called -whenever the window configuration of FRAME changes. ALLOW nil means +whenever the window configuration of FRAME changes. MADE nil means these functions are not called. -This function is currently called by `face-set-after-frame-default' only -and should be otherwise used with utter care to avoid that running -functions on `window-configuration-change-hook' is impeded forever. */) - (Lisp_Object frame, Lisp_Object allow) +This function is currently called by `make-frame' only and should be +otherwise used with utter care to avoid that running functions on +`window-configuration-change-hook' is impeded forever. */) + (Lisp_Object frame, Lisp_Object made) { struct frame *f = decode_live_frame (frame); - - f->can_run_window_configuration_change_hook = NILP (allow) ? false : true; - return Qnil; + f->after_make_frame = !NILP (made); + return made; } @@ -2591,7 +2612,12 @@ If FRAME is nil, describe the currently selected frame. */) important when param_alist's notion of colors is "unspecified". We need to do the same here. */ if (STRINGP (value) && !FRAME_WINDOW_P (f)) - value = frame_unspecified_color (f, value); + { + Lisp_Object tem = frame_unspecified_color (f, value); + + if (!NILP (tem)) + value = tem; + } } else value = Fcdr (Fassq (parameter, Fframe_parameters (frame))); @@ -3037,7 +3063,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) set them both at once. So we wait until we've looked at the entire list before we set them. */ int width IF_LINT (= 0), height IF_LINT (= 0); - bool width_change = 0, height_change = 0; + bool width_change = false, height_change = false; /* Same here. */ Lisp_Object left, top; @@ -3045,6 +3071,10 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) /* Same with these. */ Lisp_Object icon_left, icon_top; + /* And with this. */ + Lisp_Object fullscreen; + bool fullscreen_change = false; + /* Record in these vectors all the parms specified. */ Lisp_Object *parms; Lisp_Object *values; @@ -3138,6 +3168,11 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) icon_top = val; else if (EQ (prop, Qicon_left)) icon_left = val; + else if (EQ (prop, Qfullscreen)) + { + fullscreen = val; + fullscreen_change = true; + } else if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color) || EQ (prop, Qfont)) @@ -3218,14 +3253,14 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) that here since otherwise a size change implied by an intermittent font change may get lost as in Bug#17142. */ if (!width_change) - width = (f->new_width + width = ((f->can_x_set_window_size && f->new_width) ? (f->new_pixelwise ? f->new_width : (f->new_width * FRAME_COLUMN_WIDTH (f))) : FRAME_TEXT_WIDTH (f)); if (!height_change) - height = (f->new_height + height = ((f->can_x_set_window_size && f->new_height) ? (f->new_pixelwise ? f->new_height : (f->new_height * FRAME_LINE_HEIGHT (f))) @@ -3298,6 +3333,20 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) /* Actually set that position, and convert to absolute. */ x_set_offset (f, leftpos, toppos, -1); } + + if (fullscreen_change) + { + Lisp_Object old_value = get_frame_param (f, Qfullscreen); + + frame_size_history_add + (f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen)); + + store_frame_param (f, Qfullscreen, fullscreen); + if (!EQ (fullscreen, old_value)) + x_set_fullscreen (f, fullscreen, old_value); + } + + #ifdef HAVE_X_WINDOWS if ((!NILP (icon_left) || !NILP (icon_top)) && ! (icon_left_no_change && icon_top_no_change)) @@ -4834,11 +4883,33 @@ syms_of_frame (void) DEFSYM (Qtool_bar_external, "tool-bar-external"); DEFSYM (Qtool_bar_size, "tool-bar-size"); DEFSYM (Qframe_inner_size, "frame-inner-size"); + /* The following are used for frame_size_history. */ + DEFSYM (Qadjust_frame_size_1, "adjust-frame-size-1"); + DEFSYM (Qadjust_frame_size_2, "adjust-frame-size-2"); + DEFSYM (Qadjust_frame_size_3, "adjust-frame-size-3"); + DEFSYM (QEmacsFrameResize, "EmacsFrameResize"); + DEFSYM (Qframe_inhibit_resize, "frame-inhibit-resize"); + DEFSYM (Qx_set_fullscreen, "x-set-fullscreen"); + DEFSYM (Qx_check_fullscreen, "x-check-fullscreen"); + DEFSYM (Qx_set_window_size_1, "x-set-window-size-1"); + DEFSYM (Qxg_frame_resized, "xg-frame-resized"); + 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_change_toolbar_position, "xg-change-toolbar-position"); + DEFSYM (Qx_net_wm_state, "x-net-wm-state"); + DEFSYM (Qx_handle_net_wm_state, "x-handle-net-wm-state"); + DEFSYM (Qtb_size_cb, "tb-size-cb"); + DEFSYM (Qupdate_frame_tool_bar, "update-frame-tool-bar"); + DEFSYM (Qfree_frame_tool_bar, "free-frame-tool-bar"); + DEFSYM (Qchange_frame_size, "change-frame-size"); DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size"); DEFSYM (Qset_window_configuration, "set-window-configuration"); DEFSYM (Qx_create_frame_1, "x-create-frame-1"); DEFSYM (Qx_create_frame_2, "x-create-frame-2"); + DEFSYM (Qtip_frame, "tip-frame"); + DEFSYM (Qterminal_frame, "terminal-frame"); #ifdef HAVE_NS DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); @@ -5106,9 +5177,22 @@ even if this option is non-nil. */); frame_inhibit_implied_resize = Qt; #endif - DEFVAR_LISP ("frame-adjust-size-history", Vframe_adjust_size_history, - doc: /* History of frame size adjustments. */); - Vframe_adjust_size_history = Qnil; + DEFVAR_LISP ("frame-size-history", frame_size_history, + doc: /* History of frame size adjustments. +If non-nil, list recording frame size adjustment. Adjustments are +recorded only if the first element of this list is a positive number. +Adding an adjustment decrements that number by one. + +The remaining elements are the adjustments. Each adjustment is a list +of four elements `frame', `function', `sizes' and `more'. `frame' is +the affected frame and `function' the invoking function. `sizes' is +usually a list of four elements `old-width', `old-height', `new-width' +and `new-height' representing the old and new sizes recorded/requested +by `function'. `more' is a list with additional information. + +The function `frame--size-history' displays the value of this variable +in a more readable form. */); + frame_size_history = Qnil; staticpro (&Vframe_list); @@ -5141,7 +5225,7 @@ even if this option is non-nil. */); defsubr (&Sraise_frame); defsubr (&Slower_frame); defsubr (&Sx_focus_frame); - defsubr (&Scan_run_window_configuration_change_hook); + defsubr (&Sframe_after_make_frame); defsubr (&Sredirect_frame_focus); defsubr (&Sframe_focus); defsubr (&Sframe_parameters); diff --git a/src/frame.h b/src/frame.h index 0c08d12c92e..6f5de3f5689 100644 --- a/src/frame.h +++ b/src/frame.h @@ -332,9 +332,8 @@ struct frame frame. */ bool_bf can_x_set_window_size : 1; - /* True means run_window_configuration_change_hook can be processed - for this frame. */ - bool_bf can_run_window_configuration_change_hook : 1; + /* Set to true after this frame was made by `make-frame'. */ + bool_bf after_make_frame : 1; /* True means tool bar has been redisplayed at least once in current session. */ @@ -392,9 +391,9 @@ struct frame int left_pos, top_pos; /* Total width of this frame (including fringes, vertical scroll bar - and internal border widths) and total height (including menu bar, - tool bar, horizontal scroll bar and internal border widths) in - pixels. */ + and internal border widths) and total height (including internal + menu and tool bars, horizontal scroll bar and internal border + widths) in pixels. */ int pixel_width, pixel_height; /* These many pixels are the difference between the outer window (i.e. the @@ -1124,6 +1123,8 @@ 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, Lisp_Object); extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object); +extern void frame_size_history_add (struct frame *f, Lisp_Object fun_symbol, + int width, int height, Lisp_Object rest); extern Lisp_Object Vframe_list; diff --git a/src/gtkutil.c b/src/gtkutil.c index 21f3cb15e66..6f1707894c1 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -50,12 +50,6 @@ 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_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) \ (gtk_fixed_set_has_window (GTK_FIXED (w), b)) @@ -886,24 +880,23 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight) if (pixelwidth == -1 && pixelheight == -1) { if (FRAME_GTK_WIDGET (f) && gtk_widget_get_mapped (FRAME_GTK_WIDGET (f))) - gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)), - 0, 0, - &pixelwidth, &pixelheight); - else return; + gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)), + 0, 0, &pixelwidth, &pixelheight); + else + return; } - width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth); height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight); + frame_size_history_add + (f, Qxg_frame_resized, width, height, Qnil); + if (width != FRAME_TEXT_WIDTH (f) || height != FRAME_TEXT_HEIGHT (f) || pixelwidth != FRAME_PIXEL_WIDTH (f) || pixelheight != FRAME_PIXEL_HEIGHT (f)) { - FRAME_PIXEL_WIDTH (f) = pixelwidth; - FRAME_PIXEL_HEIGHT (f) = pixelheight; - xg_clear_under_internal_border (f); change_frame_size (f, width, height, 0, 1, 0, 1); SET_FRAME_GARBAGED (f); @@ -921,24 +914,71 @@ xg_frame_set_char_size (struct frame *f, int width, int height) { int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + gint gwidth, gheight; if (FRAME_PIXEL_HEIGHT (f) == 0) return; + gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), + &gwidth, &gheight); + /* Do this before resize, as we don't know yet if we will be resized. */ xg_clear_under_internal_border (f); - /* Must resize our top level widget. Font size may have changed, - but not rows/cols. */ - gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - pixelwidth + FRAME_TOOLBAR_WIDTH (f), - pixelheight + FRAME_TOOLBAR_HEIGHT (f) - + FRAME_MENUBAR_HEIGHT (f)); - x_wm_set_size_hint (f, 0, 0); + /* Resize the top level widget so rows and columns remain constant. + + When the frame is fullheight and we only want to change the width + or it is fullwidth and we only want to change the height we should + be able to preserve the fullscreen property. However, due to the + fact that we have to send a resize request anyway, the window + manager will abolish it. At least the respective size should + remain unchanged but giving the frame back its normal size will + be broken ... */ + if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f)) + { + frame_size_history_add + (f, Qxg_frame_set_char_size_1, width, height, + list2 (make_number (gheight), + make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f) + + FRAME_MENUBAR_HEIGHT (f)))); + + gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), + gwidth, + pixelheight + FRAME_TOOLBAR_HEIGHT (f) + + FRAME_MENUBAR_HEIGHT (f)); + } + else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f)) + { + frame_size_history_add + (f, Qxg_frame_set_char_size_2, width, height, + list2 (make_number (gwidth), + make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)))); + + gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), + pixelwidth + FRAME_TOOLBAR_WIDTH (f), + gheight); + } + + else + { + frame_size_history_add + (f, Qxg_frame_set_char_size_3, width, height, + list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)), + make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f) + + FRAME_MENUBAR_HEIGHT (f)))); + + gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), + pixelwidth + FRAME_TOOLBAR_WIDTH (f), + pixelheight + FRAME_TOOLBAR_HEIGHT (f) + + FRAME_MENUBAR_HEIGHT (f)); + fullscreen = Qnil; + } SET_FRAME_GARBAGED (f); cancel_mouse_face (f); + x_wm_set_size_hint (f, 0, 0); /* 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. @@ -952,9 +992,17 @@ xg_frame_set_char_size (struct frame *f, int width, int height) (void)gtk_events_pending (); gdk_flush (); x_wait_for_event (f, ConfigureNotify); + + if (!NILP (fullscreen)) + /* Try to restore fullscreen state. */ + { + store_frame_param (f, Qfullscreen, fullscreen); + x_set_fullscreen (f, fullscreen, fullscreen); + } } else - adjust_frame_size (f, -1, -1, 5, 0, Qxg_frame_set_char_size); + adjust_frame_size (f, width, height, 5, 0, Qxg_frame_set_char_size); + } /* Handle height/width changes (i.e. add/remove/move menu/toolbar). @@ -4214,8 +4262,12 @@ tb_size_cb (GtkWidget *widget, allocated between widgets, it may get another. So we must update 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)) - adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); + { + frame_size_history_add (f, Qtb_size_cb, 0, 0, Qnil); + adjust_frame_size (f, -1, -1, 5, 0, Qtool_bar_lines); + } } /* Create a tool bar for frame F. */ @@ -4489,10 +4541,11 @@ xg_update_tool_bar_sizes (struct frame *f) FRAME_TOOLBAR_RIGHT_WIDTH (f) = nr; FRAME_TOOLBAR_TOP_HEIGHT (f) = nt; FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = nb; - return 1; - } - return 0; + return true; + } + else + return false; } static char * @@ -4815,7 +4868,10 @@ 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)) - adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); + { + frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil); + adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); + } } unblock_input (); @@ -4863,6 +4919,7 @@ free_frame_tool_bar (struct frame *f) NULL); } + frame_size_history_add (f, Qfree_frame_tool_bar, 0, 0, Qnil); adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); unblock_input (); @@ -4892,8 +4949,13 @@ 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)) - adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); + { + frame_size_history_add (f, Qxg_change_toolbar_position, 0, 0, Qnil); + adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); + } + unblock_input (); } diff --git a/src/w32fns.c b/src/w32fns.c index 8435270438d..08000d87d38 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1722,6 +1722,7 @@ x_change_tool_bar_height (struct frame *f, int height) int old_height = FRAME_TOOL_BAR_HEIGHT (f); int lines = (height + unit - 1) / unit; int old_text_height = FRAME_TEXT_HEIGHT (f); + Lisp_Object fullscreen; /* Make sure we redisplay all windows in this frame. */ windows_or_buffers_changed = 23; @@ -1746,7 +1747,10 @@ x_change_tool_bar_height (struct frame *f, int height) f->n_tool_bar_rows = 0; adjust_frame_size (f, -1, -1, - (!f->tool_bar_redisplayed_once ? 1 + ((!f->tool_bar_redisplayed_once + && (NILP (fullscreen = + get_frame_param (f, Qfullscreen)) + || EQ (fullscreen, Qfullwidth))) ? 1 : (old_height == 0 || height == 0) ? 2 : 4), false, Qtool_bar_lines); @@ -4668,8 +4672,6 @@ This function is an internal primitive--use `make-frame' instead. */) "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL); x_default_parameter (f, parameters, Qtitle, Qnil, "title", "Title", RES_TYPE_STRING); - x_default_parameter (f, parameters, Qfullscreen, Qnil, - "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; @@ -4728,6 +4730,12 @@ This function is an internal primitive--use `make-frame' instead. */) x_wm_set_size_hint (f, window_prompting, false); unblock_input (); + /* Process fullscreen parameter here in the hope that normalizing a + fullheight/fullwidth frame will produce the size set by the last + adjust_frame_size call. */ + x_default_parameter (f, parameters, Qfullscreen, Qnil, + "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); + /* Make the window appear on the frame and enable display, unless the caller says not to. However, with explicit parent, Emacs cannot control visibility, so don't try. */ @@ -5832,7 +5840,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, true, Qnil); + height * FRAME_LINE_HEIGHT (f), 0, true, Qtip_frame); /* Add `tooltip' frame parameter's default value. */ if (NILP (Fframe_parameter (frame, Qtooltip))) @@ -7558,7 +7566,7 @@ elements (all size values are in pixels). menu_bar_height = single_bar_height; return - listn (CONSTYPE_PURE, 10, + listn (CONSTYPE_HEAP, 10, Fcons (Qframe_position, Fcons (make_number (frame_outer_edges.left), make_number (frame_outer_edges.top))), diff --git a/src/w32term.c b/src/w32term.c index 251c46c73cf..fb9d2388d6b 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -3344,8 +3344,6 @@ static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, Time *); -static void x_check_fullscreen (struct frame *); - static void w32_define_cursor (Window window, Cursor cursor) { @@ -4989,8 +4987,12 @@ w32_read_socket (struct terminal *terminal, sets the WAIT flag. */ if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam) && (f->want_fullscreen & FULLSCREEN_WAIT)) - w32fullscreen_hook (f); - x_check_fullscreen (f); + { + /* Must set visibility right here since otherwise + w32fullscreen_hook returns immediately. */ + SET_FRAME_VISIBLE (f, 1); + w32fullscreen_hook (f); + } } check_visibility = 1; break; @@ -5269,11 +5271,18 @@ w32_read_socket (struct terminal *terminal, if (f) { + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + dpyinfo->n_cbits = msg.msg.wParam; /* The new display could have a different resolution, in - which case we must reconsider what fullscreen - means. */ - x_check_fullscreen (f); + which case we must reconsider what fullscreen means. + The following code is untested yet. */ + if (!NILP (fullscreen)) + { + x_set_fullscreen (f, fullscreen, fullscreen); + w32fullscreen_hook (f); + } + DebPrint (("display change: %d %d\n", (short) LOWORD (msg.msg.lParam), (short) HIWORD (msg.msg.lParam))); @@ -5959,75 +5968,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, unblock_input (); } -/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the - wanted positions of the WM window (not Emacs window). - Return in *WIDTH and *HEIGHT the wanted width and height of Emacs - window (FRAME_X_WINDOW). - */ - -static void -x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *left_pos) -{ - int newwidth = FRAME_COLS (f); - int newheight = FRAME_LINES (f); - Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); - - *top_pos = f->top_pos; - *left_pos = f->left_pos; - - if (f->want_fullscreen & FULLSCREEN_HEIGHT) - { - int ph; - - ph = x_display_pixel_height (dpyinfo); - newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph); - ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff; - newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph); - *top_pos = 0; - } - - if (f->want_fullscreen & FULLSCREEN_WIDTH) - { - int pw; - - pw = x_display_pixel_width (dpyinfo); - newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw); - pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff; - newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw); - *left_pos = 0; - } - - *width = newwidth; - *height = newheight; -} - -/* Check if we need to resize the frame due to a fullscreen request. - If so needed, resize the frame. */ -static void -x_check_fullscreen (struct frame *f) -{ - if (f->want_fullscreen & FULLSCREEN_BOTH) - { - int width, height, ign; - - x_real_positions (f, &f->left_pos, &f->top_pos); - - x_fullscreen_adjust (f, &width, &height, &ign, &ign); - - /* We do not need to move the window, it shall be taken care of - when setting WM manager hints. */ - if (FRAME_COLS (f) != width || FRAME_LINES (f) != height) - { - change_frame_size (f, width, height, 0, 1, 0, 0); - SET_FRAME_GARBAGED (f); - cancel_mouse_face (f); - - /* Wait for the change of frame size to occur. */ - f->want_fullscreen |= FULLSCREEN_WAIT; - } - } -} - static void w32fullscreen_hook (struct frame *f) { @@ -6074,6 +6014,10 @@ w32fullscreen_hook (struct frame *f) SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + change_frame_size + (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, rect.right - rect.left), + FRAME_PIXEL_TO_TEXT_HEIGHT (f, rect.bottom - rect.top), + 0, 1, 0, 1); } else { @@ -6082,10 +6026,39 @@ w32fullscreen_hook (struct frame *f) FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); + + if (f->want_fullscreen == FULLSCREEN_WIDTH) + { + int border_width = GetSystemMetrics (SM_CXFRAME); + + change_frame_size + (f, (FRAME_PIXEL_TO_TEXT_WIDTH + (f, rect.right - rect.left - 2 * border_width)), + 0, 0, 1, 0, 1); + } + else + { + int border_height = GetSystemMetrics (SM_CYFRAME); + /* Won't work for wrapped menu bar. */ + int menu_bar_height = GetSystemMetrics (SM_CYMENU); + int title_height = GetSystemMetrics (SM_CYCAPTION); + + change_frame_size + (f, 0, (FRAME_PIXEL_TO_TEXT_HEIGHT + (f, rect.bottom - rect.top - 2 * border_height + - title_height - menu_bar_height)), + 0, 1, 0, 1); + } } f->want_fullscreen = FULLSCREEN_NONE; unblock_input (); + + if (f->want_fullscreen == FULLSCREEN_BOTH + || f->want_fullscreen == FULLSCREEN_WIDTH + || f->want_fullscreen == FULLSCREEN_HEIGHT) + do_pending_window_change (0); + } else f->want_fullscreen |= FULLSCREEN_WAIT; @@ -6101,6 +6074,7 @@ x_set_window_size (struct frame *f, bool change_gravity, int width, int height, bool pixelwise) { int pixelwidth, pixelheight; + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); RECT rect; block_input (); @@ -6119,7 +6093,7 @@ x_set_window_size (struct frame *f, bool change_gravity, if (w32_add_wrapped_menu_bar_lines) { /* When the menu bar wraps sending a SetWindowPos shrinks the - height of the frame when the wrapped menu bar lines are not + height of the frame then the wrapped menu bar lines are not accounted for (Bug#15174 and Bug#18720). Here we add these extra lines to the frame height. */ MENUBARINFO info; @@ -6143,9 +6117,6 @@ x_set_window_size (struct frame *f, bool change_gravity, f->win_gravity = NorthWestGravity; x_wm_set_size_hint (f, (long) 0, false); - f->want_fullscreen = FULLSCREEN_NONE; - w32fullscreen_hook (f); - rect.left = rect.top = 0; rect.right = pixelwidth; rect.bottom = pixelheight; @@ -6153,45 +6124,45 @@ x_set_window_size (struct frame *f, bool change_gravity, AdjustWindowRect (&rect, f->output_data.w32->dwStyle, FRAME_EXTERNAL_MENU_BAR (f)); - my_set_window_pos (FRAME_W32_WINDOW (f), - NULL, - 0, 0, - rect.right - rect.left, - rect.bottom - rect.top, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - - /* If w32_enable_frame_resize_hack is non-nil, immediately apply the - new pixel sizes to the frame and its subwindows. - - Jason Rumney earlier refused to call change_frame_size right here - with the following argument: - - The following mirrors what is done in xterm.c. It appears to be for - informing lisp of the new size immediately, while the actual resize - will happen asynchronously. But on Windows, the menu bar - automatically wraps when the frame is too narrow to contain it, and - that causes any calculations made here to come out wrong. The end - is some nasty buggy behavior, including the potential loss of the - minibuffer. - - Disabling this code is either not sufficient to fix the problems - completely, or it causes fresh problems, but at least it removes - the most problematic symptom of the minibuffer becoming unusable. - - However, as the discussion about how to handle frame size - parameters on Windows (Bug#1348, Bug#16028) shows, that cure seems - worse than the disease. In particular, menu bar wrapping looks - like a non-issue - maybe so because Windows eventually gets back to - us with the correct client rectangle anyway. But we have to avoid - calling change_frame_size with a delta of less than one canoncial - character size when frame_resize_pixelwise is nil, as explained in - the comment above. */ - - if (w32_enable_frame_resize_hack) + if (!(f->after_make_frame) + && !(f->want_fullscreen & FULLSCREEN_WAIT) + && FRAME_VISIBLE_P (f)) + { + RECT window_rect; + + GetWindowRect (FRAME_W32_WINDOW (f), &window_rect); + if (EQ (fullscreen, Qmaximized) + || EQ (fullscreen, Qfullboth) + || EQ (fullscreen, Qfullwidth)) + { + rect.left = window_rect.left; + rect.right = window_rect.right; + pixelwidth = 0; + } + if (EQ (fullscreen, Qmaximized) + || EQ (fullscreen, Qfullboth) + || EQ (fullscreen, Qfullheight)) + { + rect.top = window_rect.top; + rect.bottom = window_rect.bottom; + pixelheight = 0; + } + } + + if (pixelwidth > 0 || pixelheight > 0) { - change_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), - FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight), + my_set_window_pos (FRAME_W32_WINDOW (f), NULL, + 0, 0, + rect.right - rect.left, + rect.bottom - rect.top, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + + change_frame_size (f, + ((pixelwidth == 0) + ? 0 : FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth)), + ((pixelheight == 0) + ? 0 : FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)), 0, 1, 0, 1); SET_FRAME_GARBAGED (f); @@ -7102,7 +7073,7 @@ Windows 8. It is set to nil on Windows 9X. */); w32_unicode_filenames = 0; - /* FIXME: The following two variables will be (hopefully) removed + /* FIXME: The following variable will be (hopefully) removed before Emacs 25.1 gets released. */ DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines", @@ -7116,16 +7087,6 @@ wrapped menu bar lines when sending frame resize requests to the Windows API. */); w32_add_wrapped_menu_bar_lines = 1; - DEFVAR_BOOL ("w32-enable-frame-resize-hack", - w32_enable_frame_resize_hack, - doc: /* Non-nil means enable hack for frame resizing on Windows. -A value of nil means to resize frames by sending a corresponding request -to the Windows API and changing the pixel sizes of the frame and its -windows after the latter calls back. If this is non-nil, Emacs changes -the pixel sizes of the frame and its windows at the time it sends the -resize request to the API. */); - w32_enable_frame_resize_hack = 1; - /* Tell Emacs about this window system. */ Fprovide (Qw32, Qnil); } diff --git a/src/widget.c b/src/widget.c index c4d69407176..acf559f313b 100644 --- a/src/widget.c +++ b/src/widget.c @@ -460,7 +460,7 @@ update_wm_hints (EmacsFrame ew) 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))); + + (rounded_height - (char_height * ch))); /* 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. @@ -573,39 +573,20 @@ EmacsFrameResize (Widget widget) { EmacsFrame ew = (EmacsFrame)widget; struct frame *f = ew->emacs_frame.frame; + int width, height; - /* Always process resize requests pixelwise. Frame maximizing - should work even when frame_resize_pixelwise is nil. */ - if (true || frame_resize_pixelwise) - { - int width, height; - - pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height); - change_frame_size (f, width, height, 0, 1, 0, 1); + pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height); - update_wm_hints (ew); - update_various_frame_slots (ew); + frame_size_history_add + (f, QEmacsFrameResize, width, height, + list2 (make_number (ew->core.width), make_number (ew->core.height))); - cancel_mouse_face (f); - } - else - { - struct x_output *x = f->output_data.x; - int columns, rows; + change_frame_size (f, width, height, 0, 1, 0, 1); - pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows); - if (columns != FRAME_COLS (f) - || rows != FRAME_LINES (f) - || ew->core.width != FRAME_PIXEL_WIDTH (f) - || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f)) - { - change_frame_size (f, columns, rows, 0, 1, 0, 0); - update_wm_hints (ew); - update_various_frame_slots (ew); + update_wm_hints (ew); + update_various_frame_slots (ew); - cancel_mouse_face (f); - } - } + cancel_mouse_face (f); } static XtGeometryResult diff --git a/src/window.c b/src/window.c index b4230100150..5cbd58ddde9 100644 --- a/src/window.c +++ b/src/window.c @@ -3332,7 +3332,7 @@ run_window_configuration_change_hook (struct frame *f) if (NILP (Vrun_hooks) || !(f->can_x_set_window_size) - || !(f->can_run_window_configuration_change_hook)) + || !(f->after_make_frame)) return; /* Use the right buffer. Matters when running the local hooks. */ diff --git a/src/xdisp.c b/src/xdisp.c index 4459363d3bc..faec93fc6f9 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9703,7 +9703,7 @@ in_display_vector_p (struct it *it) && it->dpvec + it->current.dpvec_index != it->dpend); } -DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0, +DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0, doc: /* Return the size of the text of WINDOW's buffer in pixels. WINDOW must be a live window and defaults to the selected one. The return value is a cons of the maximum pixel-width of any text line and @@ -9736,17 +9736,12 @@ Optional argument MODE-AND-HEADER-LINE nil or omitted means do not include the height of the mode- or header-line of WINDOW in the return value. If it is either the symbol `mode-line' or `header-line', include only the height of that line, if present, in the return value. If t, -include the height of both, if present, in the return value. - -Optional argument BUFFER nil means to return the size of the text of -WINDOW's buffer. BUFFER t means to return the size of the text of the -current buffer as if it were displayed in WINDOW. Else BUFFER has to -specify a live buffer and this function returns the size of the text of -BUFFER as if it were displayed in WINDOW. */) +include the height of both, if present, in the return value. */) (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, - Lisp_Object y_limit, Lisp_Object mode_and_header_line, Lisp_Object buffer) + Lisp_Object y_limit, Lisp_Object mode_and_header_line) { struct window *w = decode_live_window (window); + Lisp_Object buffer = w->contents; struct buffer *b; struct it it; struct buffer *old_b = NULL; @@ -9755,23 +9750,13 @@ BUFFER as if it were displayed in WINDOW. */) void *itdata = NULL; int c, max_y = -1, x = 0, y = 0; - if (EQ (buffer, Qt)) - b = current_buffer; - else - { - if (NILP (buffer)) - buffer = w->contents; - - CHECK_BUFFER (buffer); - if (!BUFFER_LIVE_P (XBUFFER (buffer))) - error ("Not a live buffer"); + CHECK_BUFFER (buffer); + b = XBUFFER (buffer); - b = XBUFFER (buffer); - if (b != current_buffer) - { - old_b = current_buffer; - set_buffer_internal (b); - } + if (b != current_buffer) + { + old_b = current_buffer; + set_buffer_internal (b); } if (NILP (from)) @@ -10184,7 +10169,7 @@ message3_nolog (Lisp_Object m) fwrite (SDATA (s), SBYTES (s), 1, stderr); } - if (cursor_in_echo_area == 0) + if (!cursor_in_echo_area) fprintf (stderr, "\n"); fflush (stderr); } @@ -10326,7 +10311,7 @@ vmessage (const char *m, va_list ap) putc ('\n', stderr); noninteractive_need_newline = 0; vfprintf (stderr, m, ap); - if (cursor_in_echo_area == 0) + if (!cursor_in_echo_area) fprintf (stderr, "\n"); fflush (stderr); } diff --git a/src/xfns.c b/src/xfns.c index 65eb6b497f2..629ac4b26ff 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1095,6 +1095,7 @@ x_change_tool_bar_height (struct frame *f, int height) int unit = FRAME_LINE_HEIGHT (f); int old_height = FRAME_TOOL_BAR_HEIGHT (f); int lines = (height + unit - 1) / unit; + Lisp_Object fullscreen; /* Make sure we redisplay all windows in this frame. */ windows_or_buffers_changed = 60; @@ -1126,7 +1127,10 @@ x_change_tool_bar_height (struct frame *f, int height) f->n_tool_bar_rows = 0; adjust_frame_size (f, -1, -1, - (!f->tool_bar_redisplayed_once ? 1 + ((!f->tool_bar_redisplayed_once + && (NILP (fullscreen = + get_frame_param (f, Qfullscreen)) + || EQ (fullscreen, Qfullwidth))) ? 1 : (old_height == 0 || height == 0) ? 2 : 4), false, Qtool_bar_lines); @@ -3180,8 +3184,6 @@ This function is an internal primitive--use `make-frame' instead. */) "title", "Title", RES_TYPE_STRING); x_default_parameter (f, parms, Qwait_for_wm, Qt, "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN); - x_default_parameter (f, parms, Qfullscreen, Qnil, - "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); x_default_parameter (f, parms, Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL); @@ -3259,6 +3261,12 @@ This function is an internal primitive--use `make-frame' instead. */) x_wm_set_size_hint (f, window_prompting, false); unblock_input (); + /* Process fullscreen parameter here in the hope that normalizing a + fullheight/fullwidth frame will produce the size set by the last + adjust_frame_size call. */ + x_default_parameter (f, parms, Qfullscreen, Qnil, + "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); + /* Make the window appear on the frame and enable display, unless the caller says not to. However, with explicit parent, Emacs cannot control visibility, so don't try. */ @@ -4318,7 +4326,7 @@ elements (all size values are in pixels). inner_height -= tool_bar_height; return - listn (CONSTYPE_PURE, 10, + listn (CONSTYPE_HEAP, 10, Fcons (Qframe_position, Fcons (make_number (f->left_pos), make_number (f->top_pos))), Fcons (Qframe_outer_size, diff --git a/src/xterm.c b/src/xterm.c index abceefb1b0e..555af2b536c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -215,7 +215,7 @@ enum xembed_message }; static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *); -static void x_set_window_size_1 (struct frame *, bool, int, int, bool); +static void x_set_window_size_1 (struct frame *, bool, int, int); static void x_raise_frame (struct frame *); static void x_lower_frame (struct frame *); static const XColor *x_color_cells (Display *, int *); @@ -6585,6 +6585,10 @@ x_net_wm_state (struct frame *f, Window window) break; } + frame_size_history_add + (f, Qx_net_wm_state, 0, 0, + list2 (get_frame_param (f, Qfullscreen), lval)); + store_frame_param (f, Qfullscreen, lval); /** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/ } @@ -9242,30 +9246,78 @@ do_ewmh_fullscreen (struct frame *f) None); break; case FULLSCREEN_WIDTH: - if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT - || cur == FULLSCREEN_MAXIMIZED) - set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, - dpyinfo->Xatom_net_wm_state_maximized_vert); - if (cur != FULLSCREEN_MAXIMIZED) - set_wm_state (frame, true, - dpyinfo->Xatom_net_wm_state_maximized_horz, None); + if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED) + { + set_wm_state (frame, false, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, None); + } + else + { + if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT + || cur == FULLSCREEN_MAXIMIZED) + set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, + dpyinfo->Xatom_net_wm_state_maximized_vert); + if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize) + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, None); + } break; case FULLSCREEN_HEIGHT: - if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH - || cur == FULLSCREEN_MAXIMIZED) - set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, - dpyinfo->Xatom_net_wm_state_maximized_horz); - if (cur != FULLSCREEN_MAXIMIZED) - set_wm_state (frame, true, - dpyinfo->Xatom_net_wm_state_maximized_vert, None); + if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED) + { + set_wm_state (frame, false, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_vert, None); + } + else + { + if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH + || cur == FULLSCREEN_MAXIMIZED) + set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, + dpyinfo->Xatom_net_wm_state_maximized_horz); + if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize) + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_vert, None); + } break; case FULLSCREEN_MAXIMIZED: - if (cur == FULLSCREEN_BOTH) - set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, - None); - set_wm_state (frame, true, - dpyinfo->Xatom_net_wm_state_maximized_horz, - dpyinfo->Xatom_net_wm_state_maximized_vert); + if (x_frame_normalize_before_maximize && cur == FULLSCREEN_WIDTH) + { + set_wm_state (frame, false, + dpyinfo->Xatom_net_wm_state_maximized_horz, None); + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + } + else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_HEIGHT) + { + set_wm_state (frame, false, + dpyinfo->Xatom_net_wm_state_maximized_vert, None); + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + } + else + { + if (cur == FULLSCREEN_BOTH) + set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, + None); + else if (cur == FULLSCREEN_HEIGHT) + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, None); + else if (cur == FULLSCREEN_WIDTH) + set_wm_state (frame, true, None, + dpyinfo->Xatom_net_wm_state_maximized_vert); + else + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + } break; case FULLSCREEN_NONE: if (cur == FULLSCREEN_BOTH) @@ -9322,6 +9374,10 @@ x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event) break; } + frame_size_history_add + (f, Qx_handle_net_wm_state, 0, 0, + list2 (get_frame_param (f, Qfullscreen), lval)); + store_frame_param (f, Qfullscreen, lval); store_frame_param (f, Qsticky, sticky ? Qt : Qnil); @@ -9358,13 +9414,26 @@ x_check_fullscreen (struct frame *f) break; case FULLSCREEN_WIDTH: width = x_display_pixel_width (dpyinfo); - break; + height = height + FRAME_MENUBAR_HEIGHT (f); + break; case FULLSCREEN_HEIGHT: height = x_display_pixel_height (dpyinfo); } + frame_size_history_add + (f, Qx_check_fullscreen, width, height, Qnil); + XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), - width, height); + width, height); + + if (FRAME_VISIBLE_P (f)) + x_wait_for_event (f, ConfigureNotify); + else + { + change_frame_size (f, width, height - FRAME_MENUBAR_HEIGHT (f), + false, true, false, true); + x_sync (f); + } } } @@ -9505,21 +9574,57 @@ x_wait_for_event (struct frame *f, int eventtype) static void x_set_window_size_1 (struct frame *f, bool change_gravity, - int width, int height, bool pixelwise) + int width, int height) { - int pixelwidth, pixelheight; - - pixelwidth = (pixelwise - ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) - : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)); - pixelheight = ((pixelwise - ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height) - : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))); + int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); + int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); + int old_width = FRAME_PIXEL_WIDTH (f); + int old_height = FRAME_PIXEL_HEIGHT (f); + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); if (change_gravity) f->win_gravity = NorthWestGravity; x_wm_set_size_hint (f, 0, false); - XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), - pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); + + /* When the frame is fullheight and we only want to change the width + or it is fullwidth and we only want to change the height we should + be able to preserve the fullscreen property. However, due to the + fact that we have to send a resize request anyway, the window + manager will abolish it. At least the respective size should + remain unchanged but giving the frame back its normal size will + be broken ... */ + if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f)) + { + frame_size_history_add + (f, Qxg_frame_set_char_size_1, width, height, + list2 (make_number (old_height), + make_number (pixelheight + FRAME_MENUBAR_HEIGHT (f)))); + + XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + old_width, pixelheight + FRAME_MENUBAR_HEIGHT (f)); + } + else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f)) + { + frame_size_history_add + (f, Qxg_frame_set_char_size_2, width, height, + list2 (make_number (old_width), make_number (pixelwidth))); + + XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + pixelwidth, old_height); + } + + else + { + frame_size_history_add + (f, Qxg_frame_set_char_size_3, width, height, + list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)), + make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f) + + FRAME_MENUBAR_HEIGHT (f)))); + + XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); + fullscreen = Qnil; + } + /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to @@ -9546,7 +9651,16 @@ x_set_window_size_1 (struct frame *f, bool change_gravity, not right if the frame is visible. Instead wait (with timeout) for the ConfigureNotify. */ if (FRAME_VISIBLE_P (f)) - x_wait_for_event (f, ConfigureNotify); + { + x_wait_for_event (f, ConfigureNotify); + + if (!NILP (fullscreen)) + /* Try to restore fullscreen state. */ + { + store_frame_param (f, Qfullscreen, fullscreen); + x_set_fullscreen (f, fullscreen, fullscreen); + } + } else { change_frame_size (f, width, height, false, true, false, true); @@ -9593,20 +9707,21 @@ x_set_window_size (struct frame *f, bool change_gravity, } #endif + /* Pixelize width and height, if necessary. */ + if (! pixelwise) + { + width = width * FRAME_COLUMN_WIDTH (f); + height = height * FRAME_LINE_HEIGHT (f); + } + #ifdef USE_GTK if (FRAME_GTK_WIDGET (f)) - if (! pixelwise) - xg_frame_set_char_size (f, width * FRAME_COLUMN_WIDTH (f), - height * FRAME_LINE_HEIGHT (f)); - else - xg_frame_set_char_size (f, width, height); + xg_frame_set_char_size (f, width, height); else - x_set_window_size_1 (f, change_gravity, width, height, pixelwise); + x_set_window_size_1 (f, change_gravity, width, height); #else /* not USE_GTK */ - - x_set_window_size_1 (f, change_gravity, width, height, pixelwise); + x_set_window_size_1 (f, change_gravity, width, height); x_clear_under_internal_border (f); - #endif /* not USE_GTK */ /* If cursor was outside the new size, mark it as off. */ @@ -11617,4 +11732,15 @@ default is nil, which is the same as `super'. */); make_float (DEFAULT_REHASH_SIZE), make_float (DEFAULT_REHASH_THRESHOLD), Qnil); + + DEFVAR_BOOL ("x-frame-normalize-before-maximize", + x_frame_normalize_before_maximize, + doc: /* Non-nil means normalize frame before maximizing. +If this variable is t, Emacs asks the window manager to give the frame +intermediately its normal size whenever changing from a full-height or +full-width state to the fully maximized one and vice versa. + +Set this variable only if your window manager cannot handle the +transition between the various maximization states. */); + x_frame_normalize_before_maximize = false; } |