lxqt / qtermwidget

The terminal widget for QTerminal

Home Page:https://lxqt.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Missing TERM environment variable

willbelr opened this issue · comments

Some odd behaviors happen when Vim is launched without a terminal, such as mouse and hotkey not working correctly. The problem narrows down to the TERM variable, which is not set by QTermWidget. Thus, setting it to "xterm" fixes it. The solution is easy, but I was wondering if it should rather be set by QTermWidget by default. Using an arbitrary value does not work, but xterm does it.

The bug can be reproduced by enabling or disabling the 'terminal' variable in a desktop file (ie. vim.desktop):

[Desktop Entry]
Name=Test
Exec=python /tmp/vim.py
Terminal=false
Type=Application

PyQt minimal example (ie. /tmp/vim.py)

#!/usr/bin/python3
from PyQt5 import QtWidgets
from QTermWidget import QTermWidget

NOTE = "/tmp/note.txt"
with open(NOTE, "w") as f:
    f.write("a\nb\nc\nd\ne\nf")


class Terminal(QTermWidget):
    def __init__(self, process: str, args: list):
        super().__init__(0)
        self.finished.connect(self.close)
        self.setEnvironment(["TERM=xterm"])  # Workaround
        self.setColorScheme("DarkPastels")
        self.setShellProgram(process)
        self.setArgs(args)
        self.startShellProgram()
        self.resize(300, 200)
        self.show()


app = QtWidgets.QApplication([])
args = ["--clean", "--noplugin",
        "--cmd", "set mouse=a",
        NOTE]
term = Terminal("vim", args)
app.exec()

In my case I had to make the following C++ call to QTermWidget:

QTermWidget->sendText("export TERM=xterm\n");

I've added an additional "clear\n" so the output of the export doesn't appear in the terminal. Not beautiful, but solves the issue. Being a UI widget I would assume that at least for Q_OS_LINUX this would be included in the instantiation of QTermWidget.

I've added an additional "clear\n" so the output of the export doesn't appear in the terminal.

Unfortunately, the setEnvironment only works with startnow=0. Thus to declare TERM in the console one must use sendText indeed;

if vim:
    super().__init__(0)
    self.setEnvironment(["TERM=xterm"])
elif script:
    super().__init__(0)
    self.setEnvironment(["TERM=xterm"])
    self.setShellProgram(program)
    self.setArgs([path])
    self.startShellProgram()
else:
    # Console
    super().__init__(1)
    self.sendText("export TERM=xterm && clear\n")

To add on this, programs such as clear or htop won't run unless TERM is defined;

TERM environment variable not set.

@francescmm Looking at the source code, all startnow does in QTermWidget::init is:

    if (startnow && m_impl->m_session) {
        m_impl->m_session->run();
    }

Which can also be called with QTermWidget::startShellProgram() when no session is running (ie. no program set).

void QTermWidget::startShellProgram()
{
    if ( m_impl->m_session->isRunning() ) {
        return;
    }

    m_impl->m_session->run();
}

Hence, instead of using sendText,

    super().__init__(1)
    self.sendText("export TERM=xterm && clear\n")

One can set the environement then start the session:

    super().__init__(0)
    self.setEnvironment(env)
    self.startShellProgram()

Hope this helps

Thanks for the tip. I agree qtermwidget should define default TERM. Probably moving relevant logic from qterminal to qtermwidget.

Fixed by #511