From a79dfb7beb2cc079d309560d305475cc18dbbcc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Thu, 17 Oct 2019 12:13:32 +0200 Subject: [PATCH 1/2] layer-surface: Emit signals on width/height changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We missed signals on phosh_layer_surface_set_size(). Signed-off-by: Guido Günther --- src/layersurface.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/layersurface.c b/src/layersurface.c index 11deb048f..784c0e9a4 100644 --- a/src/layersurface.c +++ b/src/layersurface.c @@ -64,10 +64,23 @@ static void layer_surface_configure(void *data, uint32_t height) { PhoshLayerSurface *self = data; + PhoshLayerSurfacePrivate *priv; + g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self)); + priv = phosh_layer_surface_get_instance_private (self); gtk_window_resize (GTK_WINDOW (self), width, height); zwlr_layer_surface_v1_ack_configure(surface, serial); + if (priv->height != height) { + priv->height = height; + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]); + } + + if (priv->width != width) { + priv->width = width; + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]); + } + g_debug("Configured %p", self); g_signal_emit (self, signals[CONFIGURED], 0); } @@ -148,9 +161,13 @@ phosh_layer_surface_set_property (GObject *object, break; case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH: priv->width = g_value_get_uint (value); + /* construct-only, so we can always emit the signal */ + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]); break; case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT: priv->height = g_value_get_uint (value); + /* construct-only, so we can always emit the signal */ + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]); break; case PHOSH_LAYER_SURFACE_PROP_NAMESPACE: g_free (priv->namespace); @@ -431,6 +448,10 @@ phosh_layer_surface_class_init (PhoshLayerSurfaceClass *klass) 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + /* + * construct only since we don't want width height to be set individually + * but rather through set_size to avoid multiple calls to zwlr_layer_surface_v1_set_size + */ props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH] = g_param_spec_uint ( "width", @@ -439,7 +460,7 @@ phosh_layer_surface_class_init (PhoshLayerSurfaceClass *klass) 0, G_MAXUINT, 0, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT] = g_param_spec_uint ( @@ -449,7 +470,7 @@ phosh_layer_surface_class_init (PhoshLayerSurfaceClass *klass) 0, G_MAXUINT, 0, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); props[PHOSH_LAYER_SURFACE_PROP_NAMESPACE] = g_param_spec_string ( @@ -535,6 +556,7 @@ void phosh_layer_surface_set_size(PhoshLayerSurface *self, gint width, gint height) { PhoshLayerSurfacePrivate *priv; + gint old_width, old_height; g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self)); priv = phosh_layer_surface_get_instance_private (self); @@ -542,6 +564,9 @@ phosh_layer_surface_set_size(PhoshLayerSurface *self, gint width, gint height) if (priv->height == height && priv->width == width) return; + old_width = priv->width; + old_height = priv->height; + if (width != -1) priv->width = width; @@ -549,6 +574,12 @@ phosh_layer_surface_set_size(PhoshLayerSurface *self, gint width, gint height) priv->height = height; zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height); + + if (priv->height != old_height) + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]); + + if (priv->width != old_width) + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]); } /** -- GitLab From be3f3e599357f41cad015e50fa6d21aac51cb88f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sat, 19 Oct 2019 14:00:43 +0200 Subject: [PATCH 2/2] layer-surface: Make actual width/height separate from size constraints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The allocated size is useful to know even if a size constraint is not exact. So the size in `layer_surface.set_size` is a constraint, and the size received in `configure` is a value, which are incompatible, and setting them in one variable causes trouble. This gets solved by requesting size without touching the configured size values. Signed-off-by: Guido Günther Signed-off-by: Dorota Czaplejewicz --- src/layersurface.c | 115 +++++++++++++++++++++++++++++++-------------- 1 file changed, 80 insertions(+), 35 deletions(-) diff --git a/src/layersurface.c b/src/layersurface.c index 784c0e9a4..e652ecc01 100644 --- a/src/layersurface.c +++ b/src/layersurface.c @@ -24,6 +24,8 @@ enum { PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM, PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT, PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT, + PHOSH_LAYER_SURFACE_PROP_REQUESTED_WIDTH, + PHOSH_LAYER_SURFACE_PROP_REQUESTED_HEIGHT, PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH, PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT, PHOSH_LAYER_SURFACE_PROP_NAMESPACE, @@ -50,6 +52,7 @@ typedef struct { gint margin_top, margin_bottom; gint margin_left, margin_right; gint width, height; + guint configured_width, configured_height; gchar *namespace; struct zwlr_layer_shell_v1 *layer_shell; struct wl_output *wl_output; @@ -71,13 +74,13 @@ static void layer_surface_configure(void *data, gtk_window_resize (GTK_WINDOW (self), width, height); zwlr_layer_surface_v1_ack_configure(surface, serial); - if (priv->height != height) { - priv->height = height; + if (priv->configured_height != height) { + priv->configured_height = height; g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]); } - if (priv->width != width) { - priv->width = width; + if (priv->configured_width != width) { + priv->configured_width = width; g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]); } @@ -99,8 +102,8 @@ static void layer_surface_closed (void *data, } static struct zwlr_layer_surface_v1_listener layer_surface_listener = { - .configure = layer_surface_configure, - .closed = layer_surface_closed, + .configure = layer_surface_configure, + .closed = layer_surface_closed, }; static void @@ -160,14 +163,16 @@ phosh_layer_surface_set_property (GObject *object, priv->margin_left); break; case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH: - priv->width = g_value_get_uint (value); - /* construct-only, so we can always emit the signal */ - g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]); + priv->configured_width = g_value_get_uint (value); break; case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT: + priv->configured_height = g_value_get_uint (value); + break; + case PHOSH_LAYER_SURFACE_PROP_REQUESTED_WIDTH: + priv->width = g_value_get_uint (value); + break; + case PHOSH_LAYER_SURFACE_PROP_REQUESTED_HEIGHT: priv->height = g_value_get_uint (value); - /* construct-only, so we can always emit the signal */ - g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]); break; case PHOSH_LAYER_SURFACE_PROP_NAMESPACE: g_free (priv->namespace); @@ -221,9 +226,15 @@ phosh_layer_surface_get_property (GObject *object, g_value_set_int (value, priv->margin_right); break; case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH: - g_value_set_uint (value, priv->width); + g_value_set_uint (value, priv->configured_width); break; case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT: + g_value_set_uint (value, priv->configured_height); + break; + case PHOSH_LAYER_SURFACE_PROP_REQUESTED_WIDTH: + g_value_set_uint (value, priv->width); + break; + case PHOSH_LAYER_SURFACE_PROP_REQUESTED_HEIGHT: g_value_set_uint (value, priv->height); break; case PHOSH_LAYER_SURFACE_PROP_NAMESPACE: @@ -259,6 +270,7 @@ on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused) { PhoshLayerSurfacePrivate *priv; GdkWindow *gdk_window; + guint wanted_width = 0, wanted_height = 0; g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self)); priv = phosh_layer_surface_get_instance_private (self); @@ -276,7 +288,20 @@ on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused) priv->layer, priv->namespace); zwlr_layer_surface_v1_set_exclusive_zone(priv->layer_surface, priv->exclusive_zone); - zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height); + + // Take into account that if the user wanted the compositor to choose a value, + // then it should be allowed again + // but at the same time, if an allocation was done with a specific value, + // then favor not resizing. + if (priv->width != 0) { + wanted_width = priv->configured_width; + } + + if (priv->height != 0) { + wanted_height = priv->configured_height; + } + + zwlr_layer_surface_v1_set_size(priv->layer_surface, wanted_width, wanted_height); zwlr_layer_surface_v1_set_anchor(priv->layer_surface, priv->anchor); zwlr_layer_surface_v1_set_margin(priv->layer_surface, priv->margin_top, @@ -448,25 +473,41 @@ phosh_layer_surface_class_init (PhoshLayerSurfaceClass *klass) 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); - /* - * construct only since we don't want width height to be set individually - * but rather through set_size to avoid multiple calls to zwlr_layer_surface_v1_set_size - */ - props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH] = + props[PHOSH_LAYER_SURFACE_PROP_REQUESTED_WIDTH] = g_param_spec_uint ( "width", "Width", - "The width of the layer surface", + "The requested width of the layer surface", 0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); - props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT] = + props[PHOSH_LAYER_SURFACE_PROP_REQUESTED_HEIGHT] = g_param_spec_uint ( "height", "Height", - "The height of the layer surface", + "The requested height of the layer surface", + 0, + G_MAXUINT, + 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + + props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH] = + g_param_spec_uint ( + "configured-width", + "Configured width", + "The width of the layer surface set by the compositor", + 0, + G_MAXUINT, + 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); + + props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT] = + g_param_spec_uint ( + "configured-height", + "Configured height", + "The height of the layer surface set by the compositor", 0, G_MAXUINT, 0, @@ -550,36 +591,39 @@ phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self) /** * phosh_layer_surface_set_size: * - * Set the size of a layer surface. A value of '-1' indicates 'use old value' + * Set the size of a layer surface. + * A value of '-1' indicates 'use configured value' */ void phosh_layer_surface_set_size(PhoshLayerSurface *self, gint width, gint height) { PhoshLayerSurfacePrivate *priv; - gint old_width, old_height; g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self)); priv = phosh_layer_surface_get_instance_private (self); - if (priv->height == height && priv->width == width) - return; + if (width == -1) + width = priv->configured_width; - old_width = priv->width; - old_height = priv->height; + if (height == -1) + height = priv->configured_height; - if (width != -1) + if (priv->width != width) { priv->width = width; + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_REQUESTED_WIDTH]); + } - if (height != -1) + if (priv->height != height) { priv->height = height; + g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_REQUESTED_HEIGHT]); + } - zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height); - - if (priv->height != old_height) - g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]); + if (priv->configured_height == height && priv->configured_width == width) + return; - if (priv->width != old_width) - g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]); + if (gtk_widget_get_mapped (GTK_WIDGET (self))) { + zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height); + } } /** @@ -689,3 +733,4 @@ phosh_layer_surface_wl_surface_commit (PhoshLayerSurface *self) if (priv->wl_surface) wl_surface_commit (priv->wl_surface); } + -- GitLab