From 291afe361cda741dadc1ab0395b710cd31c2471a Mon Sep 17 00:00:00 2001 From: MoonlightWave-12 <135532-MoonlightWave-12@users.noreply.gitlab.gnome.org> Date: Tue, 5 Nov 2024 23:05:47 +0100 Subject: [PATCH 1/6] layout.rs: Fix code-style Part-of: --- src/layout.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index 79fddf4f..4745d073 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -818,8 +818,8 @@ impl LayoutData { let outside_margins = c::Transformation { origin_x: (available.width - (scale_x * size.width)) / 2.0, origin_y: (available.height - (scale_y * size.height)) / 2.0, - scale_x: scale_x, - scale_y: scale_y, + scale_x, + scale_y, }; outside_margins.chain(c::Transformation { origin_x: self.margins.left, From b9f54a4e4b44a078f753378ba92b90bdad9f6034 Mon Sep 17 00:00:00 2001 From: MoonlightWave-12 <135532-MoonlightWave-12@users.noreply.gitlab.gnome.org> Date: Sun, 3 Nov 2024 13:27:34 +0100 Subject: [PATCH 2/6] scaling: Add a setting for fitting layouts to the panel It can be useful to deactivate this while designing layouts, to be able to see the accurate size of those layouts. Part-of: --- data/sm.puri.Squeekboard.gschema.xml | 9 +++++++++ src/layout.rs | 11 ++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/data/sm.puri.Squeekboard.gschema.xml b/data/sm.puri.Squeekboard.gschema.xml index 73f752cd..63f4a979 100644 --- a/data/sm.puri.Squeekboard.gschema.xml +++ b/data/sm.puri.Squeekboard.gschema.xml @@ -27,6 +27,15 @@ For square screens, the setting for screens in landscape-orientation is used. + + true + Wether layouts will stretch to fit the panel or not + + While this setting is active, the proportions of layouts can change, + to fit the available space on the panel. + It can be useful to deactivate this while designing layouts. + + diff --git a/src/layout.rs b/src/layout.rs index 4745d073..72af674c 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -17,6 +17,8 @@ * and let the renderer scale and center it within the widget. */ +use gdk::prelude::SettingsExt; +use gio::Settings; use std::cmp; use std::collections::HashMap; use std::ffi::CString; @@ -809,11 +811,18 @@ impl LayoutData { &self, available: Size, ) -> c::Transformation { + let gsettings = Settings::new("sm.puri.Squeekboard"); + let stretch_layout_to_fit_panel = gsettings.boolean ("layout-shape-changes-to-fit-panel"); + + let layout_stretching_limit: f64; + if stretch_layout_to_fit_panel == true { layout_stretching_limit = 1.055 } + else { layout_stretching_limit = 1.0 }; + let size = self.calculate_size(); let h_scale = available.width / size.width; let v_scale = available.height / size.height; // Allow up to 5% (and a bit more) horizontal stretching for filling up available space - let scale_x = if (h_scale / v_scale) < 1.055 { h_scale } else { v_scale }; + let scale_x = if (h_scale / v_scale) < layout_stretching_limit { h_scale } else { v_scale }; let scale_y = cmp::min(FloatOrd(h_scale), FloatOrd(v_scale)).0; let outside_margins = c::Transformation { origin_x: (available.width - (scale_x * size.width)) / 2.0, From 4483dfcacc9b66cf4b2711bf7d32e7b08aea240d Mon Sep 17 00:00:00 2001 From: MoonlightWave-12 <135532-MoonlightWave-12@users.noreply.gitlab.gnome.org> Date: Tue, 5 Nov 2024 23:05:24 +0100 Subject: [PATCH 3/6] doc/layout.md: Update information about how to deactivate layout-stretching and mention how to activate it again. Part-of: --- doc/layouts.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/layouts.md b/doc/layouts.md index 167dd37a..35a79c97 100644 --- a/doc/layouts.md +++ b/doc/layouts.md @@ -67,9 +67,18 @@ scale = 1.00 ### Layout-stretching -Squeekboard may slightly stretch layouts horizontally (up to 5.5%) before showing them. -For creating layouts with precise sizes, it can be useful to disable this. -This can be done by changing the value `1.055` in the line `let scale_x = if (h_scale / v_scale) < 1.055 { h_scale } else { v_scale };` of the `calculate_transformation` function in `src/layout.rs` to `1.0`, before building Squeekboard. +Layouts will adjust their proportions to fit the available space on a panel. +For creating layouts with precise sizes, it can be useful to deactivate this with: + +``` +$ gsettings set sm.puri.Squeekboard layout-shape-changes-to-fit-panel false +``` + +It can be activated again with: + +``` +$ gsettings set sm.puri.Squeekboard layout-shape-changes-to-fit-panel true +``` Layout syntax ------------- From f87b708867b12696663370e3d30b521bab90f7ba Mon Sep 17 00:00:00 2001 From: MoonlightWave-12 <135532-MoonlightWave-12@users.noreply.gitlab.gnome.org> Date: Wed, 13 Nov 2024 16:42:14 +0100 Subject: [PATCH 4/6] README.md: Mention the settings for layout-stretching Part-of: --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 12ef728e..c00f78ed 100644 --- a/README.md +++ b/README.md @@ -106,8 +106,14 @@ You can change the height of the panel for the keyboard with: $ gsettings set sm.puri.Squeekboard scale-in-horizontal-screen-orientation 1.0 $ gsettings set sm.puri.Squeekboard scale-in-vertical-screen-orientation 1.0 ``` +and wether or not layouts will stretch to fit the panel with: -Note: If the keyboard is open when the settings for the panel-height are changed, the height of the keyboard will not change until it is opened again, or the layout is changed. +```sh +$ gsettings set sm.puri.Squeekboard layout-shape-changes-to-fit-panel true +$ gsettings set sm.puri.Squeekboard layout-shape-changes-to-fit-panel false +``` + +Note: If the keyboard is open when the settings are changed, the changes will not be visible until the keyboard is opened again, or the layout is changed. While using Phosh, you can long-click/long-tap the home-bar at the bottom, to open and close the keyboard. To reset the settings to the default, you can use: From e08f6b4a277b66d26e1926d568557f08e75876f4 Mon Sep 17 00:00:00 2001 From: MoonlightWave-12 <135532-MoonlightWave-12@users.noreply.gitlab.gnome.org> Date: Wed, 13 Nov 2024 21:23:33 +0100 Subject: [PATCH 5/6] scaling: Let layouts stretch to fill the panel so that those can fit various screens better. This is particularly useful for smartphones with an aspect-ratio of 2:1 or wider, while those are held in horizontal orientation. Part-of: --- src/layout.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index 72af674c..c1cac890 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -815,15 +815,30 @@ impl LayoutData { let stretch_layout_to_fit_panel = gsettings.boolean ("layout-shape-changes-to-fit-panel"); let layout_stretching_limit: f64; - if stretch_layout_to_fit_panel == true { layout_stretching_limit = 1.055 } - else { layout_stretching_limit = 1.0 }; + if stretch_layout_to_fit_panel == true { + // The "Base"-layout-shape is intended for use on small displays, + // and thus should fill the available space. + if self.kind == ArrangementKind::Base { layout_stretching_limit = 5.0 } + // The "Wide"-layout-shape is also used on monitors, + // and thus should not stretch more than necessary. + else { layout_stretching_limit = 1.4 } + } + else { layout_stretching_limit = 1.0 } let size = self.calculate_size(); let h_scale = available.width / size.width; let v_scale = available.height / size.height; - // Allow up to 5% (and a bit more) horizontal stretching for filling up available space - let scale_x = if (h_scale / v_scale) < layout_stretching_limit { h_scale } else { v_scale }; - let scale_y = cmp::min(FloatOrd(h_scale), FloatOrd(v_scale)).0; + // Stretch layouts to fill available space, up to some reasonable limits. + // TODO: On screens that are too large to be held during normal use (such as monitors), + // layouts should probably not stretch to fit the panel. + let scale_x = if stretch_layout_to_fit_panel == true { + if (h_scale / v_scale) <= layout_stretching_limit { h_scale } + else { v_scale } + } + else if h_scale / v_scale < 1.0 { h_scale } + else { v_scale }; + let scale_y = if stretch_layout_to_fit_panel == true && h_scale / v_scale > 0.49 { v_scale } + else { cmp::min(FloatOrd(h_scale), FloatOrd(v_scale)).0 }; let outside_margins = c::Transformation { origin_x: (available.width - (scale_x * size.width)) / 2.0, origin_y: (available.height - (scale_y * size.height)) / 2.0, From f311816e22ef7332037b1653facf3dec51361b3b Mon Sep 17 00:00:00 2001 From: MoonlightWave-12 <135532-MoonlightWave-12@users.noreply.gitlab.gnome.org> Date: Thu, 14 Nov 2024 12:43:07 +0100 Subject: [PATCH 6/6] layout.rs: Adjust tests to work with layout-stretching Part-of: --- src/layout.rs | 94 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index c1cac890..6d85ef6a 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -1583,7 +1583,10 @@ mod test { #[test] fn check_bottom_margin() { - // just one button + // TODO: This should work correctly independent from the current settings on the system. + let gsettings = Settings::new("sm.puri.Squeekboard"); + let stretch_layout_to_fit_panel = gsettings.boolean("layout-shape-changes-to-fit-panel"); + // Just one button let view = View::new(vec![ ( 0.0, @@ -1619,21 +1622,25 @@ mod test { layout.calculate_size(), Size { width: 1.0, height: 2.0 } ); - // Don't change those values randomly! - // They take advantage of incidental precise float representation - // to even be comparable. + // Do not change these values randomly, + // because these are comparable due to incidentally precise float-representation. let transformation = layout.calculate_transformation( - Size { width: 2.0, height: 2.0 } + Size { width: 2.0, height: 2.0 } // Panel with a size of 2x2 pixels. ); - assert_eq!(transformation.scale_x, 1.0); - assert_eq!(transformation.scale_y, 1.0); - assert_eq!(transformation.origin_x, 0.5); - assert_eq!(transformation.origin_y, 0.0); + let scale_x_comparison = if stretch_layout_to_fit_panel == true { 2.0 } else { 1.0 }; + let origin_x_comparison = if stretch_layout_to_fit_panel == true { 0.0 } else { 0.5 }; + assert_eq!(transformation.scale_x, scale_x_comparison, "transformation.scale_x changed."); + assert_eq!(transformation.scale_y, 1.0, "transformation.scale_y changed."); + assert_eq!(transformation.origin_x, origin_x_comparison, "transformation.origin_x changed."); + assert_eq!(transformation.origin_y, 0.0, "transformation.origin_y changed."); } #[test] fn check_stretching() { - // just one button + // TODO: This should work correctly independent from the current settings on the system. + let gsettings = Settings::new("sm.puri.Squeekboard"); + let stretch_layout_to_fit_panel = gsettings.boolean("layout-shape-changes-to-fit-panel"); + // Just one button let view = View::new(vec![ ( 0.0, @@ -1660,25 +1667,58 @@ mod test { }, purpose: ContentPurpose::Normal, }; + // Test that layouts will keep their defined proportions, + // if those fit the panel precisely. let transformation = layout.calculate_transformation( Size { width: 100.0, height: 100.0 } ); - assert_eq!(transformation.scale_x, 100.0); - assert_eq!(transformation.scale_y, 100.0); - let transformation = layout.calculate_transformation( - Size { width: 95.0, height: 100.0 } - ); - assert_eq!(transformation.scale_x, 95.0); - assert_eq!(transformation.scale_y, 95.0); - let transformation = layout.calculate_transformation( - Size { width: 105.0, height: 100.0 } - ); - assert_eq!(transformation.scale_x, 105.0); - assert_eq!(transformation.scale_y, 100.0); - let transformation = layout.calculate_transformation( - Size { width: 106.0, height: 100.0 } - ); - assert_eq!(transformation.scale_x, 100.0); - assert_eq!(transformation.scale_y, 100.0); + assert_eq!(transformation.scale_x, 100.0, + "Layout-width changed when it was supposed to not change."); + assert_eq!(transformation.scale_y, 100.0, + "Layout-height changed when it was supposed to not change."); + // Test that layouts will keep their defined proportions when their size decreases, + // if layout-stretching is off. + if stretch_layout_to_fit_panel == false { + let transformation = layout.calculate_transformation( + Size { width: 95.0, height: 100.0 } + ); + assert_eq!(transformation.scale_x, 95.0, + "Layout-width did not decrease by the expected amount."); + assert_eq!(transformation.scale_y, 95.0, + "Layout-height did not decrease by the expected amount."); + } + // Test that layouts adjust to the panel-size, if layout-stretching is on. + if stretch_layout_to_fit_panel == true { + let transformation = layout.calculate_transformation( + Size { width: 500.0, height: 100.0 } + ); + assert_eq!(transformation.scale_x, 500.0, + "Layout-width did not increase by the expected amount."); + assert_eq!(transformation.scale_y, 100.0, + "Layout-height changed when it was supposed to not change."); + let transformation = layout.calculate_transformation( + Size { width: 100.0, height: 204.0 } + ); + assert_eq!(transformation.scale_x, 100.0, + "Layout-width changed when it was supposed to not change."); + assert_eq!(transformation.scale_y, 204.0, + "Layout-height did not increase by the expected amount."); + // Test that layouts will keep their defined proportions, + // if those cannot reach the borders of the screen without stretching by more than the limit. + let transformation = layout.calculate_transformation( + Size { width: 501.0, height: 100.0 } + ); + assert_eq!(transformation.scale_x, 100.0, + "Layout-width changed when it was supposed to not change."); + assert_eq!(transformation.scale_y, 100.0, + "Layout-height changed when it was supposed to not change."); + let transformation = layout.calculate_transformation( + Size { width: 100.0, height: 205.0 } + ); + assert_eq!(transformation.scale_x, 100.0, + "Layout-width changed when it was supposed to not change."); + assert_eq!(transformation.scale_y, 100.0, + "Layout-height changed when it was supposed to not change."); + } } }