Compare commits
	
		
			13 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1fac218c70 | |||
| 01bde740bb | |||
| ef516c2082 | |||
| fe39632303 | |||
| e94619883b | |||
| af09304835 | |||
| bd96f4c0c2 | |||
| 83fda9d38a | |||
| 8c89b4dc2c | |||
| b17716a427 | |||
| 367d8dd5c7 | |||
| 97371b8dfb | |||
| 6f66edf8a1 | 
							
								
								
									
										63
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										63
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -108,7 +108,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
 "syn 1.0.109",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@ -129,7 +129,7 @@ checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
 "syn 1.0.109",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@ -325,9 +325,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "indexmap"
 | 
			
		||||
version = "1.9.2"
 | 
			
		||||
version = "1.9.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
 | 
			
		||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "autocfg",
 | 
			
		||||
 "hashbrown",
 | 
			
		||||
@ -350,9 +350,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "libc"
 | 
			
		||||
version = "0.2.139"
 | 
			
		||||
version = "0.2.140"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
 | 
			
		||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "linked-hash-map"
 | 
			
		||||
@ -433,18 +433,18 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "proc-macro2"
 | 
			
		||||
version = "1.0.51"
 | 
			
		||||
version = "1.0.54"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
 | 
			
		||||
checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "unicode-ident",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "quote"
 | 
			
		||||
version = "1.0.23"
 | 
			
		||||
version = "1.0.26"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
 | 
			
		||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
]
 | 
			
		||||
@ -474,9 +474,9 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "ryu"
 | 
			
		||||
version = "1.0.12"
 | 
			
		||||
version = "1.0.13"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
 | 
			
		||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "scoped-tls"
 | 
			
		||||
@ -486,33 +486,33 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde"
 | 
			
		||||
version = "1.0.152"
 | 
			
		||||
version = "1.0.159"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
 | 
			
		||||
checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "serde_derive",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde_derive"
 | 
			
		||||
version = "1.0.152"
 | 
			
		||||
version = "1.0.159"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
 | 
			
		||||
checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
 "syn 2.0.12",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde_repr"
 | 
			
		||||
version = "0.1.10"
 | 
			
		||||
version = "0.1.12"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e"
 | 
			
		||||
checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
 "syn 2.0.12",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@ -529,9 +529,20 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "syn"
 | 
			
		||||
version = "1.0.107"
 | 
			
		||||
version = "1.0.109"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
 | 
			
		||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "unicode-ident",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "syn"
 | 
			
		||||
version = "2.0.12"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
@ -558,9 +569,9 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "unicode-ident"
 | 
			
		||||
version = "1.0.6"
 | 
			
		||||
version = "1.0.8"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
 | 
			
		||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "unicode-width"
 | 
			
		||||
@ -643,7 +654,7 @@ dependencies = [
 | 
			
		||||
 "proc-macro-crate",
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
 "syn 1.0.109",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@ -665,5 +676,5 @@ checksum = "d68726e8c12757384a8d1485080527e263dea67d91f19e97cd71b9292f22d7c5"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
 "syn 1.0.109",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								NEWS.md
									
									
									
									
									
								
							@ -1,3 +1,14 @@
 | 
			
		||||
1.22.0 "Superposition"
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
New or updated translations:
 | 
			
		||||
- Basque
 | 
			
		||||
 | 
			
		||||
Changes:
 | 
			
		||||
- fixed panel sizing when scaling
 | 
			
		||||
- fixed panel sizing when rotating
 | 
			
		||||
- fixed Dvorak terminal layout
 | 
			
		||||
 | 
			
		||||
1.21.0 "Expected value"
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,9 @@ views:
 | 
			
		||||
        - "show_numbers preferences      space        show_actions Return"
 | 
			
		||||
    upper:
 | 
			
		||||
        - "Ctrl Alt PgUp PgDn Home End"
 | 
			
		||||
        - "Shift_L   p y f g c r l  BackSpace"
 | 
			
		||||
        - "a o e u i d h t n s"
 | 
			
		||||
        - ", q j k x b m w v z"
 | 
			
		||||
        - "Shift_L   P Y F G C R L  BackSpace"
 | 
			
		||||
        - "A O E U I D H T N S"
 | 
			
		||||
        - ", Q J K X B M W V Z"
 | 
			
		||||
        - "show_numbers preferences      space        show_actions Return"
 | 
			
		||||
    numbers:
 | 
			
		||||
        - "Ctrl Alt ↑ ↓ ← →"
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,9 @@ views:
 | 
			
		||||
        - "show_numbers preferences      space        show_actions Return"
 | 
			
		||||
    upper:
 | 
			
		||||
        - "EscSmall TabSmall Ctrl Alt PgUp PgDn Home End"
 | 
			
		||||
        - "Shift_L   p y f g c r l  BackSpace"
 | 
			
		||||
        - "a o e u i d h t n s"
 | 
			
		||||
        - ", q j k x b m w v z"
 | 
			
		||||
        - "Shift_L   P Y F G C R L  BackSpace"
 | 
			
		||||
        - "A O E U I D H T N S"
 | 
			
		||||
        - ", Q J K X B M W V Z"
 | 
			
		||||
        - "show_numbers preferences      space        show_actions Return"
 | 
			
		||||
    numbers:
 | 
			
		||||
        - "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,20 @@
 | 
			
		||||
squeekboard (1.22.0-1) experimental; urgency=medium
 | 
			
		||||
 | 
			
		||||
  [ Asier Sarasua Garmendia ]
 | 
			
		||||
  * Add Basque translation
 | 
			
		||||
 | 
			
		||||
  [ Dorota Czaplejewicz ]
 | 
			
		||||
  * state: Make size independent of scaling factor
 | 
			
		||||
  * cleanup: Remove debug prints
 | 
			
		||||
  * tests: Make panel manager modifications pure
 | 
			
		||||
  * panel: Fix sizing on output reconfiguration
 | 
			
		||||
  * Update deps
 | 
			
		||||
 | 
			
		||||
  [ Undef ]
 | 
			
		||||
  * layout: fix uppercase dvorak terminal mode
 | 
			
		||||
 | 
			
		||||
 -- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm>  Sat, 01 Apr 2023 13:46:23 +0000
 | 
			
		||||
 | 
			
		||||
squeekboard (1.21.0-1) experimental; urgency=medium
 | 
			
		||||
 | 
			
		||||
  [ Dorota Czaplejewicz ]
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
project(
 | 
			
		||||
    'squeekboard',
 | 
			
		||||
    'c', 'rust',
 | 
			
		||||
    version: '1.21.0',
 | 
			
		||||
    version: '1.22.0',
 | 
			
		||||
    license: 'GPLv3',
 | 
			
		||||
    meson_version: '>=0.51.0',
 | 
			
		||||
    default_options: [
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ cs
 | 
			
		||||
de
 | 
			
		||||
el
 | 
			
		||||
es
 | 
			
		||||
eu
 | 
			
		||||
fa
 | 
			
		||||
fi
 | 
			
		||||
fr
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										42
									
								
								po/eu.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								po/eu.po
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
# Basque translation for squeekboard.
 | 
			
		||||
# Copyright (C) 2023 squeekboard's COPYRIGHT HOLDER
 | 
			
		||||
# This file is distributed under the same license as the squeekboard package.
 | 
			
		||||
# Asier Sarasua Garmendia <asiersarasua@ni.eus>, 2023.
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr "Project-Id-Version: squeekboard master\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2023-02-26 09:13+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2023-03-06 09:13+0000\n"
 | 
			
		||||
"Last-Translator: Asier Sarasua Garmendia <asiersarasua@ni.eus>\n"
 | 
			
		||||
"Language-Team: Basque <librezale@librezale.eus>\n"
 | 
			
		||||
"Language: eu\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
 | 
			
		||||
#. translators: This is a emmoji keyboard layout
 | 
			
		||||
#: data/popover.ui:6
 | 
			
		||||
msgid "Emoji"
 | 
			
		||||
msgstr "Emojia"
 | 
			
		||||
 | 
			
		||||
#. translators: This is a terminal keyboard layout
 | 
			
		||||
#: data/popover.ui:12
 | 
			
		||||
msgid "Terminal"
 | 
			
		||||
msgstr "Terminala"
 | 
			
		||||
 | 
			
		||||
#: data/popover.ui:18
 | 
			
		||||
msgid "Keyboard Settings"
 | 
			
		||||
msgstr "Teklatuaren ezarpenak"
 | 
			
		||||
 | 
			
		||||
#: data/sm.puri.Squeekboard.desktop.in.in:3
 | 
			
		||||
msgid "Squeekboard"
 | 
			
		||||
msgstr "Squeekboard"
 | 
			
		||||
 | 
			
		||||
#: data/sm.puri.Squeekboard.desktop.in.in:4
 | 
			
		||||
msgid "On Screen Keyboard"
 | 
			
		||||
msgstr "Pantailako teklatua"
 | 
			
		||||
 | 
			
		||||
#: data/sm.puri.Squeekboard.desktop.in.in:5
 | 
			
		||||
msgid "An on screen virtual keyboard"
 | 
			
		||||
msgstr "Gehitu pantailako teklatu birtuala"
 | 
			
		||||
@ -29,9 +29,14 @@ pub mod c {
 | 
			
		||||
    pub struct WlOutput(*const c_void);
 | 
			
		||||
 | 
			
		||||
    impl WlOutput {
 | 
			
		||||
        fn null() -> Self {
 | 
			
		||||
        const fn null() -> Self {
 | 
			
		||||
            Self(ptr::null())
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        #[cfg(test)]
 | 
			
		||||
        pub const fn dummy() -> Self {
 | 
			
		||||
            Self::null()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[repr(C)]
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										243
									
								
								src/panel.rs
									
									
									
									
									
								
							
							
						
						
									
										243
									
								
								src/panel.rs
									
									
									
									
									
								
							@ -94,7 +94,7 @@ impl PixelSize {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
#[derive(Clone, Debug, PartialEq)]
 | 
			
		||||
struct Size {
 | 
			
		||||
    width: u32,
 | 
			
		||||
    height: u32,
 | 
			
		||||
@ -104,7 +104,7 @@ struct Size {
 | 
			
		||||
/// the application asks for some size,
 | 
			
		||||
/// and then receives a size that the compositor thought appropriate.
 | 
			
		||||
/// Stores raw values passed to Wayland, i.e. scaled dimensions.
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
#[derive(Clone, Debug, PartialEq)]
 | 
			
		||||
enum State {
 | 
			
		||||
    Hidden,
 | 
			
		||||
    SizeRequested {
 | 
			
		||||
@ -119,6 +119,18 @@ enum State {
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// A command to send out to the next layer of processing.
 | 
			
		||||
/// Here, it's the C side of the panel.
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
enum Update {
 | 
			
		||||
    Hide,
 | 
			
		||||
    Resize { height: u32 },
 | 
			
		||||
    RequestWidget {
 | 
			
		||||
        output: OutputId,
 | 
			
		||||
        height: u32,
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, PartialEq, Debug)]
 | 
			
		||||
pub enum Command {
 | 
			
		||||
    Show {
 | 
			
		||||
@ -153,7 +165,50 @@ impl Manager {
 | 
			
		||||
            eprintln!("Panel received configure {:?}", &size);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.state = match self.state.clone() {
 | 
			
		||||
        self.state = self.state.clone().configure(size);
 | 
			
		||||
 | 
			
		||||
        if self.debug {
 | 
			
		||||
            eprintln!("Panel now {:?}", &self.state);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn update(mgr: Wrapped<Manager>, cmd: Command) {
 | 
			
		||||
        let copied = mgr.clone();
 | 
			
		||||
 | 
			
		||||
        let mgr = mgr.clone_ref();
 | 
			
		||||
        let mut mgr = mgr.borrow_mut();
 | 
			
		||||
        
 | 
			
		||||
        if mgr.debug {
 | 
			
		||||
            eprintln!("Panel received {:?}", &cmd);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        let (state, updates) = mgr.state.clone().update(cmd);
 | 
			
		||||
        (*mgr).state = state;
 | 
			
		||||
        
 | 
			
		||||
        for update in &updates {
 | 
			
		||||
            unsafe {
 | 
			
		||||
                match update {
 | 
			
		||||
                    Update::Hide => c::panel_manager_hide(mgr.panel),
 | 
			
		||||
                    Update::Resize { height }
 | 
			
		||||
                        => c::panel_manager_resize(mgr.panel, *height),
 | 
			
		||||
                    Update::RequestWidget{output, height}
 | 
			
		||||
                        => c::panel_manager_request_widget(mgr.panel, output.0, *height, copied.clone()),
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if mgr.debug {
 | 
			
		||||
            for update in &updates {
 | 
			
		||||
                eprintln!("Panel updates: {:?}", &update);
 | 
			
		||||
            }
 | 
			
		||||
            eprintln!("Panel is now {:?}", &(*mgr).state);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl State {
 | 
			
		||||
    fn configure(self, size: Size) -> Self {
 | 
			
		||||
         match self {
 | 
			
		||||
            State::Hidden => {
 | 
			
		||||
                // This may happen if a hide is scheduled immediately after a show.
 | 
			
		||||
                log_print!(
 | 
			
		||||
@ -174,49 +229,34 @@ impl Manager {
 | 
			
		||||
                wanted_height: height,
 | 
			
		||||
                allocated: size,
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if self.debug {
 | 
			
		||||
            eprintln!("Panel now {:?}", &self.state);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn update(mgr: Wrapped<Manager>, cmd: Command) {
 | 
			
		||||
        let copied = mgr.clone();
 | 
			
		||||
 | 
			
		||||
        let mgr = mgr.clone_ref();
 | 
			
		||||
        let mut mgr = mgr.borrow_mut();
 | 
			
		||||
        
 | 
			
		||||
        if mgr.debug {
 | 
			
		||||
            eprintln!("Panel received {:?}", &cmd);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        (*mgr).state = match (cmd, mgr.state.clone()) {
 | 
			
		||||
            (Command::Hide, State::Hidden) => State::Hidden,
 | 
			
		||||
            (Command::Hide, State::SizeAllocated{..}) => {
 | 
			
		||||
                unsafe { c::panel_manager_hide(mgr.panel); }
 | 
			
		||||
                State::Hidden
 | 
			
		||||
            },
 | 
			
		||||
            (Command::Hide, State::SizeRequested{..}) => {
 | 
			
		||||
                unsafe { c::panel_manager_hide(mgr.panel); }
 | 
			
		||||
                State::Hidden
 | 
			
		||||
            },
 | 
			
		||||
    fn update(self, cmd: Command) -> (Self, Vec<Update>) {
 | 
			
		||||
        match (cmd, self) {
 | 
			
		||||
            (Command::Hide, State::Hidden) => (State::Hidden, Vec::new()),
 | 
			
		||||
            (Command::Hide, State::SizeAllocated{..}) => (
 | 
			
		||||
                State::Hidden, vec![Update::Hide],
 | 
			
		||||
            ),
 | 
			
		||||
            (Command::Hide, State::SizeRequested{..}) => (
 | 
			
		||||
                State::Hidden, vec![Update::Hide],
 | 
			
		||||
            ),
 | 
			
		||||
            (Command::Show{output, height}, State::Hidden) => {
 | 
			
		||||
                let height = height.as_scaled_ceiling();
 | 
			
		||||
                if mgr.debug {
 | 
			
		||||
                    eprintln!("Panel requests widget {:?}", (&output.0, &height));
 | 
			
		||||
                }
 | 
			
		||||
                unsafe { c::panel_manager_request_widget(mgr.panel, output.0, height, copied); }
 | 
			
		||||
                State::SizeRequested{output, height}
 | 
			
		||||
                (
 | 
			
		||||
                    State::SizeRequested{output, height},
 | 
			
		||||
                    vec![Update::RequestWidget{ output, height }],
 | 
			
		||||
                )
 | 
			
		||||
            },
 | 
			
		||||
            (
 | 
			
		||||
                Command::Show{output, height},
 | 
			
		||||
                State::SizeRequested{output: req_output, height: req_height},
 | 
			
		||||
            ) => {
 | 
			
		||||
                let height = height.as_scaled_ceiling();
 | 
			
		||||
                if output == req_output && height == req_height {
 | 
			
		||||
                    State::SizeRequested{output: req_output, height: req_height}
 | 
			
		||||
                } else if output == req_output {
 | 
			
		||||
                if output == req_output && height == req_height {(
 | 
			
		||||
                    State::SizeRequested{output: req_output, height: req_height},
 | 
			
		||||
                    Vec::new(),
 | 
			
		||||
                )} else if output == req_output {(
 | 
			
		||||
                    // I'm not sure about that.
 | 
			
		||||
                    // This could cause a busy loop,
 | 
			
		||||
                    // when two requests are being processed at the same time:
 | 
			
		||||
@ -225,50 +265,119 @@ impl Manager {
 | 
			
		||||
                    // the other from the state wanting height B',
 | 
			
		||||
                    // causing the compositor to change size to B.
 | 
			
		||||
                    // So better cut this short here, despite artifacts.
 | 
			
		||||
                    // Out of simplicty, just ignore the new request.
 | 
			
		||||
                    // If that causes problems, the request in flight could be stored
 | 
			
		||||
                    // for the purpose of handling it better somehow.
 | 
			
		||||
                    State::SizeRequested{output: req_output, height: req_height}
 | 
			
		||||
                } else {
 | 
			
		||||
                    if mgr.debug {
 | 
			
		||||
                        eprintln!("Panel requests widget {:?}", (&output.0, &height));
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    // Doing nothing means that Squeekboard will occasionally use the stale size (see test),
 | 
			
		||||
                    // so instead always listen to the higher layer and request a new size.
 | 
			
		||||
                    // If this causes problems, maybe count requests/configures, or track what was allocated in response to what request.
 | 
			
		||||
                    State::SizeRequested{output, height},
 | 
			
		||||
                    vec![Update::Resize { height }],
 | 
			
		||||
                )} else {(
 | 
			
		||||
                    // This looks weird, but should be safe.
 | 
			
		||||
                    // The stack seems to handle
 | 
			
		||||
                    // configure events on a dead surface.
 | 
			
		||||
                    unsafe {
 | 
			
		||||
                        c::panel_manager_hide(mgr.panel);
 | 
			
		||||
                        c::panel_manager_request_widget(mgr.panel, output.0, height, copied);
 | 
			
		||||
                    }
 | 
			
		||||
                    State::SizeRequested{output, height}
 | 
			
		||||
                }
 | 
			
		||||
                    State::SizeRequested{output, height},
 | 
			
		||||
                    vec![
 | 
			
		||||
                        Update::Hide,
 | 
			
		||||
                        Update::RequestWidget { output, height },
 | 
			
		||||
                    ],
 | 
			
		||||
                )}
 | 
			
		||||
            },
 | 
			
		||||
            (
 | 
			
		||||
                Command::Show{output, height},
 | 
			
		||||
                State::SizeAllocated{output: alloc_output, allocated, wanted_height},
 | 
			
		||||
            ) => {
 | 
			
		||||
                let height = height.as_scaled_ceiling();
 | 
			
		||||
                if output == alloc_output && height == wanted_height {
 | 
			
		||||
                    State::SizeAllocated{output: alloc_output, wanted_height, allocated}
 | 
			
		||||
                } else if output == alloc_output && height == allocated.height {
 | 
			
		||||
                    State::SizeAllocated{output: alloc_output, wanted_height: height, allocated}
 | 
			
		||||
                } else if output == alloc_output {
 | 
			
		||||
                if output == alloc_output && height == wanted_height {(
 | 
			
		||||
                    State::SizeAllocated{output: alloc_output, wanted_height, allocated},
 | 
			
		||||
                    Vec::new(),
 | 
			
		||||
                )} else if output == alloc_output && height == allocated.height {(
 | 
			
		||||
                    State::SizeAllocated{output: alloc_output, wanted_height: height, allocated},
 | 
			
		||||
                    Vec::new(),
 | 
			
		||||
                )} else if output == alloc_output {(
 | 
			
		||||
                    // Should *all* other heights cause a resize?
 | 
			
		||||
                    // What about those between wanted and allocated?
 | 
			
		||||
                    unsafe { c::panel_manager_resize(mgr.panel, height); }
 | 
			
		||||
                    State::SizeRequested{output, height}
 | 
			
		||||
                } else {
 | 
			
		||||
                    unsafe {
 | 
			
		||||
                        c::panel_manager_hide(mgr.panel);
 | 
			
		||||
                        c::panel_manager_request_widget(mgr.panel, output.0, height, copied);
 | 
			
		||||
                    }
 | 
			
		||||
                    State::SizeRequested{output, height}
 | 
			
		||||
                }
 | 
			
		||||
                    State::SizeRequested{output, height},
 | 
			
		||||
                    vec![Update::Resize{height}],
 | 
			
		||||
                )} else {(
 | 
			
		||||
                    State::SizeRequested{output, height},
 | 
			
		||||
                    vec![
 | 
			
		||||
                        Update::Hide,
 | 
			
		||||
                        Update::RequestWidget{output, height},
 | 
			
		||||
                    ]
 | 
			
		||||
                   )}
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        if mgr.debug {
 | 
			
		||||
            eprintln!("Panel is now {:?}", &(*mgr).state);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    use crate::outputs::c::WlOutput;
 | 
			
		||||
    
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn resize_before_configured() {
 | 
			
		||||
        // allow to make typing fields easier
 | 
			
		||||
        #[allow(non_upper_case_globals)]
 | 
			
		||||
        const output: OutputId = OutputId(WlOutput::dummy());
 | 
			
		||||
        
 | 
			
		||||
        let state = State::Hidden;
 | 
			
		||||
        
 | 
			
		||||
        // Initial show
 | 
			
		||||
        let (state, cmds) = state.update(Command::Show {
 | 
			
		||||
            output,
 | 
			
		||||
            height: PixelSize { pixels: 100, scale_factor: 1 },
 | 
			
		||||
        });
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            cmds,
 | 
			
		||||
            vec![Update::RequestWidget { output, height: 100 }],
 | 
			
		||||
        );
 | 
			
		||||
        // layer shell requests a resize
 | 
			
		||||
 | 
			
		||||
        // but another show comes before first can be confirmed
 | 
			
		||||
        let (state, cmds) = dbg!(state).update(Command::Show {
 | 
			
		||||
            output,
 | 
			
		||||
            height: PixelSize { pixels: 50, scale_factor: 1 },
 | 
			
		||||
        });
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            cmds,
 | 
			
		||||
            vec![Update::Resize { height: 50 }],
 | 
			
		||||
            "{:?}",
 | 
			
		||||
            state,
 | 
			
		||||
        );
 | 
			
		||||
        // This is too many layers of indirection, but as long as layer shell is tied to gtk widgets, there's not much to be done.
 | 
			
		||||
        // The main issue is that as the outputs change, we acknowledge the wrong (maintained) size:
 | 
			
		||||
        /*
 | 
			
		||||
        [346947.774] wl_output@31.geometry(0, 0, 65, 130, 0, "<Unknown>", "<Unknown>", 3)
 | 
			
		||||
[346948.117] wl_output@17.geometry(0, 0, 65, 130, 0, "<Unknown>", "<Unknown>", 3)
 | 
			
		||||
[346948.198] zwlr_layer_surface_v1@41.configure(1709, 720, 210)
 | 
			
		||||
[346948.268]  -> zwlr_layer_surface_v1@41.ack_configure(1709)
 | 
			
		||||
        */
 | 
			
		||||
        // TODO: check if layer_shell allows not acknowledging a configure event, and which part of squeekboard is responsible for that
 | 
			
		||||
        // (there are no messages in between, so it's not PanelMgr; panel.c almost-unconditionally calls to Rust too; could it be layer-shell.c?).
 | 
			
		||||
        
 | 
			
		||||
        // event we want
 | 
			
		||||
        let good_state = state.clone().configure(Size { width: 50, height: 50 });
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            good_state,
 | 
			
		||||
            State::SizeAllocated {
 | 
			
		||||
                output,
 | 
			
		||||
                wanted_height: 50,
 | 
			
		||||
                allocated: Size { width: 50, height: 50 },
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
        
 | 
			
		||||
        // or stale event we do not want
 | 
			
		||||
        let state = state.configure(Size { width: 50, height: 100 });
 | 
			
		||||
        // followed by the good one
 | 
			
		||||
        let state = state.configure(Size { width: 50, height: 50 });
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            state,
 | 
			
		||||
            State::SizeAllocated {
 | 
			
		||||
                output,
 | 
			
		||||
                wanted_height: 50,
 | 
			
		||||
                allocated: Size { width: 50, height: 50 },
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								src/state.rs
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								src/state.rs
									
									
									
									
									
								
							@ -385,19 +385,20 @@ Outcome:
 | 
			
		||||
                let ideal_height = IDEAL_TARGET_SIZE * ROW_COUNT as i32;
 | 
			
		||||
                let ideal_height_px = (ideal_height * density).ceil().0 as u32;
 | 
			
		||||
 | 
			
		||||
                let max_wide_height = Rational {
 | 
			
		||||
                    numerator: 172,
 | 
			
		||||
                    denominator: 540,
 | 
			
		||||
                };
 | 
			
		||||
                let ideal_panel_height = Rational {
 | 
			
		||||
                    numerator: ideal_height_px as i32,
 | 
			
		||||
                    denominator: px_size.width,
 | 
			
		||||
                };
 | 
			
		||||
                // Reduce height to match what the layout can fill.
 | 
			
		||||
                // For this, we need to guess if normal or wide will be picked up.
 | 
			
		||||
                // For this, we need to guess if normal or wide will be picked.
 | 
			
		||||
                // This must match `eek_gtk_keyboard.c::get_type`.
 | 
			
		||||
                // TODO: query layout database and choose one directly
 | 
			
		||||
                let abstract_width
 | 
			
		||||
                    = PixelSize {
 | 
			
		||||
                        scale_factor: output.scale as u32,
 | 
			
		||||
                        pixels: px_size.width,
 | 
			
		||||
                    } 
 | 
			
		||||
                    .as_scaled_ceiling();
 | 
			
		||||
 | 
			
		||||
                let (arrangement, height_as_widths) = {
 | 
			
		||||
                    if abstract_width < 540 {(
 | 
			
		||||
                    if max_wide_height < ideal_panel_height {(
 | 
			
		||||
                        ArrangementKind::Base,
 | 
			
		||||
                        Rational {
 | 
			
		||||
                            numerator: 210,
 | 
			
		||||
@ -405,10 +406,7 @@ Outcome:
 | 
			
		||||
                        },
 | 
			
		||||
                    )} else {(
 | 
			
		||||
                        ArrangementKind::Wide,
 | 
			
		||||
                        Rational {
 | 
			
		||||
                            numerator: 172,
 | 
			
		||||
                            denominator: 540,
 | 
			
		||||
                        }
 | 
			
		||||
                        max_wide_height,
 | 
			
		||||
                    )}
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
@ -755,4 +753,33 @@ pub mod test {
 | 
			
		||||
            )),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn size_l5_scale1() {
 | 
			
		||||
        use crate::outputs::{Mode, Geometry, c, Size};
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            Application::get_preferred_height_and_arrangement(&OutputState {
 | 
			
		||||
                current_mode: Some(Mode {
 | 
			
		||||
                    width: 720,
 | 
			
		||||
                    height: 1440,
 | 
			
		||||
                }),
 | 
			
		||||
                geometry: Some(Geometry{
 | 
			
		||||
                    transform: c::Transform::Normal,
 | 
			
		||||
                    phys_size: Size {
 | 
			
		||||
                        width: Some(Millimeter(65)),
 | 
			
		||||
                        height: Some(Millimeter(130)),
 | 
			
		||||
                    },
 | 
			
		||||
                }),
 | 
			
		||||
                scale: 1,
 | 
			
		||||
            }),
 | 
			
		||||
            Some((
 | 
			
		||||
                PixelSize {
 | 
			
		||||
                    scale_factor: 1,
 | 
			
		||||
                    pixels: 420,
 | 
			
		||||
                },
 | 
			
		||||
                ArrangementKind::Base,
 | 
			
		||||
            )),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										45
									
								
								src/util.rs
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								src/util.rs
									
									
									
									
									
								
							@ -4,6 +4,7 @@ use std::rc::Rc;
 | 
			
		||||
use crate::float_ord::FloatOrd;
 | 
			
		||||
 | 
			
		||||
use std::borrow::Borrow;
 | 
			
		||||
use std::cmp::{Ordering, PartialOrd};
 | 
			
		||||
use std::hash::{ Hash, Hasher };
 | 
			
		||||
use std::ops::Mul;
 | 
			
		||||
 | 
			
		||||
@ -242,6 +243,34 @@ impl<U, T: Mul<U, Output=T>> Mul<Rational<U>> for Rational<T> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PartialEq for Rational<i32> {
 | 
			
		||||
    fn eq(&self, other: &Self) -> bool {
 | 
			
		||||
        (self.denominator as i64).saturating_mul(other.numerator as i64)
 | 
			
		||||
            == (other.denominator as i64).saturating_mul(self.numerator as i64)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Eq for Rational<i32> {}
 | 
			
		||||
 | 
			
		||||
impl Ord for Rational<i32> {
 | 
			
		||||
    fn cmp(&self, other: &Self) -> Ordering {
 | 
			
		||||
        // Using 64-bit values to make overflows unlikely.
 | 
			
		||||
        // If i32_max * u32_max can exceed i64_max,
 | 
			
		||||
        // then this is actually PartialOrd.
 | 
			
		||||
        // Saturating mul used just to avoid propagating mistakes.
 | 
			
		||||
        (other.denominator as i64).saturating_mul(self.numerator as i64)
 | 
			
		||||
            .cmp(
 | 
			
		||||
                &(self.denominator as i64).saturating_mul(other.numerator as i64)
 | 
			
		||||
             )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PartialOrd for Rational<i32> {
 | 
			
		||||
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 | 
			
		||||
        Some(self.cmp(other))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Compares pointers but not internal values of Rc
 | 
			
		||||
pub struct Pointer<T>(pub Rc<T>);
 | 
			
		||||
 | 
			
		||||
@ -327,4 +356,20 @@ mod tests {
 | 
			
		||||
            vec![(5, 0), (6, 0), (7, 0), (5, 1), (6, 1), (7, 1), (5, 2)]
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn check_rational_cmp() {
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            Rational { numerator: 1, denominator: 1 },
 | 
			
		||||
            Rational { numerator: 1, denominator: 1 },
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            Rational { numerator: 1, denominator: 1 },
 | 
			
		||||
            Rational { numerator: 2, denominator: 2 },
 | 
			
		||||
        );
 | 
			
		||||
        assert!(
 | 
			
		||||
            Rational { numerator: 1, denominator: 1 }
 | 
			
		||||
            < Rational { numerator: 2, denominator: 1 }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user