summaryrefslogtreecommitdiff
path: root/src/compositor/meta-background-group.c
blob: 5bf6d4a936cfb02f1a69505f3438fd3aa5e2686a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */

#include <config.h>

#include "compositor-private.h"
#include "clutter-utils.h"
#include "meta-background-actor-private.h"
#include "meta-background-group-private.h"

G_DEFINE_TYPE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR);

struct _MetaBackgroundGroupPrivate
{
  ClutterLayoutManager *layout_manager;
};

static void
meta_background_group_dispose (GObject *object)
{
  G_OBJECT_CLASS (meta_background_group_parent_class)->dispose (object);
}

static gboolean
meta_background_group_get_paint_volume (ClutterActor       *actor,
                                        ClutterPaintVolume *volume)
{
  return clutter_paint_volume_set_from_allocation (volume, actor);
}

static void
meta_background_group_class_init (MetaBackgroundGroupClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);

  actor_class->get_paint_volume = meta_background_group_get_paint_volume;
  object_class->dispose = meta_background_group_dispose;

  g_type_class_add_private (klass, sizeof (MetaBackgroundGroupPrivate));
}

static void
meta_background_group_init (MetaBackgroundGroup *self)
{
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
                                            META_TYPE_BACKGROUND_GROUP,
                                            MetaBackgroundGroupPrivate);

  self->priv->layout_manager = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FIXED,
                                                       CLUTTER_BIN_ALIGNMENT_FIXED);

  clutter_actor_set_layout_manager (CLUTTER_ACTOR (self), self->priv->layout_manager);
}

/**
 * meta_background_group_set_visible_region:
 * @self: a #MetaBackgroundGroup
 * @visible_region: (allow-none): the parts of the background to paint
 *
 * Sets the area of the backgrounds that is unobscured by overlapping windows.
 * This is used to optimize and only paint the visible portions.
 */
void
meta_background_group_set_visible_region (MetaBackgroundGroup *self,
                                          cairo_region_t      *region)
{
  GList *children, *l;

  children = clutter_actor_get_children (CLUTTER_ACTOR (self));
  for (l = children; l; l = l->next)
    {
      ClutterActor *actor = l->data;

      if (META_IS_BACKGROUND_ACTOR (actor))
        {
          meta_background_actor_set_visible_region (META_BACKGROUND_ACTOR (actor), region);
        }
      else if (META_IS_BACKGROUND_GROUP (actor))
        {
          int x, y;

          if (!meta_actor_is_untransformed (actor, &x, &y))
            continue;

          cairo_region_translate (region, -x, -y);
          meta_background_group_set_visible_region (META_BACKGROUND_GROUP (actor), region);
          cairo_region_translate (region, x, y);
        }
    }
  g_list_free (children);
}

ClutterActor *
meta_background_group_new (void)
{
  MetaBackgroundGroup *background_group;

  background_group = g_object_new (META_TYPE_BACKGROUND_GROUP, NULL);

  return CLUTTER_ACTOR (background_group);
}