summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/faces.el3
-rw-r--r--lisp/frame.el23
-rw-r--r--src/ChangeLog76
-rw-r--r--src/frame.c202
-rw-r--r--src/frame.h13
-rw-r--r--src/gtkutil.c113
-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/xfns.c18
-rw-r--r--src/xterm.c214
13 files changed, 641 insertions, 306 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c67113f2a61..a3abb1a4f1f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,12 @@
+2015-02-07 Martin Rudalics <rudalics@gmx.at>
+
+ * frame.el (frame-notice-user-settings): Update
+ `frame-size-history'.
+ (make-frame): Update `frame-size-history'. Call
+ `frame-after-make-frame'.
+ * faces.el (face-set-after-frame-default): Remove call to
+ frame-can-run-window-configuration-change-hook.
+
2015-02-06 Dmitry Gutov <dgutov@yandex.ru>
* vc/vc-cvs.el (vc-cvs-dir-status-files): Don't pass DIR to
diff --git a/lisp/faces.el b/lisp/faces.el
index 22bf2626722..ce74c728474 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2092,8 +2092,7 @@ frame parameters in PARAMETERS."
(value (cdr (assq param-name parameters))))
(if value
(set-face-attribute (nth 1 param) frame
- (nth 2 param) value))))
- (frame-can-run-window-configuration-change-hook frame t)))
+ (nth 2 param) value))))))
(defun tty-handle-reverse-video (frame parameters)
"Handle the reverse-video frame parameter for terminal frames."
diff --git a/lisp/frame.el b/lisp/frame.el
index 1d5bbf2317e..ecb433e8335 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -465,6 +465,16 @@ there (in decreasing order of priority)."
(frame-set-background-mode frame-initial-frame))
(face-set-after-frame-default frame-initial-frame)
(setq newparms (delq new-bg newparms)))
+
+ (when (numberp (car frame-size-history))
+ (setq frame-size-history
+ (cons (1- (car frame-size-history))
+ (cons
+ (list frame-initial-frame
+ "frame-notice-user-settings"
+ nil newparms)
+ (cdr frame-size-history)))))
+
(modify-frame-parameters frame-initial-frame newparms)))))
;; Restore the original buffer.
@@ -686,7 +696,7 @@ the new frame according to its own rules."
;; Now make the frame.
(run-hooks 'before-make-frame-hook)
-;; (setq frame-adjust-size-history '(t))
+;; (setq frame-size-history '(1000))
(setq frame
(funcall (gui-method frame-creation-function w) params))
@@ -697,11 +707,14 @@ the new frame according to its own rules."
(let ((val (frame-parameter oldframe param)))
(when val (set-frame-parameter frame param val)))))
- (when (eq (car frame-adjust-size-history) t)
- (setq frame-adjust-size-history
- (cons t (cons (list "Frame made")
- (cdr frame-adjust-size-history)))))
+ (when (numberp (car frame-size-history))
+ (setq frame-size-history
+ (cons (1- (car frame-size-history))
+ (cons (list frame "make-frame")
+ (cdr frame-size-history)))))
+ ;; We can run `window-configuration-change-hook' for this frame now.
+ (frame-after-make-frame frame t)
(run-hook-with-args 'after-make-frame-functions frame)
frame))
diff --git a/src/ChangeLog b/src/ChangeLog
index cd72f98c116..ec70cdb93a9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,79 @@
+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
diff --git a/src/frame.c b/src/frame.c
index 890e8972617..96fe3778dbc 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -149,6 +149,33 @@ 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;
+ int number;
+
+ XSETFRAME (frame, f);
+ if (CONSP (frame_size_history)
+ && NUMBERP (Fcar (frame_size_history))
+ && ((number = XINT (Fcar (frame_size_history))) > 0))
+ frame_size_history =
+ Fcons (make_number (number - 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),
+ Fcdr (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 +183,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 +412,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 +425,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 +483,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 +553,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 +566,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 +630,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 +1042,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 +2283,25 @@ 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) ? false : true;
+
+ return made;
}
@@ -3037,7 +3061,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 +3069,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 +3166,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 +3251,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 +3331,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 +4881,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 +5175,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 +5223,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..063e88262d9 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -886,23 +886,25 @@ 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;
+/** 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);
@@ -921,24 +923,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 +1001,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 +4271,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 +4550,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 +4877,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 +4928,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 +4958,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 2f44bf78304..293140041a9 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3329,7 +3329,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/xfns.c b/src/xfns.c
index 65eb6b497f2..e667e71b563 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,9 +3184,7 @@ 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,
+ x_default_parameter (f, parms, Qtool_bar_position,
FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
/* Compute the size of the X window. */
@@ -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 3955d027a52..6a63a454bac 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -212,7 +212,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 *);
@@ -6575,6 +6575,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); **/
}
@@ -9227,30 +9231,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)
@@ -9307,6 +9359,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);
@@ -9343,13 +9399,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);
+ }
}
}
@@ -9490,21 +9559,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
@@ -9531,7 +9636,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);
@@ -9578,20 +9692,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. */
@@ -11602,4 +11717,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;
}