diff --git a/ChangeLog b/ChangeLog index 94eb51d95..ccaa0de51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-04-04 Neil Roberts + + Applied patch from bug #810. + + * clutter/x11/clutter-event-x11.c (event_translate): Set a flag + when resizing the stage from a ConfigureNotify event. + + * clutter/x11/clutter-stage-x11.c + (clutter_stage_x11_request_coords): Don't try to resize the window + again if the flag is set. + (clutter_stage_x11_init): Added initialiser for the flag. + + * clutter/x11/clutter-stage-x11.h (struct _ClutterStageX11): Added + the flag. + 2008-04-04 Matthew Allum reviewed by: diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 94806cb3b..bb5d30157 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -387,19 +387,17 @@ event_translate (ClutterBackend *backend, case ConfigureNotify: if (!stage_x11->is_foreign_xwin) { - guint stage_width, stage_height; + /* Set a flag so that the stage will know the actor is being + resized in response to the window size changing as + opposed to a request from the application. This prevents + it from trying to resize the window again */ + stage_x11->handling_configure = TRUE; - clutter_actor_get_size (CLUTTER_ACTOR (stage), - &stage_width, - &stage_height); + clutter_actor_set_size (CLUTTER_ACTOR (stage), + xevent->xconfigure.width, + xevent->xconfigure.height); - if (xevent->xconfigure.width != stage_width || - xevent->xconfigure.height != stage_height) - { - clutter_actor_set_size (CLUTTER_ACTOR (stage), - xevent->xconfigure.width, - xevent->xconfigure.height); - } + stage_x11->handling_configure = FALSE; } res = FALSE; break; diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index c5d935c3c..bb52d4d0f 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -173,22 +173,33 @@ clutter_stage_x11_request_coords (ClutterActor *self, new_width = ABS (CLUTTER_UNITS_TO_INT (box->x2 - box->x1)); new_height = ABS (CLUTTER_UNITS_TO_INT (box->y2 - box->y1)); - if (new_width != stage_x11->xwin_width || - new_height != stage_x11->xwin_height) + if (new_width != stage_x11->xwin_width + || new_height != stage_x11->xwin_height) { stage_x11->xwin_width = new_width; stage_x11->xwin_height = new_height; - if (stage_x11->xwin != None && - !stage_x11->is_foreign_xwin) - { - XResizeWindow (stage_x11->xdpy, - stage_x11->xwin, - stage_x11->xwin_width, - stage_x11->xwin_height); - - clutter_stage_x11_fix_window_size (stage_x11); - } + /* The 'handling_configure' flag below is used to prevent the + window from being resized again in response to a + ConfigureNotify event. Normally this will not be a problem + because the window will be resized to xwin_width and + xwin_height so the above test will prevent it from resizing + the window a second time. However if the stage is resized + multiple times without the events being processed in between + (eg, when calling g_object_set to set both width and height) + then there will be multiple ConfigureNotify events in the + 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); + + clutter_stage_x11_fix_window_size (stage_x11); if (stage_x11->xpixmap != None) { @@ -200,8 +211,9 @@ clutter_stage_x11_request_coords (ClutterActor *self, CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES); } - if (stage_x11->xwin != None && - !stage_x11->is_foreign_xwin) /* Do we want to bother ? */ + if (stage_x11->xwin != None + && !stage_x11->is_foreign_xwin + && !stage_x11->handling_configure) /* Do we want to bother ? */ XMoveWindow (stage_x11->xdpy, stage_x11->xwin, CLUTTER_UNITS_TO_INT (box->x1), @@ -425,6 +437,7 @@ clutter_stage_x11_init (ClutterStageX11 *stage) stage->is_foreign_xwin = FALSE; stage->fullscreen_on_map = FALSE; + stage->handling_configure = FALSE; CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); } diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h index 9a00741d8..8f3269190 100644 --- a/clutter/x11/clutter-stage-x11.h +++ b/clutter/x11/clutter-stage-x11.h @@ -56,6 +56,7 @@ struct _ClutterStageX11 gint xwin_width; gint xwin_height; /* FIXME target_width / height */ Pixmap xpixmap; + gboolean handling_configure; ClutterBackendX11 *backend; ClutterStageState state;