diff options
| author | Gerd Moellmann | 2001-01-04 20:33:06 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2001-01-04 20:33:06 +0000 |
| commit | 06d62053479e90d8b0d83d37bdefc77609f273c5 (patch) | |
| tree | 59e85557f33a88e5bab3b0656f17791983362940 /src | |
| parent | 7948d50a76fe8f96d6783e2efdf9f317c7a603f2 (diff) | |
| download | emacs-06d62053479e90d8b0d83d37bdefc77609f273c5.tar.gz emacs-06d62053479e90d8b0d83d37bdefc77609f273c5.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 113 |
1 files changed, 92 insertions, 21 deletions
diff --git a/src/xfns.c b/src/xfns.c index 5c0d3ec5f6a..b2a5ebb0c2f 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -10347,6 +10347,8 @@ hide_busy_cursor () | |||
| 10347 | 10347 | ||
| 10348 | static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *, | 10348 | static Lisp_Object x_create_tip_frame P_ ((struct x_display_info *, |
| 10349 | Lisp_Object)); | 10349 | Lisp_Object)); |
| 10350 | static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object, | ||
| 10351 | Lisp_Object, int *, int *)); | ||
| 10350 | 10352 | ||
| 10351 | /* The frame of a currently visible tooltip. */ | 10353 | /* The frame of a currently visible tooltip. */ |
| 10352 | 10354 | ||
| @@ -10358,6 +10360,11 @@ Lisp_Object tip_frame; | |||
| 10358 | Lisp_Object tip_timer; | 10360 | Lisp_Object tip_timer; |
| 10359 | Window tip_window; | 10361 | Window tip_window; |
| 10360 | 10362 | ||
| 10363 | /* If non-nil, a vector of 3 elements containing the last args | ||
| 10364 | with which x-show-tip was called. See there. */ | ||
| 10365 | |||
| 10366 | Lisp_Object last_show_tip_args; | ||
| 10367 | |||
| 10361 | 10368 | ||
| 10362 | static Lisp_Object | 10369 | static Lisp_Object |
| 10363 | unwind_create_tip_frame (frame) | 10370 | unwind_create_tip_frame (frame) |
| @@ -10397,6 +10404,7 @@ x_create_tip_frame (dpyinfo, parms) | |||
| 10397 | int count = BINDING_STACK_SIZE (); | 10404 | int count = BINDING_STACK_SIZE (); |
| 10398 | struct gcpro gcpro1, gcpro2, gcpro3; | 10405 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 10399 | struct kboard *kb; | 10406 | struct kboard *kb; |
| 10407 | int face_change_count_before = face_change_count; | ||
| 10400 | 10408 | ||
| 10401 | check_x (); | 10409 | check_x (); |
| 10402 | 10410 | ||
| @@ -10655,11 +10663,55 @@ x_create_tip_frame (dpyinfo, parms) | |||
| 10655 | its display. */ | 10663 | its display. */ |
| 10656 | FRAME_X_DISPLAY_INFO (f)->reference_count++; | 10664 | FRAME_X_DISPLAY_INFO (f)->reference_count++; |
| 10657 | 10665 | ||
| 10666 | /* Setting attributes of faces of the tooltip frame from resources | ||
| 10667 | and similar will increment face_change_count, which leads to the | ||
| 10668 | clearing of all current matrices. Since this isn't necessary | ||
| 10669 | here, avoid it by resetting face_change_count to the value it | ||
| 10670 | had before we created the tip frame. */ | ||
| 10671 | face_change_count = face_change_count_before; | ||
| 10672 | |||
| 10658 | /* Discard the unwind_protect. */ | 10673 | /* Discard the unwind_protect. */ |
| 10659 | return unbind_to (count, frame); | 10674 | return unbind_to (count, frame); |
| 10660 | } | 10675 | } |
| 10661 | 10676 | ||
| 10662 | 10677 | ||
| 10678 | /* Compute where to display tip frame F. PARMS is the list of frame | ||
| 10679 | parameters for F. DX and DY are specified offsets from the current | ||
| 10680 | location of the mouse. Return coordinates relative to the root | ||
| 10681 | window of the display in *ROOT_X, and *ROOT_Y. */ | ||
| 10682 | |||
| 10683 | static void | ||
| 10684 | compute_tip_xy (f, parms, dx, dy, root_x, root_y) | ||
| 10685 | struct frame *f; | ||
| 10686 | Lisp_Object parms, dx, dy; | ||
| 10687 | int *root_x, *root_y; | ||
| 10688 | { | ||
| 10689 | Lisp_Object left, top; | ||
| 10690 | int win_x, win_y; | ||
| 10691 | Window root, child; | ||
| 10692 | unsigned pmask; | ||
| 10693 | |||
| 10694 | /* User-specified position? */ | ||
| 10695 | left = Fcdr (Fassq (Qleft, parms)); | ||
| 10696 | top = Fcdr (Fassq (Qtop, parms)); | ||
| 10697 | |||
| 10698 | /* Move the tooltip window where the mouse pointer is. Resize and | ||
| 10699 | show it. */ | ||
| 10700 | BLOCK_INPUT; | ||
| 10701 | XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, | ||
| 10702 | &root, &child, root_x, root_y, &win_x, &win_y, &pmask); | ||
| 10703 | UNBLOCK_INPUT; | ||
| 10704 | |||
| 10705 | *root_x += XINT (dx); | ||
| 10706 | *root_y += XINT (dy); | ||
| 10707 | |||
| 10708 | if (INTEGERP (left)) | ||
| 10709 | *root_x = XINT (left); | ||
| 10710 | if (INTEGERP (top)) | ||
| 10711 | *root_y = XINT (top); | ||
| 10712 | } | ||
| 10713 | |||
| 10714 | |||
| 10663 | DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, | 10715 | DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, |
| 10664 | "Show STRING in a \"tooltip\" window on frame FRAME.\n\ | 10716 | "Show STRING in a \"tooltip\" window on frame FRAME.\n\ |
| 10665 | A tooltip window is a small X window displaying a string.\n\ | 10717 | A tooltip window is a small X window displaying a string.\n\ |
| @@ -10684,16 +10736,14 @@ DY added (default is -10).") | |||
| 10684 | { | 10736 | { |
| 10685 | struct frame *f; | 10737 | struct frame *f; |
| 10686 | struct window *w; | 10738 | struct window *w; |
| 10687 | Window root, child; | ||
| 10688 | Lisp_Object buffer, top, left; | 10739 | Lisp_Object buffer, top, left; |
| 10740 | int root_x, root_y; | ||
| 10689 | struct buffer *old_buffer; | 10741 | struct buffer *old_buffer; |
| 10690 | struct text_pos pos; | 10742 | struct text_pos pos; |
| 10691 | int i, width, height; | 10743 | int i, width, height; |
| 10692 | int root_x, root_y, win_x, win_y; | ||
| 10693 | unsigned pmask; | ||
| 10694 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 10744 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 10695 | int old_windows_or_buffers_changed = windows_or_buffers_changed; | 10745 | int old_windows_or_buffers_changed = windows_or_buffers_changed; |
| 10696 | int count = specpdl_ptr - specpdl; | 10746 | int count = BINDING_STACK_SIZE (); |
| 10697 | 10747 | ||
| 10698 | specbind (Qinhibit_redisplay, Qt); | 10748 | specbind (Qinhibit_redisplay, Qt); |
| 10699 | 10749 | ||
| @@ -10716,9 +10766,41 @@ DY added (default is -10).") | |||
| 10716 | else | 10766 | else |
| 10717 | CHECK_NUMBER (dy, 6); | 10767 | CHECK_NUMBER (dy, 6); |
| 10718 | 10768 | ||
| 10769 | if (NILP (last_show_tip_args)) | ||
| 10770 | last_show_tip_args = Fmake_vector (make_number (3), Qnil); | ||
| 10771 | |||
| 10772 | if (!NILP (tip_frame)) | ||
| 10773 | { | ||
| 10774 | Lisp_Object last_string = AREF (last_show_tip_args, 0); | ||
| 10775 | Lisp_Object last_frame = AREF (last_show_tip_args, 1); | ||
| 10776 | Lisp_Object last_parms = AREF (last_show_tip_args, 2); | ||
| 10777 | |||
| 10778 | if (EQ (frame, last_frame) | ||
| 10779 | && !NILP (Fequal (last_string, string)) | ||
| 10780 | && !NILP (Fequal (last_parms, parms))) | ||
| 10781 | { | ||
| 10782 | struct frame *f = XFRAME (tip_frame); | ||
| 10783 | |||
| 10784 | /* Only DX and DY have changed. */ | ||
| 10785 | if (!NILP (tip_timer)) | ||
| 10786 | call1 (intern ("cancel-timer"), tip_timer); | ||
| 10787 | |||
| 10788 | BLOCK_INPUT; | ||
| 10789 | compute_tip_xy (f, parms, dx, dy, &root_x, &root_y); | ||
| 10790 | XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 10791 | root_x, root_y - PIXEL_HEIGHT (f)); | ||
| 10792 | UNBLOCK_INPUT; | ||
| 10793 | goto start_timer; | ||
| 10794 | } | ||
| 10795 | } | ||
| 10796 | |||
| 10719 | /* Hide a previous tip, if any. */ | 10797 | /* Hide a previous tip, if any. */ |
| 10720 | Fx_hide_tip (); | 10798 | Fx_hide_tip (); |
| 10721 | 10799 | ||
| 10800 | ASET (last_show_tip_args, 0, string); | ||
| 10801 | ASET (last_show_tip_args, 1, frame); | ||
| 10802 | ASET (last_show_tip_args, 2, parms); | ||
| 10803 | |||
| 10722 | /* Add default values to frame parameters. */ | 10804 | /* Add default values to frame parameters. */ |
| 10723 | if (NILP (Fassq (Qname, parms))) | 10805 | if (NILP (Fassq (Qname, parms))) |
| 10724 | parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms); | 10806 | parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms); |
| @@ -10793,31 +10875,16 @@ DY added (default is -10).") | |||
| 10793 | height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); | 10875 | height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); |
| 10794 | width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); | 10876 | width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); |
| 10795 | 10877 | ||
| 10796 | /* User-specified position? */ | ||
| 10797 | left = Fcdr (Fassq (Qleft, parms)); | ||
| 10798 | top = Fcdr (Fassq (Qtop, parms)); | ||
| 10799 | |||
| 10800 | /* Move the tooltip window where the mouse pointer is. Resize and | 10878 | /* Move the tooltip window where the mouse pointer is. Resize and |
| 10801 | show it. */ | 10879 | show it. */ |
| 10802 | BLOCK_INPUT; | 10880 | compute_tip_xy (f, parms, dx, dy, &root_x, &root_y); |
| 10803 | XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window, | ||
| 10804 | &root, &child, &root_x, &root_y, &win_x, &win_y, &pmask); | ||
| 10805 | UNBLOCK_INPUT; | ||
| 10806 | 10881 | ||
| 10807 | root_x += XINT (dx); | ||
| 10808 | root_y += XINT (dy); | ||
| 10809 | |||
| 10810 | if (INTEGERP (left)) | ||
| 10811 | root_x = XINT (left); | ||
| 10812 | if (INTEGERP (top)) | ||
| 10813 | root_y = XINT (top); | ||
| 10814 | |||
| 10815 | BLOCK_INPUT; | 10882 | BLOCK_INPUT; |
| 10816 | XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 10883 | XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 10817 | root_x, root_y - height, width, height); | 10884 | root_x, root_y - height, width, height); |
| 10818 | XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); | 10885 | XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); |
| 10819 | UNBLOCK_INPUT; | 10886 | UNBLOCK_INPUT; |
| 10820 | 10887 | ||
| 10821 | /* Draw into the window. */ | 10888 | /* Draw into the window. */ |
| 10822 | w->must_be_updated_p = 1; | 10889 | w->must_be_updated_p = 1; |
| 10823 | update_single_window (w, 1); | 10890 | update_single_window (w, 1); |
| @@ -10826,6 +10893,7 @@ DY added (default is -10).") | |||
| 10826 | set_buffer_internal_1 (old_buffer); | 10893 | set_buffer_internal_1 (old_buffer); |
| 10827 | windows_or_buffers_changed = old_windows_or_buffers_changed; | 10894 | windows_or_buffers_changed = old_windows_or_buffers_changed; |
| 10828 | 10895 | ||
| 10896 | start_timer: | ||
| 10829 | /* Let the tip disappear after timeout seconds. */ | 10897 | /* Let the tip disappear after timeout seconds. */ |
| 10830 | tip_timer = call3 (intern ("run-at-time"), timeout, Qnil, | 10898 | tip_timer = call3 (intern ("run-at-time"), timeout, Qnil, |
| 10831 | intern ("x-hide-tip")); | 10899 | intern ("x-hide-tip")); |
| @@ -11508,6 +11576,9 @@ meaning don't clear the cache."); | |||
| 11508 | tip_frame = Qnil; | 11576 | tip_frame = Qnil; |
| 11509 | staticpro (&tip_frame); | 11577 | staticpro (&tip_frame); |
| 11510 | 11578 | ||
| 11579 | last_show_tip_args = Qnil; | ||
| 11580 | staticpro (&last_show_tip_args); | ||
| 11581 | |||
| 11511 | #ifdef USE_MOTIF | 11582 | #ifdef USE_MOTIF |
| 11512 | defsubr (&Sx_file_dialog); | 11583 | defsubr (&Sx_file_dialog); |
| 11513 | #endif | 11584 | #endif |