diff options
Diffstat (limited to 'src/macterm.c')
| -rw-r--r-- | src/macterm.c | 209 |
1 files changed, 155 insertions, 54 deletions
diff --git a/src/macterm.c b/src/macterm.c index 5b7d3ee2262..099b69bfb09 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* Implementation of GUI terminal on the Mac OS. | 1 | /* Implementation of GUI terminal on the Mac OS. |
| 2 | Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | 2 | Copyright (C) 2000, 2001, 2002, 2003, 2004, |
| 3 | 2005 Free Software Foundation, Inc. | ||
| 3 | 4 | ||
| 4 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 5 | 6 | ||
| @@ -797,6 +798,8 @@ mac_copy_area (display, src, dest, gc, src_x, src_y, width, height, dest_x, | |||
| 797 | &src_r, &dest_r, srcCopy, 0); | 798 | &src_r, &dest_r, srcCopy, 0); |
| 798 | #endif /* not TARGET_API_MAC_CARBON */ | 799 | #endif /* not TARGET_API_MAC_CARBON */ |
| 799 | UnlockPixels (GetGWorldPixMap (src)); | 800 | UnlockPixels (GetGWorldPixMap (src)); |
| 801 | |||
| 802 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest))); | ||
| 800 | } | 803 | } |
| 801 | 804 | ||
| 802 | 805 | ||
| @@ -835,6 +838,8 @@ mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y, | |||
| 835 | #endif /* not TARGET_API_MAC_CARBON */ | 838 | #endif /* not TARGET_API_MAC_CARBON */ |
| 836 | UnlockPixels (GetGWorldPixMap (mask)); | 839 | UnlockPixels (GetGWorldPixMap (mask)); |
| 837 | UnlockPixels (GetGWorldPixMap (src)); | 840 | UnlockPixels (GetGWorldPixMap (src)); |
| 841 | |||
| 842 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest))); | ||
| 838 | } | 843 | } |
| 839 | 844 | ||
| 840 | 845 | ||
| @@ -5661,6 +5666,53 @@ XTframe_raise_lower (f, raise_flag) | |||
| 5661 | 5666 | ||
| 5662 | /* Change of visibility. */ | 5667 | /* Change of visibility. */ |
| 5663 | 5668 | ||
| 5669 | static void | ||
| 5670 | mac_handle_visibility_change (f) | ||
| 5671 | struct frame *f; | ||
| 5672 | { | ||
| 5673 | WindowPtr wp = FRAME_MAC_WINDOW (f); | ||
| 5674 | int visible = 0, iconified = 0; | ||
| 5675 | struct input_event buf; | ||
| 5676 | |||
| 5677 | if (IsWindowVisible (wp)) | ||
| 5678 | if (IsWindowCollapsed (wp)) | ||
| 5679 | iconified = 1; | ||
| 5680 | else | ||
| 5681 | visible = 1; | ||
| 5682 | |||
| 5683 | if (!f->async_visible && visible) | ||
| 5684 | { | ||
| 5685 | if (f->iconified) | ||
| 5686 | { | ||
| 5687 | /* wait_reading_process_output will notice this and update | ||
| 5688 | the frame's display structures. If we were made | ||
| 5689 | invisible, we should not set garbaged, because that stops | ||
| 5690 | redrawing on Update events. */ | ||
| 5691 | SET_FRAME_GARBAGED (f); | ||
| 5692 | |||
| 5693 | EVENT_INIT (buf); | ||
| 5694 | buf.kind = DEICONIFY_EVENT; | ||
| 5695 | XSETFRAME (buf.frame_or_window, f); | ||
| 5696 | kbd_buffer_store_event (&buf); | ||
| 5697 | } | ||
| 5698 | else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list))) | ||
| 5699 | /* Force a redisplay sooner or later to update the | ||
| 5700 | frame titles in case this is the second frame. */ | ||
| 5701 | record_asynch_buffer_change (); | ||
| 5702 | } | ||
| 5703 | else if (f->async_visible && !visible) | ||
| 5704 | if (iconified) | ||
| 5705 | { | ||
| 5706 | EVENT_INIT (buf); | ||
| 5707 | buf.kind = ICONIFY_EVENT; | ||
| 5708 | XSETFRAME (buf.frame_or_window, f); | ||
| 5709 | kbd_buffer_store_event (&buf); | ||
| 5710 | } | ||
| 5711 | |||
| 5712 | f->async_visible = visible; | ||
| 5713 | f->async_iconified = iconified; | ||
| 5714 | } | ||
| 5715 | |||
| 5664 | /* This tries to wait until the frame is really visible. | 5716 | /* This tries to wait until the frame is really visible. |
| 5665 | However, if the window manager asks the user where to position | 5717 | However, if the window manager asks the user where to position |
| 5666 | the frame, this will return before the user finishes doing that. | 5718 | the frame, this will return before the user finishes doing that. |
| @@ -5685,29 +5737,32 @@ x_make_frame_visible (f) | |||
| 5685 | before the window gets really visible. */ | 5737 | before the window gets really visible. */ |
| 5686 | if (! FRAME_ICONIFIED_P (f) | 5738 | if (! FRAME_ICONIFIED_P (f) |
| 5687 | && ! f->output_data.mac->asked_for_visible) | 5739 | && ! f->output_data.mac->asked_for_visible) |
| 5688 | x_set_offset (f, f->left_pos, f->top_pos, 0); | ||
| 5689 | |||
| 5690 | f->output_data.mac->asked_for_visible = 1; | ||
| 5691 | |||
| 5692 | #if TARGET_API_MAC_CARBON | 5740 | #if TARGET_API_MAC_CARBON |
| 5693 | if (!(FRAME_SIZE_HINTS (f)->flags & (USPosition | PPosition))) | 5741 | if (!(FRAME_SIZE_HINTS (f)->flags & (USPosition | PPosition))) |
| 5694 | { | 5742 | { |
| 5695 | struct frame *sf = SELECTED_FRAME (); | 5743 | struct frame *sf = SELECTED_FRAME (); |
| 5696 | if (!FRAME_MAC_P (sf)) | 5744 | if (!FRAME_MAC_P (sf)) |
| 5697 | RepositionWindow (FRAME_MAC_WINDOW (f), NULL, | 5745 | RepositionWindow (FRAME_MAC_WINDOW (f), NULL, |
| 5698 | kWindowCenterOnMainScreen); | 5746 | kWindowCenterOnMainScreen); |
| 5699 | else | 5747 | else |
| 5700 | RepositionWindow (FRAME_MAC_WINDOW (f), | 5748 | RepositionWindow (FRAME_MAC_WINDOW (f), |
| 5701 | FRAME_MAC_WINDOW (sf), | 5749 | FRAME_MAC_WINDOW (sf), |
| 5702 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 | 5750 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 |
| 5703 | kWindowCascadeStartAtParentWindowScreen | 5751 | kWindowCascadeStartAtParentWindowScreen |
| 5704 | #else | 5752 | #else |
| 5705 | kWindowCascadeOnParentWindowScreen | 5753 | kWindowCascadeOnParentWindowScreen |
| 5706 | #endif | 5754 | #endif |
| 5707 | ); | 5755 | ); |
| 5708 | x_real_positions (f, &f->left_pos, &f->top_pos); | 5756 | x_real_positions (f, &f->left_pos, &f->top_pos); |
| 5709 | } | 5757 | } |
| 5758 | else | ||
| 5710 | #endif | 5759 | #endif |
| 5760 | x_set_offset (f, f->left_pos, f->top_pos, 0); | ||
| 5761 | |||
| 5762 | f->output_data.mac->asked_for_visible = 1; | ||
| 5763 | |||
| 5764 | SelectWindow (FRAME_MAC_WINDOW (f)); | ||
| 5765 | CollapseWindow (FRAME_MAC_WINDOW (f), false); | ||
| 5711 | ShowWindow (FRAME_MAC_WINDOW (f)); | 5766 | ShowWindow (FRAME_MAC_WINDOW (f)); |
| 5712 | } | 5767 | } |
| 5713 | 5768 | ||
| @@ -5766,9 +5821,14 @@ void | |||
| 5766 | x_make_frame_invisible (f) | 5821 | x_make_frame_invisible (f) |
| 5767 | struct frame *f; | 5822 | struct frame *f; |
| 5768 | { | 5823 | { |
| 5824 | /* A deactivate event does not occur when the last visible frame is | ||
| 5825 | made invisible. So if we clear the highlight here, it will not | ||
| 5826 | be rehighlighted when it is made visible. */ | ||
| 5827 | #if 0 | ||
| 5769 | /* Don't keep the highlight on an invisible frame. */ | 5828 | /* Don't keep the highlight on an invisible frame. */ |
| 5770 | if (FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame == f) | 5829 | if (FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame == f) |
| 5771 | FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame = 0; | 5830 | FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame = 0; |
| 5831 | #endif | ||
| 5772 | 5832 | ||
| 5773 | BLOCK_INPUT; | 5833 | BLOCK_INPUT; |
| 5774 | 5834 | ||
| @@ -5781,17 +5841,11 @@ x_make_frame_invisible (f) | |||
| 5781 | 5841 | ||
| 5782 | HideWindow (FRAME_MAC_WINDOW (f)); | 5842 | HideWindow (FRAME_MAC_WINDOW (f)); |
| 5783 | 5843 | ||
| 5784 | /* We can't distinguish this from iconification | ||
| 5785 | just by the event that we get from the server. | ||
| 5786 | So we can't win using the usual strategy of letting | ||
| 5787 | FRAME_SAMPLE_VISIBILITY set this. So do it by hand, | ||
| 5788 | and synchronize with the server to make sure we agree. */ | ||
| 5789 | f->visible = 0; | ||
| 5790 | FRAME_ICONIFIED_P (f) = 0; | ||
| 5791 | f->async_visible = 0; | ||
| 5792 | f->async_iconified = 0; | ||
| 5793 | |||
| 5794 | UNBLOCK_INPUT; | 5844 | UNBLOCK_INPUT; |
| 5845 | |||
| 5846 | #if !USE_CARBON_EVENTS | ||
| 5847 | mac_handle_visibility_change (f); | ||
| 5848 | #endif | ||
| 5795 | } | 5849 | } |
| 5796 | 5850 | ||
| 5797 | /* Change window state from mapped to iconified. */ | 5851 | /* Change window state from mapped to iconified. */ |
| @@ -5800,21 +5854,37 @@ void | |||
| 5800 | x_iconify_frame (f) | 5854 | x_iconify_frame (f) |
| 5801 | struct frame *f; | 5855 | struct frame *f; |
| 5802 | { | 5856 | { |
| 5857 | OSErr err; | ||
| 5858 | |||
| 5859 | /* A deactivate event does not occur when the last visible frame is | ||
| 5860 | iconified. So if we clear the highlight here, it will not be | ||
| 5861 | rehighlighted when it is deiconified. */ | ||
| 5862 | #if 0 | ||
| 5803 | /* Don't keep the highlight on an invisible frame. */ | 5863 | /* Don't keep the highlight on an invisible frame. */ |
| 5804 | if (FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame == f) | 5864 | if (FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame == f) |
| 5805 | FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame = 0; | 5865 | FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame = 0; |
| 5866 | #endif | ||
| 5806 | 5867 | ||
| 5807 | #if 0 | ||
| 5808 | /* Review: Since window is still visible in dock, still allow updates? */ | ||
| 5809 | if (f->async_iconified) | 5868 | if (f->async_iconified) |
| 5810 | return; | 5869 | return; |
| 5811 | #endif | ||
| 5812 | 5870 | ||
| 5813 | BLOCK_INPUT; | 5871 | BLOCK_INPUT; |
| 5814 | 5872 | ||
| 5815 | CollapseWindow (FRAME_MAC_WINDOW (f), true); | 5873 | FRAME_SAMPLE_VISIBILITY (f); |
| 5874 | |||
| 5875 | if (! FRAME_VISIBLE_P (f)) | ||
| 5876 | ShowWindow (FRAME_MAC_WINDOW (f)); | ||
| 5877 | |||
| 5878 | err = CollapseWindow (FRAME_MAC_WINDOW (f), true); | ||
| 5816 | 5879 | ||
| 5817 | UNBLOCK_INPUT; | 5880 | UNBLOCK_INPUT; |
| 5881 | |||
| 5882 | if (err != noErr) | ||
| 5883 | error ("Can't notify window manager of iconification"); | ||
| 5884 | |||
| 5885 | #if !USE_CARBON_EVENTS | ||
| 5886 | mac_handle_visibility_change (f); | ||
| 5887 | #endif | ||
| 5818 | } | 5888 | } |
| 5819 | 5889 | ||
| 5820 | 5890 | ||
| @@ -7212,7 +7282,7 @@ x_load_font (f, fontname, size) | |||
| 7212 | 7282 | ||
| 7213 | /* Set global flag fonts_changed_p to non-zero if the font loaded | 7283 | /* Set global flag fonts_changed_p to non-zero if the font loaded |
| 7214 | has a character with a smaller width than any other character | 7284 | has a character with a smaller width than any other character |
| 7215 | before, or if the font loaded has a smalle>r height than any | 7285 | before, or if the font loaded has a smaller height than any |
| 7216 | other font loaded before. If this happens, it will make a | 7286 | other font loaded before. If this happens, it will make a |
| 7217 | glyph matrix reallocation necessary. */ | 7287 | glyph matrix reallocation necessary. */ |
| 7218 | fonts_changed_p |= x_compute_min_glyph_bounds (f); | 7288 | fonts_changed_p |= x_compute_min_glyph_bounds (f); |
| @@ -7343,12 +7413,12 @@ Lisp_Object Vmac_pass_command_to_system; | |||
| 7343 | /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox | 7413 | /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox |
| 7344 | for processing before Emacs sees it. */ | 7414 | for processing before Emacs sees it. */ |
| 7345 | Lisp_Object Vmac_pass_control_to_system; | 7415 | Lisp_Object Vmac_pass_control_to_system; |
| 7416 | #endif | ||
| 7346 | 7417 | ||
| 7347 | /* Points to the variable `inev' in the function XTread_socket. It is | 7418 | /* Points to the variable `inev' in the function XTread_socket. It is |
| 7348 | used for passing an input event to the function back from | 7419 | used for passing an input event to the function back from |
| 7349 | Carbon/Apple event handlers. */ | 7420 | Carbon/Apple event handlers. */ |
| 7350 | static struct input_event *read_socket_inev = NULL; | 7421 | static struct input_event *read_socket_inev = NULL; |
| 7351 | #endif | ||
| 7352 | 7422 | ||
| 7353 | /* Set in term/mac-win.el to indicate that event loop can now generate | 7423 | /* Set in term/mac-win.el to indicate that event loop can now generate |
| 7354 | drag and drop events. */ | 7424 | drag and drop events. */ |
| @@ -7633,37 +7703,30 @@ do_window_update (WindowPtr win) | |||
| 7633 | { | 7703 | { |
| 7634 | if (f->async_visible == 0) | 7704 | if (f->async_visible == 0) |
| 7635 | { | 7705 | { |
| 7706 | /* Update events may occur when a frame gets iconified. */ | ||
| 7707 | #if 0 | ||
| 7636 | f->async_visible = 1; | 7708 | f->async_visible = 1; |
| 7637 | f->async_iconified = 0; | 7709 | f->async_iconified = 0; |
| 7638 | SET_FRAME_GARBAGED (f); | 7710 | SET_FRAME_GARBAGED (f); |
| 7639 | 7711 | #endif | |
| 7640 | /* An update event is equivalent to MapNotify on X, so report | ||
| 7641 | visibility changes properly. */ | ||
| 7642 | if (! NILP(Vframe_list) && ! NILP (XCDR (Vframe_list))) | ||
| 7643 | /* Force a redisplay sooner or later to update the | ||
| 7644 | frame titles in case this is the second frame. */ | ||
| 7645 | record_asynch_buffer_change (); | ||
| 7646 | } | 7712 | } |
| 7647 | else | 7713 | else |
| 7648 | { | 7714 | { |
| 7649 | Rect r; | 7715 | Rect r; |
| 7650 | |||
| 7651 | #if TARGET_API_MAC_CARBON | 7716 | #if TARGET_API_MAC_CARBON |
| 7652 | { | 7717 | RgnHandle region = NewRgn (); |
| 7653 | RgnHandle region = NewRgn (); | ||
| 7654 | 7718 | ||
| 7655 | GetPortVisibleRegion (GetWindowPort (win), region); | 7719 | GetPortVisibleRegion (GetWindowPort (win), region); |
| 7656 | GetRegionBounds (region, &r); | 7720 | GetRegionBounds (region, &r); |
| 7657 | expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top); | 7721 | expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top); |
| 7658 | UpdateControls (win, region); | 7722 | UpdateControls (win, region); |
| 7659 | DisposeRgn (region); | 7723 | DisposeRgn (region); |
| 7660 | } | ||
| 7661 | #else | 7724 | #else |
| 7662 | r = (*win->visRgn)->rgnBBox; | 7725 | r = (*win->visRgn)->rgnBBox; |
| 7663 | expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top); | 7726 | expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top); |
| 7664 | UpdateControls (win, win->visRgn); | 7727 | UpdateControls (win, win->visRgn); |
| 7665 | #endif | 7728 | #endif |
| 7666 | } | 7729 | } |
| 7667 | } | 7730 | } |
| 7668 | 7731 | ||
| 7669 | EndUpdate (win); | 7732 | EndUpdate (win); |
| @@ -8195,6 +8258,17 @@ mac_handle_window_event (next_handler, event, data) | |||
| 8195 | return noErr; | 8258 | return noErr; |
| 8196 | } | 8259 | } |
| 8197 | break; | 8260 | break; |
| 8261 | |||
| 8262 | case kEventWindowShown: | ||
| 8263 | case kEventWindowHidden: | ||
| 8264 | case kEventWindowExpanded: | ||
| 8265 | case kEventWindowCollapsed: | ||
| 8266 | result = CallNextEventHandler (next_handler, event); | ||
| 8267 | |||
| 8268 | mac_handle_visibility_change (mac_window_to_frame (wp)); | ||
| 8269 | return noErr; | ||
| 8270 | |||
| 8271 | break; | ||
| 8198 | } | 8272 | } |
| 8199 | 8273 | ||
| 8200 | return eventNotHandledErr; | 8274 | return eventNotHandledErr; |
| @@ -8270,7 +8344,11 @@ install_window_handler (window) | |||
| 8270 | #if USE_CARBON_EVENTS | 8344 | #if USE_CARBON_EVENTS |
| 8271 | EventTypeSpec specs_window[] = | 8345 | EventTypeSpec specs_window[] = |
| 8272 | {{kEventClassWindow, kEventWindowUpdate}, | 8346 | {{kEventClassWindow, kEventWindowUpdate}, |
| 8273 | {kEventClassWindow, kEventWindowBoundsChanging}}; | 8347 | {kEventClassWindow, kEventWindowBoundsChanging}, |
| 8348 | {kEventClassWindow, kEventWindowShown}, | ||
| 8349 | {kEventClassWindow, kEventWindowHidden}, | ||
| 8350 | {kEventClassWindow, kEventWindowExpanded}, | ||
| 8351 | {kEventClassWindow, kEventWindowCollapsed}}; | ||
| 8274 | EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}}; | 8352 | EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}}; |
| 8275 | static EventHandlerUPP handle_window_eventUPP = NULL; | 8353 | static EventHandlerUPP handle_window_eventUPP = NULL; |
| 8276 | static EventHandlerUPP handle_mouse_eventUPP = NULL; | 8354 | static EventHandlerUPP handle_mouse_eventUPP = NULL; |
| @@ -9479,6 +9557,29 @@ XTread_socket (sd, expected, hold_quit) | |||
| 9479 | pending_autoraise_frame = 0; | 9557 | pending_autoraise_frame = 0; |
| 9480 | } | 9558 | } |
| 9481 | 9559 | ||
| 9560 | #if !USE_CARBON_EVENTS | ||
| 9561 | /* Check which frames are still visible. We do this here because | ||
| 9562 | there doesn't seem to be any direct notification from the Window | ||
| 9563 | Manager that the visibility of a window has changed (at least, | ||
| 9564 | not in all cases). */ | ||
| 9565 | { | ||
| 9566 | Lisp_Object tail, frame; | ||
| 9567 | |||
| 9568 | FOR_EACH_FRAME (tail, frame) | ||
| 9569 | { | ||
| 9570 | struct frame *f = XFRAME (frame); | ||
| 9571 | |||
| 9572 | /* The tooltip has been drawn already. Avoid the | ||
| 9573 | SET_FRAME_GARBAGED in mac_handle_visibility_change. */ | ||
| 9574 | if (EQ (frame, tip_frame)) | ||
| 9575 | continue; | ||
| 9576 | |||
| 9577 | if (FRAME_MAC_P (f)) | ||
| 9578 | mac_handle_visibility_change (f); | ||
| 9579 | } | ||
| 9580 | } | ||
| 9581 | #endif | ||
| 9582 | |||
| 9482 | UNBLOCK_INPUT; | 9583 | UNBLOCK_INPUT; |
| 9483 | return count; | 9584 | return count; |
| 9484 | } | 9585 | } |