diff options
| author | Yuuki Harano | 2020-08-15 01:13:52 +0900 |
|---|---|---|
| committer | Jeff Walsh | 2020-11-24 12:24:40 +1100 |
| commit | 2dd20b2d7595877b7c733fa52695905c920a9d2a (patch) | |
| tree | 54d6b8a7570088e5dd51e543ba8eb2f22155e2de /src | |
| parent | 51462ce2ccae6461384b44ef7dfbc11d27465be8 (diff) | |
| download | emacs-2dd20b2d7595877b7c733fa52695905c920a9d2a.tar.gz emacs-2dd20b2d7595877b7c733fa52695905c920a9d2a.zip | |
Self-implement tooltip
* src/gtkutil.c (xg_create_frame_widgets): Use popup for tooltip.
* src/pgtkfns.c (unwind_create_tip_frame): Port X code.
(x_create_tip_frame): Re-port X code.
(x_hide_tip): Re-port X code.
(Fx_show_tip): Re-port X code.
(frame_geometry): Get left_pos and top_pos here.
(syms_of_pgtkfns): Add variables for tooltip.
* src/pgtkterm.c (pgtk_set_event_handler): Set event handler for tooltip.
Diffstat (limited to 'src')
| -rw-r--r-- | src/gtkutil.c | 7 | ||||
| -rw-r--r-- | src/pgtkfns.c | 644 | ||||
| -rw-r--r-- | src/pgtkterm.c | 7 |
3 files changed, 601 insertions, 57 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c index 97a8e4a5c1f..3956c581d9d 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -1355,9 +1355,10 @@ xg_create_frame_widgets (struct frame *f) | |||
| 1355 | else | 1355 | else |
| 1356 | wtop = gtk_window_new (type); | 1356 | wtop = gtk_window_new (type); |
| 1357 | #else | 1357 | #else |
| 1358 | if (!NILP(f->parent_frame)) { | 1358 | if (!NILP(f->parent_frame) || f->tooltip) |
| 1359 | type = GTK_WINDOW_POPUP; | 1359 | { |
| 1360 | } | 1360 | type = GTK_WINDOW_POPUP; |
| 1361 | } | ||
| 1361 | wtop = gtk_window_new (type); | 1362 | wtop = gtk_window_new (type); |
| 1362 | gtk_widget_add_events(wtop, GDK_ALL_EVENTS_MASK); | 1363 | gtk_widget_add_events(wtop, GDK_ALL_EVENTS_MASK); |
| 1363 | #endif | 1364 | #endif |
diff --git a/src/pgtkfns.c b/src/pgtkfns.c index a4da3302ef9..53da9b756aa 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c | |||
| @@ -2421,15 +2421,311 @@ If omitted or nil, that stands for the selected frame's display. */) | |||
| 2421 | Tool tips | 2421 | Tool tips |
| 2422 | ***********************************************************************/ | 2422 | ***********************************************************************/ |
| 2423 | 2423 | ||
| 2424 | /* The frame of a currently visible tooltip. */ | 2424 | /* The frame of the currently visible tooltip. */ |
| 2425 | static Lisp_Object tip_frame; | ||
| 2425 | 2426 | ||
| 2426 | Lisp_Object tip_frame; | 2427 | /* The window-system window corresponding to the frame of the |
| 2428 | currently visible tooltip. */ | ||
| 2429 | GtkWidget *tip_window; | ||
| 2427 | 2430 | ||
| 2428 | /* If non-nil, a timer started that hides the last tooltip when it | 2431 | /* A timer that hides or deletes the currently visible tooltip when it |
| 2429 | fires. */ | 2432 | fires. */ |
| 2430 | |||
| 2431 | static Lisp_Object tip_timer; | 2433 | static Lisp_Object tip_timer; |
| 2432 | 2434 | ||
| 2435 | /* STRING argument of last `x-show-tip' call. */ | ||
| 2436 | static Lisp_Object tip_last_string; | ||
| 2437 | |||
| 2438 | /* Normalized FRAME argument of last `x-show-tip' call. */ | ||
| 2439 | static Lisp_Object tip_last_frame; | ||
| 2440 | |||
| 2441 | /* PARMS argument of last `x-show-tip' call. */ | ||
| 2442 | static Lisp_Object tip_last_parms; | ||
| 2443 | |||
| 2444 | |||
| 2445 | static void | ||
| 2446 | unwind_create_tip_frame (Lisp_Object frame) | ||
| 2447 | { | ||
| 2448 | Lisp_Object deleted; | ||
| 2449 | |||
| 2450 | deleted = unwind_create_frame (frame); | ||
| 2451 | if (EQ (deleted, Qt)) | ||
| 2452 | { | ||
| 2453 | tip_window = NULL; | ||
| 2454 | tip_frame = Qnil; | ||
| 2455 | } | ||
| 2456 | } | ||
| 2457 | |||
| 2458 | |||
| 2459 | /* Create a frame for a tooltip on the display described by DPYINFO. | ||
| 2460 | PARMS is a list of frame parameters. TEXT is the string to | ||
| 2461 | display in the tip frame. Value is the frame. | ||
| 2462 | |||
| 2463 | Note that functions called here, esp. gui_default_parameter can | ||
| 2464 | signal errors, for instance when a specified color name is | ||
| 2465 | undefined. We have to make sure that we're in a consistent state | ||
| 2466 | when this happens. */ | ||
| 2467 | |||
| 2468 | static Lisp_Object | ||
| 2469 | x_create_tip_frame (struct pgtk_display_info *dpyinfo, Lisp_Object parms, struct frame *p) | ||
| 2470 | { | ||
| 2471 | struct frame *f; | ||
| 2472 | Lisp_Object frame; | ||
| 2473 | Lisp_Object name; | ||
| 2474 | int width, height; | ||
| 2475 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 2476 | bool face_change_before = face_change; | ||
| 2477 | int x_width = 0, x_height = 0; | ||
| 2478 | |||
| 2479 | if (!dpyinfo->terminal->name) | ||
| 2480 | error ("Terminal is not live, can't create new frames on it"); | ||
| 2481 | |||
| 2482 | parms = Fcopy_alist (parms); | ||
| 2483 | |||
| 2484 | /* Get the name of the frame to use for resource lookup. */ | ||
| 2485 | name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name", | ||
| 2486 | RES_TYPE_STRING); | ||
| 2487 | if (!STRINGP (name) | ||
| 2488 | && !EQ (name, Qunbound) | ||
| 2489 | && !NILP (name)) | ||
| 2490 | error ("Invalid frame name--not a string or nil"); | ||
| 2491 | |||
| 2492 | frame = Qnil; | ||
| 2493 | f = make_frame (false); | ||
| 2494 | f->wants_modeline = false; | ||
| 2495 | XSETFRAME (frame, f); | ||
| 2496 | record_unwind_protect (unwind_create_tip_frame, frame); | ||
| 2497 | |||
| 2498 | f->terminal = dpyinfo->terminal; | ||
| 2499 | |||
| 2500 | /* By setting the output method, we're essentially saying that | ||
| 2501 | the frame is live, as per FRAME_LIVE_P. If we get a signal | ||
| 2502 | from this point on, x_destroy_window might screw up reference | ||
| 2503 | counts etc. */ | ||
| 2504 | f->output_method = output_pgtk; | ||
| 2505 | f->output_data.pgtk = xzalloc (sizeof *f->output_data.pgtk); | ||
| 2506 | #if 0 | ||
| 2507 | f->output_data.pgtk->icon_bitmap = -1; | ||
| 2508 | #endif | ||
| 2509 | FRAME_FONTSET (f) = -1; | ||
| 2510 | f->output_data.pgtk->white_relief.pixel = -1; | ||
| 2511 | f->output_data.pgtk->black_relief.pixel = -1; | ||
| 2512 | |||
| 2513 | f->tooltip = true; | ||
| 2514 | fset_icon_name (f, Qnil); | ||
| 2515 | FRAME_DISPLAY_INFO (f) = dpyinfo; | ||
| 2516 | f->output_data.pgtk->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; | ||
| 2517 | f->output_data.pgtk->explicit_parent = false; | ||
| 2518 | |||
| 2519 | /* These colors will be set anyway later, but it's important | ||
| 2520 | to get the color reference counts right, so initialize them! */ | ||
| 2521 | { | ||
| 2522 | Lisp_Object black; | ||
| 2523 | |||
| 2524 | /* Function x_decode_color can signal an error. Make | ||
| 2525 | sure to initialize color slots so that we won't try | ||
| 2526 | to free colors we haven't allocated. */ | ||
| 2527 | FRAME_FOREGROUND_PIXEL (f) = -1; | ||
| 2528 | FRAME_BACKGROUND_PIXEL (f) = -1; | ||
| 2529 | f->output_data.pgtk->border_pixel = -1; | ||
| 2530 | |||
| 2531 | black = build_string ("black"); | ||
| 2532 | FRAME_FOREGROUND_PIXEL (f) | ||
| 2533 | = x_decode_color (f, black, BLACK_PIX_DEFAULT (f)); | ||
| 2534 | FRAME_BACKGROUND_PIXEL (f) | ||
| 2535 | = x_decode_color (f, black, BLACK_PIX_DEFAULT (f)); | ||
| 2536 | f->output_data.pgtk->border_pixel | ||
| 2537 | = x_decode_color (f, black, BLACK_PIX_DEFAULT (f)); | ||
| 2538 | } | ||
| 2539 | |||
| 2540 | /* Set the name; the functions to which we pass f expect the name to | ||
| 2541 | be set. */ | ||
| 2542 | if (EQ (name, Qunbound) || NILP (name)) | ||
| 2543 | { | ||
| 2544 | fset_name (f, build_string (dpyinfo->x_id_name)); | ||
| 2545 | f->explicit_name = false; | ||
| 2546 | } | ||
| 2547 | else | ||
| 2548 | { | ||
| 2549 | fset_name (f, name); | ||
| 2550 | f->explicit_name = true; | ||
| 2551 | /* use the frame's title when getting resources for this frame. */ | ||
| 2552 | specbind (Qx_resource_name, name); | ||
| 2553 | } | ||
| 2554 | |||
| 2555 | register_font_driver (&ftcrfont_driver, f); | ||
| 2556 | #ifdef HAVE_HARFBUZZ | ||
| 2557 | register_font_driver (&ftcrhbfont_driver, f); | ||
| 2558 | #endif /* HAVE_HARFBUZZ */ | ||
| 2559 | |||
| 2560 | image_cache_refcount = | ||
| 2561 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 2562 | #ifdef GLYPH_DEBUG | ||
| 2563 | dpyinfo_refcount = dpyinfo->reference_count; | ||
| 2564 | #endif /* GLYPH_DEBUG */ | ||
| 2565 | |||
| 2566 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | ||
| 2567 | "fontBackend", "FontBackend", RES_TYPE_STRING); | ||
| 2568 | |||
| 2569 | /* Extract the window parameters from the supplied values that are | ||
| 2570 | needed to determine window geometry. */ | ||
| 2571 | pgtk_default_font_parameter (f, parms); | ||
| 2572 | |||
| 2573 | gui_default_parameter (f, parms, Qborder_width, make_fixnum (0), | ||
| 2574 | "borderWidth", "BorderWidth", RES_TYPE_NUMBER); | ||
| 2575 | |||
| 2576 | /* This defaults to 2 in order to match xterm. We recognize either | ||
| 2577 | internalBorderWidth or internalBorder (which is what xterm calls | ||
| 2578 | it). */ | ||
| 2579 | if (NILP (Fassq (Qinternal_border_width, parms))) | ||
| 2580 | { | ||
| 2581 | Lisp_Object value; | ||
| 2582 | |||
| 2583 | value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width, | ||
| 2584 | "internalBorder", "internalBorder", | ||
| 2585 | RES_TYPE_NUMBER); | ||
| 2586 | if (! EQ (value, Qunbound)) | ||
| 2587 | parms = Fcons (Fcons (Qinternal_border_width, value), | ||
| 2588 | parms); | ||
| 2589 | } | ||
| 2590 | |||
| 2591 | gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1), | ||
| 2592 | "internalBorderWidth", "internalBorderWidth", | ||
| 2593 | RES_TYPE_NUMBER); | ||
| 2594 | gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0), | ||
| 2595 | NULL, NULL, RES_TYPE_NUMBER); | ||
| 2596 | gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0), | ||
| 2597 | NULL, NULL, RES_TYPE_NUMBER); | ||
| 2598 | |||
| 2599 | /* Also do the stuff which must be set before the window exists. */ | ||
| 2600 | gui_default_parameter (f, parms, Qforeground_color, build_string ("black"), | ||
| 2601 | "foreground", "Foreground", RES_TYPE_STRING); | ||
| 2602 | gui_default_parameter (f, parms, Qbackground_color, build_string ("white"), | ||
| 2603 | "background", "Background", RES_TYPE_STRING); | ||
| 2604 | gui_default_parameter (f, parms, Qmouse_color, build_string ("black"), | ||
| 2605 | "pointerColor", "Foreground", RES_TYPE_STRING); | ||
| 2606 | gui_default_parameter (f, parms, Qcursor_color, build_string ("black"), | ||
| 2607 | "cursorColor", "Foreground", RES_TYPE_STRING); | ||
| 2608 | gui_default_parameter (f, parms, Qborder_color, build_string ("black"), | ||
| 2609 | "borderColor", "BorderColor", RES_TYPE_STRING); | ||
| 2610 | gui_default_parameter (f, parms, Qno_special_glyphs, Qnil, | ||
| 2611 | NULL, NULL, RES_TYPE_BOOLEAN); | ||
| 2612 | |||
| 2613 | /* Init faces before gui_default_parameter is called for the | ||
| 2614 | scroll-bar-width parameter because otherwise we end up in | ||
| 2615 | init_iterator with a null face cache, which should not happen. */ | ||
| 2616 | init_frame_faces (f); | ||
| 2617 | |||
| 2618 | f->output_data.pgtk->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; | ||
| 2619 | |||
| 2620 | gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil, | ||
| 2621 | "inhibitDoubleBuffering", "InhibitDoubleBuffering", | ||
| 2622 | RES_TYPE_BOOLEAN); | ||
| 2623 | |||
| 2624 | gui_figure_window_size (f, parms, false, false, &x_width, &x_height); | ||
| 2625 | |||
| 2626 | xg_create_frame_widgets (f); | ||
| 2627 | pgtk_set_event_handler (f); | ||
| 2628 | tip_window = FRAME_GTK_OUTER_WIDGET (f); | ||
| 2629 | gtk_window_set_transient_for (GTK_WINDOW (tip_window), | ||
| 2630 | GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (p))); | ||
| 2631 | gtk_window_set_attached_to (GTK_WINDOW (tip_window), FRAME_GTK_WIDGET (p)); | ||
| 2632 | gtk_window_set_destroy_with_parent (GTK_WINDOW (tip_window), TRUE); | ||
| 2633 | gtk_window_set_decorated (GTK_WINDOW (tip_window), FALSE); | ||
| 2634 | gtk_window_set_type_hint (GTK_WINDOW (tip_window), GDK_WINDOW_TYPE_HINT_TOOLTIP); | ||
| 2635 | f->output_data.pgtk->current_cursor = f->output_data.pgtk->text_cursor; | ||
| 2636 | gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f)); | ||
| 2637 | gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)), | ||
| 2638 | f->output_data.pgtk->current_cursor); | ||
| 2639 | |||
| 2640 | #if 0 | ||
| 2641 | x_make_gc (f); | ||
| 2642 | #endif | ||
| 2643 | |||
| 2644 | gui_default_parameter (f, parms, Qauto_raise, Qnil, | ||
| 2645 | "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN); | ||
| 2646 | gui_default_parameter (f, parms, Qauto_lower, Qnil, | ||
| 2647 | "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN); | ||
| 2648 | gui_default_parameter (f, parms, Qcursor_type, Qbox, | ||
| 2649 | "cursorType", "CursorType", RES_TYPE_SYMBOL); | ||
| 2650 | gui_default_parameter (f, parms, Qalpha, Qnil, | ||
| 2651 | "alpha", "Alpha", RES_TYPE_NUMBER); | ||
| 2652 | |||
| 2653 | /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. | ||
| 2654 | Change will not be effected unless different from the current | ||
| 2655 | FRAME_LINES (f). */ | ||
| 2656 | width = FRAME_COLS (f); | ||
| 2657 | height = FRAME_LINES (f); | ||
| 2658 | SET_FRAME_COLS (f, 0); | ||
| 2659 | SET_FRAME_LINES (f, 0); | ||
| 2660 | change_frame_size (f, width, height, true, false, false, false); | ||
| 2661 | |||
| 2662 | /* Add `tooltip' frame parameter's default value. */ | ||
| 2663 | if (NILP (Fframe_parameter (frame, Qtooltip))) | ||
| 2664 | { | ||
| 2665 | AUTO_FRAME_ARG (arg, Qtooltip, Qt); | ||
| 2666 | Fmodify_frame_parameters (frame, arg); | ||
| 2667 | } | ||
| 2668 | |||
| 2669 | /* FIXME - can this be done in a similar way to normal frames? | ||
| 2670 | https://lists.gnu.org/r/emacs-devel/2007-10/msg00641.html */ | ||
| 2671 | |||
| 2672 | /* Set the `display-type' frame parameter before setting up faces. */ | ||
| 2673 | { | ||
| 2674 | Lisp_Object disptype; | ||
| 2675 | |||
| 2676 | disptype = intern ("color"); | ||
| 2677 | |||
| 2678 | if (NILP (Fframe_parameter (frame, Qdisplay_type))) | ||
| 2679 | { | ||
| 2680 | AUTO_FRAME_ARG (arg, Qdisplay_type, disptype); | ||
| 2681 | Fmodify_frame_parameters (frame, arg); | ||
| 2682 | } | ||
| 2683 | } | ||
| 2684 | |||
| 2685 | /* Set up faces after all frame parameters are known. This call | ||
| 2686 | also merges in face attributes specified for new frames. | ||
| 2687 | |||
| 2688 | Frame parameters may be changed if .Xdefaults contains | ||
| 2689 | specifications for the default font. For example, if there is an | ||
| 2690 | `Emacs.default.attributeBackground: pink', the `background-color' | ||
| 2691 | attribute of the frame get's set, which let's the internal border | ||
| 2692 | of the tooltip frame appear in pink. Prevent this. */ | ||
| 2693 | { | ||
| 2694 | Lisp_Object bg = Fframe_parameter (frame, Qbackground_color); | ||
| 2695 | |||
| 2696 | call2 (Qface_set_after_frame_default, frame, Qnil); | ||
| 2697 | |||
| 2698 | if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) | ||
| 2699 | { | ||
| 2700 | AUTO_FRAME_ARG (arg, Qbackground_color, bg); | ||
| 2701 | Fmodify_frame_parameters (frame, arg); | ||
| 2702 | } | ||
| 2703 | } | ||
| 2704 | |||
| 2705 | f->no_split = true; | ||
| 2706 | |||
| 2707 | /* Now that the frame will be official, it counts as a reference to | ||
| 2708 | its display and terminal. */ | ||
| 2709 | FRAME_DISPLAY_INFO (f)->reference_count++; | ||
| 2710 | f->terminal->reference_count++; | ||
| 2711 | |||
| 2712 | /* It is now ok to make the frame official even if we get an error | ||
| 2713 | below. And the frame needs to be on Vframe_list or making it | ||
| 2714 | visible won't work. */ | ||
| 2715 | Vframe_list = Fcons (frame, Vframe_list); | ||
| 2716 | f->can_set_window_size = true; | ||
| 2717 | |||
| 2718 | /* Setting attributes of faces of the tooltip frame from resources | ||
| 2719 | and similar will set face_change, which leads to the clearing of | ||
| 2720 | all current matrices. Since this isn't necessary here, avoid it | ||
| 2721 | by resetting face_change to the value it had before we created | ||
| 2722 | the tip frame. */ | ||
| 2723 | face_change = face_change_before; | ||
| 2724 | |||
| 2725 | /* Discard the unwind_protect. */ | ||
| 2726 | return unbind_to (count, frame); | ||
| 2727 | } | ||
| 2728 | |||
| 2433 | /* Compute where to display tip frame F. PARMS is the list of frame | 2729 | /* Compute where to display tip frame F. PARMS is the list of frame |
| 2434 | parameters for F. DX and DY are specified offsets from the current | 2730 | parameters for F. DX and DY are specified offsets from the current |
| 2435 | location of the mouse. WIDTH and HEIGHT are the width and height | 2731 | location of the mouse. WIDTH and HEIGHT are the width and height |
| @@ -2546,9 +2842,20 @@ x_hide_tip (bool delete) | |||
| 2546 | tip_timer = Qnil; | 2842 | tip_timer = Qnil; |
| 2547 | } | 2843 | } |
| 2548 | 2844 | ||
| 2549 | if (NILP (tip_frame) | 2845 | /* Any GTK+ system tooltip can be found via the x_output structure of |
| 2550 | || (!delete && FRAMEP (tip_frame) | 2846 | tip_last_frame, provided that frame is still live. Any Emacs |
| 2847 | tooltip is found via the tip_frame variable. Note that the current | ||
| 2848 | value of x_gtk_use_system_tooltips might not be the same as used | ||
| 2849 | for the tooltip we have to hide, see Bug#30399. */ | ||
| 2850 | if ((NILP (tip_last_frame) && NILP (tip_frame)) | ||
| 2851 | || (!x_gtk_use_system_tooltips | ||
| 2852 | && !delete | ||
| 2853 | && FRAMEP (tip_frame) | ||
| 2854 | && FRAME_LIVE_P (XFRAME (tip_frame)) | ||
| 2551 | && !FRAME_VISIBLE_P (XFRAME (tip_frame)))) | 2855 | && !FRAME_VISIBLE_P (XFRAME (tip_frame)))) |
| 2856 | /* Either there's no tooltip to hide or it's an already invisible | ||
| 2857 | Emacs tooltip and we don't want to change its type. Return | ||
| 2858 | quickly. */ | ||
| 2552 | return Qnil; | 2859 | return Qnil; |
| 2553 | else | 2860 | else |
| 2554 | { | 2861 | { |
| @@ -2559,29 +2866,46 @@ x_hide_tip (bool delete) | |||
| 2559 | specbind (Qinhibit_redisplay, Qt); | 2866 | specbind (Qinhibit_redisplay, Qt); |
| 2560 | specbind (Qinhibit_quit, Qt); | 2867 | specbind (Qinhibit_quit, Qt); |
| 2561 | 2868 | ||
| 2562 | { | 2869 | /* Try to hide the GTK+ system tip first. */ |
| 2563 | /* When using system tooltip, tip_frame is the Emacs frame on | 2870 | if (FRAMEP (tip_last_frame)) |
| 2564 | which the tip is shown. */ | 2871 | { |
| 2565 | struct frame *f = XFRAME (tip_frame); | 2872 | struct frame *f = XFRAME (tip_last_frame); |
| 2566 | 2873 | ||
| 2567 | if (FRAME_LIVE_P (f) && xg_hide_tooltip (f)) | 2874 | if (FRAME_LIVE_P (f)) |
| 2568 | { | 2875 | { |
| 2569 | tip_frame = Qnil; | 2876 | if (xg_hide_tooltip (f)) |
| 2570 | was_open = Qt; | 2877 | was_open = Qt; |
| 2571 | } | 2878 | } |
| 2572 | } | 2879 | } |
| 2573 | 2880 | ||
| 2881 | /* When using GTK+ system tooltips (compare Bug#41200) reset | ||
| 2882 | tip_last_frame. It will be reassigned when showing the next | ||
| 2883 | GTK+ system tooltip. */ | ||
| 2884 | if (x_gtk_use_system_tooltips) | ||
| 2885 | tip_last_frame = Qnil; | ||
| 2886 | |||
| 2887 | /* Now look whether there's an Emacs tip around. */ | ||
| 2574 | if (FRAMEP (tip_frame)) | 2888 | if (FRAMEP (tip_frame)) |
| 2575 | { | 2889 | { |
| 2576 | if (delete) | 2890 | struct frame *f = XFRAME (tip_frame); |
| 2891 | |||
| 2892 | if (FRAME_LIVE_P (f)) | ||
| 2577 | { | 2893 | { |
| 2578 | delete_frame (tip_frame, Qnil); | 2894 | if (delete || x_gtk_use_system_tooltips) |
| 2579 | tip_frame = Qnil; | 2895 | { |
| 2896 | /* Delete the Emacs tooltip frame when DELETE is true | ||
| 2897 | or we change the tooltip type from an Emacs one to | ||
| 2898 | a GTK+ system one. */ | ||
| 2899 | delete_frame (tip_frame, Qnil); | ||
| 2900 | tip_frame = Qnil; | ||
| 2901 | } | ||
| 2902 | else | ||
| 2903 | pgtk_make_frame_invisible (f); | ||
| 2904 | |||
| 2905 | was_open = Qt; | ||
| 2580 | } | 2906 | } |
| 2581 | else | 2907 | else |
| 2582 | pgtk_make_frame_invisible (XFRAME (tip_frame)); | 2908 | tip_frame = Qnil; |
| 2583 | |||
| 2584 | was_open = Qt; | ||
| 2585 | } | 2909 | } |
| 2586 | else | 2910 | else |
| 2587 | tip_frame = Qnil; | 2911 | tip_frame = Qnil; |
| @@ -2623,10 +2947,17 @@ Text larger than the specified size is clipped. */) | |||
| 2623 | (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, | 2947 | (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, |
| 2624 | Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy) | 2948 | Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy) |
| 2625 | { | 2949 | { |
| 2626 | struct frame *f; | 2950 | struct frame *f, *tip_f; |
| 2951 | struct window *w; | ||
| 2627 | int root_x, root_y; | 2952 | int root_x, root_y; |
| 2953 | struct buffer *old_buffer; | ||
| 2954 | struct text_pos pos; | ||
| 2628 | int width, height; | 2955 | int width, height; |
| 2956 | int old_windows_or_buffers_changed = windows_or_buffers_changed; | ||
| 2629 | ptrdiff_t count = SPECPDL_INDEX (); | 2957 | ptrdiff_t count = SPECPDL_INDEX (); |
| 2958 | ptrdiff_t count_1; | ||
| 2959 | Lisp_Object window, size, tip_buf; | ||
| 2960 | AUTO_STRING (tip, " *tip*"); | ||
| 2630 | 2961 | ||
| 2631 | specbind (Qinhibit_redisplay, Qt); | 2962 | specbind (Qinhibit_redisplay, Qt); |
| 2632 | 2963 | ||
| @@ -2634,7 +2965,10 @@ Text larger than the specified size is clipped. */) | |||
| 2634 | if (SCHARS (string) == 0) | 2965 | if (SCHARS (string) == 0) |
| 2635 | string = make_unibyte_string (" ", 1); | 2966 | string = make_unibyte_string (" ", 1); |
| 2636 | 2967 | ||
| 2968 | if (NILP (frame)) | ||
| 2969 | frame = selected_frame; | ||
| 2637 | f = decode_window_system_frame (frame); | 2970 | f = decode_window_system_frame (frame); |
| 2971 | |||
| 2638 | if (NILP (timeout)) | 2972 | if (NILP (timeout)) |
| 2639 | timeout = make_fixnum (5); | 2973 | timeout = make_fixnum (5); |
| 2640 | else | 2974 | else |
| @@ -2643,34 +2977,218 @@ Text larger than the specified size is clipped. */) | |||
| 2643 | if (NILP (dx)) | 2977 | if (NILP (dx)) |
| 2644 | dx = make_fixnum (5); | 2978 | dx = make_fixnum (5); |
| 2645 | else | 2979 | else |
| 2646 | CHECK_NUMBER (dx); | 2980 | CHECK_FIXNUM (dx); |
| 2647 | 2981 | ||
| 2648 | if (NILP (dy)) | 2982 | if (NILP (dy)) |
| 2649 | dy = make_fixnum (-10); | 2983 | dy = make_fixnum (-10); |
| 2650 | else | 2984 | else |
| 2651 | CHECK_NUMBER (dy); | 2985 | CHECK_FIXNUM (dy); |
| 2652 | 2986 | ||
| 2653 | { | 2987 | if (x_gtk_use_system_tooltips) |
| 2654 | bool ok; | 2988 | { |
| 2989 | bool ok; | ||
| 2655 | 2990 | ||
| 2656 | /* Hide a previous tip, if any. */ | 2991 | /* Hide a previous tip, if any. */ |
| 2657 | Fx_hide_tip (); | 2992 | Fx_hide_tip (); |
| 2658 | 2993 | ||
| 2659 | block_input (); | 2994 | block_input (); |
| 2660 | ok = xg_prepare_tooltip (f, string, &width, &height); | 2995 | ok = xg_prepare_tooltip (f, string, &width, &height); |
| 2661 | if (ok) | 2996 | if (ok) |
| 2662 | { | 2997 | { |
| 2663 | compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); | 2998 | compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); |
| 2664 | xg_show_tooltip (f, root_x, root_y); | 2999 | xg_show_tooltip (f, root_x, root_y); |
| 2665 | /* This is used in Fx_hide_tip. */ | 3000 | tip_last_frame = frame; |
| 2666 | XSETFRAME (tip_frame, f); | 3001 | } |
| 2667 | } | 3002 | |
| 2668 | unblock_input (); | 3003 | unblock_input (); |
| 2669 | if (ok) | 3004 | if (ok) goto start_timer; |
| 2670 | goto start_timer; | 3005 | } |
| 2671 | } | 3006 | |
| 3007 | if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame))) | ||
| 3008 | { | ||
| 3009 | if (FRAME_VISIBLE_P (XFRAME (tip_frame)) | ||
| 3010 | && EQ (frame, tip_last_frame) | ||
| 3011 | && !NILP (Fequal_including_properties (tip_last_string, string)) | ||
| 3012 | && !NILP (Fequal (tip_last_parms, parms))) | ||
| 3013 | { | ||
| 3014 | /* Only DX and DY have changed. */ | ||
| 3015 | tip_f = XFRAME (tip_frame); | ||
| 3016 | if (!NILP (tip_timer)) | ||
| 3017 | { | ||
| 3018 | call1 (Qcancel_timer, tip_timer); | ||
| 3019 | tip_timer = Qnil; | ||
| 3020 | } | ||
| 3021 | |||
| 3022 | block_input (); | ||
| 3023 | compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f), | ||
| 3024 | FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y); | ||
| 3025 | gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y); | ||
| 3026 | unblock_input (); | ||
| 3027 | |||
| 3028 | goto start_timer; | ||
| 3029 | } | ||
| 3030 | else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame)) | ||
| 3031 | { | ||
| 3032 | bool delete = false; | ||
| 3033 | Lisp_Object tail, elt, parm, last; | ||
| 3034 | |||
| 3035 | /* Check if every parameter in PARMS has the same value in | ||
| 3036 | tip_last_parms. This may destruct tip_last_parms which, | ||
| 3037 | however, will be recreated below. */ | ||
| 3038 | for (tail = parms; CONSP (tail); tail = XCDR (tail)) | ||
| 3039 | { | ||
| 3040 | elt = XCAR (tail); | ||
| 3041 | parm = Fcar (elt); | ||
| 3042 | /* The left, top, right and bottom parameters are handled | ||
| 3043 | by compute_tip_xy so they can be ignored here. */ | ||
| 3044 | if (!EQ (parm, Qleft) && !EQ (parm, Qtop) | ||
| 3045 | && !EQ (parm, Qright) && !EQ (parm, Qbottom)) | ||
| 3046 | { | ||
| 3047 | last = Fassq (parm, tip_last_parms); | ||
| 3048 | if (NILP (Fequal (Fcdr (elt), Fcdr (last)))) | ||
| 3049 | { | ||
| 3050 | /* We lost, delete the old tooltip. */ | ||
| 3051 | delete = true; | ||
| 3052 | break; | ||
| 3053 | } | ||
| 3054 | else | ||
| 3055 | tip_last_parms = | ||
| 3056 | call2 (Qassq_delete_all, parm, tip_last_parms); | ||
| 3057 | } | ||
| 3058 | else | ||
| 3059 | tip_last_parms = | ||
| 3060 | call2 (Qassq_delete_all, parm, tip_last_parms); | ||
| 3061 | } | ||
| 3062 | |||
| 3063 | /* Now check if every parameter in what is left of | ||
| 3064 | tip_last_parms with a non-nil value has an association in | ||
| 3065 | PARMS. */ | ||
| 3066 | for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail)) | ||
| 3067 | { | ||
| 3068 | elt = XCAR (tail); | ||
| 3069 | parm = Fcar (elt); | ||
| 3070 | if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright) | ||
| 3071 | && !EQ (parm, Qbottom) && !NILP (Fcdr (elt))) | ||
| 3072 | { | ||
| 3073 | /* We lost, delete the old tooltip. */ | ||
| 3074 | delete = true; | ||
| 3075 | break; | ||
| 3076 | } | ||
| 3077 | } | ||
| 3078 | |||
| 3079 | x_hide_tip (delete); | ||
| 3080 | } | ||
| 3081 | else | ||
| 3082 | x_hide_tip (true); | ||
| 3083 | } | ||
| 3084 | else | ||
| 3085 | x_hide_tip (true); | ||
| 3086 | |||
| 3087 | tip_last_frame = frame; | ||
| 3088 | tip_last_string = string; | ||
| 3089 | tip_last_parms = parms; | ||
| 2672 | 3090 | ||
| 2673 | start_timer: | 3091 | if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame))) |
| 3092 | { | ||
| 3093 | /* Add default values to frame parameters. */ | ||
| 3094 | if (NILP (Fassq (Qname, parms))) | ||
| 3095 | parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms); | ||
| 3096 | if (NILP (Fassq (Qinternal_border_width, parms))) | ||
| 3097 | parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), parms); | ||
| 3098 | if (NILP (Fassq (Qborder_width, parms))) | ||
| 3099 | parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms); | ||
| 3100 | if (NILP (Fassq (Qborder_color, parms))) | ||
| 3101 | parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms); | ||
| 3102 | if (NILP (Fassq (Qbackground_color, parms))) | ||
| 3103 | parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")), | ||
| 3104 | parms); | ||
| 3105 | |||
| 3106 | /* Create a frame for the tooltip, and record it in the global | ||
| 3107 | variable tip_frame. */ | ||
| 3108 | if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, f))) | ||
| 3109 | /* Creating the tip frame failed. */ | ||
| 3110 | return unbind_to (count, Qnil); | ||
| 3111 | } | ||
| 3112 | |||
| 3113 | tip_f = XFRAME (tip_frame); | ||
| 3114 | window = FRAME_ROOT_WINDOW (tip_f); | ||
| 3115 | tip_buf = Fget_buffer_create (tip); | ||
| 3116 | /* We will mark the tip window a "pseudo-window" below, and such | ||
| 3117 | windows cannot have display margins. */ | ||
| 3118 | bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0)); | ||
| 3119 | bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0)); | ||
| 3120 | set_window_buffer (window, tip_buf, false, false); | ||
| 3121 | w = XWINDOW (window); | ||
| 3122 | w->pseudo_window_p = true; | ||
| 3123 | |||
| 3124 | /* Set up the frame's root window. Note: The following code does not | ||
| 3125 | try to size the window or its frame correctly. Its only purpose is | ||
| 3126 | to make the subsequent text size calculations work. The right | ||
| 3127 | sizes should get installed when the toolkit gets back to us. */ | ||
| 3128 | w->left_col = 0; | ||
| 3129 | w->top_line = 0; | ||
| 3130 | w->pixel_left = 0; | ||
| 3131 | w->pixel_top = 0; | ||
| 3132 | |||
| 3133 | if (CONSP (Vx_max_tooltip_size) | ||
| 3134 | && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX) | ||
| 3135 | && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX)) | ||
| 3136 | { | ||
| 3137 | w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size)); | ||
| 3138 | w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size)); | ||
| 3139 | } | ||
| 3140 | else | ||
| 3141 | { | ||
| 3142 | w->total_cols = 80; | ||
| 3143 | w->total_lines = 40; | ||
| 3144 | } | ||
| 3145 | |||
| 3146 | w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f); | ||
| 3147 | w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f); | ||
| 3148 | FRAME_TOTAL_COLS (tip_f) = w->total_cols; | ||
| 3149 | adjust_frame_glyphs (tip_f); | ||
| 3150 | |||
| 3151 | /* Insert STRING into root window's buffer and fit the frame to the | ||
| 3152 | buffer. */ | ||
| 3153 | count_1 = SPECPDL_INDEX (); | ||
| 3154 | old_buffer = current_buffer; | ||
| 3155 | set_buffer_internal_1 (XBUFFER (w->contents)); | ||
| 3156 | bset_truncate_lines (current_buffer, Qnil); | ||
| 3157 | specbind (Qinhibit_read_only, Qt); | ||
| 3158 | specbind (Qinhibit_modification_hooks, Qt); | ||
| 3159 | specbind (Qinhibit_point_motion_hooks, Qt); | ||
| 3160 | Ferase_buffer (); | ||
| 3161 | Finsert (1, &string); | ||
| 3162 | clear_glyph_matrix (w->desired_matrix); | ||
| 3163 | clear_glyph_matrix (w->current_matrix); | ||
| 3164 | SET_TEXT_POS (pos, BEGV, BEGV_BYTE); | ||
| 3165 | try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); | ||
| 3166 | /* Calculate size of tooltip window. */ | ||
| 3167 | size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil, | ||
| 3168 | make_fixnum (w->pixel_height), Qnil); | ||
| 3169 | /* Add the frame's internal border to calculated size. */ | ||
| 3170 | width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); | ||
| 3171 | height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f); | ||
| 3172 | |||
| 3173 | /* Calculate position of tooltip frame. */ | ||
| 3174 | compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y); | ||
| 3175 | |||
| 3176 | /* Show tooltip frame. */ | ||
| 3177 | block_input (); | ||
| 3178 | gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), width, height); | ||
| 3179 | gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y); | ||
| 3180 | unblock_input (); | ||
| 3181 | |||
| 3182 | pgtk_cr_update_surface_desired_size (tip_f, width, height); | ||
| 3183 | |||
| 3184 | w->must_be_updated_p = true; | ||
| 3185 | update_single_window (w); | ||
| 3186 | flush_frame (tip_f); | ||
| 3187 | set_buffer_internal_1 (old_buffer); | ||
| 3188 | unbind_to (count_1, Qnil); | ||
| 3189 | windows_or_buffers_changed = old_windows_or_buffers_changed; | ||
| 3190 | |||
| 3191 | start_timer: | ||
| 2674 | /* Let the tip disappear after timeout seconds. */ | 3192 | /* Let the tip disappear after timeout seconds. */ |
| 2675 | tip_timer = call3 (intern ("run-at-time"), timeout, Qnil, | 3193 | tip_timer = call3 (intern ("run-at-time"), timeout, Qnil, |
| 2676 | intern ("x-hide-tip")); | 3194 | intern ("x-hide-tip")); |
| @@ -2705,10 +3223,16 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 2705 | int native_height = FRAME_PIXEL_HEIGHT (f); | 3223 | int native_height = FRAME_PIXEL_HEIGHT (f); |
| 2706 | int outer_width = native_width + 2 * border; | 3224 | int outer_width = native_width + 2 * border; |
| 2707 | int outer_height = native_height + 2 * border + title_height; | 3225 | int outer_height = native_height + 2 * border + title_height; |
| 2708 | int native_left = f->left_pos + border; | 3226 | |
| 2709 | int native_top = f->top_pos + border + title_height; | 3227 | /* Get these here because they can't be got in configure_event(). */ |
| 2710 | int native_right = f->left_pos + outer_width - border; | 3228 | int left_pos, top_pos; |
| 2711 | int native_bottom = f->top_pos + outer_height - border; | 3229 | gtk_window_get_position (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), |
| 3230 | &left_pos, &top_pos); | ||
| 3231 | |||
| 3232 | int native_left = left_pos + border; | ||
| 3233 | int native_top = top_pos + border + title_height; | ||
| 3234 | int native_right = left_pos + outer_width - border; | ||
| 3235 | int native_bottom = top_pos + outer_height - border; | ||
| 2712 | int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f); | 3236 | int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f); |
| 2713 | int tab_bar_height = 0, tab_bar_width = 0; | 3237 | int tab_bar_height = 0, tab_bar_width = 0; |
| 2714 | int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f); | 3238 | int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f); |
| @@ -2722,9 +3246,9 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 2722 | 3246 | ||
| 2723 | /* Construct list. */ | 3247 | /* Construct list. */ |
| 2724 | if (EQ (attribute, Qouter_edges)) | 3248 | if (EQ (attribute, Qouter_edges)) |
| 2725 | return list4 (make_fixnum (f->left_pos), make_fixnum (f->top_pos), | 3249 | return list4 (make_fixnum (left_pos), make_fixnum (top_pos), |
| 2726 | make_fixnum (f->left_pos + outer_width), | 3250 | make_fixnum (left_pos + outer_width), |
| 2727 | make_fixnum (f->top_pos + outer_height)); | 3251 | make_fixnum (top_pos + outer_height)); |
| 2728 | else if (EQ (attribute, Qnative_edges)) | 3252 | else if (EQ (attribute, Qnative_edges)) |
| 2729 | return list4 (make_fixnum (native_left), make_fixnum (native_top), | 3253 | return list4 (make_fixnum (native_left), make_fixnum (native_top), |
| 2730 | make_fixnum (native_right), make_fixnum (native_bottom)); | 3254 | make_fixnum (native_right), make_fixnum (native_bottom)); |
| @@ -2738,8 +3262,8 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 2738 | else | 3262 | else |
| 2739 | return | 3263 | return |
| 2740 | list (Fcons (Qouter_position, | 3264 | list (Fcons (Qouter_position, |
| 2741 | Fcons (make_fixnum (f->left_pos), | 3265 | Fcons (make_fixnum (left_pos), |
| 2742 | make_fixnum (f->top_pos))), | 3266 | make_fixnum (top_pos))), |
| 2743 | Fcons (Qouter_size, | 3267 | Fcons (Qouter_size, |
| 2744 | Fcons (make_fixnum (outer_width), | 3268 | Fcons (make_fixnum (outer_width), |
| 2745 | make_fixnum (outer_height))), | 3269 | make_fixnum (outer_height))), |
| @@ -3161,10 +3685,16 @@ be used as the image of the icon representing the frame. */); | |||
| 3161 | as_script = Qnil; | 3685 | as_script = Qnil; |
| 3162 | as_result = 0; | 3686 | as_result = 0; |
| 3163 | 3687 | ||
| 3164 | tip_frame = Qnil; | ||
| 3165 | staticpro (&tip_frame); | ||
| 3166 | tip_timer = Qnil; | 3688 | tip_timer = Qnil; |
| 3167 | staticpro (&tip_timer); | 3689 | staticpro (&tip_timer); |
| 3690 | tip_frame = Qnil; | ||
| 3691 | staticpro (&tip_frame); | ||
| 3692 | tip_last_frame = Qnil; | ||
| 3693 | staticpro (&tip_last_frame); | ||
| 3694 | tip_last_string = Qnil; | ||
| 3695 | staticpro (&tip_last_string); | ||
| 3696 | tip_last_parms = Qnil; | ||
| 3697 | staticpro (&tip_last_parms); | ||
| 3168 | 3698 | ||
| 3169 | /* This is not ifdef:ed, so other builds than GTK can customize it. */ | 3699 | /* This is not ifdef:ed, so other builds than GTK can customize it. */ |
| 3170 | DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog, | 3700 | DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog, |
| @@ -3192,8 +3722,14 @@ Otherwise use Emacs own tooltip implementation. | |||
| 3192 | When using Gtk+ tooltips, the tooltip face is not used. */); | 3722 | When using Gtk+ tooltips, the tooltip face is not used. */); |
| 3193 | x_gtk_use_system_tooltips = true; | 3723 | x_gtk_use_system_tooltips = true; |
| 3194 | 3724 | ||
| 3725 | DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size, | ||
| 3726 | doc: /* Maximum size for tooltips. | ||
| 3727 | Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */); | ||
| 3728 | Vx_max_tooltip_size = Fcons (make_fixnum (80), make_fixnum (40)); | ||
| 3729 | |||
| 3195 | 3730 | ||
| 3196 | DEFSYM (Qmono, "mono"); | 3731 | DEFSYM (Qmono, "mono"); |
| 3732 | DEFSYM (Qassq_delete_all, "assq-delete-all"); | ||
| 3197 | 3733 | ||
| 3198 | DEFSYM (Qpdf, "pdf"); | 3734 | DEFSYM (Qpdf, "pdf"); |
| 3199 | 3735 | ||
diff --git a/src/pgtkterm.c b/src/pgtkterm.c index aeec3f589ff..544436e6e44 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c | |||
| @@ -6369,6 +6369,13 @@ drag_data_received (GtkWidget * widget, GdkDragContext * context, | |||
| 6369 | void | 6369 | void |
| 6370 | pgtk_set_event_handler (struct frame *f) | 6370 | pgtk_set_event_handler (struct frame *f) |
| 6371 | { | 6371 | { |
| 6372 | if (f->tooltip) | ||
| 6373 | { | ||
| 6374 | g_signal_connect (G_OBJECT (FRAME_GTK_WIDGET (f)), "draw", | ||
| 6375 | G_CALLBACK (pgtk_handle_draw), NULL); | ||
| 6376 | return; | ||
| 6377 | } | ||
| 6378 | |||
| 6372 | gtk_drag_dest_set (FRAME_GTK_WIDGET (f), GTK_DEST_DEFAULT_ALL, NULL, 0, | 6379 | gtk_drag_dest_set (FRAME_GTK_WIDGET (f), GTK_DEST_DEFAULT_ALL, NULL, 0, |
| 6373 | GDK_ACTION_COPY); | 6380 | GDK_ACTION_COPY); |
| 6374 | gtk_drag_dest_add_uri_targets (FRAME_GTK_WIDGET (f)); | 6381 | gtk_drag_dest_add_uri_targets (FRAME_GTK_WIDGET (f)); |