Blame libmetacity/meta-theme-gtk.c

Packit 5e0819
/*
Packit 5e0819
 * Copyright (C) 2016 Alberts Muktupāvels
Packit 5e0819
 *
Packit 5e0819
 * This program is free software: you can redistribute it and/or modify
Packit 5e0819
 * it under the terms of the GNU General Public License as published by
Packit 5e0819
 * the Free Software Foundation, either version 2 of the License, or
Packit 5e0819
 * (at your option) any later version.
Packit 5e0819
 *
Packit 5e0819
 * This program is distributed in the hope that it will be useful,
Packit 5e0819
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5e0819
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Packit 5e0819
 * GNU General Public License for more details.
Packit 5e0819
 *
Packit 5e0819
 * You should have received a copy of the GNU General Public License
Packit 5e0819
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Packit 5e0819
 */
Packit 5e0819
Packit 5e0819
#include "config.h"
Packit 5e0819
Packit 5e0819
#include <gtk/gtk.h>
Packit 5e0819
#include <stdlib.h>
Packit 5e0819
#include <string.h>
Packit 5e0819
Packit 5e0819
#include "meta-rectangle-private.h"
Packit 5e0819
#include "meta-frame-layout-private.h"
Packit 5e0819
#include "meta-frame-style-private.h"
Packit 5e0819
#include "meta-theme-gtk-private.h"
Packit 5e0819
#include "meta-theme.h"
Packit 5e0819
Packit 5e0819
struct _MetaThemeGtk
Packit 5e0819
{
Packit 5e0819
  MetaThemeImpl   parent;
Packit 5e0819
Packit 5e0819
  MetaFrameStyle *styles[META_FRAME_TYPE_LAST];
Packit 5e0819
};
Packit 5e0819
Packit 5e0819
G_DEFINE_TYPE (MetaThemeGtk, meta_theme_gtk, META_TYPE_THEME_IMPL)
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
meta_theme_gtk_dispose (GObject *object)
Packit 5e0819
{
Packit 5e0819
  MetaThemeGtk *gtk;
Packit 5e0819
  gint i;
Packit 5e0819
Packit 5e0819
  gtk = META_THEME_GTK (object);
Packit 5e0819
Packit 5e0819
  for (i = 0; i < META_FRAME_TYPE_LAST; i++)
Packit 5e0819
    {
Packit 5e0819
      if (gtk->styles[i] != NULL)
Packit 5e0819
        {
Packit 5e0819
          meta_frame_style_unref (gtk->styles[i]);
Packit 5e0819
          gtk->styles[i] = NULL;
Packit 5e0819
        }
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  G_OBJECT_CLASS (meta_theme_gtk_parent_class)->dispose (object);
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static gboolean
Packit 5e0819
meta_theme_gtk_load (MetaThemeImpl  *impl,
Packit 5e0819
                     const gchar    *name,
Packit 5e0819
                     GError        **error)
Packit 5e0819
{
Packit 5e0819
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
Packit 5e0819
Packit 5e0819
  return TRUE;
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
get_margin (GtkStyleContext *style,
Packit 5e0819
            GtkBorder       *border)
Packit 5e0819
{
Packit 5e0819
  GtkStateFlags state;
Packit 5e0819
Packit 5e0819
  state = gtk_style_context_get_state (style);
Packit 5e0819
Packit 5e0819
  gtk_style_context_get_margin (style, state, border);
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
get_padding_and_border (GtkStyleContext *style,
Packit 5e0819
                        GtkBorder       *border)
Packit 5e0819
{
Packit 5e0819
  GtkBorder tmp;
Packit 5e0819
  GtkStateFlags state = gtk_style_context_get_state (style);
Packit 5e0819
Packit 5e0819
  gtk_style_context_get_border (style, state, border);
Packit 5e0819
  gtk_style_context_get_padding (style, state, &tmp);
Packit 5e0819
Packit 5e0819
  border->left += tmp.left;
Packit 5e0819
  border->top += tmp.top;
Packit 5e0819
  border->right += tmp.right;
Packit 5e0819
  border->bottom += tmp.bottom;
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
get_min_size (GtkStyleContext *style,
Packit 5e0819
              GtkRequisition  *requisition)
Packit 5e0819
{
Packit 5e0819
  gtk_style_context_get (style, gtk_style_context_get_state (style),
Packit 5e0819
                         "min-width", &requisition->width,
Packit 5e0819
                         "min-height", &requisition->height,
Packit 5e0819
                         NULL);
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
get_shadow_extents (GtkStyleContext *style,
Packit 5e0819
                    GtkBorder       *border)
Packit 5e0819
{
Packit 5e0819
  GdkRectangle clip;
Packit 5e0819
Packit 5e0819
  gtk_render_background_get_clip (style, 0, 0, 0, 0, &clip);
Packit 5e0819
Packit 5e0819
  border->left = abs (clip.x);
Packit 5e0819
  border->top = abs (clip.y);
Packit 5e0819
  border->right = clip.width - border->left;
Packit 5e0819
  border->bottom = clip.height - border->top;
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
frame_layout_sync_with_style (MetaFrameLayout *layout,
Packit 5e0819
                              MetaStyleInfo   *style_info,
Packit 5e0819
                              gboolean         composited,
Packit 5e0819
                              MetaFrameFlags   flags)
Packit 5e0819
{
Packit 5e0819
  GtkStyleContext *style;
Packit 5e0819
  GtkBorder border;
Packit 5e0819
  GtkRequisition requisition;
Packit 5e0819
  int border_radius, max_radius;
Packit 5e0819
Packit 5e0819
  meta_style_info_set_flags (style_info, flags);
Packit 5e0819
Packit 5e0819
  style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_DECORATION);
Packit 5e0819
  get_padding_and_border (style, &layout->gtk.frame_border);
Packit 5e0819
  scale_border (&layout->gtk.frame_border, layout->title_scale);
Packit 5e0819
Packit 5e0819
  if (composited)
Packit 5e0819
    {
Packit 5e0819
      /* With compositing manager: margin is resize area */
Packit 5e0819
      get_margin (style, &layout->invisible_resize_border);
Packit 5e0819
      get_shadow_extents (style, &layout->gtk.shadow_border);
Packit 5e0819
Packit 5e0819
      gtk_style_context_get (style, gtk_style_context_get_state (style),
Packit 5e0819
                             "border-radius", &border_radius,
Packit 5e0819
                             NULL);
Packit 5e0819
      /* GTK+ currently does not allow us to look up radii of individual
Packit 5e0819
       * corners; however we don't clip the client area, so with the
Packit 5e0819
       * current trend of using small/no visible frame borders, most
Packit 5e0819
       * themes should work fine with this.
Packit 5e0819
       */
Packit 5e0819
      layout->top_left_corner_rounded_radius = border_radius;
Packit 5e0819
      layout->top_right_corner_rounded_radius = border_radius;
Packit 5e0819
      max_radius = MIN (layout->gtk.frame_border.bottom, layout->gtk.frame_border.left);
Packit 5e0819
      layout->bottom_left_corner_rounded_radius = MAX (border_radius, max_radius);
Packit 5e0819
      max_radius = MIN (layout->gtk.frame_border.bottom, layout->gtk.frame_border.left);
Packit 5e0819
      layout->bottom_right_corner_rounded_radius = MAX (border_radius, max_radius);
Packit 5e0819
    }
Packit 5e0819
  else
Packit 5e0819
    {
Packit 5e0819
      /* Without compositing manager we can not have invisible border */
Packit 5e0819
      layout->invisible_resize_border.top = 0;
Packit 5e0819
      layout->invisible_resize_border.bottom = 0;
Packit 5e0819
      layout->invisible_resize_border.left = 0;
Packit 5e0819
      layout->invisible_resize_border.right = 0;
Packit 5e0819
Packit 5e0819
      layout->gtk.shadow_border.top = 0;
Packit 5e0819
      layout->gtk.shadow_border.bottom = 0;
Packit 5e0819
      layout->gtk.shadow_border.left = 0;
Packit 5e0819
      layout->gtk.shadow_border.right = 0;
Packit 5e0819
Packit 5e0819
      layout->top_left_corner_rounded_radius = 0;
Packit 5e0819
      layout->top_right_corner_rounded_radius = 0;
Packit 5e0819
      layout->bottom_left_corner_rounded_radius = 0;
Packit 5e0819
      layout->bottom_right_corner_rounded_radius = 0;
Packit 5e0819
Packit 5e0819
      /* Without compositing manager: margin is part of border */
Packit 5e0819
      get_margin (style, &border);
Packit 5e0819
Packit 5e0819
      layout->gtk.frame_border.left += border.left;
Packit 5e0819
      layout->gtk.frame_border.right += border.right;
Packit 5e0819
      layout->gtk.frame_border.top += border.top;
Packit 5e0819
      layout->gtk.frame_border.bottom += border.bottom;
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  if (layout->hide_buttons)
Packit 5e0819
    layout->gtk.icon_size = 0;
Packit 5e0819
Packit 5e0819
  if (!layout->has_title && layout->hide_buttons)
Packit 5e0819
    return; /* border-only - be done */
Packit 5e0819
Packit 5e0819
  style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLEBAR);
Packit 5e0819
  get_min_size (style, &layout->gtk.titlebar_min_size);
Packit 5e0819
  get_padding_and_border (style, &layout->gtk.titlebar_border);
Packit 5e0819
  scale_border (&layout->gtk.titlebar_border, layout->title_scale);
Packit 5e0819
Packit 5e0819
  style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLE);
Packit 5e0819
  get_margin (style, &layout->gtk.title_margin);
Packit 5e0819
  scale_border (&layout->gtk.title_margin, layout->title_scale);
Packit 5e0819
Packit 5e0819
  style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_BUTTON);
Packit 5e0819
  get_min_size (style, &layout->gtk.button_min_size);
Packit 5e0819
  get_padding_and_border (style, &layout->button_border);
Packit 5e0819
  scale_border (&layout->button_border, layout->title_scale);
Packit 5e0819
Packit 5e0819
  get_margin (style, &layout->gtk.button_margin);
Packit 5e0819
  scale_border (&layout->gtk.button_margin, layout->title_scale);
Packit 5e0819
Packit 5e0819
  style = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_IMAGE);
Packit 5e0819
  get_min_size (style, &requisition);
Packit 5e0819
  get_padding_and_border (style, &border);
Packit 5e0819
  scale_border (&border, layout->title_scale);
Packit 5e0819
Packit 5e0819
  layout->button_border.left += border.left;
Packit 5e0819
  layout->button_border.right += border.right;
Packit 5e0819
  layout->button_border.top += border.top;
Packit 5e0819
  layout->button_border.bottom += border.bottom;
Packit 5e0819
Packit 5e0819
  get_margin (style, &border);
Packit 5e0819
  layout->button_border.left += border.left;
Packit 5e0819
  layout->button_border.right += border.right;
Packit 5e0819
  layout->button_border.top += border.top;
Packit 5e0819
  layout->button_border.bottom += border.bottom;
Packit 5e0819
Packit 5e0819
  layout->gtk.button_min_size.width = MAX (layout->gtk.button_min_size.width,
Packit 5e0819
                                           requisition.width);
Packit 5e0819
  layout->gtk.button_min_size.height = MAX (layout->gtk.button_min_size.height,
Packit 5e0819
                                            requisition.height);
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static MetaFrameStyle *
Packit 5e0819
meta_theme_gtk_get_frame_style (MetaThemeImpl  *impl,
Packit 5e0819
                                MetaFrameType   type,
Packit 5e0819
                                MetaFrameFlags  flags)
Packit 5e0819
{
Packit 5e0819
  MetaThemeGtk *gtk;
Packit 5e0819
Packit 5e0819
  gtk = META_THEME_GTK (impl);
Packit 5e0819
Packit 5e0819
  return gtk->styles[type];
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
meta_theme_gtk_get_frame_borders (MetaThemeImpl    *impl,
Packit 5e0819
                                  MetaFrameLayout  *layout,
Packit 5e0819
                                  MetaStyleInfo    *style_info,
Packit 5e0819
                                  gint              text_height,
Packit 5e0819
                                  MetaFrameFlags    flags,
Packit 5e0819
                                  MetaFrameType     type,
Packit 5e0819
                                  MetaFrameBorders *borders)
Packit 5e0819
{
Packit 5e0819
  gboolean composited;
Packit 5e0819
  gint scale;
Packit 5e0819
  gint title_height;
Packit 5e0819
  gint buttons_height;
Packit 5e0819
  gint content_height;
Packit 5e0819
Packit 5e0819
  composited = meta_theme_impl_get_composited (impl);
Packit 5e0819
  frame_layout_sync_with_style (layout, style_info, composited, flags);
Packit 5e0819
Packit 5e0819
  meta_frame_borders_clear (borders);
Packit 5e0819
Packit 5e0819
  /* For a full-screen window, we don't have any borders, visible or not. */
Packit 5e0819
  if (flags & META_FRAME_FULLSCREEN)
Packit 5e0819
    return;
Packit 5e0819
Packit 5e0819
  g_return_if_fail (layout != NULL);
Packit 5e0819
Packit 5e0819
  if (!layout->has_title)
Packit 5e0819
    text_height = 0;
Packit 5e0819
Packit 5e0819
  /* Scale geometry for HiDPI, see comment in meta_theme_gtk_draw_frame () */
Packit 5e0819
  scale = meta_theme_impl_get_scale (impl);
Packit 5e0819
Packit 5e0819
  title_height = layout->gtk.title_margin.top +
Packit 5e0819
                 text_height / scale +
Packit 5e0819
                 layout->gtk.title_margin.bottom;
Packit 5e0819
Packit 5e0819
  buttons_height = MAX ((gint) layout->gtk.icon_size, layout->gtk.button_min_size.height) +
Packit 5e0819
                   layout->gtk.button_margin.top + layout->button_border.top +
Packit 5e0819
                   layout->gtk.button_margin.bottom + layout->button_border.bottom;
Packit 5e0819
Packit 5e0819
  content_height = MAX (title_height, buttons_height);
Packit 5e0819
  content_height = MAX (content_height, layout->gtk.titlebar_min_size.height) +
Packit 5e0819
                   layout->gtk.titlebar_border.top +
Packit 5e0819
                   layout->gtk.titlebar_border.bottom;
Packit 5e0819
Packit 5e0819
  borders->visible.top = layout->gtk.frame_border.top + content_height;
Packit 5e0819
  borders->visible.left = layout->gtk.frame_border.left;
Packit 5e0819
  borders->visible.right = layout->gtk.frame_border.right;
Packit 5e0819
  borders->visible.bottom = layout->gtk.frame_border.bottom;
Packit 5e0819
Packit 5e0819
  borders->shadow = layout->gtk.shadow_border;
Packit 5e0819
Packit 5e0819
  if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE)
Packit 5e0819
    {
Packit 5e0819
      borders->resize.left = layout->invisible_resize_border.left;
Packit 5e0819
      borders->resize.right = layout->invisible_resize_border.right;
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE)
Packit 5e0819
    {
Packit 5e0819
      borders->resize.bottom = layout->invisible_resize_border.bottom;
Packit 5e0819
Packit 5e0819
      if (type != META_FRAME_TYPE_ATTACHED)
Packit 5e0819
        borders->resize.top = layout->invisible_resize_border.top;
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  borders->invisible.left = MAX (borders->shadow.left, borders->resize.left);
Packit 5e0819
  borders->invisible.right = MAX (borders->shadow.right, borders->resize.right);
Packit 5e0819
  borders->invisible.bottom = MAX (borders->shadow.bottom, borders->resize.bottom);
Packit 5e0819
  borders->invisible.top = MAX (borders->shadow.top, borders->resize.top);
Packit 5e0819
Packit 5e0819
  borders->total.left = borders->invisible.left + borders->visible.left;
Packit 5e0819
  borders->total.right = borders->invisible.right + borders->visible.right;
Packit 5e0819
  borders->total.bottom = borders->invisible.bottom + borders->visible.bottom;
Packit 5e0819
  borders->total.top = borders->invisible.top + borders->visible.top;
Packit 5e0819
Packit 5e0819
  scale_border (&borders->visible, scale);
Packit 5e0819
  scale_border (&borders->shadow, scale);
Packit 5e0819
  scale_border (&borders->resize, scale);
Packit 5e0819
  scale_border (&borders->invisible, scale);
Packit 5e0819
  scale_border (&borders->total, scale);
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
meta_theme_gtk_calc_geometry (MetaThemeImpl     *impl,
Packit 5e0819
                              MetaFrameLayout   *layout,
Packit 5e0819
                              MetaStyleInfo     *style_info,
Packit 5e0819
                              gint               text_height,
Packit 5e0819
                              MetaFrameFlags     flags,
Packit 5e0819
                              gint               client_width,
Packit 5e0819
                              gint               client_height,
Packit 5e0819
                              MetaButtonLayout  *button_layout,
Packit 5e0819
                              MetaFrameType      type,
Packit 5e0819
                              MetaFrameGeometry *fgeom)
Packit 5e0819
{
Packit 5e0819
  MetaFrameBorders borders;
Packit 5e0819
  int i, n_left, n_right, n_left_spacers, n_right_spacers;
Packit 5e0819
  int x;
Packit 5e0819
  int button_y;
Packit 5e0819
  int title_right_edge;
Packit 5e0819
  int width, height;
Packit 5e0819
  int scale;
Packit 5e0819
  int content_height;
Packit 5e0819
  int button_width, button_height;
Packit 5e0819
  int min_size_for_rounding;
Packit 5e0819
Packit 5e0819
  META_THEME_IMPL_GET_CLASS (impl)->get_frame_borders (impl, layout,
Packit 5e0819
                                                       style_info, text_height,
Packit 5e0819
                                                       flags, type, &borders);
Packit 5e0819
Packit 5e0819
  fgeom->borders = borders;
Packit 5e0819
Packit 5e0819
  width = client_width + borders.total.left + borders.total.right;
Packit 5e0819
Packit 5e0819
  height = borders.total.top + borders.total.bottom;
Packit 5e0819
  if (!(flags & META_FRAME_SHADED))
Packit 5e0819
    height += client_height;
Packit 5e0819
Packit 5e0819
  fgeom->width = width;
Packit 5e0819
  fgeom->height = height;
Packit 5e0819
Packit 5e0819
  /* Scale geometry for HiDPI, see comment in meta_theme_gtk_draw_frame () */
Packit 5e0819
  scale = meta_theme_impl_get_scale (impl);
Packit 5e0819
Packit 5e0819
  content_height = borders.visible.top - layout->gtk.frame_border.top * scale;
Packit 5e0819
Packit 5e0819
  button_width = MAX ((gint) layout->gtk.icon_size, layout->gtk.button_min_size.width) +
Packit 5e0819
                 layout->button_border.left + layout->button_border.right;
Packit 5e0819
  button_height = MAX ((gint) layout->gtk.icon_size, layout->gtk.button_min_size.height) +
Packit 5e0819
                  layout->button_border.top + layout->button_border.bottom;
Packit 5e0819
Packit 5e0819
  button_width *= scale;
Packit 5e0819
  button_height *= scale;
Packit 5e0819
Packit 5e0819
  n_left = 0;
Packit 5e0819
  n_right = 0;
Packit 5e0819
  n_left_spacers = 0;
Packit 5e0819
  n_right_spacers = 0;
Packit 5e0819
Packit 5e0819
  if (!layout->hide_buttons)
Packit 5e0819
    {
Packit 5e0819
      MetaButton *button;
Packit 5e0819
Packit 5e0819
      for (i = 0; i < button_layout->n_left_buttons; i++)
Packit 5e0819
        {
Packit 5e0819
          button = &button_layout->left_buttons[i];
Packit 5e0819
          button->visible = is_button_visible (button, flags);
Packit 5e0819
Packit 5e0819
          if (button->visible)
Packit 5e0819
            {
Packit 5e0819
              if (button->type != META_BUTTON_TYPE_SPACER)
Packit 5e0819
                n_left++;
Packit 5e0819
              else
Packit 5e0819
                n_left_spacers++;
Packit 5e0819
            }
Packit 5e0819
        }
Packit 5e0819
Packit 5e0819
      for (i = 0; i < button_layout->n_right_buttons; i++)
Packit 5e0819
        {
Packit 5e0819
          button = &button_layout->right_buttons[i];
Packit 5e0819
          button->visible = is_button_visible (button, flags);
Packit 5e0819
Packit 5e0819
          if (button->visible)
Packit 5e0819
            {
Packit 5e0819
              if (button->type != META_BUTTON_TYPE_SPACER)
Packit 5e0819
                n_right++;
Packit 5e0819
              else
Packit 5e0819
                n_right_spacers++;
Packit 5e0819
            }
Packit 5e0819
        }
Packit 5e0819
    }
Packit 5e0819
  else
Packit 5e0819
    {
Packit 5e0819
      for (i = 0; i < button_layout->n_left_buttons; i++)
Packit 5e0819
        button_layout->left_buttons[i].visible = FALSE;
Packit 5e0819
Packit 5e0819
      for (i = 0; i < button_layout->n_right_buttons; i++)
Packit 5e0819
        button_layout->right_buttons[i].visible = FALSE;
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  /* Be sure buttons fit */
Packit 5e0819
  while (n_left > 0 || n_right > 0)
Packit 5e0819
    {
Packit 5e0819
      int space_used_by_buttons;
Packit 5e0819
      int space_available;
Packit 5e0819
Packit 5e0819
      space_available = fgeom->width -
Packit 5e0819
                        borders.total.left -
Packit 5e0819
                        layout->gtk.titlebar_border.left * scale -
Packit 5e0819
                        layout->gtk.titlebar_border.right * scale -
Packit 5e0819
                        borders.total.right;
Packit 5e0819
Packit 5e0819
      space_used_by_buttons = 0;
Packit 5e0819
Packit 5e0819
      space_used_by_buttons += layout->gtk.button_margin.left * scale * n_left;
Packit 5e0819
      space_used_by_buttons += button_width * n_left;
Packit 5e0819
      space_used_by_buttons += layout->gtk.button_margin.right * scale * n_left;
Packit 5e0819
      space_used_by_buttons += (button_width * 0.75) * n_left_spacers;
Packit 5e0819
      space_used_by_buttons += layout->gtk.titlebar_spacing * scale * MAX (n_left - 1, 0);
Packit 5e0819
Packit 5e0819
      space_used_by_buttons += layout->gtk.button_margin.left * scale * n_right;
Packit 5e0819
      space_used_by_buttons += button_width * n_right;
Packit 5e0819
      space_used_by_buttons += layout->gtk.button_margin.right * scale * n_right;
Packit 5e0819
      space_used_by_buttons += (button_width * 0.75) * n_right_spacers;
Packit 5e0819
      space_used_by_buttons += layout->gtk.titlebar_spacing * scale * MAX (n_right - 1, 0);
Packit 5e0819
Packit 5e0819
      if (space_used_by_buttons <= space_available)
Packit 5e0819
        break; /* Everything fits, bail out */
Packit 5e0819
Packit 5e0819
      /* First try to remove separators */
Packit 5e0819
      if (n_left_spacers > 0)
Packit 5e0819
        {
Packit 5e0819
          if (strip_button (button_layout->left_buttons,
Packit 5e0819
                            button_layout->n_left_buttons,
Packit 5e0819
                            META_BUTTON_TYPE_SPACER))
Packit 5e0819
            {
Packit 5e0819
              n_left_spacers--;
Packit 5e0819
              continue;
Packit 5e0819
            }
Packit 5e0819
          else
Packit 5e0819
            {
Packit 5e0819
              g_assert_not_reached ();
Packit 5e0819
            }
Packit 5e0819
        }
Packit 5e0819
      else if (n_right_spacers > 0)
Packit 5e0819
        {
Packit 5e0819
          if (strip_button (button_layout->right_buttons,
Packit 5e0819
                            button_layout->n_right_buttons,
Packit 5e0819
                            META_BUTTON_TYPE_SPACER))
Packit 5e0819
            {
Packit 5e0819
              n_right_spacers--;
Packit 5e0819
              continue;
Packit 5e0819
            }
Packit 5e0819
          else
Packit 5e0819
            {
Packit 5e0819
              g_assert_not_reached ();
Packit 5e0819
            }
Packit 5e0819
        }
Packit 5e0819
Packit 5e0819
      /* Otherwise we need to shave out a button. Shave
Packit 5e0819
       * above, stick, shade, min, max, close, then menu (menu is most useful);
Packit 5e0819
       * prefer the default button locations.
Packit 5e0819
       */
Packit 5e0819
      if (strip_buttons (button_layout, &n_left, &n_right))
Packit 5e0819
        {
Packit 5e0819
          continue;
Packit 5e0819
        }
Packit 5e0819
      else
Packit 5e0819
        {
Packit 5e0819
          g_error ("Could not find a button to strip. n_left = %d n_right = %d",
Packit 5e0819
                   n_left, n_right);
Packit 5e0819
        }
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  /* center buttons vertically */
Packit 5e0819
  button_y = borders.invisible.top + layout->gtk.frame_border.top * scale +
Packit 5e0819
             (content_height - button_height) / 2;
Packit 5e0819
Packit 5e0819
  /* right edge of farthest-right button */
Packit 5e0819
  x = width - borders.invisible.right - layout->gtk.frame_border.right * scale -
Packit 5e0819
      layout->gtk.titlebar_border.right * scale;
Packit 5e0819
Packit 5e0819
  for (i = button_layout->n_right_buttons - 1; i >= 0; i--)
Packit 5e0819
    {
Packit 5e0819
      MetaButton *button;
Packit 5e0819
      GdkRectangle rect;
Packit 5e0819
Packit 5e0819
      button = &button_layout->right_buttons[i];
Packit 5e0819
Packit 5e0819
      if (button->visible == FALSE)
Packit 5e0819
        continue;
Packit 5e0819
Packit 5e0819
      /* if we go negative, leave the buttons we don't get to as 0 - width */
Packit 5e0819
      if (x < 0)
Packit 5e0819
        break;
Packit 5e0819
Packit 5e0819
      x -= layout->gtk.button_margin.right * scale;
Packit 5e0819
Packit 5e0819
      rect.y = button_y;
Packit 5e0819
      rect.width = button_width;
Packit 5e0819
      rect.height = button_height;
Packit 5e0819
Packit 5e0819
      if (button->type == META_BUTTON_TYPE_SPACER)
Packit 5e0819
        {
Packit 5e0819
          rect.x = x - button_width * 0.75;
Packit 5e0819
          rect.width *= 0.75;
Packit 5e0819
        }
Packit 5e0819
      else
Packit 5e0819
        {
Packit 5e0819
          rect.x = x - button_width;
Packit 5e0819
        }
Packit 5e0819
Packit 5e0819
      button->rect.visible = rect;
Packit 5e0819
      button->rect.clickable = rect;
Packit 5e0819
Packit 5e0819
      if ((flags & META_FRAME_MAXIMIZED || flags & META_FRAME_TILED_RIGHT) &&
Packit 5e0819
          i == button_layout->n_right_buttons - 1)
Packit 5e0819
        {
Packit 5e0819
          gint extra_width;
Packit 5e0819
          gint extra_height;
Packit 5e0819
Packit 5e0819
          extra_width = layout->gtk.button_margin.right * scale +
Packit 5e0819
                        layout->gtk.frame_border.right * scale +
Packit 5e0819
                        layout->gtk.titlebar_border.right * scale;
Packit 5e0819
Packit 5e0819
          /* FIXME: */
Packit 5e0819
          extra_height = 0;
Packit 5e0819
Packit 5e0819
          button->rect.clickable.y -= extra_height;
Packit 5e0819
          button->rect.clickable.width += extra_width;
Packit 5e0819
          button->rect.clickable.height += extra_height;
Packit 5e0819
        }
Packit 5e0819
Packit 5e0819
      x = rect.x - layout->gtk.button_margin.left * scale;
Packit 5e0819
      x -= layout->gtk.titlebar_spacing * scale;
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  /* save right edge of titlebar for later use */
Packit 5e0819
  title_right_edge = x;
Packit 5e0819
Packit 5e0819
  /* Now x changes to be position from the left and we go through
Packit 5e0819
   * the left-side buttons
Packit 5e0819
   */
Packit 5e0819
  x = borders.invisible.left + layout->gtk.frame_border.left * scale +
Packit 5e0819
      layout->gtk.titlebar_border.left * scale;
Packit 5e0819
Packit 5e0819
  for (i = 0; i < button_layout->n_left_buttons; i++)
Packit 5e0819
    {
Packit 5e0819
      MetaButton *button;
Packit 5e0819
      GdkRectangle rect;
Packit 5e0819
Packit 5e0819
      button = &button_layout->left_buttons[i];
Packit 5e0819
Packit 5e0819
      if (button->visible == FALSE)
Packit 5e0819
        continue;
Packit 5e0819
Packit 5e0819
      rect.x = x + layout->gtk.button_margin.left * scale;
Packit 5e0819
      rect.y = button_y;
Packit 5e0819
      rect.width = button_width;
Packit 5e0819
      rect.height = button_height;
Packit 5e0819
Packit 5e0819
      if (button->type == META_BUTTON_TYPE_SPACER)
Packit 5e0819
        rect.width *= 0.75;
Packit 5e0819
Packit 5e0819
      button->rect.visible = rect;
Packit 5e0819
      button->rect.clickable = rect;
Packit 5e0819
Packit 5e0819
      if ((flags & META_FRAME_MAXIMIZED || flags & META_FRAME_TILED_LEFT) &&
Packit 5e0819
          i == 0)
Packit 5e0819
        {
Packit 5e0819
          gint extra_width;
Packit 5e0819
          gint extra_height;
Packit 5e0819
Packit 5e0819
          extra_width = layout->gtk.button_margin.left * scale +
Packit 5e0819
                        layout->gtk.frame_border.left * scale +
Packit 5e0819
                        layout->gtk.titlebar_border.left * scale;
Packit 5e0819
Packit 5e0819
          /* FIXME: */
Packit 5e0819
          extra_height = 0;
Packit 5e0819
Packit 5e0819
          button->rect.clickable.x -= extra_width;
Packit 5e0819
          button->rect.clickable.y -= extra_height;
Packit 5e0819
          button->rect.clickable.width += extra_width;
Packit 5e0819
          button->rect.clickable.height += extra_height;
Packit 5e0819
        }
Packit 5e0819
Packit 5e0819
      x = rect.x + rect.width + layout->gtk.button_margin.right * scale;
Packit 5e0819
      x += layout->gtk.titlebar_spacing * scale;
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  /* Center vertically in the available content area */
Packit 5e0819
  fgeom->title_rect.x = x;
Packit 5e0819
  fgeom->title_rect.y = borders.invisible.top + layout->gtk.frame_border.top * scale +
Packit 5e0819
                        (content_height - text_height) / 2;
Packit 5e0819
  fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x;
Packit 5e0819
  fgeom->title_rect.height = text_height;
Packit 5e0819
Packit 5e0819
  /* Nuke title if it won't fit */
Packit 5e0819
  if (fgeom->title_rect.width < 0 ||
Packit 5e0819
      fgeom->title_rect.height < 0)
Packit 5e0819
    {
Packit 5e0819
      fgeom->title_rect.width = 0;
Packit 5e0819
      fgeom->title_rect.height = 0;
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  if (flags & META_FRAME_SHADED)
Packit 5e0819
    min_size_for_rounding = 0;
Packit 5e0819
  else
Packit 5e0819
    min_size_for_rounding = 5 * scale;
Packit 5e0819
Packit 5e0819
  fgeom->top_left_corner_rounded_radius = 0;
Packit 5e0819
  fgeom->top_right_corner_rounded_radius = 0;
Packit 5e0819
  fgeom->bottom_left_corner_rounded_radius = 0;
Packit 5e0819
  fgeom->bottom_right_corner_rounded_radius = 0;
Packit 5e0819
Packit 5e0819
  if (borders.visible.top + borders.visible.left >= min_size_for_rounding)
Packit 5e0819
    fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius * scale;
Packit 5e0819
  if (borders.visible.top + borders.visible.right >= min_size_for_rounding)
Packit 5e0819
    fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius * scale;
Packit 5e0819
Packit 5e0819
  if (borders.visible.bottom + borders.visible.left >= min_size_for_rounding)
Packit 5e0819
    fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius * scale;
Packit 5e0819
  if (borders.visible.bottom + borders.visible.right >= min_size_for_rounding)
Packit 5e0819
    fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius * scale;
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static const char *
Packit 5e0819
get_class_from_button_type (MetaButtonType type)
Packit 5e0819
{
Packit 5e0819
  if (type == META_BUTTON_TYPE_CLOSE)
Packit 5e0819
    return "close";
Packit 5e0819
  else if (type == META_BUTTON_TYPE_MAXIMIZE)
Packit 5e0819
    return "maximize";
Packit 5e0819
  else if (type == META_BUTTON_TYPE_MINIMIZE)
Packit 5e0819
    return "minimize";
Packit 5e0819
Packit 5e0819
  return NULL;
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
meta_theme_gtk_draw_frame (MetaThemeImpl           *impl,
Packit 5e0819
                           MetaFrameStyle          *style,
Packit 5e0819
                           MetaStyleInfo           *style_info,
Packit 5e0819
                           cairo_t                 *cr,
Packit 5e0819
                           const MetaFrameGeometry *fgeom,
Packit 5e0819
                           PangoLayout             *title_layout,
Packit 5e0819
                           MetaFrameFlags           flags,
Packit 5e0819
                           const MetaButtonLayout  *button_layout,
Packit 5e0819
                           GdkPixbuf               *mini_icon,
Packit 5e0819
                           GdkPixbuf               *icon)
Packit 5e0819
{
Packit 5e0819
  gdouble scale;
Packit 5e0819
  GtkStyleContext *context;
Packit 5e0819
  GtkStateFlags state;
Packit 5e0819
  MetaRectangleDouble visible_rect;
Packit 5e0819
  MetaRectangleDouble titlebar_rect;
Packit 5e0819
  const MetaFrameBorders *borders;
Packit 5e0819
  gint side;
Packit 5e0819
Packit 5e0819
  /* We opt out of GTK+ HiDPI handling, so we have to do the scaling
Packit 5e0819
   * ourselves; the nitty-gritty is a bit confusing, so here is an overview:
Packit 5e0819
   *  - the values in MetaFrameLayout are always as they appear in the theme,
Packit 5e0819
   *    i.e. unscaled
Packit 5e0819
   *  - calculated values (borders, MetaFrameGeometry) include the scale - as
Packit 5e0819
   *    the geometry is comprised of scaled decorations and the client size
Packit 5e0819
   *    which we must not scale, we don't have another option
Packit 5e0819
   *  - for drawing, we scale the canvas to have GTK+ render elements (borders,
Packit 5e0819
   *    radii, ...) at the correct scale - as a result, we have to "unscale"
Packit 5e0819
   *    the geometry again to not apply the scaling twice
Packit 5e0819
   */
Packit 5e0819
  scale = meta_theme_impl_get_scale (impl);
Packit 5e0819
  cairo_scale (cr, scale, scale);
Packit 5e0819
Packit 5e0819
  borders = &fgeom->borders;
Packit 5e0819
Packit 5e0819
  visible_rect.x = borders->invisible.left / scale;
Packit 5e0819
  visible_rect.y = borders->invisible.top / scale;
Packit 5e0819
  visible_rect.width = (fgeom->width - borders->invisible.left - borders->invisible.right) / scale;
Packit 5e0819
  visible_rect.height = (fgeom->height - borders->invisible.top - borders->invisible.bottom) / scale;
Packit 5e0819
Packit 5e0819
  meta_style_info_set_flags (style_info, flags);
Packit 5e0819
Packit 5e0819
  context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_DECORATION);
Packit 5e0819
  gtk_render_background (context, cr,
Packit 5e0819
                         visible_rect.x, visible_rect.y,
Packit 5e0819
                         visible_rect.width, visible_rect.height);
Packit 5e0819
  gtk_render_frame (context, cr,
Packit 5e0819
                    visible_rect.x, visible_rect.y,
Packit 5e0819
                    visible_rect.width, visible_rect.height);
Packit 5e0819
Packit 5e0819
  if (flags & META_FRAME_FULLSCREEN)
Packit 5e0819
    return;
Packit 5e0819
Packit 5e0819
  titlebar_rect.x = visible_rect.x + borders->visible.left / scale;
Packit 5e0819
  titlebar_rect.y = visible_rect.y + style->layout->gtk.frame_border.top;
Packit 5e0819
  titlebar_rect.width = visible_rect.width - (borders->visible.left + borders->visible.right) / scale;
Packit 5e0819
  titlebar_rect.height = (borders->visible.top / scale) - style->layout->gtk.frame_border.top;
Packit 5e0819
Packit 5e0819
  context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLEBAR);
Packit 5e0819
  gtk_render_background (context, cr,
Packit 5e0819
                         titlebar_rect.x, titlebar_rect.y,
Packit 5e0819
                         titlebar_rect.width, titlebar_rect.height);
Packit 5e0819
  gtk_render_frame (context, cr,
Packit 5e0819
                    titlebar_rect.x, titlebar_rect.y,
Packit 5e0819
                    titlebar_rect.width, titlebar_rect.height);
Packit 5e0819
Packit 5e0819
  if (style->layout->has_title && title_layout)
Packit 5e0819
    {
Packit 5e0819
      PangoRectangle logical;
Packit 5e0819
      gdouble text_width, x, y;
Packit 5e0819
Packit 5e0819
      pango_layout_set_width (title_layout, -1);
Packit 5e0819
      pango_layout_get_pixel_extents (title_layout, NULL, &logical);
Packit 5e0819
Packit 5e0819
      text_width = MIN(fgeom->title_rect.width / scale, logical.width);
Packit 5e0819
Packit 5e0819
      if (text_width < logical.width)
Packit 5e0819
        pango_layout_set_width (title_layout, PANGO_SCALE * text_width);
Packit 5e0819
Packit 5e0819
      /* Center within the frame if possible */
Packit 5e0819
      x = titlebar_rect.x + (titlebar_rect.width - text_width) / 2;
Packit 5e0819
      y = titlebar_rect.y + (titlebar_rect.height - logical.height) / 2;
Packit 5e0819
Packit 5e0819
      if (x < fgeom->title_rect.x / scale)
Packit 5e0819
        x = fgeom->title_rect.x / scale;
Packit 5e0819
      else if (x + text_width > (fgeom->title_rect.x + fgeom->title_rect.width) / scale)
Packit 5e0819
        x = (fgeom->title_rect.x + fgeom->title_rect.width) / scale - text_width;
Packit 5e0819
Packit 5e0819
      cairo_save (cr);
Packit 5e0819
Packit 5e0819
      cairo_rectangle (cr,
Packit 5e0819
                       fgeom->title_rect.x / scale,
Packit 5e0819
                       fgeom->title_rect.y / scale,
Packit 5e0819
                       fgeom->title_rect.width / scale,
Packit 5e0819
                       fgeom->title_rect.height / scale);
Packit 5e0819
      cairo_clip (cr);
Packit 5e0819
Packit 5e0819
      context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_TITLE);
Packit 5e0819
      gtk_render_layout (context, cr, x, y, title_layout);
Packit 5e0819
Packit 5e0819
      cairo_restore (cr);
Packit 5e0819
    }
Packit 5e0819
Packit 5e0819
  context = meta_style_info_get_style (style_info, META_STYLE_ELEMENT_BUTTON);
Packit 5e0819
  state = gtk_style_context_get_state (context);
Packit 5e0819
Packit 5e0819
  for (side = 0; side < 2; side++)
Packit 5e0819
    {
Packit 5e0819
      MetaButton *buttons;
Packit 5e0819
      gint n_buttons;
Packit 5e0819
      gint i;
Packit 5e0819
Packit 5e0819
      if (side == 0)
Packit 5e0819
        {
Packit 5e0819
          buttons = button_layout->left_buttons;
Packit 5e0819
          n_buttons = button_layout->n_left_buttons;
Packit 5e0819
        }
Packit 5e0819
      else if (side == 1)
Packit 5e0819
        {
Packit 5e0819
          buttons = button_layout->right_buttons;
Packit 5e0819
          n_buttons = button_layout->n_right_buttons;
Packit 5e0819
        }
Packit 5e0819
      else
Packit 5e0819
        {
Packit 5e0819
          g_assert_not_reached ();
Packit 5e0819
        }
Packit 5e0819
Packit 5e0819
      for (i = 0; i < n_buttons; i++)
Packit 5e0819
        {
Packit 5e0819
          MetaButton *button;
Packit 5e0819
          gdouble x;
Packit 5e0819
          gdouble y;
Packit 5e0819
          gdouble width;
Packit 5e0819
          gdouble height;
Packit 5e0819
          const gchar *button_class;
Packit 5e0819
          const gchar *icon_name;
Packit 5e0819
          GdkPixbuf *pixbuf;
Packit 5e0819
Packit 5e0819
          button = &buttons[i];
Packit 5e0819
Packit 5e0819
          x = button->rect.visible.x / scale;
Packit 5e0819
          y = button->rect.visible.y / scale;
Packit 5e0819
          width = button->rect.visible.width / scale;
Packit 5e0819
          height = button->rect.visible.height / scale;
Packit 5e0819
Packit 5e0819
          if (!button->visible || button->type == META_BUTTON_TYPE_SPACER ||
Packit 5e0819
              width <= 0 || height <= 0)
Packit 5e0819
            {
Packit 5e0819
              continue;
Packit 5e0819
            }
Packit 5e0819
Packit 5e0819
          button_class = get_class_from_button_type (button->type);
Packit 5e0819
Packit 5e0819
          if (button_class)
Packit 5e0819
            gtk_style_context_add_class (context, button_class);
Packit 5e0819
Packit 5e0819
          if (button->state == META_BUTTON_STATE_PRELIGHT)
Packit 5e0819
            gtk_style_context_set_state (context, state | GTK_STATE_PRELIGHT);
Packit 5e0819
          else if (button->state == META_BUTTON_STATE_PRESSED)
Packit 5e0819
            gtk_style_context_set_state (context, state | GTK_STATE_ACTIVE);
Packit 5e0819
          else
Packit 5e0819
            gtk_style_context_set_state (context, state);
Packit 5e0819
Packit 5e0819
          cairo_save (cr);
Packit 5e0819
Packit 5e0819
          gtk_render_background (context, cr, x, y, width, height);
Packit 5e0819
          gtk_render_frame (context, cr, x, y, width, height);
Packit 5e0819
Packit 5e0819
          icon_name = NULL;
Packit 5e0819
          pixbuf = NULL;
Packit 5e0819
Packit 5e0819
          switch (button->type)
Packit 5e0819
            {
Packit 5e0819
              case META_BUTTON_TYPE_CLOSE:
Packit 5e0819
                icon_name = "window-close-symbolic";
Packit 5e0819
                break;
Packit 5e0819
              case META_BUTTON_TYPE_MAXIMIZE:
Packit 5e0819
                if (flags & META_FRAME_MAXIMIZED)
Packit 5e0819
                  icon_name = "window-restore-symbolic";
Packit 5e0819
                else
Packit 5e0819
                  icon_name = "window-maximize-symbolic";
Packit 5e0819
                break;
Packit 5e0819
              case META_BUTTON_TYPE_MINIMIZE:
Packit 5e0819
                icon_name = "window-minimize-symbolic";
Packit 5e0819
                break;
Packit 5e0819
              case META_BUTTON_TYPE_MENU:
Packit 5e0819
                icon_name = "open-menu-symbolic";
Packit 5e0819
                break;
Packit 5e0819
              case META_BUTTON_TYPE_APPMENU:
Packit 5e0819
                pixbuf = g_object_ref (mini_icon);
Packit 5e0819
                break;
Packit 5e0819
              case META_BUTTON_TYPE_SHADE:
Packit 5e0819
              case META_BUTTON_TYPE_ABOVE:
Packit 5e0819
              case META_BUTTON_TYPE_STICK:
Packit 5e0819
              case META_BUTTON_TYPE_UNSHADE:
Packit 5e0819
              case META_BUTTON_TYPE_UNABOVE:
Packit 5e0819
              case META_BUTTON_TYPE_UNSTICK:
Packit 5e0819
              case META_BUTTON_TYPE_SPACER:
Packit 5e0819
              case META_BUTTON_TYPE_LAST:
Packit 5e0819
              default:
Packit 5e0819
                break;
Packit 5e0819
            }
Packit 5e0819
Packit 5e0819
          if (icon_name)
Packit 5e0819
            {
Packit 5e0819
              GtkIconTheme *theme;
Packit 5e0819
              GtkIconInfo *info;
Packit 5e0819
Packit 5e0819
              theme = gtk_icon_theme_get_default ();
Packit 5e0819
              info = gtk_icon_theme_lookup_icon_for_scale (theme, icon_name,
Packit 5e0819
                                                           style->layout->gtk.icon_size,
Packit 5e0819
                                                           scale, 0);
Packit 5e0819
Packit 5e0819
              g_assert (pixbuf == NULL);
Packit 5e0819
              pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL);
Packit 5e0819
            }
Packit 5e0819
Packit 5e0819
          if (pixbuf)
Packit 5e0819
            {
Packit 5e0819
              gdouble pwidth;
Packit 5e0819
              gdouble pheight;
Packit 5e0819
              gdouble px;
Packit 5e0819
              gdouble py;
Packit 5e0819
              gdouble scale_x;
Packit 5e0819
              gdouble scale_y;
Packit 5e0819
Packit 5e0819
              pwidth = gdk_pixbuf_get_width (pixbuf) / scale;
Packit 5e0819
              pheight = gdk_pixbuf_get_height (pixbuf) / scale;
Packit 5e0819
              px = x + (width - pwidth) / 2;
Packit 5e0819
              py = y + (height - pheight) / 2;
Packit 5e0819
Packit 5e0819
              scale_x = pwidth / style->layout->gtk.icon_size / scale;
Packit 5e0819
              scale_y = pheight / style->layout->gtk.icon_size / scale;
Packit 5e0819
Packit 5e0819
              cairo_translate (cr, px, py);
Packit 5e0819
              cairo_scale (cr, scale_x, scale_y);
Packit 5e0819
              gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
Packit 5e0819
              cairo_paint (cr);
Packit 5e0819
Packit 5e0819
              g_object_unref (pixbuf);
Packit 5e0819
            }
Packit 5e0819
Packit 5e0819
          cairo_restore (cr);
Packit 5e0819
Packit 5e0819
          if (button_class)
Packit 5e0819
            gtk_style_context_remove_class (context, button_class);
Packit 5e0819
Packit 5e0819
          gtk_style_context_set_state (context, state);
Packit 5e0819
        }
Packit 5e0819
    }
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
meta_theme_gtk_class_init (MetaThemeGtkClass *gtk_class)
Packit 5e0819
{
Packit 5e0819
  GObjectClass *object_class;
Packit 5e0819
  MetaThemeImplClass *impl_class;
Packit 5e0819
Packit 5e0819
  object_class = G_OBJECT_CLASS (gtk_class);
Packit 5e0819
  impl_class = META_THEME_IMPL_CLASS (gtk_class);
Packit 5e0819
Packit 5e0819
  object_class->dispose = meta_theme_gtk_dispose;
Packit 5e0819
Packit 5e0819
  impl_class->load = meta_theme_gtk_load;
Packit 5e0819
  impl_class->get_frame_style = meta_theme_gtk_get_frame_style;
Packit 5e0819
  impl_class->get_frame_borders = meta_theme_gtk_get_frame_borders;
Packit 5e0819
  impl_class->calc_geometry = meta_theme_gtk_calc_geometry;
Packit 5e0819
  impl_class->draw_frame = meta_theme_gtk_draw_frame;
Packit 5e0819
}
Packit 5e0819
Packit 5e0819
static void
Packit 5e0819
meta_theme_gtk_init (MetaThemeGtk *gtk)
Packit 5e0819
{
Packit 5e0819
  MetaFrameType type;
Packit 5e0819
Packit 5e0819
  for (type = 0; type < META_FRAME_TYPE_LAST; type++)
Packit 5e0819
    {
Packit 5e0819
      MetaFrameStyle *style;
Packit 5e0819
Packit 5e0819
      style = meta_frame_style_new (NULL);
Packit 5e0819
      style->layout = meta_frame_layout_new ();
Packit 5e0819
Packit 5e0819
      switch (type)
Packit 5e0819
        {
Packit 5e0819
          case META_FRAME_TYPE_NORMAL:
Packit 5e0819
          case META_FRAME_TYPE_DIALOG:
Packit 5e0819
          case META_FRAME_TYPE_MODAL_DIALOG:
Packit 5e0819
          case META_FRAME_TYPE_ATTACHED:
Packit 5e0819
            break;
Packit 5e0819
Packit 5e0819
          case META_FRAME_TYPE_MENU:
Packit 5e0819
          case META_FRAME_TYPE_UTILITY:
Packit 5e0819
            style->layout->title_scale = PANGO_SCALE_SMALL;
Packit 5e0819
            break;
Packit 5e0819
Packit 5e0819
          case META_FRAME_TYPE_BORDER:
Packit 5e0819
            style->layout->has_title = FALSE;
Packit 5e0819
            style->layout->hide_buttons = TRUE;
Packit 5e0819
            break;
Packit 5e0819
Packit 5e0819
          case META_FRAME_TYPE_LAST:
Packit 5e0819
          default:
Packit 5e0819
            g_assert_not_reached ();
Packit 5e0819
        }
Packit 5e0819
Packit 5e0819
      gtk->styles[type] = style;
Packit 5e0819
    }
Packit 5e0819
}