[Top][All Lists]
[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: