diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 745fcbbd7..edcb44cf0 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -147,7 +147,8 @@ _clutter_stage_maybe_relayout (ClutterActor *stage) void _clutter_stage_maybe_setup_viewport (ClutterStage *stage) { - if (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_SYNC_MATRICES) + if ((CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_SYNC_MATRICES) && + !(CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_STAGE_IN_RESIZE)) { ClutterPerspective perspective; guint width, height; diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index c65bfb066..b1f141bf7 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -62,7 +62,8 @@ typedef enum { */ CLUTTER_ACTOR_IN_PAINT = 1 << 4, /* Used to avoid recursion */ CLUTTER_ACTOR_IN_RELAYOUT = 1 << 5, /* Used to avoid recursion */ - CLUTTER_TEXTURE_IN_CLONE_PAINT = 1 << 6 /* Used for safety in clones */ + CLUTTER_TEXTURE_IN_CLONE_PAINT = 1 << 6, /* Used for safety in clones */ + CLUTTER_STAGE_IN_RESIZE = 1 << 7 /* Used to mark stage resizes */ } ClutterPrivateFlags; typedef enum { diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 06e27e766..090e2c28c 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -438,6 +438,12 @@ event_translate (ClutterBackend *backend, xevent->xconfigure.height); stage_x11->handling_configure = FALSE; + + /* the resize process is complete, so we can remove the + * in-resize flag and allow the viewport to be resized + */ + CLUTTER_UNSET_PRIVATE_FLAGS (CLUTTER_ACTOR (stage_x11->wrapper), + CLUTTER_STAGE_IN_RESIZE); } res = FALSE; break; diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index 010063951..bfc86ba9f 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -282,13 +282,30 @@ clutter_stage_x11_allocate (ClutterActor *self, queue. Handling the first event will undo the work of setting the second property which will cause it to keep generating events in an infinite loop. See bug #810 */ - if (stage_x11->xwin != None - && !stage_x11->is_foreign_xwin - && !stage_x11->handling_configure) - XResizeWindow (stage_x11->xdpy, - stage_x11->xwin, - stage_x11->xwin_width, - stage_x11->xwin_height); + if (stage_x11->xwin != None && + !stage_x11->is_foreign_xwin && + !stage_x11->handling_configure) + { + XResizeWindow (stage_x11->xdpy, + stage_x11->xwin, + stage_x11->xwin_width, + stage_x11->xwin_height); + + /* resizing is an asynchronous process; to avoid races + * with the window manager, we flag the wrapper as being + * "in resize", so that the SYNC_MATRICES flag will not + * cause a call to cogl_get_viewport(). + * + * the flag is unset inside clutter-event-x11.c, after + * we receive a ConfigureNotify event. XXX - need to + * check what happens when running without a window manager + */ + CLUTTER_SET_PRIVATE_FLAGS (CLUTTER_ACTOR (stage_x11->wrapper), + CLUTTER_STAGE_IN_RESIZE); + } + + CLUTTER_SET_PRIVATE_FLAGS (CLUTTER_ACTOR (stage_x11->wrapper), + CLUTTER_ACTOR_SYNC_MATRICES); clutter_stage_x11_fix_window_size (stage_x11); @@ -298,9 +315,6 @@ clutter_stage_x11_allocate (ClutterActor *self, clutter_actor_unrealize (self); clutter_actor_realize (self); } - - CLUTTER_SET_PRIVATE_FLAGS (CLUTTER_ACTOR (stage_x11->wrapper), - CLUTTER_ACTOR_SYNC_MATRICES); } /* chain up to fill in actor->priv->allocation */ @@ -769,4 +783,3 @@ clutter_stage_x11_unmap (ClutterStageX11 *stage_x11) CLUTTER_ACTOR_UNSET_FLAGS (stage_x11, CLUTTER_ACTOR_MAPPED); CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_MAPPED); } -