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