# HG changeset patch # User Jan D # Date 1281551290 -7200 # Node ID be18c3b67d66d74943a1aeec22a26875daf7d659 # Parent e2f8226efb997af1794aa953c94a3fec2b7030eb Take colors for region face (selected text) from the Gtk+ theme. * lisp/dynamic-setting.el (dynamic-setting-handle-config-changed-event): Handle theme-name change. * lisp/faces.el (region): Add type gtk that uses gtk colors. * src/gtkutil.c (xg_check_special_colors, style_changed_cb): New functions. (xg_create_frame_widgets): Connect theme name changes to style_changed_cb. * src/gtkutil.h (xg_check_special_colors): Declare. * src/xfns.c (x_defined_color): If USE_GTK, call xg_check_special_colors first. diff -r e2f8226efb99 -r be18c3b67d66 etc/NEWS --- a/etc/NEWS Wed Aug 11 14:34:46 2010 +0200 +++ b/etc/NEWS Wed Aug 11 20:28:10 2010 +0200 @@ -109,6 +109,9 @@ top, left, tight or bottom. The Options => Show/Hide menu has entries for this. +** The colors for selected text (the region face) are taken from the GTK +theme when Emacs is built with GTK. + ** Emacs uses GTK tooltips by default if built with GTK. You can turn that off by customizing x-gtk-use-system-tooltips. diff -r e2f8226efb99 -r be18c3b67d66 lisp/ChangeLog --- a/lisp/ChangeLog Wed Aug 11 14:34:46 2010 +0200 +++ b/lisp/ChangeLog Wed Aug 11 20:28:10 2010 +0200 @@ -1,3 +1,10 @@ +2010-08-11 Jan Djärv + + * faces.el (region): Add type gtk that uses gtk colors. + + * dynamic-setting.el (dynamic-setting-handle-config-changed-event): + Handle theme-name change. + 2010-08-10 Michael R. Mauger * progmodes/sql.el: Version 2.5 diff -r e2f8226efb99 -r be18c3b67d66 lisp/dynamic-setting.el --- a/lisp/dynamic-setting.el Wed Aug 11 14:34:46 2010 +0200 +++ b/lisp/dynamic-setting.el Wed Aug 11 20:28:10 2010 +0200 @@ -96,6 +96,11 @@ ((eq type 'font-render) (font-setting-change-default-font display-name nil)) + ;; This is a bit heavy, ideally we would just clear faces + ;; on the affected display, and perhaps only the relevant + ;; faces. Oh well. + ((eq type 'theme-name) (clear-face-cache)) + ((eq type 'tool-bar-style) (force-mode-line-update t))))) (define-key special-event-map [config-changed-event] diff -r e2f8226efb99 -r be18c3b67d66 lisp/faces.el --- a/lisp/faces.el Wed Aug 11 14:34:46 2010 +0200 +++ b/lisp/faces.el Wed Aug 11 20:28:10 2010 +0200 @@ -2281,6 +2281,9 @@ (defface region '((((class color) (min-colors 88) (background dark)) :background "blue3") + (((class color) (min-colors 88) (background light) (type gtk)) + :foreground "gtk_selection_fg_color" + :background "gtk_selection_bg_color") (((class color) (min-colors 88) (background light) (type ns)) :background "ns_selection_color") (((class color) (min-colors 88) (background light)) diff -r e2f8226efb99 -r be18c3b67d66 src/ChangeLog --- a/src/ChangeLog Wed Aug 11 14:34:46 2010 +0200 +++ b/src/ChangeLog Wed Aug 11 20:28:10 2010 +0200 @@ -1,5 +1,14 @@ 2010-08-11 Jan Djärv + * xfns.c (x_defined_color): If USE_GTK, call xg_check_special_colors + first. + + * gtkutil.h (xg_check_special_colors): Declare. + + * gtkutil.c (xg_check_special_colors, style_changed_cb): New functions. + (xg_create_frame_widgets): Connect theme name changes to + style_changed_cb. + * xterm.c (emacs_class): New char[] for EMACS_CLASS. (xim_open_dpy, xim_initialize, xim_close_dpy): Use emacs_class. (x_term_init): Use char[] display_opt and name_opt instead of diff -r e2f8226efb99 -r be18c3b67d66 src/gtkutil.c --- a/src/gtkutil.c Wed Aug 11 14:34:46 2010 +0200 +++ b/src/gtkutil.c Wed Aug 11 20:28:10 2010 +0200 @@ -506,6 +506,41 @@ return utf8_str; } +/* Check for special colors used in face spec for region face. + The colors are fetched from the Gtk+ theme. + Return 1 if color was found, 0 if not. */ + +int +xg_check_special_colors (struct frame *f, + const char *color_name, + XColor *color) +{ + int success_p = 0; + if (FRAME_GTK_WIDGET (f)) + { + if (strcmp ("gtk_selection_bg_color", color_name) == 0) + { + GtkStyle *gsty = gtk_widget_get_style (FRAME_GTK_WIDGET (f)); + color->red = gsty->bg[GTK_STATE_SELECTED].red; + color->green = gsty->bg[GTK_STATE_SELECTED].green; + color->blue = gsty->bg[GTK_STATE_SELECTED].blue; + color->pixel = gsty->bg[GTK_STATE_SELECTED].pixel; + success_p = 1; + } + else if (strcmp ("gtk_selection_fg_color", color_name) == 0) + { + GtkStyle *gsty = gtk_widget_get_style (FRAME_GTK_WIDGET (f)); + color->red = gsty->fg[GTK_STATE_SELECTED].red; + color->green = gsty->fg[GTK_STATE_SELECTED].green; + color->blue = gsty->fg[GTK_STATE_SELECTED].blue; + color->pixel = gsty->fg[GTK_STATE_SELECTED].pixel; + success_p = 1; + } + } + + return success_p; +} + /*********************************************************************** @@ -898,6 +933,26 @@ gdk_colormap_query_color (map, pixel, c); } +/* Callback called when the gtk theme changes. + We notify lisp code so it can fix faces used for region for example. */ + +static void +style_changed_cb (GObject *go, + GParamSpec *spec, + gpointer user_data) +{ + struct input_event event; + GdkDisplay *gdpy = (GdkDisplay *) user_data; + const char *display_name = gdk_display_get_name (gdpy); + + EVENT_INIT (event); + event.kind = CONFIG_CHANGED_EVENT; + event.frame_or_window = make_string (display_name, strlen (display_name)); + /* Theme doesn't change often, so intern is called seldom. */ + event.arg = intern ("theme-name"); + kbd_buffer_store_event (&event); +} + /* Create and set up the GTK widgets for frame F. Return 0 if creation failed, non-zero otherwise. */ @@ -1023,6 +1078,22 @@ g_signal_connect (wtop, "query-tooltip", G_CALLBACK (qttip_cb), f); #endif + { + GdkScreen *screen = gtk_widget_get_screen (wtop); + GtkSettings *gs = gtk_settings_get_for_screen (screen); + /* Only connect this signal once per screen. */ + if (! g_signal_handler_find (G_OBJECT (gs), + G_SIGNAL_MATCH_FUNC, + 0, 0, 0, + G_CALLBACK (style_changed_cb), + 0)) + { + g_signal_connect (G_OBJECT (gs), "notify::gtk-theme-name", + G_CALLBACK (style_changed_cb), + gdk_screen_get_display (screen)); + } + } + UNBLOCK_INPUT; return 1; diff -r e2f8226efb99 -r be18c3b67d66 src/gtkutil.h --- a/src/gtkutil.h Wed Aug 11 14:34:46 2010 +0200 +++ b/src/gtkutil.h Wed Aug 11 20:28:10 2010 +0200 @@ -156,6 +156,9 @@ long flags, int user_position); extern void xg_set_background_color (FRAME_PTR f, unsigned long bg); +extern int xg_check_special_colors (struct frame *f, + const char *color_name, + XColor *color); extern void xg_set_frame_icon (FRAME_PTR f, Pixmap icon_pixmap, diff -r e2f8226efb99 -r be18c3b67d66 src/xfns.c --- a/src/xfns.c Wed Aug 11 14:34:46 2010 +0200 +++ b/src/xfns.c Wed Aug 11 20:28:10 2010 +0200 @@ -648,12 +648,16 @@ x_defined_color (struct frame *f, const char *color_name, XColor *color, int alloc_p) { - int success_p; + int success_p = 0; Display *dpy = FRAME_X_DISPLAY (f); Colormap cmap = FRAME_X_COLORMAP (f); BLOCK_INPUT; - success_p = XParseColor (dpy, cmap, color_name, color); +#ifdef USE_GTK + success_p = xg_check_special_colors (f, color_name, color); +#endif + if (!success_p) + success_p = XParseColor (dpy, cmap, color_name, color); if (success_p && alloc_p) success_p = x_alloc_nearest_color (f, cmap, color); UNBLOCK_INPUT;