diff --git a/SIL.Core/PlatformUtilities/Platform.cs b/SIL.Core/PlatformUtilities/Platform.cs
index 621d3fcf0..b7363d287 100644
--- a/SIL.Core/PlatformUtilities/Platform.cs
+++ b/SIL.Core/PlatformUtilities/Platform.cs
@@ -319,5 +319,17 @@ private static string RunTerminalCommand(string cmd, string args = null)
return output.Trim();
}
+
+ public static bool IsGnomeShell
+ {
+ get
+ {
+ if (!IsLinux)
+ return false;
+
+ var pids = RunTerminalCommand("pidof", "gnome-shell");
+ return !string.IsNullOrEmpty(pids);
+ }
+ }
}
}
diff --git a/SIL.Windows.Forms.Keyboarding/KeyboardController.cs b/SIL.Windows.Forms.Keyboarding/KeyboardController.cs
index abf0cff11..ca3c4d3cc 100644
--- a/SIL.Windows.Forms.Keyboarding/KeyboardController.cs
+++ b/SIL.Windows.Forms.Keyboarding/KeyboardController.cs
@@ -229,7 +229,8 @@ private void SetDefaultKeyboardAdaptors()
{
new XkbKeyboardRetrievingAdaptor(), new IbusKeyboardRetrievingAdaptor(),
new UnityXkbKeyboardRetrievingAdaptor(), new UnityIbusKeyboardRetrievingAdaptor(),
- new CombinedIbusKeyboardRetrievingAdaptor()
+ new CombinedIbusKeyboardRetrievingAdaptor(),
+ new GnomeShellIbusKeyboardRetrievingAdaptor()
}
);
}
diff --git a/SIL.Windows.Forms.Keyboarding/Linux/CombinedIbusKeyboardRetrievingAdaptor.cs b/SIL.Windows.Forms.Keyboarding/Linux/CombinedIbusKeyboardRetrievingAdaptor.cs
index 271c1bf29..ecf312a65 100644
--- a/SIL.Windows.Forms.Keyboarding/Linux/CombinedIbusKeyboardRetrievingAdaptor.cs
+++ b/SIL.Windows.Forms.Keyboarding/Linux/CombinedIbusKeyboardRetrievingAdaptor.cs
@@ -154,7 +154,7 @@ public override bool IsApplicable
}
var list = GetMyKeyboards(_settingsGeneral);
return list != null && list.Length > 0 && Platform.DesktopEnvironment != "unity"
- && Platform.DesktopEnvironment != "gnome";
+ && !Platform.DesktopEnvironment.Contains("gnome");
}
}
diff --git a/SIL.Windows.Forms.Keyboarding/Linux/GnomeShellIbusKeyboardRetrievingAdaptor.cs b/SIL.Windows.Forms.Keyboarding/Linux/GnomeShellIbusKeyboardRetrievingAdaptor.cs
new file mode 100644
index 000000000..273fbcfc5
--- /dev/null
+++ b/SIL.Windows.Forms.Keyboarding/Linux/GnomeShellIbusKeyboardRetrievingAdaptor.cs
@@ -0,0 +1,22 @@
+// Copyright (c) 2020 SIL International
+// This software is licensed under the MIT License (http://opensource.org/licenses/MIT)
+
+using SIL.PlatformUtilities;
+
+namespace SIL.Windows.Forms.Keyboarding.Linux
+{
+ ///
+ /// This class handles initializing the list of keyboards on Ubuntu versions >= 18.04.
+ /// The keyboard retrieving part is identical to previous versions but switching keyboards
+ /// changed with 18.04.
+ ///
+ public class GnomeShellIbusKeyboardRetrievingAdaptor: UnityIbusKeyboardRetrievingAdaptor
+ {
+ protected override IKeyboardSwitchingAdaptor CreateSwitchingAdaptor()
+ {
+ return new GnomeShellIbusKeyboardSwitchingAdaptor(IbusCommunicator);
+ }
+
+ public override bool IsApplicable => _helper.IsApplicable && Platform.IsGnomeShell;
+ }
+}
\ No newline at end of file
diff --git a/SIL.Windows.Forms.Keyboarding/Linux/GnomeShellIbusKeyboardSwitchingAdaptor.cs b/SIL.Windows.Forms.Keyboarding/Linux/GnomeShellIbusKeyboardSwitchingAdaptor.cs
new file mode 100644
index 000000000..5c03948a5
--- /dev/null
+++ b/SIL.Windows.Forms.Keyboarding/Linux/GnomeShellIbusKeyboardSwitchingAdaptor.cs
@@ -0,0 +1,54 @@
+// Copyright (c) 2020 SIL International
+// This software is licensed under the MIT License (http://opensource.org/licenses/MIT)
+
+using System;
+using System.Diagnostics;
+using SIL.Reporting;
+
+namespace SIL.Windows.Forms.Keyboarding.Linux
+{
+ ///
+ /// Class for dealing with ibus keyboards on Gnome Shell (as found in Ubuntu Bionic >= 18.04)
+ ///
+ public class GnomeShellIbusKeyboardSwitchingAdaptor: UnityIbusKeyboardSwitchingAdaptor, IUnityKeyboardSwitchingAdaptor
+ {
+ public GnomeShellIbusKeyboardSwitchingAdaptor(IIbusCommunicator ibusCommunicator)
+ : base(ibusCommunicator)
+ {
+ }
+
+ void IUnityKeyboardSwitchingAdaptor.SelectKeyboard(uint index)
+ {
+ var okay = false;
+ // https://askubuntu.com/a/1039964
+ try
+ {
+ using (var proc = new Process {
+ EnableRaisingEvents = false,
+ StartInfo = {
+ FileName = "/usr/bin/gdbus",
+ Arguments = "call --session --dest org.gnome.Shell --object-path /org/gnome/Shell " +
+ "--method org.gnome.Shell.Eval " +
+ $"\"imports.ui.status.keyboard.getInputSourceManager().inputSources[{index}].activate()\"",
+ UseShellExecute = false
+ }
+ })
+ {
+ proc.Start();
+ proc.WaitForExit();
+ okay = proc.ExitCode == 0;
+ }
+ }
+ finally
+ {
+ if (!okay)
+ {
+ var msg = $"GnomeShellIbusKeyboardSwitchingAdaptor.SelectKeyboard({index}) failed";
+ Console.WriteLine(msg);
+ Logger.WriteEvent(msg);
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/SIL.Windows.Forms.Keyboarding/Linux/IUnityKeyboardSwitchingAdaptor.cs b/SIL.Windows.Forms.Keyboarding/Linux/IUnityKeyboardSwitchingAdaptor.cs
new file mode 100644
index 000000000..bd690bc77
--- /dev/null
+++ b/SIL.Windows.Forms.Keyboarding/Linux/IUnityKeyboardSwitchingAdaptor.cs
@@ -0,0 +1,10 @@
+// Copyright (c) 2020 SIL International
+// This software is licensed under the MIT License (http://opensource.org/licenses/MIT)
+
+namespace SIL.Windows.Forms.Keyboarding.Linux
+{
+ internal interface IUnityKeyboardSwitchingAdaptor
+ {
+ void SelectKeyboard(uint index);
+ }
+}
\ No newline at end of file
diff --git a/SIL.Windows.Forms.Keyboarding/Linux/UnityIbusKeyboardRetrievingAdaptor.cs b/SIL.Windows.Forms.Keyboarding/Linux/UnityIbusKeyboardRetrievingAdaptor.cs
index 04dc02d6d..8ab4a2beb 100644
--- a/SIL.Windows.Forms.Keyboarding/Linux/UnityIbusKeyboardRetrievingAdaptor.cs
+++ b/SIL.Windows.Forms.Keyboarding/Linux/UnityIbusKeyboardRetrievingAdaptor.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using SIL.PlatformUtilities;
namespace SIL.Windows.Forms.Keyboarding.Linux
{
@@ -20,15 +21,20 @@ public class UnityIbusKeyboardRetrievingAdaptor : IbusKeyboardRetrievingAdaptor
#region Specific implementations of IKeyboardRetriever
- public override bool IsApplicable => _helper.IsApplicable;
+ public override bool IsApplicable => _helper.IsApplicable && !Platform.IsGnomeShell;
public override void Initialize()
{
- SwitchingAdaptor = new UnityIbusKeyboardSwitchingAdaptor(IbusCommunicator);
+ SwitchingAdaptor = CreateSwitchingAdaptor();
KeyboardRetrievingHelper.AddIbusVersionAsErrorReportProperty();
InitKeyboards();
}
+ protected virtual IKeyboardSwitchingAdaptor CreateSwitchingAdaptor()
+ {
+ return new UnityIbusKeyboardSwitchingAdaptor(IbusCommunicator);
+ }
+
protected override string GetKeyboardSetupApplication(out string arguments)
{
var program = _helper.GetKeyboardSetupApplication(out arguments);
diff --git a/SIL.Windows.Forms.Keyboarding/Linux/UnityIbusKeyboardSwitchingAdaptor.cs b/SIL.Windows.Forms.Keyboarding/Linux/UnityIbusKeyboardSwitchingAdaptor.cs
index 5cb194949..eb7097532 100644
--- a/SIL.Windows.Forms.Keyboarding/Linux/UnityIbusKeyboardSwitchingAdaptor.cs
+++ b/SIL.Windows.Forms.Keyboarding/Linux/UnityIbusKeyboardSwitchingAdaptor.cs
@@ -1,22 +1,22 @@
// Copyright (c) 2015 SIL International
// This software is licensed under the MIT License (http://opensource.org/licenses/MIT)
using System;
+using SIL.PlatformUtilities;
using SIL.Reporting;
namespace SIL.Windows.Forms.Keyboarding.Linux
{
///
- /// Class for dealing with ibus keyboards on Unity (as found in Trusty >= 13.10)
+ /// Class for dealing with ibus keyboards on Unity (as found in Trusty >= 13.10 < 18.04)
///
- [CLSCompliant(false)]
- public class UnityIbusKeyboardSwitchingAdaptor : IbusKeyboardSwitchingAdaptor
+ public class UnityIbusKeyboardSwitchingAdaptor : IbusKeyboardSwitchingAdaptor, IUnityKeyboardSwitchingAdaptor
{
public UnityIbusKeyboardSwitchingAdaptor(IIbusCommunicator ibusCommunicator) :
base(ibusCommunicator)
{
}
- internal static void SelectKeyboard(uint index)
+ void IUnityKeyboardSwitchingAdaptor.SelectKeyboard(uint index)
{
const string schema = "org.gnome.desktop.input-sources";
bool okay = true;
@@ -46,8 +46,8 @@ internal static void SelectKeyboard(uint index)
protected override void SelectKeyboard(KeyboardDescription keyboard)
{
var ibusKeyboard = (IbusKeyboardDescription) keyboard;
- uint systemIndex = ibusKeyboard.SystemIndex;
- SelectKeyboard(systemIndex);
+ var systemIndex = ibusKeyboard.SystemIndex;
+ ((IUnityKeyboardSwitchingAdaptor)this).SelectKeyboard(systemIndex);
}
}
diff --git a/SIL.Windows.Forms.Keyboarding/Linux/UnityXkbKeyboardSwitchingAdaptor.cs b/SIL.Windows.Forms.Keyboarding/Linux/UnityXkbKeyboardSwitchingAdaptor.cs
index 88775e813..6b90a7db0 100644
--- a/SIL.Windows.Forms.Keyboarding/Linux/UnityXkbKeyboardSwitchingAdaptor.cs
+++ b/SIL.Windows.Forms.Keyboarding/Linux/UnityXkbKeyboardSwitchingAdaptor.cs
@@ -16,11 +16,13 @@ public UnityXkbKeyboardSwitchingAdaptor(IXklEngine engine): base(engine)
protected override void SelectKeyboard(KeyboardDescription keyboard)
{
var xkbKeyboard = keyboard as XkbKeyboardDescription;
- if (xkbKeyboard != null)
- {
- if (xkbKeyboard.GroupIndex >= 0)
- UnityIbusKeyboardSwitchingAdaptor.SelectKeyboard((uint)xkbKeyboard.GroupIndex);
- }
+ if (xkbKeyboard == null || xkbKeyboard.GroupIndex < 0)
+ return;
+
+ var switchingAdaptor = KeyboardController.Instance
+ .Adaptors[KeyboardAdaptorType.OtherIm]
+ .SwitchingAdaptor as IUnityKeyboardSwitchingAdaptor;
+ switchingAdaptor.SelectKeyboard((uint) xkbKeyboard.GroupIndex);
}
}
}