[mutter] theme: Use style information from GTK+



commit 6eda784cf06c62936b018bf2784b53320b652a27
Author: Florian Müllner <fmuellner gnome org>
Date:   Tue Sep 23 04:20:22 2014 +0200

    theme: Use style information from GTK+
    
    We now have everything in place to pick up geometry and drawing
    information from GTK+ rather than the metacity theme, so do just
    that; the metacity theme is now only used for some constants
    (title_scale, hide_buttons, ...), which we will replace soon.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=741917

 src/ui/frames.c        |    8 +-
 src/ui/theme-private.h |    5 +-
 src/ui/theme.c         |  311 +++++++++++++++++++-----------------------------
 src/ui/ui.c            |   11 +-
 4 files changed, 135 insertions(+), 200 deletions(-)
---
diff --git a/src/ui/frames.c b/src/ui/frames.c
index 597b055..f6d0094 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -479,6 +479,7 @@ meta_frames_calc_geometry (MetaFrames        *frames,
   meta_prefs_get_button_layout (&button_layout);
 
   meta_theme_calc_geometry (meta_theme_get_current (),
+                            frame->style_info,
                             type,
                             frame->text_height,
                             flags,
@@ -646,6 +647,7 @@ meta_ui_frame_get_borders (MetaFrames *frames,
    * window size
    */
   meta_theme_get_frame_borders (meta_theme_get_current (),
+                                frame->style_info,
                                 type,
                                 frame->text_height,
                                 flags,
@@ -1587,7 +1589,7 @@ get_visible_frame_border_region (MetaUIFrame *frame)
                  META_CORE_GET_FRAME_RECT, &frame_rect,
                  META_CORE_GET_END);
 
-  meta_theme_get_frame_borders (meta_theme_get_current (),
+  meta_theme_get_frame_borders (meta_theme_get_current (), frame->style_info,
                                 type, frame->text_height, flags,
                                 &borders);
 
@@ -1755,7 +1757,6 @@ meta_frames_paint (MetaFrames   *frames,
   MetaFrameFlags flags;
   MetaFrameType type;
   GdkPixbuf *mini_icon;
-  GdkPixbuf *icon;
   int w, h;
   MetaButtonState button_states[META_BUTTON_TYPE_LAST];
   int i;
@@ -1818,7 +1819,6 @@ meta_frames_paint (MetaFrames   *frames,
                  META_CORE_GET_FRAME_FLAGS, &flags,
                  META_CORE_GET_FRAME_TYPE, &type,
                  META_CORE_GET_MINI_ICON, &mini_icon,
-                 META_CORE_GET_ICON, &icon,
                  META_CORE_GET_CLIENT_WIDTH, &w,
                  META_CORE_GET_CLIENT_HEIGHT, &h,
                  META_CORE_GET_END);
@@ -1837,7 +1837,7 @@ meta_frames_paint (MetaFrames   *frames,
                          frame->text_height,
                          &button_layout,
                          button_states,
-                         mini_icon, icon);
+                         mini_icon);
 }
 
 static gboolean
diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h
index 0c4e9a0..4d7091b 100644
--- a/src/ui/theme-private.h
+++ b/src/ui/theme-private.h
@@ -1068,16 +1068,17 @@ void meta_theme_draw_frame (MetaTheme              *theme,
                             int                     text_height,
                             const MetaButtonLayout *button_layout,
                             MetaButtonState         button_states[META_BUTTON_TYPE_LAST],
-                            GdkPixbuf              *mini_icon,
-                            GdkPixbuf              *icon);
+                            GdkPixbuf              *mini_icon);
 
 void meta_theme_get_frame_borders (MetaTheme         *theme,
+                                   MetaStyleInfo     *style_info,
                                    MetaFrameType      type,
                                    int                text_height,
                                    MetaFrameFlags     flags,
                                    MetaFrameBorders  *borders);
 
 void meta_theme_calc_geometry (MetaTheme              *theme,
+                               MetaStyleInfo          *style_info,
                                MetaFrameType           type,
                                int                     text_height,
                                MetaFrameFlags          flags,
diff --git a/src/ui/theme.c b/src/ui/theme.c
index de3d7bf..1a94df4 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -609,7 +609,8 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout,
 }
 
 static void
-meta_frame_layout_calc_geometry (const MetaFrameLayout  *layout,
+meta_frame_layout_calc_geometry (MetaFrameLayout        *layout,
+                                 MetaStyleInfo          *style_info,
                                  int                     text_height,
                                  MetaFrameFlags          flags,
                                  int                     client_width,
@@ -639,6 +640,8 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout  *layout,
 
   MetaFrameBorders borders;
 
+  meta_frame_layout_sync_with_style (layout, style_info, flags);
+
   meta_frame_layout_get_borders (layout, text_height,
                                  flags, type,
                                  &borders);
@@ -4250,28 +4253,21 @@ get_button_rect (MetaButtonType           type,
 }
 
 static void
-meta_frame_style_draw_with_style (MetaFrameStyle          *style,
+meta_frame_style_draw_with_style (MetaFrameStyle          *frame_style,
                                   MetaStyleInfo           *style_info,
                                   cairo_t                 *cr,
                                   const MetaFrameGeometry *fgeom,
-                                  int                      client_width,
-                                  int                      client_height,
                                   PangoLayout             *title_layout,
-                                  int                      text_height,
+                                  MetaFrameFlags           flags,
                                   MetaButtonState          button_states[META_BUTTON_TYPE_LAST],
-                                  GdkPixbuf               *mini_icon,
-                                  GdkPixbuf               *icon)
+                                  GdkPixbuf               *mini_icon)
 {
-  int i, j;
+  GtkStyleContext *style;
+  GtkStateFlags state;
+  MetaButtonType button_type;
   GdkRectangle visible_rect;
   GdkRectangle titlebar_rect;
-  GdkRectangle left_titlebar_edge;
-  GdkRectangle right_titlebar_edge;
-  GdkRectangle bottom_titlebar_edge;
-  GdkRectangle top_titlebar_edge;
-  GdkRectangle left_edge, right_edge, bottom_edge;
-  PangoRectangle logical_rect;
-  MetaDrawInfo draw_info;
+  GdkRectangle button_rect;
   const MetaFrameBorders *borders;
 
   borders = &fgeom->borders;
@@ -4281,211 +4277,144 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
   visible_rect.width = fgeom->width - borders->invisible.left - borders->invisible.right;
   visible_rect.height = fgeom->height - borders->invisible.top - borders->invisible.bottom;
 
+  meta_style_info_set_flags (style_info, flags);
+
+  style = style_info->styles[META_STYLE_ELEMENT_FRAME];
+  gtk_render_background (style, cr,
+                         visible_rect.x, visible_rect.y,
+                         visible_rect.width, visible_rect.height);
+  gtk_render_frame (style, cr,
+                    visible_rect.x, visible_rect.y,
+                    visible_rect.width, visible_rect.height);
+
   titlebar_rect.x = visible_rect.x;
   titlebar_rect.y = visible_rect.y;
   titlebar_rect.width = visible_rect.width;
   titlebar_rect.height = borders->visible.top;
 
-  left_titlebar_edge.x = titlebar_rect.x;
-  left_titlebar_edge.y = titlebar_rect.y + fgeom->top_titlebar_edge;
-  left_titlebar_edge.width = fgeom->left_titlebar_edge;
-  left_titlebar_edge.height = titlebar_rect.height - fgeom->top_titlebar_edge - fgeom->bottom_titlebar_edge;
-
-  right_titlebar_edge.y = left_titlebar_edge.y;
-  right_titlebar_edge.height = left_titlebar_edge.height;
-  right_titlebar_edge.width = fgeom->right_titlebar_edge;
-  right_titlebar_edge.x = titlebar_rect.x + titlebar_rect.width - right_titlebar_edge.width;
-
-  top_titlebar_edge.x = titlebar_rect.x;
-  top_titlebar_edge.y = titlebar_rect.y;
-  top_titlebar_edge.width = titlebar_rect.width;
-  top_titlebar_edge.height = fgeom->top_titlebar_edge;
-
-  bottom_titlebar_edge.x = titlebar_rect.x;
-  bottom_titlebar_edge.width = titlebar_rect.width;
-  bottom_titlebar_edge.height = fgeom->bottom_titlebar_edge;
-  bottom_titlebar_edge.y = titlebar_rect.y + titlebar_rect.height - bottom_titlebar_edge.height;
-
-  left_edge.x = visible_rect.x;
-  left_edge.y = visible_rect.y + borders->visible.top;
-  left_edge.width = borders->visible.left;
-  left_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom;
-
-  right_edge.x = visible_rect.x + visible_rect.width - borders->visible.right;
-  right_edge.y = visible_rect.y + borders->visible.top;
-  right_edge.width = borders->visible.right;
-  right_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom;
-
-  bottom_edge.x = visible_rect.x;
-  bottom_edge.y = visible_rect.y + visible_rect.height - borders->visible.bottom;
-  bottom_edge.width = visible_rect.width;
-  bottom_edge.height = borders->visible.bottom;
-
-  if (title_layout)
-    pango_layout_get_pixel_extents (title_layout,
-                                    NULL, &logical_rect);
-
-  draw_info.mini_icon = mini_icon;
-  draw_info.icon = icon;
-  draw_info.title_layout = title_layout;
-  draw_info.title_layout_width = title_layout ? logical_rect.width : 0;
-  draw_info.title_layout_height = title_layout ? logical_rect.height : 0;
-  draw_info.fgeom = fgeom;
-
-  /* The enum is in the order the pieces should be rendered. */
-  i = 0;
-  while (i < META_FRAME_PIECE_LAST)
+  style = style_info->styles[META_STYLE_ELEMENT_TITLEBAR];
+  gtk_render_background (style, cr,
+                         titlebar_rect.x, titlebar_rect.y,
+                         titlebar_rect.width, titlebar_rect.height);
+  gtk_render_frame (style, cr,
+                    titlebar_rect.x, titlebar_rect.y,
+                    titlebar_rect.width, titlebar_rect.height);
+
+  if (frame_style->layout->has_title && title_layout)
     {
-      GdkRectangle rect;
-
-      switch ((MetaFramePiece) i)
-        {
-        case META_FRAME_PIECE_ENTIRE_BACKGROUND:
-          rect = visible_rect;
-          break;
-
-        case META_FRAME_PIECE_TITLEBAR:
-          rect = titlebar_rect;
-          break;
+      PangoRectangle logical;
+      int text_width, x, y;
 
-        case META_FRAME_PIECE_LEFT_TITLEBAR_EDGE:
-          rect = left_titlebar_edge;
-          break;
+      pango_layout_set_width (title_layout, -1);
+      pango_layout_get_pixel_extents (title_layout, NULL, &logical);
 
-        case META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE:
-          rect = right_titlebar_edge;
-          break;
+      text_width = MIN(fgeom->title_rect.width, logical.width);
 
-        case META_FRAME_PIECE_TOP_TITLEBAR_EDGE:
-          rect = top_titlebar_edge;
-          break;
+      if (text_width < logical.width)
+        pango_layout_set_width (title_layout, PANGO_SCALE * text_width);
 
-        case META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE:
-          rect = bottom_titlebar_edge;
-          break;
-
-        case META_FRAME_PIECE_TITLEBAR_MIDDLE:
-          rect.x = left_titlebar_edge.x + left_titlebar_edge.width;
-          rect.y = top_titlebar_edge.y + top_titlebar_edge.height;
-          rect.width = titlebar_rect.width - left_titlebar_edge.width -
-            right_titlebar_edge.width;
-          rect.height = titlebar_rect.height - top_titlebar_edge.height - bottom_titlebar_edge.height;
-          break;
+      /* Center within the frame if possible */
+      x = titlebar_rect.x + (titlebar_rect.width - text_width) / 2;
+      y = titlebar_rect.y + (titlebar_rect.height - logical.height) / 2;
 
-        case META_FRAME_PIECE_TITLE:
-          rect = fgeom->title_rect;
-          break;
+      if (x < fgeom->title_rect.x)
+        x = fgeom->title_rect.x;
+      else if (x + text_width > fgeom->title_rect.x + fgeom->title_rect.width)
+        x = fgeom->title_rect.x + fgeom->title_rect.width - text_width;
 
-        case META_FRAME_PIECE_LEFT_EDGE:
-          rect = left_edge;
-          break;
+      style = style_info->styles[META_STYLE_ELEMENT_TITLE];
+      gtk_render_layout (style, cr, x, y, title_layout);
+    }
 
-        case META_FRAME_PIECE_RIGHT_EDGE:
-          rect = right_edge;
-          break;
+  style = style_info->styles[META_STYLE_ELEMENT_BUTTON];
+  state = gtk_style_context_get_state (style);
+  for (button_type = META_BUTTON_TYPE_CLOSE; button_type < META_BUTTON_TYPE_LAST; button_type++)
+    {
+      MetaButtonState button_state;
 
-        case META_FRAME_PIECE_BOTTOM_EDGE:
-          rect = bottom_edge;
-          break;
+      get_button_rect (button_type, fgeom, 0, &button_rect);
 
-        case META_FRAME_PIECE_OVERLAY:
-          rect = visible_rect;
-          break;
+      button_state = map_button_state (button_type, fgeom, 0, button_states);
 
-        case META_FRAME_PIECE_LAST:
-          g_assert_not_reached ();
-          break;
-        }
+      if (button_state == META_BUTTON_STATE_PRELIGHT)
+        gtk_style_context_set_state (style, state | GTK_STATE_PRELIGHT);
+      else if (button_state == META_BUTTON_STATE_PRESSED)
+        gtk_style_context_set_state (style, state | GTK_STATE_ACTIVE);
+      else
+        gtk_style_context_set_state (style, state);
 
       cairo_save (cr);
-
-      gdk_cairo_rectangle (cr, &rect);
+      gdk_cairo_rectangle (cr, &button_rect);
       cairo_clip (cr);
 
       if (gdk_cairo_get_clip_rectangle (cr, NULL))
         {
-          MetaDrawOpList *op_list;
-          MetaFrameStyle *parent;
+          GdkPixbuf *pixbuf = NULL;
+          const char *icon_name = NULL;
 
-          parent = style;
-          op_list = NULL;
-          while (parent && op_list == NULL)
-            {
-              op_list = parent->pieces[i];
-              parent = parent->parent;
-            }
+          gtk_render_background (style, cr,
+                                 button_rect.x, button_rect.y,
+                                 button_rect.width, button_rect.height);
+          gtk_render_frame (style, cr,
+                            button_rect.x, button_rect.y,
+                            button_rect.width, button_rect.height);
 
-          if (op_list)
+          switch (button_type)
             {
-              MetaRectangle m_rect;
-              m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height);
-              meta_draw_op_list_draw_with_style (op_list,
-                                                 style_info->styles[META_STYLE_ELEMENT_FRAME],
-                                                 cr,
-                                                 &draw_info,
-                                                 m_rect);
+            case META_BUTTON_TYPE_CLOSE:
+               icon_name = "window-close-symbolic";
+               break;
+            case META_BUTTON_TYPE_MAXIMIZE:
+               if (flags & META_FRAME_MAXIMIZED)
+                 icon_name = "window-restore-symbolic";
+               else
+                 icon_name = "window-maximize-symbolic";
+               break;
+            case META_BUTTON_TYPE_MINIMIZE:
+               icon_name = "window-minimize-symbolic";
+               break;
+            case META_BUTTON_TYPE_MENU:
+               icon_name = "open-menu-symbolic";
+               break;
+            case META_BUTTON_TYPE_APPMENU:
+               pixbuf = g_object_ref (mini_icon);
+               break;
+            default:
+               icon_name = NULL;
+               break;
             }
-        }
-
-      cairo_restore (cr);
 
-      /* Draw buttons just before overlay */
-      if ((i + 1) == META_FRAME_PIECE_OVERLAY)
-        {
-          MetaDrawOpList *op_list;
-          int middle_bg_offset;
-
-          middle_bg_offset = 0;
-          j = 0;
-          while (j < META_BUTTON_TYPE_LAST)
+          if (icon_name)
             {
-              MetaButtonState button_state;
-
-              get_button_rect (j, fgeom, middle_bg_offset, &rect);
+              GtkIconTheme *theme = gtk_icon_theme_get_default ();
+              GtkIconInfo *info;
 
-              button_state = map_button_state (j, fgeom, middle_bg_offset, button_states);
-
-              op_list = get_button (style, j, button_state);
-
-              if (op_list)
-                {
-                  cairo_save (cr);
-                  gdk_cairo_rectangle (cr, &rect);
-                  cairo_clip (cr);
+              info = gtk_icon_theme_lookup_icon (theme, icon_name, frame_style->layout->icon_size, 0);
+              pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
+            }
 
-                  if (gdk_cairo_get_clip_rectangle (cr, NULL))
-                    {
-                      MetaRectangle m_rect;
+          if (pixbuf)
+            {
+              float width, height;
+              int x, y;
 
-                      m_rect = meta_rect (rect.x, rect.y,
-                                          rect.width, rect.height);
+              width = gdk_pixbuf_get_width (pixbuf);
+              height = gdk_pixbuf_get_height (pixbuf);
+              x = button_rect.x + (button_rect.width - width) / 2;
+              y = button_rect.y + (button_rect.height - height) / 2;
 
-                      meta_draw_op_list_draw_with_style (op_list,
-                                                         style_info->styles[META_STYLE_ELEMENT_FRAME],
-                                                         cr,
-                                                         &draw_info,
-                                                         m_rect);
-                    }
+              cairo_translate (cr, x, y);
+              cairo_scale (cr,
+                           width / frame_style->layout->icon_size,
+                           height / frame_style->layout->icon_size);
 
-                  cairo_restore (cr);
-                }
+              gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+              cairo_paint (cr);
 
-              /* MIDDLE_BACKGROUND type may get drawn more than once */
-              if ((j == META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND ||
-                   j == META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND) &&
-                  middle_bg_offset < MAX_MIDDLE_BACKGROUNDS)
-                {
-                  ++middle_bg_offset;
-                }
-              else
-                {
-                  middle_bg_offset = 0;
-                  ++j;
-                }
+              g_object_unref (pixbuf);
             }
         }
-
-      ++i;
+      cairo_restore (cr);
     }
 }
 
@@ -5294,8 +5223,7 @@ meta_theme_draw_frame (MetaTheme              *theme,
                        int                     text_height,
                        const MetaButtonLayout *button_layout,
                        MetaButtonState         button_states[META_BUTTON_TYPE_LAST],
-                       GdkPixbuf              *mini_icon,
-                       GdkPixbuf              *icon)
+                       GdkPixbuf              *mini_icon)
 {
   MetaFrameGeometry fgeom;
   MetaFrameStyle *style;
@@ -5309,6 +5237,7 @@ meta_theme_draw_frame (MetaTheme              *theme,
     return;
 
   meta_frame_layout_calc_geometry (style->layout,
+                                   style_info,
                                    text_height,
                                    flags,
                                    client_width, client_height,
@@ -5321,15 +5250,15 @@ meta_theme_draw_frame (MetaTheme              *theme,
                                     style_info,
                                     cr,
                                     &fgeom,
-                                    client_width, client_height,
                                     title_layout,
-                                    text_height,
+                                    flags,
                                     button_states,
-                                    mini_icon, icon);
+                                    mini_icon);
 }
 
 void
 meta_theme_get_frame_borders (MetaTheme        *theme,
+                              MetaStyleInfo    *style_info,
                               MetaFrameType     type,
                               int               text_height,
                               MetaFrameFlags    flags,
@@ -5347,6 +5276,8 @@ meta_theme_get_frame_borders (MetaTheme        *theme,
   if (style == NULL)
     return;
 
+  meta_frame_layout_sync_with_style (style->layout, style_info, flags);
+
   meta_frame_layout_get_borders (style->layout,
                                  text_height,
                                  flags, type,
@@ -5355,6 +5286,7 @@ meta_theme_get_frame_borders (MetaTheme        *theme,
 
 void
 meta_theme_calc_geometry (MetaTheme              *theme,
+                          MetaStyleInfo          *style_info,
                           MetaFrameType           type,
                           int                     text_height,
                           MetaFrameFlags          flags,
@@ -5374,6 +5306,7 @@ meta_theme_calc_geometry (MetaTheme              *theme,
     return;
 
   meta_frame_layout_calc_geometry (style->layout,
+                                   style_info,
                                    text_height,
                                    flags,
                                    client_width, client_height,
diff --git a/src/ui/ui.c b/src/ui/ui.c
index e93d764..8e1fba6 100644
--- a/src/ui/ui.c
+++ b/src/ui/ui.c
@@ -583,15 +583,16 @@ meta_ui_theme_get_frame_borders (MetaUI *ui,
 
   if (meta_ui_have_a_theme ())
     {
+      GdkDisplay *display = gdk_x11_lookup_xdisplay (ui->xdisplay);
+      GdkScreen *screen = gdk_display_get_screen (display, XScreenNumberOfScreen (ui->xscreen));
+
+      style_info = meta_theme_create_style_info (screen, NULL);
+
       context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames));
       font_desc = meta_prefs_get_titlebar_font ();
 
       if (!font_desc)
         {
-          GdkDisplay *display = gdk_x11_lookup_xdisplay (ui->xdisplay);
-          GdkScreen *screen = gdk_display_get_screen (display, XScreenNumberOfScreen (ui->xscreen));
-
-          style_info = meta_theme_create_style_info (screen, NULL);
           free_font_desc = meta_style_info_create_font_desc (style_info);
           font_desc = (const PangoFontDescription *) free_font_desc;
         }
@@ -599,7 +600,7 @@ meta_ui_theme_get_frame_borders (MetaUI *ui,
       text_height = meta_pango_font_desc_get_text_height (font_desc, context);
 
       meta_theme_get_frame_borders (meta_theme_get_current (),
-                                    type, text_height, flags,
+                                    style_info, type, text_height, flags,
                                     borders);
 
       if (free_font_desc)


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