diff --git a/konsole/src/Pty.cpp b/konsole/src/Pty.cpp index 564e0da..1e4004a 100644 --- a/konsole/src/Pty.cpp +++ b/konsole/src/Pty.cpp @@ -24,6 +24,7 @@ // System #include #include +#include // Qt #include @@ -65,6 +66,12 @@ void Pty::init() setPtyChannels(KPtyProcess::AllChannels); connect(pty(), SIGNAL(readyRead()) , this , SLOT(dataReceived())); + + // Workaround for macOS/Katie: readyRead() signal doesn't work reliably on macOS + // Use a timer to poll for data instead + _pollTimer = new QTimer(this); + connect(_pollTimer, SIGNAL(timeout()), this, SLOT(dataReceived())); + _pollTimer->start(10); // Poll every 10ms } Pty::~Pty() @@ -84,8 +91,24 @@ void Pty::sendData(const char* data, int length) void Pty::dataReceived() { + // Try Katie's readAll() first QByteArray data = pty()->readAll(); - emit receivedData(data.constData(), data.count()); + + // If Katie's readAll() doesn't work (returns 0 on macOS), try direct read from file descriptor + if (data.count() == 0) { + int fd = pty()->masterFd(); + if (fd >= 0) { + char buffer[4096]; + ssize_t len = ::read(fd, buffer, sizeof(buffer)); + if (len > 0) { + data = QByteArray(buffer, len); + } + } + } + + if (data.count() > 0) { + emit receivedData(data.constData(), data.count()); + } } void Pty::setWindowSize(int columns, int lines) diff --git a/konsole/src/Pty.h b/konsole/src/Pty.h index 3954aae..204eac6 100644 --- a/konsole/src/Pty.h +++ b/konsole/src/Pty.h @@ -25,6 +25,7 @@ // Qt #include +#include // KDE #include @@ -185,6 +186,9 @@ private: char _eraseChar; bool _xonXoff; bool _utf8; + + // Workaround for macOS/Katie: poll PTY for data since readyRead() signal doesn't work + QTimer* _pollTimer; }; } diff --git a/konsole/src/TerminalDisplay.cpp b/konsole/src/TerminalDisplay.cpp index 15488cc..7120cec 100644 --- a/konsole/src/TerminalDisplay.cpp +++ b/konsole/src/TerminalDisplay.cpp @@ -346,7 +346,7 @@ TerminalDisplay::TerminalDisplay(QWidget* parent) setAcceptDrops(true); _dragInfo.state = diNone; - setFocusPolicy(Qt::WheelFocus); + setFocusPolicy(Qt::StrongFocus); // this is an important optimization, it tells Qt // that TerminalDisplay will handle repainting its entire area. @@ -1691,6 +1691,7 @@ QSize TerminalDisplay::sizeHint() const //the same signal as the one for a content size change void TerminalDisplay::showEvent(QShowEvent*) { + setFocus(Qt::OtherFocusReason); emit changedContentSizeSignal(_contentRect.height(), _contentRect.width()); } void TerminalDisplay::hideEvent(QHideEvent*) @@ -1788,6 +1789,8 @@ bool TerminalDisplay::scrollFullPage() const /* ------------------------------------------------------------------------- */ void TerminalDisplay::mousePressEvent(QMouseEvent* ev) { + setFocus(Qt::MouseFocusReason); + if (_possibleTripleClick && (ev->button() == Qt::LeftButton)) { mouseTripleClickEvent(ev); return; @@ -2902,6 +2905,14 @@ bool TerminalDisplay::handleShortcutOverrideEvent(QKeyEvent* keyEvent) keyEvent->accept(); return true; } + + // On macOS with Katie, we need to accept ShortcutOverride for all printable + // keys to ensure KeyPress events are delivered to the terminal + if (!keyEvent->text().isEmpty()) { + keyEvent->accept(); + return true; + } + return false; }