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