diff src/gtkutil.c @ 109749:be18c3b67d66

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.
author Jan D <jan.h.d@swipnet.se>
date Wed, 11 Aug 2010 20:28:10 +0200
parents e2f8226efb99
children c917fbc9b294
line wrap: on
line diff
--- 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;