mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-02 10:11:05 -08:00
Add functions to set frame size and position in one compound step
* lisp/frame.el (set-frame-size-and-position): New function. * src/frame.c (adjust_frame_size): Handle requests to set size and position. (Fset_frame_size_and_position_pixelwise): New function. * src/gtkutil.c (xg_frame_set_size_and_position): New function. (xg_wm_set_size_hint): Handle any non-NorthWestGravity values for child frames only. Some GTK implementations don't like them. * src/gtkutil.h (xg_frame_set_size_and_position.): Add external declaration. * src/termhooks.h (set_window_size_and_position_hook): New hook. * src/w32term.c (w32_set_window_size_and_position): New function. (w32_create_terminal): Make it the Microsoft Windows API set_window_size_and_position_hook. * src/xterm.c (x_set_window_size_and_position_1) (x_set_window_size_and_position): New functions. (x_create_terminal): Make x_set_window_size_and_position the set_window_size_and_position_hook for the X protocol. * src/xterm.h (x_set_window_size_and_position): Add external declaration. * etc/NEWS: Announce new functions.
This commit is contained in:
parent
5cf8af2290
commit
f3d9371a89
9 changed files with 505 additions and 23 deletions
7
etc/NEWS
7
etc/NEWS
|
|
@ -465,6 +465,13 @@ either resize the frame and change the fullscreen status accordingly or
|
|||
keep the frame size unchanged. The value t means to first reset the
|
||||
fullscreen status and then resize the frame.
|
||||
|
||||
*** New commands to set frame size and position in one compound step.
|
||||
'set-frame-size-and-position' sets the new size and position of a frame
|
||||
in one compound step. Both, size and position, can be specified as with
|
||||
the corresponding frame parameters 'width', 'height', 'left' and 'top'.
|
||||
'set-frame-size-and-position-pixelwise' is similar but has a more
|
||||
restricted set of values for specifying size and position.
|
||||
|
||||
*** New commands 'split-frame' and 'merge-frames'.
|
||||
'split-frame' moves a specified number of windows from an existing frame
|
||||
to a newly-created frame. 'merge-frames' merges all windows from two
|
||||
|
|
|
|||
194
lisp/frame.el
194
lisp/frame.el
|
|
@ -1534,6 +1534,200 @@ Functions on this hook are called with the theme name as a symbol:
|
|||
`light' or `dark'. By the time the hook is called, `toolkit-theme' will
|
||||
already be set to one of these values as well.")
|
||||
|
||||
|
||||
(defun set-frame-size-and-position (&optional frame width height left top)
|
||||
"Set size and position of specified FRAME in one compound step.
|
||||
WIDTH and HEIGHT stand for the new width and height of FRAME. They can
|
||||
be specified as follows where \"display area\" stands for the entire
|
||||
display area of FRAME's dominating monitor, \"work area\" stands for the
|
||||
work area (the usable space) of FRAME's display area and \"parent area\"
|
||||
stands for the area occupied by the native rectangle of FRAME's parent
|
||||
provided FRAME is a child frame.
|
||||
|
||||
- An integer specifies the size of FRAME's text area in characters.
|
||||
|
||||
- A cons cell with the symbol `text-pixels' in its car specifies in its
|
||||
cdr the size of FRAME's text area in pixels.
|
||||
|
||||
- A floating-point number between 0.0 and 1.0 specifies the ratio of
|
||||
FRAME's outer size to the size of its work or parent area.
|
||||
|
||||
Unless you use a plain integer value, you may have to set
|
||||
`frame-resize-pixelwise' to a non-nil value in order to get the exact
|
||||
size in pixels. A value of nil means to leave the width or height
|
||||
unaltered. Any other value will signal an error.
|
||||
|
||||
LEFT and TOP stand for FRAME's outer position relative to coordinates of
|
||||
its display, work or parent area. They can be specified as follows:
|
||||
|
||||
- An integer where a positive value relates the left or top edge of
|
||||
FRAME to the origin of its display or parent area. A negative value
|
||||
relates the right or bottom edge of FRAME to the right or bottom edge
|
||||
of its display or parent area.
|
||||
|
||||
- The symbol `-' means to place the right or bottom edge of FRAME at the
|
||||
right or bottom edge of its display or parent area.
|
||||
|
||||
- A list with `+' as its first and an integer as its second element
|
||||
specifies the position of the left or top edge of FRAME relative to
|
||||
the left or top edge of its display or parent area. If the second
|
||||
element is negative, this means a position outside FRAME's display or
|
||||
parent area.
|
||||
|
||||
- A list with `-' as its first and an integer as its second element
|
||||
specifies the position of the right or bottom edge of FRAME relative
|
||||
to the right or bottom edge of its display or parent area. If the
|
||||
second element is negative, this means a position outside the area of
|
||||
its display or parent area.
|
||||
|
||||
- A floating-point number between 0.0 and 1.0 specifies the ratio of
|
||||
FRAME's outer position to the size of its work or parent area. Thus,
|
||||
a value of 0.0 flushes FRAME to the left or top, a value of 0.5
|
||||
centers it and a ratio of 1.0 flushes it to the right or bottom of its
|
||||
work or parent area.
|
||||
|
||||
Calculating a position relative to the right or bottom edge of FRAME's
|
||||
display, work or parent area proceeds by calculating the new size of
|
||||
FRAME first and then relate the new prospective outer edges of FRAME to
|
||||
the respective edges of its display, work or parent area.
|
||||
|
||||
A value of nil means to leave the position in this direction unchanged.
|
||||
Any other value will signal an error.
|
||||
|
||||
This function calls `set-frame-size-and-position-pixelwise' to actually
|
||||
resize and move FRAME."
|
||||
(let* ((frame (window-normalize-frame frame))
|
||||
(parent (frame-parent frame))
|
||||
(monitor-attributes
|
||||
(unless parent
|
||||
(frame-monitor-attributes frame)))
|
||||
(geometry
|
||||
(unless parent
|
||||
(cdr (assq 'geometry monitor-attributes))))
|
||||
(parent-or-display-width
|
||||
(if parent
|
||||
(frame-native-width parent)
|
||||
(nth 2 geometry)))
|
||||
(parent-or-display-height
|
||||
(if parent
|
||||
(frame-native-height parent)
|
||||
(nth 3 geometry)))
|
||||
(parent-or-workarea
|
||||
(if parent
|
||||
`(0 0 ,parent-or-display-width ,parent-or-display-height)
|
||||
(cdr (assq 'workarea monitor-attributes))))
|
||||
(outer-edges (frame-edges frame 'outer-edges))
|
||||
(outer-left (nth 0 outer-edges))
|
||||
(outer-top (nth 1 outer-edges))
|
||||
(outer-width (if outer-edges
|
||||
(- (nth 2 outer-edges) outer-left)
|
||||
(frame-pixel-width frame)))
|
||||
(outer-minus-text-width
|
||||
(- outer-width (frame-text-width frame)))
|
||||
(outer-height (if outer-edges
|
||||
(- (nth 3 outer-edges) outer-top)
|
||||
(frame-pixel-height frame)))
|
||||
(outer-minus-text-height
|
||||
(- outer-height (frame-text-height frame)))
|
||||
(old-text-width (frame-text-width frame))
|
||||
(old-text-height (frame-text-height frame))
|
||||
(text-width old-text-width)
|
||||
(text-height old-text-height)
|
||||
(char-width (frame-char-width frame))
|
||||
(char-height (frame-char-height frame))
|
||||
(gravity 1)
|
||||
negative)
|
||||
|
||||
(cond
|
||||
((and (integerp width) (> width 0))
|
||||
(setq text-width (* width char-width)))
|
||||
((and (consp width) (eq (car width) 'text-pixels)
|
||||
(integerp (cdr width)) (> (cdr width) 0))
|
||||
(setq text-width (cdr width)))
|
||||
((and (floatp width) (> width 0.0) (<= width 1.0))
|
||||
(setq text-width
|
||||
(- (round (* width (- (nth 2 parent-or-workarea)
|
||||
(nth 0 parent-or-workarea))))
|
||||
outer-minus-text-width)))
|
||||
(width
|
||||
(user-error "Invalid width specification")))
|
||||
|
||||
(cond
|
||||
((and (integerp height) (> height 0))
|
||||
(setq text-height (* height char-height)))
|
||||
((and (consp height) (eq (car height) 'text-pixels)
|
||||
(integerp (cdr height)) (> (cdr height) 0))
|
||||
(setq text-height (cdr height)))
|
||||
((and (floatp height) (> height 0.0) (<= height 1.0))
|
||||
(setq text-height
|
||||
(- (round (* height (- (nth 3 parent-or-workarea)
|
||||
(nth 1 parent-or-workarea))))
|
||||
outer-minus-text-height)))
|
||||
(width
|
||||
(user-error "Invalid height specification")))
|
||||
|
||||
(cond
|
||||
((eq left '-)
|
||||
(setq left 0)
|
||||
(setq negative t))
|
||||
((integerp left)
|
||||
(setq negative (< left 0)))
|
||||
((consp left)
|
||||
(cond
|
||||
((and (eq (car left) '-) (integerp (cadr left)))
|
||||
(setq left (- (cadr left)))
|
||||
(setq negative t))
|
||||
((and (eq (car left) '+) (integerp (cadr left)))
|
||||
(setq left (cadr left)))
|
||||
(t
|
||||
(user-error "Invalid position specification"))))
|
||||
((floatp left)
|
||||
(setq left
|
||||
(round (* left (- (nth 2 parent-or-workarea)
|
||||
(nth 0 parent-or-workarea))))))
|
||||
(t (setq left outer-left)))
|
||||
|
||||
(when negative
|
||||
(setq gravity 3)
|
||||
(setq left (- parent-or-display-width (- left)
|
||||
(+ text-width
|
||||
(frame-scroll-bar-width frame)
|
||||
(frame-fringe-width frame)
|
||||
(* 2 (frame-internal-border-width frame))
|
||||
outer-minus-text-width))))
|
||||
|
||||
(setq negative nil)
|
||||
(cond
|
||||
((eq top '-)
|
||||
(setq top 0)
|
||||
(setq negative t))
|
||||
((integerp top)
|
||||
(setq negative (< top 0)))
|
||||
((consp top)
|
||||
(cond
|
||||
((and (eq (car top) '-) (integerp (cadr top)))
|
||||
(setq top (- (cadr top)))
|
||||
(setq negative t))
|
||||
((and (eq (car top) '+) (integerp (cadr top)))
|
||||
(setq top (cadr top)))
|
||||
(t
|
||||
(user-error "Invalid position specification"))))
|
||||
((floatp top)
|
||||
(setq top
|
||||
(round (* top (- (nth 3 parent-or-workarea)
|
||||
(nth 1 parent-or-workarea))))))
|
||||
(t (setq top outer-top)))
|
||||
|
||||
(when negative
|
||||
;; This should get us 7 or 9.
|
||||
(setq gravity (+ gravity 6))
|
||||
(setq top (- parent-or-display-height (- top)
|
||||
(+ text-height
|
||||
(* 2 (frame-internal-border-width frame)))
|
||||
outer-minus-text-height)))
|
||||
|
||||
(set-frame-size-and-position-pixelwise
|
||||
frame text-width text-height left top gravity)))
|
||||
|
||||
;;;; Frame configurations
|
||||
|
||||
|
|
|
|||
77
src/frame.c
77
src/frame.c
|
|
@ -777,6 +777,7 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
|
|||
int old_text_width = FRAME_TEXT_WIDTH (f);
|
||||
int old_text_height = FRAME_TEXT_HEIGHT (f);
|
||||
bool inhibit_horizontal, inhibit_vertical;
|
||||
bool size_and_position = EQ (parameter, Qsize_and_position);
|
||||
Lisp_Object frame;
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
|
|
@ -855,7 +856,8 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
|
|||
/* For inhibit == 1 call the window_size_hook only if a native
|
||||
size changes. For inhibit == 0 or inhibit == 2 always call
|
||||
it. */
|
||||
&& ((!inhibit_horizontal
|
||||
&& (size_and_position
|
||||
|| (!inhibit_horizontal
|
||||
&& (new_native_width != old_native_width
|
||||
|| inhibit == 0 || inhibit == 2))
|
||||
|| (!inhibit_vertical
|
||||
|
|
@ -907,7 +909,13 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
|
|||
f->new_size_p = false;
|
||||
}
|
||||
|
||||
if (FRAME_TERMINAL (f)->set_window_size_hook)
|
||||
if (size_and_position)
|
||||
/* The caller must have set the new position and gravity and
|
||||
made sure that set_window_size_and_position_hook has been
|
||||
defined. */
|
||||
FRAME_TERMINAL (f)->set_window_size_and_position_hook
|
||||
(f, new_native_width, new_native_height);
|
||||
else if (FRAME_TERMINAL (f)->set_window_size_hook)
|
||||
FRAME_TERMINAL (f)->set_window_size_hook
|
||||
(f, 0, new_native_width, new_native_height);
|
||||
f->resized_p = true;
|
||||
|
|
@ -4545,6 +4553,69 @@ bottom edge of FRAME's display. */)
|
|||
return Qt;
|
||||
}
|
||||
|
||||
DEFUN ("set-frame-size-and-position-pixelwise", Fset_frame_size_and_position_pixelwise,
|
||||
Sset_frame_size_and_position_pixelwise, 5, 6, 0,
|
||||
doc: /* Set FRAME's size to WIDTH and HEIGHT and its position to (X, Y).
|
||||
FRAME must be a live frame and defaults to the selected one.
|
||||
|
||||
WIDTH and HEIGHT must be positive integers and specify the new pixel
|
||||
width and height of FRAME's text area in pixels. If WIDTH or HEIGHT do
|
||||
not secify a value that is a multiple of FRAME's character sizes, you
|
||||
may have to set `frame-resize-pixelwise' to a non-nil value in order to
|
||||
get the exact size in pixels.
|
||||
|
||||
X and Y specify the coordinates of the left and top edge of FRAME's
|
||||
outer frame in pixels relative to an origin (0, 0) of FRAME's display or
|
||||
parent frame. Negative values mean the top or left edge may be outside
|
||||
the display or parent frame.
|
||||
|
||||
GRAVITY specifies the new gravity of FRAME and must be a value in the
|
||||
range 0..10. It defaults to 1.
|
||||
|
||||
This function uses any existing backend of the toolkit to resize and
|
||||
move FRAME in one compound step. If the backend does not provide such a
|
||||
function, it calls `set-frame-size' followed by `set-frame-position'
|
||||
instead. See 'set-frame-size-and-position'. */)
|
||||
(Lisp_Object frame, Lisp_Object width, Lisp_Object height,
|
||||
Lisp_Object x, Lisp_Object y, Lisp_Object gravity)
|
||||
{
|
||||
struct frame *f = decode_live_frame (frame);
|
||||
|
||||
if (NILP (gravity))
|
||||
f->win_gravity = 1;
|
||||
else
|
||||
f->win_gravity = check_integer_range (gravity, 0, 10);
|
||||
|
||||
if (FRAME_WINDOW_P (f)
|
||||
&& FRAME_TERMINAL (f)->set_window_size_and_position_hook)
|
||||
{
|
||||
int text_width = check_integer_range (width, 1, INT_MAX);
|
||||
int text_height = check_integer_range (height, 1, INT_MAX);
|
||||
|
||||
f->left_pos = check_integer_range (x, INT_MIN, INT_MAX);
|
||||
f->top_pos = check_integer_range (y, INT_MIN, INT_MAX);
|
||||
|
||||
adjust_frame_size (f, text_width, text_height, 1, false,
|
||||
Qsize_and_position);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fset_frame_size (frame, width, height, Qt);
|
||||
|
||||
int left_pos = check_integer_range (x, INT_MIN, INT_MAX);
|
||||
int top_pos = check_integer_range (y, INT_MIN, INT_MAX);
|
||||
|
||||
Lisp_Object left
|
||||
= Fcons (Qleft, left_pos < 0 ? list2 (Qplus, x) : x);
|
||||
Lisp_Object top
|
||||
= Fcons (Qtop, top_pos < 0 ? list2 (Qplus, y) : y);
|
||||
|
||||
Fmodify_frame_parameters (frame, list2 (left, top));
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("frame-window-state-change", Fframe_window_state_change,
|
||||
Sframe_window_state_change, 0, 1, 0,
|
||||
doc: /* Return t if FRAME's window state change flag is set, nil otherwise.
|
||||
|
|
@ -7113,6 +7184,7 @@ syms_of_frame (void)
|
|||
DEFSYM (Qmin_height, "min-height");
|
||||
DEFSYM (Qmouse_wheel_frame, "mouse-wheel-frame");
|
||||
DEFSYM (Qkeep_ratio, "keep-ratio");
|
||||
DEFSYM (Qsize_and_position, "size-and-position");
|
||||
DEFSYM (Qwidth_only, "width-only");
|
||||
DEFSYM (Qheight_only, "height-only");
|
||||
DEFSYM (Qleft_only, "left-only");
|
||||
|
|
@ -7593,6 +7665,7 @@ The default is \\+`inhibit' in NS builds and nil everywhere else. */);
|
|||
defsubr (&Sset_frame_size);
|
||||
defsubr (&Sframe_position);
|
||||
defsubr (&Sset_frame_position);
|
||||
defsubr (&Sset_frame_size_and_position_pixelwise);
|
||||
defsubr (&Sframe_pointer_visible_p);
|
||||
defsubr (&Smouse_position_in_root_frame);
|
||||
defsubr (&Sframe__set_was_invisible);
|
||||
|
|
|
|||
108
src/gtkutil.c
108
src/gtkutil.c
|
|
@ -1384,6 +1384,67 @@ xg_height_or_width_changed (struct frame *f)
|
|||
}
|
||||
#endif
|
||||
|
||||
/** Move and resize the outer window of frame F. WIDTH and HEIGHT are
|
||||
the new native pixel sizes of F. */
|
||||
void
|
||||
xg_frame_set_size_and_position (struct frame *f, int width, int height)
|
||||
{
|
||||
int outer_height
|
||||
= height + FRAME_TOOLBAR_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
|
||||
int outer_width = width + FRAME_TOOLBAR_WIDTH (f);
|
||||
int scale = xg_get_scale (f);
|
||||
int x = f->left_pos;
|
||||
int y = f->top_pos;
|
||||
GdkWindow *gwin = NULL;
|
||||
int flags = 0;
|
||||
|
||||
if (FRAME_GTK_OUTER_WIDGET (f))
|
||||
gwin = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f));
|
||||
else
|
||||
gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
|
||||
|
||||
outer_height /= scale;
|
||||
outer_width /= scale;
|
||||
|
||||
/* Full force ahead. For top-level frames the gravity will get reset
|
||||
to NorthWestGravity anyway. */
|
||||
flags |= USSize;
|
||||
if (f->win_gravity == 3 || f->win_gravity == 9)
|
||||
flags |= XNegative;
|
||||
if (f->win_gravity == 6 || f->win_gravity == 9)
|
||||
flags |= YNegative;
|
||||
flags |= USPosition;
|
||||
|
||||
xg_wm_set_size_hint (f, flags, true);
|
||||
|
||||
#ifndef HAVE_PGTK
|
||||
gdk_window_move_resize (gwin, x, y, outer_width, outer_height);
|
||||
#else
|
||||
if (FRAME_GTK_OUTER_WIDGET (f))
|
||||
gdk_window_move_resize (gwin, x, y, outer_width, outer_height);
|
||||
else
|
||||
gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
|
||||
outer_width, outer_height);
|
||||
#endif
|
||||
|
||||
SET_FRAME_GARBAGED (f);
|
||||
cancel_mouse_face (f);
|
||||
|
||||
if (FRAME_VISIBLE_P (f))
|
||||
{
|
||||
/* Must call this to flush out events */
|
||||
(void)gtk_events_pending ();
|
||||
gdk_flush ();
|
||||
#ifndef HAVE_PGTK
|
||||
x_wait_for_event (f, ConfigureNotify);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
|
||||
FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
|
||||
5, 0, Qxg_frame_set_char_size);
|
||||
}
|
||||
|
||||
#ifndef HAVE_PGTK
|
||||
/* Convert an X Window WSESC on display DPY to its corresponding GtkWidget.
|
||||
Must be done like this, because GtkWidget:s can have "hidden"
|
||||
|
|
@ -2041,28 +2102,33 @@ xg_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
|
|||
|
||||
/* These currently have a one to one mapping with the X values, but I
|
||||
don't think we should rely on that. */
|
||||
hint_flags |= GDK_HINT_WIN_GRAVITY;
|
||||
size_hints.win_gravity = 0;
|
||||
if (win_gravity == NorthWestGravity)
|
||||
if (FRAME_PARENT_FRAME (f))
|
||||
{
|
||||
hint_flags |= GDK_HINT_WIN_GRAVITY;
|
||||
size_hints.win_gravity = 0;
|
||||
if (win_gravity == NorthWestGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_NORTH_WEST;
|
||||
else if (win_gravity == NorthGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_NORTH;
|
||||
else if (win_gravity == NorthEastGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_NORTH_EAST;
|
||||
else if (win_gravity == WestGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_WEST;
|
||||
else if (win_gravity == CenterGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_CENTER;
|
||||
else if (win_gravity == EastGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_EAST;
|
||||
else if (win_gravity == SouthWestGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_SOUTH_WEST;
|
||||
else if (win_gravity == SouthGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_SOUTH;
|
||||
else if (win_gravity == SouthEastGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_SOUTH_EAST;
|
||||
else if (win_gravity == StaticGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_STATIC;
|
||||
}
|
||||
else
|
||||
size_hints.win_gravity = GDK_GRAVITY_NORTH_WEST;
|
||||
else if (win_gravity == NorthGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_NORTH;
|
||||
else if (win_gravity == NorthEastGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_NORTH_EAST;
|
||||
else if (win_gravity == WestGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_WEST;
|
||||
else if (win_gravity == CenterGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_CENTER;
|
||||
else if (win_gravity == EastGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_EAST;
|
||||
else if (win_gravity == SouthWestGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_SOUTH_WEST;
|
||||
else if (win_gravity == SouthGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_SOUTH;
|
||||
else if (win_gravity == SouthEastGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_SOUTH_EAST;
|
||||
else if (win_gravity == StaticGravity)
|
||||
size_hints.win_gravity = GDK_GRAVITY_STATIC;
|
||||
|
||||
if (flags & PPosition)
|
||||
hint_flags |= GDK_HINT_POS;
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ extern void xg_frame_resized (struct frame *f,
|
|||
int pixelwidth,
|
||||
int pixelheight);
|
||||
extern void xg_frame_set_char_size (struct frame *f, int width, int height);
|
||||
extern void xg_frame_set_size_and_position (struct frame *f, int width,
|
||||
int height);
|
||||
extern GtkWidget * xg_win_to_widget (Display *dpy, Window wdesc);
|
||||
|
||||
extern int xg_get_scale (struct frame *f);
|
||||
|
|
|
|||
|
|
@ -684,6 +684,11 @@ struct terminal
|
|||
void (*set_window_size_hook) (struct frame *f, bool change_gravity,
|
||||
int width, int height);
|
||||
|
||||
/* This hook is called to change the size and position of frame F's
|
||||
native (underlying) window. */
|
||||
void (*set_window_size_and_position_hook) (struct frame *f, int width,
|
||||
int height);
|
||||
|
||||
/* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
|
||||
to really change the position, and 0 when calling from
|
||||
*_make_frame_visible (in that case, XOFF and YOFF are the current
|
||||
|
|
|
|||
|
|
@ -7237,6 +7237,85 @@ w32_set_window_size (struct frame *f, bool change_gravity,
|
|||
|
||||
do_pending_window_change (false);
|
||||
}
|
||||
|
||||
/* Change the size of frame F's Windows window to WIDTH and HEIGHT
|
||||
pixels and its position to those stored in f->left_pos and
|
||||
f->top_pos. */
|
||||
static void
|
||||
w32_set_window_size_and_position (struct frame *f, int width, int height)
|
||||
{
|
||||
RECT rect;
|
||||
MENUBARINFO info;
|
||||
int menu_bar_height;
|
||||
|
||||
block_input ();
|
||||
|
||||
/* Get the height of the menu bar here. It's used below to detect
|
||||
whether the menu bar is wrapped. It's also used to specify the
|
||||
third argument for AdjustWindowRect. See bug#22105. */
|
||||
info.cbSize = sizeof (info);
|
||||
info.rcBar.top = info.rcBar.bottom = 0;
|
||||
GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
|
||||
menu_bar_height = info.rcBar.bottom - info.rcBar.top;
|
||||
|
||||
if (w32_add_wrapped_menu_bar_lines)
|
||||
{
|
||||
/* When the menu bar wraps sending a SetWindowPos shrinks the
|
||||
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. */
|
||||
int default_menu_bar_height;
|
||||
|
||||
/* Why is (apparently) SM_CYMENUSIZE needed here instead of
|
||||
SM_CYMENU ?? */
|
||||
default_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
|
||||
|
||||
if ((default_menu_bar_height > 0)
|
||||
&& (menu_bar_height > default_menu_bar_height)
|
||||
&& ((menu_bar_height % default_menu_bar_height) == 0))
|
||||
height = height + menu_bar_height - default_menu_bar_height;
|
||||
}
|
||||
|
||||
f->win_gravity = NorthWestGravity;
|
||||
w32_wm_set_size_hint (f, (long) 0, false);
|
||||
|
||||
rect.left = f->left_pos;
|
||||
rect.top = f->top_pos;
|
||||
rect.right = rect.left + width;
|
||||
rect.bottom = rect.top + height;
|
||||
|
||||
AdjustWindowRect (&rect, f->output_data.w32->dwStyle, menu_bar_height > 0);
|
||||
|
||||
if (!FRAME_PARENT_FRAME (f))
|
||||
my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
|
||||
f->left_pos, f->top_pos,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
else
|
||||
my_set_window_pos (FRAME_W32_WINDOW (f), HWND_TOP,
|
||||
f->left_pos, f->top_pos,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
SWP_NOACTIVATE);
|
||||
|
||||
change_frame_size (f, width, height, false, true, false);
|
||||
SET_FRAME_GARBAGED (f);
|
||||
|
||||
/* If cursor was outside the new size, mark it as off. */
|
||||
mark_window_cursors_off (XWINDOW (f->root_window));
|
||||
|
||||
/* Clear out any recollection of where the mouse highlighting was,
|
||||
since it might be in a place that's outside the new frame size.
|
||||
Actually checking whether it is outside is a pain in the neck,
|
||||
so don't try--just let the highlighting be done afresh with new
|
||||
size. */
|
||||
cancel_mouse_face (f);
|
||||
|
||||
unblock_input ();
|
||||
|
||||
do_pending_window_change (false);
|
||||
}
|
||||
|
||||
/* Mouse warping. */
|
||||
|
||||
|
|
@ -7891,6 +7970,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
|
|||
terminal->fullscreen_hook = w32fullscreen_hook;
|
||||
terminal->iconify_frame_hook = w32_iconify_frame;
|
||||
terminal->set_window_size_hook = w32_set_window_size;
|
||||
terminal->set_window_size_and_position_hook = w32_set_window_size_and_position;
|
||||
terminal->set_frame_offset_hook = w32_set_offset;
|
||||
terminal->set_frame_alpha_hook = w32_set_frame_alpha;
|
||||
terminal->set_new_font_hook = w32_new_font;
|
||||
|
|
|
|||
54
src/xterm.c
54
src/xterm.c
|
|
@ -28563,6 +28563,59 @@ x_set_window_size (struct frame *f, bool change_gravity,
|
|||
do_pending_window_change (false);
|
||||
}
|
||||
|
||||
static void
|
||||
x_set_window_size_and_position_1 (struct frame *f, int width, int height)
|
||||
{
|
||||
int x = f->left_pos;
|
||||
int y = f->top_pos;
|
||||
|
||||
x_wm_set_size_hint (f, 0, false);
|
||||
|
||||
XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
|
||||
x, y, width, height + FRAME_MENUBAR_HEIGHT (f));
|
||||
|
||||
SET_FRAME_GARBAGED (f);
|
||||
|
||||
if (FRAME_VISIBLE_P (f))
|
||||
x_wait_for_event (f, ConfigureNotify);
|
||||
else
|
||||
/* Call adjust_frame_size right away as with GTK. It might be
|
||||
tempting to clear out f->new_width and f->new_height here. */
|
||||
adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
|
||||
FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
|
||||
5, 0, Qx_set_window_size_1);
|
||||
}
|
||||
|
||||
void
|
||||
x_set_window_size_and_position (struct frame *f, int width, int height)
|
||||
{
|
||||
block_input ();
|
||||
|
||||
#ifdef USE_GTK
|
||||
if (FRAME_GTK_WIDGET (f))
|
||||
xg_frame_set_size_and_position (f, width, height);
|
||||
else
|
||||
x_set_window_size_and_position_1 (f, width, height);
|
||||
#else /* not USE_GTK */
|
||||
x_set_window_size_and_position_1 (f, width, height);
|
||||
#endif /* USE_GTK */
|
||||
|
||||
x_clear_under_internal_border (f);
|
||||
|
||||
/* If cursor was outside the new size, mark it as off. */
|
||||
mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
|
||||
|
||||
/* Clear out any recollection of where the mouse highlighting was,
|
||||
since it might be in a place that's outside the new frame size.
|
||||
Actually checking whether it is outside is a pain in the neck,
|
||||
so don't try--just let the highlighting be done afresh with new size. */
|
||||
cancel_mouse_face (f);
|
||||
|
||||
unblock_input ();
|
||||
|
||||
do_pending_window_change (false);
|
||||
}
|
||||
|
||||
/* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
|
||||
|
||||
void
|
||||
|
|
@ -32148,6 +32201,7 @@ x_create_terminal (struct x_display_info *dpyinfo)
|
|||
terminal->fullscreen_hook = XTfullscreen_hook;
|
||||
terminal->iconify_frame_hook = x_iconify_frame;
|
||||
terminal->set_window_size_hook = x_set_window_size;
|
||||
terminal->set_window_size_and_position_hook = x_set_window_size_and_position;
|
||||
terminal->set_frame_offset_hook = x_set_offset;
|
||||
terminal->set_frame_alpha_hook = x_set_frame_alpha;
|
||||
terminal->set_new_font_hook = x_new_font;
|
||||
|
|
|
|||
|
|
@ -1766,6 +1766,7 @@ extern void x_ignore_errors_for_next_request (struct x_display_info *,
|
|||
extern void x_stop_ignoring_errors (struct x_display_info *);
|
||||
extern void x_clear_errors (Display *);
|
||||
extern void x_set_window_size (struct frame *, bool, int, int);
|
||||
extern void x_set_window_size_and_position (struct frame *, int, int);
|
||||
extern void x_set_last_user_time_from_lisp (struct x_display_info *, Time);
|
||||
extern void x_make_frame_visible (struct frame *);
|
||||
extern void x_make_frame_invisible (struct frame *);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue