Mercurial > emacs
comparison src/xfns.c @ 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 | 3088c9745e92 |
children | e6fe439553cf |
comparison
equal
deleted
inserted
replaced
35066:f4b5ec3edf1a | 35067:7ca0048f8615 |
---|---|
10345 Tool tips | 10345 Tool tips |
10346 ***********************************************************************/ | 10346 ***********************************************************************/ |
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 |
10353 Lisp_Object tip_frame; | 10355 Lisp_Object tip_frame; |
10354 | 10356 |
10355 /* If non-nil, a timer started that hides the last tooltip when it | 10357 /* If non-nil, a timer started that hides the last tooltip when it |
10356 fires. */ | 10358 fires. */ |
10357 | 10359 |
10358 Lisp_Object tip_timer; | 10360 Lisp_Object tip_timer; |
10359 Window tip_window; | 10361 Window tip_window; |
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; | |
10360 | 10367 |
10361 | 10368 |
10362 static Lisp_Object | 10369 static Lisp_Object |
10363 unwind_create_tip_frame (frame) | 10370 unwind_create_tip_frame (frame) |
10364 Lisp_Object frame; | 10371 Lisp_Object frame; |
10395 long window_prompting = 0; | 10402 long window_prompting = 0; |
10396 int width, height; | 10403 int width, height; |
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 |
10403 /* Use this general default value to start with until we know if | 10411 /* Use this general default value to start with until we know if |
10404 this frame has a specified name. */ | 10412 this frame has a specified name. */ |
10653 | 10661 |
10654 /* Now that the frame is official, it counts as a reference to | 10662 /* Now that the frame is official, it counts as a reference to |
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); |
10675 } | |
10676 | |
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); | |
10660 } | 10712 } |
10661 | 10713 |
10662 | 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\ |
10682 (string, frame, parms, timeout, dx, dy) | 10734 (string, frame, parms, timeout, dx, dy) |
10683 Lisp_Object string, frame, parms, timeout, dx, dy; | 10735 Lisp_Object string, frame, parms, timeout, dx, dy; |
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 |
10700 GCPRO4 (string, parms, frame, timeout); | 10750 GCPRO4 (string, parms, frame, timeout); |
10701 | 10751 |
10714 if (NILP (dy)) | 10764 if (NILP (dy)) |
10715 dy = make_number (-10); | 10765 dy = make_number (-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 (); |
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); | |
10721 | 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); |
10725 if (NILP (Fassq (Qinternal_border_width, parms))) | 10807 if (NILP (Fassq (Qinternal_border_width, parms))) |
10791 /* Add the frame's internal border to the width and height the X | 10873 /* Add the frame's internal border to the width and height the X |
10792 window should have. */ | 10874 window should have. */ |
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, | 10881 |
10804 &root, &child, &root_x, &root_y, &win_x, &win_y, &pmask); | |
10805 UNBLOCK_INPUT; | |
10806 | |
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); |
10824 | 10891 |
10825 /* Restore original current buffer. */ | 10892 /* Restore original current buffer. */ |
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")); |
10832 | 10900 |
10833 UNGCPRO; | 10901 UNGCPRO; |
11506 tip_timer = Qnil; | 11574 tip_timer = Qnil; |
11507 staticpro (&tip_timer); | 11575 staticpro (&tip_timer); |
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 |
11514 } | 11585 } |
11515 | 11586 |