1 parent
79ae6cab4c
commit
a990bbef9c
33 files changed
+670
-225
No files matched your search
@@ -68,6 +68,7 @@
|
||||
D04BA9557A6C9E192D228150 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BA2C08725A5F2C34EB809 /* InfoPlist.strings */; };
|
||||
D04BA9B7A964C5FABFEB9DA2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BA053A0E0157E817B2E04 /* Localizable.strings */; };
|
||||
D04BA9D63A88AF2C20A1E656 /* SF-Pro-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = D04BA60A6D08C041F5BF8CC9 /* SF-Pro-Text-Regular.otf */; };
|
||||
D04BAA16F21AC41A23DDA63D /* ControlsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA1B438BF3E65044D1138 /* ControlsTab.swift */; };
|
||||
D04BAAAF5CFA991D3B078DB8 /* KeyboardEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA4A621A8A15660F973C1 /* KeyboardEvents.swift */; };
|
||||
D04BAAB5C4E78AE375EA7D3C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D04BAA56B4EEAF17F767C7FD /* Localizable.strings */; };
|
||||
D04BAABE804F3769CE22BEB6 /* HyperlinkLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA49E45BFFF3D9FC60E43 /* HyperlinkLabel.swift */; };
|
||||
@@ -130,6 +131,7 @@
|
||||
D04BA18724DC58FA95DB33DB /* Podfile.lock */ = {isa = PBXFileReference; lastKnownFileType = file.lock; path = Podfile.lock; sourceTree = "<group>"; };
|
||||
D04BA18B55AA6C9EE41985D0 /* Contributing.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Contributing.md; sourceTree = "<group>"; };
|
||||
D04BA19E22F2B73DB785E5DB /* subset_fonticon.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = subset_fonticon.sh; sourceTree = "<group>"; };
|
||||
D04BA1B438BF3E65044D1138 /* ControlsTab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlsTab.swift; sourceTree = "<group>"; };
|
||||
D04BA1C3E42AC44CA2C5D3D8 /* app-icon.svg */ = {isa = PBXFileReference; lastKnownFileType = file.svg; path = "app-icon.svg"; sourceTree = "<group>"; };
|
||||
D04BA1D80F4EEF2A91BAD29C /* release.config.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = release.config.js; sourceTree = "<group>"; };
|
||||
D04BA1DF8CAB2FAB7FE9244B /* ThumbnailFontIconView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThumbnailFontIconView.swift; sourceTree = "<group>"; };
|
||||
@@ -494,6 +496,7 @@
|
||||
D04BAD60C97E609A759E721E /* PoliciesTab.swift */,
|
||||
D04BA788228BA86D9EFBD1ED /* AcknowledgmentsTab.swift */,
|
||||
D04BA27695D9A5824720BD7B /* BlacklistsTab.swift */,
|
||||
D04BA1B438BF3E65044D1138 /* ControlsTab.swift */,
|
||||
);
|
||||
path = tabs;
|
||||
sourceTree = "<group>";
|
||||
@@ -1120,6 +1123,7 @@
|
||||
D04BAFF30A98CF287F85DA1E /* BlacklistsTab.swift in Sources */,
|
||||
D04BA56789A2AF52557A9BFF /* AppCenterCrashes.swift in Sources */,
|
||||
D04BADA3F2DAB820D6FC6E75 /* AppCenterApplication.m in Sources */,
|
||||
D04BAA16F21AC41A23DDA63D /* ControlsTab.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -88,9 +91,15 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Close window" = "Close window";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Controls" = "Controls";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Don’t check for updates periodically" = "Don’t check for updates periodically";
|
||||
|
||||
@@ -187,9 +196,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Optional: email (if you want a reply)" = "Optional: email (if you want a reply)";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"or press:" = "or press:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Policies" = "Policies";
|
||||
|
||||
@@ -229,9 +235,6 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Select previous window" = "Select previous window";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Select windows using:" = "Select windows using:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Send" = "Send";
|
||||
|
||||
@@ -253,6 +256,12 @@
|
||||
/* No comment provided by engineer. */
|
||||
"Share improvement ideas, or report bugs" = "Share improvement ideas, or report bugs";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/* Menubar option */
|
||||
"Show" = "Show";
|
||||
|
||||
@@ -295,6 +304,9 @@
|
||||
/* No comment provided by engineer. */
|
||||
"View existing discussions" = "View existing discussions";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"Window app icon size:" = "Window app icon size:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "إغلاق النافذة";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "لا تبحث عن تحديثات بشكل دوري";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "شارك أفكارك التطويرية، أو بلغ عن أخطاء";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "إظهار";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "أنظر للنقاشات الحالية";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "حجم أيقونة النافذة:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Erlaubt";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab ist bei der letzten Ausführung abgestürzt. Das Absenden von Absturzberichten hilft bei der Fehlerbeseitigung.";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Fenster schließen";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Richtlinie für Absturzberichte:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Nicht regelmäßig nach Updates suchen";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Teile uns deine Vorschläge mit oder melden Fehler";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Anzeigen";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Bestehende Vorschläge anzeigen";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Fenster Icon Größe:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Close window";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Don’t check for updates periodically";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Share improvement ideas, or report bugs";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Show";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "View existing discussions";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Window app icon size:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Cerrar ventana";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "No comprobar actualizaciones periódicamente";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Comparta ideas de mejora o informe de errores";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Mostrar";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Ver discusiones existentes";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Tamaño del icono de la ventana de aplicación:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Sulje ikkuna";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Älä tarkista päivityksiä";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Jaa parannusehdotuksia tai raportoi bugeja";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Näytä";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Näytä keskustelut";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Ohjelmaikonin koko:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Autorisé";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Fermer la fenêtre";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Ne pas chercher de mise-à-jour périodiquement";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Partagez des idées d’amélioration, ou signalez des bugs";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Afficher";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Voir les discussions existantes";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Taille des icones des applications :";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Engedélyezve";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Ablak bezárása";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Ne keressen frissítéseket automatikusan";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Fejlesztési ötletek megosztása, hibabejelentés";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Mutat";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Aktuális beszélgetések megtekintése";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Ablak alkalmazásikonméret:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Dibolehkan";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Tutup jendela";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Jangan periksa pembaruan secara berkala";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Bagikan gagasan peningkatan, atau laporkan bug";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Tampilkan";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Lihat diskusi yang ada";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Ukuran ikon aplikasi jendela:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Chiudi la finestra";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Non controllare gli aggiornamenti periodicamente";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Condividi idee per miglioramenti oppure riporta problemi";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Mostra";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Mostra discussioni esistenti";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Dimensione dell’icona della finestra dell’applicazione:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "ウィンドウを閉じる";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "定期的に更新を確認しない";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "改善点のご共有あるいはバグのご報告";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "アプリを表示";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "既にあるディスカッションを見る";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "ウィンドウに表示されるアイコンサイズ:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "허용됨";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "마지막으로 사용하고 나서 AltTab이 충돌했습니다. 충돌 리포트를 보내는 것은 이 문제를 해결하는데 도움을 줄 수 있습니다";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "윈도우 닫기";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "충돌 리포트 처리 방법:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "주기적으로 업데이트를 확인하지 않기";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "개선방안을 공유하거나 버그를 제보해주세요";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "보기";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "진행중인 논의 보기";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "윈도우 앱 아이콘 크기:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Close window";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Net reegelméisseg no Updates sichen";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Share improvement ideas, or report bugs";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Opbréngen";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "View existing discussions";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Window app icon size:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Sluit venster";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Controleer niet regelmatig op updates";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Deel verbetervoorstellen of meld bugs";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Toon";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Bekijk bestaande discussies";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Icoongrootte vensterapplicatie:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Fechar janela";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Não verifique periodicamente por atualizações";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Compartilhar sugestões ou reportar falhas";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Exibir";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Ver discussões existentes";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Tamanho do ícone da aplicação:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Разрешено";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab аварийно завершился в последний раз, когда вы его использовали. Отправка отчета поможет исправить проблему";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Закрыть окно";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Правило отчетов о вылетах:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Не проверять обновления";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Поделитесь идеями по улучшению или сообщите об ошибках";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Показать";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Посмотреть обсуждения";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Размер иконки окна:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "Pencereyi kapat";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "Güncellemeleri periyodik olarak kontrol etme";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "Fikir yada hata paylaş";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "Göster";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "Mevcut tartışmaları görüntüle";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "Pencere simge boyutu:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "允许";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab 在您上次使用时崩溃了, 发送崩溃报告将有助于解决问题";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "关闭窗口";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "崩溃报告政策:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "不自动检查更新";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "反馈建议或报告错误";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "显示";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "查看现有讨论";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "窗口图标大小:";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Allowed" = "Allowed";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Also select windows using:" = "Also select windows using:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"AltTab crashed last time you used it. Sending a crash report will help get the issue fixed" = "AltTab crashed last time you used it. Sending a crash report will help get the issue fixed";
|
||||
|
||||
@@ -89,9 +92,15 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Close window" = "關閉視窗";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Controls" = "Controls";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Crash reports policy:" = "Crash reports policy:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Do nothing" = "Do nothing";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Don’t check for updates periodically" = "不要定期自動檢查更新";
|
||||
|
||||
@@ -257,6 +266,12 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"Share improvement ideas, or report bugs" = "分享改進的想法,或是回報問題";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 1" = "Shortcut 1";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Shortcut 2" = "Shortcut 2";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Show" = "顯示";
|
||||
|
||||
@@ -299,6 +314,9 @@
|
||||
/*No comment provided by engineer.*/
|
||||
"View existing discussions" = "觀看目前的討論";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"While open, press:" = "While open, press:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Window app icon size:" = "視窗圖示的大小:";
|
||||
|
||||
|
||||
@@ -127,3 +127,23 @@ extension DispatchQoS {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension NSGridColumn {
|
||||
func width(_ skipCell: Int? = nil) -> CGFloat {
|
||||
var maxWidth = CGFloat(0)
|
||||
for i in (0..<numberOfCells) {
|
||||
if let skipCell = skipCell, i == skipCell { continue }
|
||||
maxWidth = max(maxWidth, cell(at: i).contentView!.fittingSize.width)
|
||||
}
|
||||
return maxWidth
|
||||
}
|
||||
}
|
||||
|
||||
extension NSViewController {
|
||||
func setView(_ subview: NSView) {
|
||||
view = NSView(frame: .zero)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.subviews = [subview]
|
||||
subview.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
||||
}
|
||||
}
|
||||
+49
-31
@@ -13,8 +13,10 @@ class Preferences {
|
||||
"iconSize": "32",
|
||||
"fontHeight": "15",
|
||||
"holdShortcut": "⌥",
|
||||
"holdShortcut2": "⌥",
|
||||
"nextWindowShortcut": "⇥",
|
||||
"nextWindowShortcut2": keyAboveTabDependingOnInputSource(),
|
||||
"focusWindowShortcut": "↩",
|
||||
"previousWindowShortcut": "⇧",
|
||||
"cancelShortcut": "⎋",
|
||||
"closeWindowShortcut": "W",
|
||||
@@ -55,6 +57,7 @@ class Preferences {
|
||||
"rowsCount": defaultsDependingOnScreenRatio_["rowsCount"]!,
|
||||
"minCellsPerRow": defaultsDependingOnScreenRatio_["minCellsPerRow"]!,
|
||||
"maxCellsPerRow": defaultsDependingOnScreenRatio_["maxCellsPerRow"]!,
|
||||
"shortcutStyle": "0",
|
||||
]
|
||||
|
||||
// constant values
|
||||
@@ -74,7 +77,9 @@ class Preferences {
|
||||
static var iconSize: CGFloat { defaults.cgfloat("iconSize") }
|
||||
static var fontHeight: CGFloat { defaults.cgfloat("fontHeight") }
|
||||
static var holdShortcut: String { defaults.string("holdShortcut") }
|
||||
static var holdShortcut2: String { defaults.string("holdShortcut2") }
|
||||
static var nextWindowShortcut: [String] { ["nextWindowShortcut", "nextWindowShortcut2"].map { defaults.string($0) } }
|
||||
static var focusWindowShortcut: String { defaults.string("focusWindowShortcut") }
|
||||
static var previousWindowShortcut: String { defaults.string("previousWindowShortcut") }
|
||||
static var cancelShortcut: String { defaults.string("cancelShortcut") }
|
||||
static var closeWindowShortcut: String { defaults.string("closeWindowShortcut") }
|
||||
@@ -108,6 +113,7 @@ class Preferences {
|
||||
static var appsToShow: [AppsToShowPreference] { ["appsToShow", "appsToShow2"].map { defaults.macroPref($0, AppsToShowPreference.allCases) } }
|
||||
static var spacesToShow: [SpacesToShowPreference] { ["spacesToShow", "spacesToShow2"].map { defaults.macroPref($0, SpacesToShowPreference.allCases) } }
|
||||
static var screensToShow: [ScreensToShowPreference] { ["screensToShow", "screensToShow2"].map { defaults.macroPref($0, ScreensToShowPreference.allCases) } }
|
||||
static var shortcutStyle: ShortcutStylePreference { defaults.macroPref("shortcutStyle", ShortcutStylePreference.allCases) }
|
||||
|
||||
// derived values
|
||||
static var cellBorderWidth: CGFloat { theme.themeParameters.cellBorderWidth }
|
||||
@@ -203,9 +209,21 @@ struct ThemeParameters {
|
||||
|
||||
typealias LocalizedString = String
|
||||
|
||||
enum AppsToShowPreference: String, CaseIterable, MacroPreference {
|
||||
case all = "All apps"
|
||||
case active = "Active app"
|
||||
enum ShortcutStylePreference: CaseIterable, MacroPreference {
|
||||
case focusOnRelease
|
||||
case doNothingOnRelease
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
case .focusOnRelease: return NSLocalizedString("Focus selected window", comment: "")
|
||||
case .doNothingOnRelease: return NSLocalizedString("Do nothing", comment: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum AppsToShowPreference: CaseIterable, MacroPreference {
|
||||
case all
|
||||
case active
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
@@ -215,9 +233,9 @@ enum AppsToShowPreference: String, CaseIterable, MacroPreference {
|
||||
}
|
||||
}
|
||||
|
||||
enum SpacesToShowPreference: String, CaseIterable, MacroPreference {
|
||||
case all = "0"
|
||||
case active = "1"
|
||||
enum SpacesToShowPreference: CaseIterable, MacroPreference {
|
||||
case all
|
||||
case active
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
@@ -227,9 +245,9 @@ enum SpacesToShowPreference: String, CaseIterable, MacroPreference {
|
||||
}
|
||||
}
|
||||
|
||||
enum ScreensToShowPreference: String, CaseIterable, MacroPreference {
|
||||
case all = "0"
|
||||
case showingAltTab = "1"
|
||||
enum ScreensToShowPreference: CaseIterable, MacroPreference {
|
||||
case all
|
||||
case showingAltTab
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
@@ -239,10 +257,10 @@ enum ScreensToShowPreference: String, CaseIterable, MacroPreference {
|
||||
}
|
||||
}
|
||||
|
||||
enum ShowOnScreenPreference: String, CaseIterable, MacroPreference {
|
||||
case active = "0"
|
||||
case includingMouse = "1"
|
||||
case includingMenubar = "2"
|
||||
enum ShowOnScreenPreference: CaseIterable, MacroPreference {
|
||||
case active
|
||||
case includingMouse
|
||||
case includingMenubar
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
@@ -253,10 +271,10 @@ enum ShowOnScreenPreference: String, CaseIterable, MacroPreference {
|
||||
}
|
||||
}
|
||||
|
||||
enum TitleTruncationPreference: String, CaseIterable, MacroPreference {
|
||||
case end = "0"
|
||||
case middle = "1"
|
||||
case start = "2"
|
||||
enum TitleTruncationPreference: CaseIterable, MacroPreference {
|
||||
case end
|
||||
case middle
|
||||
case start
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
@@ -267,9 +285,9 @@ enum TitleTruncationPreference: String, CaseIterable, MacroPreference {
|
||||
}
|
||||
}
|
||||
|
||||
enum AlignThumbnailsPreference: String, CaseIterable, MacroPreference {
|
||||
case left = "0"
|
||||
case center = "1"
|
||||
enum AlignThumbnailsPreference: CaseIterable, MacroPreference {
|
||||
case left
|
||||
case center
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
@@ -279,9 +297,9 @@ enum AlignThumbnailsPreference: String, CaseIterable, MacroPreference {
|
||||
}
|
||||
}
|
||||
|
||||
enum ThemePreference: String, CaseIterable, MacroPreference {
|
||||
case macOs = "0"
|
||||
case windows10 = "1"
|
||||
enum ThemePreference: CaseIterable, MacroPreference {
|
||||
case macOs
|
||||
case windows10
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
@@ -298,10 +316,10 @@ enum ThemePreference: String, CaseIterable, MacroPreference {
|
||||
}
|
||||
}
|
||||
|
||||
enum UpdatePolicyPreference: String, CaseIterable, MacroPreference {
|
||||
case manual = "0"
|
||||
case autoCheck = "1"
|
||||
case autoInstall = "2"
|
||||
enum UpdatePolicyPreference: CaseIterable, MacroPreference {
|
||||
case manual
|
||||
case autoCheck
|
||||
case autoInstall
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
@@ -312,10 +330,10 @@ enum UpdatePolicyPreference: String, CaseIterable, MacroPreference {
|
||||
}
|
||||
}
|
||||
|
||||
enum CrashPolicyPreference: String, CaseIterable, MacroPreference {
|
||||
case never = "0"
|
||||
case ask = "1"
|
||||
case always = "2"
|
||||
enum CrashPolicyPreference: CaseIterable, MacroPreference {
|
||||
case never
|
||||
case ask
|
||||
case always
|
||||
|
||||
var localizedString: LocalizedString {
|
||||
switch self {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Cocoa
|
||||
import Carbon.HIToolbox.Events
|
||||
import ShortcutRecorder
|
||||
|
||||
fileprivate var eventTap: CFMachPort?
|
||||
|
||||
@@ -27,22 +28,16 @@ private func observe_() {
|
||||
|
||||
private func keyboardHandler(_: CGEventTapProxy, type: CGEventType, cgEvent: CGEvent, _: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? {
|
||||
if (type == .keyDown || type == .keyUp || type == .flagsChanged) && !App.app.shortcutsShouldBeDisabled {
|
||||
if let event_ = NSEvent(cgEvent: cgEvent),
|
||||
// workaround: NSEvent.characters is not safe outside of the main thread; this is not documented by Apple
|
||||
// see https://github.com/Kentzo/ShortcutRecorder/issues/114#issuecomment-606465340
|
||||
let event = NSEvent.keyEvent(with: event_.type, location: event_.locationInWindow, modifierFlags: event_.modifierFlags,
|
||||
timestamp: event_.timestamp, windowNumber: event_.windowNumber, context: nil, characters: "",
|
||||
charactersIgnoringModifiers: "", isARepeat: type == .flagsChanged ? false : event_.isARepeat, keyCode: event_.keyCode) {
|
||||
if let event = NSEvent(cgEvent: cgEvent) {
|
||||
let appWasBeingUsed = App.app.appIsBeingUsed
|
||||
// ShortcutRecorder handles only exact matches for modifiers-only .up shortcuts. We want to activate holdShortcut even if other modifiers are still pressed
|
||||
// see https://github.com/lwouis/alt-tab-macos/issues/230
|
||||
let holdShortcutAction = GeneralTab.shortcutActions["holdShortcut"]!
|
||||
let holdShortcut = holdShortcutAction.shortcut!
|
||||
if holdShortcut.keyCode == .none && type == .flagsChanged && event.sr_keyEventType == .up &&
|
||||
event.modifierFlags.isDisjoint(with: holdShortcut.modifierFlags) {
|
||||
_ = holdShortcutAction.actionHandler!(holdShortcutAction)
|
||||
} else {
|
||||
App.shortcutMonitor.handle(event, withTarget: nil)
|
||||
if let shortcut = shortcutThatMatches(event, type) {
|
||||
if shortcut.hasPrefix("nextWindowShortcut") {
|
||||
App.app.appIsBeingUsed = true
|
||||
} else if shortcut.hasPrefix("holdShortcut") || shortcut == "cancelShortcut" || shortcut == "focusWindowShortcut" {
|
||||
App.app.appIsBeingUsed = false
|
||||
App.app.isFirstSummon = true
|
||||
}
|
||||
DispatchQueue.main.async { () -> () in ControlsTab.shortcutsActions[shortcut]!() }
|
||||
}
|
||||
if appWasBeingUsed || App.app.appIsBeingUsed {
|
||||
return nil // focused app won't receive the event
|
||||
@@ -53,3 +48,31 @@ private func keyboardHandler(_: CGEventTapProxy, type: CGEventType, cgEvent: CGE
|
||||
}
|
||||
return Unmanaged.passRetained(cgEvent) // focused app will receive the event
|
||||
}
|
||||
|
||||
// shortcutMonitor.handle only does exact matching; we match manually to allow flexible matching
|
||||
// see https://github.com/lwouis/alt-tab-macos/issues/230
|
||||
private func shortcutThatMatches(_ event: NSEvent, _ type: CGEventType) -> String? {
|
||||
for shortcutId in ControlsTab.shortcuts.keys {
|
||||
let postfix = App.app.shortcutIndex == 0 ? "" : "2"
|
||||
let shortcut = ControlsTab.shortcuts[shortcutId]!
|
||||
if shortcutId.hasPrefix("holdShortcut") {
|
||||
if event.sr_keyEventType == .up && type == .flagsChanged && shortcut.keyCode == .none && event.modifierFlags.isDisjoint(with: shortcut.modifierFlags) &&
|
||||
shortcutId == "holdShortcut" + postfix && App.app.appIsBeingUsed && Preferences.shortcutStyle == .focusOnRelease {
|
||||
return shortcutId
|
||||
}
|
||||
} else if event.sr_keyEventType == .down && (shortcut.keyCode == .none || event.keyCode == shortcut.carbonKeyCode) {
|
||||
if shortcutId.hasPrefix("nextWindowShortcut") {
|
||||
if event.modifierFlags.intersection(.deviceIndependentFlagsMask) == shortcut.modifierFlags &&
|
||||
(!App.app.appIsBeingUsed || shortcutId == "nextWindowShortcut" + postfix) {
|
||||
return shortcutId
|
||||
}
|
||||
} else {
|
||||
if event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(shortcut.modifierFlags) &&
|
||||
App.app.appIsBeingUsed {
|
||||
return shortcutId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+11
-6
@@ -13,7 +13,6 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
static let licence = Bundle.main.object(forInfoDictionaryKey: "NSHumanReadableCopyright") as! String
|
||||
static let repository = "https://github.com/lwouis/alt-tab-macos"
|
||||
static var app: App!
|
||||
static let shortcutMonitor = LocalShortcutMonitor()
|
||||
static var statusItem: NSStatusItem!
|
||||
var thumbnailsPanel: ThumbnailsPanel!
|
||||
var preferencesWindowController: PreferencesWindowController!
|
||||
@@ -81,6 +80,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
private func loadPreferencesWindow() {
|
||||
let tabs = [
|
||||
GeneralTab(),
|
||||
ControlsTab(),
|
||||
AppearanceTab(),
|
||||
PoliciesTab(),
|
||||
BlacklistsTab(),
|
||||
@@ -88,7 +88,14 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
AcknowledgmentsTab(),
|
||||
]
|
||||
// pre-load tabs so we can interact with them before the user opens the preferences window
|
||||
tabs.forEach { (tab: NSViewController) in tab.loadView() }
|
||||
let widest = tabs.reduce(CGFloat(0), {
|
||||
$1.loadView()
|
||||
return max($0, $1.view.subviews[0].fittingSize.width)
|
||||
})
|
||||
tabs.forEach {
|
||||
$0.view.fit(widest, $0.view.subviews[0].fittingSize.height)
|
||||
}
|
||||
|
||||
preferencesWindowController = PreferencesWindowController(preferencePanes: tabs as! [PreferencePane])
|
||||
|
||||
let window = preferencesWindowController.window!
|
||||
@@ -96,10 +103,8 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
let titleBarView = window.standardWindowButton(.closeButton)!.superview!
|
||||
titleBarView.addSubview(quitButton)
|
||||
quitButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
let topConstraint = NSLayoutConstraint(item: quitButton, attribute: .top, relatedBy: .equal, toItem: titleBarView, attribute: .top, multiplier: 1, constant: 5)
|
||||
let rightConstraint = NSLayoutConstraint(item: quitButton, attribute: .right, relatedBy: .equal, toItem: titleBarView, attribute: .right, multiplier: 1, constant: -10)
|
||||
titleBarView.addConstraints([topConstraint, rightConstraint])
|
||||
|
||||
quitButton.topAnchor.constraint(equalTo: titleBarView.topAnchor, constant: 5).isActive = true
|
||||
quitButton.rightAnchor.constraint(equalTo: titleBarView.rightAnchor, constant: -8).isActive = true
|
||||
}
|
||||
|
||||
// keyboard shortcuts are broken without a menu. We generated the default menu from XCode and load it
|
||||
|
||||
@@ -4,16 +4,16 @@ class GridView: NSGridView {
|
||||
static let padding = CGFloat(20)
|
||||
static let interPadding = CGFloat(10)
|
||||
|
||||
convenience init(_ controls: [[NSView]]) {
|
||||
convenience init(_ controls: [[NSView]], _ padding: CGFloat = GridView.padding) {
|
||||
self.init(views: controls)
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
yPlacement = .fill
|
||||
rowAlignment = .firstBaseline
|
||||
columnSpacing = GridView.interPadding
|
||||
rowSpacing = GridView.interPadding
|
||||
column(at: 0).leadingPadding = GridView.padding
|
||||
column(at: numberOfColumns - 1).trailingPadding = GridView.padding
|
||||
row(at: 0).topPadding = GridView.padding
|
||||
row(at: numberOfRows - 1).bottomPadding = GridView.padding
|
||||
column(at: 0).leadingPadding = padding
|
||||
column(at: numberOfColumns - 1).trailingPadding = padding
|
||||
row(at: 0).topPadding = padding
|
||||
row(at: numberOfRows - 1).bottomPadding = padding
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,8 @@ enum LabelPosition {
|
||||
class LabelAndControl: NSObject {
|
||||
static func makeLabelWithRecorder(_ labelText: String, _ rawName: String, _ shortcutString: String, _ clearable: Bool = true, labelPosition: LabelPosition = .leftWithSeparator) -> [NSView] {
|
||||
let input = CustomRecorderControl(shortcutString, clearable)
|
||||
let views = makeLabelWithProvidedControl(labelText, rawName, input, labelPosition: labelPosition, extraAction: { _ in GeneralTab.shortcutChangedCallback(input) })
|
||||
GeneralTab.shortcutChangedCallback(input)
|
||||
let views = makeLabelWithProvidedControl(labelText, rawName, input, labelPosition: labelPosition, extraAction: { _ in ControlsTab.shortcutChangedCallback(input) })
|
||||
ControlsTab.shortcutChangedCallback(input)
|
||||
return views
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ class LabelAndControl: NSObject {
|
||||
}
|
||||
|
||||
static func makeLabelWithDropdown(_ labelText: String, _ rawName: String, _ values: [MacroPreference], _ suffixText: String? = nil) -> [NSView] {
|
||||
return makeLabelWithProvidedControl(labelText, rawName, makeDropDown(rawName, values), suffixText)
|
||||
return makeLabelWithProvidedControl(labelText, rawName, dropdown_(rawName, values), suffixText)
|
||||
}
|
||||
|
||||
static func makeDropDown(_ rawName: String, _ macroPreferences: [MacroPreference]) -> NSPopUpButton {
|
||||
static func dropdown_(_ rawName: String, _ macroPreferences: [MacroPreference]) -> NSPopUpButton {
|
||||
let popUp = NSPopUpButton()
|
||||
popUp.translatesAutoresizingMaskIntoConstraints = false
|
||||
popUp.addItems(withTitles: macroPreferences.map { $0.localizedString })
|
||||
@@ -46,6 +46,11 @@ class LabelAndControl: NSObject {
|
||||
return popUp
|
||||
}
|
||||
|
||||
static func makeDropdown(_ rawName: String, _ macroPreferences: [MacroPreference]) -> NSControl {
|
||||
let dropdown = dropdown_(rawName, macroPreferences)
|
||||
return setupControl(dropdown, rawName)
|
||||
}
|
||||
|
||||
static func makeRadioButtons(_ macroPreferences: [MacroPreference], _ rawName: String, extraAction: ActionClosure? = nil) -> [NSButton] {
|
||||
var i = 0
|
||||
return macroPreferences.map {
|
||||
@@ -111,11 +116,14 @@ class LabelAndControl: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
static func makeLabel(_ labelText: String, _ labelPosition: LabelPosition = .leftWithoutSeparator) -> NSTextField {
|
||||
static func makeLabel(_ labelText: String, _ labelPosition: LabelPosition = .leftWithoutSeparator, shouldFit: Bool = true) -> NSTextField {
|
||||
let label = TextField(labelText)
|
||||
label.isSelectable = false
|
||||
label.usesSingleLineMode = true
|
||||
label.alignment = .right
|
||||
if shouldFit {
|
||||
label.fit()
|
||||
}
|
||||
return label
|
||||
}
|
||||
|
||||
@@ -170,13 +178,30 @@ enum ControlIdentifierDiscriminator: String {
|
||||
case SUFFIX = "_suffix"
|
||||
}
|
||||
|
||||
class TabView: NSTabView {
|
||||
// without the left/right value, the whole view is shifted to the right for some reason
|
||||
// let insets = NSEdgeInsets(top: 0, left: 7, bottom: 0, right: 7)
|
||||
// override var alignmentRectInsets: NSEdgeInsets { get { insets } }
|
||||
class TabView: NSTabView, NSTabViewDelegate {
|
||||
// removing insets fixes a bug where tab views shift to the right and bottom by 7px when switching to tab #2
|
||||
let insets = NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
|
||||
override var alignmentRectInsets: NSEdgeInsets { get { insets } }
|
||||
|
||||
convenience init() {
|
||||
// workaround: this is the only I found to have NSTabView fittingSize be correct
|
||||
override var intrinsicContentSize: NSSize {
|
||||
get {
|
||||
NSSize(width: selectedTabViewItem!.view!.fittingSize.width + TabView.padding * 2,
|
||||
height: selectedTabViewItem!.view!.fittingSize.height + TabView.padding * 2 + subviews[0].frame.height)
|
||||
}
|
||||
}
|
||||
|
||||
static let padding = CGFloat(7)
|
||||
|
||||
convenience init(_ labelsAndViews: [(String, NSView)]) {
|
||||
self.init(frame: .zero)
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
labelsAndViews.enumerated().forEach { (i, tuple) in
|
||||
let tab = NSTabViewItem(identifier: i)
|
||||
tab.label = tuple.0
|
||||
tab.view = tuple.1
|
||||
addTabViewItem(tab)
|
||||
tab.view!.fit()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ class AboutTab: NSViewController, PreferencePane {
|
||||
sendFeedbackCell.xPlacement = .center
|
||||
sendFeedbackCell.row!.topPadding = GridView.interPadding
|
||||
grid.fit()
|
||||
view = grid
|
||||
|
||||
setView(grid)
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ class AcknowledgmentsTab: NSViewController, PreferencePane {
|
||||
subGrid.fit()
|
||||
|
||||
let scrollView = ScrollView()
|
||||
scrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||
scrollView.documentView!.translatesAutoresizingMaskIntoConstraints = false
|
||||
scrollView.scrollerKnobStyle = .default
|
||||
scrollView.documentView!.subviews = [subGrid]
|
||||
let totalWidth = subGrid.fittingSize.width
|
||||
@@ -35,6 +37,6 @@ class AcknowledgmentsTab: NSViewController, PreferencePane {
|
||||
scrollView.documentView!.frame.size = subGrid.fittingSize
|
||||
scrollView.fit(totalWidth, totalHeight)
|
||||
|
||||
view = scrollView
|
||||
setView(scrollView)
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,6 @@ class AppearanceTab: NSViewController, PreferencePane {
|
||||
grid.rowAlignment = .lastBaseline
|
||||
grid.fit()
|
||||
|
||||
view = grid
|
||||
setView(grid)
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ class BlacklistsTab: NSViewController, PreferencePane {
|
||||
])
|
||||
grid.row(at: 2).topPadding = GridView.interPadding * 1.5
|
||||
grid.fit()
|
||||
view = grid
|
||||
|
||||
setView(grid)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
import Cocoa
|
||||
import ShortcutRecorder
|
||||
import Preferences
|
||||
|
||||
class ControlsTab: NSViewController, PreferencePane {
|
||||
let preferencePaneIdentifier = PreferencePane.Identifier("Controls")
|
||||
let preferencePaneTitle = NSLocalizedString("Controls", comment: "")
|
||||
let toolbarItemIcon = NSImage(named: NSImage.preferencesGeneralName)!
|
||||
|
||||
static var nextWindowShortcut: NSControl!
|
||||
static var nextWindowShortcut2: NSControl!
|
||||
static var shortcuts = [String: Shortcut]()
|
||||
static var shortcutsActions = [
|
||||
"holdShortcut": { App.app.focusTarget() },
|
||||
"holdShortcut2": { App.app.focusTarget() },
|
||||
"focusWindowShortcut": { App.app.focusTarget() },
|
||||
"nextWindowShortcut": { App.app.showUiOrCycleSelection(0) },
|
||||
"nextWindowShortcut2": { App.app.showUiOrCycleSelection(1) },
|
||||
"previousWindowShortcut": { App.app.cycleSelection(.trailing) },
|
||||
"→": { App.app.cycleSelection(.right) },
|
||||
"←": { App.app.cycleSelection(.left) },
|
||||
"↑": { App.app.cycleSelection(.up) },
|
||||
"↓": { App.app.cycleSelection(.down) },
|
||||
"cancelShortcut": { App.app.hideUi() },
|
||||
"closeWindowShortcut": { App.app.closeSelectedWindow() },
|
||||
"minDeminWindowShortcut": { App.app.minDeminSelectedWindow() },
|
||||
"quitAppShortcut": { App.app.quitSelectedApp() },
|
||||
"hideShowAppShortcut": { App.app.hideShowSelectedApp() },
|
||||
]
|
||||
|
||||
override func loadView() {
|
||||
let shortcutStyle = LabelAndControl.makeLabelWithDropdown(NSLocalizedString("then release:", comment: ""), "shortcutStyle", ShortcutStylePreference.allCases)
|
||||
let focusWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Focus selected window", comment: ""), "focusWindowShortcut", Preferences.focusWindowShortcut, labelPosition: .right)
|
||||
let previousWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Select previous window", comment: ""), "previousWindowShortcut", Preferences.previousWindowShortcut, labelPosition: .right)
|
||||
let cancelShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Cancel and hide", comment: ""), "cancelShortcut", Preferences.cancelShortcut, labelPosition: .right)
|
||||
let closeWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Close window", comment: ""), "closeWindowShortcut", Preferences.closeWindowShortcut, labelPosition: .right)
|
||||
let minDeminWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Minimize/Deminimize window", comment: ""), "minDeminWindowShortcut", Preferences.minDeminWindowShortcut, labelPosition: .right)
|
||||
let quitAppShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Quit app", comment: ""), "quitAppShortcut", Preferences.quitAppShortcut, labelPosition: .right)
|
||||
let hideShowAppShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Hide/Show app", comment: ""), "hideShowAppShortcut", Preferences.hideShowAppShortcut, labelPosition: .right)
|
||||
let enableArrows = LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Arrow keys", comment: ""), "arrowKeysEnabled", extraAction: ControlsTab.arrowKeysEnabledCallback, labelPosition: .right)
|
||||
let enableMouse = LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Mouse hover", comment: ""), "mouseHoverEnabled", labelPosition: .right)
|
||||
let checkboxesExplanations = LabelAndControl.makeLabel(NSLocalizedString("Also select windows using:", comment: ""))
|
||||
let checkboxes = StackView([StackView(enableArrows), StackView(enableMouse)], .vertical)
|
||||
let shortcuts = StackView([focusWindowShortcut, previousWindowShortcut, cancelShortcut, closeWindowShortcut, minDeminWindowShortcut, quitAppShortcut, hideShowAppShortcut].map { (view: [NSView]) in StackView(view) }, .vertical)
|
||||
let orPress = LabelAndControl.makeLabel(NSLocalizedString("While open, press:", comment: ""), shouldFit: false)
|
||||
let (nextWindowShortcut, tab1View) = toShowSection("")
|
||||
let (nextWindowShortcut2, tab2View) = toShowSection("2")
|
||||
let tabView = TabView([(NSLocalizedString("Shortcut 1", comment: ""), tab1View), (NSLocalizedString("Shortcut 2", comment: ""), tab2View)])
|
||||
|
||||
ControlsTab.nextWindowShortcut = nextWindowShortcut[0] as! NSControl
|
||||
ControlsTab.nextWindowShortcut2 = nextWindowShortcut2[0] as! NSControl
|
||||
ControlsTab.arrowKeysEnabledCallback(enableArrows[0] as! NSControl)
|
||||
|
||||
let grid = GridView([
|
||||
[tabView],
|
||||
shortcutStyle,
|
||||
[orPress, shortcuts],
|
||||
[checkboxesExplanations, checkboxes],
|
||||
])
|
||||
grid.column(at: 0).xPlacement = .trailing
|
||||
grid.mergeCells(inHorizontalRange: NSRange(location: 0, length: 2), verticalRange: NSRange(location: 0, length: 1))
|
||||
grid.cell(atColumnIndex: 0, rowIndex: 0).xPlacement = .leading
|
||||
|
||||
// TODO: better layout logic. Maybe freeze the width of the preference window and have labels wrap on multiple lines
|
||||
// currently this looks bad if the right column inside the tabView is larger than the right column of the top gridView
|
||||
let leftColumnWidthTabView = tab1View.column(at: 0).width()
|
||||
let leftColumnWidthTopView = grid.column(at: 0).width(0)
|
||||
debugPrint("hey", leftColumnWidthTabView, leftColumnWidthTopView)
|
||||
if leftColumnWidthTabView > leftColumnWidthTopView {
|
||||
orPress.fit(tab1View.column(at: 0).width() + GridView.interPadding + TabView.padding, orPress.fittingSize.height)
|
||||
} else {
|
||||
orPress.fit()
|
||||
tabView.leftAnchor.constraint(equalTo: tabView.superview!.leftAnchor, constant: leftColumnWidthTopView - leftColumnWidthTabView + 3).isActive = true
|
||||
}
|
||||
|
||||
setView(grid)
|
||||
}
|
||||
|
||||
private func toShowSection(_ postfix: String) -> ([NSView], GridView) {
|
||||
let toShowExplanations = LabelAndControl.makeLabel(NSLocalizedString("Show the following windows:", comment: ""))
|
||||
var holdShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Hold", comment: ""), "holdShortcut" + postfix, Preferences.holdShortcut, false, labelPosition: .leftWithoutSeparator)
|
||||
holdShortcut.append(LabelAndControl.makeLabel(NSLocalizedString("and press:", comment: "")))
|
||||
let holdAndPress = StackView(holdShortcut)
|
||||
let appsToShow = LabelAndControl.makeDropdown("appsToShow" + postfix, AppsToShowPreference.allCases)
|
||||
let spacesToShow = LabelAndControl.makeDropdown("spacesToShow" + postfix, SpacesToShowPreference.allCases)
|
||||
let screensToShow = LabelAndControl.makeDropdown("screensToShow" + postfix, ScreensToShowPreference.allCases)
|
||||
let showMinimizedWindows = StackView(LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Minimized", comment: ""), "showMinimizedWindows" + postfix, labelPosition: .right))
|
||||
let showHiddenWindows = StackView(LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hidden", comment: ""), "showHiddenWindows" + postfix, labelPosition: .right))
|
||||
let showFullscreenWindows = StackView(LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Fullscreen", comment: ""), "showFullscreenWindows" + postfix, labelPosition: .right))
|
||||
let nextWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Select next window", comment: ""), "nextWindowShortcut" + postfix, Preferences.nextWindowShortcut[postfix == "" ? 0 : 1], labelPosition: .right)
|
||||
let toShowDropdowns = StackView([appsToShow, spacesToShow, screensToShow, showMinimizedWindows, showHiddenWindows, showFullscreenWindows], .vertical, false)
|
||||
toShowDropdowns.spacing = TabView.padding
|
||||
toShowDropdowns.fit()
|
||||
let tab = GridView([
|
||||
[toShowExplanations, toShowDropdowns],
|
||||
[holdAndPress, StackView(nextWindowShortcut)],
|
||||
], TabView.padding)
|
||||
tab.column(at: 0).xPlacement = .trailing
|
||||
tab.fit()
|
||||
return (nextWindowShortcut, tab)
|
||||
}
|
||||
|
||||
private static func addShortcut(_ type: KeyEventType, _ shortcut: Shortcut, _ controlId: String) {
|
||||
removeShortcutIfExists(controlId, type) // remove the previous shortcut
|
||||
shortcuts[controlId] = shortcut
|
||||
}
|
||||
|
||||
@objc static func shortcutChangedCallback(_ sender: NSControl) {
|
||||
let controlId = sender.identifier!.rawValue
|
||||
if controlId == "holdShortcut" {
|
||||
addShortcut(.up, Shortcut(keyEquivalent: Preferences.holdShortcut)!, controlId)
|
||||
if let s = nextWindowShortcut {
|
||||
shortcutChangedCallback(s)
|
||||
}
|
||||
} else if controlId == "holdShortcut2" {
|
||||
addShortcut(.up, Shortcut(keyEquivalent: Preferences.holdShortcut2)!, controlId)
|
||||
if let s = nextWindowShortcut2 {
|
||||
shortcutChangedCallback(s)
|
||||
}
|
||||
} else {
|
||||
let newValue = shortcutStringValue(controlId, sender)
|
||||
if newValue.isEmpty {
|
||||
removeShortcutIfExists(controlId, .down)
|
||||
} else {
|
||||
addShortcut(.down, Shortcut(keyEquivalent: newValue)!, controlId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static func shortcutStringValue(_ controlId: String, _ sender: NSControl) -> String {
|
||||
let baseValue = (sender as! RecorderControl).stringValue
|
||||
if controlId == "nextWindowShortcut" || controlId == "nextWindowShortcut2" {
|
||||
let holdShortcut = controlId == "nextWindowShortcut" ? Preferences.holdShortcut : Preferences.holdShortcut2
|
||||
// remove the holdShortcut character in case they also use it in the other shortcuts
|
||||
return holdShortcut + holdShortcut.reduce(baseValue, { $0.replacingOccurrences(of: String($1), with: "") })
|
||||
}
|
||||
return baseValue
|
||||
}
|
||||
|
||||
@objc static func arrowKeysEnabledCallback(_ sender: NSControl) {
|
||||
let keys = ["←", "→", "↑", "↓"]
|
||||
if (sender as! NSButton).state == .on {
|
||||
keys.forEach { addShortcut(.down, Shortcut(keyEquivalent: $0)!, $0) }
|
||||
} else {
|
||||
keys.forEach { removeShortcutIfExists($0, .down) }
|
||||
}
|
||||
}
|
||||
|
||||
private static func removeShortcutIfExists(_ controlId: String, _ type: KeyEventType) {
|
||||
if let a = shortcuts[controlId] {
|
||||
shortcuts.removeValue(forKey: controlId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import Cocoa
|
||||
import ShortcutRecorder
|
||||
import Preferences
|
||||
|
||||
class GeneralTab: NSViewController, PreferencePane {
|
||||
@@ -7,165 +6,21 @@ class GeneralTab: NSViewController, PreferencePane {
|
||||
let preferencePaneTitle = NSLocalizedString("General", comment: "")
|
||||
let toolbarItemIcon = NSImage(named: NSImage.preferencesGeneralName)!
|
||||
|
||||
static var shortcutActions = [String: ShortcutAction]()
|
||||
static var shortcutsDependentOnHoldShortcut = [NSControl]()
|
||||
static var shortcutsActionsBlocks = [
|
||||
"holdShortcut": { App.app.focusTarget() },
|
||||
"nextWindowShortcut": { App.app.showUiOrCycleSelection(0) },
|
||||
"nextWindowShortcut2": { App.app.showUiOrCycleSelection(1) },
|
||||
"previousWindowShortcut": { App.app.cycleSelection(.trailing) },
|
||||
"→": { App.app.cycleSelection(.right) },
|
||||
"←": { App.app.cycleSelection(.left) },
|
||||
"↑": { App.app.cycleSelection(.up) },
|
||||
"↓": { App.app.cycleSelection(.down) },
|
||||
"cancelShortcut": { App.app.hideUi() },
|
||||
"closeWindowShortcut": { App.app.closeSelectedWindow() },
|
||||
"minDeminWindowShortcut": { App.app.minDeminSelectedWindow() },
|
||||
"quitAppShortcut": { App.app.quitSelectedApp() },
|
||||
"hideShowAppShortcut": { App.app.hideShowSelectedApp() },
|
||||
]
|
||||
|
||||
override func loadView() {
|
||||
let startAtLogin = LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Start at login:", comment: ""), "startAtLogin", extraAction: startAtLoginCallback)
|
||||
let hideMenubarIcon = LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hide menubar icon:", comment: ""), "hideMenubarIcon", extraAction: hideMenubarIconCallback)
|
||||
var holdShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Hold", comment: ""), "holdShortcut", Preferences.holdShortcut, false, labelPosition: .leftWithoutSeparator)
|
||||
holdShortcut.append(LabelAndControl.makeLabel(NSLocalizedString("and press:", comment: "")))
|
||||
let previousWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Select previous window", comment: ""), "previousWindowShortcut", Preferences.previousWindowShortcut, labelPosition: .right)
|
||||
let cancelShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Cancel and hide", comment: ""), "cancelShortcut", Preferences.cancelShortcut, labelPosition: .right)
|
||||
let closeWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Close window", comment: ""), "closeWindowShortcut", Preferences.closeWindowShortcut, labelPosition: .right)
|
||||
let minDeminWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Minimize/Deminimize window", comment: ""), "minDeminWindowShortcut", Preferences.minDeminWindowShortcut, labelPosition: .right)
|
||||
let quitAppShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Quit app", comment: ""), "quitAppShortcut", Preferences.quitAppShortcut, labelPosition: .right)
|
||||
let hideShowAppShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Hide/Show app", comment: ""), "hideShowAppShortcut", Preferences.hideShowAppShortcut, labelPosition: .right)
|
||||
let enableArrows = LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Arrow keys", comment: ""), "arrowKeysEnabled", extraAction: GeneralTab.arrowKeysEnabledCallback, labelPosition: .right)
|
||||
let enableMouse = LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Mouse hover", comment: ""), "mouseHoverEnabled", labelPosition: .right)
|
||||
let holdAndPress = StackView(holdShortcut)
|
||||
let checkboxesExplanations = LabelAndControl.makeLabel(NSLocalizedString("Select windows using:", comment: ""))
|
||||
let checkboxes = StackView([StackView(enableArrows), StackView(enableMouse)], .vertical)
|
||||
let shortcuts = StackView([previousWindowShortcut, cancelShortcut, closeWindowShortcut, minDeminWindowShortcut, quitAppShortcut, hideShowAppShortcut].map { (view: [NSView]) in StackView(view) }, .vertical)
|
||||
let thenRelease = LabelAndControl.makeLabel(NSLocalizedString("then release:", comment: ""))
|
||||
let orPress = LabelAndControl.makeLabel(NSLocalizedString("or press:", comment: ""))
|
||||
let focusSelectedWindow = LabelAndControl.makeLabel(NSLocalizedString("Focus selected window", comment: ""))
|
||||
let toShowExplanations = LabelAndControl.makeLabel(NSLocalizedString("Show the following windows:", comment: ""))
|
||||
|
||||
let tab1 = NSTabViewItem(identifier: 1)
|
||||
tab1.label = "1"
|
||||
let (nextWindowShortcut, tab1View) = toShowSection("")
|
||||
tab1.view = tab1View
|
||||
let tab2 = NSTabViewItem(identifier: 2)
|
||||
tab2.label = "2"
|
||||
let (nextWindowShortcut2, tab2View) = toShowSection("2")
|
||||
tab2.view = tab2View
|
||||
let tabView = TabView()
|
||||
tabView.addTabViewItem(tab1)
|
||||
tabView.addTabViewItem(tab2)
|
||||
tabView.tabPosition = .right
|
||||
tabView.heightAnchor.constraint(equalToConstant: tabView.fittingSize.height - 8).isActive = true
|
||||
|
||||
let vertical1 = StackView([toShowExplanations, holdAndPress], .vertical, false, top: 5, bottom: 3)
|
||||
vertical1.alignment = .trailing
|
||||
vertical1.distribution = .equalCentering
|
||||
vertical1.heightAnchor.constraint(equalToConstant: tabView.fittingSize.height - 14).isActive = true
|
||||
let grid = GridView([
|
||||
startAtLogin,
|
||||
hideMenubarIcon,
|
||||
[vertical1, tabView],
|
||||
[thenRelease, focusSelectedWindow],
|
||||
[orPress, shortcuts],
|
||||
[checkboxesExplanations, checkboxes],
|
||||
])
|
||||
grid.column(at: 0).xPlacement = .trailing
|
||||
grid.row(at: 2).rowAlignment = .none
|
||||
[2, 5].forEach { grid.row(at: $0).topPadding = GridView.interPadding }
|
||||
grid.fit()
|
||||
|
||||
GeneralTab.shortcutsDependentOnHoldShortcut.append(contentsOf: [enableArrows[0] as! NSControl] +
|
||||
[nextWindowShortcut, nextWindowShortcut2, previousWindowShortcut, cancelShortcut,
|
||||
closeWindowShortcut, minDeminWindowShortcut, quitAppShortcut, hideShowAppShortcut].map { $0[0] as! NSControl })
|
||||
GeneralTab.arrowKeysEnabledCallback(enableArrows[0] as! NSControl)
|
||||
setView(grid)
|
||||
|
||||
startAtLoginCallback(startAtLogin[1] as! NSControl)
|
||||
hideMenubarIconCallback(hideMenubarIcon[1] as! NSControl)
|
||||
|
||||
view = grid
|
||||
}
|
||||
|
||||
private func toShowSection(_ postfix: String) -> ([NSView], NSView) {
|
||||
let appsToShow = dropdown("appsToShow" + postfix, AppsToShowPreference.allCases)
|
||||
let spacesToShow = dropdown("spacesToShow" + postfix, SpacesToShowPreference.allCases)
|
||||
let screensToShow = dropdown("screensToShow" + postfix, ScreensToShowPreference.allCases)
|
||||
let showMinimizedWindows = StackView(LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Minimized", comment: ""), "showMinimizedWindows" + postfix, labelPosition: .right))
|
||||
let showHiddenWindows = StackView(LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Hidden", comment: ""), "showHiddenWindows" + postfix, labelPosition: .right))
|
||||
let showFullscreenWindows = StackView(LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Fullscreen", comment: ""), "showFullscreenWindows" + postfix, labelPosition: .right))
|
||||
let nextWindowShortcut = LabelAndControl.makeLabelWithRecorder(NSLocalizedString("Select next window", comment: ""), "nextWindowShortcut" + postfix, Preferences.nextWindowShortcut[postfix == "" ? 0 : 1], labelPosition: .right)
|
||||
let toShowDropdowns = StackView([appsToShow, spacesToShow, screensToShow, showMinimizedWindows, showHiddenWindows, showFullscreenWindows], .vertical, false)
|
||||
toShowDropdowns.spacing = 8
|
||||
toShowDropdowns.fit()
|
||||
let tab = StackView([toShowDropdowns, StackView(nextWindowShortcut)], .vertical, false)
|
||||
tab.spacing = GridView.padding
|
||||
tab.fit()
|
||||
return (nextWindowShortcut, tab)
|
||||
}
|
||||
|
||||
private func dropdown(_ rawName: String, _ macroPreferences: [MacroPreference]) -> NSControl {
|
||||
let dropdown = LabelAndControl.makeDropDown(rawName, macroPreferences)
|
||||
return LabelAndControl.setupControl(dropdown, rawName)
|
||||
}
|
||||
|
||||
private static func addShortcut(_ type: KeyEventType, _ shortcut: Shortcut, _ controlId: String) {
|
||||
removeShortcutIfExists(controlId, type) // remove the previous shortcut
|
||||
shortcutActions[controlId] = ShortcutAction(shortcut: shortcut, actionHandler: { _ in
|
||||
let isShortcutInitiatingTheApp = ["nextWindowShortcut", "nextWindowShortcut2"].contains(controlId)
|
||||
if isShortcutInitiatingTheApp {
|
||||
App.app.appIsBeingUsed = true
|
||||
}
|
||||
if App.app.appIsBeingUsed {
|
||||
let isShortcutClosingTheUi = ["holdShortcut", "cancelShortcut"].contains(controlId)
|
||||
if isShortcutClosingTheUi {
|
||||
App.app.appIsBeingUsed = false
|
||||
App.app.isFirstSummon = true
|
||||
}
|
||||
DispatchQueue.main.async { () -> () in shortcutsActionsBlocks[controlId]!() }
|
||||
}
|
||||
return true
|
||||
})
|
||||
App.shortcutMonitor.addAction(shortcutActions[controlId]!, forKeyEvent: type)
|
||||
}
|
||||
|
||||
@objc static func shortcutChangedCallback(_ sender: NSControl) {
|
||||
let controlId = sender.identifier!.rawValue
|
||||
if controlId == "holdShortcut" {
|
||||
addShortcut(.up, Shortcut(keyEquivalent: Preferences.holdShortcut)!, controlId)
|
||||
shortcutsDependentOnHoldShortcut.forEach {
|
||||
if $0.identifier!.rawValue == "arrowKeysEnabled" {
|
||||
GeneralTab.arrowKeysEnabledCallback($0)
|
||||
} else {
|
||||
GeneralTab.shortcutChangedCallback($0)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// remove the holdShortcut character in case they also use it in the other shortcuts
|
||||
let newValue = Preferences.holdShortcut.reduce((sender as! RecorderControl).stringValue, { $0.replacingOccurrences(of: String($1), with: "") })
|
||||
if newValue.isEmpty {
|
||||
removeShortcutIfExists(controlId, .down)
|
||||
return
|
||||
}
|
||||
addShortcut(.down, Shortcut(keyEquivalent: Preferences.holdShortcut + newValue)!, controlId)
|
||||
}
|
||||
}
|
||||
|
||||
@objc static func arrowKeysEnabledCallback(_ sender: NSControl) {
|
||||
let keys = ["←", "→", "↑", "↓"]
|
||||
if (sender as! NSButton).state == .on {
|
||||
keys.forEach { addShortcut(.down, Shortcut(keyEquivalent: Preferences.holdShortcut + $0)!, $0) }
|
||||
} else {
|
||||
keys.forEach { removeShortcutIfExists($0, .down) }
|
||||
}
|
||||
}
|
||||
|
||||
private static func removeShortcutIfExists(_ controlId: String, _ type: KeyEventType) {
|
||||
if let a = shortcutActions[controlId] {
|
||||
App.shortcutMonitor.removeAction(_: a, forKeyEvent: type)
|
||||
shortcutActions.removeValue(forKey: controlId)
|
||||
}
|
||||
}
|
||||
|
||||
// adding/removing login item depending on the checkbox state
|
||||
|
||||
@@ -36,7 +36,8 @@ class PoliciesTab: NSViewController, PreferencePane {
|
||||
grid.row(at: 2).topPadding = GridView.interPadding * 1.5
|
||||
grid.fit()
|
||||
|
||||
view = grid
|
||||
setView(grid)
|
||||
|
||||
UserDefaultsEvents.observe()
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user