X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/f435830ea42db6073ed8714452dae302a3c855c5..f8eb15727ae6a5c629e27ab9755e638766b27822:/src/frame.c diff --git a/src/frame.c b/src/frame.c index 6e56a20f85..8eabef55d1 100644 --- a/src/frame.c +++ b/src/frame.c @@ -185,7 +185,6 @@ set_menu_bar_lines_1 (Lisp_Object window, int n) { struct window *w = XWINDOW (window); - w->last_modified = 0; w->top_line += n; w->total_lines -= n; @@ -225,7 +224,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) FRAME_WINDOW_SIZES_CHANGED (f) = 1; FRAME_MENU_BAR_LINES (f) = nlines; set_menu_bar_lines_1 (f->root_window, nlines - olines); - adjust_glyphs (f); + adjust_frame_glyphs (f); } } @@ -693,24 +692,16 @@ affects all frames on the same terminal device. */) ? FRAME_TTY (XFRAME (selected_frame))->name : NULL)); if (!NILP (tty)) - { - name = alloca (SBYTES (tty) + 1); - memcpy (name, SSDATA (tty), SBYTES (tty)); - name[SBYTES (tty)] = 0; - } + name = xlispstrdupa (tty); tty_type = get_future_frame_param (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) ? FRAME_TTY (XFRAME (selected_frame))->type : NULL)); if (!NILP (tty_type)) - { - type = alloca (SBYTES (tty_type) + 1); - memcpy (type, SSDATA (tty_type), SBYTES (tty_type)); - type[SBYTES (tty_type)] = 0; - } + type = xlispstrdupa (tty_type); - t = init_tty (name, type, 0); /* Errors are not fatal. */ + t = init_tty (name, type, 0); /* Errors are not fatal. */ } f = make_terminal_frame (t); @@ -721,12 +712,12 @@ affects all frames on the same terminal device. */) change_frame_size (f, height, width, 0, 0, 0); } - adjust_glyphs (f); + adjust_frame_glyphs (f); calculate_costs (f); XSETFRAME (frame, f); store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); - store_in_alist (&parms, Qtty, + store_in_alist (&parms, Qtty, (t->display_info.tty->name ? build_string (t->display_info.tty->name) : Qnil)); @@ -1087,13 +1078,26 @@ Otherwise, include all frames. */) CHECK_LIVE_FRAME (frame); return prev_frame (frame, miniframe); } + +DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame, + Slast_nonminibuf_frame, 0, 0, 0, + doc: /* Return last non-minibuffer frame selected. */) + (void) +{ + Lisp_Object frame = Qnil; + + if (last_nonminibuf_frame) + XSETFRAME (frame, last_nonminibuf_frame); + + return frame; +} /* Return 1 if it is ok to delete frame F; 0 if all frames aside from F are invisible. (Exception: if F is the terminal frame, and we are using X, return 1.) */ static int -other_visible_frames (FRAME_PTR f) +other_visible_frames (struct frame *f) { Lisp_Object frames, this; @@ -1104,7 +1108,7 @@ other_visible_frames (FRAME_PTR f) /* Verify that we can still talk to the frame's X window, and note any recent change in visibility. */ -#ifdef HAVE_WINDOW_SYSTEM +#ifdef HAVE_X_WINDOWS if (FRAME_WINDOW_P (XFRAME (this))) x_sync (XFRAME (this)); #endif @@ -1119,6 +1123,52 @@ other_visible_frames (FRAME_PTR f) return 0; } +/* Make sure that minibuf_window doesn't refer to FRAME's minibuffer + window. Preferably use the selected frame's minibuffer window + instead. If the selected frame doesn't have one, get some other + frame's minibuffer window. SELECT non-zero means select the new + minibuffer window. */ +static void +check_minibuf_window (Lisp_Object frame, int select) +{ + struct frame *f = decode_live_frame (frame); + + XSETFRAME (frame, f); + + if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window)) + { + Lisp_Object frames, this, window = make_number (0); + + if (!EQ (frame, selected_frame) + && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame))) + window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame)); + else + FOR_EACH_FRAME (frames, this) + { + if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this))) + { + window = FRAME_MINIBUF_WINDOW (XFRAME (this)); + break; + } + } + + /* Don't abort if no window was found (Bug#15247). */ + if (WINDOWP (window)) + { + /* Use set_window_buffer instead of Fset_window_buffer (see + discussion of bug#11984, bug#12025, bug#12026). */ + set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0); + minibuf_window = window; + + /* SELECT non-zero usually means that FRAME's minibuffer + window was selected; select the new one. */ + if (select) + Fselect_window (minibuf_window, Qnil); + } + } +} + + /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME unconditionally. x_connection_closed and delete_terminal use this. Any other value of FORCE implements the semantics @@ -1206,10 +1256,18 @@ delete_frame (Lisp_Object frame, Lisp_Object force) /* Don't let the frame remain selected. */ if (f == sf) { - Lisp_Object tail, frame1; - - /* Look for another visible frame on the same terminal. */ - frame1 = next_frame (frame, Qvisible); + Lisp_Object tail; + Lisp_Object frame1 = Qnil; + + /* Look for another visible frame on the same terminal. + Do not call next_frame here because it may loop forever. + See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */ + FOR_EACH_FRAME (tail, frame1) + if (!EQ (frame, frame1) + && (FRAME_TERMINAL (XFRAME (frame)) + == FRAME_TERMINAL (XFRAME (frame1))) + && FRAME_VISIBLE_P (XFRAME (frame1))) + break; /* If there is none, find *some* other frame. */ if (NILP (frame1) || EQ (frame1, frame)) @@ -1245,19 +1303,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force) } /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->contents, 0, 0); - minibuf_window = sf->minibuffer_window; - - /* If the dying minibuffer window was selected, - select the new one. */ - if (minibuffer_selected) - Fselect_window (minibuf_window, Qnil); - } + check_minibuf_window (frame, minibuffer_selected); /* Don't let echo_area_window to remain on a deleted frame. */ if (EQ (f->minibuffer_window, echo_area_window)) @@ -1467,7 +1513,7 @@ passing the normal return value to that function as an argument, and returns whatever that function returns. */) (void) { - FRAME_PTR f; + struct frame *f; Lisp_Object lispy_dummy; Lisp_Object x, y, retval; struct gcpro gcpro1; @@ -1513,7 +1559,7 @@ to read the mouse position, it returns the selected frame for FRAME and nil for X and Y. */) (void) { - FRAME_PTR f; + struct frame *f; Lisp_Object lispy_dummy; Lisp_Object x, y; @@ -1684,16 +1730,8 @@ displayed in the terminal. */) if (NILP (force) && !other_visible_frames (f)) error ("Attempt to make invisible the sole visible or iconified frame"); - /* Don't allow minibuf_window to remain on a deleted frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - struct frame *sf = XFRAME (selected_frame); - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->contents, 0, 0); - minibuf_window = sf->minibuffer_window; - } + /* Don't allow minibuf_window to remain on an invisible frame. */ + check_minibuf_window (frame, EQ (minibuf_window, selected_window)); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1716,15 +1754,7 @@ If omitted, FRAME defaults to the currently selected frame. */) struct frame *f = decode_live_frame (frame); /* Don't allow minibuf_window to remain on an iconified frame. */ - if (EQ (f->minibuffer_window, minibuf_window)) - { - struct frame *sf = XFRAME (selected_frame); - /* Use set_window_buffer instead of Fset_window_buffer (see - discussion of bug#11984, bug#12025, bug#12026). */ - set_window_buffer (sf->minibuffer_window, - XWINDOW (minibuf_window)->contents, 0, 0); - minibuf_window = sf->minibuffer_window; - } + check_minibuf_window (frame, EQ (minibuf_window, selected_window)); /* I think this should be done with a hook. */ #ifdef HAVE_WINDOW_SYSTEM @@ -1871,6 +1901,17 @@ See `redirect-frame-focus'. */) return FRAME_FOCUS_FRAME (decode_live_frame (frame)); } +DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0, + doc: /* Set the input focus to FRAME. +FRAME nil means use the selected frame. +If there is no window system support, this function does nothing. */) + (Lisp_Object frame) +{ +#ifdef HAVE_WINDOW_SYSTEM + x_focus_frame (decode_window_system_frame (frame)); +#endif + return Qnil; +} /* Return the value of frame parameter PROP in frame FRAME. */ @@ -2177,7 +2218,7 @@ If FRAME is nil, describe the currently selected frame. */) value = f->name; #ifdef HAVE_X_WINDOWS else if (EQ (parameter, Qdisplay) && FRAME_X_P (f)) - value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element); + value = XCAR (FRAME_DISPLAY_INFO (f)->name_list_element); #endif /* HAVE_X_WINDOWS */ else if (EQ (parameter, Qbackground_color) || EQ (parameter, Qforeground_color)) @@ -2568,7 +2609,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int { int newwidth = FRAME_COLS (f); int newheight = FRAME_LINES (f); - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); *top_pos = f->top_pos; *left_pos = f->left_pos; @@ -2610,7 +2651,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int to store the new value in the parameter alist. */ void -x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) +x_set_frame_parameters (struct frame *f, Lisp_Object alist) { Lisp_Object tail; @@ -2867,10 +2908,11 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist) /* Actually set that position, and convert to absolute. */ x_set_offset (f, leftpos, toppos, -1); } - +#ifdef HAVE_X_WINDOWS if ((!NILP (icon_left) || !NILP (icon_top)) && ! (icon_left_no_change && icon_top_no_change)) x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); +#endif /* HAVE_X_WINDOWS */ } UNGCPRO; @@ -2942,9 +2984,9 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr) (FRAME_VISIBLE_P (f) ? Qt : FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); store_in_alist (alistptr, Qdisplay, - XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element)); + XCAR (FRAME_DISPLAY_INFO (f)->name_list_element)); - if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window) + if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_DISPLAY_INFO (f)->root_window) tem = Qnil; else tem = make_natnum ((uintptr_t) FRAME_X_OUTPUT (f)->parent_desc); @@ -3327,9 +3369,6 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) else if (RANGED_INTEGERP (1, arg, INT_MAX) && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) { - if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM) - XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1); - FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg); FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid; if (FRAME_X_WINDOW (f)) @@ -3347,7 +3386,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) /* Return non-nil if frame F wants a bitmap icon. */ Lisp_Object -x_icon_type (FRAME_PTR f) +x_icon_type (struct frame *f) { Lisp_Object tem; @@ -3544,7 +3583,7 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li value = x_get_string_resource (rdb, name_key, class_key); - if (value != (char *) 0 && *value) + if (value && *value) return build_string (value); else return Qnil; @@ -3600,7 +3639,7 @@ x_get_resource_string (const char *attribute, const char *class) esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); sprintf (class_key, "%s.%s", EMACS_CLASS, class); - result = x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb, + result = x_get_string_resource (FRAME_DISPLAY_INFO (sf)->xrdb, name_key, class_key); SAFE_FREE (); return result; @@ -3722,7 +3761,7 @@ x_frame_get_arg (struct frame *f, Lisp_Object alist, Lisp_Object param, const char *attribute, const char *class, enum resource_types type) { - return x_get_arg (FRAME_X_DISPLAY_INFO (f), + return x_get_arg (FRAME_DISPLAY_INFO (f), alist, param, attribute, class, type); } @@ -3736,7 +3775,7 @@ x_frame_get_and_record_arg (struct frame *f, Lisp_Object alist, { Lisp_Object value; - value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param, + value = x_get_arg (FRAME_DISPLAY_INFO (f), alist, param, attribute, class, type); if (! NILP (value) && ! EQ (value, Qunbound)) store_frame_param (f, param, value); @@ -3940,7 +3979,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p) { register Lisp_Object tem0, tem1, tem2; long window_prompting = 0; - Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); /* Default values if we fall through. Actually, if that happens we should get @@ -4203,8 +4242,7 @@ make_monitor_attribute_list (struct MonitorInfo *monitors, mi->work.width, mi->work.height); geometry = list4i (mi->geom.x, mi->geom.y, mi->geom.width, mi->geom.height); - attributes = Fcons (Fcons (Qsource, - make_string (source, strlen (source))), + attributes = Fcons (Fcons (Qsource, build_string (source)), attributes); attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), attributes); @@ -4477,6 +4515,7 @@ automatically. See also `mouse-autoselect-window'. */); defsubr (&Sframe_list); defsubr (&Snext_frame); defsubr (&Sprevious_frame); + defsubr (&Slast_nonminibuf_frame); defsubr (&Sdelete_frame); defsubr (&Smouse_position); defsubr (&Smouse_pixel_position); @@ -4493,6 +4532,7 @@ automatically. See also `mouse-autoselect-window'. */); defsubr (&Svisible_frame_list); defsubr (&Sraise_frame); defsubr (&Slower_frame); + defsubr (&Sx_focus_frame); defsubr (&Sredirect_frame_focus); defsubr (&Sframe_focus); defsubr (&Sframe_parameters);