From fd11d3098f0182f24666ed77973269111cb0a8f5 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sat, 6 Feb 2010 11:23:37 +0000 Subject: [PATCH 1/9] [stage] Add set/get_minumum_size Add two functions to set/get the minimum stage size. This takes effect when a stage is set to user resizable. --- clutter/clutter-stage.c | 75 ++++++++++++++++++++++ clutter/clutter-stage.h | 7 ++ clutter/x11/clutter-stage-x11.c | 6 +- doc/reference/clutter/clutter-sections.txt | 2 + 4 files changed, 87 insertions(+), 3 deletions(-) diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index c67056d3d..bef66524f 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -82,6 +82,8 @@ struct _ClutterStagePrivate { /* the stage implementation */ ClutterStageWindow *impl; + guint minimum_width; + guint minimum_height; ClutterColor color; ClutterPerspective perspective; @@ -1179,6 +1181,8 @@ clutter_stage_init (ClutterStage *self) priv->throttle_motion_events = TRUE; priv->color = default_stage_color; + priv->minimum_width = 640; + priv->minimum_height = 480; priv->perspective.fovy = 60.0; /* 60 Degrees */ priv->perspective.aspect = 1.0; @@ -2322,3 +2326,74 @@ clutter_stage_get_use_alpha (ClutterStage *stage) return stage->priv->use_alpha; } + +/** + * clutter_stage_set_minimum_size: + * @stage: a #ClutterStage + * @width: width, in pixels + * @height: height, in pixels + * + * Sets the minimum size for a stage window. This has no effect if the stage + * is fullscreen. + * + * Since: 1.2 + */ +void +clutter_stage_set_minimum_size (ClutterStage *stage, + guint width, + guint height) +{ + gboolean resize; + ClutterGeometry geom; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + g_return_if_fail ((width > 0) && (height > 0)); + + stage->priv->minimum_width = width; + stage->priv->minimum_height = height; + + if (stage->priv->impl == NULL) + return; + + resize = FALSE; + _clutter_stage_window_get_geometry (stage->priv->impl, &geom); + + if (geom.width < width) + resize = TRUE; + else + width = geom.width; + + if (geom.height < height) + resize = TRUE; + else + height = geom.height; + + if (resize) + _clutter_stage_window_resize (stage->priv->impl, width, height); +} + +/** + * clutter_stage_get_minimum_size: + * @stage: a #ClutterStage + * @width: width, in pixels + * @height: height, in pixels + * + * Gets the set minimum size for a stage window. This may not correspond + * to the actual minimum size and is specific to the back-end + * implementation. + * + * Since: 1.2 + */ +void +clutter_stage_get_minimum_size (ClutterStage *stage, + guint *width, + guint *height) +{ + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + + if (width) + *width = stage->priv->minimum_width; + if (height) + *height = stage->priv->minimum_height; +} + diff --git a/clutter/clutter-stage.h b/clutter/clutter-stage.h index a4e3bfbb1..c26460eaa 100644 --- a/clutter/clutter-stage.h +++ b/clutter/clutter-stage.h @@ -247,6 +247,13 @@ void clutter_stage_set_use_alpha (ClutterStage *stage, gboolean use_alpha); gboolean clutter_stage_get_use_alpha (ClutterStage *stage); +void clutter_stage_set_minimum_size (ClutterStage *stage, + guint width, + guint height); +void clutter_stage_get_minimum_size (ClutterStage *stage, + guint *width, + guint *height); + /* Commodity macro, for mallum only */ #define clutter_stage_add(stage,actor) G_STMT_START { \ if (CLUTTER_IS_STAGE ((stage)) && CLUTTER_IS_ACTOR ((actor))) \ diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index 12b13225c..f2e6f307d 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -191,9 +191,9 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window, if (resize) { - /* FIXME need API to set this */ - geometry->width = 1; - geometry->height = 1; + clutter_stage_get_minimum_size (stage_x11->wrapper, + &geometry->width, + &geometry->height); } else { diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index 6626369a4..b686072db 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -533,6 +533,8 @@ clutter_stage_set_throttle_motion_events clutter_stage_get_throttle_motion_events clutter_stage_set_use_alpha clutter_stage_get_use_alpha +clutter_stage_set_minimum_size +clutter_stage_get_minimum_size ClutterPerspective From be11564b556a1b1c08b7b9e7a0a94bc00c4e6550 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sat, 6 Feb 2010 14:04:47 +0100 Subject: [PATCH 2/9] [stage] Set minimum width/height to 1x1 Whoops, to maintain the old behaviour, make sure the default minimum width/height are 1x1. --- clutter/clutter-stage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index bef66524f..9e6baa8be 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -1181,8 +1181,8 @@ clutter_stage_init (ClutterStage *self) priv->throttle_motion_events = TRUE; priv->color = default_stage_color; - priv->minimum_width = 640; - priv->minimum_height = 480; + priv->minimum_width = 1; + priv->minimum_height = 1; priv->perspective.fovy = 60.0; /* 60 Degrees */ priv->perspective.aspect = 1.0; From 27e33aa14ff5d14f6066da74922c960a037b5089 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sat, 6 Feb 2010 14:59:51 +0100 Subject: [PATCH 3/9] [stage] Get the current size correctly Get the current size of the stage correctly in clutter_stage_set_minimum_size. The get_geometry StageWindow function is not equivalent of the current size, use clutter_actor_get_size(). --- clutter/clutter-stage.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 9e6baa8be..6d9e13c7d 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -2344,7 +2344,7 @@ clutter_stage_set_minimum_size (ClutterStage *stage, guint height) { gboolean resize; - ClutterGeometry geom; + gfloat current_width, current_height; g_return_if_fail (CLUTTER_IS_STAGE (stage)); g_return_if_fail ((width > 0) && (height > 0)); @@ -2356,17 +2356,19 @@ clutter_stage_set_minimum_size (ClutterStage *stage, return; resize = FALSE; - _clutter_stage_window_get_geometry (stage->priv->impl, &geom); + clutter_actor_get_size (CLUTTER_ACTOR (stage), + ¤t_width, + ¤t_height); - if (geom.width < width) + if ((guint)current_width < width) resize = TRUE; else - width = geom.width; + width = (guint)current_width; - if (geom.height < height) + if ((guint)current_height < height) resize = TRUE; else - height = geom.height; + height = (guint)current_height; if (resize) _clutter_stage_window_resize (stage->priv->impl, width, height); From 4887707bb34faca0d7ad92f6628d18345163f5e0 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sat, 6 Feb 2010 15:34:55 +0100 Subject: [PATCH 4/9] [stage-x11] make get_geometry always get geometry Now that we have a minimum size getter on the stage object, change get_geometry to actually always return the geometry. This fixes stages that are set as user-resizable appearing at 1x1 size. This will need changing in other back-ends too. --- clutter/x11/clutter-stage-x11.c | 57 +++++++++++++-------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index f2e6f307d..754dcc280 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -102,24 +102,20 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11, if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin) { - gint min_width, min_height; - ClutterGeometry min_size; + guint min_width, min_height; XSizeHints *size_hints; size_hints = XAllocSizeHints(); - _clutter_stage_window_get_geometry (CLUTTER_STAGE_WINDOW (stage_x11), - &min_size); + clutter_stage_get_minimum_size (stage_x11->wrapper, + &min_width, + &min_height); - if (new_width < 0) - min_width = min_size.width; - else - min_width = new_width; + if (new_width <= 0) + new_width = min_width; - if (new_height < 0) - min_height = min_size.height; - else - min_height = new_height; + if (new_height <= 0) + new_height = min_height; size_hints->flags = 0; @@ -127,15 +123,19 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11, restrictions on the window size */ if (!stage_x11->fullscreen_on_map) { - size_hints->min_width = min_width; - size_hints->min_height = min_height; - size_hints->flags = PMinSize; - - if (!resize) + if (resize) { - size_hints->max_width = size_hints->min_width; - size_hints->max_height = size_hints->min_height; - size_hints->flags |= PMaxSize; + size_hints->min_width = min_width; + size_hints->min_height = min_height; + size_hints->flags = PMinSize; + } + else + { + size_hints->min_width = new_width; + size_hints->min_height = new_height; + size_hints->max_width = new_width; + size_hints->max_height = new_height; + size_hints->flags = PMinSize | PMaxSize; } } @@ -169,7 +169,7 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window, ClutterBackend *backend = clutter_get_default_backend (); ClutterBackendX11 *backend_x11; ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - gboolean is_fullscreen, resize; + gboolean is_fullscreen; g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend)); backend_x11 = CLUTTER_BACKEND_X11 (backend); @@ -187,19 +187,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window, return; } - resize = clutter_stage_get_user_resizable (stage_x11->wrapper); - - if (resize) - { - clutter_stage_get_minimum_size (stage_x11->wrapper, - &geometry->width, - &geometry->height); - } - else - { - geometry->width = stage_x11->xwin_width; - geometry->height = stage_x11->xwin_height; - } + geometry->width = stage_x11->xwin_width; + geometry->height = stage_x11->xwin_height; } static void From cea9de7f047cb8c2b1d54f41ca1d77c3aff882e0 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sat, 6 Feb 2010 15:41:01 +0100 Subject: [PATCH 5/9] [stage] Now that get_geometry works, use it We want the actual window geometry in clutter_stage_set_minimum_size, not the set size. Now that the geometry function has been changed to do what it says, use it. --- clutter/clutter-stage.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 6d9e13c7d..9e6baa8be 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -2344,7 +2344,7 @@ clutter_stage_set_minimum_size (ClutterStage *stage, guint height) { gboolean resize; - gfloat current_width, current_height; + ClutterGeometry geom; g_return_if_fail (CLUTTER_IS_STAGE (stage)); g_return_if_fail ((width > 0) && (height > 0)); @@ -2356,19 +2356,17 @@ clutter_stage_set_minimum_size (ClutterStage *stage, return; resize = FALSE; - clutter_actor_get_size (CLUTTER_ACTOR (stage), - ¤t_width, - ¤t_height); + _clutter_stage_window_get_geometry (stage->priv->impl, &geom); - if ((guint)current_width < width) + if (geom.width < width) resize = TRUE; else - width = (guint)current_width; + width = geom.width; - if ((guint)current_height < height) + if (geom.height < height) resize = TRUE; else - height = (guint)current_height; + height = geom.height; if (resize) _clutter_stage_window_resize (stage->priv->impl, width, height); From 29cc027f069c9ad900b9044cd40075c2d17be736 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sat, 6 Feb 2010 16:47:22 +0100 Subject: [PATCH 6/9] [x11] Don't set actor size on ConfigureNotify Calling clutter_actor_set_size in response to ConfigureNotify makes setting the size of the stage racy - the most common result of which seems to be that you can't set the stage dimensions to anything less than 640x480. Instead, add a first_allocation bit to the private structure of the X11 stage and force the first resize (necessary or the default stage will be a 1x1 window). --- clutter/x11/clutter-event-x11.c | 4 ---- clutter/x11/clutter-stage-x11.c | 5 ++++- clutter/x11/clutter-stage-x11.h | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 1a3a260fc..4645b6359 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -485,10 +485,6 @@ event_translate (ClutterBackend *backend, xevent->xconfigure.width, xevent->xconfigure.height); - clutter_actor_set_size (CLUTTER_ACTOR (stage), - xevent->xconfigure.width, - xevent->xconfigure.height); - CLUTTER_UNSET_PRIVATE_FLAGS (stage_x11->wrapper, CLUTTER_STAGE_IN_RESIZE); diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index 754dcc280..f0d57bdda 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -220,10 +220,12 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window, CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height); if (width != stage_x11->xwin_width || - height != stage_x11->xwin_height) + height != stage_x11->xwin_height || + stage_x11->first_allocation) { stage_x11->xwin_width = width; stage_x11->xwin_height = height; + stage_x11->first_allocation = FALSE; if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin) { @@ -659,6 +661,7 @@ clutter_stage_x11_init (ClutterStageX11 *stage) stage->xwin = None; stage->xwin_width = 640; stage->xwin_height = 480; + stage->first_allocation = TRUE; stage->wm_state = STAGE_X11_WITHDRAWN; diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h index 71b66e348..a10c0d902 100644 --- a/clutter/x11/clutter-stage-x11.h +++ b/clutter/x11/clutter-stage-x11.h @@ -54,6 +54,7 @@ struct _ClutterStageX11 guint fullscreen_on_map : 1; guint is_cursor_visible : 1; guint viewport_initialized : 1; + guint first_allocation : 1; Window xwin; gint xwin_width; From 8083dc418b3c2b069a9b0db9323650050a3f63b1 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sat, 6 Feb 2010 16:57:37 +0100 Subject: [PATCH 7/9] Revert "[x11] Don't set actor size on ConfigureNotify" This reverts commit 29cc027f069c9ad900b9044cd40075c2d17be736. I misunderstood the problem, this commit breaks resizes coming from outside of Clutter. --- clutter/x11/clutter-event-x11.c | 4 ++++ clutter/x11/clutter-stage-x11.c | 5 +---- clutter/x11/clutter-stage-x11.h | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 4645b6359..1a3a260fc 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -485,6 +485,10 @@ event_translate (ClutterBackend *backend, xevent->xconfigure.width, xevent->xconfigure.height); + clutter_actor_set_size (CLUTTER_ACTOR (stage), + xevent->xconfigure.width, + xevent->xconfigure.height); + CLUTTER_UNSET_PRIVATE_FLAGS (stage_x11->wrapper, CLUTTER_STAGE_IN_RESIZE); diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index f0d57bdda..754dcc280 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -220,12 +220,10 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window, CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height); if (width != stage_x11->xwin_width || - height != stage_x11->xwin_height || - stage_x11->first_allocation) + height != stage_x11->xwin_height) { stage_x11->xwin_width = width; stage_x11->xwin_height = height; - stage_x11->first_allocation = FALSE; if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin) { @@ -661,7 +659,6 @@ clutter_stage_x11_init (ClutterStageX11 *stage) stage->xwin = None; stage->xwin_width = 640; stage->xwin_height = 480; - stage->first_allocation = TRUE; stage->wm_state = STAGE_X11_WITHDRAWN; diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h index a10c0d902..71b66e348 100644 --- a/clutter/x11/clutter-stage-x11.h +++ b/clutter/x11/clutter-stage-x11.h @@ -54,7 +54,6 @@ struct _ClutterStageX11 guint fullscreen_on_map : 1; guint is_cursor_visible : 1; guint viewport_initialized : 1; - guint first_allocation : 1; Window xwin; gint xwin_width; From b968defae92f3fbd5a4a762b4c817ab58989ee82 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sun, 7 Feb 2010 14:18:14 +0100 Subject: [PATCH 8/9] [stage] Set default size correctly Due to the way the new sizing works, clutter stage must set its size in init (to maintain old behaviour) and the properties on the X11 stage must be initialised to 1x1 so that it actually goes ahead with the resize. Fixes stages that aren't user resizable and have no size set from appearing at 1x1. --- clutter/clutter-stage.c | 3 +++ clutter/x11/clutter-stage-x11.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 9e6baa8be..f3b0b89c9 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -1196,6 +1196,9 @@ clutter_stage_init (ClutterStage *self) clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); clutter_stage_set_title (self, g_get_prgname ()); clutter_stage_set_key_focus (self, NULL); + + /* Set the default size */ + clutter_actor_set_size (CLUTTER_ACTOR (self), 640, 480); } /** diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index 754dcc280..d4dad7091 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -657,8 +657,8 @@ static void clutter_stage_x11_init (ClutterStageX11 *stage) { stage->xwin = None; - stage->xwin_width = 640; - stage->xwin_height = 480; + stage->xwin_width = 1; + stage->xwin_height = 1; stage->wm_state = STAGE_X11_WITHDRAWN; From c82c94e6205eda962faf5a51e663680c313be062 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Sun, 7 Feb 2010 19:17:43 +0100 Subject: [PATCH 9/9] [stage-x11] Set the default size differently We want to set the default size without triggering the layout machinary, so change the window creation process slightly so we start with a 640x480 window. --- clutter/clutter-stage.c | 3 --- clutter/glx/clutter-stage-glx.c | 4 +++- clutter/x11/clutter-stage-x11.c | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index f3b0b89c9..9e6baa8be 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -1196,9 +1196,6 @@ clutter_stage_init (ClutterStage *self) clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); clutter_stage_set_title (self, g_get_prgname ()); clutter_stage_set_key_focus (self, NULL); - - /* Set the default size */ - clutter_actor_set_size (CLUTTER_ACTOR (self), 640, 480); } /** diff --git a/clutter/glx/clutter-stage-glx.c b/clutter/glx/clutter-stage-glx.c index a99d5f645..3764d3a8f 100644 --- a/clutter/glx/clutter-stage-glx.c +++ b/clutter/glx/clutter-stage-glx.c @@ -171,7 +171,9 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window) } /* no user resize.. */ - clutter_stage_x11_fix_window_size (stage_x11, -1, -1); + clutter_stage_x11_fix_window_size (stage_x11, + stage_x11->xwin_width, + stage_x11->xwin_height); clutter_stage_x11_set_wm_protocols (stage_x11); /* ask for a context; a no-op, if a context already exists */ diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index d4dad7091..754dcc280 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -657,8 +657,8 @@ static void clutter_stage_x11_init (ClutterStageX11 *stage) { stage->xwin = None; - stage->xwin_width = 1; - stage->xwin_height = 1; + stage->xwin_width = 640; + stage->xwin_height = 480; stage->wm_state = STAGE_X11_WITHDRAWN;