| 850 | } |
| 851 | |
| 852 | void InputMethod::startInputMethod() |
| 853 | { |
| 854 | stopInputMethod(); |
| 855 | if (m_inputMethodCommand.isEmpty() || kwinApp()->isTerminating()) { |
| 856 | return; |
| 857 | } |
| 858 | |
| 859 | QStringList arguments = KShell::splitArgs(m_inputMethodCommand); |
| 860 | if (arguments.isEmpty()) { |
| 861 | qWarning("Failed to launch the input method server: %s is an invalid command", qPrintable(m_inputMethodCommand)); |
| 862 | return; |
| 863 | } |
| 864 | |
| 865 | const QString program = arguments.takeFirst(); |
| 866 | int socket = waylandServer()->createInputMethodConnection(); |
| 867 | if (socket < 0) { |
| 868 | qWarning("Failed to create the input method connection"); |
| 869 | return; |
| 870 | } |
| 871 | socket = dup(socket); |
| 872 | |
| 873 | QProcessEnvironment environment = kwinApp()->processStartupEnvironment(); |
| 874 | environment.insert(QStringLiteral("WAYLAND_SOCKET"), QString::number(socket)); |
| 875 | environment.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland")); |
| 876 | // When we use Maliit as virtual keyboard, we want KWin to handle the animation |
| 877 | // since that works a lot better. So we need to tell Maliit to not do client side |
| 878 | // animation. |
| 879 | environment.insert(QStringLiteral("MALIIT_ENABLE_ANIMATIONS"), QStringLiteral("0")); |
| 880 | |
| 881 | if (qEnvironmentVariableIntValue("KWIN_IM_WAYLAND_DEBUG") == 1) { |
| 882 | environment.insert("WAYLAND_DEBUG", QByteArrayLiteral("1")); |
| 883 | } |
| 884 | |
| 885 | m_inputMethodProcess = new QProcess(this); |
| 886 | m_inputMethodProcess->setProcessChannelMode(QProcess::ForwardedErrorChannel); |
| 887 | m_inputMethodProcess->setProcessEnvironment(environment); |
| 888 | m_inputMethodProcess->setProgram(program); |
| 889 | m_inputMethodProcess->setArguments(arguments); |
| 890 | m_inputMethodProcess->start(); |
| 891 | close(socket); |
| 892 | connect(m_inputMethodProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) { |
| 893 | if (exitStatus == QProcess::CrashExit) { |
| 894 | m_inputMethodCrashes++; |
| 895 | m_inputMethodCrashTimer.start(); |
| 896 | qWarning() << "Input Method crashed" << m_inputMethodProcess->program() << m_inputMethodProcess->arguments() << exitCode << exitStatus; |
| 897 | if (m_inputMethodCrashes < 5) { |
| 898 | startInputMethod(); |
| 899 | } else { |
| 900 | qWarning() << "Input Method keeps crashing, please fix" << m_inputMethodProcess->program() << m_inputMethodProcess->arguments(); |
| 901 | stopInputMethod(); |
| 902 | } |
| 903 | } |
| 904 | }); |
| 905 | } |
| 906 | bool InputMethod::isActive() const |
| 907 | { |
| 908 | return waylandServer()->inputMethod()->context(); |
nothing calls this directly
no test coverage detected