From 9dd67ad2bc0c39c0c30936f651e4bed83a172de2 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Fri, 9 Oct 2020 16:20:04 +0200 Subject: [PATCH] server-context-service: optimize height calculation Even though proper size management is being worked on, this patch proposes a simple and easily revertable solution to device-dependent sizing issues. First, it provides different calculations based on the display orientation. In landscape mode, this allows us to have a sensible keyboard size while leaving enough screen estate for apps to be able to display useful information. Then, it gets rid of the weird calculation for display widths between 360 and 540px. While having some continuity is a pleasant idea, in the real world in doesn't work, as shown by port attempts to other devices: a 480x800 display (scale 1) would show an unusable 190px-high keyboard (about half the size of the Librem 5 on-screen keyboard on a device I own). Finally, this commit makes sure we never use a hardcoded size. Tested on the PinePhone, PineTab and Librem 5. Note: Current behavior is preserved on the L5 in portrait mode, but keyboard is a bit smaller in landscape mode; this is deliberate, as it was previously using too much space (causing some apps, such as chatty, to be unusable). --- src/server-context-service.c | 46 +++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/server-context-service.c b/src/server-context-service.c index 515caf6e..0018e772 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -85,13 +85,20 @@ on_notify_unmap (ServerContextService *self, GtkWidget *widget) } static uint32_t -calculate_height(int32_t width) +calculate_height(int32_t width, GdkRectangle *geometry) { - uint32_t height = 180; - if (width < 360 && width > 0) { - height = ((unsigned)width * 7 / 12); // to match 360×210 - } else if (width < 540) { - height = 180 + (540 - (unsigned)width) * 30 / 180; // smooth transition + uint32_t height; + if (geometry->width > geometry->height) { + // 1:5 ratio works fine on lanscape mode, and makes sure there's + // room left for the app window + height = width / 5; + } else { + if (width < 540 && width > 0) { + height = ((unsigned)width * 7 / 12); // to match 360×210 + } else { + // Here we switch to wide layout, less height needed + height = ((unsigned)width * 7 / 22); + } } return height; } @@ -99,6 +106,10 @@ calculate_height(int32_t width) static void on_surface_configure(ServerContextService *self, PhoshLayerSurface *surface) { + GdkDisplay *display = NULL; + GdkWindow *window = NULL; + GdkMonitor *monitor = NULL; + GdkRectangle geometry; gint width; gint height; @@ -110,11 +121,24 @@ on_surface_configure(ServerContextService *self, PhoshLayerSurface *surface) "configured-height", &height, NULL); - // When the geometry event comes after surface.configure, - // this entire height calculation does nothing. - // guint desired_height = squeek_uiman_get_perceptual_height(context->manager); - // Temporarily use old method, until the size manager is complete. - guint desired_height = calculate_height(width); + // In order to improve height calculation, we need the monitor geometry so + // we can use different algorithms for portrait and landscape mode. + // Note: this is a temporary fix until the size manager is complete. + display = gdk_display_get_default (); + if (display) + window = gtk_widget_get_window (GTK_WIDGET (surface)); + if (window) + monitor = gdk_display_get_monitor_at_window (display, window); + if (monitor) + gdk_monitor_get_geometry (monitor, &geometry); + else + geometry.width = geometry.height = 0; + + // When the geometry event comes after surface.configure, + // this entire height calculation does nothing. + // guint desired_height = squeek_uiman_get_perceptual_height(context->manager); + // Temporarily use old method, until the size manager is complete. + guint desired_height = calculate_height(width, &geometry); guint configured_height = (guint)height; // if height was already requested once but a different one was given