Subject: bug#79164: [PATCH] Fix macOS frame position update after resize/move in nsterm.m

From: 川本 琢二 (Dr.Sc.KAWAMOTO,Takuji) <[email-masked]>
Date: Sun, 3 Aug 2025 15:45:25 +0900

Hello,

This patch addresses a bug in the macOS build of Emacs, where frame
position was not correctly updated after resizing from the left edge.

In particular, it fixes the issue reported in bug#74074, where
the move-frame-functions hook does not reliably reflect the final
frame location after resizing. This patch introduces the
updateFramePosition method, which is called from windowDidMove
and windowDidEndLiveResize to ensure the frame geometry stays
in sync with the actual macOS window position.

Tested on macOS 15.5.

Best regards,
Dr.Sc.KAWAMOTO, Takuji

---
  src/nsterm.m | 63 ++++++++++++++++++++++++++++++----------------------
  1 file changed, 37 insertions(+), 26 deletions(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index 003aadb9782..3db002d9678 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6736,6 +6736,11 @@ - (BOOL)fulfillService: (NSString *)name withArg: 
(NSString *)arg

  @implementation EmacsView

+- (void)windowDidEndLiveResize:(NSNotification *)notification
+{
+  [self updateFramePosition];
+}
+
  /* Needed to inform when window closed from lisp.  */
  - (void) setWindowClosing: (BOOL)closing
  {
@@ -7871,6 +7876,37 @@ - (BOOL)windowShouldClose: (id)sender
  }

+- (void)updateFramePosition
+{
+  NSWindow *win = [self window];
+  NSRect r = [win frame];
+  NSArray *screens = [NSScreen screens];
+  NSScreen *screen = [screens objectAtIndex: 0];
+
+  if (!emacsframe->output_data.ns)
+    return;
+
+  if (screen != nil)
+    {
+      emacsframe->left_pos = (NSMinX (r)
+                              - NS_PARENT_WINDOW_LEFT_POS (emacsframe));
+      emacsframe->top_pos = (NS_PARENT_WINDOW_TOP_POS (emacsframe)
+                             - NSMaxY (r));
+
+      if (emacs_event)
+        {
+          struct input_event ie;
+          EVENT_INIT (ie);
+          ie.kind = MOVE_FRAME_EVENT;
+          XSETFRAME (ie.frame_or_window, emacsframe);
+          XSETINT (ie.x, emacsframe->left_pos);
+          XSETINT (ie.y, emacsframe->top_pos);
+          kbd_buffer_store_event (&ie);
+        }
+    }
+}
+
+
  - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize
  /* Normalize frame to gridded text size.  */
  {
@@ -8205,34 +8241,9 @@ - (instancetype) initFrameFromEmacs: (struct 
frame *)f

  - (void)windowDidMove: sender
  {
-  NSWindow *win = [self window];
-  NSRect r = [win frame];
-  NSArray *screens = [NSScreen screens];
-  NSScreen *screen = [screens objectAtIndex: 0];
-
    NSTRACE ("[EmacsView windowDidMove:]");

-  if (!emacsframe->output_data.ns)
-    return;
-
-  if (screen != nil)
-    {
-      emacsframe->left_pos = (NSMinX (r)
-                  - NS_PARENT_WINDOW_LEFT_POS (emacsframe));
-      emacsframe->top_pos = (NS_PARENT_WINDOW_TOP_POS (emacsframe)
-                 - NSMaxY (r));
-
-      if (emacs_event)
-    {
-      struct input_event ie;
-      EVENT_INIT (ie);
-      ie.kind = MOVE_FRAME_EVENT;
-      XSETFRAME (ie.frame_or_window, emacsframe);
-      XSETINT (ie.x, emacsframe->left_pos);
-      XSETINT (ie.y, emacsframe->top_pos);
-      kbd_buffer_store_event (&ie);
-    }
-    }
+  [self updateFramePosition];
  }

-- 
2.49.0