summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeandro Ribeiro <leandrohr@riseup.net>2020-01-24 18:10:59 -0300
committerDaniel Stone <daniels@collabora.com>2020-08-26 14:10:50 +0000
commit33e29d88cc109555ee8286ae06b1580ef0f42c92 (patch)
tree884d0d2b7b0e6b382615d0f8fa9045b681f04635
parentb68454e893d4ffbe7a0789983e787a4f31eeaeef (diff)
downloadweston-33e29d88cc109555ee8286ae06b1580ef0f42c92.tar.gz
weston-33e29d88cc109555ee8286ae06b1580ef0f42c92.tar.bz2
weston-33e29d88cc109555ee8286ae06b1580ef0f42c92.zip
exposay: make inner border dependent of exposay's surfaces size
We've been using an inner border of fixed size (80px), but this is dangerous. If you have too many open applications or a small window, the surface size computed will be negative, crashing the exposay: "error: weston_view transformation not invertible". Also, it creates a lot of unnecessary space, making the exposay unusable when we have a small window or many applications open. Make inner border to be 10% of surface size and surface size to be 90% of its original size, avoiding the crashes and making it more visually pleasant. Signed-off-by: Leandro Ribeiro <leandrohr@riseup.net>
-rw-r--r--desktop-shell/exposay.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c
index 7594301a..e03a3114 100644
--- a/desktop-shell/exposay.c
+++ b/desktop-shell/exposay.c
@@ -207,9 +207,42 @@ handle_view_destroy(struct wl_listener *listener, void *data)
exposay_surface_destroy(esurface);
}
-/* Pretty lame layout for now; just tries to make a square. Should take
+/* Compute each surface size and then inner pad (10% of surface size).
+ * After that, it's necessary to recompute surface size (90% of its
+ * original size). Also, each surface can't be bigger than half the
+ * exposay area width and height.
+ */
+static void
+exposay_surface_and_inner_pad_size(pixman_rectangle32_t exposay_area, struct exposay_output *eoutput)
+{
+ if (exposay_area.height < exposay_area.width)
+ eoutput->surface_size =
+ (exposay_area.height - (eoutput->vpadding_outer * 2)) / eoutput->grid_size;
+ else
+ eoutput->surface_size =
+ (exposay_area.width - (eoutput->hpadding_outer * 2)) / eoutput->grid_size;
+ eoutput->padding_inner = eoutput->surface_size / 10;
+ eoutput->surface_size -= eoutput->padding_inner;
+
+ if ((uint32_t)eoutput->surface_size > (exposay_area.width / 2))
+ eoutput->surface_size = exposay_area.width / 2;
+ if ((uint32_t)eoutput->surface_size > (exposay_area.height / 2))
+ eoutput->surface_size = exposay_area.height / 2;
+}
+
+/* Pretty lame layout for now; just tries to make a square. Should take
* aspect ratio into account really. Also needs to be notified of surface
- * addition and removal and adjust layout/animate accordingly. */
+ * addition and removal and adjust layout/animate accordingly.
+ *
+ * Lay the grid out as square as possible, losing surfaces from the
+ * bottom row if required. Start with fixed padding of a 10% margin
+ * around the outside, and maximise the area made available to surfaces
+ * after this. Also, add an inner padding between surfaces that varies
+ * with the surface size (10% of its size).
+ *
+ * If we can't make a square grid, add one extra row at the bottom which
+ * will have a smaller number of columns.
+ */
static enum exposay_layout_state
exposay_layout(struct desktop_shell *shell, struct shell_output *shell_output)
{
@@ -219,7 +252,6 @@ exposay_layout(struct desktop_shell *shell, struct shell_output *shell_output)
struct weston_view *view;
struct exposay_surface *esurface, *highlight = NULL;
pixman_rectangle32_t exposay_area;
- int w, h;
int pad;
int i;
int last_row_removed = 0;
@@ -246,40 +278,18 @@ exposay_layout(struct desktop_shell *shell, struct shell_output *shell_output)
* the shell panel position and size */
get_output_work_area(shell, output, &exposay_area);
- /* Lay the grid out as square as possible, losing surfaces from the
- * bottom row if required. Start with fixed padding of a 10% margin
- * around the outside and 80px internal padding between surfaces, and
- * maximise the area made available to surfaces after this, but only
- * to a maximum of 1/3rd the total output size.
- *
- * If we can't make a square grid, add one extra row at the bottom
- * which will have a smaller number of columns.
- *
- * XXX: Surely there has to be a better way to express this maths,
- * right?!
- */
+ /* Compute grid size */
eoutput->grid_size = floor(sqrtf(eoutput->num_surfaces));
if (pow(eoutput->grid_size, 2) != eoutput->num_surfaces)
eoutput->grid_size++;
last_row_removed = pow(eoutput->grid_size, 2) - eoutput->num_surfaces;
+ /* Fixed outer padding of 10% the size of the screen */
eoutput->hpadding_outer = (exposay_area.width / 10);
eoutput->vpadding_outer = (exposay_area.height / 10);
- eoutput->padding_inner = 80;
-
- w = exposay_area.width - (eoutput->hpadding_outer * 2);
- w -= eoutput->padding_inner * (eoutput->grid_size - 1);
- w /= eoutput->grid_size;
- h = exposay_area.height - (eoutput->vpadding_outer * 2);
- h -= eoutput->padding_inner * (eoutput->grid_size - 1);
- h /= eoutput->grid_size;
-
- eoutput->surface_size = (w < h) ? w : h;
- if ((uint32_t)eoutput->surface_size > (exposay_area.width / 2))
- eoutput->surface_size = exposay_area.width / 2;
- if ((uint32_t)eoutput->surface_size > (exposay_area.height / 2))
- eoutput->surface_size = exposay_area.height / 2;
+ /* Compute each surface size and the inner padding between them */
+ exposay_surface_and_inner_pad_size(exposay_area, eoutput);
pad = eoutput->surface_size + eoutput->padding_inner;