Jump to content
Forums in Read-Only Mode - Please use Reddit ×
  • 0

Disable GTK+ 3 CSD in non-GTK+3 desktops (e.g. MATE or XFCE)


jorgicio

Question

Hi! Today I tried a trick to disable (optionally) the CSD (Client-Side Decorations) in GTK+3 apps, which is forced since 3.12. For that, you need to patch it first. Luckily, the GTK+3 ebuild contains the epatch_user instruction, so it lets us apply our patches.

 

The patch is the following:

diff -r 74e017a49c0c gtk/gtkdialog.c
--- a/gtk/gtkdialog.c	Sat Sep 27 07:35:24 2014 +0300
+++ b/gtk/gtkdialog.c	Wed Oct 01 17:34:31 2014 +0300
@@ -245,11 +245,12 @@
                     gint       use_header_bar)
 {
   GtkDialogPrivate *priv = dialog->priv;
+  gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
 
   if (use_header_bar == -1)
     return;
 
-  priv->use_header_bar = use_header_bar;
+  priv->use_header_bar = disable_csd ? FALSE : use_header_bar;
 }
 
 /* A convenience helper for built-in dialogs */
@@ -257,10 +258,12 @@
 gtk_dialog_set_use_header_bar_from_setting (GtkDialog *dialog)
 {
   GtkDialogPrivate *priv = dialog->priv;
+  gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
 
   g_assert (!priv->constructed);
 
-  g_object_get (gtk_widget_get_settings (GTK_WIDGET (dialog)),
+  if (!disable_csd)
+    g_object_get (gtk_widget_get_settings (GTK_WIDGET (dialog)),
                 "gtk-dialogs-use-header", &priv->use_header_bar,
                 NULL);
 }
@@ -293,11 +296,12 @@
 {
   GtkDialog *dialog = GTK_DIALOG (object);
   GtkDialogPrivate *priv = dialog->priv;
+  gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
 
   switch (prop_id)
     {
     case PROP_USE_HEADER_BAR:
-      g_value_set_int (value, priv->use_header_bar);
+      g_value_set_int (value, disable_csd ? FALSE : priv->use_header_bar);
       break;
 
     default:
@@ -707,9 +711,10 @@
 static void
 gtk_dialog_init (GtkDialog *dialog)
 {
+  gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
   dialog->priv = gtk_dialog_get_instance_private (dialog);
 
-  dialog->priv->use_header_bar = -1;
+  dialog->priv->use_header_bar = disable_csd ? FALSE : -1;
   dialog->priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
   gtk_widget_init_template (GTK_WIDGET (dialog));
diff -r 74e017a49c0c gtk/gtkwindow.c
--- a/gtk/gtkwindow.c	Sat Sep 27 07:35:24 2014 +0300
+++ b/gtk/gtkwindow.c	Wed Oct 01 17:34:31 2014 +0300
@@ -3822,9 +3822,13 @@
 #ifdef GDK_WINDOWING_X11
   if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (widget)))
     {
+      gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
       GdkScreen *screen;
       GdkVisual *visual;
 
+      if (disable_csd)
+        return FALSE;
+
       screen = gtk_widget_get_screen (widget);
 
       if (!gdk_screen_is_composited (screen))
@@ -3861,6 +3865,10 @@
   GtkWindowPrivate *priv = window->priv;
   GtkWidget *widget = GTK_WIDGET (window);
   GdkVisual *visual;
+  gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
+  
+  if (disable_csd)
+    return;
 
   /* We need a visual with alpha */
   visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget));
@@ -3905,6 +3913,7 @@
   GtkWindowPrivate *priv = window->priv;
   GdkVisual *visual;
   gboolean was_mapped;
+  gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
 
   g_return_if_fail (GTK_IS_WINDOW (window));
 
@@ -3922,7 +3931,7 @@
 
   unset_titlebar (window);
 
-  if (titlebar == NULL)
+  if (disable_csd || titlebar == NULL)
     {
       priv->custom_title = FALSE;
       priv->client_decorated = FALSE;
@@ -4005,11 +4014,12 @@
   gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
   if (gdk_window)
     {
+      gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
       if (priv->decorated)
         {
-          if (priv->client_decorated)
+          if (priv->client_decorated && !disable_csd)
             gdk_window_set_decorations (gdk_window, 0);
-          else if (priv->custom_title)
+          else if (priv->custom_title && !disable_csd)
             gdk_window_set_decorations (gdk_window, GDK_DECOR_BORDER);
           else
             gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL);
@@ -5611,6 +5621,10 @@
 {
   GtkWindowPrivate *priv = window->priv;
   const gchar *csd_env;
+  gboolean disable_csd = g_strcmp0 (g_getenv ("GTK_DISABLE_CSD"), "1") == 0;
+
+  if (disable_csd)
+    return FALSE;
 
   if (priv->csd_requested)
     return TRUE;

You can save it with thenameyouwant.patch and put it inside /etc/portage/patches/x11-libs/gtk+:3/ (if that path doesn't exist, create those directories).

Then, reinstall it:

emerge -1 gtk+:3

Then, you have 2 options: As a system environment variable, you can create a file named gtk3nocsd.sh with the following content:

#!/bin/sh
export GTK_DISABLE_CSD=1

And put it into /etc/profile.d.

 

Or, an alternative at user level, you can add this line in your .xprofile or .profile in your $HOME:

export GTK_DISABLE_CSD=1

After GTK+3 recompiled successfully, restart the session, and voil?!

 

PS: The CSS method just partially solves the problem, but not the shadow drawing, which is delayed. This won't happen with this tweak.

Link to comment
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

×
×
  • Create New...