Control: tags -1 + patch fixed-upstream
Control: found -1 1.27.1-4.1

Hi,

this bug still affects trixie (mate-panel 1.27.1-4.1): the workspace
switcher applet shows each workspace with a 1:1 aspect ratio instead of
the aspect ratio of the screen.

It has been fixed upstream by this commit, which is part of mate-panel
1.27.3 and later:

  wnck-pager: Fix workspace switcher aspect ratio
https://github.com/mate-desktop/mate-panel/commit/cb1a440f1f3f740bbaeb9577465c999c67f5c80a

The change touches a single file (applets/wncklet/workspace-switcher.c,
+153/-1). It wraps the WnckPager in a small container widget that
requests the pager's width for the panel height. Earlier in this bug,
smcv pointed to the equivalent fix in gnome-panel.

Attached is the commit as a patch with DEP-3 headers. To test it within
the Debian packaging, I built a local package from the trixie source
(1.27.1-4.1+armin1), with the patch added to debian/patches after 0006.
The whole series applies cleanly, and on trixie with libwnck 43.2-1 the
workspace switcher shows the correct aspect ratio again.

As a workaround I currently pin libwnck 3.36.0-1 from bullseye, which
is increasingly out of date. Would you consider applying the patch in
unstable, and possibly proposing it for a trixie point release?

Thanks,
Armin Fuerst
Description: wnck-pager: Fix workspace switcher aspect ratio
 Since libwnck 40/43, the workspace switcher applet shows each workspace
 with a 1:1 aspect ratio instead of the aspect ratio of the screen.
 libwnck changed its size negotiation to follow GTK's API requirements.
 This upstream commit wraps the WnckPager in a small container widget
 that requests the pager's width for the panel height (or its height for
 the panel width).
Author: lukefromdc <[email protected]>
Origin: upstream, https://github.com/mate-desktop/mate-panel/commit/cb1a440f1f3f740bbaeb9577465c999c67f5c80a
Bug: https://github.com/mate-desktop/mate-panel/issues/1230
Bug-Debian: https://bugs.debian.org/1033501
Applied-Upstream: 1.27.3
Last-Update: 2026-09-27
---
diff --git a/applets/wncklet/workspace-switcher.c b/applets/wncklet/workspace-switcher.c
index a3c86cd4..e3fda355 100644
--- a/applets/wncklet/workspace-switcher.c
+++ b/applets/wncklet/workspace-switcher.c
@@ -53,6 +53,153 @@
 
 #define WORKSPACE_SWITCHER_ICON "mate-panel-workspace-switcher"
 
+/* Container for the WnckPager to work around the sizing issues we have in the
+ * panel.  See
+ * https://github.com/mate-desktop/mate-panel/issues/1230#issuecomment-1046235088 */
+
+typedef struct _PagerContainer PagerContainer;
+typedef GtkBinClass PagerContainerClass;
+
+static GType pager_container_get_type (void);
+
+#define PAGER_CONTAINER_TYPE (pager_container_get_type ())
+#define PAGER_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PAGER_CONTAINER_TYPE, PagerContainer))
+
+struct _PagerContainer
+{
+	GtkBin          parent;
+	GtkOrientation  orientation;
+	int             size;
+};
+
+G_DEFINE_TYPE (PagerContainer, pager_container, GTK_TYPE_BIN)
+
+static gboolean
+queue_resize_idle_cb (gpointer user_data)
+{
+	gtk_widget_queue_resize (GTK_WIDGET (user_data));
+	return G_SOURCE_REMOVE;
+}
+
+static void
+pager_container_get_preferred_width (GtkWidget *widget,
+                                     int       *minimum_width,
+                                     int       *natural_width)
+{
+	PagerContainer *self;
+
+	self = PAGER_CONTAINER (widget);
+
+	if (self->orientation == GTK_ORIENTATION_VERTICAL)
+	{
+		/* self->size is panel width */
+		*minimum_width = *natural_width = self->size;
+	}
+	else
+	{
+		/* self->size is panel size/height, that will get allocated to pager, request width for this size */
+		gtk_widget_get_preferred_width_for_height (gtk_bin_get_child (GTK_BIN (self)),
+		                                           self->size,
+		                                           minimum_width,
+		                                           natural_width);
+	}
+}
+
+static void
+pager_container_get_preferred_height (GtkWidget *widget,
+                                      int       *minimum_height,
+                                      int       *natural_height)
+{
+	PagerContainer *self;
+
+	self = PAGER_CONTAINER (widget);
+
+	if (self->orientation == GTK_ORIENTATION_VERTICAL)
+	{
+		/* self->size is panel size/width that will get allocated to pager, request height for this size */
+		gtk_widget_get_preferred_height_for_width (gtk_bin_get_child (GTK_BIN (self)),
+		                                           self->size,
+		                                           minimum_height,
+		                                           natural_height);
+	}
+	else
+	{
+		/* self->size is panel height */
+		*minimum_height = *natural_height = self->size;
+	}
+}
+
+static void
+pager_container_size_allocate (GtkWidget     *widget,
+                               GtkAllocation *allocation)
+{
+	PagerContainer *self;
+	int size;
+
+	self = PAGER_CONTAINER (widget);
+
+	if (self->orientation == GTK_ORIENTATION_VERTICAL)
+		size = allocation->width;
+	else
+		size = allocation->height;
+
+	size = MAX (size, 1);
+
+	if (self->size != size)
+	{
+		self->size = size;
+		g_idle_add (queue_resize_idle_cb, self);
+		return;
+	}
+
+	GTK_WIDGET_CLASS (pager_container_parent_class)->size_allocate (widget,
+	                                                                allocation);
+}
+
+static void
+pager_container_class_init (PagerContainerClass *self_class)
+{
+	GtkWidgetClass *widget_class;
+
+	widget_class = GTK_WIDGET_CLASS (self_class);
+
+	widget_class->get_preferred_width = pager_container_get_preferred_width;
+	widget_class->get_preferred_height = pager_container_get_preferred_height;
+	widget_class->size_allocate = pager_container_size_allocate;
+}
+
+static void
+pager_container_init (PagerContainer *self)
+{
+}
+
+static GtkWidget *
+pager_container_new (GtkWidget     *child,
+                     GtkOrientation orientation)
+{
+	PagerContainer *self;
+
+	self = g_object_new (PAGER_CONTAINER_TYPE, "child", child, NULL);
+
+	self->orientation = orientation;
+
+	return GTK_WIDGET (self);
+}
+
+static void
+pager_container_set_orientation (PagerContainer *self,
+                                 GtkOrientation  orientation)
+{
+	if (self->orientation == orientation)
+		return;
+
+	self->orientation = orientation;
+
+	gtk_widget_queue_resize (GTK_WIDGET (self));
+}
+
+/* Pager applet itself */
+
 typedef enum {
 	PAGER_WM_MARCO,
 	PAGER_WM_METACITY,
@@ -65,6 +212,7 @@ typedef enum {
 typedef struct {
 	GtkWidget* applet;
 
+	GtkWidget* pager_container;
 	GtkWidget* pager;
 
 	WnckScreen* screen;
@@ -290,6 +438,8 @@ static void applet_change_orient(MatePanelApplet* applet, MatePanelAppletOrient
 	pager->orientation = new_orient;
 	pager_update(pager);
 
+	pager_container_set_orientation(PAGER_CONTAINER(pager->pager_container), pager->orientation);
+
 	if (pager->label_row_col)
 		gtk_label_set_text(GTK_LABEL(pager->label_row_col), pager->orientation == GTK_ORIENTATION_HORIZONTAL ? _("rows") : _("columns"));
 }
@@ -657,7 +807,8 @@ gboolean workspace_switcher_applet_fill(MatePanelApplet* applet)
 	                  G_CALLBACK (applet_scroll),
 	                  pager);
 
-	gtk_container_add(GTK_CONTAINER(pager->applet), pager->pager);
+	pager->pager_container = pager_container_new(pager->pager, pager->orientation);
+	gtk_container_add(GTK_CONTAINER(pager->applet), pager->pager_container);
 
 	g_signal_connect (pager->applet, "realize",
 	                  G_CALLBACK (applet_realized),
@@ -676,6 +827,7 @@ gboolean workspace_switcher_applet_fill(MatePanelApplet* applet)
 	                  context);
 
 	gtk_widget_show (pager->pager);
+	gtk_widget_show (pager->pager_container);
 	gtk_widget_show (pager->applet);
 
 	action_group = gtk_action_group_new("WorkspaceSwitcher Applet Actions");

Reply via email to