summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog126
-rw-r--r--src/data.c5
-rw-r--r--src/dispnew.c135
-rw-r--r--src/eval.c22
-rw-r--r--src/frame.c208
-rw-r--r--src/frame.h13
-rw-r--r--src/gtkutil.c118
-rw-r--r--src/w32fns.c18
-rw-r--r--src/w32term.c217
-rw-r--r--src/widget.c39
-rw-r--r--src/window.c2
-rw-r--r--src/xdisp.c39
-rw-r--r--src/xfns.c16
-rw-r--r--src/xterm.c214
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;
}