Clutter の Constraint (制約条件)

今回のネタは、 C だと動作しますが、 Gjs だと動作しません。原因が分かる人がいたら教えてください。
Clutter Constraint とは、Clutter の位置などに制約条件をつけることで、他の Actor が変化した時に追随して動かすことができます。
では早速 C のサンプルです。

#include <clutter/clutter.h>

int
main (int argc, char *argv[])
{
	ClutterActor *stage;
	ClutterActor *actor_center, *actor_top;
	ClutterAction *drag;
	
	if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
		return 1;
	stage = clutter_stage_new ();
	g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);

	actor_center = clutter_actor_new ();
	clutter_actor_set_size (actor_center, 30, 30);
	clutter_actor_set_position (actor_center, 100, 100);
	clutter_actor_set_background_color (actor_center,
		clutter_color_get_static (CLUTTER_COLOR_RED));
	clutter_actor_set_reactive (actor_center, TRUE);
	clutter_actor_add_child (stage, actor_center);

	drag = clutter_drag_action_new ();
	clutter_actor_add_action (actor_center,drag);

	actor_top = clutter_actor_new ();
	clutter_actor_set_background_color (actor_top,
		clutter_color_get_static (CLUTTER_COLOR_GREEN));
	clutter_actor_add_child (stage, actor_top);

	clutter_actor_add_constraint (actor_top,
		clutter_snap_constraint_new (stage,
			CLUTTER_SNAP_EDGE_TOP, CLUTTER_SNAP_EDGE_TOP, 10));
	clutter_actor_add_constraint (actor_top,
		clutter_snap_constraint_new (actor_center,
			CLUTTER_SNAP_EDGE_BOTTOM, CLUTTER_SNAP_EDGE_TOP, -10));
	clutter_actor_add_constraint (actor_top,
		clutter_snap_constraint_new (actor_center,
			CLUTTER_SNAP_EDGE_LEFT, CLUTTER_SNAP_EDGE_LEFT, 10));
	clutter_actor_add_constraint (actor_top,
		clutter_snap_constraint_new (actor_center,
			CLUTTER_SNAP_EDGE_RIGHT, CLUTTER_SNAP_EDGE_RIGHT, -10));

	clutter_actor_show (stage);
	clutter_main ();
	return 0;
}

ビルドして実行すると、赤と緑の Actor ができますが、赤は Drag 可能です。赤の Actor を Drag すると、それに併せて緑の Actor も動きます。

	clutter_actor_add_constraint (actor_top,
		clutter_snap_constraint_new (stage,
			CLUTTER_SNAP_EDGE_TOP, CLUTTER_SNAP_EDGE_TOP, 10));

こんなコードが大量にありますが、第一引数の actor に制約条件をつけるものです。制約条件は snap で、 clutter_snap_constraint_new() の第一引数の Actor に snap します。引数の意味は devhelp などでどうぞ。

さて、同じものを Gjs で書きなおすと以下のようになります。

#! /usr/bin/env gjs
const Clutter = imports.gi.Clutter;

Clutter.init (null);
let stage = new Clutter.Stage();
stage.connect('destroy', Clutter.main_quit);

let actor_center = new Clutter.Actor();
actor_center.set_size(30, 30);
actor_center.set_position(100, 100);
actor_center.set_background_color(Clutter.Color.get_static(Clutter.StaticColor.RED));
actor_center.set_reactive(true);
stage.add_child(actor_center);

let drag = new Clutter.DragAction();
actor_center.add_action(drag);

let actor_top = new Clutter.Actor();
actor_top.set_background_color(Clutter.Color.get_static(Clutter.StaticColor.GREEN));
stage.add_child(actor_top);

actor_top.add_constraint(new Clutter.SnapConstraint(stage,
	Clutter.SnapEdge.TOP, Clutter.SnapEdge.TOP, 10));
actor_top.add_constraint(new Clutter.SnapConstraint(actor_center,
	Clutter.SnapEdge.BOTTOM, Clutter.SnapEdge.TOP, -10));
actor_top.add_constraint(new Clutter.SnapConstraint(actor_center,
		Clutter.SnapEdge.LEFT, Clutter.SnapEdge.LEFT, 10));
actor_top.add_constraint(new Clutter.SnapConstraint(actor_center,
		Clutter.SnapEdge.RIGHT, Clutter.SnapEdge.RIGHT, -10));

stage.show();
Clutter.main();

しかし、残念ながら緑の Actor は出現しません。 Gjs の問題なのか、 Clutter の問題なのか不明です。