aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoakim Verona2015-02-08 21:55:28 +0100
committerJoakim Verona2015-02-08 21:55:28 +0100
commit5e1d5ef39ca0d2fbff26d659f2ec6ce863b14529 (patch)
tree860e0d53399626aee6249ebb5f972879f403b228 /src
parent148262ce3db990ed16989341345e232570b3a338 (diff)
parent7d631aa0ffab875e4979727f632703ad5b4100a2 (diff)
downloademacs-xwidget.tar.gz
emacs-xwidget.zip
merge masterxwidget
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 @@
12015-02-08 Paul Eggert <eggert@cs.ucla.edu>
2
3 Minor tweaks to frame_size_history_add
4 * frame.c (frame_size_history_add): Don't assume length fits in 'int'.
5 Prefer XCAR and XCDR to Fcar and Fcdr when the arg is a cons.
6 (Fframe_after_make_frame): Simplify.
7 * gtkutil.c: Remove commented-out code.
8 * xfns.c (Fx_create_frame): Fix indenting.
9
102015-02-08 Eli Zaretskii <eliz@gnu.org>
11
12 * frame.c (Fframe_parameter): Don't replace a non-nil value of
13 foreground-color or background-color parameters with a nil value.
14 (Bug#19802)
15
162015-02-08 Stefan Monnier <monnier@iro.umontreal.ca>
17
18 * data.c (Findirect_function): Like `symbol-function', don't signal an
19 error for void functions any more.
20
212015-02-07 Martin Rudalics <rudalics@gmx.at>
22
23 * frame.c (frame_size_history_add): New function.
24 (frame_inhibit_resize): Consider frame_inhibit_implied_resize
25 only after frame's after_make_frame slot is true.
26 Inhibit resizing fullwidth-/height frames in one direction only.
27 Update frame_size_history.
28 (adjust_frame_size): Call frame_size_history_add.
29 (make_frame): Initalize after_make_frame slot.
30 (Fmake_terminal_frame): Adjust adjust_frame_size call.
31 (Fcan_run_window_configuration_change_hook): Rename to
32 Fframe_after_make_frame. Set after_make_frame slot.
33 Return second argument.
34 (x_set_frame_parameters): Postpone handling fullscreen parameter
35 until after width and height parameters have been set.
36 Apply width and height changes only if can_x_set_window_size is true.
37 Update frame_size_history.
38 (Qadjust_frame_size_1, Qadjust_frame_size_2)
39 (Qadjust_frame_size_3, QEmacsFrameResize, Qframe_inhibit_resize)
40 (Qx_set_fullscreen, Qx_check_fullscreen, Qx_set_window_size_1)
41 (Qxg_frame_resized, Qxg_frame_set_char_size_1)
42 (Qxg_frame_set_char_size_2, Qxg_frame_set_char_size_3)
43 (Qxg_change_toolbar_position, Qx_net_wm_state)
44 (Qx_handle_net_wm_state, Qtb_size_cb, Qupdate_frame_tool_bar)
45 (Qfree_frame_tool_bar): New symbol for updating frame_size_history.
46 (Qtip_frame, Qterminal_frame): New symbols.
47 (Vframe_adjust_size_history): Rename to frame_size_history.
48 * frame.h (struct frame):
49 Rename can_run_window_configuration_change_hook slot to
50 after_make_frame.
51 (frame_size_history_add): Extern.
52 * gtkutil.c (xg_frame_resized): Call frame_size_history_add.
53 Don't set FRAME_PIXEL_WIDTH and FRAME_PIXEL_HEIGHT here.
54 (xg_frame_set_char_size): Try to preserve the status of
55 fullwidth/-height frames. Call frame_size_history_add.
56 (tb_size_cb, update_frame_tool_bar, free_frame_tool_bar)
57 (xg_change_toolbar_position): Call frame_size_history_add.
58 * w32fns.c (x_change_tool_bar_height): Handle frame's fullscreen
59 status.
60 (Fx_create_frame): Process fullscreen parameter after frame has
61 been resized.
62 (x_create_tip_frame): Pass Qtip_frame to adjust_frame_size.
63 (Fx_frame_geometry): Don't pollute pure storage.
64 * w32term.c (w32_read_socket): For WM_WINDOWPOSCHANGED,
65 WM_ACTIVATE and WM_ACTIVATEAPP set frame's visibility before
66 calling w32fullscreen_hook. For WM_DISPLAYCHANGE call
67 w32fullscreen_hook immediately.
68 (x_fullscreen_adjust, x_check_fullscreen): Remove.
69 (w32fullscreen_hook): Call change_frame_size just as with a
70 "normal" frame resize operation. Call do_pending_window_change.
71 (x_set_window_size): Try to handle fullwidth and fullheight more
72 accurately. Don't rely on w32_enable_frame_resize_hack.
73 (w32_enable_frame_resize_hack): Remove variable.
74 * widget.c (EmacsFrameResize): Remove dead code.
75 Call frame_size_history_add
76 * window.c (run_window_configuration_change_hook):
77 Check f->after_make_frame instead of
78 f->can_run_window_configuration_change_hook.
79 * xfns.c (x_change_tool_bar_height): Handle frame's fullscreen status.
80 (Fx_create_frame): Process fullscreen parameter after frame has
81 been resized.
82 (Fx_frame_geometry): Don't pollute pure storage.
83 * xterm.c (x_net_wm_state, x_handle_net_wm_state):
84 Call frame_size_history_add.
85 (do_ewmh_fullscreen): Handle x_frame_normalize_before_maximize.
86 (x_check_fullscreen): Count in menubar when calling
87 XResizeWindow. Wait for ConfigureNotify event.
88 Call frame_size_history_add.
89 (x_set_window_size_1): Remove PIXELWISE argument. Try to handle
90 changing a fullheight frame's width or a fullwidth frame's
91 height. Call frame_size_history_add.
92 (x_set_window_size): Simplify xg_frame_set_char_size and
93 x_set_window_size_1 calls.
94 (x_frame_normalize_before_maximize): New variable.
95
962015-02-07 Paul Eggert <eggert@cs.ucla.edu>
97
98 Remove no-longer-used cursor_in_echo_area code
99 * dispnew.c (set_window_cursor_after_update, update_frame_1):
100 Remove checks for negative cursor_in_echo_area, since this var is
101 a boolean, and has been a boolean for some time. Simplify.
102 * dispnew.c (init_display):
103 * xdisp.c (message3_nolog, vmessage): Use bool for boolean.
104
1052015-02-05 Stefan Monnier <monnier@iro.umontreal.ca>
106
107 * eval.c (Ffunction): Handle the new (:documentation ...) form.
108 (syms_of_eval): Declare `:documentation'.
109
1102015-02-05 Martin Rudalics <rudalics@gmx.at>
111
112 * xdisp.c (Fwindow_text_pixel_size): Remove optional BUFFER
113 argument added on 2015-02-01.
114
12015-02-04 Paul Eggert <eggert@cs.ucla.edu> 1152015-02-04 Paul Eggert <eggert@cs.ucla.edu>
2 116
3 Remove no-longer-used two_byte_p calculations 117 Remove no-longer-used two_byte_p calculations
@@ -224,8 +338,8 @@
224 (x_horizontal_scroll_bar_report_motion, w32_read_socket) 338 (x_horizontal_scroll_bar_report_motion, w32_read_socket)
225 (w32_set_vertical_scroll_bar, w32_set_horizontal_scroll_bar) 339 (w32_set_vertical_scroll_bar, w32_set_horizontal_scroll_bar)
226 (w32_draw_window_cursor, x_new_font, x_set_offset) 340 (w32_draw_window_cursor, x_new_font, x_set_offset)
227 (x_set_window_size, x_make_frame_invisible, x_iconify_frame): Use 341 (x_set_window_size, x_make_frame_invisible, x_iconify_frame):
228 bool where appropriate. 342 Use bool where appropriate.
229 343
230 Use bool for boolean in w32fns.c 344 Use bool for boolean in w32fns.c
231 * w32fns.c (w32_defined_color, x_decode_color) 345 * w32fns.c (w32_defined_color, x_decode_color)
@@ -694,8 +808,8 @@
694 Qx_create_frame_2 to adjust_frame_size. 808 Qx_create_frame_2 to adjust_frame_size.
695 * w32menu.c (set_frame_menubar): Simplify adjust_frame_size 809 * w32menu.c (set_frame_menubar): Simplify adjust_frame_size
696 call. 810 call.
697 * window.c (Fset_window_configuration): Pass 811 * window.c (Fset_window_configuration):
698 Qset_window_configuration to adjust_frame_size. 812 Pass Qset_window_configuration to adjust_frame_size.
699 * xdisp.c (redisplay_tool_bar): Assign new height to 813 * xdisp.c (redisplay_tool_bar): Assign new height to
700 frame_default_tool_bar_height. 814 frame_default_tool_bar_height.
701 (redisplay_internal): If we haven't redisplayed this frame's 815 (redisplay_internal): If we haven't redisplayed this frame's
@@ -763,8 +877,8 @@
763 877
764 * w32fns.c (Fw32_register_hot_key): Use XINT instead of XLI. 878 * w32fns.c (Fw32_register_hot_key): Use XINT instead of XLI.
765 879
766 * w32notify.c (Fw32notify_add_watch, w32_get_watch_object): Use 880 * w32notify.c (Fw32notify_add_watch, w32_get_watch_object):
767 make_pointer_integer instead of XIL. 881 Use make_pointer_integer instead of XIL.
768 (Fw32notify_rm_watch): Use XINTPTR instead of XLI. 882 (Fw32notify_rm_watch): Use XINTPTR instead of XLI.
769 883
770 * w32inevt.c (handle_file_notifications): Use make_pointer_integer 884 * 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,
2125 doc: /* Return the function at the end of OBJECT's function chain. 2125 doc: /* Return the function at the end of OBJECT's function chain.
2126If OBJECT is not a symbol, just return it. Otherwise, follow all 2126If OBJECT is not a symbol, just return it. Otherwise, follow all
2127function indirections to find the final function binding and return it. 2127function indirections to find the final function binding and return it.
2128If the final symbol in the chain is unbound, signal a void-function error.
2129Optional arg NOERROR non-nil means to return nil instead of signaling.
2130Signal a cyclic-function-indirection error if there is a loop in the 2128Signal a cyclic-function-indirection error if there is a loop in the
2131function chain of symbols. */) 2129function chain of symbols. */)
2132 (register Lisp_Object object, Lisp_Object noerror) 2130 (register Lisp_Object object, Lisp_Object noerror)
@@ -2141,9 +2139,6 @@ function chain of symbols. */)
2141 if (!NILP (result)) 2139 if (!NILP (result))
2142 return result; 2140 return result;
2143 2141
2144 if (NILP (noerror))
2145 xsignal1 (Qvoid_function, object);
2146
2147 return Qnil; 2142 return Qnil;
2148} 2143}
2149 2144
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)
3911 { 3911 {
3912 cx = cy = vpos = hpos = 0; 3912 cx = cy = vpos = hpos = 0;
3913 3913
3914 if (cursor_in_echo_area >= 0) 3914 /* If the mini-buffer is several lines high, find the last
3915 line that has any text on it. Note: either all lines
3916 are enabled or none. Otherwise we wouldn't be able to
3917 determine Y. */
3918 struct glyph_row *last_row = NULL;
3919 int yb = window_text_bottom_y (w);
3920
3921 for (struct glyph_row *row = w->current_matrix->rows;
3922 row->enabled_p && (!last_row || MATRIX_ROW_BOTTOM_Y (row) <= yb);
3923 row++)
3924 if (row->used[TEXT_AREA] && row->glyphs[TEXT_AREA][0].charpos >= 0)
3925 last_row = row;
3926
3927 if (last_row)
3915 { 3928 {
3916 /* If the mini-buffer is several lines high, find the last 3929 struct glyph *start = last_row->glyphs[TEXT_AREA];
3917 line that has any text on it. Note: either all lines 3930 struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
3918 are enabled or none. Otherwise we wouldn't be able to
3919 determine Y. */
3920 struct glyph_row *row, *last_row;
3921 struct glyph *glyph;
3922 int yb = window_text_bottom_y (w);
3923
3924 last_row = NULL;
3925 row = w->current_matrix->rows;
3926 while (row->enabled_p
3927 && (last_row == NULL
3928 || MATRIX_ROW_BOTTOM_Y (row) <= yb))
3929 {
3930 if (row->used[TEXT_AREA]
3931 && row->glyphs[TEXT_AREA][0].charpos >= 0)
3932 last_row = row;
3933 ++row;
3934 }
3935 3931
3936 if (last_row) 3932 while (last > start && last->charpos < 0)
3937 { 3933 --last;
3938 struct glyph *start = last_row->glyphs[TEXT_AREA];
3939 struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
3940
3941 while (last > start && last->charpos < 0)
3942 --last;
3943 3934
3944 for (glyph = start; glyph < last; ++glyph) 3935 for (struct glyph *glyph = start; glyph < last; glyph++)
3945 { 3936 {
3946 cx += glyph->pixel_width; 3937 cx += glyph->pixel_width;
3947 ++hpos; 3938 hpos++;
3948 }
3949
3950 cy = last_row->y;
3951 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
3952 } 3939 }
3940
3941 cy = last_row->y;
3942 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
3953 } 3943 }
3954 } 3944 }
3955 else 3945 else
@@ -4569,58 +4559,43 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4569 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)) 4559 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4570 { 4560 {
4571 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f))); 4561 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
4572 int row, col; 4562 int col;
4573 4563
4574 if (cursor_in_echo_area < 0) 4564 /* Put cursor at the end of the prompt. If the mini-buffer
4565 is several lines high, find the last line that has
4566 any text on it. */
4567 int row = FRAME_TOTAL_LINES (f);
4568 do
4575 { 4569 {
4576 /* Negative value of cursor_in_echo_area means put 4570 row--;
4577 cursor at beginning of line. */
4578 row = top;
4579 col = 0; 4571 col = 0;
4580 }
4581 else
4582 {
4583 /* Positive value of cursor_in_echo_area means put
4584 cursor at the end of the prompt. If the mini-buffer
4585 is several lines high, find the last line that has
4586 any text on it. */
4587 row = FRAME_TOTAL_LINES (f);
4588 do
4589 {
4590 --row;
4591 col = 0;
4592 4572
4593 if (MATRIX_ROW_ENABLED_P (current_matrix, row)) 4573 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
4594 { 4574 {
4595 /* Frame rows are filled up with spaces that 4575 /* Frame rows are filled up with spaces that
4596 must be ignored here. */ 4576 must be ignored here. */
4597 struct glyph_row *r = MATRIX_ROW (current_matrix, 4577 struct glyph_row *r = MATRIX_ROW (current_matrix, row);
4598 row); 4578 struct glyph *start = r->glyphs[TEXT_AREA];
4599 struct glyph *start = r->glyphs[TEXT_AREA]; 4579
4600 struct glyph *last = start + r->used[TEXT_AREA]; 4580 col = r->used[TEXT_AREA];
4601 4581 while (0 < col && start[col - 1].charpos < 0)
4602 while (last > start 4582 col--;
4603 && (last - 1)->charpos < 0)
4604 --last;
4605
4606 col = last - start;
4607 }
4608 } 4583 }
4609 while (row > top && col == 0); 4584 }
4585 while (row > top && col == 0);
4610 4586
4611 /* Make sure COL is not out of range. */ 4587 /* Make sure COL is not out of range. */
4612 if (col >= FRAME_CURSOR_X_LIMIT (f)) 4588 if (col >= FRAME_CURSOR_X_LIMIT (f))
4589 {
4590 /* If we have another row, advance cursor into it. */
4591 if (row < FRAME_TOTAL_LINES (f) - 1)
4613 { 4592 {
4614 /* If we have another row, advance cursor into it. */ 4593 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
4615 if (row < FRAME_TOTAL_LINES (f) - 1) 4594 row++;
4616 {
4617 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
4618 row++;
4619 }
4620 /* Otherwise move it back in range. */
4621 else
4622 col = FRAME_CURSOR_X_LIMIT (f) - 1;
4623 } 4595 }
4596 /* Otherwise move it back in range. */
4597 else
4598 col = FRAME_CURSOR_X_LIMIT (f) - 1;
4624 } 4599 }
4625 4600
4626 cursor_to (f, row, col); 4601 cursor_to (f, row, col);
@@ -5966,7 +5941,7 @@ init_display (void)
5966 space_glyph.charpos = -1; 5941 space_glyph.charpos = -1;
5967 5942
5968 inverse_video = 0; 5943 inverse_video = 0;
5969 cursor_in_echo_area = 0; 5944 cursor_in_echo_area = false;
5970 5945
5971 /* Now is the time to initialize this; it's used by init_sys_modes 5946 /* Now is the time to initialize this; it's used by init_sys_modes
5972 during startup. */ 5947 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) */)
575 if (!NILP (Vinternal_interpreter_environment) 575 if (!NILP (Vinternal_interpreter_environment)
576 && CONSP (quoted) 576 && CONSP (quoted)
577 && EQ (XCAR (quoted), Qlambda)) 577 && EQ (XCAR (quoted), Qlambda))
578 /* This is a lambda expression within a lexical environment; 578 { /* This is a lambda expression within a lexical environment;
579 return an interpreted closure instead of a simple lambda. */ 579 return an interpreted closure instead of a simple lambda. */
580 return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, 580 Lisp_Object cdr = XCDR (quoted);
581 XCDR (quoted))); 581 Lisp_Object tmp = cdr;
582 if (CONSP (tmp)
583 && (tmp = XCDR (tmp), CONSP (tmp))
584 && (tmp = XCAR (tmp), CONSP (tmp))
585 && (EQ (QCdocumentation, XCAR (tmp))))
586 { /* Handle the special (:documentation <form>) to build the docstring
587 dynamically. */
588 Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp)));
589 CHECK_STRING (docstring);
590 cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr))));
591 }
592 return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment,
593 cdr));
594 }
582 else 595 else
583 /* Simply quote the argument. */ 596 /* Simply quote the argument. */
584 return quoted; 597 return quoted;
@@ -3668,6 +3681,7 @@ before making `inhibit-quit' nil. */);
3668 DEFSYM (Qand_rest, "&rest"); 3681 DEFSYM (Qand_rest, "&rest");
3669 DEFSYM (Qand_optional, "&optional"); 3682 DEFSYM (Qand_optional, "&optional");
3670 DEFSYM (Qclosure, "closure"); 3683 DEFSYM (Qclosure, "closure");
3684 DEFSYM (QCdocumentation, ":documentation");
3671 DEFSYM (Qdebug, "debug"); 3685 DEFSYM (Qdebug, "debug");
3672 3686
3673 DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger, 3687 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)
149 return Fcdr (tem); 149 return Fcdr (tem);
150} 150}
151 151
152
153void
154frame_size_history_add (struct frame *f, Lisp_Object fun_symbol,
155 int width, int height, Lisp_Object rest)
156{
157 Lisp_Object frame;
158
159 XSETFRAME (frame, f);
160 if (CONSP (frame_size_history)
161 && INTEGERP (XCAR (frame_size_history))
162 && 0 < XINT (XCAR (frame_size_history)))
163 frame_size_history =
164 Fcons (make_number (XINT (XCAR (frame_size_history)) - 1),
165 Fcons (list4
166 (frame, fun_symbol,
167 ((width > 0)
168 ? list4 (make_number (FRAME_TEXT_WIDTH (f)),
169 make_number (FRAME_TEXT_HEIGHT (f)),
170 make_number (width),
171 make_number (height))
172 : Qnil),
173 rest),
174 XCDR (frame_size_history)));
175}
176
177
152/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen 178/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
153 state of frame F would be affected by a vertical (horizontal if 179 state of frame F would be affected by a vertical (horizontal if
154 HORIZONTAL is true) resize. PARAMETER is the symbol of the frame 180 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)
156bool 182bool
157frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter) 183frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
158{ 184{
159 return (EQ (frame_inhibit_implied_resize, Qt) 185 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
160 || (CONSP (frame_inhibit_implied_resize) 186 bool inhibit
161 && !NILP (Fmemq (parameter, frame_inhibit_implied_resize))) 187 = ((f->after_make_frame
162 || !NILP (get_frame_param (f, Qfullscreen)) 188 && (EQ (frame_inhibit_implied_resize, Qt)
163 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); 189 || (CONSP (frame_inhibit_implied_resize)
190 && !NILP (Fmemq (parameter, frame_inhibit_implied_resize)))))
191 || (horizontal
192 && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullheight))
193 || (!horizontal
194 && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullwidth))
195 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
196
197 if (inhibit && !FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
198 frame_size_history_add
199 (f, Qframe_inhibit_resize, 0, 0,
200 list5 (horizontal ? Qt : Qnil, parameter,
201 f->after_make_frame ? Qt : Qnil,
202 frame_inhibit_implied_resize,
203 fullscreen));
204
205 return inhibit;
164} 206}
165 207
166static void 208static void
@@ -369,18 +411,9 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
369 411
370 XSETFRAME (frame, f); 412 XSETFRAME (frame, f);
371 413
372 /* `make-frame' initializes Vframe_adjust_size_history to (Qt) and 414 frame_size_history_add
373 strips its car when exiting. Just in case make sure its size never 415 (f, Qadjust_frame_size_1, new_text_width, new_text_height,
374 exceeds 100. */ 416 list2 (parameter, make_number (inhibit)));
375 if (!NILP (Fconsp (Vframe_adjust_size_history))
376 && EQ (Fcar (Vframe_adjust_size_history), Qt)
377 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100)
378 Vframe_adjust_size_history =
379 Fcons (Qt, Fcons (list5 (make_number (0),
380 make_number (new_text_width),
381 make_number (new_text_height),
382 make_number (inhibit), parameter),
383 Fcdr (Vframe_adjust_size_history)));
384 417
385 /* The following two values are calculated from the old window body 418 /* The following two values are calculated from the old window body
386 sizes and any "new" settings for scroll bars, dividers, fringes and 419 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,
391 = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt); 424 = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt);
392 425
393 if (inhibit >= 2 && inhibit <= 4) 426 if (inhibit >= 2 && inhibit <= 4)
394 /* If INHIBIT is in [2..4] inhibit if the "old" window sizes stay 427 /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
395 within the limits and either frame_inhibit_resize tells us to do 428 within the limits and either frame_inhibit_resize tells us to do
396 so or INHIBIT equals 4. */ 429 so or INHIBIT equals 4. */
397 { 430 {
@@ -449,16 +482,10 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
449 else if (inhibit_vertical) 482 else if (inhibit_vertical)
450 new_text_height = old_text_height; 483 new_text_height = old_text_height;
451 484
452 if (!NILP (Fconsp (Vframe_adjust_size_history)) 485 frame_size_history_add
453 && EQ (Fcar (Vframe_adjust_size_history), Qt) 486 (f, Qadjust_frame_size_2, new_text_width, new_text_height,
454 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100) 487 list2 (inhibit_horizontal ? Qt : Qnil,
455 Vframe_adjust_size_history = 488 inhibit_vertical ? Qt : Qnil));
456 Fcons (Qt, Fcons (list5 (make_number (1),
457 make_number (new_text_width),
458 make_number (new_text_height),
459 make_number (new_cols),
460 make_number (new_lines)),
461 Fcdr (Vframe_adjust_size_history)));
462 489
463 x_set_window_size (f, 0, new_text_width, new_text_height, 1); 490 x_set_window_size (f, 0, new_text_width, new_text_height, 1);
464 f->resized_p = true; 491 f->resized_p = true;
@@ -525,6 +552,11 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
525 FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f); 552 FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f);
526 } 553 }
527 554
555 frame_size_history_add
556 (f, Qadjust_frame_size_3, new_text_width, new_text_height,
557 list4 (make_number (old_pixel_width), make_number (old_pixel_height),
558 make_number (new_pixel_width), make_number (new_pixel_height)));
559
528 /* Assign new sizes. */ 560 /* Assign new sizes. */
529 FRAME_TEXT_WIDTH (f) = new_text_width; 561 FRAME_TEXT_WIDTH (f) = new_text_width;
530 FRAME_TEXT_HEIGHT (f) = new_text_height; 562 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,
533 SET_FRAME_COLS (f, new_cols); 565 SET_FRAME_COLS (f, new_cols);
534 SET_FRAME_LINES (f, new_lines); 566 SET_FRAME_LINES (f, new_lines);
535 567
536 if (!NILP (Fconsp (Vframe_adjust_size_history))
537 && EQ (Fcar (Vframe_adjust_size_history), Qt)
538 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100)
539 Vframe_adjust_size_history =
540 Fcons (Qt, Fcons (list5 (make_number (2),
541 make_number (new_text_width),
542 make_number (new_text_height),
543 make_number (new_cols),
544 make_number (new_lines)),
545 Fcdr (Vframe_adjust_size_history)));
546
547 { 568 {
548 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); 569 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
549 int text_area_x, text_area_y, text_area_width, text_area_height; 570 int text_area_x, text_area_y, text_area_width, text_area_height;
@@ -608,7 +629,7 @@ make_frame (bool mini_p)
608 f->redisplay = true; 629 f->redisplay = true;
609 f->garbaged = true; 630 f->garbaged = true;
610 f->can_x_set_window_size = false; 631 f->can_x_set_window_size = false;
611 f->can_run_window_configuration_change_hook = false; 632 f->after_make_frame = false;
612 f->tool_bar_redisplayed_once = false; 633 f->tool_bar_redisplayed_once = false;
613 f->column_width = 1; /* !FRAME_WINDOW_P value. */ 634 f->column_width = 1; /* !FRAME_WINDOW_P value. */
614 f->line_height = 1; /* !FRAME_WINDOW_P value. */ 635 f->line_height = 1; /* !FRAME_WINDOW_P value. */
@@ -1020,7 +1041,8 @@ affects all frames on the same terminal device. */)
1020 { 1041 {
1021 int width, height; 1042 int width, height;
1022 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height); 1043 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1023 adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0, Qnil); 1044 adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f),
1045 5, 0, Qterminal_frame);
1024 } 1046 }
1025 1047
1026 adjust_frame_glyphs (f); 1048 adjust_frame_glyphs (f);
@@ -2260,24 +2282,23 @@ If there is no window system support, this function does nothing. */)
2260 return Qnil; 2282 return Qnil;
2261} 2283}
2262 2284
2263DEFUN ("frame-can-run-window-configuration-change-hook", 2285DEFUN ("frame-after-make-frame",
2264 Fcan_run_window_configuration_change_hook, 2286 Fframe_after_make_frame,
2265 Scan_run_window_configuration_change_hook, 2, 2, 0, 2287 Sframe_after_make_frame, 2, 2, 0,
2266 doc: /* Whether `window-configuration-change-hook' is run for frame FRAME. 2288 doc: /* Mark FRAME as made.
2267FRAME nil means use the selected frame. Second argument ALLOW non-nil 2289FRAME nil means use the selected frame. Second argument MADE non-nil
2268means functions on `window-configuration-change-hook' are called 2290means functions on `window-configuration-change-hook' are called
2269whenever the window configuration of FRAME changes. ALLOW nil means 2291whenever the window configuration of FRAME changes. MADE nil means
2270these functions are not called. 2292these functions are not called.
2271 2293
2272This function is currently called by `face-set-after-frame-default' only 2294This function is currently called by `make-frame' only and should be
2273and should be otherwise used with utter care to avoid that running 2295otherwise used with utter care to avoid that running functions on
2274functions on `window-configuration-change-hook' is impeded forever. */) 2296`window-configuration-change-hook' is impeded forever. */)
2275 (Lisp_Object frame, Lisp_Object allow) 2297 (Lisp_Object frame, Lisp_Object made)
2276{ 2298{
2277 struct frame *f = decode_live_frame (frame); 2299 struct frame *f = decode_live_frame (frame);
2278 2300 f->after_make_frame = !NILP (made);
2279 f->can_run_window_configuration_change_hook = NILP (allow) ? false : true; 2301 return made;
2280 return Qnil;
2281} 2302}
2282 2303
2283 2304
@@ -2591,7 +2612,12 @@ If FRAME is nil, describe the currently selected frame. */)
2591 important when param_alist's notion of colors is 2612 important when param_alist's notion of colors is
2592 "unspecified". We need to do the same here. */ 2613 "unspecified". We need to do the same here. */
2593 if (STRINGP (value) && !FRAME_WINDOW_P (f)) 2614 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2594 value = frame_unspecified_color (f, value); 2615 {
2616 Lisp_Object tem = frame_unspecified_color (f, value);
2617
2618 if (!NILP (tem))
2619 value = tem;
2620 }
2595 } 2621 }
2596 else 2622 else
2597 value = Fcdr (Fassq (parameter, Fframe_parameters (frame))); 2623 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
@@ -3037,7 +3063,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3037 set them both at once. So we wait until we've looked at the 3063 set them both at once. So we wait until we've looked at the
3038 entire list before we set them. */ 3064 entire list before we set them. */
3039 int width IF_LINT (= 0), height IF_LINT (= 0); 3065 int width IF_LINT (= 0), height IF_LINT (= 0);
3040 bool width_change = 0, height_change = 0; 3066 bool width_change = false, height_change = false;
3041 3067
3042 /* Same here. */ 3068 /* Same here. */
3043 Lisp_Object left, top; 3069 Lisp_Object left, top;
@@ -3045,6 +3071,10 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3045 /* Same with these. */ 3071 /* Same with these. */
3046 Lisp_Object icon_left, icon_top; 3072 Lisp_Object icon_left, icon_top;
3047 3073
3074 /* And with this. */
3075 Lisp_Object fullscreen;
3076 bool fullscreen_change = false;
3077
3048 /* Record in these vectors all the parms specified. */ 3078 /* Record in these vectors all the parms specified. */
3049 Lisp_Object *parms; 3079 Lisp_Object *parms;
3050 Lisp_Object *values; 3080 Lisp_Object *values;
@@ -3138,6 +3168,11 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3138 icon_top = val; 3168 icon_top = val;
3139 else if (EQ (prop, Qicon_left)) 3169 else if (EQ (prop, Qicon_left))
3140 icon_left = val; 3170 icon_left = val;
3171 else if (EQ (prop, Qfullscreen))
3172 {
3173 fullscreen = val;
3174 fullscreen_change = true;
3175 }
3141 else if (EQ (prop, Qforeground_color) 3176 else if (EQ (prop, Qforeground_color)
3142 || EQ (prop, Qbackground_color) 3177 || EQ (prop, Qbackground_color)
3143 || EQ (prop, Qfont)) 3178 || EQ (prop, Qfont))
@@ -3218,14 +3253,14 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3218 that here since otherwise a size change implied by an 3253 that here since otherwise a size change implied by an
3219 intermittent font change may get lost as in Bug#17142. */ 3254 intermittent font change may get lost as in Bug#17142. */
3220 if (!width_change) 3255 if (!width_change)
3221 width = (f->new_width 3256 width = ((f->can_x_set_window_size && f->new_width)
3222 ? (f->new_pixelwise 3257 ? (f->new_pixelwise
3223 ? f->new_width 3258 ? f->new_width
3224 : (f->new_width * FRAME_COLUMN_WIDTH (f))) 3259 : (f->new_width * FRAME_COLUMN_WIDTH (f)))
3225 : FRAME_TEXT_WIDTH (f)); 3260 : FRAME_TEXT_WIDTH (f));
3226 3261
3227 if (!height_change) 3262 if (!height_change)
3228 height = (f->new_height 3263 height = ((f->can_x_set_window_size && f->new_height)
3229 ? (f->new_pixelwise 3264 ? (f->new_pixelwise
3230 ? f->new_height 3265 ? f->new_height
3231 : (f->new_height * FRAME_LINE_HEIGHT (f))) 3266 : (f->new_height * FRAME_LINE_HEIGHT (f)))
@@ -3298,6 +3333,20 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3298 /* Actually set that position, and convert to absolute. */ 3333 /* Actually set that position, and convert to absolute. */
3299 x_set_offset (f, leftpos, toppos, -1); 3334 x_set_offset (f, leftpos, toppos, -1);
3300 } 3335 }
3336
3337 if (fullscreen_change)
3338 {
3339 Lisp_Object old_value = get_frame_param (f, Qfullscreen);
3340
3341 frame_size_history_add
3342 (f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen));
3343
3344 store_frame_param (f, Qfullscreen, fullscreen);
3345 if (!EQ (fullscreen, old_value))
3346 x_set_fullscreen (f, fullscreen, old_value);
3347 }
3348
3349
3301#ifdef HAVE_X_WINDOWS 3350#ifdef HAVE_X_WINDOWS
3302 if ((!NILP (icon_left) || !NILP (icon_top)) 3351 if ((!NILP (icon_left) || !NILP (icon_top))
3303 && ! (icon_left_no_change && icon_top_no_change)) 3352 && ! (icon_left_no_change && icon_top_no_change))
@@ -4834,11 +4883,33 @@ syms_of_frame (void)
4834 DEFSYM (Qtool_bar_external, "tool-bar-external"); 4883 DEFSYM (Qtool_bar_external, "tool-bar-external");
4835 DEFSYM (Qtool_bar_size, "tool-bar-size"); 4884 DEFSYM (Qtool_bar_size, "tool-bar-size");
4836 DEFSYM (Qframe_inner_size, "frame-inner-size"); 4885 DEFSYM (Qframe_inner_size, "frame-inner-size");
4886 /* The following are used for frame_size_history. */
4887 DEFSYM (Qadjust_frame_size_1, "adjust-frame-size-1");
4888 DEFSYM (Qadjust_frame_size_2, "adjust-frame-size-2");
4889 DEFSYM (Qadjust_frame_size_3, "adjust-frame-size-3");
4890 DEFSYM (QEmacsFrameResize, "EmacsFrameResize");
4891 DEFSYM (Qframe_inhibit_resize, "frame-inhibit-resize");
4892 DEFSYM (Qx_set_fullscreen, "x-set-fullscreen");
4893 DEFSYM (Qx_check_fullscreen, "x-check-fullscreen");
4894 DEFSYM (Qx_set_window_size_1, "x-set-window-size-1");
4895 DEFSYM (Qxg_frame_resized, "xg-frame-resized");
4896 DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1");
4897 DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2");
4898 DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3");
4899 DEFSYM (Qxg_change_toolbar_position, "xg-change-toolbar-position");
4900 DEFSYM (Qx_net_wm_state, "x-net-wm-state");
4901 DEFSYM (Qx_handle_net_wm_state, "x-handle-net-wm-state");
4902 DEFSYM (Qtb_size_cb, "tb-size-cb");
4903 DEFSYM (Qupdate_frame_tool_bar, "update-frame-tool-bar");
4904 DEFSYM (Qfree_frame_tool_bar, "free-frame-tool-bar");
4905
4837 DEFSYM (Qchange_frame_size, "change-frame-size"); 4906 DEFSYM (Qchange_frame_size, "change-frame-size");
4838 DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size"); 4907 DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size");
4839 DEFSYM (Qset_window_configuration, "set-window-configuration"); 4908 DEFSYM (Qset_window_configuration, "set-window-configuration");
4840 DEFSYM (Qx_create_frame_1, "x-create-frame-1"); 4909 DEFSYM (Qx_create_frame_1, "x-create-frame-1");
4841 DEFSYM (Qx_create_frame_2, "x-create-frame-2"); 4910 DEFSYM (Qx_create_frame_2, "x-create-frame-2");
4911 DEFSYM (Qtip_frame, "tip-frame");
4912 DEFSYM (Qterminal_frame, "terminal-frame");
4842 4913
4843#ifdef HAVE_NS 4914#ifdef HAVE_NS
4844 DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); 4915 DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
@@ -5106,9 +5177,22 @@ even if this option is non-nil. */);
5106 frame_inhibit_implied_resize = Qt; 5177 frame_inhibit_implied_resize = Qt;
5107#endif 5178#endif
5108 5179
5109 DEFVAR_LISP ("frame-adjust-size-history", Vframe_adjust_size_history, 5180 DEFVAR_LISP ("frame-size-history", frame_size_history,
5110 doc: /* History of frame size adjustments. */); 5181 doc: /* History of frame size adjustments.
5111 Vframe_adjust_size_history = Qnil; 5182If non-nil, list recording frame size adjustment. Adjustments are
5183recorded only if the first element of this list is a positive number.
5184Adding an adjustment decrements that number by one.
5185
5186The remaining elements are the adjustments. Each adjustment is a list
5187of four elements `frame', `function', `sizes' and `more'. `frame' is
5188the affected frame and `function' the invoking function. `sizes' is
5189usually a list of four elements `old-width', `old-height', `new-width'
5190and `new-height' representing the old and new sizes recorded/requested
5191by `function'. `more' is a list with additional information.
5192
5193The function `frame--size-history' displays the value of this variable
5194in a more readable form. */);
5195 frame_size_history = Qnil;
5112 5196
5113 staticpro (&Vframe_list); 5197 staticpro (&Vframe_list);
5114 5198
@@ -5141,7 +5225,7 @@ even if this option is non-nil. */);
5141 defsubr (&Sraise_frame); 5225 defsubr (&Sraise_frame);
5142 defsubr (&Slower_frame); 5226 defsubr (&Slower_frame);
5143 defsubr (&Sx_focus_frame); 5227 defsubr (&Sx_focus_frame);
5144 defsubr (&Scan_run_window_configuration_change_hook); 5228 defsubr (&Sframe_after_make_frame);
5145 defsubr (&Sredirect_frame_focus); 5229 defsubr (&Sredirect_frame_focus);
5146 defsubr (&Sframe_focus); 5230 defsubr (&Sframe_focus);
5147 defsubr (&Sframe_parameters); 5231 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
332 frame. */ 332 frame. */
333 bool_bf can_x_set_window_size : 1; 333 bool_bf can_x_set_window_size : 1;
334 334
335 /* True means run_window_configuration_change_hook can be processed 335 /* Set to true after this frame was made by `make-frame'. */
336 for this frame. */ 336 bool_bf after_make_frame : 1;
337 bool_bf can_run_window_configuration_change_hook : 1;
338 337
339 /* True means tool bar has been redisplayed at least once in current 338 /* True means tool bar has been redisplayed at least once in current
340 session. */ 339 session. */
@@ -392,9 +391,9 @@ struct frame
392 int left_pos, top_pos; 391 int left_pos, top_pos;
393 392
394 /* Total width of this frame (including fringes, vertical scroll bar 393 /* Total width of this frame (including fringes, vertical scroll bar
395 and internal border widths) and total height (including menu bar, 394 and internal border widths) and total height (including internal
396 tool bar, horizontal scroll bar and internal border widths) in 395 menu and tool bars, horizontal scroll bar and internal border
397 pixels. */ 396 widths) in pixels. */
398 int pixel_width, pixel_height; 397 int pixel_width, pixel_height;
399 398
400 /* These many pixels are the difference between the outer window (i.e. the 399 /* 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 *);
1124extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object); 1123extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
1125extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object); 1124extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object);
1126extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object); 1125extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object);
1126extern void frame_size_history_add (struct frame *f, Lisp_Object fun_symbol,
1127 int width, int height, Lisp_Object rest);
1127 1128
1128extern Lisp_Object Vframe_list; 1129extern Lisp_Object Vframe_list;
1129 1130
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/>. */
50#include "emacsgtkfixed.h" 50#include "emacsgtkfixed.h"
51#endif 51#endif
52 52
53/** #define FRAME_TOTAL_PIXEL_HEIGHT(f) \ **/
54/** (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) **/
55
56/** #define FRAME_TOTAL_PIXEL_WIDTH(f) \ **/
57/** (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f)) **/
58
59#ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW 53#ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW
60#define gtk_widget_set_has_window(w, b) \ 54#define gtk_widget_set_has_window(w, b) \
61 (gtk_fixed_set_has_window (GTK_FIXED (w), b)) 55 (gtk_fixed_set_has_window (GTK_FIXED (w), b))
@@ -886,24 +880,23 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
886 if (pixelwidth == -1 && pixelheight == -1) 880 if (pixelwidth == -1 && pixelheight == -1)
887 { 881 {
888 if (FRAME_GTK_WIDGET (f) && gtk_widget_get_mapped (FRAME_GTK_WIDGET (f))) 882 if (FRAME_GTK_WIDGET (f) && gtk_widget_get_mapped (FRAME_GTK_WIDGET (f)))
889 gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)), 883 gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
890 0, 0, 884 0, 0, &pixelwidth, &pixelheight);
891 &pixelwidth, &pixelheight); 885 else
892 else return; 886 return;
893 } 887 }
894 888
895
896 width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth); 889 width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth);
897 height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight); 890 height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight);
898 891
892 frame_size_history_add
893 (f, Qxg_frame_resized, width, height, Qnil);
894
899 if (width != FRAME_TEXT_WIDTH (f) 895 if (width != FRAME_TEXT_WIDTH (f)
900 || height != FRAME_TEXT_HEIGHT (f) 896 || height != FRAME_TEXT_HEIGHT (f)
901 || pixelwidth != FRAME_PIXEL_WIDTH (f) 897 || pixelwidth != FRAME_PIXEL_WIDTH (f)
902 || pixelheight != FRAME_PIXEL_HEIGHT (f)) 898 || pixelheight != FRAME_PIXEL_HEIGHT (f))
903 { 899 {
904 FRAME_PIXEL_WIDTH (f) = pixelwidth;
905 FRAME_PIXEL_HEIGHT (f) = pixelheight;
906
907 xg_clear_under_internal_border (f); 900 xg_clear_under_internal_border (f);
908 change_frame_size (f, width, height, 0, 1, 0, 1); 901 change_frame_size (f, width, height, 0, 1, 0, 1);
909 SET_FRAME_GARBAGED (f); 902 SET_FRAME_GARBAGED (f);
@@ -921,24 +914,71 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
921{ 914{
922 int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); 915 int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
923 int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); 916 int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
917 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
918 gint gwidth, gheight;
924 919
925 if (FRAME_PIXEL_HEIGHT (f) == 0) 920 if (FRAME_PIXEL_HEIGHT (f) == 0)
926 return; 921 return;
927 922
923 gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
924 &gwidth, &gheight);
925
928 /* Do this before resize, as we don't know yet if we will be resized. */ 926 /* Do this before resize, as we don't know yet if we will be resized. */
929 xg_clear_under_internal_border (f); 927 xg_clear_under_internal_border (f);
930 928
931 /* Must resize our top level widget. Font size may have changed, 929 /* Resize the top level widget so rows and columns remain constant.
932 but not rows/cols. */ 930
933 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 931 When the frame is fullheight and we only want to change the width
934 pixelwidth + FRAME_TOOLBAR_WIDTH (f), 932 or it is fullwidth and we only want to change the height we should
935 pixelheight + FRAME_TOOLBAR_HEIGHT (f) 933 be able to preserve the fullscreen property. However, due to the
936 + FRAME_MENUBAR_HEIGHT (f)); 934 fact that we have to send a resize request anyway, the window
937 x_wm_set_size_hint (f, 0, 0); 935 manager will abolish it. At least the respective size should
936 remain unchanged but giving the frame back its normal size will
937 be broken ... */
938 if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f))
939 {
940 frame_size_history_add
941 (f, Qxg_frame_set_char_size_1, width, height,
942 list2 (make_number (gheight),
943 make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f)
944 + FRAME_MENUBAR_HEIGHT (f))));
945
946 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
947 gwidth,
948 pixelheight + FRAME_TOOLBAR_HEIGHT (f)
949 + FRAME_MENUBAR_HEIGHT (f));
950 }
951 else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
952 {
953 frame_size_history_add
954 (f, Qxg_frame_set_char_size_2, width, height,
955 list2 (make_number (gwidth),
956 make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f))));
957
958 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
959 pixelwidth + FRAME_TOOLBAR_WIDTH (f),
960 gheight);
961 }
962
963 else
964 {
965 frame_size_history_add
966 (f, Qxg_frame_set_char_size_3, width, height,
967 list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)),
968 make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f)
969 + FRAME_MENUBAR_HEIGHT (f))));
970
971 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
972 pixelwidth + FRAME_TOOLBAR_WIDTH (f),
973 pixelheight + FRAME_TOOLBAR_HEIGHT (f)
974 + FRAME_MENUBAR_HEIGHT (f));
975 fullscreen = Qnil;
976 }
938 977
939 SET_FRAME_GARBAGED (f); 978 SET_FRAME_GARBAGED (f);
940 cancel_mouse_face (f); 979 cancel_mouse_face (f);
941 980
981 x_wm_set_size_hint (f, 0, 0);
942 /* We can not call change_frame_size for a mapped frame, 982 /* We can not call change_frame_size for a mapped frame,
943 we can not set pixel width/height either. The window manager may 983 we can not set pixel width/height either. The window manager may
944 override our resize request, XMonad does this all the time. 984 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)
952 (void)gtk_events_pending (); 992 (void)gtk_events_pending ();
953 gdk_flush (); 993 gdk_flush ();
954 x_wait_for_event (f, ConfigureNotify); 994 x_wait_for_event (f, ConfigureNotify);
995
996 if (!NILP (fullscreen))
997 /* Try to restore fullscreen state. */
998 {
999 store_frame_param (f, Qfullscreen, fullscreen);
1000 x_set_fullscreen (f, fullscreen, fullscreen);
1001 }
955 } 1002 }
956 else 1003 else
957 adjust_frame_size (f, -1, -1, 5, 0, Qxg_frame_set_char_size); 1004 adjust_frame_size (f, width, height, 5, 0, Qxg_frame_set_char_size);
1005
958} 1006}
959 1007
960/* Handle height/width changes (i.e. add/remove/move menu/toolbar). 1008/* Handle height/width changes (i.e. add/remove/move menu/toolbar).
@@ -4214,8 +4262,12 @@ tb_size_cb (GtkWidget *widget,
4214 allocated between widgets, it may get another. So we must update 4262 allocated between widgets, it may get another. So we must update
4215 size hints if tool bar size changes. Seen on Fedora 18 at least. */ 4263 size hints if tool bar size changes. Seen on Fedora 18 at least. */
4216 struct frame *f = user_data; 4264 struct frame *f = user_data;
4265
4217 if (xg_update_tool_bar_sizes (f)) 4266 if (xg_update_tool_bar_sizes (f))
4218 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 4267 {
4268 frame_size_history_add (f, Qtb_size_cb, 0, 0, Qnil);
4269 adjust_frame_size (f, -1, -1, 5, 0, Qtool_bar_lines);
4270 }
4219} 4271}
4220 4272
4221/* Create a tool bar for frame F. */ 4273/* Create a tool bar for frame F. */
@@ -4489,10 +4541,11 @@ xg_update_tool_bar_sizes (struct frame *f)
4489 FRAME_TOOLBAR_RIGHT_WIDTH (f) = nr; 4541 FRAME_TOOLBAR_RIGHT_WIDTH (f) = nr;
4490 FRAME_TOOLBAR_TOP_HEIGHT (f) = nt; 4542 FRAME_TOOLBAR_TOP_HEIGHT (f) = nt;
4491 FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = nb; 4543 FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = nb;
4492 return 1;
4493 }
4494 4544
4495 return 0; 4545 return true;
4546 }
4547 else
4548 return false;
4496} 4549}
4497 4550
4498static char * 4551static char *
@@ -4815,7 +4868,10 @@ update_frame_tool_bar (struct frame *f)
4815 xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f)); 4868 xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f));
4816 gtk_widget_show_all (x->toolbar_widget); 4869 gtk_widget_show_all (x->toolbar_widget);
4817 if (xg_update_tool_bar_sizes (f)) 4870 if (xg_update_tool_bar_sizes (f))
4818 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 4871 {
4872 frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
4873 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4874 }
4819 } 4875 }
4820 4876
4821 unblock_input (); 4877 unblock_input ();
@@ -4863,6 +4919,7 @@ free_frame_tool_bar (struct frame *f)
4863 NULL); 4919 NULL);
4864 } 4920 }
4865 4921
4922 frame_size_history_add (f, Qfree_frame_tool_bar, 0, 0, Qnil);
4866 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 4923 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4867 4924
4868 unblock_input (); 4925 unblock_input ();
@@ -4892,8 +4949,13 @@ xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
4892 4949
4893 xg_pack_tool_bar (f, pos); 4950 xg_pack_tool_bar (f, pos);
4894 g_object_unref (top_widget); 4951 g_object_unref (top_widget);
4952
4895 if (xg_update_tool_bar_sizes (f)) 4953 if (xg_update_tool_bar_sizes (f))
4896 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 4954 {
4955 frame_size_history_add (f, Qxg_change_toolbar_position, 0, 0, Qnil);
4956 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4957 }
4958
4897 4959
4898 unblock_input (); 4960 unblock_input ();
4899} 4961}
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)
1722 int old_height = FRAME_TOOL_BAR_HEIGHT (f); 1722 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1723 int lines = (height + unit - 1) / unit; 1723 int lines = (height + unit - 1) / unit;
1724 int old_text_height = FRAME_TEXT_HEIGHT (f); 1724 int old_text_height = FRAME_TEXT_HEIGHT (f);
1725 Lisp_Object fullscreen;
1725 1726
1726 /* Make sure we redisplay all windows in this frame. */ 1727 /* Make sure we redisplay all windows in this frame. */
1727 windows_or_buffers_changed = 23; 1728 windows_or_buffers_changed = 23;
@@ -1746,7 +1747,10 @@ x_change_tool_bar_height (struct frame *f, int height)
1746 f->n_tool_bar_rows = 0; 1747 f->n_tool_bar_rows = 0;
1747 1748
1748 adjust_frame_size (f, -1, -1, 1749 adjust_frame_size (f, -1, -1,
1749 (!f->tool_bar_redisplayed_once ? 1 1750 ((!f->tool_bar_redisplayed_once
1751 && (NILP (fullscreen =
1752 get_frame_param (f, Qfullscreen))
1753 || EQ (fullscreen, Qfullwidth))) ? 1
1750 : (old_height == 0 || height == 0) ? 2 1754 : (old_height == 0 || height == 0) ? 2
1751 : 4), 1755 : 4),
1752 false, Qtool_bar_lines); 1756 false, Qtool_bar_lines);
@@ -4668,8 +4672,6 @@ This function is an internal primitive--use `make-frame' instead. */)
4668 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL); 4672 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
4669 x_default_parameter (f, parameters, Qtitle, Qnil, 4673 x_default_parameter (f, parameters, Qtitle, Qnil,
4670 "title", "Title", RES_TYPE_STRING); 4674 "title", "Title", RES_TYPE_STRING);
4671 x_default_parameter (f, parameters, Qfullscreen, Qnil,
4672 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
4673 4675
4674 f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; 4676 f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
4675 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; 4677 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. */)
4728 x_wm_set_size_hint (f, window_prompting, false); 4730 x_wm_set_size_hint (f, window_prompting, false);
4729 unblock_input (); 4731 unblock_input ();
4730 4732
4733 /* Process fullscreen parameter here in the hope that normalizing a
4734 fullheight/fullwidth frame will produce the size set by the last
4735 adjust_frame_size call. */
4736 x_default_parameter (f, parameters, Qfullscreen, Qnil,
4737 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
4738
4731 /* Make the window appear on the frame and enable display, unless 4739 /* Make the window appear on the frame and enable display, unless
4732 the caller says not to. However, with explicit parent, Emacs 4740 the caller says not to. However, with explicit parent, Emacs
4733 cannot control visibility, so don't try. */ 4741 cannot control visibility, so don't try. */
@@ -5832,7 +5840,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5832 SET_FRAME_COLS (f, 0); 5840 SET_FRAME_COLS (f, 0);
5833 SET_FRAME_LINES (f, 0); 5841 SET_FRAME_LINES (f, 0);
5834 adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f), 5842 adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f),
5835 height * FRAME_LINE_HEIGHT (f), 0, true, Qnil); 5843 height * FRAME_LINE_HEIGHT (f), 0, true, Qtip_frame);
5836 5844
5837 /* Add `tooltip' frame parameter's default value. */ 5845 /* Add `tooltip' frame parameter's default value. */
5838 if (NILP (Fframe_parameter (frame, Qtooltip))) 5846 if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -7558,7 +7566,7 @@ elements (all size values are in pixels).
7558 menu_bar_height = single_bar_height; 7566 menu_bar_height = single_bar_height;
7559 7567
7560 return 7568 return
7561 listn (CONSTYPE_PURE, 10, 7569 listn (CONSTYPE_HEAP, 10,
7562 Fcons (Qframe_position, 7570 Fcons (Qframe_position,
7563 Fcons (make_number (frame_outer_edges.left), 7571 Fcons (make_number (frame_outer_edges.left),
7564 make_number (frame_outer_edges.top))), 7572 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
3344 enum scroll_bar_part *, 3344 enum scroll_bar_part *,
3345 Lisp_Object *, Lisp_Object *, 3345 Lisp_Object *, Lisp_Object *,
3346 Time *); 3346 Time *);
3347static void x_check_fullscreen (struct frame *);
3348
3349static void 3347static void
3350w32_define_cursor (Window window, Cursor cursor) 3348w32_define_cursor (Window window, Cursor cursor)
3351{ 3349{
@@ -4989,8 +4987,12 @@ w32_read_socket (struct terminal *terminal,
4989 sets the WAIT flag. */ 4987 sets the WAIT flag. */
4990 if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam) 4988 if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam)
4991 && (f->want_fullscreen & FULLSCREEN_WAIT)) 4989 && (f->want_fullscreen & FULLSCREEN_WAIT))
4992 w32fullscreen_hook (f); 4990 {
4993 x_check_fullscreen (f); 4991 /* Must set visibility right here since otherwise
4992 w32fullscreen_hook returns immediately. */
4993 SET_FRAME_VISIBLE (f, 1);
4994 w32fullscreen_hook (f);
4995 }
4994 } 4996 }
4995 check_visibility = 1; 4997 check_visibility = 1;
4996 break; 4998 break;
@@ -5269,11 +5271,18 @@ w32_read_socket (struct terminal *terminal,
5269 5271
5270 if (f) 5272 if (f)
5271 { 5273 {
5274 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
5275
5272 dpyinfo->n_cbits = msg.msg.wParam; 5276 dpyinfo->n_cbits = msg.msg.wParam;
5273 /* The new display could have a different resolution, in 5277 /* The new display could have a different resolution, in
5274 which case we must reconsider what fullscreen 5278 which case we must reconsider what fullscreen means.
5275 means. */ 5279 The following code is untested yet. */
5276 x_check_fullscreen (f); 5280 if (!NILP (fullscreen))
5281 {
5282 x_set_fullscreen (f, fullscreen, fullscreen);
5283 w32fullscreen_hook (f);
5284 }
5285
5277 DebPrint (("display change: %d %d\n", 5286 DebPrint (("display change: %d %d\n",
5278 (short) LOWORD (msg.msg.lParam), 5287 (short) LOWORD (msg.msg.lParam),
5279 (short) HIWORD (msg.msg.lParam))); 5288 (short) HIWORD (msg.msg.lParam)));
@@ -5959,75 +5968,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff,
5959 unblock_input (); 5968 unblock_input ();
5960} 5969}
5961 5970
5962/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
5963 wanted positions of the WM window (not Emacs window).
5964 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
5965 window (FRAME_X_WINDOW).
5966 */
5967
5968static void
5969x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *left_pos)
5970{
5971 int newwidth = FRAME_COLS (f);
5972 int newheight = FRAME_LINES (f);
5973 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
5974
5975 *top_pos = f->top_pos;
5976 *left_pos = f->left_pos;
5977
5978 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
5979 {
5980 int ph;
5981
5982 ph = x_display_pixel_height (dpyinfo);
5983 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
5984 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
5985 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
5986 *top_pos = 0;
5987 }
5988
5989 if (f->want_fullscreen & FULLSCREEN_WIDTH)
5990 {
5991 int pw;
5992
5993 pw = x_display_pixel_width (dpyinfo);
5994 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
5995 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
5996 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
5997 *left_pos = 0;
5998 }
5999
6000 *width = newwidth;
6001 *height = newheight;
6002}
6003
6004/* Check if we need to resize the frame due to a fullscreen request.
6005 If so needed, resize the frame. */
6006static void
6007x_check_fullscreen (struct frame *f)
6008{
6009 if (f->want_fullscreen & FULLSCREEN_BOTH)
6010 {
6011 int width, height, ign;
6012
6013 x_real_positions (f, &f->left_pos, &f->top_pos);
6014
6015 x_fullscreen_adjust (f, &width, &height, &ign, &ign);
6016
6017 /* We do not need to move the window, it shall be taken care of
6018 when setting WM manager hints. */
6019 if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
6020 {
6021 change_frame_size (f, width, height, 0, 1, 0, 0);
6022 SET_FRAME_GARBAGED (f);
6023 cancel_mouse_face (f);
6024
6025 /* Wait for the change of frame size to occur. */
6026 f->want_fullscreen |= FULLSCREEN_WAIT;
6027 }
6028 }
6029}
6030
6031static void 5971static void
6032w32fullscreen_hook (struct frame *f) 5972w32fullscreen_hook (struct frame *f)
6033{ 5973{
@@ -6074,6 +6014,10 @@ w32fullscreen_hook (struct frame *f)
6074 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, 6014 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
6075 rect.right - rect.left, rect.bottom - rect.top, 6015 rect.right - rect.left, rect.bottom - rect.top,
6076 SWP_NOOWNERZORDER | SWP_FRAMECHANGED); 6016 SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
6017 change_frame_size
6018 (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, rect.right - rect.left),
6019 FRAME_PIXEL_TO_TEXT_HEIGHT (f, rect.bottom - rect.top),
6020 0, 1, 0, 1);
6077 } 6021 }
6078 else 6022 else
6079 { 6023 {
@@ -6082,10 +6026,39 @@ w32fullscreen_hook (struct frame *f)
6082 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); 6026 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
6083 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, 6027 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
6084 rect.right - rect.left, rect.bottom - rect.top, 0); 6028 rect.right - rect.left, rect.bottom - rect.top, 0);
6029
6030 if (f->want_fullscreen == FULLSCREEN_WIDTH)
6031 {
6032 int border_width = GetSystemMetrics (SM_CXFRAME);
6033
6034 change_frame_size
6035 (f, (FRAME_PIXEL_TO_TEXT_WIDTH
6036 (f, rect.right - rect.left - 2 * border_width)),
6037 0, 0, 1, 0, 1);
6038 }
6039 else
6040 {
6041 int border_height = GetSystemMetrics (SM_CYFRAME);
6042 /* Won't work for wrapped menu bar. */
6043 int menu_bar_height = GetSystemMetrics (SM_CYMENU);
6044 int title_height = GetSystemMetrics (SM_CYCAPTION);
6045
6046 change_frame_size
6047 (f, 0, (FRAME_PIXEL_TO_TEXT_HEIGHT
6048 (f, rect.bottom - rect.top - 2 * border_height
6049 - title_height - menu_bar_height)),
6050 0, 1, 0, 1);
6051 }
6085 } 6052 }
6086 6053
6087 f->want_fullscreen = FULLSCREEN_NONE; 6054 f->want_fullscreen = FULLSCREEN_NONE;
6088 unblock_input (); 6055 unblock_input ();
6056
6057 if (f->want_fullscreen == FULLSCREEN_BOTH
6058 || f->want_fullscreen == FULLSCREEN_WIDTH
6059 || f->want_fullscreen == FULLSCREEN_HEIGHT)
6060 do_pending_window_change (0);
6061
6089 } 6062 }
6090 else 6063 else
6091 f->want_fullscreen |= FULLSCREEN_WAIT; 6064 f->want_fullscreen |= FULLSCREEN_WAIT;
@@ -6101,6 +6074,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
6101 int width, int height, bool pixelwise) 6074 int width, int height, bool pixelwise)
6102{ 6075{
6103 int pixelwidth, pixelheight; 6076 int pixelwidth, pixelheight;
6077 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
6104 RECT rect; 6078 RECT rect;
6105 6079
6106 block_input (); 6080 block_input ();
@@ -6119,7 +6093,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
6119 if (w32_add_wrapped_menu_bar_lines) 6093 if (w32_add_wrapped_menu_bar_lines)
6120 { 6094 {
6121 /* When the menu bar wraps sending a SetWindowPos shrinks the 6095 /* When the menu bar wraps sending a SetWindowPos shrinks the
6122 height of the frame when the wrapped menu bar lines are not 6096 height of the frame then the wrapped menu bar lines are not
6123 accounted for (Bug#15174 and Bug#18720). Here we add these 6097 accounted for (Bug#15174 and Bug#18720). Here we add these
6124 extra lines to the frame height. */ 6098 extra lines to the frame height. */
6125 MENUBARINFO info; 6099 MENUBARINFO info;
@@ -6143,9 +6117,6 @@ x_set_window_size (struct frame *f, bool change_gravity,
6143 f->win_gravity = NorthWestGravity; 6117 f->win_gravity = NorthWestGravity;
6144 x_wm_set_size_hint (f, (long) 0, false); 6118 x_wm_set_size_hint (f, (long) 0, false);
6145 6119
6146 f->want_fullscreen = FULLSCREEN_NONE;
6147 w32fullscreen_hook (f);
6148
6149 rect.left = rect.top = 0; 6120 rect.left = rect.top = 0;
6150 rect.right = pixelwidth; 6121 rect.right = pixelwidth;
6151 rect.bottom = pixelheight; 6122 rect.bottom = pixelheight;
@@ -6153,45 +6124,45 @@ x_set_window_size (struct frame *f, bool change_gravity,
6153 AdjustWindowRect (&rect, f->output_data.w32->dwStyle, 6124 AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
6154 FRAME_EXTERNAL_MENU_BAR (f)); 6125 FRAME_EXTERNAL_MENU_BAR (f));
6155 6126
6156 my_set_window_pos (FRAME_W32_WINDOW (f), 6127 if (!(f->after_make_frame)
6157 NULL, 6128 && !(f->want_fullscreen & FULLSCREEN_WAIT)
6158 0, 0, 6129 && FRAME_VISIBLE_P (f))
6159 rect.right - rect.left, 6130 {
6160 rect.bottom - rect.top, 6131 RECT window_rect;
6161 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); 6132
6162 6133 GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
6163 /* If w32_enable_frame_resize_hack is non-nil, immediately apply the
6164 new pixel sizes to the frame and its subwindows.
6165
6166 Jason Rumney earlier refused to call change_frame_size right here
6167 with the following argument:
6168
6169 The following mirrors what is done in xterm.c. It appears to be for
6170 informing lisp of the new size immediately, while the actual resize
6171 will happen asynchronously. But on Windows, the menu bar
6172 automatically wraps when the frame is too narrow to contain it, and
6173 that causes any calculations made here to come out wrong. The end
6174 is some nasty buggy behavior, including the potential loss of the
6175 minibuffer.
6176
6177 Disabling this code is either not sufficient to fix the problems
6178 completely, or it causes fresh problems, but at least it removes
6179 the most problematic symptom of the minibuffer becoming unusable.
6180
6181 However, as the discussion about how to handle frame size
6182 parameters on Windows (Bug#1348, Bug#16028) shows, that cure seems
6183 worse than the disease. In particular, menu bar wrapping looks
6184 like a non-issue - maybe so because Windows eventually gets back to
6185 us with the correct client rectangle anyway. But we have to avoid
6186 calling change_frame_size with a delta of less than one canoncial
6187 character size when frame_resize_pixelwise is nil, as explained in
6188 the comment above. */
6189
6190 if (w32_enable_frame_resize_hack)
6191 6134
6135 if (EQ (fullscreen, Qmaximized)
6136 || EQ (fullscreen, Qfullboth)
6137 || EQ (fullscreen, Qfullwidth))
6138 {
6139 rect.left = window_rect.left;
6140 rect.right = window_rect.right;
6141 pixelwidth = 0;
6142 }
6143 if (EQ (fullscreen, Qmaximized)
6144 || EQ (fullscreen, Qfullboth)
6145 || EQ (fullscreen, Qfullheight))
6146 {
6147 rect.top = window_rect.top;
6148 rect.bottom = window_rect.bottom;
6149 pixelheight = 0;
6150 }
6151 }
6152
6153 if (pixelwidth > 0 || pixelheight > 0)
6192 { 6154 {
6193 change_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), 6155 my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
6194 FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight), 6156 0, 0,
6157 rect.right - rect.left,
6158 rect.bottom - rect.top,
6159 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
6160
6161 change_frame_size (f,
6162 ((pixelwidth == 0)
6163 ? 0 : FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth)),
6164 ((pixelheight == 0)
6165 ? 0 : FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)),
6195 0, 1, 0, 1); 6166 0, 1, 0, 1);
6196 SET_FRAME_GARBAGED (f); 6167 SET_FRAME_GARBAGED (f);
6197 6168
@@ -7102,7 +7073,7 @@ Windows 8. It is set to nil on Windows 9X. */);
7102 w32_unicode_filenames = 0; 7073 w32_unicode_filenames = 0;
7103 7074
7104 7075
7105 /* FIXME: The following two variables will be (hopefully) removed 7076 /* FIXME: The following variable will be (hopefully) removed
7106 before Emacs 25.1 gets released. */ 7077 before Emacs 25.1 gets released. */
7107 7078
7108 DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines", 7079 DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines",
@@ -7116,16 +7087,6 @@ wrapped menu bar lines when sending frame resize requests to the Windows
7116API. */); 7087API. */);
7117 w32_add_wrapped_menu_bar_lines = 1; 7088 w32_add_wrapped_menu_bar_lines = 1;
7118 7089
7119 DEFVAR_BOOL ("w32-enable-frame-resize-hack",
7120 w32_enable_frame_resize_hack,
7121 doc: /* Non-nil means enable hack for frame resizing on Windows.
7122A value of nil means to resize frames by sending a corresponding request
7123to the Windows API and changing the pixel sizes of the frame and its
7124windows after the latter calls back. If this is non-nil, Emacs changes
7125the pixel sizes of the frame and its windows at the time it sends the
7126resize request to the API. */);
7127 w32_enable_frame_resize_hack = 1;
7128
7129 /* Tell Emacs about this window system. */ 7090 /* Tell Emacs about this window system. */
7130 Fprovide (Qw32, Qnil); 7091 Fprovide (Qw32, Qnil);
7131} 7092}
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)
460 base_width = (wmshell->core.width - ew->core.width 460 base_width = (wmshell->core.width - ew->core.width
461 + (rounded_width - (char_width * cw))); 461 + (rounded_width - (char_width * cw)));
462 base_height = (wmshell->core.height - ew->core.height 462 base_height = (wmshell->core.height - ew->core.height
463 + (rounded_height - (char_height * ch))); 463 + (rounded_height - (char_height * ch)));
464 464
465 /* This is kind of sleazy, but I can't see how else to tell it to 465 /* This is kind of sleazy, but I can't see how else to tell it to
466 make it mark the WM_SIZE_HINTS size as user specified. 466 make it mark the WM_SIZE_HINTS size as user specified.
@@ -573,39 +573,20 @@ EmacsFrameResize (Widget widget)
573{ 573{
574 EmacsFrame ew = (EmacsFrame)widget; 574 EmacsFrame ew = (EmacsFrame)widget;
575 struct frame *f = ew->emacs_frame.frame; 575 struct frame *f = ew->emacs_frame.frame;
576 int width, height;
576 577
577 /* Always process resize requests pixelwise. Frame maximizing 578 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
578 should work even when frame_resize_pixelwise is nil. */
579 if (true || frame_resize_pixelwise)
580 {
581 int width, height;
582
583 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
584 change_frame_size (f, width, height, 0, 1, 0, 1);
585 579
586 update_wm_hints (ew); 580 frame_size_history_add
587 update_various_frame_slots (ew); 581 (f, QEmacsFrameResize, width, height,
582 list2 (make_number (ew->core.width), make_number (ew->core.height)));
588 583
589 cancel_mouse_face (f); 584 change_frame_size (f, width, height, 0, 1, 0, 1);
590 }
591 else
592 {
593 struct x_output *x = f->output_data.x;
594 int columns, rows;
595 585
596 pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows); 586 update_wm_hints (ew);
597 if (columns != FRAME_COLS (f) 587 update_various_frame_slots (ew);
598 || rows != FRAME_LINES (f)
599 || ew->core.width != FRAME_PIXEL_WIDTH (f)
600 || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f))
601 {
602 change_frame_size (f, columns, rows, 0, 1, 0, 0);
603 update_wm_hints (ew);
604 update_various_frame_slots (ew);
605 588
606 cancel_mouse_face (f); 589 cancel_mouse_face (f);
607 }
608 }
609} 590}
610 591
611static XtGeometryResult 592static 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)
3332 3332
3333 if (NILP (Vrun_hooks) 3333 if (NILP (Vrun_hooks)
3334 || !(f->can_x_set_window_size) 3334 || !(f->can_x_set_window_size)
3335 || !(f->can_run_window_configuration_change_hook)) 3335 || !(f->after_make_frame))
3336 return; 3336 return;
3337 3337
3338 /* Use the right buffer. Matters when running the local hooks. */ 3338 /* 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)
9703 && it->dpvec + it->current.dpvec_index != it->dpend); 9703 && it->dpvec + it->current.dpvec_index != it->dpend);
9704} 9704}
9705 9705
9706DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0, 9706DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9707 doc: /* Return the size of the text of WINDOW's buffer in pixels. 9707 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9708WINDOW must be a live window and defaults to the selected one. The 9708WINDOW must be a live window and defaults to the selected one. The
9709return value is a cons of the maximum pixel-width of any text line and 9709return 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
9736include the height of the mode- or header-line of WINDOW in the return 9736include the height of the mode- or header-line of WINDOW in the return
9737value. If it is either the symbol `mode-line' or `header-line', include 9737value. If it is either the symbol `mode-line' or `header-line', include
9738only the height of that line, if present, in the return value. If t, 9738only the height of that line, if present, in the return value. If t,
9739include the height of both, if present, in the return value. 9739include the height of both, if present, in the return value. */)
9740
9741Optional argument BUFFER nil means to return the size of the text of
9742WINDOW's buffer. BUFFER t means to return the size of the text of the
9743current buffer as if it were displayed in WINDOW. Else BUFFER has to
9744specify a live buffer and this function returns the size of the text of
9745BUFFER as if it were displayed in WINDOW. */)
9746 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, 9740 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
9747 Lisp_Object y_limit, Lisp_Object mode_and_header_line, Lisp_Object buffer) 9741 Lisp_Object y_limit, Lisp_Object mode_and_header_line)
9748{ 9742{
9749 struct window *w = decode_live_window (window); 9743 struct window *w = decode_live_window (window);
9744 Lisp_Object buffer = w->contents;
9750 struct buffer *b; 9745 struct buffer *b;
9751 struct it it; 9746 struct it it;
9752 struct buffer *old_b = NULL; 9747 struct buffer *old_b = NULL;
@@ -9755,23 +9750,13 @@ BUFFER as if it were displayed in WINDOW. */)
9755 void *itdata = NULL; 9750 void *itdata = NULL;
9756 int c, max_y = -1, x = 0, y = 0; 9751 int c, max_y = -1, x = 0, y = 0;
9757 9752
9758 if (EQ (buffer, Qt)) 9753 CHECK_BUFFER (buffer);
9759 b = current_buffer; 9754 b = XBUFFER (buffer);
9760 else
9761 {
9762 if (NILP (buffer))
9763 buffer = w->contents;
9764
9765 CHECK_BUFFER (buffer);
9766 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
9767 error ("Not a live buffer");
9768 9755
9769 b = XBUFFER (buffer); 9756 if (b != current_buffer)
9770 if (b != current_buffer) 9757 {
9771 { 9758 old_b = current_buffer;
9772 old_b = current_buffer; 9759 set_buffer_internal (b);
9773 set_buffer_internal (b);
9774 }
9775 } 9760 }
9776 9761
9777 if (NILP (from)) 9762 if (NILP (from))
@@ -10184,7 +10169,7 @@ message3_nolog (Lisp_Object m)
10184 10169
10185 fwrite (SDATA (s), SBYTES (s), 1, stderr); 10170 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10186 } 10171 }
10187 if (cursor_in_echo_area == 0) 10172 if (!cursor_in_echo_area)
10188 fprintf (stderr, "\n"); 10173 fprintf (stderr, "\n");
10189 fflush (stderr); 10174 fflush (stderr);
10190 } 10175 }
@@ -10326,7 +10311,7 @@ vmessage (const char *m, va_list ap)
10326 putc ('\n', stderr); 10311 putc ('\n', stderr);
10327 noninteractive_need_newline = 0; 10312 noninteractive_need_newline = 0;
10328 vfprintf (stderr, m, ap); 10313 vfprintf (stderr, m, ap);
10329 if (cursor_in_echo_area == 0) 10314 if (!cursor_in_echo_area)
10330 fprintf (stderr, "\n"); 10315 fprintf (stderr, "\n");
10331 fflush (stderr); 10316 fflush (stderr);
10332 } 10317 }
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)
1095 int unit = FRAME_LINE_HEIGHT (f); 1095 int unit = FRAME_LINE_HEIGHT (f);
1096 int old_height = FRAME_TOOL_BAR_HEIGHT (f); 1096 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1097 int lines = (height + unit - 1) / unit; 1097 int lines = (height + unit - 1) / unit;
1098 Lisp_Object fullscreen;
1098 1099
1099 /* Make sure we redisplay all windows in this frame. */ 1100 /* Make sure we redisplay all windows in this frame. */
1100 windows_or_buffers_changed = 60; 1101 windows_or_buffers_changed = 60;
@@ -1126,7 +1127,10 @@ x_change_tool_bar_height (struct frame *f, int height)
1126 f->n_tool_bar_rows = 0; 1127 f->n_tool_bar_rows = 0;
1127 1128
1128 adjust_frame_size (f, -1, -1, 1129 adjust_frame_size (f, -1, -1,
1129 (!f->tool_bar_redisplayed_once ? 1 1130 ((!f->tool_bar_redisplayed_once
1131 && (NILP (fullscreen =
1132 get_frame_param (f, Qfullscreen))
1133 || EQ (fullscreen, Qfullwidth))) ? 1
1130 : (old_height == 0 || height == 0) ? 2 1134 : (old_height == 0 || height == 0) ? 2
1131 : 4), 1135 : 4),
1132 false, Qtool_bar_lines); 1136 false, Qtool_bar_lines);
@@ -3180,8 +3184,6 @@ This function is an internal primitive--use `make-frame' instead. */)
3180 "title", "Title", RES_TYPE_STRING); 3184 "title", "Title", RES_TYPE_STRING);
3181 x_default_parameter (f, parms, Qwait_for_wm, Qt, 3185 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3182 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN); 3186 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3183 x_default_parameter (f, parms, Qfullscreen, Qnil,
3184 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3185 x_default_parameter (f, parms, Qtool_bar_position, 3187 x_default_parameter (f, parms, Qtool_bar_position,
3186 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL); 3188 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
3187 3189
@@ -3259,6 +3261,12 @@ This function is an internal primitive--use `make-frame' instead. */)
3259 x_wm_set_size_hint (f, window_prompting, false); 3261 x_wm_set_size_hint (f, window_prompting, false);
3260 unblock_input (); 3262 unblock_input ();
3261 3263
3264 /* Process fullscreen parameter here in the hope that normalizing a
3265 fullheight/fullwidth frame will produce the size set by the last
3266 adjust_frame_size call. */
3267 x_default_parameter (f, parms, Qfullscreen, Qnil,
3268 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3269
3262 /* Make the window appear on the frame and enable display, unless 3270 /* Make the window appear on the frame and enable display, unless
3263 the caller says not to. However, with explicit parent, Emacs 3271 the caller says not to. However, with explicit parent, Emacs
3264 cannot control visibility, so don't try. */ 3272 cannot control visibility, so don't try. */
@@ -4318,7 +4326,7 @@ elements (all size values are in pixels).
4318 inner_height -= tool_bar_height; 4326 inner_height -= tool_bar_height;
4319 4327
4320 return 4328 return
4321 listn (CONSTYPE_PURE, 10, 4329 listn (CONSTYPE_HEAP, 10,
4322 Fcons (Qframe_position, 4330 Fcons (Qframe_position,
4323 Fcons (make_number (f->left_pos), make_number (f->top_pos))), 4331 Fcons (make_number (f->left_pos), make_number (f->top_pos))),
4324 Fcons (Qframe_outer_size, 4332 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
215 }; 215 };
216 216
217static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *); 217static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
218static void x_set_window_size_1 (struct frame *, bool, int, int, bool); 218static void x_set_window_size_1 (struct frame *, bool, int, int);
219static void x_raise_frame (struct frame *); 219static void x_raise_frame (struct frame *);
220static void x_lower_frame (struct frame *); 220static void x_lower_frame (struct frame *);
221static const XColor *x_color_cells (Display *, int *); 221static const XColor *x_color_cells (Display *, int *);
@@ -6585,6 +6585,10 @@ x_net_wm_state (struct frame *f, Window window)
6585 break; 6585 break;
6586 } 6586 }
6587 6587
6588 frame_size_history_add
6589 (f, Qx_net_wm_state, 0, 0,
6590 list2 (get_frame_param (f, Qfullscreen), lval));
6591
6588 store_frame_param (f, Qfullscreen, lval); 6592 store_frame_param (f, Qfullscreen, lval);
6589/** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/ 6593/** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/
6590} 6594}
@@ -9242,30 +9246,78 @@ do_ewmh_fullscreen (struct frame *f)
9242 None); 9246 None);
9243 break; 9247 break;
9244 case FULLSCREEN_WIDTH: 9248 case FULLSCREEN_WIDTH:
9245 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT 9249 if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
9246 || cur == FULLSCREEN_MAXIMIZED) 9250 {
9247 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, 9251 set_wm_state (frame, false,
9248 dpyinfo->Xatom_net_wm_state_maximized_vert); 9252 dpyinfo->Xatom_net_wm_state_maximized_horz,
9249 if (cur != FULLSCREEN_MAXIMIZED) 9253 dpyinfo->Xatom_net_wm_state_maximized_vert);
9250 set_wm_state (frame, true, 9254 set_wm_state (frame, true,
9251 dpyinfo->Xatom_net_wm_state_maximized_horz, None); 9255 dpyinfo->Xatom_net_wm_state_maximized_horz, None);
9256 }
9257 else
9258 {
9259 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT
9260 || cur == FULLSCREEN_MAXIMIZED)
9261 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
9262 dpyinfo->Xatom_net_wm_state_maximized_vert);
9263 if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
9264 set_wm_state (frame, true,
9265 dpyinfo->Xatom_net_wm_state_maximized_horz, None);
9266 }
9252 break; 9267 break;
9253 case FULLSCREEN_HEIGHT: 9268 case FULLSCREEN_HEIGHT:
9254 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH 9269 if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
9255 || cur == FULLSCREEN_MAXIMIZED) 9270 {
9256 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, 9271 set_wm_state (frame, false,
9257 dpyinfo->Xatom_net_wm_state_maximized_horz); 9272 dpyinfo->Xatom_net_wm_state_maximized_horz,
9258 if (cur != FULLSCREEN_MAXIMIZED) 9273 dpyinfo->Xatom_net_wm_state_maximized_vert);
9259 set_wm_state (frame, true, 9274 set_wm_state (frame, true,
9260 dpyinfo->Xatom_net_wm_state_maximized_vert, None); 9275 dpyinfo->Xatom_net_wm_state_maximized_vert, None);
9276 }
9277 else
9278 {
9279 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH
9280 || cur == FULLSCREEN_MAXIMIZED)
9281 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
9282 dpyinfo->Xatom_net_wm_state_maximized_horz);
9283 if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
9284 set_wm_state (frame, true,
9285 dpyinfo->Xatom_net_wm_state_maximized_vert, None);
9286 }
9261 break; 9287 break;
9262 case FULLSCREEN_MAXIMIZED: 9288 case FULLSCREEN_MAXIMIZED:
9263 if (cur == FULLSCREEN_BOTH) 9289 if (x_frame_normalize_before_maximize && cur == FULLSCREEN_WIDTH)
9264 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, 9290 {
9265 None); 9291 set_wm_state (frame, false,
9266 set_wm_state (frame, true, 9292 dpyinfo->Xatom_net_wm_state_maximized_horz, None);
9267 dpyinfo->Xatom_net_wm_state_maximized_horz, 9293 set_wm_state (frame, true,
9268 dpyinfo->Xatom_net_wm_state_maximized_vert); 9294 dpyinfo->Xatom_net_wm_state_maximized_horz,
9295 dpyinfo->Xatom_net_wm_state_maximized_vert);
9296 }
9297 else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_HEIGHT)
9298 {
9299 set_wm_state (frame, false,
9300 dpyinfo->Xatom_net_wm_state_maximized_vert, None);
9301 set_wm_state (frame, true,
9302 dpyinfo->Xatom_net_wm_state_maximized_horz,
9303 dpyinfo->Xatom_net_wm_state_maximized_vert);
9304 }
9305 else
9306 {
9307 if (cur == FULLSCREEN_BOTH)
9308 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
9309 None);
9310 else if (cur == FULLSCREEN_HEIGHT)
9311 set_wm_state (frame, true,
9312 dpyinfo->Xatom_net_wm_state_maximized_horz, None);
9313 else if (cur == FULLSCREEN_WIDTH)
9314 set_wm_state (frame, true, None,
9315 dpyinfo->Xatom_net_wm_state_maximized_vert);
9316 else
9317 set_wm_state (frame, true,
9318 dpyinfo->Xatom_net_wm_state_maximized_horz,
9319 dpyinfo->Xatom_net_wm_state_maximized_vert);
9320 }
9269 break; 9321 break;
9270 case FULLSCREEN_NONE: 9322 case FULLSCREEN_NONE:
9271 if (cur == FULLSCREEN_BOTH) 9323 if (cur == FULLSCREEN_BOTH)
@@ -9322,6 +9374,10 @@ x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event)
9322 break; 9374 break;
9323 } 9375 }
9324 9376
9377 frame_size_history_add
9378 (f, Qx_handle_net_wm_state, 0, 0,
9379 list2 (get_frame_param (f, Qfullscreen), lval));
9380
9325 store_frame_param (f, Qfullscreen, lval); 9381 store_frame_param (f, Qfullscreen, lval);
9326 store_frame_param (f, Qsticky, sticky ? Qt : Qnil); 9382 store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
9327 9383
@@ -9358,13 +9414,26 @@ x_check_fullscreen (struct frame *f)
9358 break; 9414 break;
9359 case FULLSCREEN_WIDTH: 9415 case FULLSCREEN_WIDTH:
9360 width = x_display_pixel_width (dpyinfo); 9416 width = x_display_pixel_width (dpyinfo);
9361 break; 9417 height = height + FRAME_MENUBAR_HEIGHT (f);
9418 break;
9362 case FULLSCREEN_HEIGHT: 9419 case FULLSCREEN_HEIGHT:
9363 height = x_display_pixel_height (dpyinfo); 9420 height = x_display_pixel_height (dpyinfo);
9364 } 9421 }
9365 9422
9423 frame_size_history_add
9424 (f, Qx_check_fullscreen, width, height, Qnil);
9425
9366 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 9426 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
9367 width, height); 9427 width, height);
9428
9429 if (FRAME_VISIBLE_P (f))
9430 x_wait_for_event (f, ConfigureNotify);
9431 else
9432 {
9433 change_frame_size (f, width, height - FRAME_MENUBAR_HEIGHT (f),
9434 false, true, false, true);
9435 x_sync (f);
9436 }
9368 } 9437 }
9369} 9438}
9370 9439
@@ -9505,21 +9574,57 @@ x_wait_for_event (struct frame *f, int eventtype)
9505 9574
9506static void 9575static void
9507x_set_window_size_1 (struct frame *f, bool change_gravity, 9576x_set_window_size_1 (struct frame *f, bool change_gravity,
9508 int width, int height, bool pixelwise) 9577 int width, int height)
9509{ 9578{
9510 int pixelwidth, pixelheight; 9579 int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
9511 9580 int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
9512 pixelwidth = (pixelwise 9581 int old_width = FRAME_PIXEL_WIDTH (f);
9513 ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) 9582 int old_height = FRAME_PIXEL_HEIGHT (f);
9514 : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)); 9583 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
9515 pixelheight = ((pixelwise
9516 ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height)
9517 : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height)));
9518 9584
9519 if (change_gravity) f->win_gravity = NorthWestGravity; 9585 if (change_gravity) f->win_gravity = NorthWestGravity;
9520 x_wm_set_size_hint (f, 0, false); 9586 x_wm_set_size_hint (f, 0, false);
9521 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 9587
9522 pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); 9588 /* When the frame is fullheight and we only want to change the width
9589 or it is fullwidth and we only want to change the height we should
9590 be able to preserve the fullscreen property. However, due to the
9591 fact that we have to send a resize request anyway, the window
9592 manager will abolish it. At least the respective size should
9593 remain unchanged but giving the frame back its normal size will
9594 be broken ... */
9595 if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f))
9596 {
9597 frame_size_history_add
9598 (f, Qxg_frame_set_char_size_1, width, height,
9599 list2 (make_number (old_height),
9600 make_number (pixelheight + FRAME_MENUBAR_HEIGHT (f))));
9601
9602 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
9603 old_width, pixelheight + FRAME_MENUBAR_HEIGHT (f));
9604 }
9605 else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
9606 {
9607 frame_size_history_add
9608 (f, Qxg_frame_set_char_size_2, width, height,
9609 list2 (make_number (old_width), make_number (pixelwidth)));
9610
9611 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
9612 pixelwidth, old_height);
9613 }
9614
9615 else
9616 {
9617 frame_size_history_add
9618 (f, Qxg_frame_set_char_size_3, width, height,
9619 list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)),
9620 make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f)
9621 + FRAME_MENUBAR_HEIGHT (f))));
9622
9623 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
9624 pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f));
9625 fullscreen = Qnil;
9626 }
9627
9523 9628
9524 9629
9525 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to 9630 /* 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,
9546 not right if the frame is visible. Instead wait (with timeout) 9651 not right if the frame is visible. Instead wait (with timeout)
9547 for the ConfigureNotify. */ 9652 for the ConfigureNotify. */
9548 if (FRAME_VISIBLE_P (f)) 9653 if (FRAME_VISIBLE_P (f))
9549 x_wait_for_event (f, ConfigureNotify); 9654 {
9655 x_wait_for_event (f, ConfigureNotify);
9656
9657 if (!NILP (fullscreen))
9658 /* Try to restore fullscreen state. */
9659 {
9660 store_frame_param (f, Qfullscreen, fullscreen);
9661 x_set_fullscreen (f, fullscreen, fullscreen);
9662 }
9663 }
9550 else 9664 else
9551 { 9665 {
9552 change_frame_size (f, width, height, false, true, false, true); 9666 change_frame_size (f, width, height, false, true, false, true);
@@ -9593,20 +9707,21 @@ x_set_window_size (struct frame *f, bool change_gravity,
9593 } 9707 }
9594#endif 9708#endif
9595 9709
9710 /* Pixelize width and height, if necessary. */
9711 if (! pixelwise)
9712 {
9713 width = width * FRAME_COLUMN_WIDTH (f);
9714 height = height * FRAME_LINE_HEIGHT (f);
9715 }
9716
9596#ifdef USE_GTK 9717#ifdef USE_GTK
9597 if (FRAME_GTK_WIDGET (f)) 9718 if (FRAME_GTK_WIDGET (f))
9598 if (! pixelwise) 9719 xg_frame_set_char_size (f, width, height);
9599 xg_frame_set_char_size (f, width * FRAME_COLUMN_WIDTH (f),
9600 height * FRAME_LINE_HEIGHT (f));
9601 else
9602 xg_frame_set_char_size (f, width, height);
9603 else 9720 else
9604 x_set_window_size_1 (f, change_gravity, width, height, pixelwise); 9721 x_set_window_size_1 (f, change_gravity, width, height);
9605#else /* not USE_GTK */ 9722#else /* not USE_GTK */
9606 9723 x_set_window_size_1 (f, change_gravity, width, height);
9607 x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
9608 x_clear_under_internal_border (f); 9724 x_clear_under_internal_border (f);
9609
9610#endif /* not USE_GTK */ 9725#endif /* not USE_GTK */
9611 9726
9612 /* If cursor was outside the new size, mark it as off. */ 9727 /* If cursor was outside the new size, mark it as off. */
@@ -11617,4 +11732,15 @@ default is nil, which is the same as `super'. */);
11617 make_float (DEFAULT_REHASH_SIZE), 11732 make_float (DEFAULT_REHASH_SIZE),
11618 make_float (DEFAULT_REHASH_THRESHOLD), 11733 make_float (DEFAULT_REHASH_THRESHOLD),
11619 Qnil); 11734 Qnil);
11735
11736 DEFVAR_BOOL ("x-frame-normalize-before-maximize",
11737 x_frame_normalize_before_maximize,
11738 doc: /* Non-nil means normalize frame before maximizing.
11739If this variable is t, Emacs asks the window manager to give the frame
11740intermediately its normal size whenever changing from a full-height or
11741full-width state to the fully maximized one and vice versa.
11742
11743Set this variable only if your window manager cannot handle the
11744transition between the various maximization states. */);
11745 x_frame_normalize_before_maximize = false;
11620} 11746}