emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Carbon: window close via accessibility API is broken


From: YAMAMOTO Mitsuharu
Subject: Re: Carbon: window close via accessibility API is broken
Date: Wed, 06 Sep 2006 09:50:29 +0900
User-agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/22.0.50 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI)

>>>>> On Tue, 05 Sep 2006 09:37:15 +0900, YAMAMOTO Mitsuharu <address@hidden> 
>>>>> said:

> It can be handled with Carbon events in kEventClassWindow.
> kEventWindowClose for the Close button.  kEventWindowGetIdealSize
> and kEventWindowBoundsChanged for the Maximize button.  The former
> is easy to handle and I'll install a handler.  But the latter is not
> so straightforward and it may conflict with the existing code
> because kEventWindowBoundsChanged is called in various situations.

Here's a patch for the zoom button (sorry, it was not the Maximize
button).

                                     YAMAMOTO Mitsuharu
                                address@hidden

*** macterm.c.~1.187.~  Tue Sep  5 10:04:06 2006
--- macterm.c   Wed Sep  6 09:47:34 2006
***************
*** 5805,5810 ****
--- 5805,5861 ----
  #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,5891 ****
    ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
                           kWindowConstrainMoveRegardlessOfFit
                           | kWindowConstrainAllowPartial, NULL, NULL);
!   x_real_positions (f, &f->left_pos, &f->top_pos);
  #else
    {
      Rect inner, outer, screen_rect, dummy;
--- 5936,5945 ----
    ConstrainWindowToScreen (FRAME_MAC_WINDOW (f), kWindowTitleBarRgn,
                           kWindowConstrainMoveRegardlessOfFit
                           | kWindowConstrainAllowPartial, NULL, NULL);
! #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,6008 ****
    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);
  
    UNBLOCK_INPUT;
  }
--- 6013,6023 ----
    x_wm_set_size_hint (f, (long) 0, 0);
  
    SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
  
! #if USE_CARBON_EVENTS
!   if (!NILP (tip_frame) && f == XFRAME (tip_frame))
! #endif
!     mac_handle_size_change (f, pixelwidth, pixelheight);
  
    UNBLOCK_INPUT;
  }
***************
*** 6213,6219 ****
                                  kWindowCascadeOnParentWindowScreen
  #endif
                                  );
!             x_real_positions (f, &f->left_pos, &f->top_pos);
            }
          else
  #endif
--- 6228,6237 ----
                                  kWindowCascadeOnParentWindowScreen
  #endif
                                  );
! #if USE_CARBON_EVENTS
!             if (!NILP (tip_frame) && f == XFRAME (tip_frame))
! #endif
!               mac_handle_origin_change (f);
            }
          else
  #endif
***************
*** 9165,9170 ****
--- 9183,9214 ----
  }
  
  
+ #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,9212 ****
  do_zoom_window (WindowPtr w, int zoom_in_or_out)
  {
    Rect zoom_rect, port_rect;
!   int columns, rows, 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))
      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);
  #else /* not TARGET_API_MAC_CARBON */
    GrafPtr save_port;
    Point top_left;
!   int w_title_height;
  
    GetPort (&save_port);
  
--- 9218,9245 ----
  do_zoom_window (WindowPtr w, int zoom_in_or_out)
  {
    Rect zoom_rect, port_rect;
!   int width, height;
    struct frame *f = mac_window_to_frame (w);
  #if TARGET_API_MAC_CARBON
!   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
!     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, rows;
!   struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
  
    GetPort (&save_port);
  
***************
*** 9245,9250 ****
--- 9278,9284 ----
    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,9273 ****
    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);
  }
  
  void
--- 9288,9296 ----
    height = port_rect.bottom - port_rect.top;
    width = port_rect.right - port_rect.left;
  
!   mac_handle_size_change (f, width, height);
!   mac_handle_origin_change (f);
! #endif
  }
  
  void
***************
*** 9406,9411 ****
--- 9429,9435 ----
  {
    WindowPtr wp;
    OSStatus result, err;
+   struct frame *f;
    UInt32 attributes;
    XSizeHints *size_hints;
  
***************
*** 9414,9419 ****
--- 9438,9444 ----
    if (err != noErr)
      return eventNotHandledErr;
  
+   f = mac_window_to_frame (wp);
    switch (GetEventKind (event))
      {
      case kEventWindowUpdate:
***************
*** 9424,9429 ****
--- 9449,9469 ----
        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,9440 ****
        if (err != noErr)
        break;
  
!       size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp));
        if ((attributes & kWindowBoundsChangeUserResize)
          && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
              == (PResizeInc | PBaseSize | PMinSize)))
--- 9474,9480 ----
        if (err != noErr)
        break;
  
!       size_hints = FRAME_SIZE_HINTS (f);
        if ((attributes & kWindowBoundsChangeUserResize)
          && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize))
              == (PResizeInc | PBaseSize | PMinSize)))
***************
*** 9475,9487 ****
        }
        break;
  
      case kEventWindowShown:
      case kEventWindowHidden:
      case kEventWindowExpanded:
      case kEventWindowCollapsed:
        result = CallNextEventHandler (next_handler, event);
  
!       mac_handle_visibility_change (mac_window_to_frame (wp));
        return noErr;
  
        break;
--- 9515,9555 ----
        }
        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 (f);
        return noErr;
  
        break;
***************
*** 9492,9498 ****
  
        EVENT_INIT (buf);
        buf.kind = DELETE_WINDOW_EVENT;
!       XSETFRAME (buf.frame_or_window, mac_window_to_frame (wp));
        buf.arg = Qnil;
        kbd_buffer_store_event (&buf);
        }
--- 9560,9566 ----
  
        EVENT_INIT (buf);
        buf.kind = DELETE_WINDOW_EVENT;
!       XSETFRAME (buf.frame_or_window, f);
        buf.arg = Qnil;
        kbd_buffer_store_event (&buf);
        }
***************
*** 9908,9914 ****
--- 9976,9984 ----
  #if USE_CARBON_EVENTS
    EventTypeSpec specs_window[] =
      {{kEventClassWindow, kEventWindowUpdate},
+      {kEventClassWindow, kEventWindowGetIdealSize},
       {kEventClassWindow, kEventWindowBoundsChanging},
+      {kEventClassWindow, kEventWindowBoundsChanged},
       {kEventClassWindow, kEventWindowShown},
       {kEventClassWindow, kEventWindowHidden},
       {kEventClassWindow, kEventWindowExpanded},
***************
*** 10472,10483 ****
                DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
  #endif /* not TARGET_API_MAC_CARBON */
                /* Update the frame parameters.  */
                {
                  struct frame *f = mac_window_to_frame (window_ptr);
  
                  if (f && !f->async_iconified)
!                   x_real_positions (f, &f->left_pos, &f->top_pos);
                }
                break;
  
              case inGoAway:
--- 10542,10555 ----
                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)
!                   mac_handle_origin_change (f);
                }
+ #endif
                break;
  
              case inGoAway:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]