[gtk+/gtk-3-0] window: Export theme variant to X11



commit e5f18717488f8a9b685dac1865bbe6c408ecc655
Author: Florian Müllner <fmuellner gnome org>
Date:   Sun Mar 20 14:37:27 2011 +0100

    window: Export theme variant to X11
    
    The metacity theme format allows to use colors from the current
    GTK+ theme in window decorations. Since GTK+ now gained support
    for dark theme variants, window managers using that theme format
    (metacity, mutter, compiz via gtk-window-decorator) should be able
    to use colors from the correct variant; so in case a variant is
    requested, export it in the _GTK_THEME_VARIANT property on
    toplevel windows.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=645354

 docs/reference/gdk/gdk3-sections.txt |    1 +
 gdk/gdk.symbols                      |    1 +
 gdk/x11/gdkwindow-x11.c              |   37 ++++++++++++++++++++++++++
 gdk/x11/gdkx11window.h               |    2 +
 gtk/gtkwindow.c                      |   48 ++++++++++++++++++++++++++++++++++
 5 files changed, 89 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt
index 2b41204..a05b1d1 100644
--- a/docs/reference/gdk/gdk3-sections.txt
+++ b/docs/reference/gdk/gdk3-sections.txt
@@ -949,6 +949,7 @@ gdk_x11_screen_supports_net_wm_hint
 gdk_x11_window_foreign_new_for_display
 gdk_x11_window_lookup_for_display
 gdk_x11_window_get_xid
+gdk_x11_window_set_theme_variant_gtk_only
 gdk_x11_window_set_user_time
 gdk_x11_window_move_to_current_desktop
 gdk_x11_get_default_root_xwindow
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index b159b1c..757a0de 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -564,6 +564,7 @@ gdk_x11_window_lookup_for_display
 gdk_x11_window_get_type
 gdk_x11_window_get_xid
 gdk_x11_window_move_to_current_desktop
+gdk_x11_window_set_theme_variant_gtk_only
 gdk_x11_window_set_user_time
 gdk_x11_xatom_to_atom
 gdk_x11_xatom_to_atom_for_display
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 6cd5573..fcca9d8 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -3086,6 +3086,43 @@ gdk_x11_window_set_user_time (GdkWindow *window,
     toplevel->user_time = timestamp_long;
 }
 
+/*
+ * gdk_x11_window_set_theme_variant_gtk_only:
+ * @window: a #GdkWindow
+ * @variant: the theme variant to export
+ *
+ * GTK+ applications can request a dark theme variant. In order to
+ * make other applications - namely window managers using GTK+ for
+ * themeing - aware of this choice, GTK+ uses this function to
+ * export the requested theme variant as _GTK_THEME_VARIANT property
+ * on toplevel windows.
+ *
+ * Note that this property is automatically updated by GTK+, so this
+ * function should only be used by applications which do not use GTK+
+ * to create toplevel windows.
+ */
+void
+gdk_x11_window_set_theme_variant_gtk_only (GdkWindow *window,
+                                           char      *variant)
+{
+  GdkDisplay *display = gdk_window_get_display (window);
+
+  if (variant != NULL)
+    {
+      XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+                       GDK_WINDOW_XID (window),
+                       gdk_x11_get_xatom_by_name_for_display (display, "_GTK_THEME_VARIANT"),
+                       gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
+                       PropModeReplace, (guchar *)variant, strlen (variant));
+    }
+  else
+    {
+      XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
+                       GDK_WINDOW_XID (window),
+                       gdk_x11_get_xatom_by_name_for_display (display, "_GTK_THEME_VARIANT"));
+    }
+}
+
 #define GDK_SELECTION_MAX_SIZE(display)                                 \
   MIN(262144,                                                           \
       XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0     \
diff --git a/gdk/x11/gdkx11window.h b/gdk/x11/gdkx11window.h
index ecfbea5..fbad024 100644
--- a/gdk/x11/gdkx11window.h
+++ b/gdk/x11/gdkx11window.h
@@ -57,6 +57,8 @@ GType    gdk_x11_window_get_type          (void);
 Window   gdk_x11_window_get_xid           (GdkWindow   *window);
 void     gdk_x11_window_set_user_time     (GdkWindow   *window,
                                            guint32      timestamp);
+void     gdk_x11_window_set_theme_variant_gtk_only (GdkWindow *window,
+                                                    char      *variant);
 void     gdk_x11_window_move_to_current_desktop (GdkWindow   *window);
 
 /**
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 6d42d42..94c60f9 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -413,6 +413,10 @@ static GtkKeyHash *gtk_window_get_key_hash        (GtkWindow   *window);
 static void        gtk_window_free_key_hash       (GtkWindow   *window);
 static void	   gtk_window_on_composited_changed (GdkScreen *screen,
 						     GtkWindow *window);
+static void        gtk_window_on_theme_variant_changed (GtkSettings *settings,
+                                                        GParamSpec  *pspec,
+                                                        GtkWindow   *window);
+static void        gtk_window_set_theme_variant         (GtkWindow  *window);
 
 static GSList      *toplevel_list = NULL;
 static guint        window_signals[LAST_SIGNAL] = { 0 };
@@ -1111,6 +1115,12 @@ gtk_window_init (GtkWindow *window)
   if (priv->screen)
     g_signal_connect (priv->screen, "composited-changed",
                       G_CALLBACK (gtk_window_on_composited_changed), window);
+
+#ifdef GDK_WINDOWING_X11
+  g_signal_connect (gtk_settings_get_default (),
+                    "notify::gtk-application-prefer-dark-theme",
+                    G_CALLBACK (gtk_window_on_theme_variant_changed), window);
+#endif
 }
 
 static void
@@ -4531,6 +4541,12 @@ gtk_window_finalize (GObject *object)
 
   g_free (priv->startup_id);
 
+#ifdef GDK_WINDOWING_X11
+  g_signal_handlers_disconnect_by_func (gtk_settings_get_default (),
+                                        gtk_window_on_theme_variant_changed,
+                                        window);
+#endif
+
   G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
 }
 
@@ -4696,6 +4712,9 @@ gtk_window_map (GtkWidget *widget)
 
   gdk_window_set_keep_below (toplevel, priv->below_initially);
 
+  if (priv->type == GTK_WINDOW_TOPLEVEL)
+    gtk_window_set_theme_variant (window);
+
   /* No longer use the default settings */
   priv->need_default_size = FALSE;
   priv->need_default_position = FALSE;
@@ -8009,6 +8028,35 @@ gtk_window_set_screen (GtkWindow *window,
 }
 
 static void
+gtk_window_set_theme_variant (GtkWindow *window)
+{
+#ifdef GDK_WINDOWING_X11
+  GdkWindow *gdk_window;
+  gboolean   dark_theme_requested;
+
+  g_object_get (gtk_settings_get_default (),
+                "gtk-application-prefer-dark-theme", &dark_theme_requested,
+                NULL);
+
+  gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+
+  if (GDK_IS_X11_WINDOW (gdk_window))
+    gdk_x11_window_set_theme_variant_gtk_only (gdk_window,
+                                               dark_theme_requested ? "dark"
+                                                                    : NULL);
+#endif
+}
+
+static void
+gtk_window_on_theme_variant_changed (GtkSettings *settings,
+                                     GParamSpec  *pspec,
+                                     GtkWindow   *window)
+{
+  if (window->priv->type == GTK_WINDOW_TOPLEVEL)
+    gtk_window_set_theme_variant (window);
+}
+
+static void
 gtk_window_on_composited_changed (GdkScreen *screen,
 				  GtkWindow *window)
 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]