Compare commits
	
		
			11 Commits
		
	
	
		
			squeekboar
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						566e54a5aa
	
				 | 
					
					
						|||
| 885383670a | |||
| cdb97d388d | |||
| 8d7afd8e4e | |||
| 8207cb7051 | |||
| 610b30fa12 | |||
| 053faf2598 | |||
| 716fa62e8b | |||
| f786f8d452 | |||
| 30f324c73a | |||
| 6cda9eb617 | 
							
								
								
									
										6
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,9 @@
 | 
				
			|||||||
 | 
					squeekboard (1.44.0~alpha0) UNRELEASED; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * treewide: Increase version to 1.44.0~alpha0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- MoonlightWave-12 <135532-MoonlightWave-12@users.noreply.gitlab.gnome.org>  Fri, 15 Nov 2024 15:37:09 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
squeekboard (1.43.0) experimental; urgency=medium
 | 
					squeekboard (1.43.0) experimental; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [ MoonlightWave-12 ]
 | 
					  [ MoonlightWave-12 ]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
project(
 | 
					project(
 | 
				
			||||||
    'squeekboard',
 | 
					    'squeekboard',
 | 
				
			||||||
    'c', 'rust',
 | 
					    'c', 'rust',
 | 
				
			||||||
    version: '1.43.0',
 | 
					    version: '1.44.0-alpha0',
 | 
				
			||||||
    license: 'GPLv3',
 | 
					    license: 'GPLv3',
 | 
				
			||||||
    meson_version: '>=1.0.0',
 | 
					    meson_version: '>=1.0.0',
 | 
				
			||||||
    default_options: [
 | 
					    default_options: [
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,11 @@
 | 
				
			|||||||
 | 
					ar
 | 
				
			||||||
be
 | 
					be
 | 
				
			||||||
bg
 | 
					bg
 | 
				
			||||||
ca
 | 
					ca
 | 
				
			||||||
cs
 | 
					cs
 | 
				
			||||||
de
 | 
					de
 | 
				
			||||||
el
 | 
					el
 | 
				
			||||||
 | 
					en_GB
 | 
				
			||||||
es
 | 
					es
 | 
				
			||||||
eu
 | 
					eu
 | 
				
			||||||
fa
 | 
					fa
 | 
				
			||||||
@ -17,6 +19,7 @@ hr
 | 
				
			|||||||
ht
 | 
					ht
 | 
				
			||||||
hu
 | 
					hu
 | 
				
			||||||
it
 | 
					it
 | 
				
			||||||
 | 
					ja
 | 
				
			||||||
ka
 | 
					ka
 | 
				
			||||||
ko
 | 
					ko
 | 
				
			||||||
nl
 | 
					nl
 | 
				
			||||||
@ -31,4 +34,5 @@ sr
 | 
				
			|||||||
tr
 | 
					tr
 | 
				
			||||||
uk
 | 
					uk
 | 
				
			||||||
sv
 | 
					sv
 | 
				
			||||||
 | 
					uz
 | 
				
			||||||
zh_CN
 | 
					zh_CN
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										45
									
								
								po/ar.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								po/ar.po
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					# Arabic translation for squeekboard.
 | 
				
			||||||
 | 
					# Copyright (C) 2024 squeekboard's COPYRIGHT HOLDER
 | 
				
			||||||
 | 
					# This file is distributed under the same license as the squeekboard package.
 | 
				
			||||||
 | 
					# Ahmed Mohammed <iramosu@protonmail.com>, 2024.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					msgid ""
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Project-Id-Version: squeekboard main\n"
 | 
				
			||||||
 | 
					"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
 | 
				
			||||||
 | 
					"issues\n"
 | 
				
			||||||
 | 
					"POT-Creation-Date: 2024-08-08 20:39+0000\n"
 | 
				
			||||||
 | 
					"PO-Revision-Date: 2024-10-22 13:54+0300\n"
 | 
				
			||||||
 | 
					"Last-Translator: Ahmed Mohammed <iramosu@protonmail.com>\n"
 | 
				
			||||||
 | 
					"Language-Team: Arabic <Arabic>\n"
 | 
				
			||||||
 | 
					"Language: ar\n"
 | 
				
			||||||
 | 
					"MIME-Version: 1.0\n"
 | 
				
			||||||
 | 
					"Content-Type: text/plain; charset=UTF-8\n"
 | 
				
			||||||
 | 
					"Content-Transfer-Encoding: 8bit\n"
 | 
				
			||||||
 | 
					"X-Generator: Poedit 3.4.3\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#. translators: This is a emmoji keyboard layout
 | 
				
			||||||
 | 
					#: data/popover.ui:6
 | 
				
			||||||
 | 
					msgid "Emoji"
 | 
				
			||||||
 | 
					msgstr "إيموجي"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#. translators: This is a terminal keyboard layout
 | 
				
			||||||
 | 
					#: data/popover.ui:12
 | 
				
			||||||
 | 
					msgid "Terminal"
 | 
				
			||||||
 | 
					msgstr "الطرفية"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/popover.ui:18
 | 
				
			||||||
 | 
					msgid "Keyboard Settings"
 | 
				
			||||||
 | 
					msgstr "إعدادات لوحة المفاتيح"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/sm.puri.Squeekboard.desktop.in.in:3
 | 
				
			||||||
 | 
					msgid "Squeekboard"
 | 
				
			||||||
 | 
					msgstr "سكويك بورد"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/sm.puri.Squeekboard.desktop.in.in:4
 | 
				
			||||||
 | 
					msgid "On Screen Keyboard"
 | 
				
			||||||
 | 
					msgstr "لوحة مفاتيح على الشاشة"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/sm.puri.Squeekboard.desktop.in.in:5
 | 
				
			||||||
 | 
					msgid "An on screen virtual keyboard"
 | 
				
			||||||
 | 
					msgstr "لوحة مفاتيح افتراضية على الشاشة"
 | 
				
			||||||
							
								
								
									
										45
									
								
								po/en_GB.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								po/en_GB.po
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					# British English translation for squeekboard.
 | 
				
			||||||
 | 
					# Copyright (C) 2024 squeekboard's COPYRIGHT HOLDER
 | 
				
			||||||
 | 
					# This file is distributed under the same license as the squeekboard package.
 | 
				
			||||||
 | 
					# Andi Chandler <andi@gowling.com>, 2024.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					msgid ""
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Project-Id-Version: squeekboard master\n"
 | 
				
			||||||
 | 
					"Report-Msgid-Bugs-To: https://source.puri.sm/Librem5/squeekboard/issues\n"
 | 
				
			||||||
 | 
					"POT-Creation-Date: 2024-03-08 15:47+0000\n"
 | 
				
			||||||
 | 
					"PO-Revision-Date: 2024-03-08 16:56+0000\n"
 | 
				
			||||||
 | 
					"Last-Translator: Andi Chandler <andi@gowling.com>\n"
 | 
				
			||||||
 | 
					"Language-Team: British English <en_GB@li.org>\n"
 | 
				
			||||||
 | 
					"Language: en_GB\n"
 | 
				
			||||||
 | 
					"MIME-Version: 1.0\n"
 | 
				
			||||||
 | 
					"Content-Type: text/plain; charset=UTF-8\n"
 | 
				
			||||||
 | 
					"Content-Transfer-Encoding: 8bit\n"
 | 
				
			||||||
 | 
					"Plural-Forms: nplurals=2; plural=(n != 1);;\n"
 | 
				
			||||||
 | 
					"X-Generator: Poedit 3.4.2\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#. translators: This is a emmoji keyboard layout
 | 
				
			||||||
 | 
					#: data/popover.ui:6
 | 
				
			||||||
 | 
					msgid "Emoji"
 | 
				
			||||||
 | 
					msgstr "Emoji"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#. translators: This is a terminal keyboard layout
 | 
				
			||||||
 | 
					#: data/popover.ui:12
 | 
				
			||||||
 | 
					msgid "Terminal"
 | 
				
			||||||
 | 
					msgstr "Terminal"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/popover.ui:18
 | 
				
			||||||
 | 
					msgid "Keyboard Settings"
 | 
				
			||||||
 | 
					msgstr "Keyboard Settings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: 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 "On Screen Keyboard"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/sm.puri.Squeekboard.desktop.in.in:5
 | 
				
			||||||
 | 
					msgid "An on screen virtual keyboard"
 | 
				
			||||||
 | 
					msgstr "An on screen virtual keyboard"
 | 
				
			||||||
							
								
								
									
										45
									
								
								po/ja.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								po/ja.po
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					# Japanese translation for squeekboard.
 | 
				
			||||||
 | 
					# Copyright (C) 2025 squeekboard's COPYRIGHT HOLDER
 | 
				
			||||||
 | 
					# This file is distributed under the same license as the squeekboard package.
 | 
				
			||||||
 | 
					# Kusano Takayuki <https://bsky.app/profile/tkusano.jp>,  2025.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					msgid ""
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Project-Id-Version: squeekboard main\n"
 | 
				
			||||||
 | 
					"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
 | 
				
			||||||
 | 
					"issues\n"
 | 
				
			||||||
 | 
					"POT-Creation-Date: 2025-05-10 22:18+0000\n"
 | 
				
			||||||
 | 
					"PO-Revision-Date: 2025-05-28 23:36+0000\n"
 | 
				
			||||||
 | 
					"Last-Translator: Kusano Takayuki <https://bsky.app/profile/tkusano.jp>\n"
 | 
				
			||||||
 | 
					"Language-Team: Japanese <https://l10n.gnome.org/teams/ja/>\n"
 | 
				
			||||||
 | 
					"Language: ja\n"
 | 
				
			||||||
 | 
					"MIME-Version: 1.0\n"
 | 
				
			||||||
 | 
					"Content-Type: text/plain; charset=UTF-8\n"
 | 
				
			||||||
 | 
					"Content-Transfer-Encoding: 8bit\n"
 | 
				
			||||||
 | 
					"Plural-Forms: nplurals=1; plural=0;\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#. translators: This is a emmoji keyboard layout
 | 
				
			||||||
 | 
					#: data/popover.ui:6
 | 
				
			||||||
 | 
					msgid "Emoji"
 | 
				
			||||||
 | 
					msgstr "絵文字"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#. translators: This is a terminal keyboard layout
 | 
				
			||||||
 | 
					#: data/popover.ui:12
 | 
				
			||||||
 | 
					msgid "Terminal"
 | 
				
			||||||
 | 
					msgstr "端末"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/popover.ui:18
 | 
				
			||||||
 | 
					msgid "Keyboard Settings"
 | 
				
			||||||
 | 
					msgstr "キーボード設定"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: 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 "オンスクリーンキーボード"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/sm.puri.Squeekboard.desktop.in.in:5
 | 
				
			||||||
 | 
					msgid "An on screen virtual keyboard"
 | 
				
			||||||
 | 
					msgstr "オンスクリーンの仮想キーボード"
 | 
				
			||||||
							
								
								
									
										45
									
								
								po/uz.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								po/uz.po
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					# Uzbek (Latin) translation for squeekboard.
 | 
				
			||||||
 | 
					# Copyright (C) 2025 squeekboard's COPYRIGHT HOLDER
 | 
				
			||||||
 | 
					# This file is distributed under the same license as the squeekboard package.
 | 
				
			||||||
 | 
					# Baxrom Raxmatov <magdiyevbahrom@gmail.com>,  2025.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					msgid ""
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Project-Id-Version: squeekboard main\n"
 | 
				
			||||||
 | 
					"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
 | 
				
			||||||
 | 
					"issues\n"
 | 
				
			||||||
 | 
					"POT-Creation-Date: 2025-03-25 17:01+0000\n"
 | 
				
			||||||
 | 
					"PO-Revision-Date: 2025-04-04 22:08+0500\n"
 | 
				
			||||||
 | 
					"Last-Translator: \n"
 | 
				
			||||||
 | 
					"Language-Team: Uzbek (Latin) <uz@li.org>\n"
 | 
				
			||||||
 | 
					"Language: uz\n"
 | 
				
			||||||
 | 
					"MIME-Version: 1.0\n"
 | 
				
			||||||
 | 
					"Content-Type: text/plain; charset=UTF-8\n"
 | 
				
			||||||
 | 
					"Content-Transfer-Encoding: 8bit\n"
 | 
				
			||||||
 | 
					"X-Generator: Poedit 3.6\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#. translators: This is a emmoji keyboard layout
 | 
				
			||||||
 | 
					#: data/popover.ui:6
 | 
				
			||||||
 | 
					msgid "Emoji"
 | 
				
			||||||
 | 
					msgstr "Emoji"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#. translators: This is a terminal keyboard layout
 | 
				
			||||||
 | 
					#: data/popover.ui:12
 | 
				
			||||||
 | 
					msgid "Terminal"
 | 
				
			||||||
 | 
					msgstr "Terminal"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/popover.ui:18
 | 
				
			||||||
 | 
					msgid "Keyboard Settings"
 | 
				
			||||||
 | 
					msgstr "Klaviatura sozlamalari"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: 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 "Ekran klaviaturasi"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: data/sm.puri.Squeekboard.desktop.in.in:5
 | 
				
			||||||
 | 
					msgid "An on screen virtual keyboard"
 | 
				
			||||||
 | 
					msgstr "Ekrandagi virtual klaviatura"
 | 
				
			||||||
@ -1186,7 +1186,7 @@ mod seat {
 | 
				
			|||||||
                        key_id,
 | 
					                        key_id,
 | 
				
			||||||
                        modifier, time,
 | 
					                        modifier, time,
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    false => submission.handle_drop_modifier(key_id, time),
 | 
					                    false => submission.handle_drop_modifier(key_id, modifier, time),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // only show when UI is present
 | 
					            // only show when UI is present
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										204
									
								
								src/popover.rs
									
									
									
									
									
								
							
							
						
						
									
										204
									
								
								src/popover.rs
									
									
									
									
									
								
							@ -1,24 +1,24 @@
 | 
				
			|||||||
/*! The layout chooser popover */
 | 
					/*! The layout chooser popover */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use gio;
 | 
					 | 
				
			||||||
use gtk;
 | 
					 | 
				
			||||||
use std::ffi::CString;
 | 
					 | 
				
			||||||
use std::cmp::Ordering;
 | 
					 | 
				
			||||||
use crate::actors;
 | 
					use crate::actors;
 | 
				
			||||||
use crate::layout::c::{Bounds, EekGtkKeyboard};
 | 
					use crate::layout::c::{Bounds, EekGtkKeyboard};
 | 
				
			||||||
use crate::locale::{ OwnedTranslation, compare_current_locale };
 | 
					use crate::locale::{compare_current_locale, OwnedTranslation};
 | 
				
			||||||
use crate::logging;
 | 
					use crate::logging;
 | 
				
			||||||
use crate::receiver;
 | 
					use crate::receiver;
 | 
				
			||||||
use crate::resources;
 | 
					use crate::resources;
 | 
				
			||||||
use crate::state;
 | 
					use crate::state;
 | 
				
			||||||
 | 
					use gio;
 | 
				
			||||||
 | 
					use gtk;
 | 
				
			||||||
 | 
					use std::cmp::Ordering;
 | 
				
			||||||
 | 
					use std::ffi::CString;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Traits
 | 
					// Traits
 | 
				
			||||||
 | 
					use crate::logging::Warn;
 | 
				
			||||||
use gio::prelude::ActionMapExt;
 | 
					use gio::prelude::ActionMapExt;
 | 
				
			||||||
use gio::prelude::SettingsExt;
 | 
					use gio::prelude::SettingsExt;
 | 
				
			||||||
use glib::translate::FromGlibPtrNone;
 | 
					use glib::translate::FromGlibPtrNone;
 | 
				
			||||||
use glib::variant::ToVariant;
 | 
					use glib::variant::ToVariant;
 | 
				
			||||||
use gtk::prelude::*;
 | 
					use gtk::prelude::*;
 | 
				
			||||||
use crate::logging::Warn;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod c {
 | 
					mod c {
 | 
				
			||||||
    use std::os::raw::c_char;
 | 
					    use std::os::raw::c_char;
 | 
				
			||||||
@ -34,22 +34,23 @@ mod variants {
 | 
				
			|||||||
    use glib_sys;
 | 
					    use glib_sys;
 | 
				
			||||||
    use std::os::raw::c_char;
 | 
					    use std::os::raw::c_char;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    use glib::ToVariant;
 | 
					 | 
				
			||||||
    use glib::translate::FromGlibPtrFull;
 | 
					    use glib::translate::FromGlibPtrFull;
 | 
				
			||||||
    use glib::translate::FromGlibPtrNone;
 | 
					    use glib::translate::FromGlibPtrNone;
 | 
				
			||||||
    use glib::translate::ToGlibPtr;
 | 
					    use glib::translate::ToGlibPtr;
 | 
				
			||||||
 | 
					    use glib::ToVariant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Unpacks tuple & array variants
 | 
					    /// Unpacks tuple & array variants
 | 
				
			||||||
    fn get_items(items: glib::Variant) -> Vec<glib::Variant> {
 | 
					    fn get_items(items: glib::Variant) -> Vec<glib::Variant> {
 | 
				
			||||||
        let variant_naked = items.to_glib_none().0;
 | 
					        let variant_naked = items.to_glib_none().0;
 | 
				
			||||||
        let count = unsafe { glib_sys::g_variant_n_children(variant_naked) };
 | 
					        let count = unsafe { glib_sys::g_variant_n_children(variant_naked) };
 | 
				
			||||||
        (0..count).map(|index| 
 | 
					        (0..count)
 | 
				
			||||||
            unsafe {
 | 
					            .map(|index| unsafe {
 | 
				
			||||||
                glib::Variant::from_glib_full(
 | 
					                glib::Variant::from_glib_full(glib_sys::g_variant_get_child_value(
 | 
				
			||||||
                    glib_sys::g_variant_get_child_value(variant_naked, index)
 | 
					                    variant_naked,
 | 
				
			||||||
                )
 | 
					                    index,
 | 
				
			||||||
            }
 | 
					                ))
 | 
				
			||||||
        ).collect()
 | 
					            })
 | 
				
			||||||
 | 
					            .collect()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Unpacks "a(ss)" variants
 | 
					    /// Unpacks "a(ss)" variants
 | 
				
			||||||
@ -57,12 +58,7 @@ mod variants {
 | 
				
			|||||||
        get_items(items)
 | 
					        get_items(items)
 | 
				
			||||||
            .into_iter()
 | 
					            .into_iter()
 | 
				
			||||||
            .map(get_items)
 | 
					            .map(get_items)
 | 
				
			||||||
            .map(|v| {
 | 
					            .map(|v| (v[0].get::<String>().unwrap(), v[1].get::<String>().unwrap()))
 | 
				
			||||||
                (
 | 
					 | 
				
			||||||
                    v[0].get::<String>().unwrap(),
 | 
					 | 
				
			||||||
                    v[1].get::<String>().unwrap(),
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
            .collect()
 | 
					            .collect()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -88,11 +84,7 @@ mod variants {
 | 
				
			|||||||
                    let a: *const c_char = a.0;
 | 
					                    let a: *const c_char = a.0;
 | 
				
			||||||
                    let b: *const c_char = b.0;
 | 
					                    let b: *const c_char = b.0;
 | 
				
			||||||
                    unsafe {
 | 
					                    unsafe {
 | 
				
			||||||
                        glib_sys::g_variant_builder_add(
 | 
					                        glib_sys::g_variant_builder_add(builder, ispec.0, a, b);
 | 
				
			||||||
                            builder,
 | 
					 | 
				
			||||||
                            ispec.0,
 | 
					 | 
				
			||||||
                            a, b
 | 
					 | 
				
			||||||
                        );
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -115,14 +107,13 @@ fn get_settings(schema_name: &str) -> Option<gio::Settings> {
 | 
				
			|||||||
        logging::Problem::Surprise,
 | 
					        logging::Problem::Surprise,
 | 
				
			||||||
        "No gsettings schemas installed.",
 | 
					        "No gsettings schemas installed.",
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
        .and_then(|sss| 
 | 
					    .and_then(|sss| {
 | 
				
			||||||
            sss.lookup(schema_name, true)
 | 
					        sss.lookup(schema_name, true).or_warn(
 | 
				
			||||||
                .or_warn(
 | 
					 | 
				
			||||||
            &mut error_handler,
 | 
					            &mut error_handler,
 | 
				
			||||||
            logging::Problem::Surprise,
 | 
					            logging::Problem::Surprise,
 | 
				
			||||||
            &format!("Gsettings schema {} not installed", schema_name),
 | 
					            &format!("Gsettings schema {} not installed", schema_name),
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        )
 | 
					    })
 | 
				
			||||||
    .map(|_sschema| gio::Settings::new(schema_name))
 | 
					    .map(|_sschema| gio::Settings::new(schema_name))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -134,14 +125,11 @@ fn set_layout(kind: &str, name: &str) {
 | 
				
			|||||||
        let inputs = settings.value("sources");
 | 
					        let inputs = settings.value("sources");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let current = (kind.clone(), name.clone());
 | 
					        let current = (kind.clone(), name.clone());
 | 
				
			||||||
        let inputs = variants::get_tuples(inputs).into_iter()
 | 
					        let inputs = variants::get_tuples(inputs)
 | 
				
			||||||
 | 
					            .into_iter()
 | 
				
			||||||
            .filter(|t| t != ¤t);
 | 
					            .filter(|t| t != ¤t);
 | 
				
			||||||
        let inputs = vec![(kind, name)].into_iter()
 | 
					        let inputs = vec![(kind, name)].into_iter().chain(inputs).collect();
 | 
				
			||||||
            .chain(inputs).collect();
 | 
					        let _ = settings.set_value("sources", &variants::ArrayPairString(inputs).to_variant());
 | 
				
			||||||
        let _ = settings.set_value(
 | 
					 | 
				
			||||||
            "sources",
 | 
					 | 
				
			||||||
            &variants::ArrayPairString(inputs).to_variant(),
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        settings.apply();
 | 
					        settings.apply();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -150,10 +138,7 @@ fn set_layout(kind: &str, name: &str) {
 | 
				
			|||||||
#[derive(PartialEq, Clone, Debug)]
 | 
					#[derive(PartialEq, Clone, Debug)]
 | 
				
			||||||
pub enum LayoutId {
 | 
					pub enum LayoutId {
 | 
				
			||||||
    /// Affects the layout in system settings
 | 
					    /// Affects the layout in system settings
 | 
				
			||||||
    System {
 | 
					    System { kind: String, name: String },
 | 
				
			||||||
        kind: String,
 | 
					 | 
				
			||||||
        name: String,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    /// Only affects what this input method presents
 | 
					    /// Only affects what this input method presents
 | 
				
			||||||
    Local(String),
 | 
					    Local(String),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -167,14 +152,12 @@ impl LayoutId {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn set_visible_layout(
 | 
					fn set_visible_layout(layout_id: &LayoutId) {
 | 
				
			||||||
    layout_id: &LayoutId,
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
    match layout_id {
 | 
					    match layout_id {
 | 
				
			||||||
        LayoutId::System { kind, name } => {
 | 
					        LayoutId::System { kind, name } => {
 | 
				
			||||||
            set_layout(kind, name);
 | 
					            set_layout(kind, name);
 | 
				
			||||||
        },
 | 
					        }
 | 
				
			||||||
        _ => {},
 | 
					        _ => {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -204,16 +187,15 @@ fn translate_layout_names(layouts: &Vec<LayoutId>) -> Vec<OwnedTranslation> {
 | 
				
			|||||||
    // Attempt to take all xkb names from gnome-desktop's xkb info.
 | 
					    // Attempt to take all xkb names from gnome-desktop's xkb info.
 | 
				
			||||||
    let xkb_translator = crate::locale::XkbInfo::new();
 | 
					    let xkb_translator = crate::locale::XkbInfo::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let translated_names = layouts.iter()
 | 
					    let translated_names = layouts.iter().map(|id| match id {
 | 
				
			||||||
        .map(|id| match id {
 | 
					        LayoutId::System { name, kind: _ } => xkb_translator
 | 
				
			||||||
            LayoutId::System { name, kind: _ } => {
 | 
					            .get_display_name(name)
 | 
				
			||||||
                xkb_translator.get_display_name(name)
 | 
					 | 
				
			||||||
            .map(|s| Status::Translated(OwnedTranslation(s)))
 | 
					            .map(|s| Status::Translated(OwnedTranslation(s)))
 | 
				
			||||||
            .or_print(
 | 
					            .or_print(
 | 
				
			||||||
                logging::Problem::Surprise,
 | 
					                logging::Problem::Surprise,
 | 
				
			||||||
                &format!("No display name for xkb layout {}", name),
 | 
					                &format!("No display name for xkb layout {}", name),
 | 
				
			||||||
                    ).unwrap_or_else(|| Status::Remaining(name.clone()))
 | 
					            )
 | 
				
			||||||
            },
 | 
					            .unwrap_or_else(|| Status::Remaining(name.clone())),
 | 
				
			||||||
        LayoutId::Local(_) => unreachable!(),
 | 
					        LayoutId::Local(_) => unreachable!(),
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -234,7 +216,8 @@ pub fn show(
 | 
				
			|||||||
    unsafe { gtk::set_initialized() };
 | 
					    unsafe { gtk::set_initialized() };
 | 
				
			||||||
    let window = unsafe { gtk::Widget::from_glib_none(window.0) };
 | 
					    let window = unsafe { gtk::Widget::from_glib_none(window.0) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let overlay_layouts = resources::get_overlays().into_iter()
 | 
					    let overlay_layouts = resources::get_overlays()
 | 
				
			||||||
 | 
					        .into_iter()
 | 
				
			||||||
        .map(|name| LayoutId::Local(name.to_string()));
 | 
					        .map(|name| LayoutId::Local(name.to_string()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let settings = get_settings("org.gnome.desktop.input-sources");
 | 
					    let settings = get_settings("org.gnome.desktop.input-sources");
 | 
				
			||||||
@ -246,13 +229,9 @@ pub fn show(
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
        .unwrap_or_else(|| Vec::new());
 | 
					        .unwrap_or_else(|| Vec::new());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let system_layouts: Vec<LayoutId> = inputs.into_iter()
 | 
					    let system_layouts: Vec<LayoutId> = inputs
 | 
				
			||||||
        .map(|(kind, name)| LayoutId::System { kind, name })
 | 
					 | 
				
			||||||
        .collect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let all_layouts: Vec<LayoutId> = system_layouts.clone()
 | 
					 | 
				
			||||||
        .into_iter()
 | 
					        .into_iter()
 | 
				
			||||||
        .chain(overlay_layouts)
 | 
					        .map(|(kind, name)| LayoutId::System { kind, name })
 | 
				
			||||||
        .collect();
 | 
					        .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let translated_names = translate_layout_names(&system_layouts);
 | 
					    let translated_names = translate_layout_names(&system_layouts);
 | 
				
			||||||
@ -268,96 +247,35 @@ pub fn show(
 | 
				
			|||||||
        match (layout_a, layout_b) {
 | 
					        match (layout_a, layout_b) {
 | 
				
			||||||
            (LayoutId::Local(_), LayoutId::System { .. }) => Ordering::Greater,
 | 
					            (LayoutId::Local(_), LayoutId::System { .. }) => Ordering::Greater,
 | 
				
			||||||
            (LayoutId::System { .. }, LayoutId::Local(_)) => Ordering::Less,
 | 
					            (LayoutId::System { .. }, LayoutId::Local(_)) => Ordering::Less,
 | 
				
			||||||
            _ => compare_current_locale(&tr_a.0, &tr_b.0)
 | 
					            _ => compare_current_locale(&tr_a.0, &tr_b.0),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let model: gio::Menu = {
 | 
					    let current_layout = get_current_layout(popover, &system_layouts);
 | 
				
			||||||
        {
 | 
					    let mut found_current = false;
 | 
				
			||||||
            let builder = gtk::Builder::from_resource("/sm/puri/squeekboard/popover.ui");
 | 
					    let mut target_layout = None;
 | 
				
			||||||
            builder.object("app-menu").unwrap()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (tr, l) in human_names.iter().rev() {
 | 
					    for (_, l) in human_names.iter() {
 | 
				
			||||||
        let detailed_action = format!("layout::{}", l.get_name());
 | 
					        if found_current {
 | 
				
			||||||
        let item = gio::MenuItem::new(Some(&tr.0), Some(detailed_action.as_str()));
 | 
					            target_layout = Some(l.clone());
 | 
				
			||||||
        model.prepend_item (&item);
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if let Some(current) = ¤t_layout {
 | 
				
			||||||
 | 
					            if current == l {
 | 
				
			||||||
 | 
					                println!("Found current: {:?} vs {:?}", current, l);
 | 
				
			||||||
 | 
					                found_current = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if target_layout.is_none() {
 | 
				
			||||||
 | 
					        target_layout = human_names.first().map(|item| item.1.clone());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let menu = gtk::Popover::from_model(Some(&window), &model);
 | 
					    if let Some(target) = target_layout {
 | 
				
			||||||
 | 
					        println!("Target layout: {:?}", target);
 | 
				
			||||||
    menu.set_pointing_to(>k::Rectangle::new (
 | 
					 | 
				
			||||||
        position.x.ceil() as i32,
 | 
					 | 
				
			||||||
        position.y.ceil() as i32,
 | 
					 | 
				
			||||||
        position.width.floor() as i32,
 | 
					 | 
				
			||||||
        position.width.floor() as i32,
 | 
					 | 
				
			||||||
    ));
 | 
					 | 
				
			||||||
    menu.set_constrain_to(gtk::PopoverConstraint::None);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let action_group = gio::SimpleActionGroup::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if let Some(current_layout) = get_current_layout(popover, &system_layouts) {
 | 
					 | 
				
			||||||
        let current_layout_name = all_layouts.iter()
 | 
					 | 
				
			||||||
            .find(
 | 
					 | 
				
			||||||
                |l| l.get_name() == current_layout.get_name()
 | 
					 | 
				
			||||||
            ).unwrap()
 | 
					 | 
				
			||||||
            .get_name();
 | 
					 | 
				
			||||||
        log_print!(logging::Level::Debug, "Current Layout {}", current_layout_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let layout_action = gio::SimpleAction::new_stateful(
 | 
					 | 
				
			||||||
            "layout",
 | 
					 | 
				
			||||||
            Some(current_layout_name.to_variant().type_()),
 | 
					 | 
				
			||||||
            ¤t_layout_name.to_variant()
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let menu_inner = menu.clone();
 | 
					 | 
				
			||||||
        layout_action.connect_change_state(move |_action, state| {
 | 
					 | 
				
			||||||
            match state {
 | 
					 | 
				
			||||||
                Some(v) => {
 | 
					 | 
				
			||||||
                    log_print!(logging::Level::Debug, "Selected layout {}", v);
 | 
					 | 
				
			||||||
                    v.get::<String>()
 | 
					 | 
				
			||||||
                        .or_print(
 | 
					 | 
				
			||||||
                            logging::Problem::Bug,
 | 
					 | 
				
			||||||
                            &format!("Variant is not string: {:?}", v)
 | 
					 | 
				
			||||||
                        )
 | 
					 | 
				
			||||||
                        .map(|state| {
 | 
					 | 
				
			||||||
                            let layout = all_layouts.iter()
 | 
					 | 
				
			||||||
                                .find(
 | 
					 | 
				
			||||||
                                    |choices| state == choices.get_name()
 | 
					 | 
				
			||||||
                                ).unwrap();
 | 
					 | 
				
			||||||
        app_state
 | 
					        app_state
 | 
				
			||||||
                                .send(state::Event::OverlayChanged(layout.clone()))
 | 
					            .send(state::Event::OverlayChanged(target.clone()))
 | 
				
			||||||
                                .or_print(
 | 
					            .or_print(logging::Problem::Bug, &format!("Can't send to state"));
 | 
				
			||||||
                                    logging::Problem::Bug,
 | 
					        set_visible_layout(&target);
 | 
				
			||||||
                                    &format!("Can't send to state"),
 | 
					    }
 | 
				
			||||||
                                );
 | 
					 | 
				
			||||||
                            set_visible_layout(layout)
 | 
					 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                None => log_print!(
 | 
					 | 
				
			||||||
                    logging::Level::Debug,
 | 
					 | 
				
			||||||
                    "No variant selected",
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            menu_inner.popdown();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        action_group.add_action(&layout_action);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let settings_action = gio::SimpleAction::new("settings", None);
 | 
					 | 
				
			||||||
    settings_action.set_enabled(popover.settings_active);
 | 
					 | 
				
			||||||
    settings_action.connect_activate(move |_, _| {
 | 
					 | 
				
			||||||
        let s = CString::new("keyboard").unwrap();
 | 
					 | 
				
			||||||
        unsafe { c::popover_open_settings_panel(s.as_ptr()) };
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    action_group.add_action(&settings_action);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    menu.insert_action_group("popup", Some(&action_group));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    menu.bind_model(Some(&model), Some("popup"));
 | 
					 | 
				
			||||||
    glib::idle_add_local(move || {
 | 
					 | 
				
			||||||
        menu.popup();
 | 
					 | 
				
			||||||
        glib::ControlFlow::Break
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -220,7 +220,8 @@ impl Submission {
 | 
				
			|||||||
    pub fn handle_add_modifier(
 | 
					    pub fn handle_add_modifier(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
        key_id: KeyStateId,
 | 
					        key_id: KeyStateId,
 | 
				
			||||||
        modifier: Modifier, _time: Timestamp,
 | 
					        modifier: Modifier,
 | 
				
			||||||
 | 
					        _time: Timestamp,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        self.modifiers_active.push((key_id, modifier));
 | 
					        self.modifiers_active.push((key_id, modifier));
 | 
				
			||||||
        self.update_modifiers();
 | 
					        self.update_modifiers();
 | 
				
			||||||
@ -228,10 +229,11 @@ impl Submission {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub fn handle_drop_modifier(
 | 
					    pub fn handle_drop_modifier(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
        key_id: KeyStateId,
 | 
					        _key_id: KeyStateId,
 | 
				
			||||||
 | 
					        modifier: Modifier,
 | 
				
			||||||
        _time: Timestamp,
 | 
					        _time: Timestamp,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        vec_remove(&mut self.modifiers_active, |(id, _)| *id == key_id);
 | 
					        vec_remove(&mut self.modifiers_active, |(_, m)| *m == modifier);
 | 
				
			||||||
        self.update_modifiers();
 | 
					        self.update_modifiers();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -311,7 +311,7 @@ pub trait WarningHandler {
 | 
				
			|||||||
    fn handle(&mut self, warning: &str);
 | 
					    fn handle(&mut self, warning: &str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Removes the first matcing item
 | 
					/// Removes the first matching item
 | 
				
			||||||
pub fn vec_remove<T, F: FnMut(&T) -> bool>(v: &mut Vec<T>, pred: F) -> Option<T> {
 | 
					pub fn vec_remove<T, F: FnMut(&T) -> bool>(v: &mut Vec<T>, pred: F) -> Option<T> {
 | 
				
			||||||
    let idx = v.iter().position(pred);
 | 
					    let idx = v.iter().position(pred);
 | 
				
			||||||
    idx.map(|idx| v.remove(idx))
 | 
					    idx.map(|idx| v.remove(idx))
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user