[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/trunk r100956: Use Gtk+ tooltips by default
From: |
Jan D |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/trunk r100956: Use Gtk+ tooltips by default for Gtk+ Emacs. |
Date: |
Sun, 01 Aug 2010 15:57:07 +0200 |
User-agent: |
Bazaar (2.0.3) |
------------------------------------------------------------
revno: 100956
committer: Jan D <address@hidden>
branch nick: trunk
timestamp: Sun 2010-08-01 15:57:07 +0200
message:
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.
modified:
etc/NEWS
lisp/ChangeLog
lisp/cus-start.el
src/ChangeLog
src/gtkutil.c
src/gtkutil.h
src/xfns.c
src/xterm.c
src/xterm.h
=== modified file 'etc/NEWS'
--- a/etc/NEWS 2010-07-29 17:10:41 +0000
+++ b/etc/NEWS 2010-08-01 13:57:07 +0000
@@ -104,6 +104,9 @@
top, left, tight or bottom. The Options => Show/Hide menu has entries
for this.
+** Emacs uses GTK tooltips by default if built with GTK. You can turn that
+off by customizing x-gtk-use-system-tooltips.
+
** Lucid menus and dialogs can display antialiased fonts if Emacs is built
with Xft.
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog 2010-08-01 00:38:19 +0000
+++ b/lisp/ChangeLog 2010-08-01 13:57:07 +0000
@@ -1,3 +1,7 @@
+2010-08-01 Jan Djärv <address@hidden>
+
+ * cus-start.el (x-gtk-use-system-tooltips): New variable.
+
2010-08-01 Chong Yidong <address@hidden>
* emacs-lisp/package.el (package--list-packages): Fix column
=== modified file 'lisp/cus-start.el'
--- a/lisp/cus-start.el 2010-07-28 17:34:51 +0000
+++ b/lisp/cus-start.el 2010-08-01 13:57:07 +0000
@@ -358,6 +358,7 @@
(x-gtk-show-hidden-files menu boolean "22.1")
(x-gtk-file-dialog-help-text menu boolean "22.1")
(x-gtk-whole-detached-tool-bar x boolean "22.1")
+ (x-gtk-use-system-tooltips tooltip boolean "23.3")
;; xterm.c
(x-use-underline-position-properties display boolean "22.1")
(x-underline-at-descent-line display boolean "22.1")
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog 2010-08-01 04:37:41 +0000
+++ b/src/ChangeLog 2010-08-01 13:57:07 +0000
@@ -1,3 +1,28 @@
+2010-08-01 Jan Djärv <address@hidden>
+
+ * xterm.h (struct x_output): Add ttip_widget, ttip_window and
+ ttip_lbl.
+
+ * 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.
+
+ * 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.
+
+ * gtkutil.h (xg_free_frame_widgets, xg_prepare_tooltip)
+ (xg_show_tooltip, xg_hide_tooltip): Declare.
+
+ * 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.
+
2010-08-01 Stefan Monnier <address@hidden>
* keymap.c (Fdefine_key, Flookup_key): Say what event is invalid.
=== modified file 'src/gtkutil.c'
--- a/src/gtkutil.c 2010-07-29 16:49:59 +0000
+++ b/src/gtkutil.c 2010-08-01 13:57:07 +0000
@@ -508,6 +508,161 @@
/***********************************************************************
+ Tooltips
+ ***********************************************************************/
+/* Gtk+ calls this callback when the parent of our tooltip dummy changes.
+ We use that to pop down the tooltip. This happens if Gtk+ for some
+ reason wants to change or hide the tooltip. */
+
+static void
+hierarchy_ch_cb (GtkWidget *widget,
+ GtkWidget *previous_toplevel,
+ gpointer user_data)
+{
+ FRAME_PTR f = (FRAME_PTR) user_data;
+ struct x_output *x = f->output_data.x;
+ GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl);
+
+ if (! top || ! GTK_IS_WINDOW (top))
+ gtk_widget_hide (previous_toplevel);
+}
+
+/* Callback called when Gtk+ thinks a tooltip should be displayed.
+ We use it to get the tooltip window and the tooltip widget so
+ we can manipulate the ourselves.
+
+ Return FALSE ensures that the tooltip is not shown. */
+
+static gboolean
+qttip_cb (GtkWidget *widget,
+ gint xpos,
+ gint ypos,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip,
+ gpointer user_data)
+{
+ FRAME_PTR f = (FRAME_PTR) user_data;
+ struct x_output *x = f->output_data.x;
+ if (x->ttip_widget == NULL)
+ {
+ g_object_set (G_OBJECT (widget), "has-tooltip", FALSE, NULL);
+ x->ttip_widget = tooltip;
+ g_object_ref (G_OBJECT (tooltip));
+ x->ttip_lbl = gtk_label_new ("");
+ g_object_ref (G_OBJECT (x->ttip_lbl));
+ gtk_tooltip_set_custom (tooltip, x->ttip_lbl);
+ x->ttip_window = GTK_WINDOW (gtk_widget_get_toplevel (x->ttip_lbl));
+ /* Realize so we can safely get screen later on. */
+ gtk_widget_realize (GTK_WIDGET (x->ttip_window));
+ gtk_widget_realize (x->ttip_lbl);
+
+ g_signal_connect (x->ttip_lbl, "hierarchy-changed",
+ G_CALLBACK (hierarchy_ch_cb), f);
+ }
+ return FALSE;
+}
+
+/* Prepare a tooltip to be shown, i.e. calculate WIDTH and HEIGHT.
+ Return zero if no system tooltip available, non-zero otherwise. */
+
+int
+xg_prepare_tooltip (FRAME_PTR f,
+ Lisp_Object string,
+ int *width,
+ int *height)
+{
+ struct x_output *x = f->output_data.x;
+ GtkWidget *widget;
+ GdkWindow *gwin;
+ GdkScreen *screen;
+ GtkSettings *settings;
+ gboolean tt_enabled = TRUE;
+ GtkRequisition req;
+ Lisp_Object encoded_string;
+
+ if (!x->ttip_lbl) return 0;
+
+ BLOCK_INPUT;
+ encoded_string = ENCODE_UTF_8 (string);
+ widget = GTK_WIDGET (x->ttip_lbl);
+ gwin = gtk_widget_get_window (GTK_WIDGET (x->ttip_window));
+ screen = gdk_drawable_get_screen (gwin);
+ settings = gtk_settings_get_for_screen (screen);
+ g_object_get (settings, "gtk-enable-tooltips", &tt_enabled, NULL);
+ if (tt_enabled)
+ {
+ g_object_set (settings, "gtk-enable-tooltips", FALSE, NULL);
+ /* Record that we disabled it so it can be enabled again. */
+ g_object_set_data (G_OBJECT (x->ttip_window), "restore-tt",
+ (gpointer)f);
+ }
+
+ /* Prevent Gtk+ from hiding tooltip on mouse move and such. */
+ g_object_set_data (G_OBJECT
+ (gtk_widget_get_display (GTK_WIDGET (x->ttip_window))),
+ "gdk-display-current-tooltip", NULL);
+
+ /* Put out dummy widget in so we can get callbacks for unrealize and
+ hierarchy-changed. */
+ gtk_tooltip_set_custom (x->ttip_widget, widget);
+
+ gtk_tooltip_set_text (x->ttip_widget, SDATA (encoded_string));
+ gtk_widget_size_request (GTK_WIDGET (x->ttip_window), &req);
+ if (width) *width = req.width;
+ if (height) *height = req.height;
+
+ UNBLOCK_INPUT;
+
+ return 1;
+}
+
+/* Show the tooltip at ROOT_X and ROOT_Y.
+ xg_prepare_tooltip must have been called before this function. */
+
+void
+xg_show_tooltip (FRAME_PTR f, int root_x, int root_y)
+{
+ struct x_output *x = f->output_data.x;
+ if (x->ttip_window)
+ {
+ BLOCK_INPUT;
+ gtk_window_move (x->ttip_window, root_x, root_y);
+ gtk_widget_show_all (GTK_WIDGET (x->ttip_window));
+ UNBLOCK_INPUT;
+ }
+}
+
+/* Hide tooltip if shown. Do nothing if not shown.
+ Return non-zero if tip was hidden, non-ero if not (i.e. not using
+ system tooltips). */
+
+int
+xg_hide_tooltip (FRAME_PTR f)
+{
+ int ret = 0;
+ if (f->output_data.x->ttip_window)
+ {
+ GtkWindow *win = f->output_data.x->ttip_window;
+ BLOCK_INPUT;
+ gtk_widget_hide (GTK_WIDGET (win));
+
+ if (g_object_get_data (G_OBJECT (win), "restore-tt"))
+ {
+ GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET (win));
+ GdkScreen *screen = gdk_drawable_get_screen (gwin);
+ GtkSettings *settings = gtk_settings_get_for_screen (screen);
+ g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL);
+ }
+ UNBLOCK_INPUT;
+
+ ret = 1;
+ }
+
+ return ret;
+}
+
+
+/***********************************************************************
General functions for creating widgets, resizing, events, e.t.c.
***********************************************************************/
@@ -847,17 +1002,34 @@
style->bg_pixmap_name[GTK_STATE_NORMAL] = g_strdup ("<none>");
gtk_widget_modify_style (wfixed, style);
- /* GTK does not set any border, and they look bad with GTK. */
- /* That they look bad is no excuse for imposing this here. --Stef
- It should be done by providing the proper default in Fx_create_Frame.
- f->border_width = 0;
- f->internal_border_width = 0; */
+ /* Steal a tool tip window we can move ourselves. */
+ f->output_data.x->ttip_widget = 0;
+ f->output_data.x->ttip_lbl = 0;
+ f->output_data.x->ttip_window = 0;
+ gtk_widget_set_tooltip_text (wtop, "Dummy text");
+ g_signal_connect (wtop, "query-tooltip", G_CALLBACK (qttip_cb), f);
UNBLOCK_INPUT;
return 1;
}
+void
+xg_free_frame_widgets (FRAME_PTR f)
+{
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ struct x_output *x = f->output_data.x;
+ gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
+ FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow in xterm.c */
+ FRAME_GTK_OUTER_WIDGET (f) = 0;
+ if (x->ttip_lbl)
+ gtk_widget_destroy (x->ttip_lbl);
+ if (x->ttip_widget)
+ g_object_unref (G_OBJECT (x->ttip_widget));
+ }
+}
+
/* Set the normal size hints for the window manager, for frame F.
FLAGS is the flags word to use--or 0 meaning preserve the flags
that the window now has.
=== modified file 'src/gtkutil.h'
--- a/src/gtkutil.h 2010-07-29 16:49:59 +0000
+++ b/src/gtkutil.h 2010-08-01 13:57:07 +0000
@@ -194,6 +194,7 @@
extern GdkCursor * xg_create_default_cursor (Display *dpy);
extern int xg_create_frame_widgets (FRAME_PTR f);
+extern void xg_free_frame_widgets (FRAME_PTR f);
extern void x_wm_set_size_hint (FRAME_PTR f,
long flags,
int user_position);
@@ -203,6 +204,14 @@
Pixmap icon_pixmap,
Pixmap icon_mask);
+extern int xg_prepare_tooltip (FRAME_PTR f,
+ Lisp_Object string,
+ int *width,
+ int *height);
+extern void xg_show_tooltip (FRAME_PTR f, int root_x, int root_y);
+extern int xg_hide_tooltip (FRAME_PTR f);
+
+
/* Mark all callback data that are Lisp_object:s during GC. */
extern void xg_mark_data (void);
=== modified file 'src/xfns.c'
--- a/src/xfns.c 2010-07-29 18:08:51 +0000
+++ b/src/xfns.c 2010-08-01 13:57:07 +0000
@@ -161,6 +161,10 @@
int x_gtk_whole_detached_tool_bar;
+/* If non-zero, use Gtk+ tooltips. */
+
+static int x_gtk_use_system_tooltips;
+
/* The background and shape of the mouse pointer, and shape when not
over text or in the modeline. */
@@ -4610,7 +4614,9 @@
when this happens. */
static Lisp_Object
-x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms,
Lisp_Object text)
+x_create_tip_frame (struct x_display_info *dpyinfo,
+ Lisp_Object parms,
+ Lisp_Object text)
{
struct frame *f;
Lisp_Object frame, tem;
@@ -5037,6 +5043,27 @@
else
CHECK_NUMBER (dy);
+#ifdef USE_GTK
+ if (x_gtk_use_system_tooltips)
+ {
+ int ok;
+
+ /* Hide a previous tip, if any. */
+ Fx_hide_tip ();
+
+ BLOCK_INPUT;
+ if ((ok = xg_prepare_tooltip (f, string, &width, &height)) != 0)
+ {
+ compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
+ xg_show_tooltip (f, root_x, root_y);
+ /* This is used in Fx_hide_tip. */
+ XSETFRAME (tip_frame, f);
+ }
+ UNBLOCK_INPUT;
+ if (ok) goto start_timer;
+ }
+#endif /* USE_GTK */
+
if (NILP (last_show_tip_args))
last_show_tip_args = Fmake_vector (make_number (3), Qnil);
@@ -5197,6 +5224,7 @@
int count;
Lisp_Object deleted, frame, timer;
struct gcpro gcpro1, gcpro2;
+ struct frame *f;
/* Return quickly if nothing to do. */
if (NILP (tip_timer) && NILP (tip_frame))
@@ -5214,6 +5242,14 @@
if (!NILP (timer))
call1 (Qcancel_timer, timer);
+#ifdef USE_GTK
+ /* When using system tooltip, tip_frame is the Emacs frame on which
+ the tip is shown. */
+ f = XFRAME (frame);
+ if (xg_hide_tooltip (f))
+ frame = Qnil;
+#endif
+
if (FRAMEP (frame))
{
delete_frame (frame, Qnil);
@@ -5224,8 +5260,9 @@
redisplay procedure is not called when a tip frame over menu
items is unmapped. Redisplay the menu manually... */
{
- struct frame *f = SELECTED_FRAME ();
- Widget w = f->output_data.x->menubar_widget;
+ Widget w;
+ f = SELECTED_FRAME ();
+ w = f->output_data.x->menubar_widget;
if (!DoesSaveUnders (FRAME_X_DISPLAY_INFO (f)->screen)
&& w != NULL)
@@ -5894,6 +5931,12 @@
the tool bar buttons. */);
x_gtk_whole_detached_tool_bar = 0;
+ DEFVAR_BOOL ("x-gtk-use-system-tooltips", &x_gtk_use_system_tooltips,
+ doc: /* *If non-nil with a Gtk+ built Emacs, the Gtk+ toolip is used.
+Otherwise use Emacs own tooltip implementation.
+When using Gtk+ tooltips, the tooltip face is not used. */);
+ x_gtk_use_system_tooltips = 1;
+
Fprovide (intern_c_string ("x"), Qnil);
#ifdef USE_X_TOOLKIT
=== modified file 'src/xterm.c'
--- a/src/xterm.c 2010-07-29 16:49:59 +0000
+++ b/src/xterm.c 2010-08-01 13:57:07 +0000
@@ -2842,7 +2842,8 @@
#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
/* Make sure scroll bars are redrawn. As they aren't redrawn by
redisplay, do it here. */
- gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
+ if (FRAME_GTK_WIDGET (f))
+ gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
#endif
XFlush (FRAME_X_DISPLAY (f));
@@ -9278,14 +9279,7 @@
#else /* !USE_X_TOOLKIT */
#ifdef USE_GTK
- /* In the GTK version, tooltips are normal X
- frames. We must check and free both types. */
- if (FRAME_GTK_OUTER_WIDGET (f))
- {
- gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
- FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow below */
- FRAME_GTK_OUTER_WIDGET (f) = 0;
- }
+ xg_free_frame_widgets (f);
#endif /* USE_GTK */
if (FRAME_X_WINDOW (f))
=== modified file 'src/xterm.h'
--- a/src/xterm.h 2010-07-29 16:49:59 +0000
+++ b/src/xterm.h 2010-08-01 13:57:07 +0000
@@ -502,6 +502,10 @@
/* The last size hints set. */
GdkGeometry size_hints;
long hint_flags;
+
+ GtkTooltip *ttip_widget;
+ GtkWidget *ttip_lbl;
+ GtkWindow *ttip_window;
#endif
/* If >=0, a bitmap index. The indicated bitmap is used for the
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/trunk r100956: Use Gtk+ tooltips by default for Gtk+ Emacs.,
Jan D <=