osx: Implement the updated ClutterStageWindow interface

In the new Clutter world backend stage implementations should be lightweight
objects implementing the ClutterStageWindow interface and not ClutterActor
subclasses.

This patch performs various cut-n-pastes to acheive that for the OSX backend

http://bugzilla.openedhand.com/show_bug.cgi?id=1864
This commit is contained in:
Joshua Lock 2009-11-05 15:44:32 +00:00 committed by Emmanuele Bassi
parent cb60c038ac
commit 4533e37744
3 changed files with 91 additions and 121 deletions

View File

@ -96,12 +96,12 @@ clutter_backend_osx_get_features (ClutterBackend *backend)
return CLUTTER_FEATURE_STAGE_MULTIPLE|CLUTTER_FEATURE_STAGE_USER_RESIZE; return CLUTTER_FEATURE_STAGE_MULTIPLE|CLUTTER_FEATURE_STAGE_USER_RESIZE;
} }
static ClutterActor* static ClutterStageWindow*
clutter_backend_osx_create_stage (ClutterBackend *backend, clutter_backend_osx_create_stage (ClutterBackend *backend,
ClutterStage *wrapper, ClutterStage *wrapper,
GError **error) GError **error)
{ {
ClutterActor *impl; ClutterStageWindow *impl;
CLUTTER_NOTE (BACKEND, "create_stage: wrapper=%p", wrapper); CLUTTER_NOTE (BACKEND, "create_stage: wrapper=%p", wrapper);

View File

@ -31,7 +31,9 @@
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
G_DEFINE_TYPE_WITH_CODE (ClutterStageOSX, clutter_stage_osx, CLUTTER_TYPE_ACTOR, G_DEFINE_TYPE_WITH_CODE (ClutterStageOSX,
clutter_stage_osx,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
clutter_stage_window_iface_init)) clutter_stage_window_iface_init))
@ -213,19 +215,15 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
static void static void
clutter_stage_osx_save_frame (ClutterStageOSX *self) clutter_stage_osx_save_frame (ClutterStageOSX *self)
{ {
if (CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (self))) g_assert (self->window != NULL);
{
g_assert (self->window != NULL);
self->normalFrame = [self->window frame]; self->normalFrame = [self->window frame];
self->haveNormalFrame = TRUE; self->haveNormalFrame = TRUE;
}
} }
static void static void
clutter_stage_osx_set_frame (ClutterStageOSX *self) clutter_stage_osx_set_frame (ClutterStageOSX *self)
{ {
g_assert (CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (self)));
g_assert (self->window != NULL); g_assert (self->window != NULL);
if (self->stage_state & CLUTTER_STAGE_STATE_FULLSCREEN) if (self->stage_state & CLUTTER_STAGE_STATE_FULLSCREEN)
@ -254,17 +252,14 @@ clutter_stage_osx_set_frame (ClutterStageOSX *self)
} }
/*************************************************************************/ /*************************************************************************/
static void static gboolean
clutter_stage_osx_realize (ClutterActor *actor) clutter_stage_osx_realize (ClutterStageWindow *stage_window)
{ {
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor); ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
ClutterBackendOSX *backend_osx; ClutterBackendOSX *backend_osx;
CLUTTER_NOTE (BACKEND, "[%p] realize", self); CLUTTER_NOTE (BACKEND, "[%p] realize", self);
/* ensure we get realize+unrealize properly paired */
g_return_if_fail (self->view == NULL && self->window == NULL);
CLUTTER_OSX_POOL_ALLOC(); CLUTTER_OSX_POOL_ALLOC();
backend_osx = CLUTTER_BACKEND_OSX (self->backend); backend_osx = CLUTTER_BACKEND_OSX (self->backend);
@ -288,12 +283,14 @@ clutter_stage_osx_realize (ClutterActor *actor)
CLUTTER_OSX_POOL_RELEASE(); CLUTTER_OSX_POOL_RELEASE();
CLUTTER_NOTE (BACKEND, "Stage successfully realized"); CLUTTER_NOTE (BACKEND, "Stage successfully realized");
return TRUE;
} }
static void static void
clutter_stage_osx_unrealize (ClutterActor *actor) clutter_stage_osx_unrealize (ClutterStageWindow *stage_window)
{ {
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor); ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
CLUTTER_NOTE (BACKEND, "[%p] unrealize", self); CLUTTER_NOTE (BACKEND, "[%p] unrealize", self);
@ -321,7 +318,7 @@ clutter_stage_osx_show (ClutterStageWindow *stage_window,
CLUTTER_OSX_POOL_ALLOC(); CLUTTER_OSX_POOL_ALLOC();
clutter_actor_map (CLUTTER_ACTOR (self)); clutter_stage_osx_realize (stage_window);
clutter_actor_map (CLUTTER_ACTOR (self->wrapper)); clutter_actor_map (CLUTTER_ACTOR (self->wrapper));
clutter_stage_osx_set_frame (self); clutter_stage_osx_set_frame (self);
@ -342,100 +339,75 @@ clutter_stage_osx_hide (ClutterStageWindow *stage_window)
[self->window orderOut: nil]; [self->window orderOut: nil];
clutter_actor_unmap (CLUTTER_ACTOR (self)); clutter_stage_osx_unrealize (stage_window);
clutter_actor_unmap (CLUTTER_ACTOR (self->wrapper)); clutter_actor_unmap (CLUTTER_ACTOR (self->wrapper));
CLUTTER_OSX_POOL_RELEASE(); CLUTTER_OSX_POOL_RELEASE();
} }
static void static void
clutter_stage_osx_get_preferred_width (ClutterActor *actor, clutter_stage_osx_get_geometry (ClutterStageWindow *stage_window,
gfloat for_height, ClutterGeometry *geometry)
gfloat *min_width_p,
gfloat *natural_width_p)
{ {
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor); ClutterBackend *backend = clutter_get_default_backend ();
gboolean is_resizable; ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
gboolean is_fullscreen, resize;
CLUTTER_OSX_POOL_ALLOC(); g_return_if_fail (CLUTTER_IS_BACKEND_OSX (backend));
is_resizable = clutter_stage_get_user_resizable (self->wrapper); CLUTTER_OSX_POOL_ALLOC ();
if (min_width_p) is_fullscreen = FALSE;
g_object_get (G_OBJECT (self->wrapper),
"fullscreen-set", &is_fullscreen,
NULL);
if (is_fullscreen)
{ {
if (is_resizable) NSSize size = [[NSScreen mainScreen] frame].size;
*min_width_p = 1.0;
geometry->width = size.width;
geometry->height = size.height;
}
else
{
resize = clutter_stage_get_user_resizable (self->wrapper);
if (resize)
{
geometry->width = 1;
geometry->height = 1;
}
else else
*min_width_p = self->requisition_width; {
geometry->width = self->requisition_width;
geometry->height = self->requisition_height;
}
} }
if (natural_width_p) CLUTTER_OSX_POOL_RELEASE ();
*natural_width_p = self->requisition_width;
CLUTTER_OSX_POOL_RELEASE();
} }
static void static void
clutter_stage_osx_get_preferred_height (ClutterActor *actor, clutter_stage_osx_resize (ClutterStageWindow *stage_window,
gfloat for_width, gint width,
gfloat *min_height_p, gint height)
gfloat *natural_height_p)
{ {
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor); ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
gboolean is_resizable;
CLUTTER_OSX_POOL_ALLOC(); self->requisition_width = width;
self->requisition_height = height;
is_resizable = clutter_stage_get_user_resizable (self->wrapper); CLUTTER_OSX_POOL_ALLOC ();
if (min_height_p) NSSize size = NSMakeSize (self->requisition_width,
{ self->requisition_height);
if (is_resizable) [self->window setContentSize: size];
*min_height_p = 1.0;
else
*min_height_p = self->requisition_height;
}
if (natural_height_p) CLUTTER_OSX_POOL_RELEASE ();
*natural_height_p = self->requisition_height;
CLUTTER_OSX_POOL_RELEASE();
}
static void
clutter_stage_osx_allocate (ClutterActor *actor,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
ClutterActorClass *parent_class;
CLUTTER_NOTE (BACKEND, "[%p], allocate: %d, %d - %d x %d", self,
(int) box->x1,
(int) box->y1,
(int) (box->x2 - box->x1),
(int) (box->y2 - box->y1));
self->requisition_width = (int) (box->x2 - box->x1);
self->requisition_height = (int) (box->y2 - box->y1);
if (CLUTTER_ACTOR_IS_REALIZED (actor))
{
CLUTTER_OSX_POOL_ALLOC();
NSSize size = NSMakeSize(self->requisition_width,
self->requisition_height);
[self->window setContentSize: size];
CLUTTER_OSX_POOL_RELEASE();
}
/* make sure that the viewport is updated */ /* make sure that the viewport is updated */
CLUTTER_SET_PRIVATE_FLAGS (self->wrapper, CLUTTER_ACTOR_SYNC_MATRICES); CLUTTER_SET_PRIVATE_FLAGS (self->wrapper, CLUTTER_ACTOR_SYNC_MATRICES);
/* chain up */
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class);
parent_class->allocate (actor, box, flags);
} }
/*************************************************************************/ /*************************************************************************/
@ -457,8 +429,7 @@ clutter_stage_osx_set_title (ClutterStageWindow *stage_window,
CLUTTER_OSX_POOL_ALLOC(); CLUTTER_OSX_POOL_ALLOC();
if (CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (self))) [self->window setTitle:[NSString stringWithUTF8String: title ? title : ""]];
[self->window setTitle:[NSString stringWithUTF8String: title ? title : ""]];
CLUTTER_OSX_POOL_RELEASE(); CLUTTER_OSX_POOL_RELEASE();
} }
@ -482,27 +453,14 @@ clutter_stage_osx_set_fullscreen (ClutterStageWindow *stage_window,
* We do state change first. Not sure there's any difference. * We do state change first. Not sure there's any difference.
*/ */
if (fullscreen) if (fullscreen)
clutter_stage_osx_state_update (self, 0, CLUTTER_STAGE_STATE_FULLSCREEN); {
clutter_stage_osx_state_update (self, 0, CLUTTER_STAGE_STATE_FULLSCREEN);
clutter_stage_osx_save_frame (self);
}
else else
clutter_stage_osx_state_update (self, CLUTTER_STAGE_STATE_FULLSCREEN, 0); clutter_stage_osx_state_update (self, CLUTTER_STAGE_STATE_FULLSCREEN, 0);
if (CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (self))) clutter_stage_osx_set_frame (self);
{
if (fullscreen)
clutter_stage_osx_save_frame (self);
clutter_stage_osx_set_frame (self);
}
else if (fullscreen)
{
/* FIXME: if you go fullscreen before realize we throw away the normal
* stage size and can't return. Need to maintain them separately.
*/
NSSize size = [[NSScreen mainScreen] frame].size;
clutter_actor_set_size (CLUTTER_ACTOR (self),
(int)size.width, (int)size.height);
}
CLUTTER_OSX_POOL_RELEASE(); CLUTTER_OSX_POOL_RELEASE();
} }
@ -515,10 +473,14 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->set_fullscreen = clutter_stage_osx_set_fullscreen; iface->set_fullscreen = clutter_stage_osx_set_fullscreen;
iface->show = clutter_stage_osx_show; iface->show = clutter_stage_osx_show;
iface->hide = clutter_stage_osx_hide; iface->hide = clutter_stage_osx_hide;
iface->realize = clutter_stage_osx_realize;
iface->unrealize = clutter_stage_osx_unrealize;
iface->get_geometry = clutter_stage_osx_get_geometry;
iface->resize = clutter_stage_osx_resize;
} }
/*************************************************************************/ /*************************************************************************/
ClutterActor * ClutterStageWindow *
clutter_stage_osx_new (ClutterBackend *backend, clutter_stage_osx_new (ClutterBackend *backend,
ClutterStage *wrapper) ClutterStage *wrapper)
{ {
@ -528,7 +490,7 @@ clutter_stage_osx_new (ClutterBackend *backend,
self->backend = backend; self->backend = backend;
self->wrapper = wrapper; self->wrapper = wrapper;
return CLUTTER_ACTOR(self); return CLUTTER_STAGE_WINDOW(self);
} }
/*************************************************************************/ /*************************************************************************/
@ -541,15 +503,23 @@ clutter_stage_osx_init (ClutterStageOSX *self)
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_IS_TOPLEVEL); CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_IS_TOPLEVEL);
} }
static void
clutter_stage_osx_finalize (GObject *gobject)
{
G_OBJECT_CLASS (clutter_stage_osx_parent_class)->finalize (gobject);
}
static void
clutter_stage_osx_dispose (GObject *gobject)
{
G_OBJECT_CLASS (clutter_stage_osx_parent_class)->dispose (gobject);
}
static void static void
clutter_stage_osx_class_init (ClutterStageOSXClass *klass) clutter_stage_osx_class_init (ClutterStageOSXClass *klass)
{ {
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
actor_class->realize = clutter_stage_osx_realize; gobject_class->finalize = clutter_stage_osx_finalize;
actor_class->unrealize = clutter_stage_osx_unrealize; gobject_class->dispose = clutter_stage_osx_dispose;
actor_class->allocate = clutter_stage_osx_allocate;
actor_class->get_preferred_width = clutter_stage_osx_get_preferred_width;
actor_class->get_preferred_height = clutter_stage_osx_get_preferred_height;
} }

View File

@ -50,7 +50,7 @@ typedef struct _ClutterStageOSXClass ClutterStageOSXClass;
struct _ClutterStageOSX struct _ClutterStageOSX
{ {
ClutterActor parent; ClutterGroup parent;
ClutterBackend *backend; ClutterBackend *backend;
ClutterStage *wrapper; ClutterStage *wrapper;
@ -69,13 +69,13 @@ struct _ClutterStageOSX
struct _ClutterStageOSXClass struct _ClutterStageOSXClass
{ {
ClutterActorClass parent_class; ClutterGroupClass parent_class;
}; };
GType clutter_stage_osx_get_type (void) G_GNUC_CONST; GType clutter_stage_osx_get_type (void) G_GNUC_CONST;
ClutterActor* clutter_stage_osx_new (ClutterBackend *backend, ClutterStageWindow* clutter_stage_osx_new (ClutterBackend *backend,
ClutterStage *wrapper); ClutterStage *wrapper);
G_END_DECLS G_END_DECLS