aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan D2010-08-01 15:57:07 +0200
committerJan D2010-08-01 15:57:07 +0200
commitaa1859f5cd51d760a1b30f01d1fc3928a8c10363 (patch)
tree53dc2df9be3cbe487e79c0085612a0c83615881b /src
parent6e051c0a1330f539e036597988a0973fbd1adaef (diff)
downloademacs-aa1859f5cd51d760a1b30f01d1fc3928a8c10363.tar.gz
emacs-aa1859f5cd51d760a1b30f01d1fc3928a8c10363.zip
Use Gtk+ tooltips by default for Gtk+ Emacs.
* lisp/cus-start.el (x-gtk-use-system-tooltips): New variable. * src/gtkutil.c (hierarchy_ch_cb, qttip_cb, xg_prepare_tooltip) (xg_show_tooltip, xg_hide_tooltip, xg_free_frame_widgets): New functions. (xg_create_frame_widgets): Set ttip_* to 0. Set a dummy tooltip text so qttip_cb is called. Connect query-tooltip to qttip_cb. Remove code that is commented out. * src/gtkutil.h (xg_free_frame_widgets, xg_prepare_tooltip) (xg_show_tooltip, xg_hide_tooltip): Declare. * src/xfns.c (x_gtk_use_system_tooltips): New variable. (Fx_show_tip): If USE_GTK and x_gtk_use_system_tooltips, call new gtkutil tooltip functions to show the tooltip. (Fx_hide_tip): Call xg_hide_tooltip. (syms_of_xfns): Defvar x-gtk-use-system-tooltips. * src/xterm.c (x_clear_frame): Check FRAME_GTK_WIDGET (f) before calling gtk_widget_queue_draw. (x_free_frame_resources): Call xg_free_frame_widgets. * src/xterm.h (struct x_output): Add ttip_widget, ttip_window and ttip_lbl.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog25
-rw-r--r--src/gtkutil.c182
-rw-r--r--src/gtkutil.h9
-rw-r--r--src/xfns.c49
-rw-r--r--src/xterm.c12
-rw-r--r--src/xterm.h4
6 files changed, 264 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a641336d7a6..c382f217a51 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,28 @@
12010-08-01 Jan Djärv <jan.h.d@swipnet.se>
2
3 * xterm.h (struct x_output): Add ttip_widget, ttip_window and
4 ttip_lbl.
5
6 * xterm.c (x_clear_frame): Check FRAME_GTK_WIDGET (f) before
7 calling gtk_widget_queue_draw.
8 (x_free_frame_resources): Call xg_free_frame_widgets.
9
10 * xfns.c (x_gtk_use_system_tooltips): New variable.
11 (Fx_show_tip): If USE_GTK and x_gtk_use_system_tooltips, call
12 new gtkutil tooltip functions to show the tooltip.
13 (Fx_hide_tip): Call xg_hide_tooltip.
14 (syms_of_xfns): Defvar x-gtk-use-system-tooltips.
15
16 * gtkutil.h (xg_free_frame_widgets, xg_prepare_tooltip)
17 (xg_show_tooltip, xg_hide_tooltip): Declare.
18
19 * gtkutil.c (hierarchy_ch_cb, qttip_cb, xg_prepare_tooltip)
20 (xg_show_tooltip, xg_hide_tooltip, xg_free_frame_widgets): New
21 functions.
22 (xg_create_frame_widgets): Set ttip_* to 0. Set a dummy tooltip
23 text so qttip_cb is called. Connect query-tooltip to qttip_cb.
24 Remove code that is commented out.
25
12010-08-01 Stefan Monnier <monnier@iro.umontreal.ca> 262010-08-01 Stefan Monnier <monnier@iro.umontreal.ca>
2 27
3 * keymap.c (Fdefine_key, Flookup_key): Say what event is invalid. 28 * keymap.c (Fdefine_key, Flookup_key): Say what event is invalid.
diff --git a/src/gtkutil.c b/src/gtkutil.c
index b31eb2d21f2..48b013993a7 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -508,6 +508,161 @@ get_utf8_string (char *str)
508 508
509 509
510/*********************************************************************** 510/***********************************************************************
511 Tooltips
512 ***********************************************************************/
513/* Gtk+ calls this callback when the parent of our tooltip dummy changes.
514 We use that to pop down the tooltip. This happens if Gtk+ for some
515 reason wants to change or hide the tooltip. */
516
517static void
518hierarchy_ch_cb (GtkWidget *widget,
519 GtkWidget *previous_toplevel,
520 gpointer user_data)
521{
522 FRAME_PTR f = (FRAME_PTR) user_data;
523 struct x_output *x = f->output_data.x;
524 GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl);
525
526 if (! top || ! GTK_IS_WINDOW (top))
527 gtk_widget_hide (previous_toplevel);
528}
529
530/* Callback called when Gtk+ thinks a tooltip should be displayed.
531 We use it to get the tooltip window and the tooltip widget so
532 we can manipulate the ourselves.
533
534 Return FALSE ensures that the tooltip is not shown. */
535
536static gboolean
537qttip_cb (GtkWidget *widget,
538 gint xpos,
539 gint ypos,
540 gboolean keyboard_mode,
541 GtkTooltip *tooltip,
542 gpointer user_data)
543{
544 FRAME_PTR f = (FRAME_PTR) user_data;
545 struct x_output *x = f->output_data.x;
546 if (x->ttip_widget == NULL)
547 {
548 g_object_set (G_OBJECT (widget), "has-tooltip", FALSE, NULL);
549 x->ttip_widget = tooltip;
550 g_object_ref (G_OBJECT (tooltip));
551 x->ttip_lbl = gtk_label_new ("");
552 g_object_ref (G_OBJECT (x->ttip_lbl));
553 gtk_tooltip_set_custom (tooltip, x->ttip_lbl);
554 x->ttip_window = GTK_WINDOW (gtk_widget_get_toplevel (x->ttip_lbl));
555 /* Realize so we can safely get screen later on. */
556 gtk_widget_realize (GTK_WIDGET (x->ttip_window));
557 gtk_widget_realize (x->ttip_lbl);
558
559 g_signal_connect (x->ttip_lbl, "hierarchy-changed",
560 G_CALLBACK (hierarchy_ch_cb), f);
561 }
562 return FALSE;
563}
564
565/* Prepare a tooltip to be shown, i.e. calculate WIDTH and HEIGHT.
566 Return zero if no system tooltip available, non-zero otherwise. */
567
568int
569xg_prepare_tooltip (FRAME_PTR f,
570 Lisp_Object string,
571 int *width,
572 int *height)
573{
574 struct x_output *x = f->output_data.x;
575 GtkWidget *widget;
576 GdkWindow *gwin;
577 GdkScreen *screen;
578 GtkSettings *settings;
579 gboolean tt_enabled = TRUE;
580 GtkRequisition req;
581 Lisp_Object encoded_string;
582
583 if (!x->ttip_lbl) return 0;
584
585 BLOCK_INPUT;
586 encoded_string = ENCODE_UTF_8 (string);
587 widget = GTK_WIDGET (x->ttip_lbl);
588 gwin = gtk_widget_get_window (GTK_WIDGET (x->ttip_window));
589 screen = gdk_drawable_get_screen (gwin);
590 settings = gtk_settings_get_for_screen (screen);
591 g_object_get (settings, "gtk-enable-tooltips", &tt_enabled, NULL);
592 if (tt_enabled)
593 {
594 g_object_set (settings, "gtk-enable-tooltips", FALSE, NULL);
595 /* Record that we disabled it so it can be enabled again. */
596 g_object_set_data (G_OBJECT (x->ttip_window), "restore-tt",
597 (gpointer)f);
598 }
599
600 /* Prevent Gtk+ from hiding tooltip on mouse move and such. */
601 g_object_set_data (G_OBJECT
602 (gtk_widget_get_display (GTK_WIDGET (x->ttip_window))),
603 "gdk-display-current-tooltip", NULL);
604
605 /* Put out dummy widget in so we can get callbacks for unrealize and
606 hierarchy-changed. */
607 gtk_tooltip_set_custom (x->ttip_widget, widget);
608
609 gtk_tooltip_set_text (x->ttip_widget, SDATA (encoded_string));
610 gtk_widget_size_request (GTK_WIDGET (x->ttip_window), &req);
611 if (width) *width = req.width;
612 if (height) *height = req.height;
613
614 UNBLOCK_INPUT;
615
616 return 1;
617}
618
619/* Show the tooltip at ROOT_X and ROOT_Y.
620 xg_prepare_tooltip must have been called before this function. */
621
622void
623xg_show_tooltip (FRAME_PTR f, int root_x, int root_y)
624{
625 struct x_output *x = f->output_data.x;
626 if (x->ttip_window)
627 {
628 BLOCK_INPUT;
629 gtk_window_move (x->ttip_window, root_x, root_y);
630 gtk_widget_show_all (GTK_WIDGET (x->ttip_window));
631 UNBLOCK_INPUT;
632 }
633}
634
635/* Hide tooltip if shown. Do nothing if not shown.
636 Return non-zero if tip was hidden, non-ero if not (i.e. not using
637 system tooltips). */
638
639int
640xg_hide_tooltip (FRAME_PTR f)
641{
642 int ret = 0;
643 if (f->output_data.x->ttip_window)
644 {
645 GtkWindow *win = f->output_data.x->ttip_window;
646 BLOCK_INPUT;
647 gtk_widget_hide (GTK_WIDGET (win));
648
649 if (g_object_get_data (G_OBJECT (win), "restore-tt"))
650 {
651 GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET (win));
652 GdkScreen *screen = gdk_drawable_get_screen (gwin);
653 GtkSettings *settings = gtk_settings_get_for_screen (screen);
654 g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL);
655 }
656 UNBLOCK_INPUT;
657
658 ret = 1;
659 }
660
661 return ret;
662}
663
664
665/***********************************************************************
511 General functions for creating widgets, resizing, events, e.t.c. 666 General functions for creating widgets, resizing, events, e.t.c.
512 ***********************************************************************/ 667 ***********************************************************************/
513 668
@@ -847,17 +1002,34 @@ xg_create_frame_widgets (FRAME_PTR f)
847 style->bg_pixmap_name[GTK_STATE_NORMAL] = g_strdup ("<none>"); 1002 style->bg_pixmap_name[GTK_STATE_NORMAL] = g_strdup ("<none>");
848 gtk_widget_modify_style (wfixed, style); 1003 gtk_widget_modify_style (wfixed, style);
849 1004
850 /* GTK does not set any border, and they look bad with GTK. */ 1005 /* Steal a tool tip window we can move ourselves. */
851 /* That they look bad is no excuse for imposing this here. --Stef 1006 f->output_data.x->ttip_widget = 0;
852 It should be done by providing the proper default in Fx_create_Frame. 1007 f->output_data.x->ttip_lbl = 0;
853 f->border_width = 0; 1008 f->output_data.x->ttip_window = 0;
854 f->internal_border_width = 0; */ 1009 gtk_widget_set_tooltip_text (wtop, "Dummy text");
1010 g_signal_connect (wtop, "query-tooltip", G_CALLBACK (qttip_cb), f);
855 1011
856 UNBLOCK_INPUT; 1012 UNBLOCK_INPUT;
857 1013
858 return 1; 1014 return 1;
859} 1015}
860 1016
1017void
1018xg_free_frame_widgets (FRAME_PTR f)
1019{
1020 if (FRAME_GTK_OUTER_WIDGET (f))
1021 {
1022 struct x_output *x = f->output_data.x;
1023 gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
1024 FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow in xterm.c */
1025 FRAME_GTK_OUTER_WIDGET (f) = 0;
1026 if (x->ttip_lbl)
1027 gtk_widget_destroy (x->ttip_lbl);
1028 if (x->ttip_widget)
1029 g_object_unref (G_OBJECT (x->ttip_widget));
1030 }
1031}
1032
861/* Set the normal size hints for the window manager, for frame F. 1033/* Set the normal size hints for the window manager, for frame F.
862 FLAGS is the flags word to use--or 0 meaning preserve the flags 1034 FLAGS is the flags word to use--or 0 meaning preserve the flags
863 that the window now has. 1035 that the window now has.
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 3f1d1a2b856..9748b07cca0 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -194,6 +194,7 @@ extern void xg_display_close (Display *dpy);
194extern GdkCursor * xg_create_default_cursor (Display *dpy); 194extern GdkCursor * xg_create_default_cursor (Display *dpy);
195 195
196extern int xg_create_frame_widgets (FRAME_PTR f); 196extern int xg_create_frame_widgets (FRAME_PTR f);
197extern void xg_free_frame_widgets (FRAME_PTR f);
197extern void x_wm_set_size_hint (FRAME_PTR f, 198extern void x_wm_set_size_hint (FRAME_PTR f,
198 long flags, 199 long flags,
199 int user_position); 200 int user_position);
@@ -203,6 +204,14 @@ extern void xg_set_frame_icon (FRAME_PTR f,
203 Pixmap icon_pixmap, 204 Pixmap icon_pixmap,
204 Pixmap icon_mask); 205 Pixmap icon_mask);
205 206
207extern int xg_prepare_tooltip (FRAME_PTR f,
208 Lisp_Object string,
209 int *width,
210 int *height);
211extern void xg_show_tooltip (FRAME_PTR f, int root_x, int root_y);
212extern int xg_hide_tooltip (FRAME_PTR f);
213
214
206/* Mark all callback data that are Lisp_object:s during GC. */ 215/* Mark all callback data that are Lisp_object:s during GC. */
207extern void xg_mark_data (void); 216extern void xg_mark_data (void);
208 217
diff --git a/src/xfns.c b/src/xfns.c
index 28de53c5998..1496daa9f63 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -161,6 +161,10 @@ int x_gtk_file_dialog_help_text;
161 161
162int x_gtk_whole_detached_tool_bar; 162int x_gtk_whole_detached_tool_bar;
163 163
164/* If non-zero, use Gtk+ tooltips. */
165
166static int x_gtk_use_system_tooltips;
167
164/* The background and shape of the mouse pointer, and shape when not 168/* The background and shape of the mouse pointer, and shape when not
165 over text or in the modeline. */ 169 over text or in the modeline. */
166 170
@@ -4610,7 +4614,9 @@ unwind_create_tip_frame (Lisp_Object frame)
4610 when this happens. */ 4614 when this happens. */
4611 4615
4612static Lisp_Object 4616static Lisp_Object
4613x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms, Lisp_Object text) 4617x_create_tip_frame (struct x_display_info *dpyinfo,
4618 Lisp_Object parms,
4619 Lisp_Object text)
4614{ 4620{
4615 struct frame *f; 4621 struct frame *f;
4616 Lisp_Object frame, tem; 4622 Lisp_Object frame, tem;
@@ -5037,6 +5043,27 @@ Text larger than the specified size is clipped. */)
5037 else 5043 else
5038 CHECK_NUMBER (dy); 5044 CHECK_NUMBER (dy);
5039 5045
5046#ifdef USE_GTK
5047 if (x_gtk_use_system_tooltips)
5048 {
5049 int ok;
5050
5051 /* Hide a previous tip, if any. */
5052 Fx_hide_tip ();
5053
5054 BLOCK_INPUT;
5055 if ((ok = xg_prepare_tooltip (f, string, &width, &height)) != 0)
5056 {
5057 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5058 xg_show_tooltip (f, root_x, root_y);
5059 /* This is used in Fx_hide_tip. */
5060 XSETFRAME (tip_frame, f);
5061 }
5062 UNBLOCK_INPUT;
5063 if (ok) goto start_timer;
5064 }
5065#endif /* USE_GTK */
5066
5040 if (NILP (last_show_tip_args)) 5067 if (NILP (last_show_tip_args))
5041 last_show_tip_args = Fmake_vector (make_number (3), Qnil); 5068 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5042 5069
@@ -5197,6 +5224,7 @@ Value is t if tooltip was open, nil otherwise. */)
5197 int count; 5224 int count;
5198 Lisp_Object deleted, frame, timer; 5225 Lisp_Object deleted, frame, timer;
5199 struct gcpro gcpro1, gcpro2; 5226 struct gcpro gcpro1, gcpro2;
5227 struct frame *f;
5200 5228
5201 /* Return quickly if nothing to do. */ 5229 /* Return quickly if nothing to do. */
5202 if (NILP (tip_timer) && NILP (tip_frame)) 5230 if (NILP (tip_timer) && NILP (tip_frame))
@@ -5214,6 +5242,14 @@ Value is t if tooltip was open, nil otherwise. */)
5214 if (!NILP (timer)) 5242 if (!NILP (timer))
5215 call1 (Qcancel_timer, timer); 5243 call1 (Qcancel_timer, timer);
5216 5244
5245#ifdef USE_GTK
5246 /* When using system tooltip, tip_frame is the Emacs frame on which
5247 the tip is shown. */
5248 f = XFRAME (frame);
5249 if (xg_hide_tooltip (f))
5250 frame = Qnil;
5251#endif
5252
5217 if (FRAMEP (frame)) 5253 if (FRAMEP (frame))
5218 { 5254 {
5219 delete_frame (frame, Qnil); 5255 delete_frame (frame, Qnil);
@@ -5224,8 +5260,9 @@ Value is t if tooltip was open, nil otherwise. */)
5224 redisplay procedure is not called when a tip frame over menu 5260 redisplay procedure is not called when a tip frame over menu
5225 items is unmapped. Redisplay the menu manually... */ 5261 items is unmapped. Redisplay the menu manually... */
5226 { 5262 {
5227 struct frame *f = SELECTED_FRAME (); 5263 Widget w;
5228 Widget w = f->output_data.x->menubar_widget; 5264 f = SELECTED_FRAME ();
5265 w = f->output_data.x->menubar_widget;
5229 5266
5230 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen) 5267 if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
5231 && w != NULL) 5268 && w != NULL)
@@ -5894,6 +5931,12 @@ The default is to just show an arrow and pressing on that arrow shows
5894the tool bar buttons. */); 5931the tool bar buttons. */);
5895 x_gtk_whole_detached_tool_bar = 0; 5932 x_gtk_whole_detached_tool_bar = 0;
5896 5933
5934 DEFVAR_BOOL ("x-gtk-use-system-tooltips", &x_gtk_use_system_tooltips,
5935 doc: /* *If non-nil with a Gtk+ built Emacs, the Gtk+ toolip is used.
5936Otherwise use Emacs own tooltip implementation.
5937When using Gtk+ tooltips, the tooltip face is not used. */);
5938 x_gtk_use_system_tooltips = 1;
5939
5897 Fprovide (intern_c_string ("x"), Qnil); 5940 Fprovide (intern_c_string ("x"), Qnil);
5898 5941
5899#ifdef USE_X_TOOLKIT 5942#ifdef USE_X_TOOLKIT
diff --git a/src/xterm.c b/src/xterm.c
index 61e93470cbd..f003fc7648d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2842,7 +2842,8 @@ x_clear_frame (struct frame *f)
2842#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS) 2842#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
2843 /* Make sure scroll bars are redrawn. As they aren't redrawn by 2843 /* Make sure scroll bars are redrawn. As they aren't redrawn by
2844 redisplay, do it here. */ 2844 redisplay, do it here. */
2845 gtk_widget_queue_draw (FRAME_GTK_WIDGET (f)); 2845 if (FRAME_GTK_WIDGET (f))
2846 gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
2846#endif 2847#endif
2847 2848
2848 XFlush (FRAME_X_DISPLAY (f)); 2849 XFlush (FRAME_X_DISPLAY (f));
@@ -9278,14 +9279,7 @@ x_free_frame_resources (struct frame *f)
9278#else /* !USE_X_TOOLKIT */ 9279#else /* !USE_X_TOOLKIT */
9279 9280
9280#ifdef USE_GTK 9281#ifdef USE_GTK
9281 /* In the GTK version, tooltips are normal X 9282 xg_free_frame_widgets (f);
9282 frames. We must check and free both types. */
9283 if (FRAME_GTK_OUTER_WIDGET (f))
9284 {
9285 gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
9286 FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow below */
9287 FRAME_GTK_OUTER_WIDGET (f) = 0;
9288 }
9289#endif /* USE_GTK */ 9283#endif /* USE_GTK */
9290 9284
9291 if (FRAME_X_WINDOW (f)) 9285 if (FRAME_X_WINDOW (f))
diff --git a/src/xterm.h b/src/xterm.h
index c487ae4bd63..1674cdbac68 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -502,6 +502,10 @@ struct x_output
502 /* The last size hints set. */ 502 /* The last size hints set. */
503 GdkGeometry size_hints; 503 GdkGeometry size_hints;
504 long hint_flags; 504 long hint_flags;
505
506 GtkTooltip *ttip_widget;
507 GtkWidget *ttip_lbl;
508 GtkWindow *ttip_window;
505#endif 509#endif
506 510
507 /* If >=0, a bitmap index. The indicated bitmap is used for the 511 /* If >=0, a bitmap index. The indicated bitmap is used for the