Add ns_set_window_size_and_position

* src/frame.c (Fset_frame_size_and_position_pixelwise): Correct
docstring typo.
* src/nsterm.m (compute_offset): New function of common code.
(ns_set_offset): Call compute_offset.
(ns_set_window_size_and_position): New function.
(ns_create_terminal): Add new function to the hook.
This commit is contained in:
Stéphane Marks 2025-12-24 16:32:04 +01:00 committed by Martin Rudalics
parent b3aa0a652c
commit d576216adb
2 changed files with 66 additions and 16 deletions

View file

@ -4561,7 +4561,7 @@ 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
not specify 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.

View file

@ -1677,27 +1677,17 @@ Hide the window (X11 semantics)
ns_window_num--;
}
void
ns_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
/* --------------------------------------------------------------------------
External: Position the window
-------------------------------------------------------------------------- */
static NSPoint
compute_offset (struct frame *f, NSView *view, int xoff, int yoff)
{
NSView *view = FRAME_NS_VIEW (f);
NSRect windowFrame = [[view window] frame];
NSPoint topLeft;
NSTRACE ("ns_set_offset");
block_input ();
/* If there is no parent frame then just convert to screen
coordinates, UNLESS we have negative values, in which case I
think it's best to position from the bottom and right of the
current screen rather than the main screen or whole display. */
NSRect parentRect = ns_parent_window_rect (f);
NSRect windowFrame = [[view window] frame];
NSPoint topLeft;
if (f->size_hint_flags & XNegative)
topLeft.x = NSMaxX (parentRect) - NSWidth (windowFrame) + xoff;
@ -1722,6 +1712,25 @@ Hide the window (X11 semantics)
topLeft.x = 100;
#endif
return topLeft;
}
void
ns_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
/* --------------------------------------------------------------------------
External: Position the window
-------------------------------------------------------------------------- */
{
NSView *view = FRAME_NS_VIEW (f);
NSTRACE ("ns_set_offset");
if (view == nil)
return;
block_input ();
NSPoint topLeft = compute_offset (f, view, xoff, yoff);
NSTRACE_POINT ("setFrameTopLeftPoint", topLeft);
[[view window] setFrameTopLeftPoint:topLeft];
f->size_hint_flags &= ~(XNegative|YNegative);
@ -1729,7 +1738,6 @@ Hide the window (X11 semantics)
unblock_input ();
}
static void
ns_set_window_size (struct frame *f, bool change_gravity,
int width, int height)
@ -1773,6 +1781,47 @@ Hide the window (X11 semantics)
unblock_input ();
}
static void
ns_set_window_size_and_position (struct frame *f,
int width, int height)
/* --------------------------------------------------------------------------
Adjust window pixelwise size and position in one operation.
-------------------------------------------------------------------------- */
{
EmacsView *view = FRAME_NS_VIEW (f);
NSWindow *window = [view window];
NSTRACE ("ns_set_window_size_and_position");
if (view == nil)
return;
block_input ();
/* Both window frame origin, and the rect that setFrame accepts are
anchored to the bottom-left corner of the window. */
NSPoint topLeft = compute_offset (f, view, f->left_pos, f->top_pos);
NSPoint bottomLeft = NSMakePoint(topLeft.x,
/* text-area pixels + decorations. */
topLeft.y - (height
+ FRAME_NS_TITLEBAR_HEIGHT(f)
+ FRAME_TOOLBAR_HEIGHT(f)));
NSRect frameRect = [window frameRectForContentRect:NSMakeRect (bottomLeft.x,
bottomLeft.y,
width,
height)];
if (f->output_data.ns->zooming)
f->output_data.ns->zooming = 0;
/* Usually it seems safe to delay changing the frame size, but when a
series of actions are taken with no redisplay between them then we
can end up using old values so don't delay here. */
change_frame_size (f, width, height, false, NO, false);
[window setFrame:frameRect display:NO];
f->size_hint_flags &= ~(XNegative|YNegative);
unblock_input ();
}
void
ns_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
/* --------------------------------------------------------------------------
@ -5721,6 +5770,7 @@ static Lisp_Object ns_new_font (struct frame *f, Lisp_Object font_object,
terminal->fullscreen_hook = ns_fullscreen_hook;
terminal->iconify_frame_hook = ns_iconify_frame;
terminal->set_window_size_hook = ns_set_window_size;
terminal->set_window_size_and_position_hook = ns_set_window_size_and_position;
terminal->set_frame_offset_hook = ns_set_offset;
terminal->set_frame_alpha_hook = ns_set_frame_alpha;
terminal->set_new_font_hook = ns_new_font;