changeset 72706:10536ef853fe

(mac_handle_origin_change, mac_handle_size_change) (mac_get_ideal_size): New functions. (x_set_offset, x_set_window_size, x_make_frame_visible) (do_zoom_window, mac_handle_window_event, XTread_socket): Use them. (install_window_handler, mac_handle_window_event) [USE_CARBON_EVENTS]: Handle kEventWindowGetIdealSize and kEventWindowBoundsChanged. (XTread_socket) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: Don't call DragWindow.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Fri, 08 Sep 2006 08:18:18 +0000
parents d51cd08a3471
children d7f93349a89e
files src/macterm.c
diffstat 1 files changed, 167 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/src/macterm.c	Fri Sep 08 08:18:08 2006 +0000
+++ b/src/macterm.c	Fri Sep 08 08:18:18 2006 +0000
@@ -5805,6 +5805,57 @@
 #endif /* not TARGET_API_MAC_CARBON */
 }
 
+static void
+mac_handle_origin_change (f)
+     struct frame *f;
+{
+  x_real_positions (f, &f->left_pos, &f->top_pos);
+}
+
+static void
+mac_handle_size_change (f, pixelwidth, pixelheight)
+     struct frame *f;
+     int pixelwidth, pixelheight;
+{
+  int cols, rows;
+
+  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth);
+  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight);
+
+  if (cols != FRAME_COLS (f)
+      || rows != FRAME_LINES (f)
+      || pixelwidth != FRAME_PIXEL_WIDTH (f)
+      || pixelheight != FRAME_PIXEL_HEIGHT (f))
+    {
+      /* We pass 1 for DELAY since we can't run Lisp code inside of
+	 a BLOCK_INPUT.  */
+      change_frame_size (f, rows, cols, 0, 1, 0);
+      FRAME_PIXEL_WIDTH (f) = pixelwidth;
+      FRAME_PIXEL_HEIGHT (f) = pixelheight;
+      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);
+
+#if TARGET_API_MAC_CARBON
+      if (f->output_data.mac->hourglass_control)
+	{
+#if USE_CG_DRAWING
+	  mac_prepare_for_quickdraw (f);
+#endif
+	  MoveControl (f->output_data.mac->hourglass_control,
+		       pixelwidth - HOURGLASS_WIDTH, 0);
+	}
+#endif
+    }
+}
 
 
 /* Calculate the absolute position in frame F
@@ -5885,7 +5936,10 @@
   ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
 			   kWindowConstrainMoveRegardlessOfFit
 			   | kWindowConstrainAllowPartial, NULL, NULL);
-  x_real_positions (f, &f->left_pos, &f->top_pos);
+#if USE_CARBON_EVENTS
+  if (!NILP (tip_frame) && XFRAME (tip_frame) == f)
+#endif
+    mac_handle_origin_change (f);
 #else
   {
     Rect inner, outer, screen_rect, dummy;
@@ -5959,50 +6013,11 @@
   x_wm_set_size_hint (f, (long) 0, 0);
 
   SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
-#if TARGET_API_MAC_CARBON
-  if (f->output_data.mac->hourglass_control)
-    {
-#if USE_CG_DRAWING
-      mac_prepare_for_quickdraw (f);
-#endif
-      MoveControl (f->output_data.mac->hourglass_control,
-		   pixelwidth - HOURGLASS_WIDTH, 0);
-    }
-#endif
-
-  /* Now, strictly speaking, we can't be sure that this is accurate,
-     but the window manager will get around to dealing with the size
-     change request eventually, and we'll hear how it went when the
-     ConfigureNotify event gets here.
-
-     We could just not bother storing any of this information here,
-     and let the ConfigureNotify event set everything up, but that
-     might be kind of confusing to the Lisp code, since size changes
-     wouldn't be reported in the frame parameters until some random
-     point in the future when the ConfigureNotify event arrives.
-
-     We pass 1 for DELAY since we can't run Lisp code inside of
-     a BLOCK_INPUT.  */
-  change_frame_size (f, rows, cols, 0, 1, 0);
-  FRAME_PIXEL_WIDTH (f) = pixelwidth;
-  FRAME_PIXEL_HEIGHT (f) = pixelheight;
-
-  /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
-     receive in the ConfigureNotify event; if we get what we asked
-     for, then the event won't cause the screen to become garbaged, so
-     we have to make sure to do it here.  */
-  SET_FRAME_GARBAGED (f);
-
-  XFlush (FRAME_X_DISPLAY (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);
+
+#if USE_CARBON_EVENTS
+  if (!NILP (tip_frame) && f == XFRAME (tip_frame))
+#endif
+    mac_handle_size_change (f, pixelwidth, pixelheight);
 
   UNBLOCK_INPUT;
 }
@@ -6213,7 +6228,10 @@
 				  kWindowCascadeOnParentWindowScreen
 #endif
 				  );
-	      x_real_positions (f, &f->left_pos, &f->top_pos);
+#if USE_CARBON_EVENTS
+	      if (!NILP (tip_frame) && f == XFRAME (tip_frame))
+#endif
+		mac_handle_origin_change (f);
 	    }
 	  else
 #endif
@@ -9165,6 +9183,32 @@
 }
 
 
+#if TARGET_API_MAC_CARBON
+static Point
+mac_get_ideal_size (f)
+     struct frame *f;
+{
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+  WindowPtr w = FRAME_MAC_WINDOW (f);
+  Point ideal_size;
+  Rect standard_rect;
+  int height, width, columns, rows;
+
+  ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
+  ideal_size.v = dpyinfo->height;
+  IsWindowInStandardState (w, &ideal_size, &standard_rect);
+  /* Adjust the standard size according to character boundaries.  */
+  width = standard_rect.right - standard_rect.left;
+  height = standard_rect.bottom - standard_rect.top;
+  columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
+  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
+  ideal_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
+  ideal_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+
+  return ideal_size;
+}
+#endif
+
 /* Handle clicks in zoom box.  Calculation of "standard state" based
    on code in IM - Window Manager A and code contributed by Ben
    Mesander.  The standard state of an Emacs window is 80-characters
@@ -9174,39 +9218,28 @@
 do_zoom_window (WindowPtr w, int zoom_in_or_out)
 {
   Rect zoom_rect, port_rect;
-  int columns, rows, width, height;
+  int width, height;
   struct frame *f = mac_window_to_frame (w);
-  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
 #if TARGET_API_MAC_CARBON
-  Point standard_size;
-
-  standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
-  standard_size.v = dpyinfo->height;
-
-  if (IsWindowInStandardState (w, &standard_size, &zoom_rect))
+  Point ideal_size = mac_get_ideal_size (f);
+
+  GetWindowBounds (w, kWindowContentRgn, &port_rect);
+  if (IsWindowInStandardState (w, &ideal_size, &zoom_rect)
+      && port_rect.left == zoom_rect.left
+      && port_rect.top == zoom_rect.top)
     zoom_in_or_out = inZoomIn;
   else
-    {
-      /* Adjust the standard size according to character boundaries.  */
-
-      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, zoom_rect.right - zoom_rect.left);
-      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, zoom_rect.bottom - zoom_rect.top);
-      standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, columns);
-      standard_size.v = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
-      GetWindowBounds (w, kWindowContentRgn, &port_rect);
-      if (IsWindowInStandardState (w, &standard_size, &zoom_rect)
-	  && port_rect.left == zoom_rect.left
-	  && port_rect.top == zoom_rect.top)
-	zoom_in_or_out = inZoomIn;
-      else
-	zoom_in_or_out = inZoomOut;
-    }
-
-  ZoomWindowIdeal (w, zoom_in_or_out, &standard_size);
+    zoom_in_or_out = inZoomOut;
+
+#ifdef MAC_OS8
+  mac_clear_window (f);
+#endif
+  ZoomWindowIdeal (w, zoom_in_or_out, &ideal_size);
 #else /* not TARGET_API_MAC_CARBON */
   GrafPtr save_port;
   Point top_left;
-  int w_title_height;
+  int w_title_height, rows;
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
 
   GetPort (&save_port);
 
@@ -9245,6 +9278,7 @@
   SetPort (save_port);
 #endif /* not TARGET_API_MAC_CARBON */
 
+#if !USE_CARBON_EVENTS
   /* retrieve window size and update application values */
 #if TARGET_API_MAC_CARBON
   GetWindowPortBounds (w, &port_rect);
@@ -9254,20 +9288,9 @@
   height = port_rect.bottom - port_rect.top;
   width = port_rect.right - port_rect.left;
 
-  if (width != FRAME_PIXEL_WIDTH (f)
-      || height != FRAME_PIXEL_HEIGHT (f))
-    {
-      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
-      columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
-
-      change_frame_size (f, rows, columns, 0, 1, 0);
-      SET_FRAME_GARBAGED (f);
-      cancel_mouse_face (f);
-
-      FRAME_PIXEL_WIDTH (f) = width;
-      FRAME_PIXEL_HEIGHT (f) = height;
-    }
-  x_real_positions (f, &f->left_pos, &f->top_pos);
+  mac_handle_size_change (f, width, height);
+  mac_handle_origin_change (f);
+#endif
 }
 
 void
@@ -9406,6 +9429,7 @@
 {
   WindowPtr wp;
   OSStatus result, err;
+  struct frame *f;
   UInt32 attributes;
   XSizeHints *size_hints;
 
@@ -9414,6 +9438,7 @@
   if (err != noErr)
     return eventNotHandledErr;
 
+  f = mac_window_to_frame (wp);
   switch (GetEventKind (event))
     {
     case kEventWindowUpdate:
@@ -9424,6 +9449,21 @@
       do_window_update (wp);
       return noErr;
 
+    case kEventWindowGetIdealSize:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+	return result;
+
+      {
+	Point ideal_size = mac_get_ideal_size (f);
+
+	err = SetEventParameter (event, kEventParamDimensions,
+				 typeQDPoint, sizeof (Point), &ideal_size);
+	if (err == noErr)
+	  return noErr;
+      }
+      break;
+
     case kEventWindowBoundsChanging:
       result = CallNextEventHandler (next_handler, event);
       if (result != eventNotHandledErr)
@@ -9434,7 +9474,7 @@
       if (err != noErr)
 	break;
 
-      size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp));
+      size_hints = FRAME_SIZE_HINTS (f);
       if ((attributes & kWindowBoundsChangeUserResize)
 	  && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
 	      == (PResizeInc | PBaseSize | PMinSize)))
@@ -9475,24 +9515,53 @@
 	}
       break;
 
+    case kEventWindowBoundsChanged:
+      err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
+			       NULL, sizeof (UInt32), NULL, &attributes);
+      if (err != noErr)
+	break;
+
+      if (attributes & kWindowBoundsChangeSizeChanged)
+	{
+	  Rect bounds;
+
+	  err = GetEventParameter (event, kEventParamCurrentBounds,
+				   typeQDRectangle, NULL, sizeof (Rect),
+				   NULL, &bounds);
+	  if (err == noErr)
+	    {
+	      int width, height;
+
+	      width = bounds.right - bounds.left;
+	      height = bounds.bottom - bounds.top;
+	      mac_handle_size_change (f, width, height);
+	    }
+	}
+
+      if (attributes & kWindowBoundsChangeOriginChanged)
+	mac_handle_origin_change (f);
+
+      return noErr;
+
     case kEventWindowShown:
     case kEventWindowHidden:
     case kEventWindowExpanded:
     case kEventWindowCollapsed:
       result = CallNextEventHandler (next_handler, event);
 
-      mac_handle_visibility_change (mac_window_to_frame (wp));
+      mac_handle_visibility_change (f);
       return noErr;
 
       break;
 
     case kEventWindowClose:
+      result = CallNextEventHandler (next_handler, event);
       {
 	struct input_event buf;
 
 	EVENT_INIT (buf);
 	buf.kind = DELETE_WINDOW_EVENT;
-	XSETFRAME (buf.frame_or_window, mac_window_to_frame (wp));
+	XSETFRAME (buf.frame_or_window, f);
 	buf.arg = Qnil;
 	kbd_buffer_store_event (&buf);
       }
@@ -9908,7 +9977,9 @@
 #if USE_CARBON_EVENTS
   EventTypeSpec specs_window[] =
     {{kEventClassWindow, kEventWindowUpdate},
+     {kEventClassWindow, kEventWindowGetIdealSize},
      {kEventClassWindow, kEventWindowBoundsChanging},
+     {kEventClassWindow, kEventWindowBoundsChanged},
      {kEventClassWindow, kEventWindowShown},
      {kEventClassWindow, kEventWindowHidden},
      {kEventClassWindow, kEventWindowExpanded},
@@ -10467,17 +10538,23 @@
 		    && (TrackWindowProxyDrag (window_ptr, er.where)
 			!= errUserWantsToDragWindow))
 		  break;
+		/* kWindowAsyncDragAttribute is specified on Mac OS X
+		   10.3 and later.*/
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
 		DragWindow (window_ptr, er.where, NULL);
+#endif
 #else /* not TARGET_API_MAC_CARBON */
 		DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
 #endif /* not TARGET_API_MAC_CARBON */
 		/* Update the frame parameters.  */
+#if !USE_CARBON_EVENTS
 		{
 		  struct frame *f = mac_window_to_frame (window_ptr);
 
 		  if (f && !f->async_iconified)
-		    x_real_positions (f, &f->left_pos, &f->top_pos);
+		    mac_handle_origin_change (f);
 		}
+#endif
 		break;
 
 	      case inGoAway: