[gtk+] Improve CSD decorations without a compositor



commit 03213b9509fc1df16c66194ea168aed6c15110e9
Author: Olivier Fourdan <fourdan xfce org>
Date:   Wed Mar 11 13:52:21 2015 +0100

    Improve CSD decorations without a compositor
    
    It turned out that using mwm hints to instruct wms to
    create border-only decorations is not really working
    universally. So, instead of doing this, render a solid
    frame without shadow on the client-side to handle this
    case.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=746222
    
    Signed-off-by: Olivier Fourdan <fourdan xfce org>

 gtk/gtkwindow.c                          |   87 ++++++++++++++++--------------
 gtk/theme/Adwaita/_common.scss           |    7 +++
 gtk/theme/Adwaita/gtk-contained-dark.css |    6 ++
 gtk/theme/Adwaita/gtk-contained.css      |    6 ++
 gtk/theme/HighContrast/_common.scss      |    7 +++
 gtk/theme/HighContrast/gtk.css           |    6 ++
 gtk/theme/Raleigh/gtk-default.css        |    9 +++
 7 files changed, 88 insertions(+), 40 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 4378ca6..05b11b5 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -227,8 +227,7 @@ struct _GtkWindowPrivate
   guint    gravity                   : 5; /* GdkGravity */
   guint    csd_requested             : 1;
   guint    client_decorated          : 1; /* Decorations drawn client-side */
-  guint    custom_title              : 1; /* app-provided titlebar if CSD can't
-                                           * be enabled */
+  guint    use_client_shadow         : 1; /* Decorations use client-side shadows */
   guint    maximized                 : 1;
   guint    fullscreen                : 1;
   guint    tiled                     : 1;
@@ -3947,7 +3946,7 @@ unset_titlebar (GtkWindow *window)
 }
 
 static gboolean
-gtk_window_supports_csd (GtkWindow *window)
+gtk_window_supports_client_shadow (GtkWindow *window)
 {
   GtkWidget *widget = GTK_WIDGET (window);
 
@@ -3997,13 +3996,21 @@ gtk_window_enable_csd (GtkWindow *window)
   GtkWidget *widget = GTK_WIDGET (window);
   GdkVisual *visual;
 
-  /* We need a visual with alpha */
-  visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget));
-  g_assert (visual != NULL);
-  gtk_widget_set_visual (widget, visual);
+  /* We need a visual with alpha for client shadows */
+  if (priv->use_client_shadow)
+    {
+      visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget));
+      if (visual != NULL)
+        gtk_widget_set_visual (widget, visual);
+
+      gtk_style_context_add_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_CSD);
+    }
+  else
+    {
+      gtk_style_context_add_class (gtk_widget_get_style_context (widget), "solid-csd");
+    }
 
   priv->client_decorated = TRUE;
-  gtk_style_context_add_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_CSD);
 }
 
 static void
@@ -4038,7 +4045,6 @@ gtk_window_set_titlebar (GtkWindow *window,
 {
   GtkWidget *widget = GTK_WIDGET (window);
   GtkWindowPrivate *priv = window->priv;
-  GdkVisual *visual;
   gboolean was_mapped;
 
   g_return_if_fail (GTK_IS_WINDOW (window));
@@ -4059,18 +4065,15 @@ gtk_window_set_titlebar (GtkWindow *window,
 
   if (titlebar == NULL)
     {
-      priv->custom_title = FALSE;
       priv->client_decorated = FALSE;
       gtk_style_context_remove_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_CSD);
 
       goto out;
     }
 
-  if (gtk_window_supports_csd (window))
-    gtk_window_enable_csd (window);
-  else
-    priv->custom_title = TRUE;
+  priv->use_client_shadow = gtk_window_supports_client_shadow (window);
 
+  gtk_window_enable_csd (window);
   priv->title_box = titlebar;
   gtk_widget_set_parent (priv->title_box, widget);
   if (GTK_IS_HEADER_BAR (titlebar))
@@ -4080,10 +4083,6 @@ gtk_window_set_titlebar (GtkWindow *window,
       on_titlebar_title_notify (GTK_HEADER_BAR (titlebar), NULL, window);
     }
 
-  visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget));
-  if (visual)
-    gtk_widget_set_visual (widget, visual);
-
   gtk_style_context_add_class (gtk_widget_get_style_context (titlebar),
                                GTK_STYLE_CLASS_TITLEBAR);
 
@@ -4171,8 +4170,6 @@ gtk_window_set_decorated (GtkWindow *window,
         {
           if (priv->client_decorated)
             gdk_window_set_decorations (gdk_window, 0);
-          else if (priv->custom_title)
-            gdk_window_set_decorations (gdk_window, GDK_DECOR_BORDER);
           else
             gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL);
         }
@@ -5809,7 +5806,7 @@ create_decoration (GtkWidget *widget)
   GtkWindow *window = GTK_WINDOW (widget);
   GtkWindowPrivate *priv = window->priv;
 
-  if (!gtk_window_supports_csd (window))
+  if (!gtk_window_supports_client_shadow (window))
     return;
 
   gtk_window_enable_csd (window);
@@ -6626,7 +6623,7 @@ update_border_windows (GtkWindow *window)
                               border.right + handle, border.top + handle);
       gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_SOUTH_WEST],
                               window_border.left - border.left, window_border.top + height - handle,
-                              window_border.left + handle, border.bottom + handle);
+                              border.left + handle, border.bottom + handle);
       gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_SOUTH_EAST],
                               window_border.left + width - handle, window_border.top + height - handle,
                               border.right + handle, border.bottom + handle);
@@ -6892,7 +6889,7 @@ update_realized_window_properties (GtkWindow     *window,
 {
   GtkWindowPrivate *priv = window->priv;
 
-  if (priv->client_decorated)
+  if (priv->client_decorated && priv->use_client_shadow)
     update_shadow_width (window, window_border);
 
   update_opaque_region (window, window_border, child_allocation);
@@ -7035,8 +7032,7 @@ gtk_window_realize (GtkWidget *widget)
                                 GDK_FOCUS_CHANGE_MASK |
                                 GDK_STRUCTURE_MASK);
 
-      if (priv->decorated &&
-          (priv->client_decorated || priv->custom_title))
+      if (priv->decorated && priv->client_decorated)
         attributes.event_mask |= GDK_POINTER_MOTION_MASK;
 
       attributes.type_hint = priv->type_hint;
@@ -7111,8 +7107,6 @@ gtk_window_realize (GtkWidget *widget)
 
   if (!priv->decorated || priv->client_decorated)
     gdk_window_set_decorations (gdk_window, 0);
-  else if (priv->custom_title)
-    gdk_window_set_decorations (gdk_window, GDK_DECOR_BORDER);
 
   if (!priv->deletable)
     gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
@@ -9689,18 +9683,31 @@ gtk_window_draw (GtkWidget *widget,
 
           add_window_frame_style_class (context);
 
-          gtk_render_background (context, cr,
-                                 window_border.left, window_border.top,
-                                 allocation.width -
-                                 (window_border.left + window_border.right),
-                                 allocation.height -
-                                 (window_border.top + window_border.bottom));
-          gtk_render_frame (context, cr,
-                            window_border.left, window_border.top,
-                            allocation.width -
-                            (window_border.left + window_border.right),
-                            allocation.height -
-                            (window_border.top + window_border.bottom));
+          if (priv->use_client_shadow)
+            {
+              gtk_render_background (context, cr,
+                                     window_border.left, window_border.top,
+                                     allocation.width -
+                                     (window_border.left + window_border.right),
+                                     allocation.height -
+                                     (window_border.top + window_border.bottom));
+              gtk_render_frame (context, cr,
+                                window_border.left, window_border.top,
+                                allocation.width -
+                                (window_border.left + window_border.right),
+                                allocation.height -
+                                (window_border.top + window_border.bottom));
+            }
+          else
+            {
+              gtk_render_background (context, cr, 0, 0,
+                                     allocation.width,
+                                     allocation.height);
+
+              gtk_render_frame (context, cr, 0, 0,
+                                allocation.width,
+                                allocation.height);
+            }
 
           gtk_style_context_restore (context);
         }
@@ -10466,7 +10473,7 @@ gtk_window_set_screen (GtkWindow *window,
     }
   g_object_notify (G_OBJECT (window), "screen");
 
-  if (was_rgba)
+  if (was_rgba && priv->use_client_shadow)
     {
       GdkVisual *visual;
 
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index a7860b2..3c94d30 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -3227,6 +3227,13 @@ GtkVolumeButton.button { padding: 8px; }
                   0 0 0 1px transparentize($_wm_border,0.1);
     }
   }
+  &.solid-csd {
+    border-radius: 0;
+    margin: 4px;
+    background-color: $backdrop_bg_color;
+    border: solid 1px $backdrop_borders_color;
+    box-shadow: none;
+  }
 }
 
 // Window Close button
diff --git a/gtk/theme/Adwaita/gtk-contained-dark.css b/gtk/theme/Adwaita/gtk-contained-dark.css
index 4706863..d4e0193 100644
--- a/gtk/theme/Adwaita/gtk-contained-dark.css
+++ b/gtk/theme/Adwaita/gtk-contained-dark.css
@@ -4245,6 +4245,12 @@ GtkVolumeButton.button, .header-bar GtkVolumeButton.button.titlebutton,
   .window-frame.csd.message-dialog {
     border-radius: 7px;
     box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(28, 31, 31, 0.8); }
+  .window-frame.solid-csd {
+    border-radius: 0;
+    margin: 4px;
+    background-color: #393f3f;
+    border: solid 1px #1e2222;
+    box-shadow: none; }
 
 .header-bar .titlebutton.button,
 .titlebar .titlebutton.button {
diff --git a/gtk/theme/Adwaita/gtk-contained.css b/gtk/theme/Adwaita/gtk-contained.css
index fa74563..4b5cfd7 100644
--- a/gtk/theme/Adwaita/gtk-contained.css
+++ b/gtk/theme/Adwaita/gtk-contained.css
@@ -4417,6 +4417,12 @@ GtkVolumeButton.button, .header-bar GtkVolumeButton.button.titlebutton,
   .window-frame.csd.message-dialog {
     border-radius: 7px;
     box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.13); }
+  .window-frame.solid-csd {
+    border-radius: 0;
+    margin: 4px;
+    background-color: #ededed;
+    border: solid 1px #a8a8a8;
+    box-shadow: none; }
 
 .header-bar .titlebutton.button,
 .titlebar .titlebutton.button {
diff --git a/gtk/theme/HighContrast/_common.scss b/gtk/theme/HighContrast/_common.scss
index 4e4f46f..5723eee 100644
--- a/gtk/theme/HighContrast/_common.scss
+++ b/gtk/theme/HighContrast/_common.scss
@@ -2260,6 +2260,13 @@ GtkColorChooserWidget #add-color-button {
       box-shadow: none;
     }
   }
+  &.solid-csd {
+    border-radius: 0;
+    margin: 4px;
+    background-color: $backdrop_bg_color;
+    border: solid 1px $backdrop_borders_color;
+    box-shadow: none;
+  }
 }
 
 // Window Close button
diff --git a/gtk/theme/HighContrast/gtk.css b/gtk/theme/HighContrast/gtk.css
index 1d606b8..6a0df81 100644
--- a/gtk/theme/HighContrast/gtk.css
+++ b/gtk/theme/HighContrast/gtk.css
@@ -2511,6 +2511,12 @@ GtkColorChooserWidget #add-color-button {
   .window-frame.csd.tooltip {
     border-radius: 5px;
     box-shadow: none; }
+  .window-frame.solid-csd {
+    border-radius: 0;
+    margin: 4px;
+    background-color: #fff;
+    border: solid 1px #8b8b8b;
+    box-shadow: none; }
 
 .button.titlebutton {
   padding: 8px;
diff --git a/gtk/theme/Raleigh/gtk-default.css b/gtk/theme/Raleigh/gtk-default.css
index 7dad942..cae7da6 100644
--- a/gtk/theme/Raleigh/gtk-default.css
+++ b/gtk/theme/Raleigh/gtk-default.css
@@ -872,3 +872,12 @@ GtkCalendar.button:hover {
 .window-frame:backdrop {
   box-shadow: 0 2px 5px 1px alpha(black, 0.5);
 }
+
+.window-frame.solid-csd {
+  border-radius: 0;
+  margin: 2px;
+  background-color: @bg_color;
+  border-style: outset;
+  border-width: 2px;
+  box-shadow: none;
+}


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