Mercurial > emacs
changeset 61574:d3c53b9d1828
(x_autoselect_window_p): Remove variable.
(last_window): New variable.
(XTreassert_line_highlight, x_change_line_highlight): Remove
declarations.
(mac_focus_changed, x_detect_focus_change): New functions and
declarations.
(XTextExtents16, front_emacs_window): Remove function.
(mac_focus_frame): New function.
(XTmouse_position, do_menu_choice, do_zoom_window, XTread_socket)
(mac_check_for_quit_char): Use it instead of front_emacs_window.
(x_scroll_bar_report_motion): Obtain window from control owner.
(x_make_frame_invisible): Set window manager size hint.
(do_mouse_moved): Remove function.
(XTread_socket): Move its contents here. Generate select-window
event on mouse movement if needed. Use x_detect_focus_change on
activate/deactivate events. Don't deiconify frame or invalidate
window rectangle when dnd items are dropped. Don't
activate/deactivate root control.
(frame_highlight, frame_unhighlight): Activate/deactivate root
control here.
(syms_of_macterm): Delete DEFVAR_BOOL for x_autoselect_window_p.
author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
---|---|
date | Sat, 16 Apr 2005 03:05:15 +0000 |
parents | 5b0b486b7f71 |
children | 999aacd9ac84 |
files | src/macterm.c |
diffstat | 1 files changed, 211 insertions(+), 162 deletions(-) [+] |
line wrap: on
line diff
--- a/src/macterm.c Sat Apr 16 03:04:13 2005 +0000 +++ b/src/macterm.c Sat Apr 16 03:05:15 2005 +0000 @@ -95,6 +95,7 @@ : controlKey) #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey) +#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP) /* Non-nil means Emacs uses toolkit scroll bars. */ @@ -110,9 +111,8 @@ static int any_help_event_p; -/* Non-zero means autoselect window with the mouse cursor. */ - -int x_autoselect_window_p; +/* Last window where we saw the mouse. Used by mouse-autoselect-window. */ +static Lisp_Object last_window; /* Non-zero means make use of UNDERLINE_POSITION font properties. */ @@ -273,14 +273,16 @@ static int x_compute_min_glyph_bounds P_ ((struct frame *)); static void x_update_end P_ ((struct frame *)); static void XTframe_up_to_date P_ ((struct frame *)); -static void XTreassert_line_highlight P_ ((int, int)); -static void x_change_line_highlight P_ ((int, int, int, int)); static void XTset_terminal_modes P_ ((void)); static void XTreset_terminal_modes P_ ((void)); static void x_clear_frame P_ ((void)); static void frame_highlight P_ ((struct frame *)); static void frame_unhighlight P_ ((struct frame *)); static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); +static void mac_focus_changed P_ ((int, struct mac_display_info *, + struct frame *, struct input_event *)); +static void x_detect_focus_change P_ ((struct mac_display_info *, + EventRecord *, struct input_event *)); static void XTframe_rehighlight P_ ((struct frame *)); static void x_frame_rehighlight P_ ((struct x_display_info *)); static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); @@ -1198,15 +1200,6 @@ } -static void -XTextExtents16 (XFontStruct *font, XChar2b *text, int nchars, - int *direction,int *font_ascent, - int *font_descent, XCharStruct *cs) -{ - /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */ -} - - /* x_sync is a no-op on Mac. */ void x_sync (f) @@ -3494,6 +3487,14 @@ frame_highlight (f) struct frame *f; { + OSErr err; + ControlRef root_control; + + BLOCK_INPUT; + err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control); + if (err == noErr) + ActivateControl (root_control); + UNBLOCK_INPUT; x_update_cursor (f, 1); } @@ -3501,6 +3502,14 @@ frame_unhighlight (f) struct frame *f; { + OSErr err; + ControlRef root_control; + + BLOCK_INPUT; + err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control); + if (err == noErr) + DeactivateControl (root_control); + UNBLOCK_INPUT; x_update_cursor (f, 1); } @@ -3543,6 +3552,68 @@ x_frame_rehighlight (dpyinfo); } +/* Handle FocusIn and FocusOut state changes for FRAME. + If FRAME has focus and there exists more than one frame, puts + a FOCUS_IN_EVENT into *BUFP. */ + +static void +mac_focus_changed (type, dpyinfo, frame, bufp) + int type; + struct mac_display_info *dpyinfo; + struct frame *frame; + struct input_event *bufp; +{ + if (type == activeFlag) + { + if (dpyinfo->x_focus_event_frame != frame) + { + x_new_focus_frame (dpyinfo, frame); + dpyinfo->x_focus_event_frame = frame; + + /* Don't stop displaying the initial startup message + for a switch-frame event we don't need. */ + if (GC_NILP (Vterminal_frame) + && GC_CONSP (Vframe_list) + && !GC_NILP (XCDR (Vframe_list))) + { + bufp->kind = FOCUS_IN_EVENT; + XSETFRAME (bufp->frame_or_window, frame); + } + } + } + else + { + if (dpyinfo->x_focus_event_frame == frame) + { + dpyinfo->x_focus_event_frame = 0; + x_new_focus_frame (dpyinfo, 0); + } + } +} + +/* The focus may have changed. Figure out if it is a real focus change, + by checking both FocusIn/Out and Enter/LeaveNotify events. + + Returns FOCUS_IN_EVENT event in *BUFP. */ + +static void +x_detect_focus_change (dpyinfo, event, bufp) + struct mac_display_info *dpyinfo; + EventRecord *event; + struct input_event *bufp; +{ + struct frame *frame; + + frame = mac_window_to_frame ((WindowPtr) event->message); + if (! frame) + return; + + /* On Mac, this is only called from focus events, so no switch needed. */ + mac_focus_changed ((event->modifiers & activeFlag), + dpyinfo, frame, bufp); +} + + /* Handle an event saying the mouse has moved out of an Emacs frame. */ void @@ -3980,25 +4051,19 @@ } -static WindowPtr -front_emacs_window () -{ -#if TARGET_API_MAC_CARBON - WindowPtr wp = GetFrontWindowOfClass (kDocumentWindowClass, true); - - while (wp && !is_emacs_window (wp)) - wp = GetNextWindowOfClass (wp, kDocumentWindowClass, true); -#else - WindowPtr wp = FrontWindow (); - - while (wp && (wp == tip_window || !is_emacs_window (wp))) - wp = GetNextWindow (wp); -#endif - - return wp; -} - -#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP) +static struct frame * +mac_focus_frame (dpyinfo) + struct mac_display_info *dpyinfo; +{ + if (dpyinfo->x_focus_frame) + return dpyinfo->x_focus_frame; + else + /* Mac version may get events, such as a menu bar click, even when + all the frames are invisible. In this case, we regard the + event came to the selected frame. */ + return SELECTED_FRAME (); +} + /* Return the current position of the mouse. *fp should be a frame which indicates which display to ask about. @@ -4031,13 +4096,10 @@ { Point mouse_pos; int ignore1, ignore2; - WindowPtr wp = front_emacs_window (); - struct frame *f; + struct frame *f = mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp)); + WindowPtr wp = FRAME_MAC_WINDOW (f); Lisp_Object frame, tail; - if (is_emacs_window(wp)) - f = mac_window_to_frame (wp); - BLOCK_INPUT; if (! NILP (last_mouse_scroll_bar) && insist == 0) @@ -4604,7 +4666,12 @@ unsigned long *time; { struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar); - WindowPtr wp = front_emacs_window (); + ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar); +#if TARGET_API_MAC_CARBON + WindowPtr wp = GetControlOwner (ch); +#else + WindowPtr wp = (*ch)->contrlOwner; +#endif Point mouse_pos; struct frame *f = mac_window_to_frame (wp); int win_y, top_range; @@ -5050,7 +5117,7 @@ return Qnil; /* Since x_new_font doesn't update any fontset information, do it now. */ - FRAME_FONTSET(f) = fontset; + FRAME_FONTSET (f) = fontset; return build_string (fontsetname); } @@ -5498,6 +5565,13 @@ BLOCK_INPUT; + /* Before unmapping the window, update the WM_SIZE_HINTS property to claim + that the current position of the window is user-specified, rather than + program-specified, so that when the window is mapped again, it will be + placed at the same location, without forcing the user to position it + by hand again (they have already done that once for this window.) */ + x_wm_set_size_hint (f, (long) 0, 1); + HideWindow (FRAME_MAC_WINDOW (f)); /* We can't distinguish this from iconification @@ -7454,21 +7528,6 @@ { /* Window-activate events will do the job. */ #if 0 - WindowPtr wp; - struct frame *f; - - wp = front_emacs_window (); - if (wp) - { - f = mac_window_to_frame (wp); - - if (f) - { - x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), f); - activate_scroll_bars (f); - } - } - app_is_suspended = false; app_sleep_time = WNE_SLEEP_AT_RESUME; #endif @@ -7479,21 +7538,6 @@ { /* Window-deactivate events will do the job. */ #if 0 - WindowPtr wp; - struct frame *f; - - wp = front_emacs_window (); - if (wp) - { - f = mac_window_to_frame (wp); - - if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame) - { - x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), 0); - deactivate_scroll_bars (f); - } - } - app_is_suspended = true; app_sleep_time = WNE_SLEEP_AT_SUSPEND; #endif @@ -7501,40 +7545,6 @@ static void -do_mouse_moved (mouse_pos, f) - Point mouse_pos; - FRAME_PTR *f; -{ - WindowPtr wp = front_emacs_window (); - struct x_display_info *dpyinfo; - - if (wp) - { - *f = mac_window_to_frame (wp); - dpyinfo = FRAME_MAC_DISPLAY_INFO (*f); - - if (dpyinfo->mouse_face_hidden) - { - dpyinfo->mouse_face_hidden = 0; - clear_mouse_face (dpyinfo); - } - - SetPortWindowPort (wp); - - GlobalToLocal (&mouse_pos); - - if (dpyinfo->grabbed && tracked_scroll_bar) - x_scroll_bar_note_movement (tracked_scroll_bar, - mouse_pos.v - - XINT (tracked_scroll_bar->top), - TickCount() * (1000 / 60)); - else - note_mouse_movement (*f, &mouse_pos); - } -} - - -static void do_apple_menu (SInt16 menu_item) { #if !TARGET_API_MAC_CARBON @@ -7570,7 +7580,7 @@ default: { - struct frame *f = mac_window_to_frame (front_emacs_window ()); + struct frame *f = mac_focus_frame (&one_mac_display_info); MenuHandle menu = GetMenuHandle (menu_id); if (menu) { @@ -7648,13 +7658,14 @@ Point top_left; int w_title_height, 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 = FRAME_MAC_DISPLAY_INFO (f)->height; + standard_size.v = dpyinfo->height; if (IsWindowInStandardState (w, &standard_size, &zoom_rect)) zoom_in_or_out = inZoomIn; @@ -7710,7 +7721,7 @@ = zoom_rect; } - ZoomWindow (w, zoom_in_or_out, w == front_emacs_window ()); + ZoomWindow (w, zoom_in_or_out, f == mac_focus_frame (dpyinfo)); SetPort (save_port); #endif /* not TARGET_API_MAC_CARBON */ @@ -8576,10 +8587,13 @@ { SInt32 delta; Point point; - WindowPtr window_ptr = front_emacs_window (); - - if (!IsValidWindowPtr (window_ptr)) + struct frame *f = mac_focus_frame (dpyinfo); + WindowPtr window_ptr; + + if (!f) { + /* Beep if wheel move occurs when all the frames + are invisible. */ SysBeep(1); break; } @@ -8595,6 +8609,7 @@ inev.modifiers = (mac_event_to_emacs_modifiers (eventRef) | ((delta < 0) ? down_modifier : up_modifier)); + window_ptr = FRAME_MAC_WINDOW (f); SetPortWindowPort (window_ptr); GlobalToLocal (&point); XSETINT (inev.x, point.h); @@ -8653,14 +8668,14 @@ switch (part_code) { case inMenuBar: - f = mac_window_to_frame (front_emacs_window ()); + f = mac_focus_frame (dpyinfo); saved_menu_event_location = er.where; inev.kind = MENU_BAR_ACTIVATE_EVENT; XSETFRAME (inev.frame_or_window, f); break; case inContent: - if (window_ptr != front_emacs_window ()) + if (window_ptr != FRAME_MAC_WINDOW (mac_focus_frame (dpyinfo))) SelectWindow (window_ptr); else { @@ -8851,7 +8866,61 @@ help_echo_string = help_echo_object = help_echo_window = Qnil; help_echo_pos = -1; - do_mouse_moved (er.where, &f); + if (dpyinfo->grabbed && last_mouse_frame + && FRAME_LIVE_P (last_mouse_frame)) + f = last_mouse_frame; + else + f = dpyinfo->x_focus_frame; + + if (dpyinfo->mouse_face_hidden) + { + dpyinfo->mouse_face_hidden = 0; + clear_mouse_face (dpyinfo); + } + + if (f) + { + WindowPtr wp = FRAME_MAC_WINDOW (f); + Point mouse_pos = er.where; + + SetPortWindowPort (wp); + + GlobalToLocal (&mouse_pos); + + if (dpyinfo->grabbed && tracked_scroll_bar) + x_scroll_bar_note_movement (tracked_scroll_bar, + mouse_pos.v + - XINT (tracked_scroll_bar->top), + TickCount() * (1000 / 60)); + else + { + /* Generate SELECT_WINDOW_EVENTs when needed. */ + if (mouse_autoselect_window) + { + Lisp_Object window; + + window = window_from_coordinates (f, + mouse_pos.h, + mouse_pos.v, + 0, 0, 0, 0); + + /* Window will be selected only when it is + not selected now and last mouse movement + event was not in it. Minibuffer window + will be selected iff it is active. */ + if (WINDOWP (window) + && !EQ (window, last_window) + && !EQ (window, selected_window)) + { + inev.kind = SELECT_WINDOW_EVENT; + inev.frame_or_window = window; + } + + last_window=window; + } + note_mouse_movement (f, &mouse_pos); + } + } /* If the contents of the global variable help_echo_string has changed, generate a @@ -8865,7 +8934,6 @@ case activateEvt: { WindowPtr window_ptr = (WindowPtr) er.message; - ControlRef root_control; #if USE_CARBON_EVENTS if (SendEventToEventTarget (eventRef, toolbox_dispatcher) @@ -8881,16 +8949,12 @@ if (!is_emacs_window (window_ptr)) break; - f = mac_window_to_frame (window_ptr); - GetRootControl (window_ptr, &root_control); - if ((er.modifiers & activeFlag) != 0) { /* A window has been activated */ Point mouse_loc = er.where; - x_new_focus_frame (dpyinfo, f); - ActivateControl (root_control); + x_detect_focus_change (dpyinfo, &er, &inev); SetPortWindowPort (window_ptr); GlobalToLocal (&mouse_loc); @@ -8904,13 +8968,9 @@ /* A window has been deactivated */ dpyinfo->grabbed = 0; - if (f == dpyinfo->x_focus_frame) - { - x_new_focus_frame (dpyinfo, 0); - DeactivateControl (root_control); - } - - + x_detect_focus_change (dpyinfo, &er, &inev); + + f = mac_window_to_frame (window_ptr); if (f == dpyinfo->mouse_face_mouse_frame) { /* If we move outside the frame, then we're @@ -8951,13 +9011,14 @@ break; #endif -#if TARGET_API_MAC_CARBON - if (!IsValidWindowPtr (front_emacs_window ())) + if (dpyinfo->x_focus_frame == NULL) { + /* Beep if keyboard input occurs when all the frames + are invisible. */ SysBeep (1); break; } -#endif + { static SInt16 last_key_script = -1; SInt16 current_key_script = GetScriptManagerVariable (smKeyScript); @@ -8965,7 +9026,7 @@ if (last_key_script != current_key_script) { struct input_event event; - + EVENT_INIT (event); event.kind = LANGUAGE_CHANGE_EVENT; event.arg = Qnil; @@ -9009,18 +9070,20 @@ unsigned long some_state = 0; inev.code = KeyTranslate (kchr_ptr, new_keycode, &some_state) & 0xff; - } else if (!NILP(Vmac_option_modifier) && (er.modifiers & optionKey)) - { - /* When using the option key as an emacs modifier, convert - the pressed key code back to one without the Mac option - modifier applied. */ - int new_modifiers = er.modifiers & ~optionKey; - int new_keycode = keycode | new_modifiers; - Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache); - unsigned long some_state = 0; - inev.code = KeyTranslate (kchr_ptr, new_keycode, - &some_state) & 0xff; - } + } + else if (!NILP (Vmac_option_modifier) + && (er.modifiers & optionKey)) + { + /* When using the option key as an emacs modifier, + convert the pressed key code back to one + without the Mac option modifier applied. */ + int new_modifiers = er.modifiers & ~optionKey; + int new_keycode = keycode | new_modifiers; + Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache); + unsigned long some_state = 0; + inev.code = KeyTranslate (kchr_ptr, new_keycode, + &some_state) & 0xff; + } else inev.code = er.message & charCodeMask; inev.kind = ASCII_KEYSTROKE_EVENT; @@ -9032,8 +9095,7 @@ #else inev.modifiers = mac_to_emacs_modifiers (er.modifiers); #endif - XSETFRAME (inev.frame_or_window, - mac_window_to_frame (front_emacs_window ())); + XSETFRAME (inev.frame_or_window, mac_focus_frame (dpyinfo)); inev.timestamp = er.when * (1000 / 60); /* ticks to milliseconds */ break; @@ -9046,22 +9108,10 @@ constuct_drag_n_drop in w32term.c. */ if (!NILP (drag_and_drop_file_list)) { - struct frame *f = NULL; + struct frame *f = mac_focus_frame (dpyinfo); WindowPtr wp; Lisp_Object frame; - wp = front_emacs_window (); - - if (!wp) - { - struct frame *f = XFRAME (XCAR (Vframe_list)); - CollapseWindow (FRAME_MAC_WINDOW (f), false); - wp = front_emacs_window (); - } - - if (wp) - f = mac_window_to_frame (wp); - inev.kind = DRAG_N_DROP_EVENT; inev.code = 0; inev.timestamp = er.when * (1000 / 60); @@ -9078,10 +9128,12 @@ XSETFRAME (frame, f); inev.frame_or_window = Fcons (frame, drag_and_drop_file_list); +#if 0 /* Regardless of whether Emacs was suspended or in the foreground, ask it to redraw its entire screen. Otherwise parts of the screen can be left in an inconsistent state. */ + wp = FRAME_MAC_WINDOW (f); if (wp) #if TARGET_API_MAC_CARBON { @@ -9093,6 +9145,7 @@ #else /* not TARGET_API_MAC_CARBON */ InvalRect (&(wp->portRect)); #endif /* not TARGET_API_MAC_CARBON */ +#endif } default: break; @@ -9572,7 +9625,7 @@ e.arg = Qnil; e.modifiers = NULL; e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60); - XSETFRAME (e.frame_or_window, mac_window_to_frame (front_emacs_window ())); + XSETFRAME (e.frame_or_window, mac_focus_frame (&one_mac_display_info)); /* Remove event from queue to prevent looping. */ RemoveEventFromQueue (GetMainEventQueue (), event); ReleaseEvent (event); @@ -9765,10 +9818,6 @@ Qeuc_kr = intern ("euc-kr"); staticpro (&Qeuc_kr); - DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p, - doc: /* *Non-nil means autoselect window with mouse pointer. */); - x_autoselect_window_p = 0; - DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, doc: /* If not nil, Emacs uses toolkit scroll bars. */); Vx_toolkit_scroll_bars = Qt;