Compare commits
66 Commits
wip/smcv/c
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
9321249b8d | |||
932340a989 | |||
ca0156e9a7 | |||
6d75b4fc53 | |||
6bd382ad23 | |||
a1b3d1a2a7 | |||
53f61f3778 | |||
74c0d9140c | |||
268336c21a | |||
49e983b06e | |||
0f97196d84 | |||
18c792d6f8 | |||
675a97d58e | |||
8127494e52 | |||
670f4f22fe | |||
e27d2702a8 | |||
dfe33897db | |||
90c20b185b | |||
4d7c8d68bc | |||
455de5d6d3 | |||
99c9f4c1fa | |||
dd32ff018a | |||
019643bad0 | |||
a031ac067e | |||
f712387325 | |||
1eaf9e5f63 | |||
7222bdde57 | |||
007d27fa40 | |||
01609de587 | |||
83ee122fad | |||
55302dbb38 | |||
7876018755 | |||
e3c332fa10 | |||
faa831f2f6 | |||
1a915f06cf | |||
6754195580 | |||
25f9406e69 | |||
9fc428f2e7 | |||
a05dd813da | |||
08b30d6fe2 | |||
84f55d38dd | |||
75b5e079cf | |||
d742f9331c | |||
420ca31f0b | |||
73da901cd3 | |||
dd16fac0c7 | |||
1b2af2891f | |||
050c21c24f | |||
7b45de941b | |||
8d84449941 | |||
f61d4b4e70 | |||
dcb42d3b25 | |||
59a2bff8e2 | |||
720360b07a | |||
9b39e37fee | |||
38104755a2 | |||
7abf0f1e2d | |||
0a37c32a72 | |||
9f121a211d | |||
c823b5ddba | |||
97175f8fa1 | |||
c5b1bdc0fe | |||
f8e2234ce5 | |||
38bbd9593b | |||
a3cc62c285 | |||
c3bf10d19a |
27
NEWS
27
NEWS
@ -1,3 +1,30 @@
|
||||
3.37.2
|
||||
======
|
||||
* Fix move-to-center keybinding with multiple monitors [Sergey; #1073]
|
||||
* Fix stuck buttons when a virtual device is destroyed [Carlos; !1239]
|
||||
* Use workarea when centering new windows [Akatsuki; #964]
|
||||
* Limit mipmap levels when rendering background [Daniel; !1003]
|
||||
* Broadcast clipboard/primary offers [Carlos; !1253]
|
||||
* Support primary-selection protocol from wayland-protocols [Carlos; !1255]
|
||||
* Fix monitor screen cast on X11 [Jonas Å.; !1251]
|
||||
* Support a "blank" cursor type [Florian; !1244]
|
||||
* Improve stage view damage tracking [Jonas Å.; !1237]
|
||||
* Implement touch-mode detecation for the X11 backend [Carlos; !1278]
|
||||
* Drop external keyboard detection from touch-mode heuristics [Carlos; !1277]
|
||||
* Optimize actor allocations [Jonas D.; !1247]
|
||||
* Fixed crashes [Daniel, Carlos, Jonas Å., Jonas D.; !1256, !1258, !1217, !1280]
|
||||
* Misc. bug fixes and cleanups [Christian, Jonas D., Olivier, Ting-Wei,
|
||||
Jonas Å., Marco, Corentin, Daniel, Robert, Niels, Florian, Simon; !1231,
|
||||
!1228, !1238, !1229, !1192, !1236, !1171, !1134, #1126, !1234, !1230, !1210,
|
||||
!1242, !1243, !1252, !1113, !1232, !1259, !1245, !1265, !1180, !1261, !788,
|
||||
!1264, !1235, !1218, !1150, !1274, !1271, !1279, !1283, !1272]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Akatsuki, Jonas Dreßler, Olivier Fourdan,
|
||||
Carlos Garnacho, Niels De Graef, Ting-Wei Lan, Robert Mader, Simon McVittie,
|
||||
Florian Müllner, Corentin Noël, Christian Rauch, Daniel van Vugt,
|
||||
Sergey Zigachev, Jonas Ådahl
|
||||
|
||||
3.37.1
|
||||
======
|
||||
* Fix screencasting non-maximized windows [Jonas Å.; !1174]
|
||||
|
@ -313,7 +313,7 @@ void _clutter_actor_detach_clone
|
||||
void _clutter_actor_queue_redraw_on_clones (ClutterActor *actor);
|
||||
void _clutter_actor_queue_relayout_on_clones (ClutterActor *actor);
|
||||
void _clutter_actor_queue_only_relayout (ClutterActor *actor);
|
||||
void _clutter_actor_queue_update_resource_scale_recursive (ClutterActor *actor);
|
||||
void clutter_actor_clear_stage_views_recursive (ClutterActor *actor);
|
||||
|
||||
gboolean _clutter_actor_get_real_resource_scale (ClutterActor *actor,
|
||||
float *resource_scale);
|
||||
@ -321,6 +321,8 @@ gboolean _clutter_actor_get_real_resource_scale
|
||||
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
|
||||
CoglTexture *texture);
|
||||
|
||||
void clutter_actor_update_stage_views (ClutterActor *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
|
||||
|
@ -446,7 +446,8 @@
|
||||
* ]|
|
||||
*
|
||||
* - the initial `@` is mandatory
|
||||
* - the `section` fragment can be one between "actions", "constraints" and "effects"
|
||||
* - the `section` fragment can be one between "actions", "constraints", "content",
|
||||
* and "effects"
|
||||
* - the `meta-name` fragment is the name of the action, effect, or constraint, as
|
||||
* specified by the #ClutterActorMeta:name property of #ClutterActorMeta
|
||||
* - the `property-name` fragment is the name of the action, effect, or constraint
|
||||
@ -811,6 +812,9 @@ struct _ClutterActorPrivate
|
||||
|
||||
gulong resolution_changed_id;
|
||||
gulong font_changed_id;
|
||||
gulong layout_changed_id;
|
||||
|
||||
GList *stage_views;
|
||||
|
||||
/* bitfields: KEEP AT THE END */
|
||||
|
||||
@ -854,6 +858,7 @@ struct _ClutterActorPrivate
|
||||
guint had_effects_on_last_paint_volume_update : 1;
|
||||
guint needs_compute_resource_scale : 1;
|
||||
guint absolute_origin_changed : 1;
|
||||
guint needs_update_stage_views : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -1016,6 +1021,7 @@ enum
|
||||
TRANSITIONS_COMPLETED,
|
||||
TOUCH_EVENT,
|
||||
TRANSITION_STOPPED,
|
||||
STAGE_VIEWS_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@ -1613,6 +1619,22 @@ clutter_actor_update_map_state (ClutterActor *self,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
queue_update_stage_views (ClutterActor *actor)
|
||||
{
|
||||
while (actor && !actor->priv->needs_update_stage_views)
|
||||
{
|
||||
actor->priv->needs_update_stage_views = TRUE;
|
||||
|
||||
/* We don't really need to update the stage-views of the actors up the
|
||||
* hierarchy, we set the flag anyway though so we can avoid traversing
|
||||
* the whole scenegraph when looking for actors which need an update
|
||||
* in clutter_actor_update_stage_views().
|
||||
*/
|
||||
actor = actor->priv->parent;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_real_map (ClutterActor *self)
|
||||
{
|
||||
@ -1627,6 +1649,18 @@ clutter_actor_real_map (ClutterActor *self)
|
||||
|
||||
self->priv->needs_paint_volume_update = TRUE;
|
||||
|
||||
/* We skip unmapped actors when updating the stage-views list, so if
|
||||
* an actors list got invalidated while it was unmapped make sure to
|
||||
* set priv->needs_update_stage_views to TRUE for all actors up the
|
||||
* hierarchy now.
|
||||
*/
|
||||
if (self->priv->needs_update_stage_views)
|
||||
{
|
||||
/* Avoid the early return in queue_update_stage_views() */
|
||||
self->priv->needs_update_stage_views = FALSE;
|
||||
queue_update_stage_views (self);
|
||||
}
|
||||
|
||||
clutter_actor_ensure_resource_scale (self);
|
||||
|
||||
/* notify on parent mapped before potentially mapping
|
||||
@ -2560,6 +2594,23 @@ clutter_actor_notify_if_geometry_changed (ClutterActor *self,
|
||||
g_object_thaw_notify (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
absolute_allocation_changed (ClutterActor *actor)
|
||||
{
|
||||
actor->priv->needs_compute_resource_scale = TRUE;
|
||||
queue_update_stage_views (actor);
|
||||
}
|
||||
|
||||
static ClutterActorTraverseVisitFlags
|
||||
absolute_allocation_changed_cb (ClutterActor *actor,
|
||||
int depth,
|
||||
gpointer user_data)
|
||||
{
|
||||
absolute_allocation_changed (actor);
|
||||
|
||||
return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* clutter_actor_set_allocation_internal:
|
||||
* @self: a #ClutterActor
|
||||
@ -2585,6 +2636,9 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
gboolean x1_changed, y1_changed, x2_changed, y2_changed;
|
||||
ClutterActorBox old_alloc = { 0, };
|
||||
|
||||
g_return_if_fail (!isnan (box->x1) && !isnan (box->x2) &&
|
||||
!isnan (box->y1) && !isnan (box->y2));
|
||||
|
||||
obj = G_OBJECT (self);
|
||||
|
||||
g_object_freeze_notify (obj);
|
||||
@ -2603,6 +2657,11 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
priv->needs_height_request = FALSE;
|
||||
priv->needs_allocation = FALSE;
|
||||
|
||||
priv->absolute_origin_changed |= x1_changed || y1_changed;
|
||||
|
||||
if (priv->absolute_origin_changed || x2_changed || y2_changed)
|
||||
absolute_allocation_changed (self);
|
||||
|
||||
if (x1_changed ||
|
||||
y1_changed ||
|
||||
x2_changed ||
|
||||
@ -4257,6 +4316,7 @@ typedef enum
|
||||
REMOVE_CHILD_FLUSH_QUEUE = 1 << 4,
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST = 1 << 5,
|
||||
REMOVE_CHILD_STOP_TRANSITIONS = 1 << 6,
|
||||
REMOVE_CHILD_CLEAR_STAGE_VIEWS = 1 << 7,
|
||||
|
||||
/* default flags for public API */
|
||||
REMOVE_CHILD_DEFAULT_FLAGS = REMOVE_CHILD_STOP_TRANSITIONS |
|
||||
@ -4265,14 +4325,16 @@ typedef enum
|
||||
REMOVE_CHILD_EMIT_ACTOR_REMOVED |
|
||||
REMOVE_CHILD_CHECK_STATE |
|
||||
REMOVE_CHILD_FLUSH_QUEUE |
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST,
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST |
|
||||
REMOVE_CHILD_CLEAR_STAGE_VIEWS,
|
||||
|
||||
/* flags for legacy/deprecated API */
|
||||
REMOVE_CHILD_LEGACY_FLAGS = REMOVE_CHILD_STOP_TRANSITIONS |
|
||||
REMOVE_CHILD_CHECK_STATE |
|
||||
REMOVE_CHILD_FLUSH_QUEUE |
|
||||
REMOVE_CHILD_EMIT_PARENT_SET |
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST
|
||||
REMOVE_CHILD_NOTIFY_FIRST_LAST |
|
||||
REMOVE_CHILD_CLEAR_STAGE_VIEWS
|
||||
} ClutterActorRemoveChildFlags;
|
||||
|
||||
/*< private >
|
||||
@ -4294,6 +4356,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
|
||||
gboolean notify_first_last;
|
||||
gboolean was_mapped;
|
||||
gboolean stop_transitions;
|
||||
gboolean clear_stage_views;
|
||||
GObject *obj;
|
||||
|
||||
if (self == child)
|
||||
@ -4310,6 +4373,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
|
||||
flush_queue = (flags & REMOVE_CHILD_FLUSH_QUEUE) != 0;
|
||||
notify_first_last = (flags & REMOVE_CHILD_NOTIFY_FIRST_LAST) != 0;
|
||||
stop_transitions = (flags & REMOVE_CHILD_STOP_TRANSITIONS) != 0;
|
||||
clear_stage_views = (flags & REMOVE_CHILD_CLEAR_STAGE_VIEWS) != 0;
|
||||
|
||||
obj = G_OBJECT (self);
|
||||
g_object_freeze_notify (obj);
|
||||
@ -4383,6 +4447,13 @@ clutter_actor_remove_child_internal (ClutterActor *self,
|
||||
clutter_actor_queue_compute_expand (self);
|
||||
}
|
||||
|
||||
/* Only actors which are attached to a stage get notified about changes
|
||||
* to the stage views, so make sure all the stage-views lists are
|
||||
* cleared as the child and its children leave the actor tree.
|
||||
*/
|
||||
if (clear_stage_views && !CLUTTER_ACTOR_IN_DESTRUCTION (child))
|
||||
clutter_actor_clear_stage_views_recursive (child);
|
||||
|
||||
if (emit_parent_set && !CLUTTER_ACTOR_IN_DESTRUCTION (child))
|
||||
{
|
||||
child->priv->needs_compute_resource_scale = TRUE;
|
||||
@ -5173,7 +5244,7 @@ clutter_actor_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_OFFSCREEN_REDIRECT:
|
||||
clutter_actor_set_offscreen_redirect (actor, g_value_get_enum (value));
|
||||
clutter_actor_set_offscreen_redirect (actor, g_value_get_flags (value));
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
@ -6038,6 +6109,7 @@ clutter_actor_dispose (GObject *object)
|
||||
|
||||
if (priv->layout_manager != NULL)
|
||||
{
|
||||
g_clear_signal_handler (&priv->layout_changed_id, priv->layout_manager);
|
||||
clutter_layout_manager_set_container (priv->layout_manager, NULL);
|
||||
g_clear_object (&priv->layout_manager);
|
||||
}
|
||||
@ -6054,6 +6126,8 @@ clutter_actor_dispose (GObject *object)
|
||||
priv->clones = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->stage_views, g_list_free);
|
||||
|
||||
G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -8590,6 +8664,27 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
g_signal_set_va_marshaller (actor_signals[TOUCH_EVENT],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_BOOLEAN__BOXEDv);
|
||||
|
||||
/**
|
||||
* ClutterActor::stage-views-changed:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* The ::stage-views-changed signal is emitted when the position or
|
||||
* size an actor is being painted at have changed so that it's visible
|
||||
* on different stage views.
|
||||
*
|
||||
* This signal is also emitted when the actor gets detached from the stage
|
||||
* or when the views of the stage have been invalidated and will be
|
||||
* replaced; it's not emitted when the actor gets hidden.
|
||||
*/
|
||||
actor_signals[STAGE_VIEWS_CHANGED] =
|
||||
g_signal_new (I_("stage-views-changed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -8608,6 +8703,7 @@ clutter_actor_init (ClutterActor *self)
|
||||
priv->needs_allocation = TRUE;
|
||||
priv->needs_paint_volume_update = TRUE;
|
||||
priv->needs_compute_resource_scale = TRUE;
|
||||
priv->needs_update_stage_views = TRUE;
|
||||
|
||||
priv->cached_width_age = 1;
|
||||
priv->cached_height_age = 1;
|
||||
@ -10094,7 +10190,6 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
{
|
||||
ClutterActorBox old_allocation, real_allocation;
|
||||
gboolean origin_changed, size_changed;
|
||||
gboolean stage_allocation_changed;
|
||||
ClutterActorPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
@ -10106,14 +10201,34 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!clutter_actor_is_visible (self))
|
||||
return;
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
priv->absolute_origin_changed = priv->parent
|
||||
? priv->parent->priv->absolute_origin_changed
|
||||
: FALSE;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
|
||||
{
|
||||
if (priv->absolute_origin_changed)
|
||||
{
|
||||
_clutter_actor_traverse (self,
|
||||
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
|
||||
absolute_allocation_changed_cb,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
old_allocation = priv->allocation;
|
||||
real_allocation = *box;
|
||||
|
||||
g_return_if_fail (!isnan (real_allocation.x1) &&
|
||||
!isnan (real_allocation.x2) &&
|
||||
!isnan (real_allocation.y1) &&
|
||||
!isnan (real_allocation.y2));
|
||||
|
||||
/* constraints are allowed to modify the allocation only here; we do
|
||||
* this prior to all the other checks so that we can bail out if the
|
||||
* allocation did not change
|
||||
@ -10142,49 +10257,46 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
size_changed = (real_allocation.x2 != old_allocation.x2 ||
|
||||
real_allocation.y2 != old_allocation.y2);
|
||||
|
||||
priv->absolute_origin_changed = priv->parent
|
||||
? priv->parent->priv->absolute_origin_changed
|
||||
: FALSE;
|
||||
|
||||
priv->absolute_origin_changed |= origin_changed;
|
||||
|
||||
stage_allocation_changed = priv->absolute_origin_changed || size_changed;
|
||||
|
||||
/* If we get an allocation "out of the blue"
|
||||
* (we did not queue relayout), then we want to
|
||||
* ignore it. But if we have needs_allocation set,
|
||||
* we want to guarantee that allocate() virtual
|
||||
* method is always called, i.e. that queue_relayout()
|
||||
* always results in an allocate() invocation on
|
||||
* an actor.
|
||||
/* When needs_allocation is set but we didn't move nor resize, we still
|
||||
* want to call the allocate() vfunc because a child probably called
|
||||
* queue_relayout() and needs a new allocation.
|
||||
*
|
||||
* The optimization here is to avoid re-allocating
|
||||
* actors that did not queue relayout and were
|
||||
* not moved.
|
||||
* In case needs_allocation isn't set and we didn't move nor resize, we
|
||||
* can safely stop allocating, but we need to notify the sub-tree in case
|
||||
* our absolute origin changed.
|
||||
*/
|
||||
if (!priv->needs_allocation && !stage_allocation_changed)
|
||||
if (!priv->needs_allocation && !origin_changed && !size_changed)
|
||||
{
|
||||
if (priv->absolute_origin_changed)
|
||||
{
|
||||
_clutter_actor_traverse (self,
|
||||
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
|
||||
absolute_allocation_changed_cb,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
CLUTTER_NOTE (LAYOUT, "No allocation needed");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (CLUTTER_ACTOR_IS_MAPPED (self))
|
||||
self->priv->needs_paint_volume_update = TRUE;
|
||||
|
||||
if (stage_allocation_changed)
|
||||
priv->needs_compute_resource_scale = TRUE;
|
||||
|
||||
if (!stage_allocation_changed)
|
||||
if (!origin_changed && !size_changed)
|
||||
{
|
||||
/* If the actor didn't move but needs_allocation is set, we just
|
||||
* need to allocate the children */
|
||||
* need to allocate the children (see comment above) */
|
||||
clutter_actor_allocate_internal (self, &real_allocation);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
_clutter_actor_create_transition (self, obj_props[PROP_ALLOCATION],
|
||||
&priv->allocation,
|
||||
&real_allocation);
|
||||
|
||||
out:
|
||||
priv->absolute_origin_changed = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -14511,6 +14623,37 @@ get_layout_from_animation_property (ClutterActor *actor,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_content_from_animation_property (ClutterActor *actor,
|
||||
const gchar *name,
|
||||
gchar **name_p)
|
||||
{
|
||||
g_auto (GStrv) tokens = NULL;
|
||||
|
||||
if (!g_str_has_prefix (name, "@content"))
|
||||
return FALSE;
|
||||
|
||||
if (!actor->priv->content)
|
||||
{
|
||||
CLUTTER_NOTE (ANIMATION, "No ClutterContent available for '%s'",
|
||||
name + 1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tokens = g_strsplit (name, ".", -1);
|
||||
if (tokens == NULL || g_strv_length (tokens) != 2)
|
||||
{
|
||||
CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'",
|
||||
name + 1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (name_p != NULL)
|
||||
*name_p = g_strdup (tokens[1]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterActorMeta *
|
||||
get_meta_from_animation_property (ClutterActor *actor,
|
||||
const gchar *name,
|
||||
@ -14578,6 +14721,7 @@ clutter_actor_find_property (ClutterAnimatable *animatable,
|
||||
GObjectClass *klass = NULL;
|
||||
GParamSpec *pspec = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_content = FALSE;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
@ -14585,6 +14729,11 @@ clutter_actor_find_property (ClutterAnimatable *animatable,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
use_content = get_content_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout && !use_content)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
@ -14599,6 +14748,12 @@ clutter_actor_find_property (ClutterAnimatable *animatable,
|
||||
{
|
||||
klass = G_OBJECT_GET_CLASS (actor->priv->layout_manager);
|
||||
|
||||
pspec = g_object_class_find_property (klass, p_name);
|
||||
}
|
||||
else if (use_content)
|
||||
{
|
||||
klass = G_OBJECT_GET_CLASS (actor->priv->content);
|
||||
|
||||
pspec = g_object_class_find_property (klass, p_name);
|
||||
}
|
||||
else
|
||||
@ -14621,6 +14776,7 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable,
|
||||
ClutterActor *actor = CLUTTER_ACTOR (animatable);
|
||||
ClutterActorMeta *meta = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_content = FALSE;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
@ -14628,6 +14784,11 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
use_content = get_content_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout && !use_content)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
@ -14636,6 +14797,8 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable,
|
||||
g_object_get_property (G_OBJECT (meta), p_name, initial);
|
||||
else if (use_layout)
|
||||
g_object_get_property (G_OBJECT (actor->priv->layout_manager), p_name, initial);
|
||||
else if (use_content)
|
||||
g_object_get_property (G_OBJECT (actor->priv->content), p_name, initial);
|
||||
else
|
||||
g_object_get_property (G_OBJECT (animatable), property_name, initial);
|
||||
|
||||
@ -14786,6 +14949,7 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable,
|
||||
ClutterActor *actor = CLUTTER_ACTOR (animatable);
|
||||
ClutterActorMeta *meta = NULL;
|
||||
gchar *p_name = NULL;
|
||||
gboolean use_content = FALSE;
|
||||
gboolean use_layout;
|
||||
|
||||
use_layout = get_layout_from_animation_property (actor,
|
||||
@ -14793,6 +14957,11 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout)
|
||||
use_content = get_content_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
|
||||
if (!use_layout && !use_content)
|
||||
meta = get_meta_from_animation_property (actor,
|
||||
property_name,
|
||||
&p_name);
|
||||
@ -14801,6 +14970,8 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable,
|
||||
g_object_set_property (G_OBJECT (meta), p_name, final);
|
||||
else if (use_layout)
|
||||
g_object_set_property (G_OBJECT (actor->priv->layout_manager), p_name, final);
|
||||
else if (use_content)
|
||||
g_object_set_property (G_OBJECT (actor->priv->content), p_name, final);
|
||||
else
|
||||
{
|
||||
GObjectClass *obj_class = G_OBJECT_GET_CLASS (animatable);
|
||||
@ -17379,17 +17550,27 @@ _clutter_actor_get_resource_scale_for_rect (ClutterActor *self,
|
||||
float *resource_scale)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
g_autoptr (GList) views = NULL;
|
||||
GList *l;
|
||||
float max_scale = 0;
|
||||
|
||||
stage = _clutter_actor_get_stage_internal (self);
|
||||
if (!stage)
|
||||
return FALSE;
|
||||
|
||||
if (!_clutter_stage_get_max_view_scale_factor_for_rect (CLUTTER_STAGE (stage),
|
||||
bounding_rect,
|
||||
&max_scale))
|
||||
views = clutter_stage_get_views_for_rect (CLUTTER_STAGE (stage),
|
||||
bounding_rect);
|
||||
|
||||
if (!views)
|
||||
return FALSE;
|
||||
|
||||
for (l = views; l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
|
||||
max_scale = MAX (clutter_stage_view_get_scale (view), max_scale);
|
||||
}
|
||||
|
||||
*resource_scale = max_scale;
|
||||
|
||||
return TRUE;
|
||||
@ -17465,20 +17646,29 @@ _clutter_actor_compute_resource_scale (ClutterActor *self,
|
||||
}
|
||||
|
||||
static ClutterActorTraverseVisitFlags
|
||||
queue_update_resource_scale_cb (ClutterActor *actor,
|
||||
int depth,
|
||||
void *user_data)
|
||||
clear_stage_views_cb (ClutterActor *actor,
|
||||
int depth,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr (GList) old_stage_views = NULL;
|
||||
|
||||
actor->priv->needs_update_stage_views = TRUE;
|
||||
actor->priv->needs_compute_resource_scale = TRUE;
|
||||
|
||||
old_stage_views = g_steal_pointer (&actor->priv->stage_views);
|
||||
|
||||
if (old_stage_views)
|
||||
g_signal_emit (actor, actor_signals[STAGE_VIEWS_CHANGED], 0);
|
||||
|
||||
return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_actor_queue_update_resource_scale_recursive (ClutterActor *self)
|
||||
clutter_actor_clear_stage_views_recursive (ClutterActor *self)
|
||||
{
|
||||
_clutter_actor_traverse (self,
|
||||
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
|
||||
queue_update_resource_scale_cb,
|
||||
clear_stage_views_cb,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
@ -17570,6 +17760,125 @@ clutter_actor_get_resource_scale (ClutterActor *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sorted_lists_equal (GList *list_a,
|
||||
GList *list_b)
|
||||
{
|
||||
GList *a, *b;
|
||||
|
||||
if (!list_a && !list_b)
|
||||
return TRUE;
|
||||
|
||||
for (a = list_a, b = list_b;
|
||||
a && b;
|
||||
a = a->next, b = b->next)
|
||||
{
|
||||
if (a->data != b->data)
|
||||
break;
|
||||
|
||||
if (!a->next && !b->next)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_stage_views (ClutterActor *self)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
g_autoptr (GList) old_stage_views = NULL;
|
||||
ClutterStage *stage;
|
||||
graphene_rect_t bounding_rect;
|
||||
|
||||
old_stage_views = g_steal_pointer (&priv->stage_views);
|
||||
|
||||
if (priv->needs_allocation)
|
||||
{
|
||||
g_warning ("Can't update stage views actor %s is on because it needs an "
|
||||
"allocation.", _clutter_actor_get_debug_name (self));
|
||||
goto out;
|
||||
}
|
||||
|
||||
stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self));
|
||||
g_return_if_fail (stage);
|
||||
|
||||
clutter_actor_get_transformed_position (self,
|
||||
&bounding_rect.origin.x,
|
||||
&bounding_rect.origin.y);
|
||||
clutter_actor_get_transformed_size (self,
|
||||
&bounding_rect.size.width,
|
||||
&bounding_rect.size.height);
|
||||
|
||||
if (bounding_rect.size.width == 0.0 ||
|
||||
bounding_rect.size.height == 0.0)
|
||||
goto out;
|
||||
|
||||
priv->stage_views = clutter_stage_get_views_for_rect (stage,
|
||||
&bounding_rect);
|
||||
|
||||
out:
|
||||
if (g_signal_has_handler_pending (self, actor_signals[STAGE_VIEWS_CHANGED],
|
||||
0, TRUE))
|
||||
{
|
||||
if (!sorted_lists_equal (old_stage_views, priv->stage_views))
|
||||
g_signal_emit (self, actor_signals[STAGE_VIEWS_CHANGED], 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_actor_update_stage_views (ClutterActor *self)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
ClutterActor *child;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (self) ||
|
||||
CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||
return;
|
||||
|
||||
if (!priv->needs_update_stage_views)
|
||||
return;
|
||||
|
||||
update_stage_views (self);
|
||||
|
||||
priv->needs_update_stage_views = FALSE;
|
||||
|
||||
for (child = priv->first_child; child; child = child->priv->next_sibling)
|
||||
clutter_actor_update_stage_views (child);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_peek_stage_views:
|
||||
* @self: A #ClutterActor
|
||||
*
|
||||
* Retrieves the list of #ClutterStageView<!-- -->s the actor is being
|
||||
* painted on.
|
||||
*
|
||||
* If this function is called during the paint cycle, the list is guaranteed
|
||||
* to be up-to-date, if called outside the paint cycle, the list will
|
||||
* contain the views the actor was painted on last.
|
||||
*
|
||||
* The list returned by this function is not updated when the actors
|
||||
* visibility changes: If an actor gets hidden and is not being painted
|
||||
* anymore, this function will return the list of views the actor was
|
||||
* painted on last.
|
||||
*
|
||||
* If an actor is not attached to a stage (realized), this function will
|
||||
* always return an empty list.
|
||||
*
|
||||
* Returns: (transfer none) (element-type Clutter.StageView): The list of
|
||||
* #ClutterStageView<!-- -->s the actor is being painted on. The list and
|
||||
* its contents are owned by the #ClutterActor and the list may not be
|
||||
* freed or modified.
|
||||
*/
|
||||
GList *
|
||||
clutter_actor_peek_stage_views (ClutterActor *self)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
|
||||
|
||||
return self->priv->stage_views;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_has_overlaps:
|
||||
* @self: A #ClutterActor
|
||||
@ -17931,9 +18240,7 @@ clutter_actor_set_layout_manager (ClutterActor *self,
|
||||
|
||||
if (priv->layout_manager != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->layout_manager,
|
||||
G_CALLBACK (on_layout_manager_changed),
|
||||
self);
|
||||
g_clear_signal_handler (&priv->layout_changed_id, priv->layout_manager);
|
||||
clutter_layout_manager_set_container (priv->layout_manager, NULL);
|
||||
g_clear_object (&priv->layout_manager);
|
||||
}
|
||||
@ -17945,9 +18252,10 @@ clutter_actor_set_layout_manager (ClutterActor *self,
|
||||
g_object_ref_sink (priv->layout_manager);
|
||||
clutter_layout_manager_set_container (priv->layout_manager,
|
||||
CLUTTER_CONTAINER (self));
|
||||
g_signal_connect (priv->layout_manager, "layout-changed",
|
||||
G_CALLBACK (on_layout_manager_changed),
|
||||
self);
|
||||
priv->layout_changed_id =
|
||||
g_signal_connect (priv->layout_manager, "layout-changed",
|
||||
G_CALLBACK (on_layout_manager_changed),
|
||||
self);
|
||||
}
|
||||
|
||||
clutter_actor_queue_relayout (self);
|
||||
|
@ -919,6 +919,9 @@ void clutter_actor_pick_box (ClutterActor *self,
|
||||
ClutterPickContext *pick_context,
|
||||
const ClutterActorBox *box);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_peek_stage_views (ClutterActor *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_H__ */
|
||||
|
@ -84,12 +84,11 @@ G_DEFINE_TYPE (ClutterAlignConstraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
|
||||
static void
|
||||
source_position_changed (ClutterActor *actor,
|
||||
GParamSpec *pspec,
|
||||
ClutterAlignConstraint *align)
|
||||
source_queue_relayout (ClutterActor *actor,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
_clutter_actor_queue_only_relayout (align->actor);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -186,7 +185,7 @@ clutter_align_constraint_dispose (GObject *gobject)
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (align->source,
|
||||
G_CALLBACK (source_position_changed),
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
align->source = NULL;
|
||||
}
|
||||
@ -402,15 +401,15 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_position_changed),
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
}
|
||||
|
||||
align->source = source;
|
||||
if (align->source != NULL)
|
||||
{
|
||||
g_signal_connect (align->source, "notify::allocation",
|
||||
G_CALLBACK (source_position_changed),
|
||||
g_signal_connect (align->source, "queue-relayout",
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
g_signal_connect (align->source, "destroy",
|
||||
G_CALLBACK (source_destroyed),
|
||||
|
@ -1317,8 +1317,6 @@ typedef enum
|
||||
* painting the stages
|
||||
* @CLUTTER_REPAINT_FLAGS_POST_PAINT: Run the repaint function after
|
||||
* painting the stages
|
||||
* @CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD: Ensure that a new frame
|
||||
* is queued after adding the repaint function
|
||||
*
|
||||
* Flags to pass to clutter_threads_add_repaint_func_full().
|
||||
*
|
||||
@ -1328,7 +1326,6 @@ typedef enum
|
||||
{
|
||||
CLUTTER_REPAINT_FLAGS_PRE_PAINT = 1 << 0,
|
||||
CLUTTER_REPAINT_FLAGS_POST_PAINT = 1 << 1,
|
||||
CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD = 1 << 2
|
||||
} ClutterRepaintFlags;
|
||||
|
||||
/**
|
||||
|
@ -2392,8 +2392,7 @@ clutter_threads_add_repaint_func_full (ClutterRepaintFlags flags,
|
||||
|
||||
repaint_func->id = context->last_repaint_id++;
|
||||
|
||||
/* mask out QUEUE_REDRAW_ON_ADD, since we're going to consume it */
|
||||
repaint_func->flags = flags & ~CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD;
|
||||
repaint_func->flags = flags;
|
||||
repaint_func->func = func;
|
||||
repaint_func->data = data;
|
||||
repaint_func->notify = notify;
|
||||
@ -2403,13 +2402,6 @@ clutter_threads_add_repaint_func_full (ClutterRepaintFlags flags,
|
||||
|
||||
_clutter_context_unlock ();
|
||||
|
||||
if ((flags & CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD) != 0)
|
||||
{
|
||||
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
|
||||
|
||||
_clutter_master_clock_ensure_next_iteration (master_clock);
|
||||
}
|
||||
|
||||
return repaint_func->id;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ CLUTTER_EXPORT
|
||||
void clutter_stage_thaw_updates (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_update_resource_scales (ClutterStage *stage);
|
||||
void clutter_stage_clear_stage_views (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_view_assign_next_scanout (ClutterStageView *stage_view,
|
||||
|
@ -136,7 +136,8 @@ enum
|
||||
|
||||
static guint pan_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterPanAction, clutter_pan_action, CLUTTER_TYPE_GESTURE_ACTION)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterPanAction, clutter_pan_action,
|
||||
CLUTTER_TYPE_GESTURE_ACTION)
|
||||
|
||||
static void
|
||||
emit_pan (ClutterPanAction *self,
|
||||
@ -156,14 +157,18 @@ emit_pan (ClutterPanAction *self,
|
||||
gfloat scroll_threshold = G_PI_4/2;
|
||||
gfloat drag_angle;
|
||||
|
||||
clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (self), 0, &delta_x, &delta_y);
|
||||
clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (self),
|
||||
0,
|
||||
&delta_x,
|
||||
&delta_y);
|
||||
|
||||
if (delta_x != 0.0f)
|
||||
drag_angle = atanf (delta_y / delta_x);
|
||||
else
|
||||
drag_angle = G_PI_2;
|
||||
|
||||
if ((drag_angle > -scroll_threshold) && (drag_angle < scroll_threshold))
|
||||
if ((drag_angle > -scroll_threshold) &&
|
||||
(drag_angle < scroll_threshold))
|
||||
priv->pin_state = SCROLL_PINNED_HORIZONTAL;
|
||||
else if ((drag_angle > (G_PI_2 - scroll_threshold)) ||
|
||||
(drag_angle < -(G_PI_2 - scroll_threshold)))
|
||||
@ -282,7 +287,10 @@ gesture_end (ClutterGestureAction *gesture,
|
||||
gfloat tau;
|
||||
gint duration;
|
||||
|
||||
clutter_gesture_action_get_release_coords (CLUTTER_GESTURE_ACTION (self), 0, &priv->release_x, &priv->release_y);
|
||||
clutter_gesture_action_get_release_coords (CLUTTER_GESTURE_ACTION (self),
|
||||
0,
|
||||
&priv->release_x,
|
||||
&priv->release_y);
|
||||
|
||||
if (!priv->should_interpolate)
|
||||
{
|
||||
@ -293,7 +301,9 @@ gesture_end (ClutterGestureAction *gesture,
|
||||
priv->state = PAN_STATE_INTERPOLATING;
|
||||
|
||||
clutter_gesture_action_get_motion_delta (gesture, 0, &delta_x, &delta_y);
|
||||
velocity = clutter_gesture_action_get_velocity (gesture, 0, &velocity_x, &velocity_y);
|
||||
velocity = clutter_gesture_action_get_velocity (gesture, 0,
|
||||
&velocity_x,
|
||||
&velocity_y);
|
||||
|
||||
/* Exponential timing constant v(t) = v(0) * exp(-t/tau)
|
||||
* tau = 1000ms / (frame_per_second * - ln(decay_per_frame))
|
||||
@ -304,17 +314,22 @@ gesture_end (ClutterGestureAction *gesture,
|
||||
/* See where the decreasing velocity reaches $min_velocity px/ms
|
||||
* v(t) = v(0) * exp(-t/tau) = min_velocity
|
||||
* t = - tau * ln( min_velocity / |v(0)|) */
|
||||
duration = - tau * logf (min_velocity / (ABS (velocity) * priv->acceleration_factor));
|
||||
duration = - tau * logf (min_velocity / (ABS (velocity) *
|
||||
priv->acceleration_factor));
|
||||
|
||||
/* Target point: x(t) = v(0) * tau * [1 - exp(-t/tau)] */
|
||||
priv->target_x = velocity_x * priv->acceleration_factor * tau * (1 - exp ((float)-duration / tau));
|
||||
priv->target_y = velocity_y * priv->acceleration_factor * tau * (1 - exp ((float)-duration / tau));
|
||||
priv->target_x = (velocity_x * priv->acceleration_factor * tau *
|
||||
(1 - exp ((float)-duration / tau)));
|
||||
priv->target_y = (velocity_y * priv->acceleration_factor * tau *
|
||||
(1 - exp ((float)-duration / tau)));
|
||||
|
||||
if (ABS (velocity) * priv->acceleration_factor > min_velocity && duration > FLOAT_EPSILON)
|
||||
if (ABS (velocity) * priv->acceleration_factor > min_velocity &&
|
||||
duration > FLOAT_EPSILON)
|
||||
{
|
||||
priv->interpolated_x = priv->interpolated_y = 0.0f;
|
||||
priv->deceleration_timeline = clutter_timeline_new (duration);
|
||||
clutter_timeline_set_progress_mode (priv->deceleration_timeline, CLUTTER_EASE_OUT_EXPO);
|
||||
clutter_timeline_set_progress_mode (priv->deceleration_timeline,
|
||||
CLUTTER_EASE_OUT_EXPO);
|
||||
|
||||
g_signal_connect (priv->deceleration_timeline, "new_frame",
|
||||
G_CALLBACK (on_deceleration_new_frame), self);
|
||||
@ -367,7 +382,8 @@ clutter_pan_action_set_property (GObject *gobject,
|
||||
break;
|
||||
|
||||
case PROP_ACCELERATION_FACTOR :
|
||||
clutter_pan_action_set_acceleration_factor (self, g_value_get_double (value));
|
||||
clutter_pan_action_set_acceleration_factor (self,
|
||||
g_value_get_double (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -411,9 +427,11 @@ static void
|
||||
clutter_pan_action_constructed (GObject *gobject)
|
||||
{
|
||||
ClutterGestureAction *gesture;
|
||||
ClutterGestureTriggerEdge edge;
|
||||
|
||||
gesture = CLUTTER_GESTURE_ACTION (gobject);
|
||||
clutter_gesture_action_set_threshold_trigger_edge (gesture, CLUTTER_GESTURE_TRIGGER_EDGE_AFTER);
|
||||
edge = CLUTTER_GESTURE_TRIGGER_EDGE_AFTER;
|
||||
clutter_gesture_action_set_threshold_trigger_edge (gesture, edge);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -442,7 +460,8 @@ clutter_pan_action_set_actor (ClutterActorMeta *meta,
|
||||
g_clear_object (&priv->deceleration_timeline);
|
||||
}
|
||||
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_pan_action_parent_class)->set_actor (meta, actor);
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_pan_action_parent_class)->set_actor (meta,
|
||||
actor);
|
||||
}
|
||||
|
||||
|
||||
@ -880,7 +899,9 @@ clutter_pan_action_get_constrained_motion_delta (ClutterPanAction *self,
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
distance = clutter_pan_action_get_motion_delta (self, point, &delta_x, &delta_y);
|
||||
distance = clutter_pan_action_get_motion_delta (self, point,
|
||||
&delta_x,
|
||||
&delta_y);
|
||||
|
||||
switch (priv->pan_axis)
|
||||
{
|
||||
|
@ -1523,7 +1523,7 @@ clutter_script_construct_parameters (ClutterScript *script,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(pspec->flags & G_PARAM_CONSTRUCT_ONLY))
|
||||
if (!(pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
|
||||
{
|
||||
unparsed = g_list_prepend (unparsed, pinfo);
|
||||
continue;
|
||||
|
@ -682,7 +682,6 @@ clutter_seat_warp_pointer (ClutterSeat *seat,
|
||||
* requirements are fulfilled:
|
||||
*
|
||||
* - A touchscreen is available
|
||||
* - No external keyboard is attached to the device
|
||||
* - A tablet mode switch, if present, is enabled
|
||||
*
|
||||
* Returns: %TRUE if the device is a tablet that doesn't have an external
|
||||
|
@ -50,11 +50,6 @@ ClutterStageWindow *_clutter_stage_get_window (ClutterStage
|
||||
void _clutter_stage_get_projection_matrix (ClutterStage *stage,
|
||||
CoglMatrix *projection);
|
||||
void _clutter_stage_dirty_projection (ClutterStage *stage);
|
||||
void _clutter_stage_set_viewport (ClutterStage *stage,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height);
|
||||
void _clutter_stage_get_viewport (ClutterStage *stage,
|
||||
float *x,
|
||||
float *y,
|
||||
@ -130,9 +125,6 @@ gboolean _clutter_stage_update_state (ClutterStage *stag
|
||||
|
||||
void _clutter_stage_set_scale_factor (ClutterStage *stage,
|
||||
int factor);
|
||||
gboolean _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
|
||||
graphene_rect_t *rect,
|
||||
float *view_scale);
|
||||
|
||||
void _clutter_stage_presented (ClutterStage *stage,
|
||||
CoglFrameEvent frame_event,
|
||||
@ -141,6 +133,9 @@ void _clutter_stage_presented (ClutterStage *stag
|
||||
void clutter_stage_queue_actor_relayout (ClutterStage *stage,
|
||||
ClutterActor *actor);
|
||||
|
||||
GList * clutter_stage_get_views_for_rect (ClutterStage *stage,
|
||||
const graphene_rect_t *rect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
||||
|
@ -189,6 +189,9 @@ static void capture_view_into (ClutterStage *stage,
|
||||
uint8_t *data,
|
||||
int stride);
|
||||
static void clutter_stage_update_view_perspective (ClutterStage *stage);
|
||||
static void clutter_stage_set_viewport (ClutterStage *stage,
|
||||
float width,
|
||||
float height);
|
||||
|
||||
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||
|
||||
@ -619,7 +622,6 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
{
|
||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||
ClutterActorBox alloc = CLUTTER_ACTOR_BOX_INIT_ZERO;
|
||||
float old_width, old_height;
|
||||
float new_width, new_height;
|
||||
float width, height;
|
||||
cairo_rectangle_int_t window_size;
|
||||
@ -628,10 +630,6 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
if (priv->impl == NULL)
|
||||
return;
|
||||
|
||||
/* our old allocation */
|
||||
clutter_actor_get_allocation_box (self, &alloc);
|
||||
clutter_actor_box_get_size (&alloc, &old_width, &old_height);
|
||||
|
||||
/* the current allocation */
|
||||
clutter_actor_box_get_size (box, &width, &height);
|
||||
|
||||
@ -719,27 +717,11 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
&override);
|
||||
}
|
||||
|
||||
/* reset the viewport if the allocation effectively changed */
|
||||
/* set the viewport to the new allocation */
|
||||
clutter_actor_get_allocation_box (self, &alloc);
|
||||
clutter_actor_box_get_size (&alloc, &new_width, &new_height);
|
||||
|
||||
if (CLUTTER_NEARBYINT (old_width) != CLUTTER_NEARBYINT (new_width) ||
|
||||
CLUTTER_NEARBYINT (old_height) != CLUTTER_NEARBYINT (new_height))
|
||||
{
|
||||
int real_width = CLUTTER_NEARBYINT (new_width);
|
||||
int real_height = CLUTTER_NEARBYINT (new_height);
|
||||
|
||||
_clutter_stage_set_viewport (CLUTTER_STAGE (self),
|
||||
0, 0,
|
||||
real_width,
|
||||
real_height);
|
||||
|
||||
/* Note: we don't assume that set_viewport will queue a full redraw
|
||||
* since it may bail-out early if something preemptively set the
|
||||
* viewport before the stage was really allocated its new size.
|
||||
*/
|
||||
queue_full_redraw (CLUTTER_STAGE (self));
|
||||
}
|
||||
clutter_stage_set_viewport (CLUTTER_STAGE (self), new_width, new_height);
|
||||
}
|
||||
|
||||
typedef struct _Vector4
|
||||
@ -1089,6 +1071,7 @@ clutter_stage_hide (ClutterActor *self)
|
||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||
|
||||
g_assert (priv->impl != NULL);
|
||||
_clutter_stage_clear_pick_stack (CLUTTER_STAGE (self));
|
||||
_clutter_stage_window_hide (priv->impl);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->hide (self);
|
||||
@ -1486,6 +1469,14 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage)
|
||||
return updating;
|
||||
}
|
||||
|
||||
static void
|
||||
update_actor_stage_views (ClutterStage *stage)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (stage);
|
||||
|
||||
clutter_actor_update_stage_views (actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* _clutter_stage_do_update:
|
||||
* @stage: A #ClutterStage
|
||||
@ -1533,6 +1524,10 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
if (stage_was_relayout)
|
||||
pointers = _clutter_stage_check_updated_pointers (stage);
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStageUpdateActorStageViews, "Actor stage-views");
|
||||
update_actor_stage_views (stage);
|
||||
COGL_TRACE_END (ClutterStageUpdateActorStageViews);
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStagePaint, "Paint");
|
||||
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
@ -2257,10 +2252,7 @@ clutter_stage_init (ClutterStage *self)
|
||||
g_signal_connect (self, "notify::min-height",
|
||||
G_CALLBACK (clutter_stage_notify_min_size), NULL);
|
||||
|
||||
_clutter_stage_set_viewport (self,
|
||||
0, 0,
|
||||
geom.width,
|
||||
geom.height);
|
||||
clutter_stage_set_viewport (self, geom.width, geom.height);
|
||||
|
||||
priv->paint_volume_stack =
|
||||
g_array_new (FALSE, FALSE, sizeof (ClutterPaintVolume));
|
||||
@ -2447,8 +2439,6 @@ _clutter_stage_dirty_projection (ClutterStage *stage)
|
||||
/*
|
||||
* clutter_stage_set_viewport:
|
||||
* @stage: A #ClutterStage
|
||||
* @x: The X postition to render the stage at, in window coordinates
|
||||
* @y: The Y position to render the stage at, in window coordinates
|
||||
* @width: The width to render the stage at, in window coordinates
|
||||
* @height: The height to render the stage at, in window coordinates
|
||||
*
|
||||
@ -2481,19 +2471,22 @@ _clutter_stage_dirty_projection (ClutterStage *stage)
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
void
|
||||
_clutter_stage_set_viewport (ClutterStage *stage,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height)
|
||||
static void
|
||||
clutter_stage_set_viewport (ClutterStage *stage,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
float x, y;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
x = 0.f;
|
||||
y = 0.f;
|
||||
width = roundf (width);
|
||||
height = roundf (height);
|
||||
|
||||
if (x == priv->viewport[0] &&
|
||||
y == priv->viewport[1] &&
|
||||
@ -3191,37 +3184,6 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
|
||||
#undef _DEG_TO_RAD
|
||||
|
||||
/**
|
||||
* clutter_stage_ensure_redraw:
|
||||
* @stage: a #ClutterStage
|
||||
*
|
||||
* Ensures that @stage is redrawn
|
||||
*
|
||||
* This function should not be called by applications: it is
|
||||
* used when embedding a #ClutterStage into a toolkit with
|
||||
* another windowing system, like GTK+.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_stage_ensure_redraw (ClutterStage *stage)
|
||||
{
|
||||
ClutterMasterClock *master_clock;
|
||||
ClutterStagePrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
if (!_clutter_stage_needs_update (stage))
|
||||
clutter_stage_schedule_update (stage);
|
||||
|
||||
priv->redraw_pending = TRUE;
|
||||
|
||||
master_clock = _clutter_master_clock_get_default ();
|
||||
_clutter_master_clock_start_running (master_clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_is_redraw_queued: (skip)
|
||||
*/
|
||||
@ -4127,20 +4089,29 @@ clutter_stage_get_capture_final_size (ClutterStage *stage,
|
||||
int *out_height,
|
||||
float *out_scale)
|
||||
{
|
||||
float max_scale;
|
||||
float max_scale = 1.0;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
|
||||
|
||||
if (rect)
|
||||
{
|
||||
graphene_rect_t capture_rect;
|
||||
g_autoptr (GList) views = NULL;
|
||||
GList *l;
|
||||
|
||||
_clutter_util_rect_from_rectangle (rect, &capture_rect);
|
||||
if (!_clutter_stage_get_max_view_scale_factor_for_rect (stage,
|
||||
&capture_rect,
|
||||
&max_scale))
|
||||
views = clutter_stage_get_views_for_rect (stage, &capture_rect);
|
||||
|
||||
if (!views)
|
||||
return FALSE;
|
||||
|
||||
for (l = views; l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
|
||||
max_scale = MAX (clutter_stage_view_get_scale (view), max_scale);
|
||||
}
|
||||
|
||||
if (out_width)
|
||||
*out_width = (gint) roundf (rect->width * max_scale);
|
||||
|
||||
@ -4421,18 +4392,17 @@ clutter_stage_peek_stage_views (ClutterStage *stage)
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_update_resource_scales (ClutterStage *stage)
|
||||
clutter_stage_clear_stage_views (ClutterStage *stage)
|
||||
{
|
||||
_clutter_actor_queue_update_resource_scale_recursive (CLUTTER_ACTOR (stage));
|
||||
clutter_actor_clear_stage_views_recursive (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
|
||||
graphene_rect_t *rect,
|
||||
float *view_scale)
|
||||
GList *
|
||||
clutter_stage_get_views_for_rect (ClutterStage *stage,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
float scale = 0.0f;
|
||||
GList *views_for_rect = NULL;
|
||||
GList *l;
|
||||
|
||||
for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next)
|
||||
@ -4445,12 +4415,8 @@ _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
|
||||
_clutter_util_rect_from_rectangle (&view_layout, &view_rect);
|
||||
|
||||
if (graphene_rect_intersection (&view_rect, rect, NULL))
|
||||
scale = MAX (clutter_stage_view_get_scale (view), scale);
|
||||
views_for_rect = g_list_prepend (views_for_rect, view);
|
||||
}
|
||||
|
||||
if (scale == 0.0)
|
||||
return FALSE;
|
||||
|
||||
*view_scale = scale;
|
||||
return TRUE;
|
||||
return views_for_rect;
|
||||
}
|
||||
|
@ -195,8 +195,6 @@ guchar * clutter_stage_read_pixels (ClutterStage
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_ensure_viewport (ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_ensure_redraw (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_stage_is_redraw_queued (ClutterStage *stage);
|
||||
|
@ -172,7 +172,6 @@ enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_LOOP,
|
||||
PROP_DELAY,
|
||||
PROP_DURATION,
|
||||
PROP_DIRECTION,
|
||||
@ -290,23 +289,6 @@ clutter_timeline_add_marker_internal (ClutterTimeline *timeline,
|
||||
g_hash_table_insert (priv->markers_by_name, marker->name, marker);
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_timeline_set_loop_internal (ClutterTimeline *timeline,
|
||||
gboolean loop)
|
||||
{
|
||||
gint old_repeat_count;
|
||||
|
||||
old_repeat_count = timeline->priv->repeat_count;
|
||||
|
||||
if (loop)
|
||||
clutter_timeline_set_repeat_count (timeline, -1);
|
||||
else
|
||||
clutter_timeline_set_repeat_count (timeline, 0);
|
||||
|
||||
if (old_repeat_count != timeline->priv->repeat_count)
|
||||
g_object_notify_by_pspec (G_OBJECT (timeline), obj_props[PROP_LOOP]);
|
||||
}
|
||||
|
||||
/* Scriptable */
|
||||
typedef struct _ParseClosure {
|
||||
ClutterTimeline *timeline;
|
||||
@ -448,10 +430,6 @@ clutter_timeline_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LOOP:
|
||||
clutter_timeline_set_loop_internal (timeline, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_DELAY:
|
||||
clutter_timeline_set_delay (timeline, g_value_get_uint (value));
|
||||
break;
|
||||
@ -493,10 +471,6 @@ clutter_timeline_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LOOP:
|
||||
g_value_set_boolean (value, priv->repeat_count != 0);
|
||||
break;
|
||||
|
||||
case PROP_DELAY:
|
||||
g_value_set_uint (value, priv->delay);
|
||||
break;
|
||||
@ -572,25 +546,6 @@ clutter_timeline_class_init (ClutterTimelineClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
/**
|
||||
* ClutterTimeline:loop:
|
||||
*
|
||||
* Whether the timeline should automatically rewind and restart.
|
||||
*
|
||||
* As a side effect, setting this property to %TRUE will set the
|
||||
* #ClutterTimeline:repeat-count property to -1, while setting this
|
||||
* property to %FALSE will set the #ClutterTimeline:repeat-count
|
||||
* property to 0.
|
||||
*
|
||||
* Deprecated: 1.10: Use the #ClutterTimeline:repeat-count property instead.
|
||||
*/
|
||||
obj_props[PROP_LOOP] =
|
||||
g_param_spec_boolean ("loop",
|
||||
P_("Loop"),
|
||||
P_("Should the timeline automatically restart"),
|
||||
FALSE,
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED);
|
||||
|
||||
/**
|
||||
* ClutterTimeline:delay:
|
||||
*
|
||||
@ -1251,45 +1206,6 @@ clutter_timeline_stop (ClutterTimeline *timeline)
|
||||
g_signal_emit (timeline, timeline_signals[STOPPED], 0, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_set_loop:
|
||||
* @timeline: a #ClutterTimeline
|
||||
* @loop: %TRUE for enable looping
|
||||
*
|
||||
* Sets whether @timeline should loop.
|
||||
*
|
||||
* This function is equivalent to calling clutter_timeline_set_repeat_count()
|
||||
* with -1 if @loop is %TRUE, and with 0 if @loop is %FALSE.
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_timeline_set_repeat_count() instead.
|
||||
*/
|
||||
void
|
||||
clutter_timeline_set_loop (ClutterTimeline *timeline,
|
||||
gboolean loop)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
|
||||
|
||||
clutter_timeline_set_loop_internal (timeline, loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_get_loop:
|
||||
* @timeline: a #ClutterTimeline
|
||||
*
|
||||
* Gets whether @timeline is looping
|
||||
*
|
||||
* Return value: %TRUE if the timeline is looping
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_timeline_get_repeat_count() instead.
|
||||
*/
|
||||
gboolean
|
||||
clutter_timeline_get_loop (ClutterTimeline *timeline)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE);
|
||||
|
||||
return timeline->priv->repeat_count != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_rewind:
|
||||
* @timeline: A #ClutterTimeline
|
||||
@ -1405,49 +1321,11 @@ clutter_timeline_is_playing (ClutterTimeline *timeline)
|
||||
return timeline->priv->is_playing;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_clone:
|
||||
* @timeline: #ClutterTimeline to duplicate.
|
||||
*
|
||||
* Create a new #ClutterTimeline instance which has property values
|
||||
* matching that of supplied timeline. The cloned timeline will not
|
||||
* be started and will not be positioned to the current position of
|
||||
* the original @timeline: you will have to start it with
|
||||
* clutter_timeline_start().
|
||||
*
|
||||
* The only cloned properties are:
|
||||
*
|
||||
* - #ClutterTimeline:duration
|
||||
* - #ClutterTimeline:loop
|
||||
* - #ClutterTimeline:delay
|
||||
* - #ClutterTimeline:direction
|
||||
*
|
||||
* Return value: (transfer full): a new #ClutterTimeline, cloned
|
||||
* from @timeline
|
||||
*
|
||||
* Since: 0.4
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_timeline_new() or g_object_new()
|
||||
* instead
|
||||
*/
|
||||
ClutterTimeline *
|
||||
clutter_timeline_clone (ClutterTimeline *timeline)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL);
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_TIMELINE,
|
||||
"duration", timeline->priv->duration,
|
||||
"loop", timeline->priv->repeat_count != 0,
|
||||
"delay", timeline->priv->delay,
|
||||
"direction", timeline->priv->direction,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_timeline_new:
|
||||
* @msecs: Duration of the timeline in milliseconds
|
||||
* @duration_ms: Duration of the timeline in milliseconds
|
||||
*
|
||||
* Creates a new #ClutterTimeline with a duration of @msecs.
|
||||
* Creates a new #ClutterTimeline with a duration of @duration_ms milli seconds.
|
||||
*
|
||||
* Return value: the newly created #ClutterTimeline instance. Use
|
||||
* g_object_unref() when done using it
|
||||
@ -1455,10 +1333,10 @@ clutter_timeline_clone (ClutterTimeline *timeline)
|
||||
* Since: 0.6
|
||||
*/
|
||||
ClutterTimeline *
|
||||
clutter_timeline_new (guint msecs)
|
||||
clutter_timeline_new (guint duration_ms)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_TIMELINE,
|
||||
"duration", msecs,
|
||||
"duration", duration_ms,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ CLUTTER_EXPORT
|
||||
GType clutter_timeline_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterTimeline * clutter_timeline_new (guint msecs);
|
||||
ClutterTimeline * clutter_timeline_new (guint duration_ms);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_timeline_get_duration (ClutterTimeline *timeline);
|
||||
|
@ -26,16 +26,6 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_new)
|
||||
ClutterTimeline * clutter_timeline_clone (ClutterTimeline *timeline);
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_set_repeat_count)
|
||||
void clutter_timeline_set_loop (ClutterTimeline *timeline,
|
||||
gboolean loop);
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_get_repeat_count)
|
||||
gboolean clutter_timeline_get_loop (ClutterTimeline *timeline);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_TIMELINE_PRIVATE_H__ */
|
||||
|
@ -43,8 +43,6 @@ struct _CoglFrameInfo
|
||||
float refresh_rate;
|
||||
|
||||
int64_t global_frame_counter;
|
||||
|
||||
CoglOutput *output;
|
||||
};
|
||||
|
||||
CoglFrameInfo *_cogl_frame_info_new (void);
|
||||
|
@ -72,12 +72,6 @@ cogl_frame_info_get_refresh_rate (CoglFrameInfo *info)
|
||||
return info->refresh_rate;
|
||||
}
|
||||
|
||||
CoglOutput *
|
||||
cogl_frame_info_get_output (CoglFrameInfo *info)
|
||||
{
|
||||
return info->output;
|
||||
}
|
||||
|
||||
int64_t
|
||||
cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info)
|
||||
{
|
||||
|
@ -126,20 +126,6 @@ int64_t cogl_frame_info_get_presentation_time (CoglFrameInfo *info);
|
||||
COGL_EXPORT
|
||||
float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info);
|
||||
|
||||
/**
|
||||
* cogl_frame_info_get_output:
|
||||
* @info: a #CoglFrameInfo object
|
||||
*
|
||||
* Gets the #CoglOutput that the swapped frame was presented to.
|
||||
*
|
||||
* Return value: (transfer none): The #CoglOutput that the frame was
|
||||
* presented to, or %NULL if this could not be determined.
|
||||
* Since: 1.14
|
||||
* Stability: unstable
|
||||
*/
|
||||
COGL_EXPORT CoglOutput *
|
||||
cogl_frame_info_get_output (CoglFrameInfo *info);
|
||||
|
||||
/**
|
||||
* cogl_frame_info_get_global_frame_counter: (skip)
|
||||
*/
|
||||
|
@ -1662,8 +1662,6 @@ set_frame_info_output (CoglOnscreen *onscreen,
|
||||
{
|
||||
CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
||||
|
||||
info->output = output;
|
||||
|
||||
if (output)
|
||||
{
|
||||
float refresh_rate = cogl_output_get_refresh_rate (output);
|
||||
|
@ -77,7 +77,7 @@ is_boolean_env_set (const char *variable)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
gboolean
|
||||
test_utils_init (TestFlags requirement_flags,
|
||||
TestFlags known_failure_flags)
|
||||
{
|
||||
@ -156,6 +156,8 @@ test_utils_init (TestFlags requirement_flags,
|
||||
g_print ("WARNING: Missing required feature[s] for this test\n");
|
||||
else if (known_failure)
|
||||
g_print ("WARNING: Test is known to fail\n");
|
||||
|
||||
return (!missing_requirement && !known_failure);
|
||||
}
|
||||
|
||||
void
|
||||
@ -250,7 +252,17 @@ void
|
||||
test_utils_check_pixel_rgb (CoglFramebuffer *test_fb,
|
||||
int x, int y, int r, int g, int b)
|
||||
{
|
||||
test_utils_check_pixel (test_fb, x, y, (r << 24) | (g << 16) | (b << 8));
|
||||
g_return_if_fail (r >= 0);
|
||||
g_return_if_fail (g >= 0);
|
||||
g_return_if_fail (b >= 0);
|
||||
g_return_if_fail (r <= 0xFF);
|
||||
g_return_if_fail (g <= 0xFF);
|
||||
g_return_if_fail (b <= 0xFF);
|
||||
|
||||
test_utils_check_pixel (test_fb, x, y,
|
||||
(((guint32) r) << 24) |
|
||||
(((guint32) g) << 16) |
|
||||
(((guint32) b) << 8));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -68,7 +68,7 @@ typedef enum
|
||||
extern CoglContext *test_ctx;
|
||||
extern CoglFramebuffer *test_fb;
|
||||
|
||||
void
|
||||
gboolean
|
||||
test_utils_init (TestFlags requirement_flags,
|
||||
TestFlags known_failure_flags);
|
||||
|
||||
|
@ -99,9 +99,9 @@ verify_texture (CoglTexture *texture, int size)
|
||||
};
|
||||
|
||||
test_utils_compare_pixel (p,
|
||||
(real_color.red << 24) |
|
||||
(real_color.green << 16) |
|
||||
(real_color.blue << 8) |
|
||||
(((guint32) real_color.red) << 24) |
|
||||
(((guint32) real_color.green) << 16) |
|
||||
(((guint32) real_color.blue) << 8) |
|
||||
opacity);
|
||||
g_assert_cmpint (p[3], ==, opacity);
|
||||
|
||||
|
@ -15,10 +15,17 @@
|
||||
G_STMT_START { \
|
||||
if (strcmp (#FUNC, argv[1]) == 0) \
|
||||
{ \
|
||||
test_utils_init (REQUIREMENTS, KNOWN_FAIL_REQUIREMENTS); \
|
||||
FUNC (); \
|
||||
test_utils_fini (); \
|
||||
exit (0); \
|
||||
if (test_utils_init (REQUIREMENTS, KNOWN_FAIL_REQUIREMENTS) \
|
||||
|| g_getenv ("COGL_TEST_TRY_EVERYTHING") != NULL) \
|
||||
{ \
|
||||
FUNC (); \
|
||||
test_utils_fini (); \
|
||||
exit (0); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
exit (1); \
|
||||
} \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
@ -55,7 +62,7 @@ main (int argc, char **argv)
|
||||
ADD_TEST (test_pipeline_user_matrix, 0, 0);
|
||||
ADD_TEST (test_blend_strings, 0, 0);
|
||||
ADD_TEST (test_blend, 0, 0);
|
||||
ADD_TEST (test_premult, 0, TEST_KNOWN_FAILURE);
|
||||
ADD_TEST (test_premult, 0, 0);
|
||||
UNPORTED_TEST (test_readpixels);
|
||||
ADD_TEST (test_depth_test, 0, 0);
|
||||
ADD_TEST (test_backface_culling, 0, TEST_REQUIREMENT_NPOT);
|
||||
|
@ -50,6 +50,7 @@ make_texture (uint32_t color,
|
||||
CoglPixelFormat src_format,
|
||||
MakeTextureFlags flags)
|
||||
{
|
||||
static CoglUserDataKey bitmap_free_key;
|
||||
CoglTexture2D *tex_2d;
|
||||
guchar *tex_data = gen_tex_data (color);
|
||||
CoglBitmap *bmp = cogl_bitmap_new_for_data (test_ctx,
|
||||
@ -58,6 +59,10 @@ make_texture (uint32_t color,
|
||||
src_format,
|
||||
QUAD_WIDTH * 4,
|
||||
tex_data);
|
||||
cogl_object_set_user_data (COGL_OBJECT (bmp),
|
||||
&bitmap_free_key,
|
||||
tex_data,
|
||||
g_free);
|
||||
|
||||
tex_2d = cogl_texture_2d_new_from_bitmap (bmp);
|
||||
|
||||
@ -67,7 +72,6 @@ make_texture (uint32_t color,
|
||||
cogl_texture_set_premultiplied (tex_2d, FALSE);
|
||||
|
||||
cogl_object_unref (bmp);
|
||||
g_free (tex_data);
|
||||
|
||||
return tex_2d;
|
||||
}
|
||||
|
@ -36,10 +36,16 @@ main (int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_utils_init (unit_test->requirement_flags,
|
||||
unit_test->known_failure_flags);
|
||||
unit_test->run ();
|
||||
test_utils_fini ();
|
||||
|
||||
return 0;
|
||||
if (test_utils_init (unit_test->requirement_flags,
|
||||
unit_test->known_failure_flags)
|
||||
|| g_getenv ("COGL_TEST_TRY_EVERYTHING") != NULL)
|
||||
{
|
||||
unit_test->run ();
|
||||
test_utils_fini ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
project('mutter', 'c',
|
||||
version: '3.37.1',
|
||||
version: '3.37.2',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ option('opengl_libname',
|
||||
|
||||
option('gles2_libname',
|
||||
type: 'string',
|
||||
value: 'libGLESv2.so',
|
||||
value: 'libGLESv2.so.2',
|
||||
description: 'GLESv2 library file name'
|
||||
)
|
||||
|
||||
|
@ -156,10 +156,6 @@ xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend);
|
||||
|
||||
gboolean meta_backend_is_lid_closed (MetaBackend *backend);
|
||||
|
||||
void meta_backend_freeze_updates (MetaBackend *backend);
|
||||
|
||||
void meta_backend_thaw_updates (MetaBackend *backend);
|
||||
|
||||
void meta_backend_update_last_device (MetaBackend *backend,
|
||||
ClutterInputDevice *device);
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
#ifndef META_BACKEND_TYPE_H
|
||||
#define META_BACKEND_TYPE_H
|
||||
|
||||
typedef struct _MetaBackend MetaBackend;
|
||||
|
||||
typedef struct _MetaMonitorManager MetaMonitorManager;
|
||||
|
||||
typedef struct _MetaMonitorConfigManager MetaMonitorConfigManager;
|
||||
|
@ -575,12 +575,6 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
}
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
meta_backend_real_create_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
return meta_cursor_renderer_new ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_backend_real_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@ -762,7 +756,6 @@ meta_backend_class_init (MetaBackendClass *klass)
|
||||
object_class->constructed = meta_backend_constructed;
|
||||
|
||||
klass->post_init = meta_backend_real_post_init;
|
||||
klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer;
|
||||
klass->grab_device = meta_backend_real_grab_device;
|
||||
klass->ungrab_device = meta_backend_real_ungrab_device;
|
||||
klass->select_stage_events = meta_backend_real_select_stage_events;
|
||||
@ -1275,24 +1268,6 @@ meta_backend_get_stage (MetaBackend *backend)
|
||||
return priv->stage;
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_freeze_updates (MetaBackend *backend)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
|
||||
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
clutter_stage_freeze_updates (stage);
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_thaw_updates (MetaBackend *backend)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
|
||||
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
clutter_stage_thaw_updates (stage);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_last_device (MetaBackend *backend)
|
||||
{
|
||||
|
@ -38,8 +38,21 @@
|
||||
G_DEFINE_INTERFACE (MetaHwCursorInhibitor, meta_hw_cursor_inhibitor,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_BACKEND,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
struct _MetaCursorRendererPrivate
|
||||
{
|
||||
MetaBackend *backend;
|
||||
|
||||
float current_x;
|
||||
float current_y;
|
||||
|
||||
@ -89,8 +102,7 @@ align_cursor_position (MetaCursorRenderer *renderer,
|
||||
{
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (priv->backend);
|
||||
ClutterStageView *view;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
float view_scale;
|
||||
@ -115,8 +127,7 @@ queue_redraw (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (priv->backend);
|
||||
CoglTexture *texture;
|
||||
graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO;
|
||||
|
||||
@ -165,13 +176,54 @@ meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BACKEND:
|
||||
g_value_set_object (value, priv->backend);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BACKEND:
|
||||
priv->backend = g_value_get_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_finalize (GObject *object)
|
||||
{
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (priv->backend);
|
||||
|
||||
if (priv->stage_overlay)
|
||||
meta_stage_remove_cursor_overlay (META_STAGE (stage), priv->stage_overlay);
|
||||
@ -186,9 +238,21 @@ meta_cursor_renderer_class_init (MetaCursorRendererClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = meta_cursor_renderer_get_property;
|
||||
object_class->set_property = meta_cursor_renderer_set_property;
|
||||
object_class->finalize = meta_cursor_renderer_finalize;
|
||||
klass->update_cursor = meta_cursor_renderer_real_update_cursor;
|
||||
|
||||
obj_props[PROP_BACKEND] =
|
||||
g_param_spec_object ("backend",
|
||||
"backend",
|
||||
"MetaBackend",
|
||||
META_TYPE_BACKEND,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
|
||||
signals[CURSOR_PAINTED] = g_signal_new ("cursor-painted",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
@ -273,9 +337,11 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
|
||||
}
|
||||
|
||||
MetaCursorRenderer *
|
||||
meta_cursor_renderer_new (void)
|
||||
meta_cursor_renderer_new (MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER, NULL);
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -54,7 +54,7 @@ struct _MetaCursorRendererClass
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
};
|
||||
|
||||
MetaCursorRenderer * meta_cursor_renderer_new (void);
|
||||
MetaCursorRenderer * meta_cursor_renderer_new (MetaBackend *backend);
|
||||
|
||||
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
|
56
src/backends/meta-keymap-utils.c
Normal file
56
src/backends/meta-keymap-utils.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Utilities for use with libxkbcommon
|
||||
*
|
||||
* Copyright 2019 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/meta-keymap-utils.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <limits.h>
|
||||
|
||||
struct xkb_context *
|
||||
meta_create_xkb_context (void)
|
||||
{
|
||||
struct xkb_context *ctx;
|
||||
char xdg[PATH_MAX] = {0};
|
||||
const char *env;
|
||||
|
||||
/*
|
||||
* We can only append search paths in libxkbcommon, so we start with an
|
||||
* emtpy set, then add the XDG dir, then add the default search paths.
|
||||
*/
|
||||
ctx = xkb_context_new (XKB_CONTEXT_NO_DEFAULT_INCLUDES);
|
||||
|
||||
env = g_getenv ("XDG_CONFIG_HOME");
|
||||
if (env)
|
||||
{
|
||||
g_snprintf (xdg, sizeof xdg, "%s/xkb", env);
|
||||
}
|
||||
else if ((env = g_getenv ("HOME")))
|
||||
{
|
||||
g_snprintf (xdg, sizeof xdg, "%s/.config/xkb", env);
|
||||
}
|
||||
|
||||
if (env)
|
||||
xkb_context_include_path_append (ctx, xdg);
|
||||
xkb_context_include_path_append_default (ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
28
src/backends/meta-keymap-utils.h
Normal file
28
src/backends/meta-keymap-utils.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Utilities for use with libxkbcommon
|
||||
*
|
||||
* Copyright 2020 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_KEYMAP_UTILS_H
|
||||
#define META_KEYMAP_UTILS_H
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct xkb_context * meta_create_xkb_context (void);
|
||||
|
||||
#endif /* META_KEYMAP_UTILS_H */
|
@ -996,8 +996,8 @@ meta_screen_cast_stream_src_finalize (GObject *object)
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
|
||||
g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
|
||||
g_clear_pointer (&priv->pipewire_stream, pw_stream_destroy);
|
||||
g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
|
||||
g_clear_pointer (&priv->pipewire_core, pw_core_disconnect);
|
||||
g_clear_pointer (&priv->pipewire_context, pw_context_destroy);
|
||||
g_source_destroy (&priv->pipewire_source->base);
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include "backends/meta-cursor-tracker-private.h"
|
||||
#include "backends/meta-idle-monitor-private.h"
|
||||
#include "backends/meta-keymap-utils.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
#include "backends/meta-pointer-constraint.h"
|
||||
@ -340,7 +341,7 @@ meta_backend_native_create_clutter_backend (MetaBackend *backend)
|
||||
static void
|
||||
meta_backend_native_post_init (MetaBackend *backend)
|
||||
{
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
MetaSettings *settings = meta_backend_get_settings (backend);
|
||||
|
||||
@ -425,6 +426,7 @@ meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
struct xkb_rule_names names;
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_context *context;
|
||||
@ -436,11 +438,11 @@ meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
names.variant = variants;
|
||||
names.options = options;
|
||||
|
||||
context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
context = meta_create_xkb_context ();
|
||||
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_context_unref (context);
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat), keymap);
|
||||
|
||||
meta_backend_notify_keymap_changed (backend);
|
||||
@ -451,18 +453,20 @@ meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
static struct xkb_keymap *
|
||||
meta_backend_native_get_keymap (MetaBackend *backend)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
return meta_seat_native_get_keyboard_map (META_SEAT_NATIVE (seat));
|
||||
}
|
||||
|
||||
static xkb_layout_index_t
|
||||
meta_backend_native_get_keymap_layout_group (MetaBackend *backend)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
return meta_seat_native_get_keyboard_layout_index (META_SEAT_NATIVE (seat));
|
||||
}
|
||||
|
||||
@ -470,6 +474,7 @@ static void
|
||||
meta_backend_native_lock_layout_group (MetaBackend *backend,
|
||||
guint idx)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
xkb_layout_index_t old_idx;
|
||||
ClutterSeat *seat;
|
||||
|
||||
@ -477,7 +482,7 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
|
||||
if (old_idx == idx)
|
||||
return;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
meta_seat_native_set_keyboard_layout_index (META_SEAT_NATIVE (seat), idx);
|
||||
meta_backend_notify_keymap_layout_group_changed (backend, idx);
|
||||
}
|
||||
@ -486,9 +491,10 @@ static void
|
||||
meta_backend_native_set_numlock (MetaBackend *backend,
|
||||
gboolean numlock_state)
|
||||
{
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
ClutterSeat *seat;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
seat = clutter_backend_get_default_seat (clutter_backend);
|
||||
meta_seat_native_set_keyboard_numlock (META_SEAT_NATIVE (seat),
|
||||
numlock_state);
|
||||
}
|
||||
@ -780,7 +786,7 @@ meta_backend_native_pause (MetaBackendNative *native)
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaMonitorManagerKms *monitor_manager_kms =
|
||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
MetaSeatNative *seat =
|
||||
META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
|
||||
|
||||
@ -805,7 +811,7 @@ void meta_backend_native_resume (MetaBackendNative *native)
|
||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||
MetaInputSettings *input_settings;
|
||||
MetaIdleMonitor *idle_monitor;
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
MetaSeatNative *seat =
|
||||
META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
|
||||
|
||||
|
@ -1719,8 +1719,9 @@ meta_cursor_renderer_native_new (MetaBackend *backend)
|
||||
MetaCursorRendererNative *cursor_renderer_native;
|
||||
MetaCursorRendererNativePrivate *priv;
|
||||
|
||||
cursor_renderer_native =
|
||||
g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE, NULL);
|
||||
cursor_renderer_native = g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
priv =
|
||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/meta-keymap-utils.h"
|
||||
#include "backends/native/meta-keymap-native.h"
|
||||
#include "backends/native/meta-seat-native.h"
|
||||
|
||||
@ -111,7 +112,7 @@ meta_keymap_native_init (MetaKeymapNative *keymap)
|
||||
names.variant = option_xkb_variant;
|
||||
names.options = option_xkb_options;
|
||||
|
||||
ctx = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
ctx = meta_create_xkb_context ();
|
||||
g_assert (ctx);
|
||||
keymap->keymap = xkb_keymap_new_from_names (ctx, &names, 0);
|
||||
xkb_context_unref (ctx);
|
||||
|
@ -2168,6 +2168,7 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
{
|
||||
CoglFramebuffer *dmabuf_fb;
|
||||
CoglDmaBufHandle *dmabuf_handle;
|
||||
struct gbm_bo *new_bo;
|
||||
int stride;
|
||||
int offset;
|
||||
@ -2210,10 +2211,13 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
||||
if (!dmabuf_fb)
|
||||
return NULL;
|
||||
|
||||
return cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd,
|
||||
width, height, stride, offset, bpp,
|
||||
new_bo,
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
dmabuf_handle =
|
||||
cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd,
|
||||
width, height, stride, offset, bpp,
|
||||
new_bo,
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
cogl_object_unref (dmabuf_fb);
|
||||
return dmabuf_handle;
|
||||
}
|
||||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
|
@ -1380,35 +1380,6 @@ has_touchscreen (MetaSeatNative *seat)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_external_keyboard (MetaSeatNative *seat)
|
||||
{
|
||||
GList *devices, *l;
|
||||
gboolean has_external = FALSE;
|
||||
|
||||
devices = g_udev_client_query_by_subsystem (seat->udev_client, "input");
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
if (!g_udev_device_has_property (l->data, "ID_INPUT_KEYBOARD"))
|
||||
continue;
|
||||
|
||||
/* May be "hid" or something else, we don't care. This property
|
||||
* will not be present in virtual "AT Translated Set 2 keyboard"
|
||||
* devices.
|
||||
*/
|
||||
if (!g_udev_device_has_property (l->data, "ID_TYPE"))
|
||||
break;
|
||||
|
||||
has_external = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
g_list_free_full (devices, g_object_unref);
|
||||
|
||||
return has_external;
|
||||
}
|
||||
|
||||
static void
|
||||
update_touch_mode (MetaSeatNative *seat)
|
||||
{
|
||||
@ -1421,10 +1392,10 @@ update_touch_mode (MetaSeatNative *seat)
|
||||
else if (seat->has_tablet_switch && !seat->tablet_mode_switch_state)
|
||||
touch_mode = FALSE;
|
||||
/* If tablet mode is enabled, or if there is no tablet mode switch
|
||||
* (eg. kiosk machines), check availability of external keyboards.
|
||||
* (eg. kiosk machines), assume touch-mode.
|
||||
*/
|
||||
else
|
||||
touch_mode = !seat->has_external_keyboard;
|
||||
touch_mode = TRUE;
|
||||
|
||||
if (seat->touch_mode != touch_mode)
|
||||
{
|
||||
@ -1465,12 +1436,7 @@ evdev_add_device (MetaSeatNative *seat,
|
||||
|
||||
g_signal_emit_by_name (seat, "device-added", device);
|
||||
|
||||
if (type == CLUTTER_KEYBOARD_DEVICE)
|
||||
{
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
check_touch_mode = TRUE;
|
||||
}
|
||||
else if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
{
|
||||
seat->has_touchscreen = TRUE;
|
||||
check_touch_mode = TRUE;
|
||||
@ -1503,12 +1469,7 @@ evdev_remove_device (MetaSeatNative *seat,
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (device_type == CLUTTER_KEYBOARD_DEVICE)
|
||||
{
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
update_touch_mode (seat);
|
||||
}
|
||||
else if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
{
|
||||
seat->has_touchscreen = has_touchscreen (seat);
|
||||
update_touch_mode (seat);
|
||||
@ -2553,7 +2514,6 @@ meta_seat_native_constructed (GObject *object)
|
||||
xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL);
|
||||
}
|
||||
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
seat->has_touchscreen = has_touchscreen (seat);
|
||||
update_touch_mode (seat);
|
||||
|
||||
|
@ -120,7 +120,6 @@ struct _MetaSeatNative
|
||||
|
||||
GUdevClient *udev_client;
|
||||
guint tablet_mode_switch_state : 1;
|
||||
guint has_external_keyboard : 1;
|
||||
guint has_touchscreen : 1;
|
||||
guint has_tablet_switch : 1;
|
||||
guint touch_mode : 1;
|
||||
|
@ -140,7 +140,7 @@ meta_stage_native_rebuild_views (MetaStageNative *stage_native)
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
|
||||
meta_renderer_rebuild_views (renderer);
|
||||
clutter_stage_update_resource_scales (CLUTTER_STAGE (stage));
|
||||
clutter_stage_clear_stage_views (CLUTTER_STAGE (stage));
|
||||
ensure_frame_callbacks (stage_native);
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,9 @@ meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend,
|
||||
static MetaCursorRenderer *
|
||||
meta_backend_x11_cm_create_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static MetaInputSettings *
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
|
||||
#include "backends/meta-idle-monitor-private.h"
|
||||
#include "backends/meta-keymap-utils.h"
|
||||
#include "backends/meta-stage-private.h"
|
||||
#include "backends/x11/meta-clutter-backend-x11.h"
|
||||
#include "backends/x11/meta-event-x11.h"
|
||||
@ -704,7 +705,7 @@ meta_backend_x11_get_keymap (MetaBackend *backend)
|
||||
|
||||
if (priv->keymap == NULL)
|
||||
{
|
||||
struct xkb_context *context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
struct xkb_context *context = meta_create_xkb_context ();
|
||||
priv->keymap = xkb_x11_keymap_new_from_device (context,
|
||||
priv->xcb,
|
||||
xkb_x11_get_core_keyboard_device_id (priv->xcb),
|
||||
|
@ -38,7 +38,10 @@ enum
|
||||
PROP_OPCODE,
|
||||
PROP_POINTER_ID,
|
||||
PROP_KEYBOARD_ID,
|
||||
N_PROPS
|
||||
N_PROPS,
|
||||
|
||||
/* This property is overridden */
|
||||
PROP_TOUCH_MODE,
|
||||
};
|
||||
|
||||
struct _MetaSeatX11
|
||||
@ -54,6 +57,8 @@ struct _MetaSeatX11
|
||||
int pointer_id;
|
||||
int keyboard_id;
|
||||
int opcode;
|
||||
guint has_touchscreens : 1;
|
||||
guint touch_mode : 1;
|
||||
};
|
||||
|
||||
static GParamSpec *props[N_PROPS] = { 0 };
|
||||
@ -605,6 +610,20 @@ pad_passive_button_grab (ClutterInputDevice *device)
|
||||
g_free (xi_event_mask.mask);
|
||||
}
|
||||
|
||||
static void
|
||||
update_touch_mode (MetaSeatX11 *seat_x11)
|
||||
{
|
||||
gboolean touch_mode;
|
||||
|
||||
touch_mode = seat_x11->has_touchscreens;
|
||||
|
||||
if (seat_x11->touch_mode == touch_mode)
|
||||
return;
|
||||
|
||||
seat_x11->touch_mode = touch_mode;
|
||||
g_object_notify (G_OBJECT (seat_x11), "touch-mode");
|
||||
}
|
||||
|
||||
static ClutterInputDevice *
|
||||
add_device (MetaSeatX11 *seat_x11,
|
||||
ClutterBackend *backend,
|
||||
@ -635,6 +654,8 @@ add_device (MetaSeatX11 *seat_x11,
|
||||
info->attachment == seat_x11->keyboard_id))
|
||||
{
|
||||
seat_x11->devices = g_list_prepend (seat_x11->devices, device);
|
||||
seat_x11->has_touchscreens |=
|
||||
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -663,18 +684,38 @@ add_device (MetaSeatX11 *seat_x11,
|
||||
}
|
||||
}
|
||||
|
||||
update_touch_mode (seat_x11);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_touchscreens (MetaSeatX11 *seat_x11)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = seat_x11->devices; l; l = l->next)
|
||||
{
|
||||
if (clutter_input_device_get_device_type (l->data) == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_device (MetaSeatX11 *seat_x11,
|
||||
int device_id)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
gboolean check_touchscreens = FALSE;
|
||||
|
||||
device = g_hash_table_lookup (seat_x11->devices_by_id,
|
||||
GINT_TO_POINTER (device_id));
|
||||
|
||||
if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
check_touchscreens = TRUE;
|
||||
|
||||
if (device != NULL)
|
||||
{
|
||||
if (seat_x11->core_pointer == device)
|
||||
@ -695,6 +736,12 @@ remove_device (MetaSeatX11 *seat_x11,
|
||||
g_hash_table_remove (seat_x11->devices_by_id,
|
||||
GINT_TO_POINTER (device_id));
|
||||
}
|
||||
|
||||
if (check_touchscreens)
|
||||
{
|
||||
seat_x11->has_touchscreens = has_touchscreens (seat_x11);
|
||||
update_touch_mode (seat_x11);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1272,6 +1319,7 @@ meta_seat_x11_set_property (GObject *object,
|
||||
case PROP_KEYBOARD_ID:
|
||||
seat_x11->keyboard_id = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_TOUCH_MODE:
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -1296,6 +1344,9 @@ meta_seat_x11_get_property (GObject *object,
|
||||
case PROP_KEYBOARD_ID:
|
||||
g_value_set_int (value, seat_x11->keyboard_id);
|
||||
break;
|
||||
case PROP_TOUCH_MODE:
|
||||
g_value_set_boolean (value, seat_x11->touch_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -1547,6 +1598,9 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass)
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||
|
||||
g_object_class_override_property (object_class, PROP_TOUCH_MODE,
|
||||
"touch-mode");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -65,7 +65,9 @@ meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend,
|
||||
static MetaCursorRenderer *
|
||||
meta_backend_x11_nested_create_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL);
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static MetaInputSettings *
|
||||
@ -85,7 +87,7 @@ meta_backend_x11_nested_update_screen_size (MetaBackend *backend,
|
||||
if (meta_is_stage_views_enabled ())
|
||||
{
|
||||
meta_renderer_rebuild_views (renderer);
|
||||
clutter_stage_update_resource_scales (CLUTTER_STAGE (stage));
|
||||
clutter_stage_clear_stage_views (CLUTTER_STAGE (stage));
|
||||
}
|
||||
clutter_actor_set_size (stage, width, height);
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ enum
|
||||
PROP_0,
|
||||
|
||||
PROP_DISPLAY,
|
||||
PROP_BACKEND,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
@ -111,6 +112,7 @@ typedef struct _MetaCompositorPrivate
|
||||
GObject parent;
|
||||
|
||||
MetaDisplay *display;
|
||||
MetaBackend *backend;
|
||||
|
||||
guint pre_paint_func_id;
|
||||
guint post_paint_func_id;
|
||||
@ -231,7 +233,7 @@ meta_get_stage_for_display (MetaDisplay *display)
|
||||
g_return_val_if_fail (compositor, NULL);
|
||||
priv = meta_compositor_get_instance_private (compositor);
|
||||
|
||||
return priv->stage;
|
||||
return meta_backend_get_stage (priv->backend);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -564,12 +566,11 @@ meta_compositor_do_manage (MetaCompositor *compositor,
|
||||
MetaCompositorPrivate *priv =
|
||||
meta_compositor_get_instance_private (compositor);
|
||||
MetaDisplay *display = priv->display;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
priv->stage = meta_backend_get_stage (backend);
|
||||
MetaBackend *backend = priv->backend;
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
|
||||
priv->stage_presented_id =
|
||||
g_signal_connect (priv->stage, "presented",
|
||||
g_signal_connect (stage, "presented",
|
||||
G_CALLBACK (on_presented),
|
||||
compositor);
|
||||
|
||||
@ -582,18 +583,18 @@ meta_compositor_do_manage (MetaCompositor *compositor,
|
||||
* matter.
|
||||
*/
|
||||
priv->stage_after_paint_id =
|
||||
g_signal_connect_after (priv->stage, "after-paint",
|
||||
g_signal_connect_after (stage, "after-paint",
|
||||
G_CALLBACK (after_stage_paint), compositor);
|
||||
|
||||
clutter_stage_set_sync_delay (CLUTTER_STAGE (priv->stage), META_SYNC_DELAY);
|
||||
clutter_stage_set_sync_delay (CLUTTER_STAGE (stage), META_SYNC_DELAY);
|
||||
|
||||
priv->window_group = meta_window_group_new (display);
|
||||
priv->top_window_group = meta_window_group_new (display);
|
||||
priv->feedback_group = meta_window_group_new (display);
|
||||
|
||||
clutter_actor_add_child (priv->stage, priv->window_group);
|
||||
clutter_actor_add_child (priv->stage, priv->top_window_group);
|
||||
clutter_actor_add_child (priv->stage, priv->feedback_group);
|
||||
clutter_actor_add_child (stage, priv->window_group);
|
||||
clutter_actor_add_child (stage, priv->top_window_group);
|
||||
clutter_actor_add_child (stage, priv->feedback_group);
|
||||
|
||||
if (!META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor, error))
|
||||
return FALSE;
|
||||
@ -1162,7 +1163,7 @@ meta_compositor_real_post_paint (MetaCompositor *compositor)
|
||||
|
||||
case COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET:
|
||||
g_signal_emit_by_name (priv->display, "gl-video-memory-purged");
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->stage));
|
||||
clutter_actor_queue_redraw (meta_backend_get_stage (priv->backend));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1211,6 +1212,9 @@ meta_compositor_set_property (GObject *object,
|
||||
case PROP_DISPLAY:
|
||||
priv->display = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_BACKEND:
|
||||
priv->backend = g_value_get_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -1231,6 +1235,9 @@ meta_compositor_get_property (GObject *object,
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, priv->display);
|
||||
break;
|
||||
case PROP_BACKEND:
|
||||
g_value_set_object (value, priv->backend);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -1266,11 +1273,12 @@ meta_compositor_dispose (GObject *object)
|
||||
MetaCompositor *compositor = META_COMPOSITOR (object);
|
||||
MetaCompositorPrivate *priv =
|
||||
meta_compositor_get_instance_private (compositor);
|
||||
ClutterActor *stage = meta_backend_get_stage (priv->backend);
|
||||
|
||||
g_clear_pointer (&priv->laters, meta_laters_free);
|
||||
|
||||
g_clear_signal_handler (&priv->stage_after_paint_id, priv->stage);
|
||||
g_clear_signal_handler (&priv->stage_presented_id, priv->stage);
|
||||
g_clear_signal_handler (&priv->stage_after_paint_id, stage);
|
||||
g_clear_signal_handler (&priv->stage_presented_id, stage);
|
||||
|
||||
g_clear_handle_id (&priv->pre_paint_func_id,
|
||||
clutter_threads_remove_repaint_func);
|
||||
@ -1309,6 +1317,14 @@ meta_compositor_class_init (MetaCompositorClass *klass)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_BACKEND] =
|
||||
g_param_spec_object ("backend",
|
||||
"backend",
|
||||
"MetaBackend",
|
||||
META_TYPE_BACKEND,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
|
||||
signals[PRE_PAINT] =
|
||||
@ -1615,7 +1631,7 @@ meta_compositor_get_stage (MetaCompositor *compositor)
|
||||
MetaCompositorPrivate *priv =
|
||||
meta_compositor_get_instance_private (compositor);
|
||||
|
||||
return CLUTTER_STAGE (priv->stage);
|
||||
return CLUTTER_STAGE (meta_backend_get_stage (priv->backend));
|
||||
}
|
||||
|
||||
MetaWindowActor *
|
||||
|
@ -19,142 +19,19 @@
|
||||
* Portions adapted from gnome-shell/src/shell-global.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:meta-background-actor
|
||||
* @title: MetaBackgroundActor
|
||||
* @short_description: Actor for painting the root window background
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The overall model drawing model of this widget is that we have one
|
||||
* texture, or two interpolated textures, possibly with alpha or
|
||||
* margins that let the underlying background show through, blended
|
||||
* over a solid color or a gradient. The result of that combination
|
||||
* can then be affected by a "vignette" that darkens the background
|
||||
* away from a central point (or as a no-GLSL fallback, simply darkens
|
||||
* the background) and by overall opacity.
|
||||
*
|
||||
* As of GNOME 3.14, GNOME is only using a fraction of this when the
|
||||
* user sets the background through the control center - what can be
|
||||
* set is:
|
||||
*
|
||||
* A single image without a border
|
||||
* An animation of images without a border that blend together,
|
||||
* with the blend changing every 4-5 minutes
|
||||
* A solid color with a repeated noise texture blended over it
|
||||
*
|
||||
* This all is pretty easy to do in a fragment shader, except when:
|
||||
*
|
||||
* A) We don't have GLSL - in this case, the operation of
|
||||
* interpolating the two textures and blending the result over the
|
||||
* background can't be expressed with Cogl's fixed-function layer
|
||||
* combining (which is confined to what GL's texture environment
|
||||
* combining can do) So we can only handle the above directly if
|
||||
* there are no margins or alpha.
|
||||
*
|
||||
* B) The image textures are sliced. Texture size limits on older
|
||||
* hardware (pre-965 intel hardware, r300, etc.) is often 2048,
|
||||
* and it would be common to use a texture larger than this for a
|
||||
* background and expect it to be scaled down. Cogl can compensate
|
||||
* for this by breaking the texture up into multiple textures, but
|
||||
* can't multitexture with sliced textures. So we can only handle
|
||||
* the above if there's a single texture.
|
||||
*
|
||||
* However, even when we *can* represent everything in a single pass,
|
||||
* it's not necessarily efficient. If we want to draw a 1024x768
|
||||
* background, it's pretty inefficient to bilinearly texture from
|
||||
* two 2560x1440 images and mix that. So the drawing model we take
|
||||
* here is that MetaBackground generates a single texture (which
|
||||
* might be a 1x1 texture for a solid color, or a 1x2 texture for a
|
||||
* gradient, or a repeated texture for wallpaper, or a pre-rendered
|
||||
* texture the size of the screen), and we draw with that, possibly
|
||||
* adding the vignette and opacity.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "compositor/meta-background-actor-private.h"
|
||||
#include "compositor/meta-background-content-private.h"
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "compositor/clutter-utils.h"
|
||||
#include "compositor/cogl-utils.h"
|
||||
#include "compositor/meta-background-private.h"
|
||||
#include "compositor/meta-cullable.h"
|
||||
#include "meta/display.h"
|
||||
#include "meta/meta-x11-errors.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_META_DISPLAY = 1,
|
||||
PROP_MONITOR,
|
||||
PROP_BACKGROUND,
|
||||
PROP_GRADIENT,
|
||||
PROP_GRADIENT_HEIGHT,
|
||||
PROP_GRADIENT_MAX_DARKNESS,
|
||||
PROP_VIGNETTE,
|
||||
PROP_VIGNETTE_SHARPNESS,
|
||||
PROP_VIGNETTE_BRIGHTNESS
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHANGED_BACKGROUND = 1 << 0,
|
||||
CHANGED_EFFECTS = 1 << 2,
|
||||
CHANGED_VIGNETTE_PARAMETERS = 1 << 3,
|
||||
CHANGED_GRADIENT_PARAMETERS = 1 << 4,
|
||||
CHANGED_ALL = 0xFFFF
|
||||
} ChangedFlags;
|
||||
|
||||
#define GRADIENT_VERTEX_SHADER_DECLARATIONS \
|
||||
"uniform vec2 scale;\n" \
|
||||
"varying vec2 position;\n" \
|
||||
|
||||
#define GRADIENT_VERTEX_SHADER_CODE \
|
||||
"position = cogl_tex_coord0_in.xy * scale;\n" \
|
||||
|
||||
#define GRADIENT_FRAGMENT_SHADER_DECLARATIONS \
|
||||
"uniform float gradient_height_perc;\n" \
|
||||
"uniform float gradient_max_darkness;\n" \
|
||||
"varying vec2 position;\n" \
|
||||
|
||||
#define GRADIENT_FRAGMENT_SHADER_CODE \
|
||||
"float min_brightness = 1.0 - gradient_max_darkness;\n" \
|
||||
"float gradient_y_pos = min(position.y, gradient_height_perc) / gradient_height_perc;\n" \
|
||||
"float pixel_brightness = (1.0 - min_brightness) * gradient_y_pos + min_brightness;\n" \
|
||||
"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \
|
||||
|
||||
#define VIGNETTE_VERTEX_SHADER_DECLARATIONS \
|
||||
"uniform vec2 scale;\n" \
|
||||
"uniform vec2 offset;\n" \
|
||||
"varying vec2 position;\n" \
|
||||
|
||||
#define VIGNETTE_VERTEX_SHADER_CODE \
|
||||
"position = cogl_tex_coord0_in.xy * scale + offset;\n" \
|
||||
|
||||
#define VIGNETTE_SQRT_2 "1.4142"
|
||||
|
||||
#define VIGNETTE_FRAGMENT_SHADER_DECLARATIONS \
|
||||
"uniform float vignette_sharpness;\n" \
|
||||
"varying vec2 position;\n" \
|
||||
"float rand(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453123); }\n" \
|
||||
|
||||
#define VIGNETTE_FRAGMENT_SHADER_CODE \
|
||||
"float t = " VIGNETTE_SQRT_2 " * length(position);\n" \
|
||||
"t = min(t, 1.0);\n" \
|
||||
"float pixel_brightness = 1.0 - t * vignette_sharpness;\n" \
|
||||
"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \
|
||||
"cogl_color_out.rgb += (rand(position) - 0.5) / 255.0;\n" \
|
||||
|
||||
typedef struct _MetaBackgroundLayer MetaBackgroundLayer;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIPELINE_VIGNETTE = (1 << 0),
|
||||
PIPELINE_BLEND = (1 << 1),
|
||||
PIPELINE_GRADIENT = (1 << 2),
|
||||
} PipelineFlags;
|
||||
|
||||
struct _MetaBackgroundActor
|
||||
{
|
||||
ClutterActor parent;
|
||||
@ -162,24 +39,7 @@ struct _MetaBackgroundActor
|
||||
MetaDisplay *display;
|
||||
int monitor;
|
||||
|
||||
MetaBackground *background;
|
||||
|
||||
gboolean gradient;
|
||||
double gradient_max_darkness;
|
||||
int gradient_height;
|
||||
|
||||
gboolean vignette;
|
||||
double vignette_brightness;
|
||||
double vignette_sharpness;
|
||||
|
||||
ChangedFlags changed;
|
||||
CoglPipeline *pipeline;
|
||||
PipelineFlags pipeline_flags;
|
||||
cairo_rectangle_int_t texture_area;
|
||||
gboolean force_bilinear;
|
||||
|
||||
cairo_region_t *clip_region;
|
||||
cairo_region_t *unobscured_region;
|
||||
MetaBackgroundContent *content;
|
||||
};
|
||||
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
@ -188,407 +48,16 @@ G_DEFINE_TYPE_WITH_CODE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYP
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
||||
|
||||
static void
|
||||
set_clip_region (MetaBackgroundActor *self,
|
||||
cairo_region_t *clip_region)
|
||||
maybe_create_content (MetaBackgroundActor *self)
|
||||
{
|
||||
g_clear_pointer (&self->clip_region, cairo_region_destroy);
|
||||
if (clip_region)
|
||||
{
|
||||
if (cairo_region_is_empty (clip_region))
|
||||
self->clip_region = cairo_region_reference (clip_region);
|
||||
else
|
||||
self->clip_region = cairo_region_copy (clip_region);
|
||||
}
|
||||
}
|
||||
g_autoptr (ClutterContent) content = NULL;
|
||||
|
||||
static void
|
||||
set_unobscured_region (MetaBackgroundActor *self,
|
||||
cairo_region_t *unobscured_region)
|
||||
{
|
||||
g_clear_pointer (&self->unobscured_region, cairo_region_destroy);
|
||||
if (unobscured_region)
|
||||
{
|
||||
if (cairo_region_is_empty (unobscured_region))
|
||||
self->unobscured_region = cairo_region_reference (unobscured_region);
|
||||
else
|
||||
self->unobscured_region = cairo_region_copy (unobscured_region);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_actor_dispose (GObject *object)
|
||||
{
|
||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
|
||||
|
||||
set_clip_region (self, NULL);
|
||||
set_unobscured_region (self, NULL);
|
||||
meta_background_actor_set_background (self, NULL);
|
||||
if (self->pipeline)
|
||||
{
|
||||
cogl_object_unref (self->pipeline);
|
||||
self->pipeline = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
get_preferred_size (MetaBackgroundActor *self,
|
||||
gfloat *width,
|
||||
gfloat *height)
|
||||
{
|
||||
MetaRectangle monitor_geometry;
|
||||
|
||||
meta_display_get_monitor_geometry (self->display,
|
||||
self->monitor,
|
||||
&monitor_geometry);
|
||||
|
||||
if (width != NULL)
|
||||
*width = monitor_geometry.width;
|
||||
|
||||
if (height != NULL)
|
||||
*height = monitor_geometry.height;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_actor_get_preferred_width (ClutterActor *actor,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
gfloat width;
|
||||
|
||||
get_preferred_size (META_BACKGROUND_ACTOR (actor), &width, NULL);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = width;
|
||||
if (natural_width_p)
|
||||
*natural_width_p = width;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_actor_get_preferred_height (ClutterActor *actor,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
|
||||
{
|
||||
gfloat height;
|
||||
|
||||
get_preferred_size (META_BACKGROUND_ACTOR (actor), NULL, &height);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = height;
|
||||
if (natural_height_p)
|
||||
*natural_height_p = height;
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
make_pipeline (PipelineFlags pipeline_flags)
|
||||
{
|
||||
static CoglPipeline *templates[8];
|
||||
CoglPipeline **templatep;
|
||||
|
||||
templatep = &templates[pipeline_flags];
|
||||
if (*templatep == NULL)
|
||||
{
|
||||
/* Cogl automatically caches pipelines with no eviction policy,
|
||||
* so we need to prevent identical pipelines from getting cached
|
||||
* separately, by reusing the same shader snippets.
|
||||
*/
|
||||
*templatep = COGL_PIPELINE (meta_create_texture_pipeline (NULL));
|
||||
|
||||
if ((pipeline_flags & PIPELINE_VIGNETTE) != 0)
|
||||
{
|
||||
static CoglSnippet *vignette_vertex_snippet;
|
||||
static CoglSnippet *vignette_fragment_snippet;
|
||||
|
||||
if (!vignette_vertex_snippet)
|
||||
vignette_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
|
||||
VIGNETTE_VERTEX_SHADER_DECLARATIONS,
|
||||
VIGNETTE_VERTEX_SHADER_CODE);
|
||||
|
||||
cogl_pipeline_add_snippet (*templatep, vignette_vertex_snippet);
|
||||
|
||||
if (!vignette_fragment_snippet)
|
||||
vignette_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
VIGNETTE_FRAGMENT_SHADER_DECLARATIONS,
|
||||
VIGNETTE_FRAGMENT_SHADER_CODE);
|
||||
|
||||
cogl_pipeline_add_snippet (*templatep, vignette_fragment_snippet);
|
||||
}
|
||||
|
||||
if ((pipeline_flags & PIPELINE_GRADIENT) != 0)
|
||||
{
|
||||
static CoglSnippet *gradient_vertex_snippet;
|
||||
static CoglSnippet *gradient_fragment_snippet;
|
||||
|
||||
if (!gradient_vertex_snippet)
|
||||
gradient_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
|
||||
GRADIENT_VERTEX_SHADER_DECLARATIONS,
|
||||
GRADIENT_VERTEX_SHADER_CODE);
|
||||
|
||||
cogl_pipeline_add_snippet (*templatep, gradient_vertex_snippet);
|
||||
|
||||
if (!gradient_fragment_snippet)
|
||||
gradient_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
GRADIENT_FRAGMENT_SHADER_DECLARATIONS,
|
||||
GRADIENT_FRAGMENT_SHADER_CODE);
|
||||
|
||||
cogl_pipeline_add_snippet (*templatep, gradient_fragment_snippet);
|
||||
}
|
||||
|
||||
if ((pipeline_flags & PIPELINE_BLEND) == 0)
|
||||
cogl_pipeline_set_blend (*templatep, "RGBA = ADD (SRC_COLOR, 0)", NULL);
|
||||
}
|
||||
|
||||
return cogl_pipeline_copy (*templatep);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_pipeline (MetaBackgroundActor *self,
|
||||
ClutterPaintContext *paint_context,
|
||||
cairo_rectangle_int_t *actor_pixel_rect)
|
||||
{
|
||||
PipelineFlags pipeline_flags = 0;
|
||||
guint8 opacity;
|
||||
float color_component;
|
||||
CoglFramebuffer *fb;
|
||||
CoglPipelineFilter filter;
|
||||
|
||||
opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self));
|
||||
if (opacity < 255)
|
||||
pipeline_flags |= PIPELINE_BLEND;
|
||||
if (self->vignette && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
pipeline_flags |= PIPELINE_VIGNETTE;
|
||||
if (self->gradient && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
pipeline_flags |= PIPELINE_GRADIENT;
|
||||
|
||||
if (self->pipeline &&
|
||||
pipeline_flags != self->pipeline_flags)
|
||||
{
|
||||
cogl_object_unref (self->pipeline);
|
||||
self->pipeline = NULL;
|
||||
}
|
||||
|
||||
if (self->pipeline == NULL)
|
||||
{
|
||||
self->pipeline_flags = pipeline_flags;
|
||||
self->pipeline = make_pipeline (pipeline_flags);
|
||||
self->changed = CHANGED_ALL;
|
||||
}
|
||||
|
||||
if ((self->changed & CHANGED_BACKGROUND) != 0)
|
||||
{
|
||||
CoglPipelineWrapMode wrap_mode;
|
||||
CoglTexture *texture = meta_background_get_texture (self->background,
|
||||
self->monitor,
|
||||
&self->texture_area,
|
||||
&wrap_mode);
|
||||
self->force_bilinear = texture &&
|
||||
(self->texture_area.width != (int)cogl_texture_get_width (texture) ||
|
||||
self->texture_area.height != (int)cogl_texture_get_height (texture));
|
||||
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
cogl_pipeline_set_layer_wrap_mode (self->pipeline, 0, wrap_mode);
|
||||
|
||||
self->changed &= ~CHANGED_BACKGROUND;
|
||||
}
|
||||
|
||||
if ((self->changed & CHANGED_VIGNETTE_PARAMETERS) != 0)
|
||||
{
|
||||
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"vignette_sharpness"),
|
||||
self->vignette_sharpness);
|
||||
|
||||
self->changed &= ~CHANGED_VIGNETTE_PARAMETERS;
|
||||
}
|
||||
|
||||
if ((self->changed & CHANGED_GRADIENT_PARAMETERS) != 0)
|
||||
{
|
||||
MetaRectangle monitor_geometry;
|
||||
float gradient_height_perc;
|
||||
|
||||
meta_display_get_monitor_geometry (self->display,
|
||||
self->monitor, &monitor_geometry);
|
||||
gradient_height_perc = MAX (0.0001, self->gradient_height / (float)monitor_geometry.height);
|
||||
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"gradient_height_perc"),
|
||||
gradient_height_perc);
|
||||
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"gradient_max_darkness"),
|
||||
self->gradient_max_darkness);
|
||||
|
||||
self->changed &= ~CHANGED_GRADIENT_PARAMETERS;
|
||||
}
|
||||
|
||||
if (self->vignette)
|
||||
{
|
||||
color_component = self->vignette_brightness * opacity / 255.;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
{
|
||||
/* Darken everything to match the average brightness that would
|
||||
* be there if we were drawing the vignette, which is
|
||||
* (1 - (pi/12.) * vignette_sharpness) [exercise for the reader :]
|
||||
*/
|
||||
color_component *= (1 - 0.74 * self->vignette_sharpness);
|
||||
}
|
||||
}
|
||||
else
|
||||
color_component = opacity / 255.;
|
||||
|
||||
cogl_pipeline_set_color4f (self->pipeline,
|
||||
color_component,
|
||||
color_component,
|
||||
color_component,
|
||||
opacity / 255.);
|
||||
|
||||
fb = clutter_paint_context_get_framebuffer (paint_context);
|
||||
if (!self->force_bilinear &&
|
||||
meta_actor_painting_untransformed (fb,
|
||||
actor_pixel_rect->width,
|
||||
actor_pixel_rect->height,
|
||||
actor_pixel_rect->width,
|
||||
actor_pixel_rect->height,
|
||||
NULL, NULL))
|
||||
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
else
|
||||
filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||
|
||||
cogl_pipeline_set_layer_filters (self->pipeline, 0, filter, filter);
|
||||
}
|
||||
|
||||
static void
|
||||
set_glsl_parameters (MetaBackgroundActor *self,
|
||||
cairo_rectangle_int_t *actor_pixel_rect)
|
||||
{
|
||||
float scale[2];
|
||||
float offset[2];
|
||||
|
||||
/* Compute a scale and offset for transforming texture coordinates to the
|
||||
* coordinate system from [-0.5 to 0.5] across the area of the actor
|
||||
*/
|
||||
scale[0] = self->texture_area.width / (float)actor_pixel_rect->width;
|
||||
scale[1] = self->texture_area.height / (float)actor_pixel_rect->height;
|
||||
offset[0] = self->texture_area.x / (float)actor_pixel_rect->width - 0.5;
|
||||
offset[1] = self->texture_area.y / (float)actor_pixel_rect->height - 0.5;
|
||||
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"scale"),
|
||||
2, 1, scale);
|
||||
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"offset"),
|
||||
2, 1, offset);
|
||||
}
|
||||
|
||||
static void
|
||||
paint_clipped_rectangle (CoglFramebuffer *fb,
|
||||
CoglPipeline *pipeline,
|
||||
cairo_rectangle_int_t *rect,
|
||||
cairo_rectangle_int_t *texture_area)
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
float tx1, ty1, tx2, ty2;
|
||||
|
||||
x1 = rect->x;
|
||||
y1 = rect->y;
|
||||
x2 = rect->x + rect->width;
|
||||
y2 = rect->y + rect->height;
|
||||
|
||||
tx1 = (x1 - texture_area->x) / texture_area->width;
|
||||
ty1 = (y1 - texture_area->y) / texture_area->height;
|
||||
tx2 = (x2 - texture_area->x) / texture_area->width;
|
||||
ty2 = (y2 - texture_area->y) / texture_area->height;
|
||||
|
||||
cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
|
||||
x1, y1, x2, y2,
|
||||
tx1, ty1, tx2, ty2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_background_actor_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
return clutter_paint_volume_set_from_allocation (volume, actor);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_actor_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
|
||||
ClutterActorBox actor_box;
|
||||
cairo_rectangle_int_t actor_pixel_rect;
|
||||
CoglFramebuffer *fb;
|
||||
cairo_region_t *region;
|
||||
int i, n_rects;
|
||||
|
||||
if ((self->clip_region && cairo_region_is_empty (self->clip_region)))
|
||||
return;
|
||||
|
||||
clutter_actor_get_content_box (actor, &actor_box);
|
||||
actor_pixel_rect.x = actor_box.x1;
|
||||
actor_pixel_rect.y = actor_box.y1;
|
||||
actor_pixel_rect.width = actor_box.x2 - actor_box.x1;
|
||||
actor_pixel_rect.height = actor_box.y2 - actor_box.y1;
|
||||
|
||||
setup_pipeline (self, paint_context, &actor_pixel_rect);
|
||||
set_glsl_parameters (self, &actor_pixel_rect);
|
||||
|
||||
/* Limit to how many separate rectangles we'll draw; beyond this just
|
||||
* fall back and draw the whole thing */
|
||||
#define MAX_RECTS 64
|
||||
|
||||
fb = clutter_paint_context_get_framebuffer (paint_context);
|
||||
|
||||
/* Now figure out what to actually paint.
|
||||
*/
|
||||
if (self->clip_region)
|
||||
{
|
||||
region = cairo_region_copy (self->clip_region);
|
||||
cairo_region_intersect_rectangle (region, &actor_pixel_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
region = cairo_region_create_rectangle (&actor_pixel_rect);
|
||||
}
|
||||
|
||||
if (self->unobscured_region)
|
||||
cairo_region_intersect (region, self->unobscured_region);
|
||||
|
||||
if (cairo_region_is_empty (region))
|
||||
{
|
||||
cairo_region_destroy (region);
|
||||
if (self->content || !self->display || self->monitor == -1)
|
||||
return;
|
||||
}
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
if (n_rects <= MAX_RECTS)
|
||||
{
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
paint_clipped_rectangle (fb, self->pipeline, &rect,
|
||||
&self->texture_area);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_extents (region, &rect);
|
||||
paint_clipped_rectangle (fb, self->pipeline, &rect,
|
||||
&self->texture_area);
|
||||
}
|
||||
|
||||
cairo_region_destroy (region);
|
||||
content = meta_background_content_new (self->display, self->monitor);
|
||||
self->content = META_BACKGROUND_CONTENT (content);
|
||||
clutter_actor_set_content (CLUTTER_ACTOR (self), content);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -603,48 +72,11 @@ meta_background_actor_set_property (GObject *object,
|
||||
{
|
||||
case PROP_META_DISPLAY:
|
||||
self->display = g_value_get_object (value);
|
||||
maybe_create_content (self);
|
||||
break;
|
||||
case PROP_MONITOR:
|
||||
meta_background_actor_set_monitor (self, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_BACKGROUND:
|
||||
meta_background_actor_set_background (self, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_GRADIENT:
|
||||
meta_background_actor_set_gradient (self,
|
||||
g_value_get_boolean (value),
|
||||
self->gradient_height,
|
||||
self->gradient_max_darkness);
|
||||
break;
|
||||
case PROP_GRADIENT_HEIGHT:
|
||||
meta_background_actor_set_gradient (self,
|
||||
self->gradient,
|
||||
g_value_get_int (value),
|
||||
self->gradient_max_darkness);
|
||||
break;
|
||||
case PROP_GRADIENT_MAX_DARKNESS:
|
||||
meta_background_actor_set_gradient (self,
|
||||
self->gradient,
|
||||
self->gradient_height,
|
||||
g_value_get_double (value));
|
||||
break;
|
||||
case PROP_VIGNETTE:
|
||||
meta_background_actor_set_vignette (self,
|
||||
g_value_get_boolean (value),
|
||||
self->vignette_brightness,
|
||||
self->vignette_sharpness);
|
||||
break;
|
||||
case PROP_VIGNETTE_SHARPNESS:
|
||||
meta_background_actor_set_vignette (self,
|
||||
self->vignette,
|
||||
self->vignette_brightness,
|
||||
g_value_get_double (value));
|
||||
break;
|
||||
case PROP_VIGNETTE_BRIGHTNESS:
|
||||
meta_background_actor_set_vignette (self,
|
||||
self->vignette,
|
||||
g_value_get_double (value),
|
||||
self->vignette_sharpness);
|
||||
self->monitor = g_value_get_int (value);
|
||||
maybe_create_content (self);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@ -668,27 +100,6 @@ meta_background_actor_get_property (GObject *object,
|
||||
case PROP_MONITOR:
|
||||
g_value_set_int (value, self->monitor);
|
||||
break;
|
||||
case PROP_BACKGROUND:
|
||||
g_value_set_object (value, self->background);
|
||||
break;
|
||||
case PROP_GRADIENT:
|
||||
g_value_set_boolean (value, self->gradient);
|
||||
break;
|
||||
case PROP_GRADIENT_HEIGHT:
|
||||
g_value_set_int (value, self->gradient_height);
|
||||
break;
|
||||
case PROP_GRADIENT_MAX_DARKNESS:
|
||||
g_value_set_double (value, self->gradient_max_darkness);
|
||||
break;
|
||||
case PROP_VIGNETTE:
|
||||
g_value_set_boolean (value, self->vignette);
|
||||
break;
|
||||
case PROP_VIGNETTE_BRIGHTNESS:
|
||||
g_value_set_double (value, self->vignette_brightness);
|
||||
break;
|
||||
case PROP_VIGNETTE_SHARPNESS:
|
||||
g_value_set_double (value, self->vignette_sharpness);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -699,18 +110,11 @@ static void
|
||||
meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GParamSpec *param_spec;
|
||||
|
||||
object_class->dispose = meta_background_actor_dispose;
|
||||
object_class->set_property = meta_background_actor_set_property;
|
||||
object_class->get_property = meta_background_actor_get_property;
|
||||
|
||||
actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
|
||||
actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
|
||||
actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
|
||||
actor_class->paint = meta_background_actor_paint;
|
||||
|
||||
param_spec = g_param_spec_object ("meta-display",
|
||||
"MetaDisplay",
|
||||
"MetaDisplay",
|
||||
@ -730,88 +134,15 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MONITOR,
|
||||
param_spec);
|
||||
|
||||
param_spec = g_param_spec_object ("background",
|
||||
"Background",
|
||||
"MetaBackground object holding background parameters",
|
||||
META_TYPE_BACKGROUND,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_BACKGROUND,
|
||||
param_spec);
|
||||
|
||||
param_spec = g_param_spec_boolean ("gradient",
|
||||
"Gradient",
|
||||
"Whether gradient effect is enabled",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_GRADIENT,
|
||||
param_spec);
|
||||
|
||||
param_spec = g_param_spec_int ("gradient-height",
|
||||
"Gradient Height",
|
||||
"Height of gradient effect",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_GRADIENT_HEIGHT,
|
||||
param_spec);
|
||||
|
||||
param_spec = g_param_spec_double ("gradient-max-darkness",
|
||||
"Gradient Max Darkness",
|
||||
"How dark is the gradient initially",
|
||||
0.0, 1.0, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_GRADIENT_MAX_DARKNESS,
|
||||
param_spec);
|
||||
|
||||
param_spec = g_param_spec_boolean ("vignette",
|
||||
"Vignette",
|
||||
"Whether vignette effect is enabled",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_VIGNETTE,
|
||||
param_spec);
|
||||
|
||||
param_spec = g_param_spec_double ("brightness",
|
||||
"Vignette Brightness",
|
||||
"Brightness of vignette effect",
|
||||
0.0, 1.0, 1.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_VIGNETTE_BRIGHTNESS,
|
||||
param_spec);
|
||||
|
||||
param_spec = g_param_spec_double ("vignette-sharpness",
|
||||
"Vignette Sharpness",
|
||||
"Sharpness of vignette effect",
|
||||
0.0, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_VIGNETTE_SHARPNESS,
|
||||
param_spec);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_actor_init (MetaBackgroundActor *self)
|
||||
{
|
||||
self->gradient = FALSE;
|
||||
self->gradient_height = 0;
|
||||
self->gradient_max_darkness = 0.0;
|
||||
self->monitor = -1;
|
||||
|
||||
self->vignette = FALSE;
|
||||
self->vignette_brightness = 1.0;
|
||||
self->vignette_sharpness = 0.0;
|
||||
clutter_actor_set_request_mode (CLUTTER_ACTOR (self),
|
||||
CLUTTER_REQUEST_CONTENT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -843,8 +174,12 @@ meta_background_actor_cull_out (MetaCullable *cullable,
|
||||
{
|
||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
|
||||
|
||||
set_unobscured_region (self, unobscured_region);
|
||||
set_clip_region (self, clip_region);
|
||||
if (!self->content)
|
||||
return;
|
||||
|
||||
meta_background_content_cull_out (self->content,
|
||||
unobscured_region,
|
||||
clip_region);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -852,8 +187,10 @@ meta_background_actor_reset_culling (MetaCullable *cullable)
|
||||
{
|
||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
|
||||
|
||||
set_unobscured_region (self, NULL);
|
||||
set_clip_region (self, NULL);
|
||||
if (!self->content)
|
||||
return;
|
||||
|
||||
meta_background_content_reset_culling (self->content);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -874,135 +211,8 @@ cullable_iface_init (MetaCullableInterface *iface)
|
||||
cairo_region_t *
|
||||
meta_background_actor_get_clip_region (MetaBackgroundActor *self)
|
||||
{
|
||||
return self->clip_region;
|
||||
}
|
||||
|
||||
static void
|
||||
invalidate_pipeline (MetaBackgroundActor *self,
|
||||
ChangedFlags changed)
|
||||
{
|
||||
self->changed |= changed;
|
||||
}
|
||||
|
||||
static void
|
||||
on_background_changed (MetaBackground *background,
|
||||
MetaBackgroundActor *self)
|
||||
{
|
||||
invalidate_pipeline (self, CHANGED_BACKGROUND);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_actor_set_background (MetaBackgroundActor *self,
|
||||
MetaBackground *background)
|
||||
{
|
||||
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
|
||||
g_return_if_fail (background == NULL || META_IS_BACKGROUND (background));
|
||||
|
||||
if (background == self->background)
|
||||
return;
|
||||
|
||||
if (self->background)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (self->background,
|
||||
(gpointer)on_background_changed,
|
||||
self);
|
||||
g_object_unref (self->background);
|
||||
self->background = NULL;
|
||||
}
|
||||
|
||||
if (background)
|
||||
{
|
||||
self->background = g_object_ref (background);
|
||||
g_signal_connect (self->background, "changed",
|
||||
G_CALLBACK (on_background_changed), self);
|
||||
}
|
||||
|
||||
invalidate_pipeline (self, CHANGED_BACKGROUND);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_actor_set_gradient (MetaBackgroundActor *self,
|
||||
gboolean enabled,
|
||||
int height,
|
||||
double max_darkness)
|
||||
{
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
|
||||
g_return_if_fail (height >= 0);
|
||||
g_return_if_fail (max_darkness >= 0. && max_darkness <= 1.);
|
||||
|
||||
enabled = enabled != FALSE && height != 0;
|
||||
|
||||
if (enabled != self->gradient)
|
||||
{
|
||||
self->gradient = enabled;
|
||||
invalidate_pipeline (self, CHANGED_EFFECTS);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (height != self->gradient_height || max_darkness != self->gradient_max_darkness)
|
||||
{
|
||||
self->gradient_height = height;
|
||||
self->gradient_max_darkness = max_darkness;
|
||||
invalidate_pipeline (self, CHANGED_GRADIENT_PARAMETERS);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_actor_set_monitor (MetaBackgroundActor *self,
|
||||
int monitor)
|
||||
{
|
||||
MetaRectangle old_monitor_geometry;
|
||||
MetaRectangle new_monitor_geometry;
|
||||
MetaDisplay *display = self->display;
|
||||
|
||||
if(self->monitor == monitor)
|
||||
return;
|
||||
|
||||
meta_display_get_monitor_geometry (display, self->monitor, &old_monitor_geometry);
|
||||
meta_display_get_monitor_geometry (display, monitor, &new_monitor_geometry);
|
||||
if(old_monitor_geometry.height != new_monitor_geometry.height)
|
||||
invalidate_pipeline (self, CHANGED_GRADIENT_PARAMETERS);
|
||||
|
||||
self->monitor = monitor;
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_actor_set_vignette (MetaBackgroundActor *self,
|
||||
gboolean enabled,
|
||||
double brightness,
|
||||
double sharpness)
|
||||
{
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
|
||||
g_return_if_fail (brightness >= 0. && brightness <= 1.);
|
||||
g_return_if_fail (sharpness >= 0.);
|
||||
|
||||
enabled = enabled != FALSE;
|
||||
|
||||
if (enabled != self->vignette)
|
||||
{
|
||||
self->vignette = enabled;
|
||||
invalidate_pipeline (self, CHANGED_EFFECTS);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (brightness != self->vignette_brightness || sharpness != self->vignette_sharpness)
|
||||
{
|
||||
self->vignette_brightness = brightness;
|
||||
self->vignette_sharpness = sharpness;
|
||||
invalidate_pipeline (self, CHANGED_VIGNETTE_PARAMETERS);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||
if (!self->content)
|
||||
return NULL;
|
||||
|
||||
return meta_background_content_get_clip_region (self->content);
|
||||
}
|
||||
|
16
src/compositor/meta-background-content-private.h
Normal file
16
src/compositor/meta-background-content-private.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#ifndef META_BACKGROUND_CONTENT_PRIVATE_H
|
||||
#define META_BACKGROUND_CONTENT_PRIVATE_H
|
||||
|
||||
#include "meta/meta-background-content.h"
|
||||
|
||||
cairo_region_t *meta_background_content_get_clip_region (MetaBackgroundContent *self);
|
||||
|
||||
void meta_background_content_cull_out (MetaBackgroundContent *self,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region);
|
||||
|
||||
void meta_background_content_reset_culling (MetaBackgroundContent *self);
|
||||
|
||||
#endif /* META_BACKGROUND_CONTENT_PRIVATE_H */
|
937
src/compositor/meta-background-content.c
Normal file
937
src/compositor/meta-background-content.c
Normal file
@ -0,0 +1,937 @@
|
||||
/*
|
||||
* Copyright 2009 Sander Dijkhuis
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
* Copyright 2020 Endless Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Portions adapted from gnome-shell/src/shell-global.c
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:meta-background-content
|
||||
* @title: MetaBackgroundContent
|
||||
* @short_description: ClutterContent for painting the root window background
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The overall model drawing model of this content is that we have one
|
||||
* texture, or two interpolated textures, possibly with alpha or
|
||||
* margins that let the underlying background show through, blended
|
||||
* over a solid color or a gradient. The result of that combination
|
||||
* can then be affected by a "vignette" that darkens the background
|
||||
* away from a central point (or as a no-GLSL fallback, simply darkens
|
||||
* the background) and by overall opacity.
|
||||
*
|
||||
* As of GNOME 3.14, GNOME is only using a fraction of this when the
|
||||
* user sets the background through the control center - what can be
|
||||
* set is:
|
||||
*
|
||||
* A single image without a border
|
||||
* An animation of images without a border that blend together,
|
||||
* with the blend changing every 4-5 minutes
|
||||
* A solid color with a repeated noise texture blended over it
|
||||
*
|
||||
* This all is pretty easy to do in a fragment shader, except when:
|
||||
*
|
||||
* A) We don't have GLSL - in this case, the operation of
|
||||
* interpolating the two textures and blending the result over the
|
||||
* background can't be expressed with Cogl's fixed-function layer
|
||||
* combining (which is confined to what GL's texture environment
|
||||
* combining can do) So we can only handle the above directly if
|
||||
* there are no margins or alpha.
|
||||
*
|
||||
* B) The image textures are sliced. Texture size limits on older
|
||||
* hardware (pre-965 intel hardware, r300, etc.) is often 2048,
|
||||
* and it would be common to use a texture larger than this for a
|
||||
* background and expect it to be scaled down. Cogl can compensate
|
||||
* for this by breaking the texture up into multiple textures, but
|
||||
* can't multitexture with sliced textures. So we can only handle
|
||||
* the above if there's a single texture.
|
||||
*
|
||||
* However, even when we *can* represent everything in a single pass,
|
||||
* it's not necessarily efficient. If we want to draw a 1024x768
|
||||
* background, it's pretty inefficient to bilinearly texture from
|
||||
* two 2560x1440 images and mix that. So the drawing model we take
|
||||
* here is that MetaBackground generates a single texture (which
|
||||
* might be a 1x1 texture for a solid color, or a 1x2 texture for a
|
||||
* gradient, or a repeated texture for wallpaper, or a pre-rendered
|
||||
* texture the size of the screen), and we draw with that, possibly
|
||||
* adding the vignette and opacity.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "compositor/meta-background-content-private.h"
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "compositor/clutter-utils.h"
|
||||
#include "compositor/cogl-utils.h"
|
||||
#include "compositor/meta-background-private.h"
|
||||
#include "compositor/meta-cullable.h"
|
||||
#include "meta/display.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHANGED_BACKGROUND = 1 << 0,
|
||||
CHANGED_EFFECTS = 1 << 2,
|
||||
CHANGED_VIGNETTE_PARAMETERS = 1 << 3,
|
||||
CHANGED_GRADIENT_PARAMETERS = 1 << 4,
|
||||
CHANGED_ALL = 0xFFFF
|
||||
} ChangedFlags;
|
||||
|
||||
#define GRADIENT_VERTEX_SHADER_DECLARATIONS \
|
||||
"uniform vec2 scale;\n" \
|
||||
"varying vec2 position;\n" \
|
||||
|
||||
#define GRADIENT_VERTEX_SHADER_CODE \
|
||||
"position = cogl_tex_coord0_in.xy * scale;\n" \
|
||||
|
||||
#define GRADIENT_FRAGMENT_SHADER_DECLARATIONS \
|
||||
"uniform float gradient_height_perc;\n" \
|
||||
"uniform float gradient_max_darkness;\n" \
|
||||
"varying vec2 position;\n" \
|
||||
|
||||
#define GRADIENT_FRAGMENT_SHADER_CODE \
|
||||
"float min_brightness = 1.0 - gradient_max_darkness;\n" \
|
||||
"float gradient_y_pos = min(position.y, gradient_height_perc) / gradient_height_perc;\n" \
|
||||
"float pixel_brightness = (1.0 - min_brightness) * gradient_y_pos + min_brightness;\n" \
|
||||
"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \
|
||||
|
||||
#define VIGNETTE_VERTEX_SHADER_DECLARATIONS \
|
||||
"uniform vec2 scale;\n" \
|
||||
"uniform vec2 offset;\n" \
|
||||
"varying vec2 position;\n" \
|
||||
|
||||
#define VIGNETTE_VERTEX_SHADER_CODE \
|
||||
"position = cogl_tex_coord0_in.xy * scale + offset;\n" \
|
||||
|
||||
#define VIGNETTE_SQRT_2 "1.4142"
|
||||
|
||||
#define VIGNETTE_FRAGMENT_SHADER_DECLARATIONS \
|
||||
"uniform float vignette_sharpness;\n" \
|
||||
"varying vec2 position;\n" \
|
||||
"float rand(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453123); }\n" \
|
||||
|
||||
#define VIGNETTE_FRAGMENT_SHADER_CODE \
|
||||
"float t = " VIGNETTE_SQRT_2 " * length(position);\n" \
|
||||
"t = min(t, 1.0);\n" \
|
||||
"float pixel_brightness = 1.0 - t * vignette_sharpness;\n" \
|
||||
"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \
|
||||
"cogl_color_out.rgb += (rand(position) - 0.5) / 255.0;\n" \
|
||||
|
||||
typedef struct _MetaBackgroundLayer MetaBackgroundLayer;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIPELINE_VIGNETTE = (1 << 0),
|
||||
PIPELINE_BLEND = (1 << 1),
|
||||
PIPELINE_GRADIENT = (1 << 2),
|
||||
} PipelineFlags;
|
||||
|
||||
struct _MetaBackgroundContent
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaDisplay *display;
|
||||
int monitor;
|
||||
|
||||
MetaBackground *background;
|
||||
|
||||
gboolean gradient;
|
||||
double gradient_max_darkness;
|
||||
int gradient_height;
|
||||
|
||||
gboolean vignette;
|
||||
double vignette_brightness;
|
||||
double vignette_sharpness;
|
||||
|
||||
ChangedFlags changed;
|
||||
CoglPipeline *pipeline;
|
||||
PipelineFlags pipeline_flags;
|
||||
cairo_rectangle_int_t texture_area;
|
||||
gboolean force_bilinear;
|
||||
|
||||
cairo_region_t *clip_region;
|
||||
cairo_region_t *unobscured_region;
|
||||
};
|
||||
|
||||
static void clutter_content_iface_init (ClutterContentInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaBackgroundContent,
|
||||
meta_background_content,
|
||||
G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
|
||||
clutter_content_iface_init));
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_META_DISPLAY,
|
||||
PROP_MONITOR,
|
||||
PROP_BACKGROUND,
|
||||
PROP_GRADIENT,
|
||||
PROP_GRADIENT_HEIGHT,
|
||||
PROP_GRADIENT_MAX_DARKNESS,
|
||||
PROP_VIGNETTE,
|
||||
PROP_VIGNETTE_SHARPNESS,
|
||||
PROP_VIGNETTE_BRIGHTNESS,
|
||||
N_PROPS,
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
|
||||
static void
|
||||
set_clip_region (MetaBackgroundContent *self,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
g_clear_pointer (&self->clip_region, cairo_region_destroy);
|
||||
if (clip_region)
|
||||
{
|
||||
if (cairo_region_is_empty (clip_region))
|
||||
self->clip_region = cairo_region_reference (clip_region);
|
||||
else
|
||||
self->clip_region = cairo_region_copy (clip_region);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_unobscured_region (MetaBackgroundContent *self,
|
||||
cairo_region_t *unobscured_region)
|
||||
{
|
||||
g_clear_pointer (&self->unobscured_region, cairo_region_destroy);
|
||||
if (unobscured_region)
|
||||
{
|
||||
if (cairo_region_is_empty (unobscured_region))
|
||||
self->unobscured_region = cairo_region_reference (unobscured_region);
|
||||
else
|
||||
self->unobscured_region = cairo_region_copy (unobscured_region);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
invalidate_pipeline (MetaBackgroundContent *self,
|
||||
ChangedFlags changed)
|
||||
{
|
||||
self->changed |= changed;
|
||||
}
|
||||
|
||||
static void
|
||||
on_background_changed (MetaBackground *background,
|
||||
MetaBackgroundContent *self)
|
||||
{
|
||||
invalidate_pipeline (self, CHANGED_BACKGROUND);
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (self));
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
make_pipeline (PipelineFlags pipeline_flags)
|
||||
{
|
||||
static CoglPipeline *templates[8];
|
||||
CoglPipeline **templatep;
|
||||
|
||||
templatep = &templates[pipeline_flags];
|
||||
if (*templatep == NULL)
|
||||
{
|
||||
/* Cogl automatically caches pipelines with no eviction policy,
|
||||
* so we need to prevent identical pipelines from getting cached
|
||||
* separately, by reusing the same shader snippets.
|
||||
*/
|
||||
*templatep = COGL_PIPELINE (meta_create_texture_pipeline (NULL));
|
||||
|
||||
if ((pipeline_flags & PIPELINE_VIGNETTE) != 0)
|
||||
{
|
||||
static CoglSnippet *vignette_vertex_snippet;
|
||||
static CoglSnippet *vignette_fragment_snippet;
|
||||
|
||||
if (!vignette_vertex_snippet)
|
||||
vignette_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
|
||||
VIGNETTE_VERTEX_SHADER_DECLARATIONS,
|
||||
VIGNETTE_VERTEX_SHADER_CODE);
|
||||
|
||||
cogl_pipeline_add_snippet (*templatep, vignette_vertex_snippet);
|
||||
|
||||
if (!vignette_fragment_snippet)
|
||||
vignette_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
VIGNETTE_FRAGMENT_SHADER_DECLARATIONS,
|
||||
VIGNETTE_FRAGMENT_SHADER_CODE);
|
||||
|
||||
cogl_pipeline_add_snippet (*templatep, vignette_fragment_snippet);
|
||||
}
|
||||
|
||||
if ((pipeline_flags & PIPELINE_GRADIENT) != 0)
|
||||
{
|
||||
static CoglSnippet *gradient_vertex_snippet;
|
||||
static CoglSnippet *gradient_fragment_snippet;
|
||||
|
||||
if (!gradient_vertex_snippet)
|
||||
gradient_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
|
||||
GRADIENT_VERTEX_SHADER_DECLARATIONS,
|
||||
GRADIENT_VERTEX_SHADER_CODE);
|
||||
|
||||
cogl_pipeline_add_snippet (*templatep, gradient_vertex_snippet);
|
||||
|
||||
if (!gradient_fragment_snippet)
|
||||
gradient_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
GRADIENT_FRAGMENT_SHADER_DECLARATIONS,
|
||||
GRADIENT_FRAGMENT_SHADER_CODE);
|
||||
|
||||
cogl_pipeline_add_snippet (*templatep, gradient_fragment_snippet);
|
||||
}
|
||||
|
||||
if ((pipeline_flags & PIPELINE_BLEND) == 0)
|
||||
cogl_pipeline_set_blend (*templatep, "RGBA = ADD (SRC_COLOR, 0)", NULL);
|
||||
}
|
||||
|
||||
return cogl_pipeline_copy (*templatep);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_pipeline (MetaBackgroundContent *self,
|
||||
ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context,
|
||||
cairo_rectangle_int_t *actor_pixel_rect)
|
||||
{
|
||||
PipelineFlags pipeline_flags = 0;
|
||||
guint8 opacity;
|
||||
float color_component;
|
||||
CoglFramebuffer *fb;
|
||||
CoglPipelineFilter filter;
|
||||
|
||||
opacity = clutter_actor_get_paint_opacity (actor);
|
||||
if (opacity < 255)
|
||||
pipeline_flags |= PIPELINE_BLEND;
|
||||
if (self->vignette && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
pipeline_flags |= PIPELINE_VIGNETTE;
|
||||
if (self->gradient && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
pipeline_flags |= PIPELINE_GRADIENT;
|
||||
|
||||
if (pipeline_flags != self->pipeline_flags)
|
||||
g_clear_pointer (&self->pipeline, cogl_object_unref);
|
||||
|
||||
if (self->pipeline == NULL)
|
||||
{
|
||||
self->pipeline_flags = pipeline_flags;
|
||||
self->pipeline = make_pipeline (pipeline_flags);
|
||||
self->changed = CHANGED_ALL;
|
||||
}
|
||||
|
||||
if (self->changed & CHANGED_BACKGROUND)
|
||||
{
|
||||
CoglPipelineWrapMode wrap_mode;
|
||||
CoglTexture *texture = meta_background_get_texture (self->background,
|
||||
self->monitor,
|
||||
&self->texture_area,
|
||||
&wrap_mode);
|
||||
self->force_bilinear = texture &&
|
||||
(self->texture_area.width != (int)cogl_texture_get_width (texture) ||
|
||||
self->texture_area.height != (int)cogl_texture_get_height (texture));
|
||||
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
cogl_pipeline_set_layer_wrap_mode (self->pipeline, 0, wrap_mode);
|
||||
|
||||
self->changed &= ~CHANGED_BACKGROUND;
|
||||
}
|
||||
|
||||
if (self->changed & CHANGED_VIGNETTE_PARAMETERS)
|
||||
{
|
||||
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"vignette_sharpness"),
|
||||
self->vignette_sharpness);
|
||||
|
||||
self->changed &= ~CHANGED_VIGNETTE_PARAMETERS;
|
||||
}
|
||||
|
||||
if (self->changed & CHANGED_GRADIENT_PARAMETERS)
|
||||
{
|
||||
MetaRectangle monitor_geometry;
|
||||
float gradient_height_perc;
|
||||
|
||||
meta_display_get_monitor_geometry (self->display,
|
||||
self->monitor, &monitor_geometry);
|
||||
gradient_height_perc = MAX (0.0001, self->gradient_height / (float)monitor_geometry.height);
|
||||
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"gradient_height_perc"),
|
||||
gradient_height_perc);
|
||||
cogl_pipeline_set_uniform_1f (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"gradient_max_darkness"),
|
||||
self->gradient_max_darkness);
|
||||
|
||||
self->changed &= ~CHANGED_GRADIENT_PARAMETERS;
|
||||
}
|
||||
|
||||
if (self->vignette)
|
||||
{
|
||||
color_component = self->vignette_brightness * opacity / 255.;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
{
|
||||
/* Darken everything to match the average brightness that would
|
||||
* be there if we were drawing the vignette, which is
|
||||
* (1 - (pi/12.) * vignette_sharpness) [exercise for the reader :]
|
||||
*/
|
||||
color_component *= (1 - 0.74 * self->vignette_sharpness);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
color_component = opacity / 255.;
|
||||
}
|
||||
|
||||
cogl_pipeline_set_color4f (self->pipeline,
|
||||
color_component,
|
||||
color_component,
|
||||
color_component,
|
||||
opacity / 255.);
|
||||
|
||||
fb = clutter_paint_context_get_framebuffer (paint_context);
|
||||
if (!self->force_bilinear &&
|
||||
meta_actor_painting_untransformed (fb,
|
||||
actor_pixel_rect->width,
|
||||
actor_pixel_rect->height,
|
||||
actor_pixel_rect->width,
|
||||
actor_pixel_rect->height,
|
||||
NULL, NULL))
|
||||
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
else
|
||||
filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||
|
||||
cogl_pipeline_set_layer_filters (self->pipeline, 0, filter, filter);
|
||||
}
|
||||
|
||||
static void
|
||||
set_glsl_parameters (MetaBackgroundContent *self,
|
||||
cairo_rectangle_int_t *actor_pixel_rect)
|
||||
{
|
||||
float scale[2];
|
||||
float offset[2];
|
||||
|
||||
/* Compute a scale and offset for transforming texture coordinates to the
|
||||
* coordinate system from [-0.5 to 0.5] across the area of the actor
|
||||
*/
|
||||
scale[0] = self->texture_area.width / (float)actor_pixel_rect->width;
|
||||
scale[1] = self->texture_area.height / (float)actor_pixel_rect->height;
|
||||
offset[0] = self->texture_area.x / (float)actor_pixel_rect->width - 0.5;
|
||||
offset[1] = self->texture_area.y / (float)actor_pixel_rect->height - 0.5;
|
||||
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"scale"),
|
||||
2, 1, scale);
|
||||
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"offset"),
|
||||
2, 1, offset);
|
||||
}
|
||||
|
||||
static void
|
||||
paint_clipped_rectangle (MetaBackgroundContent *self,
|
||||
ClutterPaintNode *node,
|
||||
ClutterActorBox *actor_box,
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
g_autoptr (ClutterPaintNode) pipeline_node = NULL;
|
||||
float h_scale, v_scale;
|
||||
float x1, y1, x2, y2;
|
||||
float tx1, ty1, tx2, ty2;
|
||||
|
||||
h_scale = self->texture_area.width / clutter_actor_box_get_width (actor_box);
|
||||
v_scale = self->texture_area.height / clutter_actor_box_get_height (actor_box);
|
||||
|
||||
x1 = rect->x;
|
||||
y1 = rect->y;
|
||||
x2 = rect->x + rect->width;
|
||||
y2 = rect->y + rect->height;
|
||||
|
||||
tx1 = (x1 * h_scale - self->texture_area.x) / (float)self->texture_area.width;
|
||||
ty1 = (y1 * v_scale - self->texture_area.y) / (float)self->texture_area.height;
|
||||
tx2 = (x2 * h_scale - self->texture_area.x) / (float)self->texture_area.width;
|
||||
ty2 = (y2 * v_scale - self->texture_area.y) / (float)self->texture_area.height;
|
||||
|
||||
pipeline_node = clutter_pipeline_node_new (self->pipeline);
|
||||
clutter_paint_node_set_name (pipeline_node, "MetaBackgroundContent (Slice)");
|
||||
clutter_paint_node_add_texture_rectangle (pipeline_node,
|
||||
&(ClutterActorBox) {
|
||||
.x1 = x1,
|
||||
.y1 = y1,
|
||||
.x2 = x2,
|
||||
.y2 = y2,
|
||||
},
|
||||
tx1, ty1,
|
||||
tx2, ty2);
|
||||
|
||||
clutter_paint_node_add_child (node, pipeline_node);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_content_paint_content (ClutterContent *content,
|
||||
ClutterActor *actor,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
MetaBackgroundContent *self = META_BACKGROUND_CONTENT (content);
|
||||
ClutterActorBox actor_box;
|
||||
cairo_rectangle_int_t actor_pixel_rect;
|
||||
cairo_region_t *region;
|
||||
int i, n_rects;
|
||||
|
||||
if ((self->clip_region && cairo_region_is_empty (self->clip_region)))
|
||||
return;
|
||||
|
||||
clutter_actor_get_content_box (actor, &actor_box);
|
||||
actor_pixel_rect.x = actor_box.x1;
|
||||
actor_pixel_rect.y = actor_box.x1;
|
||||
actor_pixel_rect.width = actor_box.x2 - actor_box.x1;
|
||||
actor_pixel_rect.height = actor_box.y2 - actor_box.y1;
|
||||
|
||||
setup_pipeline (self, actor, paint_context, &actor_pixel_rect);
|
||||
set_glsl_parameters (self, &actor_pixel_rect);
|
||||
|
||||
/* Limit to how many separate rectangles we'll draw; beyond this just
|
||||
* fall back and draw the whole thing */
|
||||
#define MAX_RECTS 64
|
||||
|
||||
/* Now figure out what to actually paint */
|
||||
if (self->clip_region)
|
||||
{
|
||||
region = cairo_region_copy (self->clip_region);
|
||||
cairo_region_intersect_rectangle (region, &actor_pixel_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
region = cairo_region_create_rectangle (&actor_pixel_rect);
|
||||
}
|
||||
|
||||
if (self->unobscured_region)
|
||||
cairo_region_intersect (region, self->unobscured_region);
|
||||
|
||||
if (cairo_region_is_empty (region))
|
||||
{
|
||||
cairo_region_destroy (region);
|
||||
return;
|
||||
}
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
if (n_rects <= MAX_RECTS)
|
||||
{
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
paint_clipped_rectangle (self, node, &actor_box, &rect);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_extents (region, &rect);
|
||||
paint_clipped_rectangle (self, node, &actor_box, &rect);
|
||||
}
|
||||
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_background_content_get_preferred_size (ClutterContent *content,
|
||||
float *width,
|
||||
float *height)
|
||||
|
||||
{
|
||||
MetaBackgroundContent *background_content = META_BACKGROUND_CONTENT (content);
|
||||
MetaRectangle monitor_geometry;
|
||||
|
||||
meta_display_get_monitor_geometry (background_content->display,
|
||||
background_content->monitor,
|
||||
&monitor_geometry);
|
||||
|
||||
if (width)
|
||||
*width = monitor_geometry.width;
|
||||
|
||||
if (height)
|
||||
*height = monitor_geometry.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_iface_init (ClutterContentInterface *iface)
|
||||
{
|
||||
iface->paint_content = meta_background_content_paint_content;
|
||||
iface->get_preferred_size = meta_background_content_get_preferred_size;
|
||||
}
|
||||
|
||||
static void
|
||||
set_monitor (MetaBackgroundContent *self,
|
||||
int monitor)
|
||||
{
|
||||
MetaRectangle old_monitor_geometry;
|
||||
MetaRectangle new_monitor_geometry;
|
||||
MetaDisplay *display = self->display;
|
||||
|
||||
if(self->monitor == monitor)
|
||||
return;
|
||||
|
||||
meta_display_get_monitor_geometry (display, self->monitor, &old_monitor_geometry);
|
||||
meta_display_get_monitor_geometry (display, monitor, &new_monitor_geometry);
|
||||
if(old_monitor_geometry.height != new_monitor_geometry.height)
|
||||
invalidate_pipeline (self, CHANGED_GRADIENT_PARAMETERS);
|
||||
|
||||
self->monitor = monitor;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_content_dispose (GObject *object)
|
||||
{
|
||||
MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
|
||||
|
||||
set_clip_region (self, NULL);
|
||||
set_unobscured_region (self, NULL);
|
||||
meta_background_content_set_background (self, NULL);
|
||||
|
||||
g_clear_pointer (&self->pipeline, cogl_object_unref);
|
||||
|
||||
G_OBJECT_CLASS (meta_background_content_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_content_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_META_DISPLAY:
|
||||
self->display = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_MONITOR:
|
||||
set_monitor (self, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_BACKGROUND:
|
||||
meta_background_content_set_background (self, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_GRADIENT:
|
||||
meta_background_content_set_gradient (self,
|
||||
g_value_get_boolean (value),
|
||||
self->gradient_height,
|
||||
self->gradient_max_darkness);
|
||||
break;
|
||||
case PROP_GRADIENT_HEIGHT:
|
||||
meta_background_content_set_gradient (self,
|
||||
self->gradient,
|
||||
g_value_get_int (value),
|
||||
self->gradient_max_darkness);
|
||||
break;
|
||||
case PROP_GRADIENT_MAX_DARKNESS:
|
||||
meta_background_content_set_gradient (self,
|
||||
self->gradient,
|
||||
self->gradient_height,
|
||||
g_value_get_double (value));
|
||||
break;
|
||||
case PROP_VIGNETTE:
|
||||
meta_background_content_set_vignette (self,
|
||||
g_value_get_boolean (value),
|
||||
self->vignette_brightness,
|
||||
self->vignette_sharpness);
|
||||
break;
|
||||
case PROP_VIGNETTE_SHARPNESS:
|
||||
meta_background_content_set_vignette (self,
|
||||
self->vignette,
|
||||
self->vignette_brightness,
|
||||
g_value_get_double (value));
|
||||
break;
|
||||
case PROP_VIGNETTE_BRIGHTNESS:
|
||||
meta_background_content_set_vignette (self,
|
||||
self->vignette,
|
||||
g_value_get_double (value),
|
||||
self->vignette_sharpness);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_content_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaBackgroundContent *self = META_BACKGROUND_CONTENT (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_META_DISPLAY:
|
||||
g_value_set_object (value, self->display);
|
||||
break;
|
||||
case PROP_MONITOR:
|
||||
g_value_set_int (value, self->monitor);
|
||||
break;
|
||||
case PROP_BACKGROUND:
|
||||
g_value_set_object (value, self->background);
|
||||
break;
|
||||
case PROP_GRADIENT:
|
||||
g_value_set_boolean (value, self->gradient);
|
||||
break;
|
||||
case PROP_GRADIENT_HEIGHT:
|
||||
g_value_set_int (value, self->gradient_height);
|
||||
break;
|
||||
case PROP_GRADIENT_MAX_DARKNESS:
|
||||
g_value_set_double (value, self->gradient_max_darkness);
|
||||
break;
|
||||
case PROP_VIGNETTE:
|
||||
g_value_set_boolean (value, self->vignette);
|
||||
break;
|
||||
case PROP_VIGNETTE_BRIGHTNESS:
|
||||
g_value_set_double (value, self->vignette_brightness);
|
||||
break;
|
||||
case PROP_VIGNETTE_SHARPNESS:
|
||||
g_value_set_double (value, self->vignette_sharpness);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_content_class_init (MetaBackgroundContentClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_background_content_dispose;
|
||||
object_class->set_property = meta_background_content_set_property;
|
||||
object_class->get_property = meta_background_content_get_property;
|
||||
|
||||
properties[PROP_META_DISPLAY] =
|
||||
g_param_spec_object ("meta-display",
|
||||
"MetaDisplay",
|
||||
"MetaDisplay",
|
||||
META_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_MONITOR] =
|
||||
g_param_spec_int ("monitor",
|
||||
"monitor",
|
||||
"monitor",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_BACKGROUND] =
|
||||
g_param_spec_object ("background",
|
||||
"Background",
|
||||
"MetaBackground object holding background parameters",
|
||||
META_TYPE_BACKGROUND,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_GRADIENT] =
|
||||
g_param_spec_boolean ("gradient",
|
||||
"Gradient",
|
||||
"Whether gradient effect is enabled",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_GRADIENT_HEIGHT] =
|
||||
g_param_spec_int ("gradient-height",
|
||||
"Gradient Height",
|
||||
"Height of gradient effect",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_GRADIENT_MAX_DARKNESS] =
|
||||
g_param_spec_double ("gradient-max-darkness",
|
||||
"Gradient Max Darkness",
|
||||
"How dark is the gradient initially",
|
||||
0.0, 1.0, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VIGNETTE] =
|
||||
g_param_spec_boolean ("vignette",
|
||||
"Vignette",
|
||||
"Whether vignette effect is enabled",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VIGNETTE_BRIGHTNESS] =
|
||||
g_param_spec_double ("brightness",
|
||||
"Vignette Brightness",
|
||||
"Brightness of vignette effect",
|
||||
0.0, 1.0, 1.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VIGNETTE_SHARPNESS] =
|
||||
g_param_spec_double ("vignette-sharpness",
|
||||
"Vignette Sharpness",
|
||||
"Sharpness of vignette effect",
|
||||
0.0, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_content_init (MetaBackgroundContent *self)
|
||||
{
|
||||
self->gradient = FALSE;
|
||||
self->gradient_height = 0;
|
||||
self->gradient_max_darkness = 0.0;
|
||||
|
||||
self->vignette = FALSE;
|
||||
self->vignette_brightness = 1.0;
|
||||
self->vignette_sharpness = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_background_content_new:
|
||||
* @monitor: Index of the monitor for which to draw the background
|
||||
*
|
||||
* Creates a new actor to draw the background for the given monitor.
|
||||
*
|
||||
* Return value: (transfer full): the newly created background actor
|
||||
*/
|
||||
ClutterContent *
|
||||
meta_background_content_new (MetaDisplay *display,
|
||||
int monitor)
|
||||
{
|
||||
return g_object_new (META_TYPE_BACKGROUND_CONTENT,
|
||||
"meta-display", display,
|
||||
"monitor", monitor,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_content_set_background (MetaBackgroundContent *self,
|
||||
MetaBackground *background)
|
||||
{
|
||||
g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
|
||||
g_return_if_fail (background == NULL || META_IS_BACKGROUND (background));
|
||||
|
||||
if (background == self->background)
|
||||
return;
|
||||
|
||||
if (self->background)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (self->background,
|
||||
(gpointer)on_background_changed,
|
||||
self);
|
||||
g_clear_object (&self->background);
|
||||
}
|
||||
|
||||
if (background)
|
||||
{
|
||||
self->background = g_object_ref (background);
|
||||
g_signal_connect (self->background, "changed",
|
||||
G_CALLBACK (on_background_changed), self);
|
||||
}
|
||||
|
||||
invalidate_pipeline (self, CHANGED_BACKGROUND);
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (self));
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_content_set_gradient (MetaBackgroundContent *self,
|
||||
gboolean enabled,
|
||||
int height,
|
||||
double max_darkness)
|
||||
{
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
|
||||
g_return_if_fail (height >= 0);
|
||||
g_return_if_fail (max_darkness >= 0. && max_darkness <= 1.);
|
||||
|
||||
enabled = enabled != FALSE && height != 0;
|
||||
|
||||
if (enabled != self->gradient)
|
||||
{
|
||||
self->gradient = enabled;
|
||||
invalidate_pipeline (self, CHANGED_EFFECTS);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (height != self->gradient_height || max_darkness != self->gradient_max_darkness)
|
||||
{
|
||||
self->gradient_height = height;
|
||||
self->gradient_max_darkness = max_darkness;
|
||||
invalidate_pipeline (self, CHANGED_GRADIENT_PARAMETERS);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (self));
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_content_set_vignette (MetaBackgroundContent *self,
|
||||
gboolean enabled,
|
||||
double brightness,
|
||||
double sharpness)
|
||||
{
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (META_IS_BACKGROUND_CONTENT (self));
|
||||
g_return_if_fail (brightness >= 0. && brightness <= 1.);
|
||||
g_return_if_fail (sharpness >= 0.);
|
||||
|
||||
enabled = enabled != FALSE;
|
||||
|
||||
if (enabled != self->vignette)
|
||||
{
|
||||
self->vignette = enabled;
|
||||
invalidate_pipeline (self, CHANGED_EFFECTS);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (brightness != self->vignette_brightness || sharpness != self->vignette_sharpness)
|
||||
{
|
||||
self->vignette_brightness = brightness;
|
||||
self->vignette_sharpness = sharpness;
|
||||
invalidate_pipeline (self, CHANGED_VIGNETTE_PARAMETERS);
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (self));
|
||||
}
|
||||
|
||||
cairo_region_t *
|
||||
meta_background_content_get_clip_region (MetaBackgroundContent *self)
|
||||
{
|
||||
return self->clip_region;
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_content_cull_out (MetaBackgroundContent *self,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
set_unobscured_region (self, unobscured_region);
|
||||
set_clip_region (self, clip_region);
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_content_reset_culling (MetaBackgroundContent *self)
|
||||
{
|
||||
set_unobscured_region (self, NULL);
|
||||
set_clip_region (self, NULL);
|
||||
}
|
@ -127,10 +127,12 @@ meta_compositor_native_pre_paint (MetaCompositor *compositor)
|
||||
}
|
||||
|
||||
MetaCompositorNative *
|
||||
meta_compositor_native_new (MetaDisplay *display)
|
||||
meta_compositor_native_new (MetaDisplay *display,
|
||||
MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_COMPOSITOR_NATIVE,
|
||||
"display", display,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
G_DECLARE_FINAL_TYPE (MetaCompositorNative, meta_compositor_native,
|
||||
META, COMPOSITOR_NATIVE, MetaCompositor)
|
||||
|
||||
MetaCompositorNative * meta_compositor_native_new (MetaDisplay *display);
|
||||
MetaCompositorNative * meta_compositor_native_new (MetaDisplay *display,
|
||||
MetaBackend *backend);
|
||||
|
||||
#endif /* META_COMPOSITOR_NATIVE_H */
|
||||
|
@ -37,10 +37,12 @@ meta_compositor_server_unmanage (MetaCompositor *compositor)
|
||||
}
|
||||
|
||||
MetaCompositorServer *
|
||||
meta_compositor_server_new (MetaDisplay *display)
|
||||
meta_compositor_server_new (MetaDisplay *display,
|
||||
MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_COMPOSITOR_SERVER,
|
||||
"display", display,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ struct _MetaCompositorServerClass
|
||||
MetaCompositorClass parent_class;
|
||||
};
|
||||
|
||||
MetaCompositorServer * meta_compositor_server_new (MetaDisplay *display);
|
||||
MetaCompositorServer * meta_compositor_server_new (MetaDisplay *display,
|
||||
MetaBackend *backend);
|
||||
|
||||
#endif /* META_COMPOSITOR_SERVER_H */
|
||||
|
@ -371,10 +371,12 @@ meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11)
|
||||
}
|
||||
|
||||
MetaCompositorX11 *
|
||||
meta_compositor_x11_new (MetaDisplay *display)
|
||||
meta_compositor_x11_new (MetaDisplay *display,
|
||||
MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_COMPOSITOR_X11,
|
||||
"display", display,
|
||||
"backend", backend,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,8 @@
|
||||
G_DECLARE_FINAL_TYPE (MetaCompositorX11, meta_compositor_x11,
|
||||
META, COMPOSITOR_X11, MetaCompositor)
|
||||
|
||||
MetaCompositorX11 * meta_compositor_x11_new (MetaDisplay *display);
|
||||
MetaCompositorX11 * meta_compositor_x11_new (MetaDisplay *display,
|
||||
MetaBackend *backend);
|
||||
|
||||
void meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11,
|
||||
XEvent *xevent,
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "clutter/clutter.h"
|
||||
#include "meta/meta-backend.h"
|
||||
#include "meta/meta-background-actor.h"
|
||||
#include "meta/meta-background-content.h"
|
||||
#include "meta/meta-background-group.h"
|
||||
#include "meta/meta-monitor-manager.h"
|
||||
#include "meta/meta-plugin.h"
|
||||
@ -332,6 +333,8 @@ on_monitors_changed (MetaMonitorManager *monitor_manager,
|
||||
n = meta_display_get_n_monitors (display);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
MetaBackgroundContent *background_content;
|
||||
ClutterContent *content;
|
||||
MetaRectangle rect;
|
||||
ClutterActor *background_actor;
|
||||
MetaBackground *background;
|
||||
@ -340,6 +343,8 @@ on_monitors_changed (MetaMonitorManager *monitor_manager,
|
||||
meta_display_get_monitor_geometry (display, i, &rect);
|
||||
|
||||
background_actor = meta_background_actor_new (display, i);
|
||||
content = clutter_actor_get_content (background_actor);
|
||||
background_content = META_BACKGROUND_CONTENT (content);
|
||||
|
||||
clutter_actor_set_position (background_actor, rect.x, rect.y);
|
||||
clutter_actor_set_size (background_actor, rect.width, rect.height);
|
||||
@ -356,13 +361,10 @@ on_monitors_changed (MetaMonitorManager *monitor_manager,
|
||||
|
||||
background = meta_background_new (display);
|
||||
meta_background_set_color (background, &color);
|
||||
meta_background_actor_set_background (META_BACKGROUND_ACTOR (background_actor), background);
|
||||
meta_background_content_set_background (background_content, background);
|
||||
g_object_unref (background);
|
||||
|
||||
meta_background_actor_set_vignette (META_BACKGROUND_ACTOR (background_actor),
|
||||
TRUE,
|
||||
0.5,
|
||||
0.5);
|
||||
meta_background_content_set_vignette (background_content, TRUE, 0.5, 0.5);
|
||||
|
||||
clutter_actor_add_child (self->priv->background_group, background_actor);
|
||||
}
|
||||
|
@ -573,17 +573,17 @@ meta_display_remove_pending_pings_for_window (MetaDisplay *display,
|
||||
static MetaCompositor *
|
||||
create_compositor (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
return META_COMPOSITOR (meta_compositor_native_new (display));
|
||||
return META_COMPOSITOR (meta_compositor_native_new (display, backend));
|
||||
#endif
|
||||
if (META_IS_BACKEND_X11_NESTED (backend))
|
||||
return META_COMPOSITOR (meta_compositor_server_new (display));
|
||||
return META_COMPOSITOR (meta_compositor_server_new (display, backend));
|
||||
#endif
|
||||
return META_COMPOSITOR (meta_compositor_x11_new (display));
|
||||
return META_COMPOSITOR (meta_compositor_x11_new (display, backend));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-keymap-utils.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
@ -741,7 +742,7 @@ create_us_layout (void)
|
||||
names.variant = "";
|
||||
names.options = "";
|
||||
|
||||
context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
context = meta_create_xkb_context ();
|
||||
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_context_unref (context);
|
||||
|
||||
|
@ -152,6 +152,7 @@ owner_changed_cb (MetaSelection *selection,
|
||||
display->saved_clipboard);
|
||||
g_set_object (&display->selection_source, new_owner);
|
||||
meta_selection_set_owner (selection, selection_type, new_owner);
|
||||
g_object_unref (new_owner);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,6 +171,7 @@ meta_clipboard_manager_shutdown (MetaDisplay *display)
|
||||
{
|
||||
MetaSelection *selection;
|
||||
|
||||
g_clear_object (&display->selection_source);
|
||||
g_clear_pointer (&display->saved_clipboard, g_bytes_unref);
|
||||
g_clear_pointer (&display->saved_clipboard_mimetype, g_free);
|
||||
selection = meta_display_get_selection (display);
|
||||
|
@ -365,103 +365,119 @@ move_window_above (GArray *stack,
|
||||
static gboolean
|
||||
meta_stack_op_apply (MetaStackTracker *tracker,
|
||||
MetaStackOp *op,
|
||||
GArray *stack,
|
||||
GArray *stack,
|
||||
ApplyFlags apply_flags)
|
||||
{
|
||||
switch (op->any.type)
|
||||
{
|
||||
case STACK_OP_ADD:
|
||||
{
|
||||
int old_pos;
|
||||
|
||||
if (META_STACK_ID_IS_X11 (op->add.window) &&
|
||||
(apply_flags & NO_RESTACK_X_WINDOWS) != 0)
|
||||
return FALSE;
|
||||
|
||||
int old_pos = find_window (stack, op->add.window);
|
||||
if (old_pos >= 0)
|
||||
{
|
||||
g_warning ("STACK_OP_ADD: window %s already in stack",
|
||||
get_window_desc (tracker, op->add.window));
|
||||
return FALSE;
|
||||
}
|
||||
old_pos = find_window (stack, op->add.window);
|
||||
if (old_pos >= 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"STACK_OP_ADD: window %s already in stack",
|
||||
get_window_desc (tracker, op->add.window));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_array_append_val (stack, op->add.window);
|
||||
return TRUE;
|
||||
g_array_append_val (stack, op->add.window);
|
||||
return TRUE;
|
||||
}
|
||||
case STACK_OP_REMOVE:
|
||||
{
|
||||
int old_pos;
|
||||
|
||||
if (META_STACK_ID_IS_X11 (op->remove.window) &&
|
||||
(apply_flags & NO_RESTACK_X_WINDOWS) != 0)
|
||||
return FALSE;
|
||||
|
||||
int old_pos = find_window (stack, op->remove.window);
|
||||
if (old_pos < 0)
|
||||
{
|
||||
g_warning ("STACK_OP_REMOVE: window %s not in stack",
|
||||
get_window_desc (tracker, op->remove.window));
|
||||
return FALSE;
|
||||
}
|
||||
old_pos = find_window (stack, op->remove.window);
|
||||
if (old_pos < 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"STACK_OP_REMOVE: window %s not in stack",
|
||||
get_window_desc (tracker, op->remove.window));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_array_remove_index (stack, old_pos);
|
||||
return TRUE;
|
||||
g_array_remove_index (stack, old_pos);
|
||||
return TRUE;
|
||||
}
|
||||
case STACK_OP_RAISE_ABOVE:
|
||||
{
|
||||
int old_pos = find_window (stack, op->raise_above.window);
|
||||
int above_pos;
|
||||
if (old_pos < 0)
|
||||
{
|
||||
g_warning ("STACK_OP_RAISE_ABOVE: window %s not in stack",
|
||||
get_window_desc (tracker, op->raise_above.window));
|
||||
return FALSE;
|
||||
}
|
||||
int old_pos;
|
||||
int above_pos;
|
||||
|
||||
old_pos = find_window (stack, op->raise_above.window);
|
||||
if (old_pos < 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"STACK_OP_RAISE_ABOVE: window %s not in stack",
|
||||
get_window_desc (tracker, op->raise_above.window));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (op->raise_above.sibling)
|
||||
{
|
||||
above_pos = find_window (stack, op->raise_above.sibling);
|
||||
if (above_pos < 0)
|
||||
{
|
||||
g_warning ("STACK_OP_RAISE_ABOVE: sibling window %s not in stack",
|
||||
get_window_desc (tracker, op->raise_above.sibling));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
above_pos = -1;
|
||||
}
|
||||
{
|
||||
above_pos = find_window (stack, op->raise_above.sibling);
|
||||
if (above_pos < 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"STACK_OP_RAISE_ABOVE: sibling window %s not in stack",
|
||||
get_window_desc (tracker, op->raise_above.sibling));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
above_pos = -1;
|
||||
}
|
||||
|
||||
return move_window_above (stack, op->raise_above.window, old_pos, above_pos,
|
||||
return move_window_above (stack, op->raise_above.window, old_pos, above_pos,
|
||||
apply_flags);
|
||||
}
|
||||
case STACK_OP_LOWER_BELOW:
|
||||
{
|
||||
int old_pos = find_window (stack, op->lower_below.window);
|
||||
int above_pos;
|
||||
if (old_pos < 0)
|
||||
{
|
||||
g_warning ("STACK_OP_LOWER_BELOW: window %s not in stack",
|
||||
get_window_desc (tracker, op->lower_below.window));
|
||||
return FALSE;
|
||||
}
|
||||
int old_pos;
|
||||
int above_pos;
|
||||
|
||||
old_pos = find_window (stack, op->raise_above.window);
|
||||
if (old_pos < 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"STACK_OP_LOWER_BELOW: window %s not in stack",
|
||||
get_window_desc (tracker, op->lower_below.window));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (op->lower_below.sibling)
|
||||
{
|
||||
int below_pos = find_window (stack, op->lower_below.sibling);
|
||||
if (below_pos < 0)
|
||||
{
|
||||
g_warning ("STACK_OP_LOWER_BELOW: sibling window %s not in stack",
|
||||
get_window_desc (tracker, op->lower_below.sibling));
|
||||
return FALSE;
|
||||
}
|
||||
{
|
||||
int below_pos;
|
||||
|
||||
above_pos = below_pos - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
above_pos = stack->len - 1;
|
||||
}
|
||||
below_pos = find_window (stack, op->lower_below.sibling);
|
||||
if (below_pos < 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"STACK_OP_LOWER_BELOW: sibling window %s not in stack",
|
||||
get_window_desc (tracker, op->lower_below.sibling));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return move_window_above (stack, op->lower_below.window, old_pos, above_pos,
|
||||
above_pos = below_pos - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
above_pos = stack->len - 1;
|
||||
}
|
||||
|
||||
return move_window_above (stack, op->lower_below.window, old_pos, above_pos,
|
||||
apply_flags);
|
||||
}
|
||||
}
|
||||
|
@ -195,6 +195,8 @@ mutter_sources = [
|
||||
'backends/meta-input-mapper-private.h',
|
||||
'backends/meta-input-settings.c',
|
||||
'backends/meta-input-settings-private.h',
|
||||
'backends/meta-keymap-utils.c',
|
||||
'backends/meta-keymap-utils.h',
|
||||
'backends/meta-logical-monitor.c',
|
||||
'backends/meta-logical-monitor.h',
|
||||
'backends/meta-monitor.c',
|
||||
@ -287,6 +289,8 @@ mutter_sources = [
|
||||
'compositor/compositor-private.h',
|
||||
'compositor/meta-background-actor.c',
|
||||
'compositor/meta-background-actor-private.h',
|
||||
'compositor/meta-background-content.c',
|
||||
'compositor/meta-background-content-private.h',
|
||||
'compositor/meta-background.c',
|
||||
'compositor/meta-background-group.c',
|
||||
'compositor/meta-background-image.c',
|
||||
@ -529,6 +533,12 @@ if have_wayland
|
||||
'wayland/meta-wayland-inhibit-shortcuts-dialog.c',
|
||||
'wayland/meta-wayland-inhibit-shortcuts-dialog.h',
|
||||
'wayland/meta-wayland-inhibit-shortcuts.h',
|
||||
'wayland/meta-wayland-inputfd-evdev-device.c',
|
||||
'wayland/meta-wayland-inputfd-evdev-device.h',
|
||||
'wayland/meta-wayland-inputfd-manager.c',
|
||||
'wayland/meta-wayland-inputfd-manager.h',
|
||||
'wayland/meta-wayland-inputfd-seat.c',
|
||||
'wayland/meta-wayland-inputfd-seat.h',
|
||||
'wayland/meta-wayland-input-device.c',
|
||||
'wayland/meta-wayland-input-device.h',
|
||||
'wayland/meta-wayland-keyboard.c',
|
||||
@ -810,6 +820,7 @@ if have_wayland
|
||||
['gtk-primary-selection', 'private', ],
|
||||
['gtk-shell', 'private', ],
|
||||
['gtk-text-input', 'private', ],
|
||||
['inputfd', 'unstable', 'v1', ],
|
||||
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
|
||||
['linux-dmabuf', 'unstable', 'v1', ],
|
||||
['pointer-constraints', 'unstable', 'v1', ],
|
||||
|
@ -11,6 +11,7 @@ mutter_public_headers = [
|
||||
'meta-backend.h',
|
||||
'meta-background.h',
|
||||
'meta-background-actor.h',
|
||||
'meta-background-content.h',
|
||||
'meta-background-group.h',
|
||||
'meta-background-image.h',
|
||||
'meta-close-dialog.h',
|
||||
|
@ -47,24 +47,4 @@ META_EXPORT
|
||||
ClutterActor *meta_background_actor_new (MetaDisplay *display,
|
||||
int monitor);
|
||||
|
||||
META_EXPORT
|
||||
void meta_background_actor_set_background (MetaBackgroundActor *self,
|
||||
MetaBackground *background);
|
||||
|
||||
META_EXPORT
|
||||
void meta_background_actor_set_gradient (MetaBackgroundActor *self,
|
||||
gboolean enabled,
|
||||
int height,
|
||||
double tone_start);
|
||||
|
||||
META_EXPORT
|
||||
void meta_background_actor_set_monitor (MetaBackgroundActor *self,
|
||||
int monitor);
|
||||
|
||||
META_EXPORT
|
||||
void meta_background_actor_set_vignette (MetaBackgroundActor *self,
|
||||
gboolean enabled,
|
||||
double brightness,
|
||||
double sharpness);
|
||||
|
||||
#endif /* META_BACKGROUND_ACTOR_H */
|
||||
|
66
src/meta/meta-background-content.h
Normal file
66
src/meta/meta-background-content.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* meta-background-content.h: ClutterContent for painting the wallpaper
|
||||
*
|
||||
* Copyright 2010 Red Hat, Inc.
|
||||
* Copyright 2020 Endless Foundation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_BACKGROUND_CONTENT_H
|
||||
#define META_BACKGROUND_CONTENT_H
|
||||
|
||||
#include <gsettings-desktop-schemas/gdesktop-enums.h>
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "meta/meta-background.h"
|
||||
|
||||
/**
|
||||
* MetaBackgroundContent:
|
||||
*
|
||||
* This class handles tracking and painting the root window background.
|
||||
* By integrating with #MetaWindowGroup we can avoid painting parts of
|
||||
* the background that are obscured by other windows.
|
||||
*/
|
||||
|
||||
#define META_TYPE_BACKGROUND_CONTENT (meta_background_content_get_type ())
|
||||
|
||||
META_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (MetaBackgroundContent,
|
||||
meta_background_content,
|
||||
META, BACKGROUND_CONTENT,
|
||||
GObject)
|
||||
|
||||
|
||||
META_EXPORT
|
||||
ClutterContent *meta_background_content_new (MetaDisplay *display,
|
||||
int monitor);
|
||||
|
||||
META_EXPORT
|
||||
void meta_background_content_set_background (MetaBackgroundContent *self,
|
||||
MetaBackground *background);
|
||||
|
||||
META_EXPORT
|
||||
void meta_background_content_set_gradient (MetaBackgroundContent *self,
|
||||
gboolean enabled,
|
||||
int height,
|
||||
double tone_start);
|
||||
|
||||
META_EXPORT
|
||||
void meta_background_content_set_vignette (MetaBackgroundContent *self,
|
||||
gboolean enabled,
|
||||
double brightness,
|
||||
double sharpness);
|
||||
|
||||
#endif /* META_BACKGROUND_CONTENT_H */
|
@ -5,8 +5,6 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
typedef struct {
|
||||
ClutterActor *stage;
|
||||
|
||||
guint no_display : 1;
|
||||
} ClutterTestEnvironment;
|
||||
|
||||
@ -98,18 +96,9 @@ out:
|
||||
ClutterActor *
|
||||
clutter_test_get_stage (void)
|
||||
{
|
||||
g_assert (test_environ != NULL);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
if (test_environ->stage == NULL)
|
||||
{
|
||||
/* create a stage, and ensure that it goes away at the end */
|
||||
test_environ->stage = clutter_stage_new ();
|
||||
clutter_actor_set_name (test_environ->stage, "Test Stage");
|
||||
g_object_add_weak_pointer (G_OBJECT (test_environ->stage),
|
||||
(gpointer *) &test_environ->stage);
|
||||
}
|
||||
|
||||
return test_environ->stage;
|
||||
return meta_backend_get_stage (backend);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -122,11 +111,13 @@ static void
|
||||
clutter_test_func_wrapper (gconstpointer data_)
|
||||
{
|
||||
const ClutterTestData *data = data_;
|
||||
ClutterActor *stage;
|
||||
|
||||
g_test_log_set_fatal_handler (log_func, NULL);
|
||||
|
||||
/* ensure that the previous test state has been cleaned up */
|
||||
g_assert_null (test_environ->stage);
|
||||
stage = clutter_test_get_stage ();
|
||||
g_assert_false (clutter_actor_is_mapped (stage));
|
||||
|
||||
if (test_environ->no_display)
|
||||
{
|
||||
@ -151,11 +142,8 @@ out:
|
||||
if (data->test_notify != NULL)
|
||||
data->test_notify (data->test_data);
|
||||
|
||||
if (test_environ->stage != NULL)
|
||||
{
|
||||
clutter_actor_destroy (test_environ->stage);
|
||||
g_assert_null (test_environ->stage);
|
||||
}
|
||||
clutter_actor_remove_all_children (stage);
|
||||
clutter_actor_hide (stage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,7 +132,7 @@ check_coords (TestState *state,
|
||||
gint y_2,
|
||||
const graphene_point3d_t *verts)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("checking that (%i,%i,%i,%i) \xe2\x89\x88 (%i,%i,%i,%i): %s\n",
|
||||
x_1, y_1, x_2, y_2,
|
||||
(int) (verts[0].x),
|
||||
@ -200,7 +200,7 @@ test_anchor_point (TestState *state)
|
||||
/* Change the anchor point with each of the gravities */
|
||||
for (i = 0; i < G_N_ELEMENTS (gravities); i++)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
GEnumClass *gravity_class = g_type_class_ref (CLUTTER_TYPE_GRAVITY);
|
||||
GEnumValue *value = g_enum_get_value (gravity_class,
|
||||
@ -356,7 +356,7 @@ test_scale_center (TestState *state)
|
||||
/* Change the anchor point with each of the gravities */
|
||||
for (i = 0; i < G_N_ELEMENTS (gravities); i++)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
GEnumClass *gravity_class = g_type_class_ref (CLUTTER_TYPE_GRAVITY);
|
||||
GEnumValue *value = g_enum_get_value (gravity_class,
|
||||
@ -472,7 +472,7 @@ test_rotate_center (TestState *state)
|
||||
char prop_name[] = "rotation-angle- ";
|
||||
prop_name[sizeof (prop_name) - 2] = i - CLUTTER_X_AXIS + 'x';
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Setting %s to 90 degrees\n", prop_name);
|
||||
|
||||
g_object_set (rect, prop_name, 90.0, NULL);
|
||||
@ -531,7 +531,7 @@ test_rotate_center (TestState *state)
|
||||
char prop_name[] = "rotation-angle- ";
|
||||
prop_name[sizeof (prop_name) - 2] = i - CLUTTER_X_AXIS + 'x';
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Setting %s to 90 degrees with center 10,20,0\n", prop_name);
|
||||
|
||||
clutter_actor_set_rotation (rect, i, 90.0, 10, 20, 0);
|
||||
@ -605,7 +605,7 @@ test_rotate_center (TestState *state)
|
||||
/* Try rotating the z with all of the gravities */
|
||||
for (i = 0; i < G_N_ELEMENTS (gravities); i++)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
GEnumClass *gravity_class = g_type_class_ref (CLUTTER_TYPE_GRAVITY);
|
||||
GEnumValue *value = g_enum_get_value (gravity_class,
|
||||
|
@ -39,7 +39,7 @@ test_destroy_add (ClutterContainer *container,
|
||||
{
|
||||
TestDestroy *self = TEST_DESTROY (container);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Adding '%s' (type:%s)\n",
|
||||
clutter_actor_get_name (actor),
|
||||
G_OBJECT_TYPE_NAME (actor));
|
||||
@ -54,7 +54,7 @@ test_destroy_remove (ClutterContainer *container,
|
||||
{
|
||||
TestDestroy *self = TEST_DESTROY (container);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Removing '%s' (type:%s)\n",
|
||||
clutter_actor_get_name (actor),
|
||||
G_OBJECT_TYPE_NAME (actor));
|
||||
@ -81,7 +81,7 @@ test_destroy_destroy (ClutterActor *self)
|
||||
|
||||
if (test->bg != NULL)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Destroying '%s' (type:%s)\n",
|
||||
clutter_actor_get_name (test->bg),
|
||||
G_OBJECT_TYPE_NAME (test->bg));
|
||||
@ -92,7 +92,7 @@ test_destroy_destroy (ClutterActor *self)
|
||||
|
||||
if (test->label != NULL)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Destroying '%s' (type:%s)\n",
|
||||
clutter_actor_get_name (test->label),
|
||||
G_OBJECT_TYPE_NAME (test->label));
|
||||
@ -174,7 +174,7 @@ actor_destruction (void)
|
||||
g_object_add_weak_pointer (G_OBJECT (test), (gpointer *) &test);
|
||||
g_object_add_weak_pointer (G_OBJECT (child), (gpointer *) &child);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Adding external child...\n");
|
||||
|
||||
clutter_actor_set_name (child, "Child");
|
||||
@ -184,7 +184,7 @@ actor_destruction (void)
|
||||
g_signal_connect (child, "notify", G_CALLBACK (on_notify), &property_changed);
|
||||
g_signal_connect (child, "destroy", G_CALLBACK (on_destroy), &destroy_called);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Calling destroy()...\n");
|
||||
|
||||
clutter_actor_destroy (test);
|
||||
|
@ -408,7 +408,7 @@ actor_added (ClutterContainer *container,
|
||||
int *counter = data;
|
||||
ClutterActor *old_child;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Adding actor '%s'\n", clutter_actor_get_name (child));
|
||||
|
||||
old_child = clutter_actor_get_child_at_index (actor, 0);
|
||||
@ -425,7 +425,7 @@ actor_removed (ClutterContainer *container,
|
||||
{
|
||||
int *counter = data;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Removing actor '%s'\n", clutter_actor_get_name (child));
|
||||
|
||||
*counter += 1;
|
||||
|
@ -15,7 +15,7 @@ actor_initial_state (void)
|
||||
g_object_ref_sink (actor);
|
||||
g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("initial state - visible: %s, realized: %s, mapped: %s\n",
|
||||
CLUTTER_ACTOR_IS_VISIBLE (actor) ? "yes" : "no",
|
||||
CLUTTER_ACTOR_IS_REALIZED (actor) ? "yes" : "no",
|
||||
@ -40,7 +40,7 @@ actor_shown_not_parented (void)
|
||||
|
||||
clutter_actor_show (actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("show without a parent - visible: %s, realized: %s, mapped: %s\n",
|
||||
CLUTTER_ACTOR_IS_VISIBLE (actor) ? "yes" : "no",
|
||||
CLUTTER_ACTOR_IS_REALIZED (actor) ? "yes" : "no",
|
||||
@ -92,7 +92,7 @@ actor_mapped (void)
|
||||
|
||||
clutter_actor_add_child (stage, actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("adding to a container should map - "
|
||||
"visible: %s, realized: %s, mapped: %s\n",
|
||||
CLUTTER_ACTOR_IS_VISIBLE (actor) ? "yes" : "no",
|
||||
@ -105,7 +105,7 @@ actor_mapped (void)
|
||||
|
||||
clutter_actor_hide (actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("hiding should unmap - "
|
||||
"visible: %s, realized: %s, mapped: %s\n",
|
||||
CLUTTER_ACTOR_IS_VISIBLE (actor) ? "yes" : "no",
|
||||
|
@ -40,7 +40,7 @@ actor_iter_traverse_children (void)
|
||||
g_assert (CLUTTER_IS_ACTOR (child));
|
||||
g_assert (clutter_actor_get_parent (child) == actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("actor %d = '%s'\n", i, clutter_actor_get_name (child));
|
||||
|
||||
if (i == 0)
|
||||
@ -63,7 +63,7 @@ actor_iter_traverse_children (void)
|
||||
g_assert (CLUTTER_IS_ACTOR (child));
|
||||
g_assert (clutter_actor_get_parent (child) == actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("actor %d = '%s'\n", i, clutter_actor_get_name (child));
|
||||
|
||||
if (i == 0)
|
||||
@ -115,7 +115,7 @@ actor_iter_traverse_remove (void)
|
||||
g_assert (CLUTTER_IS_ACTOR (child));
|
||||
g_assert (clutter_actor_get_parent (child) == actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("actor %d = '%s'\n", i, clutter_actor_get_name (child));
|
||||
|
||||
if (i == 0)
|
||||
@ -176,7 +176,7 @@ actor_iter_assignment (void)
|
||||
g_assert (CLUTTER_IS_ACTOR (child));
|
||||
g_assert (clutter_actor_get_parent (child) == actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("actor %2d = '%s'\n", i, clutter_actor_get_name (child));
|
||||
|
||||
if (i == 0)
|
||||
@ -196,7 +196,7 @@ actor_iter_assignment (void)
|
||||
{
|
||||
g_assert (clutter_actor_get_parent (child) == actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("actor %2d = '%s'\n", i, clutter_actor_get_name (child));
|
||||
|
||||
if (i == n_actors - 1)
|
||||
|
@ -16,7 +16,7 @@ opacity_label (void)
|
||||
label = clutter_text_new_with_text ("Sans 18px", "Label, 50% opacity");
|
||||
clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("label 50%%.get_color()/1\n");
|
||||
clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
@ -24,16 +24,16 @@ opacity_label (void)
|
||||
clutter_actor_add_child (stage, label);
|
||||
clutter_actor_set_position (label, 10, 10);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("label 50%%.get_color()/2\n");
|
||||
clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("label 50%%.get_paint_opacity()/1\n");
|
||||
g_assert (clutter_actor_get_paint_opacity (label) == 255);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("label 50%%.get_paint_opacity()/2\n");
|
||||
clutter_actor_set_opacity (label, 128);
|
||||
g_assert (clutter_actor_get_paint_opacity (label) == 128);
|
||||
@ -54,19 +54,19 @@ opacity_rectangle (void)
|
||||
clutter_actor_set_size (rect, 128, 128);
|
||||
clutter_actor_set_position (rect, 150, 90);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("rect 100%%.get_color()/1\n");
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
clutter_actor_add_child (stage, rect);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("rect 100%%.get_color()/2\n");
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("rect 100%%.get_paint_opacity()\n");
|
||||
g_assert (clutter_actor_get_paint_opacity (rect) == 255);
|
||||
}
|
||||
@ -93,19 +93,19 @@ opacity_paint (void)
|
||||
label = clutter_text_new_with_text ("Sans 18px", "Label+Group, 25% opacity");
|
||||
clutter_text_set_color (CLUTTER_TEXT (label), &label_color);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("label 50%% + group 50%%.get_color()/1\n");
|
||||
clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (group1), label, NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("label 50%% + group 50%%.get_color()/2\n");
|
||||
clutter_text_get_color (CLUTTER_TEXT (label), &color_check);
|
||||
g_assert (color_check.alpha == label_color.alpha);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("label 50%% + group 50%%.get_paint_opacity() = 128\n");
|
||||
g_assert (clutter_actor_get_paint_opacity (label) == 128);
|
||||
|
||||
@ -118,19 +118,19 @@ opacity_paint (void)
|
||||
rect = clutter_rectangle_new_with_color (&rect_color);
|
||||
clutter_actor_set_size (rect, 128, 128);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("rect 100%% + group 100%% + group 50%%.get_color()/1\n");
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (group2), rect, NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("rect 100%% + group 100%% + group 50%%.get_color()/2\n");
|
||||
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
|
||||
g_assert (color_check.alpha == rect_color.alpha);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("rect 100%%.get_paint_opacity()\n");
|
||||
g_assert (clutter_actor_get_paint_opacity (rect) == 128);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ on_timeout (gpointer data)
|
||||
{
|
||||
if (test_num == 0)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("No covering actor:\n");
|
||||
}
|
||||
if (test_num == 1)
|
||||
@ -62,7 +62,7 @@ on_timeout (gpointer data)
|
||||
clutter_actor_add_child (state->stage, over_actor);
|
||||
clutter_actor_hide (over_actor);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Invisible covering actor:\n");
|
||||
}
|
||||
else if (test_num == 2)
|
||||
@ -84,7 +84,7 @@ on_timeout (gpointer data)
|
||||
*/
|
||||
clutter_actor_allocate (over_actor, &over_actor_box);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Clipped covering actor:\n");
|
||||
}
|
||||
else if (test_num == 3)
|
||||
@ -98,7 +98,7 @@ on_timeout (gpointer data)
|
||||
"blur",
|
||||
clutter_blur_effect_new ());
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("With blur effect:\n");
|
||||
}
|
||||
|
||||
@ -121,13 +121,13 @@ on_timeout (gpointer data)
|
||||
y * state->actor_height
|
||||
+ state->actor_height / 2);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("% 3i,% 3i / %p -> ",
|
||||
x, y, state->actors[y * ACTORS_X + x]);
|
||||
|
||||
if (actor == NULL)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("NULL: FAIL\n");
|
||||
}
|
||||
else if (actor == over_actor)
|
||||
@ -137,7 +137,7 @@ on_timeout (gpointer data)
|
||||
&& y >= 2 && y < ACTORS_Y - 2)
|
||||
pass = TRUE;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("over_actor: %s\n", pass ? "pass" : "FAIL");
|
||||
}
|
||||
else
|
||||
@ -148,7 +148,7 @@ on_timeout (gpointer data)
|
||||
|| y < 2 || y >= ACTORS_Y - 2))
|
||||
pass = TRUE;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("%p: %s\n", actor, pass ? "pass" : "FAIL");
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ actor_pick (void)
|
||||
|
||||
clutter_main ();
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
if (!state.pass)
|
||||
g_test_message ("Failed pass: %s[%d], actor index: %d [%p]\n",
|
||||
|
@ -260,7 +260,7 @@ actor_shader_effect (void)
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
return;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
stage = clutter_test_get_stage ();
|
||||
|
||||
rect = make_actor (foo_old_shader_effect_get_type ());
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
|
||||
|
@ -91,7 +91,7 @@ actor_preferred_size (void)
|
||||
test = g_object_new (TEST_TYPE_ACTOR, NULL);
|
||||
self = (TestActor *) test;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Preferred size\n");
|
||||
|
||||
clutter_actor_get_preferred_size (test,
|
||||
@ -105,7 +105,7 @@ actor_preferred_size (void)
|
||||
g_assert_cmpfloat (nat_width, ==, min_width);
|
||||
g_assert_cmpfloat (nat_height, ==, min_height);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Preferred width\n");
|
||||
self->preferred_width_called = FALSE;
|
||||
clutter_actor_get_preferred_width (test, 10, &min_width, &nat_width);
|
||||
@ -113,7 +113,7 @@ actor_preferred_size (void)
|
||||
g_assert_cmpfloat (min_width, ==, 10);
|
||||
g_assert_cmpfloat (nat_width, ==, 100);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Preferred height\n");
|
||||
self->preferred_height_called = FALSE;
|
||||
clutter_actor_get_preferred_height (test, 200, &min_height, &nat_height);
|
||||
@ -121,7 +121,7 @@ actor_preferred_size (void)
|
||||
g_assert_cmpfloat (min_height, !=, 10);
|
||||
g_assert_cmpfloat (nat_height, ==, 100);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Preferred width (cached)\n");
|
||||
self->preferred_width_called = FALSE;
|
||||
clutter_actor_get_preferred_width (test, 10, &min_width, &nat_width);
|
||||
@ -129,7 +129,7 @@ actor_preferred_size (void)
|
||||
g_assert_cmpfloat (min_width, ==, 10);
|
||||
g_assert_cmpfloat (nat_width, ==, 100);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Preferred height (cache eviction)\n");
|
||||
self->preferred_height_called = FALSE;
|
||||
clutter_actor_get_preferred_height (test, 10, &min_height, &nat_height);
|
||||
@ -152,7 +152,7 @@ actor_fixed_size (void)
|
||||
rect = clutter_actor_new ();
|
||||
g_object_ref_sink (rect);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Initial size is 0\n");
|
||||
|
||||
g_assert_cmpfloat (clutter_actor_get_width (rect), ==, 0);
|
||||
@ -160,7 +160,7 @@ actor_fixed_size (void)
|
||||
|
||||
clutter_actor_set_size (rect, 100, 100);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Explicit size set\n");
|
||||
|
||||
g_assert_cmpfloat (clutter_actor_get_width (rect), ==, 100);
|
||||
@ -173,7 +173,7 @@ actor_fixed_size (void)
|
||||
"natural-height-set", &nat_height_set,
|
||||
NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Notification properties\n");
|
||||
|
||||
g_assert (min_width_set && nat_width_set);
|
||||
@ -183,7 +183,7 @@ actor_fixed_size (void)
|
||||
&min_width, &min_height,
|
||||
&nat_width, &nat_height);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Preferred size\n");
|
||||
|
||||
g_assert_cmpfloat (min_width, ==, 100);
|
||||
@ -193,7 +193,7 @@ actor_fixed_size (void)
|
||||
|
||||
clutter_actor_set_size (rect, -1, -1);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Explicit size unset\n");
|
||||
|
||||
g_object_get (G_OBJECT (rect),
|
||||
|
@ -107,7 +107,7 @@ check_result (CallbackData *data)
|
||||
|
||||
if (g_strcmp0 (expected_text, text) != 0)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("text value differs %s vs %s\n", expected_text, text);
|
||||
fail = TRUE;
|
||||
}
|
||||
@ -116,7 +116,7 @@ check_result (CallbackData *data)
|
||||
expected_char = g_utf8_get_char (g_utf8_offset_to_pointer (text, data->offset));
|
||||
if (expected_char != unichar)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("text af offset differs\n");
|
||||
fail = TRUE;
|
||||
}
|
||||
@ -125,25 +125,25 @@ check_result (CallbackData *data)
|
||||
ATK_XY_WINDOW);
|
||||
if (x != data->extents_x)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("extents x position at index 0 differs (current value=%d)\n", x);
|
||||
fail = TRUE;
|
||||
}
|
||||
if (y != data->extents_y)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("extents y position at index 0 differs (current value=%d)\n", y);
|
||||
fail = TRUE;
|
||||
}
|
||||
if (width != data->extents_width)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("extents width at index 0 differs (current value=%d)\n", width);
|
||||
fail = TRUE;
|
||||
}
|
||||
if (height != data->extents_height)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("extents height at index 0 differs (current value=%d)\n", height);
|
||||
fail = TRUE;
|
||||
}
|
||||
@ -151,7 +151,7 @@ check_result (CallbackData *data)
|
||||
pos = atk_text_get_offset_at_point (cally_text, x, y, ATK_XY_WINDOW);
|
||||
if (pos != data->offset)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("offset at position (%d, %d) differs (current value=%d)\n", x,
|
||||
y, pos);
|
||||
fail = TRUE;
|
||||
@ -161,20 +161,20 @@ check_result (CallbackData *data)
|
||||
&start, &end);
|
||||
if (start != 0)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("run attributes start offset is not 0: %d\n", start);
|
||||
fail = TRUE;
|
||||
}
|
||||
if (end != g_utf8_strlen (text, -1))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("run attributes end offset is not text length: %d\n", end);
|
||||
fail = TRUE;
|
||||
}
|
||||
|
||||
attrs = (GSList*) at_set;
|
||||
fail = compare_lists (attrs, data->run_attributes);
|
||||
if (fail && g_test_verbose ())
|
||||
if (fail && !g_test_quiet ())
|
||||
{
|
||||
g_print ("run attributes mismatch\n");
|
||||
dump_attribute_set (attrs);
|
||||
@ -183,7 +183,7 @@ check_result (CallbackData *data)
|
||||
at_set = atk_text_get_default_attributes (cally_text);
|
||||
attrs = (GSList*) at_set;
|
||||
fail = compare_lists (attrs, data->default_attributes);
|
||||
if (fail && g_test_verbose ())
|
||||
if (fail && !g_test_quiet ())
|
||||
{
|
||||
g_print ("default attributes mismatch\n");
|
||||
dump_attribute_set (attrs);
|
||||
@ -194,11 +194,11 @@ check_result (CallbackData *data)
|
||||
|
||||
if (fail)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("FAIL\n");
|
||||
data->test_failed = TRUE;
|
||||
}
|
||||
else if (g_test_verbose ())
|
||||
else if (!g_test_quiet ())
|
||||
g_print ("pass\n");
|
||||
|
||||
return fail;
|
||||
@ -319,10 +319,10 @@ cally_text (void)
|
||||
|
||||
clutter_actor_destroy (data.stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("\nOverall result: ");
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
if (data.test_failed)
|
||||
g_print ("FAIL\n");
|
||||
|
@ -18,7 +18,7 @@ color_hls_roundtrip (void)
|
||||
g_assert_cmpfloat (hue, ==, 0.0);
|
||||
g_assert (luminance >= 0.0 && luminance <= 1.0);
|
||||
g_assert_cmpfloat (saturation, ==, 0.0);
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("RGB = { %x, %x, %x }, HLS = { %.2f, %.2f, %.2f }\n",
|
||||
color.red,
|
||||
@ -48,7 +48,7 @@ color_hls_roundtrip (void)
|
||||
g_assert (hue >= 0.0 && hue < 360.0);
|
||||
g_assert (luminance >= 0.0 && luminance <= 1.0);
|
||||
g_assert (saturation >= 0.0 && saturation <= 1.0);
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("RGB = { %x, %x, %x }, HLS = { %.2f, %.2f, %.2f }\n",
|
||||
color.red,
|
||||
@ -92,7 +92,7 @@ color_from_string_valid (void)
|
||||
ClutterColor color;
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "#ff0000ff"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 0xff, 0, 0, 0xff }\n",
|
||||
color.red,
|
||||
@ -106,7 +106,7 @@ color_from_string_valid (void)
|
||||
g_assert_cmpuint (color.alpha, ==, 0xff);
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "#0f0f"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 0, 0xff, 0, 0xff }\n",
|
||||
color.red,
|
||||
@ -120,7 +120,7 @@ color_from_string_valid (void)
|
||||
g_assert_cmpuint (color.alpha, ==, 0xff);
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "#0000ff"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 0, 0, 0xff, 0xff }\n",
|
||||
color.red,
|
||||
@ -134,7 +134,7 @@ color_from_string_valid (void)
|
||||
g_assert_cmpuint (color.alpha, ==, 0xff);
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "#abc"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 0xaa, 0xbb, 0xcc, 0xff }\n",
|
||||
color.red,
|
||||
@ -148,7 +148,7 @@ color_from_string_valid (void)
|
||||
g_assert_cmpuint (color.alpha, ==, 0xff);
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "#123abc"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 0x12, 0x3a, 0xbc, 0xff }\n",
|
||||
color.red,
|
||||
@ -162,7 +162,7 @@ color_from_string_valid (void)
|
||||
g_assert (color.alpha == 0xff);
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "rgb(255, 128, 64)"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 255, 128, 64, 255 }\n",
|
||||
color.red,
|
||||
@ -176,7 +176,7 @@ color_from_string_valid (void)
|
||||
g_assert_cmpuint (color.alpha, ==, 255);
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "rgba ( 30%, 0, 25%, 0.5 ) "));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { %.1f, 0, %.1f, 128 }\n",
|
||||
color.red,
|
||||
@ -192,7 +192,7 @@ color_from_string_valid (void)
|
||||
g_assert_cmpuint (color.alpha, ==, 127);
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "rgb( 50%, -50%, 150% )"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 127, 0, 255, 255 }\n",
|
||||
color.red,
|
||||
@ -206,7 +206,7 @@ color_from_string_valid (void)
|
||||
g_assert_cmpuint (color.alpha, ==, 255);
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "hsl( 0, 100%, 50% )"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 255, 0, 0, 255 }\n",
|
||||
color.red,
|
||||
@ -222,7 +222,7 @@ color_from_string_valid (void)
|
||||
g_assert (clutter_color_from_string (&color, "hsl( 0, 100%, 50% )"));
|
||||
|
||||
g_assert (clutter_color_from_string (&color, "hsla( 0, 100%, 50%, 0.5 )"));
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
g_print ("color = { %x, %x, %x, %x }, expected = { 255, 0, 0, 127 }\n",
|
||||
color.red,
|
||||
@ -274,7 +274,7 @@ color_operators (void)
|
||||
g_assert_cmpuint (op2.blue, ==, 0);
|
||||
g_assert_cmpuint (op2.alpha, ==, 0xff);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Adding %x, %x; expected result: %x\n",
|
||||
clutter_color_to_pixel (&op1),
|
||||
clutter_color_to_pixel (&op2),
|
||||
@ -283,7 +283,7 @@ color_operators (void)
|
||||
clutter_color_add (&op1, &op2, &res);
|
||||
g_assert_cmpuint (clutter_color_to_pixel (&res), ==, 0xffff00ff);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Checking alpha channel on color add\n");
|
||||
|
||||
op1.alpha = 0xdd;
|
||||
@ -294,7 +294,7 @@ color_operators (void)
|
||||
clutter_color_from_pixel (&op1, 0xffffffff);
|
||||
clutter_color_from_pixel (&op2, 0xff00ffff);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Subtracting %x, %x; expected result: %x\n",
|
||||
clutter_color_to_pixel (&op1),
|
||||
clutter_color_to_pixel (&op2),
|
||||
@ -303,7 +303,7 @@ color_operators (void)
|
||||
clutter_color_subtract (&op1, &op2, &res);
|
||||
g_assert_cmpuint (clutter_color_to_pixel (&res), ==, 0x00ff00ff);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Checking alpha channel on color subtract\n");
|
||||
|
||||
op1.alpha = 0xdd;
|
||||
|
@ -81,21 +81,21 @@ interval_from_script (void)
|
||||
"test-script-interval.json",
|
||||
NULL);
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
if (!g_test_quiet () && error)
|
||||
g_printerr ("\tError: %s", error->message);
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
||||
interval = CLUTTER_INTERVAL (clutter_script_get_object (script, "int-1"));
|
||||
initial = clutter_interval_peek_initial_value (interval);
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_test_message ("\tinitial ['%s'] = '%.2f'",
|
||||
g_type_name (G_VALUE_TYPE (initial)),
|
||||
g_value_get_float (initial));
|
||||
g_assert (G_VALUE_HOLDS (initial, G_TYPE_FLOAT));
|
||||
g_assert_cmpfloat (g_value_get_float (initial), ==, 23.3f);
|
||||
final = clutter_interval_peek_final_value (interval);
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_test_message ("\tfinal ['%s'] = '%.2f'",
|
||||
g_type_name (G_VALUE_TYPE (final)),
|
||||
g_value_get_float (final));
|
||||
|
@ -33,6 +33,10 @@ clutter_conform_tests_general_tests = [
|
||||
'color',
|
||||
'interval',
|
||||
'script-parser',
|
||||
'timeline',
|
||||
'timeline-interpolate',
|
||||
'timeline-progress',
|
||||
'timeline-rewind',
|
||||
'units',
|
||||
]
|
||||
|
||||
@ -73,6 +77,7 @@ foreach test : clutter_conform_tests
|
||||
|
||||
test(test, test_executable,
|
||||
suite: ['clutter', 'clutter/conform'],
|
||||
env: test_env
|
||||
env: test_env,
|
||||
is_parallel: false,
|
||||
)
|
||||
endforeach
|
||||
|
@ -556,7 +556,7 @@ path_test_get_length (CallbackData *data)
|
||||
|
||||
if (!(fabs (approx_length - 46340.f) / 46340.f <= 0.15f))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("M 0 0 L 46340 0 - Expected 46340, got %d instead.", approx_length);
|
||||
|
||||
return FALSE;
|
||||
@ -567,7 +567,7 @@ path_test_get_length (CallbackData *data)
|
||||
|
||||
if (!(fabs (approx_length - 46341.f) / 46341.f <= 0.15f))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("M 0 0 L 46341 0 - Expected 46341, got %d instead.", approx_length);
|
||||
|
||||
return FALSE;
|
||||
@ -580,7 +580,7 @@ path_test_get_length (CallbackData *data)
|
||||
/* Allow 15% margin of error */
|
||||
if (!(fabs (approx_length - actual_length) / (float) actual_length <= 0.15f))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Expected %g, got %d instead.\n", actual_length, approx_length);
|
||||
|
||||
return FALSE;
|
||||
@ -724,12 +724,12 @@ path_base (TestConformSimpleFixture *fixture,
|
||||
{
|
||||
gboolean succeeded;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("%s... ", path_tests[i].desc);
|
||||
|
||||
succeeded = path_tests[i].func (&data) && compare_nodes (&data);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("%s\n", succeeded ? "ok" : "FAIL");
|
||||
|
||||
g_assert (succeeded);
|
||||
|
@ -131,7 +131,7 @@ script_child (void)
|
||||
|
||||
test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-child.json", NULL);
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
if (!g_test_quiet () && error)
|
||||
g_print ("Error: %s", error->message);
|
||||
|
||||
g_assert_no_error (error);
|
||||
@ -177,7 +177,7 @@ script_single (void)
|
||||
|
||||
test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-single.json", NULL);
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
if (!g_test_quiet () && error)
|
||||
g_print ("Error: %s", error->message);
|
||||
|
||||
g_assert_no_error (error);
|
||||
@ -209,7 +209,7 @@ script_object_property (void)
|
||||
|
||||
test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-object-property.json", NULL);
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
if (!g_test_quiet () && error)
|
||||
g_print ("Error: %s", error->message);
|
||||
|
||||
g_assert_no_error (error);
|
||||
@ -235,7 +235,7 @@ script_named_object (void)
|
||||
|
||||
test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-named-object.json", NULL);
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
if (!g_test_quiet () && error)
|
||||
g_print ("Error: %s", error->message);
|
||||
|
||||
g_assert_no_error (error);
|
||||
@ -261,7 +261,7 @@ script_margin (void)
|
||||
|
||||
test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-margin.json", NULL);
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
if (!g_test_quiet () && error)
|
||||
g_print ("Error: %s", error->message);
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
@ -68,7 +68,7 @@ check_result (CallbackData *data, const char *note,
|
||||
PangoRectangle test_extents;
|
||||
gboolean fail = FALSE;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("%s: ", note);
|
||||
|
||||
/* Force a redraw to get the on_paint handler to run */
|
||||
@ -79,7 +79,7 @@ check_result (CallbackData *data, const char *note,
|
||||
pango_layout_get_extents (data->test_layout, NULL, &test_extents);
|
||||
if (memcmp (&test_extents, &data->label_extents, sizeof (PangoRectangle)))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("extents are different: expected: %d, %d, %d, %d "
|
||||
"-> text: %d, %d, %d, %d\n",
|
||||
test_extents.x / 1024,
|
||||
@ -95,18 +95,18 @@ check_result (CallbackData *data, const char *note,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("extents are the same, ");
|
||||
}
|
||||
|
||||
if (data->layout_changed)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("layout changed, ");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("layout did not change, ");
|
||||
}
|
||||
|
||||
@ -115,14 +115,14 @@ check_result (CallbackData *data, const char *note,
|
||||
|
||||
if (fail)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("FAIL\n");
|
||||
|
||||
data->test_failed = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("pass\n");
|
||||
}
|
||||
|
||||
@ -283,10 +283,10 @@ text_cache (void)
|
||||
|
||||
clutter_actor_destroy (data.stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("\nOverall result: ");
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
{
|
||||
if (data.test_failed)
|
||||
g_print ("FAIL\n");
|
||||
|
@ -214,12 +214,12 @@ text_delete_chars (void)
|
||||
for (j = 0; j < 4; j++)
|
||||
clutter_text_insert_unichar (text, t->unichar);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("text: %s\n", clutter_text_get_text (text));
|
||||
|
||||
clutter_text_set_cursor_position (text, 2);
|
||||
clutter_text_delete_chars (text, 1);
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("text: %s (cursor at: %d)\n",
|
||||
clutter_text_get_text (text),
|
||||
clutter_text_get_cursor_position (text));
|
||||
@ -229,7 +229,7 @@ text_delete_chars (void)
|
||||
|
||||
clutter_text_set_cursor_position (text, 2);
|
||||
clutter_text_delete_chars (text, 1);
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("text: %s (cursor at: %d)\n",
|
||||
clutter_text_get_text (text),
|
||||
clutter_text_get_cursor_position (text));
|
||||
@ -503,7 +503,7 @@ text_idempotent_use_markup (void)
|
||||
int bar_end_index = bar_start_index + strlen ("bar");
|
||||
|
||||
/* case 1: text -> use_markup */
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("text: '%s' -> use-markup: TRUE\n", contents);
|
||||
|
||||
text = g_object_new (CLUTTER_TYPE_TEXT,
|
||||
@ -511,7 +511,7 @@ text_idempotent_use_markup (void)
|
||||
NULL);
|
||||
g_object_ref_sink (text);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Contents: '%s' (expected: '%s')\n",
|
||||
clutter_text_get_text (text),
|
||||
display);
|
||||
@ -526,14 +526,14 @@ text_idempotent_use_markup (void)
|
||||
clutter_actor_destroy (CLUTTER_ACTOR (text));
|
||||
|
||||
/* case 2: use_markup -> text */
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("use-markup: TRUE -> text: '%s'\n", contents);
|
||||
|
||||
text = g_object_new (CLUTTER_TYPE_TEXT,
|
||||
"use-markup", TRUE, "text", contents,
|
||||
NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Contents: '%s' (expected: '%s')\n",
|
||||
clutter_text_get_text (text),
|
||||
display);
|
||||
|
@ -116,24 +116,24 @@ validate_result (TestState *state)
|
||||
{
|
||||
int ypos = 0;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Testing onscreen clone...\n");
|
||||
validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, 0);
|
||||
ypos++;
|
||||
|
||||
#if 0 /* this doesn't work */
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Testing offscreen clone...\n");
|
||||
validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, 0);
|
||||
#endif
|
||||
ypos++;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Testing onscreen clone with rectangular clip...\n");
|
||||
validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, ~1);
|
||||
ypos++;
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Testing onscreen clone with path clip...\n");
|
||||
validate_part (state, SOURCE_SIZE, ypos * SOURCE_SIZE, 1);
|
||||
ypos++;
|
||||
|
@ -1,8 +1,9 @@
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
#include "tests/clutter-test-utils.h"
|
||||
|
||||
/* We ask for 1 frame per millisecond.
|
||||
* Whenever this rate can't be achieved then the timeline
|
||||
@ -12,8 +13,13 @@
|
||||
#define TEST_TIMELINE_DURATION 5000
|
||||
|
||||
/* We are at the mercy of the system scheduler so this
|
||||
* may not be a very reliable tolerance. */
|
||||
#define TEST_ERROR_TOLERANCE 20
|
||||
* may not be a very reliable tolerance.
|
||||
*
|
||||
* It's set as very tolerable (1 ms shorter than the frame interval) as
|
||||
* otherwise CI, which are very prone to not get CPU time scheduled, tend to
|
||||
* often fail.
|
||||
*/
|
||||
#define TEST_ERROR_TOLERANCE ((TEST_TIMELINE_FPS / 4) - 1)
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
@ -118,26 +124,23 @@ completed_cb (ClutterTimeline *timeline,
|
||||
if (state->completion_count == 2)
|
||||
{
|
||||
if (state->passed)
|
||||
{
|
||||
g_test_message ("Passed\n");
|
||||
clutter_main_quit ();
|
||||
}
|
||||
clutter_main_quit ();
|
||||
else
|
||||
{
|
||||
g_test_message ("Failed\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
timeline_interpolation (void)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
TestState state;
|
||||
|
||||
stage = clutter_test_get_stage ();
|
||||
|
||||
state.timeline =
|
||||
clutter_timeline_new (TEST_TIMELINE_DURATION);
|
||||
clutter_timeline_set_loop (state.timeline, TRUE);
|
||||
clutter_timeline_set_repeat_count (state.timeline, -1);
|
||||
g_signal_connect (G_OBJECT(state.timeline),
|
||||
"new-frame",
|
||||
G_CALLBACK(new_frame_cb),
|
||||
@ -152,6 +155,8 @@ timeline_interpolation (void)
|
||||
state.passed = TRUE;
|
||||
state.expected_frame = 0;
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
state.start_time = g_get_real_time ();
|
||||
clutter_timeline_start (state.timeline);
|
||||
|
||||
@ -159,3 +164,7 @@ timeline_interpolation (void)
|
||||
|
||||
g_object_unref (state.timeline);
|
||||
}
|
||||
|
||||
CLUTTER_TEST_SUITE (
|
||||
CLUTTER_TEST_UNIT ("/timeline/interpolate", timeline_interpolation)
|
||||
)
|
||||
|
@ -1,16 +1,17 @@
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#include <glib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "test-conform-common.h"
|
||||
|
||||
void
|
||||
timeline_progress_step (TestConformSimpleFixture *fixture G_GNUC_UNUSED,
|
||||
gconstpointer dummy G_GNUC_UNUSED)
|
||||
#include "tests/clutter-test-utils.h"
|
||||
|
||||
static void
|
||||
timeline_progress_step (void)
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
|
||||
timeline = clutter_timeline_new (1000);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("mode: step(3, end)\n");
|
||||
|
||||
clutter_timeline_rewind (timeline);
|
||||
@ -45,7 +46,7 @@ timeline_progress_step (TestConformSimpleFixture *fixture G_GNUC_UNUSED,
|
||||
clutter_timeline_advance (timeline, 1000);
|
||||
g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("mode: step-start\n");
|
||||
|
||||
clutter_timeline_rewind (timeline);
|
||||
@ -64,7 +65,7 @@ timeline_progress_step (TestConformSimpleFixture *fixture G_GNUC_UNUSED,
|
||||
clutter_timeline_advance (timeline, 1000);
|
||||
g_assert_cmpfloat (clutter_timeline_get_progress (timeline), ==, 1.0);
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("mode: step-end\n");
|
||||
|
||||
clutter_timeline_rewind (timeline);
|
||||
@ -86,9 +87,8 @@ timeline_progress_step (TestConformSimpleFixture *fixture G_GNUC_UNUSED,
|
||||
g_object_unref (timeline);
|
||||
}
|
||||
|
||||
void
|
||||
timeline_progress_mode (TestConformSimpleFixture *fixture G_GNUC_UNUSED,
|
||||
gconstpointer dummy G_GNUC_UNUSED)
|
||||
static void
|
||||
timeline_progress_mode (void)
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
|
||||
@ -108,3 +108,8 @@ timeline_progress_mode (TestConformSimpleFixture *fixture G_GNUC_UNUSED,
|
||||
|
||||
g_object_unref (timeline);
|
||||
}
|
||||
|
||||
CLUTTER_TEST_SUITE (
|
||||
CLUTTER_TEST_UNIT ("/timeline/progress/step", timeline_progress_step);
|
||||
CLUTTER_TEST_UNIT ("/timeline/progress/mode", timeline_progress_mode)
|
||||
)
|
||||
|
@ -1,8 +1,9 @@
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
#include "tests/clutter-test-utils.h"
|
||||
|
||||
#define TEST_TIMELINE_DURATION 500
|
||||
#define TEST_WATCHDOG_KICK_IN_SECONDS 10
|
||||
@ -66,11 +67,14 @@ new_frame_cb (ClutterTimeline *timeline,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
timeline_rewind (void)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
TestState state;
|
||||
|
||||
stage = clutter_test_get_stage ();
|
||||
|
||||
state.timeline =
|
||||
clutter_timeline_new (TEST_TIMELINE_DURATION);
|
||||
g_signal_connect (G_OBJECT(state.timeline),
|
||||
@ -84,9 +88,15 @@ timeline_rewind (void)
|
||||
&state);
|
||||
state.rewind_count = 0;
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_timeline_start (state.timeline);
|
||||
|
||||
clutter_main();
|
||||
|
||||
g_object_unref (state.timeline);
|
||||
}
|
||||
|
||||
CLUTTER_TEST_SUITE (
|
||||
CLUTTER_TEST_UNIT ("/timeline/rewind", timeline_rewind)
|
||||
)
|
||||
|
@ -1,11 +1,12 @@
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
#include "tests/clutter-test-utils.h"
|
||||
|
||||
/* This test runs three timelines at 30 fps with 10 frames. Some of
|
||||
/* This test runs three timelines at 6 fps with 10 frames. Some of
|
||||
the timelines have markers. Once the timelines are run it then
|
||||
checks that all of the frames were hit, all of the markers were hit
|
||||
and that the completed signal was fired. The timelines are then run
|
||||
@ -15,7 +16,7 @@
|
||||
for. */
|
||||
|
||||
#define FRAME_COUNT 10
|
||||
#define FPS 30
|
||||
#define FPS 6
|
||||
|
||||
typedef struct _TimelineData TimelineData;
|
||||
|
||||
@ -45,7 +46,7 @@ static void
|
||||
timeline_complete_cb (ClutterTimeline *timeline,
|
||||
TimelineData *data)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("%i: Completed\n", data->timeline_num);
|
||||
|
||||
data->completed_count++;
|
||||
@ -61,7 +62,7 @@ timeline_new_frame_cb (ClutterTimeline *timeline,
|
||||
int frame_no = ((msec * FRAME_COUNT + (FRAME_COUNT * 1000 / FPS) / 2)
|
||||
/ (FRAME_COUNT * 1000 / FPS));
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("%i: Doing frame %d, delta = %i\n",
|
||||
data->timeline_num, frame_no,
|
||||
clutter_timeline_get_delta (timeline));
|
||||
@ -77,7 +78,7 @@ timeline_marker_reached_cb (ClutterTimeline *timeline,
|
||||
guint frame_num,
|
||||
TimelineData *data)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("%i: Marker '%s' (%d) reached, delta = %i\n",
|
||||
data->timeline_num, marker_name, frame_num,
|
||||
clutter_timeline_get_delta (timeline));
|
||||
@ -117,7 +118,7 @@ check_timeline (ClutterTimeline *timeline,
|
||||
marker_reached_count[i]++;
|
||||
else
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("FAIL: unknown marker '%s' hit for timeline %i\n",
|
||||
(char *) node->data, data->timeline_num);
|
||||
succeeded = FALSE;
|
||||
@ -127,7 +128,7 @@ check_timeline (ClutterTimeline *timeline,
|
||||
for (i = 0; i < n_markers; i++)
|
||||
if (marker_reached_count[i] != 1)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("FAIL: marker '%s' hit %i times for timeline %i\n",
|
||||
markers[i], marker_reached_count[i], data->timeline_num);
|
||||
succeeded = FALSE;
|
||||
@ -141,7 +142,7 @@ check_timeline (ClutterTimeline *timeline,
|
||||
|
||||
if (missed_frame_count)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("FAIL: missed %i frame%s for timeline %i\n",
|
||||
missed_frame_count, missed_frame_count == 1 ? "" : "s",
|
||||
data->timeline_num);
|
||||
@ -151,7 +152,7 @@ check_timeline (ClutterTimeline *timeline,
|
||||
|
||||
if (data->completed_count != 1)
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("FAIL: timeline %i completed %i times\n",
|
||||
data->timeline_num, data->completed_count);
|
||||
succeeded = FALSE;
|
||||
@ -180,10 +181,10 @@ delay_cb (gpointer data)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
timeline_base (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
static void
|
||||
timeline_base (void)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterTimeline *timeline_1;
|
||||
TimelineData data_1;
|
||||
ClutterTimeline *timeline_2;
|
||||
@ -194,9 +195,7 @@ timeline_base (TestConformSimpleFixture *fixture,
|
||||
gsize n_markers;
|
||||
guint delay_tag;
|
||||
|
||||
/* NB: We have to ensure a stage is instantiated else the master
|
||||
* clock wont run... */
|
||||
ClutterActor *stage = clutter_stage_new ();
|
||||
stage = clutter_test_get_stage ();
|
||||
|
||||
timeline_data_init (&data_1, 1);
|
||||
timeline_1 = clutter_timeline_new (FRAME_COUNT * 1000 / FPS);
|
||||
@ -216,7 +215,7 @@ timeline_base (TestConformSimpleFixture *fixture,
|
||||
g_strfreev (markers);
|
||||
|
||||
timeline_data_init (&data_2, 2);
|
||||
timeline_2 = clutter_timeline_clone (timeline_1);
|
||||
timeline_2 = clutter_timeline_new (FRAME_COUNT * 1000 / FPS);
|
||||
clutter_timeline_add_marker_at_time (timeline_2, "bar", 2 * 1000 / FPS);
|
||||
markers = clutter_timeline_list_markers (timeline_2, -1, &n_markers);
|
||||
g_assert (markers != NULL);
|
||||
@ -225,7 +224,7 @@ timeline_base (TestConformSimpleFixture *fixture,
|
||||
g_strfreev (markers);
|
||||
|
||||
timeline_data_init (&data_3, 3);
|
||||
timeline_3 = clutter_timeline_clone (timeline_1);
|
||||
timeline_3 = clutter_timeline_new (FRAME_COUNT * 1000 / FPS);
|
||||
clutter_timeline_set_direction (timeline_3, CLUTTER_TIMELINE_BACKWARD);
|
||||
clutter_timeline_add_marker_at_time (timeline_3, "start-marker",
|
||||
FRAME_COUNT * 1000 / FPS);
|
||||
@ -267,7 +266,9 @@ timeline_base (TestConformSimpleFixture *fixture,
|
||||
"completed", G_CALLBACK (timeline_complete_cb),
|
||||
&data_3);
|
||||
|
||||
if (g_test_verbose ())
|
||||
clutter_actor_show (stage);
|
||||
|
||||
if (!g_test_quiet ())
|
||||
g_print ("Without delay...\n");
|
||||
|
||||
clutter_timeline_start (timeline_1);
|
||||
@ -282,7 +283,7 @@ timeline_base (TestConformSimpleFixture *fixture,
|
||||
g_assert (check_timeline (timeline_2, &data_2, TRUE));
|
||||
g_assert (check_timeline (timeline_3, &data_3, TRUE));
|
||||
|
||||
if (g_test_verbose ())
|
||||
if (!g_test_quiet ())
|
||||
g_print ("With delay...\n");
|
||||
|
||||
timeline_data_destroy (&data_1);
|
||||
@ -314,13 +315,10 @@ timeline_base (TestConformSimpleFixture *fixture,
|
||||
timeline_data_destroy (&data_3);
|
||||
|
||||
g_clear_handle_id (&delay_tag, g_source_remove);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
}
|
||||
|
||||
void
|
||||
timeline_markers_from_script (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
static void
|
||||
timeline_markers_from_script (void)
|
||||
{
|
||||
ClutterScript *script = clutter_script_new ();
|
||||
ClutterTimeline *timeline;
|
||||
@ -329,9 +327,12 @@ timeline_markers_from_script (TestConformSimpleFixture *fixture,
|
||||
gchar **markers;
|
||||
gsize n_markers;
|
||||
|
||||
test_file = clutter_test_get_data_file ("test-script-timeline-markers.json");
|
||||
test_file = g_test_build_filename (G_TEST_DIST,
|
||||
"scripts",
|
||||
"test-script-timeline-markers.json",
|
||||
NULL);
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error != NULL)
|
||||
if (!g_test_quiet () && error != NULL)
|
||||
g_print ("Error: %s", error->message);
|
||||
|
||||
g_assert_no_error (error);
|
||||
@ -351,11 +352,16 @@ timeline_markers_from_script (TestConformSimpleFixture *fixture,
|
||||
markers = clutter_timeline_list_markers (timeline, 500, &n_markers);
|
||||
g_assert_cmpint (n_markers, ==, 2);
|
||||
g_assert (markers != NULL);
|
||||
g_assert_cmpstr (markers[0], ==, "marker3");
|
||||
g_assert_cmpstr (markers[1], ==, "marker1");
|
||||
g_assert (g_strv_contains ((const char * const *) markers, "marker1"));
|
||||
g_assert (g_strv_contains ((const char * const *) markers, "marker3"));
|
||||
g_strfreev (markers);
|
||||
|
||||
g_object_unref (script);
|
||||
|
||||
g_free (test_file);
|
||||
}
|
||||
|
||||
CLUTTER_TEST_SUITE (
|
||||
CLUTTER_TEST_UNIT ("/timeline/base", timeline_base);
|
||||
CLUTTER_TEST_UNIT ("/timeline/markers-from-script", timeline_markers_from_script)
|
||||
)
|
||||
|
@ -410,7 +410,7 @@ test_cogl_tex_polygon_main (int argc, char *argv[])
|
||||
|
||||
/* Timeline for animation */
|
||||
timeline = clutter_timeline_new (6000);
|
||||
clutter_timeline_set_loop (timeline, TRUE);
|
||||
clutter_timeline_set_repeat_count (timeline, -1);
|
||||
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), coglbox);
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
|
@ -216,7 +216,7 @@ test_cogl_tex_tile_main (int argc, char *argv[])
|
||||
|
||||
/* Timeline for animation */
|
||||
timeline = clutter_timeline_new (6000); /* 6 second duration */
|
||||
clutter_timeline_set_loop (timeline, TRUE);
|
||||
clutter_timeline_set_repeat_count (timeline, -1);
|
||||
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), coglbox);
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
|
@ -123,6 +123,27 @@ headless_start_test = executable('mutter-headless-start-test',
|
||||
install_dir: mutter_installed_tests_libexecdir,
|
||||
)
|
||||
|
||||
stage_view_tests = executable('mutter-stage-view-tests',
|
||||
sources: [
|
||||
'meta-backend-test.c',
|
||||
'meta-backend-test.h',
|
||||
'meta-gpu-test.c',
|
||||
'meta-gpu-test.h',
|
||||
'meta-monitor-manager-test.c',
|
||||
'meta-monitor-manager-test.h',
|
||||
'monitor-test-utils.c',
|
||||
'monitor-test-utils.h',
|
||||
'stage-view-tests.c',
|
||||
'test-utils.c',
|
||||
'test-utils.h',
|
||||
],
|
||||
include_directories: tests_includepath,
|
||||
c_args: tests_c_args,
|
||||
dependencies: [tests_deps],
|
||||
install: have_installed_tests,
|
||||
install_dir: mutter_installed_tests_libexecdir,
|
||||
)
|
||||
|
||||
stacking_tests = [
|
||||
'basic-x11',
|
||||
'basic-wayland',
|
||||
@ -173,3 +194,10 @@ test('headless-start', headless_start_test,
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
|
||||
test('stage-view', stage_view_tests,
|
||||
suite: ['core', 'mutter/unit'],
|
||||
env: test_env,
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
|
@ -16,11 +16,11 @@ wait_reconfigure
|
||||
assert_position x/1 100 100
|
||||
|
||||
tile x/1 left
|
||||
wait
|
||||
wait_reconfigure
|
||||
assert_position x/1 0 0
|
||||
|
||||
untile x/1
|
||||
wait
|
||||
wait_reconfigure
|
||||
assert_position x/1 100 100
|
||||
|
||||
tile x/1 left
|
||||
@ -57,11 +57,11 @@ wait_reconfigure
|
||||
assert_position w/1 0 0
|
||||
|
||||
untile w/1
|
||||
wait
|
||||
wait_reconfigure
|
||||
assert_position w/1 100 100
|
||||
|
||||
tile w/1 left
|
||||
wait
|
||||
wait_reconfigure
|
||||
assert_position w/1 0 0
|
||||
|
||||
maximize w/1
|
||||
|
504
src/tests/stage-view-tests.c
Normal file
504
src/tests/stage-view-tests.c
Normal file
@ -0,0 +1,504 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Jonas Dreßler
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "compositor/meta-plugin-manager.h"
|
||||
#include "core/main-private.h"
|
||||
#include "meta/main.h"
|
||||
#include "tests/meta-backend-test.h"
|
||||
#include "tests/monitor-test-utils.h"
|
||||
#include "tests/test-utils.h"
|
||||
|
||||
#define FRAME_WARNING "Frame has assigned frame counter but no frame drawn time"
|
||||
|
||||
static gboolean
|
||||
run_tests (gpointer data)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaSettings *settings = meta_backend_get_settings (backend);
|
||||
gboolean ret;
|
||||
|
||||
g_test_log_set_fatal_handler (NULL, NULL);
|
||||
|
||||
meta_settings_override_experimental_features (settings);
|
||||
|
||||
meta_settings_enable_experimental_feature (
|
||||
settings,
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
|
||||
|
||||
ret = g_test_run ();
|
||||
|
||||
meta_quit (ret != 0);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ignore_frame_counter_warning (const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
if ((log_level & G_LOG_LEVEL_WARNING) &&
|
||||
g_strcmp0 (log_domain, "mutter") == 0 &&
|
||||
g_str_has_suffix (message, FRAME_WARNING))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MonitorTestCaseSetup initial_test_case_setup = {
|
||||
.modes = {
|
||||
{
|
||||
.width = 1024,
|
||||
.height = 768,
|
||||
.refresh_rate = 60.0
|
||||
}
|
||||
},
|
||||
.n_modes = 1,
|
||||
.outputs = {
|
||||
{
|
||||
.crtc = 0,
|
||||
.modes = { 0 },
|
||||
.n_modes = 1,
|
||||
.preferred_mode = 0,
|
||||
.possible_crtcs = { 0 },
|
||||
.n_possible_crtcs = 1,
|
||||
.width_mm = 222,
|
||||
.height_mm = 125
|
||||
},
|
||||
{
|
||||
.crtc = 1,
|
||||
.modes = { 0 },
|
||||
.n_modes = 1,
|
||||
.preferred_mode = 0,
|
||||
.possible_crtcs = { 1 },
|
||||
.n_possible_crtcs = 1,
|
||||
.width_mm = 220,
|
||||
.height_mm = 124
|
||||
}
|
||||
},
|
||||
.n_outputs = 2,
|
||||
.crtcs = {
|
||||
{
|
||||
.current_mode = 0
|
||||
},
|
||||
{
|
||||
.current_mode = 0
|
||||
}
|
||||
},
|
||||
.n_crtcs = 2
|
||||
};
|
||||
|
||||
static void
|
||||
meta_test_stage_views_exist (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage;
|
||||
GList *stage_views;
|
||||
|
||||
stage = meta_backend_get_stage (backend);
|
||||
g_assert_cmpint (clutter_actor_get_width (stage), ==, 1024 * 2);
|
||||
g_assert_cmpint (clutter_actor_get_height (stage), ==, 768);
|
||||
|
||||
stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
|
||||
g_assert_cmpint (g_list_length (stage_views), ==, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
on_after_paint (ClutterStage *stage,
|
||||
gboolean *was_painted)
|
||||
{
|
||||
*was_painted = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
wait_for_paint (ClutterActor *stage)
|
||||
{
|
||||
gboolean was_painted = FALSE;
|
||||
gulong was_painted_id;
|
||||
|
||||
was_painted_id = g_signal_connect (CLUTTER_STAGE (stage),
|
||||
"after-paint",
|
||||
G_CALLBACK (on_after_paint),
|
||||
&was_painted);
|
||||
|
||||
while (!was_painted)
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
g_signal_handler_disconnect (stage, was_painted_id);
|
||||
}
|
||||
|
||||
static void
|
||||
on_stage_views_changed (ClutterActor *actor,
|
||||
gboolean *stage_views_changed)
|
||||
{
|
||||
*stage_views_changed = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
is_on_stage_views (ClutterActor *actor,
|
||||
unsigned int n_views,
|
||||
...)
|
||||
{
|
||||
va_list valist;
|
||||
int i = 0;
|
||||
GList *stage_views = clutter_actor_peek_stage_views (actor);
|
||||
|
||||
va_start (valist, n_views);
|
||||
for (i = 0; i < n_views; i++)
|
||||
{
|
||||
ClutterStageView *view = va_arg (valist, ClutterStageView*);
|
||||
g_assert_nonnull (g_list_find (stage_views, view));
|
||||
}
|
||||
|
||||
va_end (valist);
|
||||
g_assert (g_list_length (stage_views) == n_views);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_test_actor_stage_views (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage, *container, *test_actor;
|
||||
GList *stage_views;
|
||||
gboolean stage_views_changed_container = FALSE;
|
||||
gboolean stage_views_changed_test_actor = FALSE;
|
||||
gboolean *stage_views_changed_container_ptr =
|
||||
&stage_views_changed_container;
|
||||
gboolean *stage_views_changed_test_actor_ptr =
|
||||
&stage_views_changed_test_actor;
|
||||
|
||||
stage = meta_backend_get_stage (backend);
|
||||
stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
|
||||
|
||||
container = clutter_actor_new ();
|
||||
clutter_actor_set_size (container, 100, 100);
|
||||
clutter_actor_add_child (stage, container);
|
||||
|
||||
test_actor = clutter_actor_new ();
|
||||
clutter_actor_set_size (test_actor, 50, 50);
|
||||
clutter_actor_add_child (container, test_actor);
|
||||
|
||||
g_signal_connect (container, "stage-views-changed",
|
||||
G_CALLBACK (on_stage_views_changed),
|
||||
stage_views_changed_container_ptr);
|
||||
g_signal_connect (test_actor, "stage-views-changed",
|
||||
G_CALLBACK (on_stage_views_changed),
|
||||
stage_views_changed_test_actor_ptr);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
is_on_stage_views (container, 1, stage_views->data);
|
||||
is_on_stage_views (test_actor, 1, stage_views->data);
|
||||
|
||||
/* The signal was emitted for the initial change */
|
||||
g_assert (stage_views_changed_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
stage_views_changed_container = FALSE;
|
||||
stage_views_changed_test_actor = FALSE;
|
||||
|
||||
/* Move the container to the second stage view */
|
||||
clutter_actor_set_x (container, 1040);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
is_on_stage_views (container, 1, stage_views->next->data);
|
||||
is_on_stage_views (test_actor, 1, stage_views->next->data);
|
||||
|
||||
/* The signal was emitted again */
|
||||
g_assert (stage_views_changed_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
stage_views_changed_container = FALSE;
|
||||
stage_views_changed_test_actor = FALSE;
|
||||
|
||||
/* Move the container so it's on both stage views while the test_actor
|
||||
* is only on the first one.
|
||||
*/
|
||||
clutter_actor_set_x (container, 940);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
is_on_stage_views (container, 2, stage_views->data, stage_views->next->data);
|
||||
is_on_stage_views (test_actor, 1, stage_views->data);
|
||||
|
||||
/* The signal was emitted again */
|
||||
g_assert (stage_views_changed_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (container, on_stage_views_changed,
|
||||
stage_views_changed_container_ptr);
|
||||
g_signal_handlers_disconnect_by_func (test_actor, on_stage_views_changed,
|
||||
stage_views_changed_test_actor_ptr);
|
||||
clutter_actor_destroy (container);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_test_actor_stage_views_reparent (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage, *container, *test_actor;
|
||||
GList *stage_views;
|
||||
gboolean stage_views_changed_container = FALSE;
|
||||
gboolean stage_views_changed_test_actor = FALSE;
|
||||
gboolean *stage_views_changed_container_ptr =
|
||||
&stage_views_changed_container;
|
||||
gboolean *stage_views_changed_test_actor_ptr =
|
||||
&stage_views_changed_test_actor;
|
||||
|
||||
stage = meta_backend_get_stage (backend);
|
||||
stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
|
||||
|
||||
container = clutter_actor_new ();
|
||||
clutter_actor_set_size (container, 100, 100);
|
||||
clutter_actor_set_x (container, 1020);
|
||||
clutter_actor_add_child (stage, container);
|
||||
|
||||
test_actor = clutter_actor_new ();
|
||||
clutter_actor_set_size (test_actor, 20, 20);
|
||||
clutter_actor_add_child (container, test_actor);
|
||||
|
||||
g_signal_connect (container, "stage-views-changed",
|
||||
G_CALLBACK (on_stage_views_changed),
|
||||
stage_views_changed_container_ptr);
|
||||
g_signal_connect (test_actor, "stage-views-changed",
|
||||
G_CALLBACK (on_stage_views_changed),
|
||||
stage_views_changed_test_actor_ptr);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
is_on_stage_views (container, 2, stage_views->data, stage_views->next->data);
|
||||
is_on_stage_views (test_actor, 2, stage_views->data, stage_views->next->data);
|
||||
|
||||
/* The signal was emitted for both actors */
|
||||
g_assert (stage_views_changed_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
stage_views_changed_container = FALSE;
|
||||
stage_views_changed_test_actor = FALSE;
|
||||
|
||||
/* Remove the test_actor from the scene-graph */
|
||||
g_object_ref (test_actor);
|
||||
clutter_actor_remove_child (container, test_actor);
|
||||
|
||||
/* While the test_actor is not on stage, it must be on no stage views */
|
||||
is_on_stage_views (test_actor, 0);
|
||||
|
||||
/* When the test_actor left the stage, the signal was emitted */
|
||||
g_assert (!stage_views_changed_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
stage_views_changed_test_actor = FALSE;
|
||||
|
||||
/* Add the test_actor again as a child of the stage */
|
||||
clutter_actor_add_child (stage, test_actor);
|
||||
g_object_unref (test_actor);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
/* The container is still on both stage views... */
|
||||
is_on_stage_views (container, 2, stage_views->data, stage_views->next->data);
|
||||
|
||||
/* ...while the test_actor is only on the first one now */
|
||||
is_on_stage_views (test_actor, 1, stage_views->data);
|
||||
|
||||
/* The signal was emitted for the test_actor again */
|
||||
g_assert (!stage_views_changed_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
stage_views_changed_test_actor = FALSE;
|
||||
|
||||
/* Move the container out of the stage... */
|
||||
clutter_actor_set_y (container, 2000);
|
||||
g_object_ref (test_actor);
|
||||
clutter_actor_remove_child (stage, test_actor);
|
||||
|
||||
/* When the test_actor left the stage, the signal was emitted */
|
||||
g_assert (!stage_views_changed_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
stage_views_changed_test_actor = FALSE;
|
||||
|
||||
/* ...and reparent the test_actor to the container again */
|
||||
clutter_actor_add_child (container, test_actor);
|
||||
g_object_unref (test_actor);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
/* Now both actors are on no stage views */
|
||||
is_on_stage_views (container, 0);
|
||||
is_on_stage_views (test_actor, 0);
|
||||
|
||||
/* The signal was emitted only for the container, the test_actor already
|
||||
* has no stage-views.
|
||||
*/
|
||||
g_assert (stage_views_changed_container);
|
||||
g_assert (!stage_views_changed_test_actor);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (container, on_stage_views_changed,
|
||||
stage_views_changed_container_ptr);
|
||||
g_signal_handlers_disconnect_by_func (test_actor, on_stage_views_changed,
|
||||
stage_views_changed_test_actor_ptr);
|
||||
clutter_actor_destroy (container);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_test_actor_stage_views_hide_parent (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage, *outer_container, *inner_container, *test_actor;
|
||||
GList *stage_views;
|
||||
gboolean stage_views_changed_outer_container = FALSE;
|
||||
gboolean stage_views_changed_inner_container = FALSE;
|
||||
gboolean stage_views_changed_test_actor = FALSE;
|
||||
gboolean *stage_views_changed_outer_container_ptr =
|
||||
&stage_views_changed_outer_container;
|
||||
gboolean *stage_views_changed_inner_container_ptr =
|
||||
&stage_views_changed_inner_container;
|
||||
gboolean *stage_views_changed_test_actor_ptr =
|
||||
&stage_views_changed_test_actor;
|
||||
|
||||
stage = meta_backend_get_stage (backend);
|
||||
stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
|
||||
|
||||
outer_container = clutter_actor_new ();
|
||||
clutter_actor_add_child (stage, outer_container);
|
||||
|
||||
inner_container = clutter_actor_new ();
|
||||
clutter_actor_add_child (outer_container, inner_container);
|
||||
|
||||
test_actor = clutter_actor_new ();
|
||||
clutter_actor_set_size (test_actor, 20, 20);
|
||||
clutter_actor_add_child (inner_container, test_actor);
|
||||
|
||||
g_signal_connect (outer_container, "stage-views-changed",
|
||||
G_CALLBACK (on_stage_views_changed),
|
||||
stage_views_changed_outer_container_ptr);
|
||||
g_signal_connect (inner_container, "stage-views-changed",
|
||||
G_CALLBACK (on_stage_views_changed),
|
||||
stage_views_changed_inner_container_ptr);
|
||||
g_signal_connect (test_actor, "stage-views-changed",
|
||||
G_CALLBACK (on_stage_views_changed),
|
||||
stage_views_changed_test_actor_ptr);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
/* The containers and the test_actor are on all on the first view */
|
||||
is_on_stage_views (outer_container, 1, stage_views->data);
|
||||
is_on_stage_views (inner_container, 1, stage_views->data);
|
||||
is_on_stage_views (test_actor, 1, stage_views->data);
|
||||
|
||||
/* The signal was emitted for all three */
|
||||
g_assert (stage_views_changed_outer_container);
|
||||
g_assert (stage_views_changed_inner_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
stage_views_changed_outer_container = FALSE;
|
||||
stage_views_changed_inner_container = FALSE;
|
||||
stage_views_changed_test_actor = FALSE;
|
||||
|
||||
/* Hide the inner_container */
|
||||
clutter_actor_hide (inner_container);
|
||||
|
||||
/* Move the outer_container so it's still on the first view */
|
||||
clutter_actor_set_x (outer_container, 1023);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
/* The outer_container is still expanded so it should be on both views */
|
||||
is_on_stage_views (outer_container, 2,
|
||||
stage_views->data, stage_views->next->data);
|
||||
|
||||
/* The inner_container and test_actor aren't updated because they're hidden */
|
||||
is_on_stage_views (inner_container, 1, stage_views->data);
|
||||
is_on_stage_views (test_actor, 1, stage_views->data);
|
||||
|
||||
/* The signal was emitted for the outer_container */
|
||||
g_assert (stage_views_changed_outer_container);
|
||||
g_assert (!stage_views_changed_inner_container);
|
||||
g_assert (!stage_views_changed_test_actor);
|
||||
stage_views_changed_outer_container = FALSE;
|
||||
|
||||
/* Show the inner_container again */
|
||||
clutter_actor_show (inner_container);
|
||||
|
||||
wait_for_paint (stage);
|
||||
|
||||
/* All actors are on both views now */
|
||||
is_on_stage_views (outer_container, 2,
|
||||
stage_views->data, stage_views->next->data);
|
||||
is_on_stage_views (inner_container, 2,
|
||||
stage_views->data, stage_views->next->data);
|
||||
is_on_stage_views (test_actor, 2,
|
||||
stage_views->data, stage_views->next->data);
|
||||
|
||||
/* The signal was emitted for the inner_container and test_actor */
|
||||
g_assert (!stage_views_changed_outer_container);
|
||||
g_assert (stage_views_changed_inner_container);
|
||||
g_assert (stage_views_changed_test_actor);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (outer_container, on_stage_views_changed,
|
||||
stage_views_changed_outer_container_ptr);
|
||||
g_signal_handlers_disconnect_by_func (inner_container, on_stage_views_changed,
|
||||
stage_views_changed_inner_container_ptr);
|
||||
g_signal_handlers_disconnect_by_func (test_actor, on_stage_views_changed,
|
||||
stage_views_changed_test_actor_ptr);
|
||||
clutter_actor_destroy (outer_container);
|
||||
}
|
||||
|
||||
static void
|
||||
init_tests (int argc, char **argv)
|
||||
{
|
||||
MetaMonitorTestSetup *test_setup;
|
||||
|
||||
test_setup = create_monitor_test_setup (&initial_test_case_setup,
|
||||
MONITOR_TEST_FLAG_NO_STORED);
|
||||
|
||||
meta_monitor_manager_test_init_test_setup (test_setup);
|
||||
|
||||
g_test_add_func ("/stage-view/stage-views-exist",
|
||||
meta_test_stage_views_exist);
|
||||
g_test_add_func ("/stage-views/actor-stage-views",
|
||||
meta_test_actor_stage_views);
|
||||
g_test_add_func ("/stage-views/actor-stage-views-reparent",
|
||||
meta_test_actor_stage_views_reparent);
|
||||
g_test_add_func ("/stage-views/actor-stage-views-hide-parent",
|
||||
meta_test_actor_stage_views_hide_parent);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
test_init (&argc, &argv);
|
||||
init_tests (argc, argv);
|
||||
|
||||
meta_plugin_manager_load (test_get_plugin_name ());
|
||||
|
||||
meta_override_compositor_configuration (META_COMPOSITOR_TYPE_WAYLAND,
|
||||
META_TYPE_BACKEND_TEST);
|
||||
|
||||
meta_init ();
|
||||
meta_register_with_session ();
|
||||
|
||||
g_test_log_set_fatal_handler (ignore_frame_counter_warning, NULL);
|
||||
|
||||
g_idle_add (run_tests, NULL);
|
||||
|
||||
return meta_run ();
|
||||
}
|
@ -858,6 +858,8 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
GOptionContext *context = g_option_context_new (NULL);
|
||||
GdkScreen *screen;
|
||||
GtkCssProvider *provider;
|
||||
GError *error = NULL;
|
||||
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
@ -876,31 +878,25 @@ main(int argc, char **argv)
|
||||
|
||||
gtk_init (NULL, NULL);
|
||||
|
||||
if (!wayland)
|
||||
screen = gdk_screen_get_default ();
|
||||
provider = gtk_css_provider_new ();
|
||||
static const char *no_decoration_css =
|
||||
"decoration {"
|
||||
" border-radius: 0 0 0 0;"
|
||||
" border-width: 0;"
|
||||
" box-shadow: 0 0 0 0 rgba(0, 0, 0, 0), 0 0 0 0 rgba(0, 0, 0, 0);"
|
||||
" margin: 0px;"
|
||||
"}";
|
||||
if (!gtk_css_provider_load_from_data (provider,
|
||||
no_decoration_css,
|
||||
strlen (no_decoration_css),
|
||||
&error))
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
screen = gdk_screen_get_default ();
|
||||
provider = gtk_css_provider_new ();
|
||||
static const char *no_decoration_css =
|
||||
"decoration {"
|
||||
" border-radius: 0 0 0 0;"
|
||||
" border-width: 0;"
|
||||
" box-shadow: 0 0 0 0 rgba(0, 0, 0, 0), 0 0 0 0 rgba(0, 0, 0, 0);"
|
||||
" margin: 0px;"
|
||||
"}";
|
||||
if (!gtk_css_provider_load_from_data (provider,
|
||||
no_decoration_css,
|
||||
strlen (no_decoration_css),
|
||||
&error))
|
||||
{
|
||||
g_printerr ("%s", error->message);
|
||||
return 1;
|
||||
}
|
||||
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
g_printerr ("%s", error->message);
|
||||
return 1;
|
||||
}
|
||||
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
windows = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, NULL);
|
||||
|
@ -572,6 +572,9 @@ test_case_do (TestCase *test,
|
||||
if (!test_client_do (client, error, argv[0], window_id, NULL))
|
||||
return FALSE;
|
||||
|
||||
if (!test_case_wait (test, error))
|
||||
return FALSE;
|
||||
|
||||
MetaWindow *window = test_client_find_window (client, window_id, error);
|
||||
if (!window)
|
||||
return FALSE;
|
||||
|
@ -94,7 +94,7 @@ static struct wl_resource *
|
||||
create_and_send_dnd_offer (MetaWaylandDataSource *source,
|
||||
struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||
MetaWaylandDataOffer *offer;
|
||||
struct wl_array *mime_types;
|
||||
struct wl_resource *resource;
|
||||
char **p;
|
||||
|
@ -51,6 +51,7 @@ transfer_cb (MetaSelection *selection,
|
||||
}
|
||||
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -51,6 +51,7 @@ transfer_cb (MetaSelection *selection,
|
||||
}
|
||||
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user