Mercurial > emacs
changeset 35067:7ca0048f8615
(x_create_tip_frame): Preserve the value of
face_change_count around the creation of the tip frame.
(last_show_tip_args): New variable.
(compute_tip_xy): New function.
(Fx_show_tip): Reuse an existing tip frame, if possible.
(syms_of_xfns): Initialize and staticpro last_show_tip_args.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Thu, 04 Jan 2001 20:33:06 +0000 |
parents | f4b5ec3edf1a |
children | e6fe439553cf |
files | src/xfns.c |
diffstat | 1 files changed, 93 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/src/xfns.c Thu Jan 04 20:32:20 2001 +0000 +++ b/src/xfns.c Thu Jan 04 20:33:06 2001 +0000 @@ -10347,6 +10347,8 @@ static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *, Lisp_Object)); +static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object, + Lisp_Object, int *, int *)); /* The frame of a currently visible tooltip. */ @@ -10358,6 +10360,11 @@ Lisp_Object tip_timer; Window tip_window; +/* If non-nil, a vector of 3 elements containing the last args + with which x-show-tip was called. See there. */ + +Lisp_Object last_show_tip_args; + static Lisp_Object unwind_create_tip_frame (frame) @@ -10397,6 +10404,7 @@ int count = BINDING_STACK_SIZE (); struct gcpro gcpro1, gcpro2, gcpro3; struct kboard *kb; + int face_change_count_before = face_change_count; check_x (); @@ -10655,11 +10663,55 @@ its display. */ FRAME_X_DISPLAY_INFO (f)->reference_count++; + /* Setting attributes of faces of the tooltip frame from resources + and similar will increment face_change_count, which leads to the + clearing of all current matrices. Since this isn't necessary + here, avoid it by resetting face_change_count to the value it + had before we created the tip frame. */ + face_change_count = face_change_count_before; + /* Discard the unwind_protect. */ return unbind_to (count, frame); } +/* Compute where to display tip frame F. PARMS is the list of frame + parameters for F. DX and DY are specified offsets from the current + location of the mouse. Return coordinates relative to the root + window of the display in *ROOT_X, and *ROOT_Y. */ + +static void +compute_tip_xy (f, parms, dx, dy, root_x, root_y) + struct frame *f; + Lisp_Object parms, dx, dy; + int *root_x, *root_y; +{ + Lisp_Object left, top; + int win_x, win_y; + Window root, child; + unsigned pmask; + + /* User-specified position? */ + left = Fcdr (Fassq (Qleft, parms)); + top = Fcdr (Fassq (Qtop, parms)); + + /* Move the tooltip window where the mouse pointer is. Resize and + show it. */ + BLOCK_INPUT; + XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, + &root, &child, root_x, root_y, &win_x, &win_y, &pmask); + UNBLOCK_INPUT; + + *root_x += XINT (dx); + *root_y += XINT (dy); + + if (INTEGERP (left)) + *root_x = XINT (left); + if (INTEGERP (top)) + *root_y = XINT (top); +} + + DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, "Show STRING in a \"tooltip\" window on frame FRAME.\n\ A tooltip window is a small X window displaying a string.\n\ @@ -10684,16 +10736,14 @@ { struct frame *f; struct window *w; - Window root, child; Lisp_Object buffer, top, left; + int root_x, root_y; struct buffer *old_buffer; struct text_pos pos; int i, width, height; - int root_x, root_y, win_x, win_y; - unsigned pmask; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; int old_windows_or_buffers_changed = windows_or_buffers_changed; - int count = specpdl_ptr - specpdl; + int count = BINDING_STACK_SIZE (); specbind (Qinhibit_redisplay, Qt); @@ -10716,9 +10766,41 @@ else CHECK_NUMBER (dy, 6); + if (NILP (last_show_tip_args)) + last_show_tip_args = Fmake_vector (make_number (3), Qnil); + + if (!NILP (tip_frame)) + { + Lisp_Object last_string = AREF (last_show_tip_args, 0); + Lisp_Object last_frame = AREF (last_show_tip_args, 1); + Lisp_Object last_parms = AREF (last_show_tip_args, 2); + + if (EQ (frame, last_frame) + && !NILP (Fequal (last_string, string)) + && !NILP (Fequal (last_parms, parms))) + { + struct frame *f = XFRAME (tip_frame); + + /* Only DX and DY have changed. */ + if (!NILP (tip_timer)) + call1 (intern ("cancel-timer"), tip_timer); + + BLOCK_INPUT; + compute_tip_xy (f, parms, dx, dy, &root_x, &root_y); + XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + root_x, root_y - PIXEL_HEIGHT (f)); + UNBLOCK_INPUT; + goto start_timer; + } + } + /* Hide a previous tip, if any. */ Fx_hide_tip (); + ASET (last_show_tip_args, 0, string); + ASET (last_show_tip_args, 1, frame); + ASET (last_show_tip_args, 2, parms); + /* Add default values to frame parameters. */ if (NILP (Fassq (Qname, parms))) parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms); @@ -10793,31 +10875,16 @@ height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); - /* User-specified position? */ - left = Fcdr (Fassq (Qleft, parms)); - top = Fcdr (Fassq (Qtop, parms)); - /* Move the tooltip window where the mouse pointer is. Resize and show it. */ - BLOCK_INPUT; - XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, - &root, &child, &root_x, &root_y, &win_x, &win_y, &pmask); - UNBLOCK_INPUT; - - root_x += XINT (dx); - root_y += XINT (dy); - - if (INTEGERP (left)) - root_x = XINT (left); - if (INTEGERP (top)) - root_y = XINT (top); - + compute_tip_xy (f, parms, dx, dy, &root_x, &root_y); + BLOCK_INPUT; XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), root_x, root_y - height, width, height); XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); UNBLOCK_INPUT; - + /* Draw into the window. */ w->must_be_updated_p = 1; update_single_window (w, 1); @@ -10826,6 +10893,7 @@ set_buffer_internal_1 (old_buffer); windows_or_buffers_changed = old_windows_or_buffers_changed; + start_timer: /* Let the tip disappear after timeout seconds. */ tip_timer = call3 (intern ("run-at-time"), timeout, Qnil, intern ("x-hide-tip")); @@ -11508,6 +11576,9 @@ tip_frame = Qnil; staticpro (&tip_frame); + last_show_tip_args = Qnil; + staticpro (&last_show_tip_args); + #ifdef USE_MOTIF defsubr (&Sx_file_dialog); #endif