From 9fa7b2bb57e10df1dfa75671fabeefa87ef00149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 7 Jan 2026 13:23:22 -0300 Subject: [PATCH] Correctly handle Private mode queries in the terminal emulator implementation. Fix in terminal keybindings handling. --- .../eterm/terminal/terminalemulator.hpp | 1 + .../src/eterm/terminal/terminalemulator.cpp | 56 ++++++++++++++++++- src/modules/eterm/src/eterm/ui/uiterminal.cpp | 5 +- src/tools/ecode/terminalmanager.cpp | 2 + 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp b/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp index 58b11df44..391c9ba39 100644 --- a/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp +++ b/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp @@ -374,6 +374,7 @@ class TerminalEmulator final { void xximspot( int, int ); int xgetcolor( int x, unsigned char* r, unsigned char* g, unsigned char* b ); void osc_color_response( int num, int index, int is_osc4 ); + void handleDeviceAttributes(); void trimMemory(); diff --git a/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp b/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp index e2f4162fa..ff9e99c5e 100644 --- a/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp +++ b/src/modules/eterm/src/eterm/terminal/terminalemulator.cpp @@ -1223,6 +1223,14 @@ int32_t TerminalEmulator::tdefcolor( int* attr, int* npar, int l ) { } void TerminalEmulator::tsetattr( int* attr, int l ) { + // Check if this is a private sequence (should be ignored for SGR) + // Private sequences start with '?' and should not affect text attributes + if ( mCsiescseq.priv ) { + // Private mode queries/commands don't set text attributes + // Just return without changing any attributes + return; + } + int i; int32_t idx; @@ -1360,6 +1368,8 @@ void TerminalEmulator::tsetmode( int priv, int set, int* args, int narg ) { case 18: /* DECPFF -- Printer feed (IGNORED) */ case 19: /* DECPEX -- Printer extent (IGNORED) */ case 42: /* DECNRCM -- National characters (IGNORED) */ + case 45: /* Reverse wrap-around (IGNORED) */ + case 67: /* DECBKM -- Backarrow key sends backspace vs DEL (IGNORED) */ case 12: /* att610 -- Start blinking cursor (IGNORED) */ break; case 25: /* DECTCEM -- Text Cursor Enable Mode */ @@ -1427,12 +1437,15 @@ void TerminalEmulator::tsetmode( int priv, int set, int* args, int narg ) { case 1015: /* urxvt mangled mouse mode; incompatible and can be mistaken for other control codes. */ + case 1039: /* ESC to Meta (not implemented) */ break; case 2026: // IGNORE DECSET/DECRST 2026 for sync updates // (https://codeberg.org/dnkl/foot/pulls/461/files) break; default: +#ifdef EE_DEBUG fprintf( stderr, "erresc: unknown private set/reset mode %d\n", *args ); +#endif break; } } else { @@ -1452,13 +1465,45 @@ void TerminalEmulator::tsetmode( int priv, int set, int* args, int narg ) { MODBIT( mTerm.mode, set, MODE_CRLF ); break; default: +#ifdef EE_DEBUG fprintf( stderr, "erresc: unknown set/reset mode %d\n", *args ); +#endif break; } } } } +void TerminalEmulator::handleDeviceAttributes() { + if ( mCsiescseq.priv ) { + char buf[64]; + int len; + // Private Device Attributes - respond with terminal capabilities + switch ( mCsiescseq.arg[0] ) { + case 0: // Primary DA + case 1: // Secondary DA + // Respond with VT220 emulation + len = snprintf( buf, sizeof( buf ), "\033[?1;2c" ); + ttywrite( buf, len, 0 ); + break; + case 62: // Request terminfo/termcap name + // Respond with our terminal name + len = snprintf( buf, sizeof( buf ), "\033P1+r%s\033\\", "st-256color" ); + ttywrite( buf, len, 0 ); + break; + case 63: // Request terminfo/termcap name (secondary) + // Similar response + break; + default: + // Unknown private DA query + break; + } + } else { + // Standard DA - respond with VT100 identification + ttywrite( vtiden, strlen( vtiden ), 0 ); + } +} + void TerminalEmulator::csihandle( void ) { char buf[40]; int len; @@ -1507,8 +1552,7 @@ void TerminalEmulator::csihandle( void ) { } break; case 'c': /* DA -- Device Attributes */ - if ( mCsiescseq.arg[0] == 0 ) - ttywrite( vtiden, strlen( vtiden ), 0 ); + handleDeviceAttributes(); break; case 'b': /* REP -- if last char is printable print it more times */ DEFAULT( mCsiescseq.arg[0], 1 ); @@ -1732,6 +1776,12 @@ void TerminalEmulator::csihandle( void ) { goto unknown; } break; + case '?': + /* Private mode queries - ignore or handle appropriately */ + /* For XTQMODKEYS and similar queries, we should either: + 1. Ignore completely (do nothing) + 2. Send a proper response if required */ + break; } } @@ -1808,7 +1858,7 @@ void TerminalEmulator::strhandle( void ) { dec = base64dec( mStrescseq.args[2] ); if ( dec ) { setClipboard( dec ); - free( dec ); + xfree( dec ); } else { fprintf( stderr, "erresc: invalid base64\n" ); } diff --git a/src/modules/eterm/src/eterm/ui/uiterminal.cpp b/src/modules/eterm/src/eterm/ui/uiterminal.cpp index 719870211..540f7d57d 100644 --- a/src/modules/eterm/src/eterm/ui/uiterminal.cpp +++ b/src/modules/eterm/src/eterm/ui/uiterminal.cpp @@ -462,9 +462,8 @@ Uint32 UITerminal::onKeyDown( const KeyEvent& event ) { if ( !mTerm->isRegisteredShortcut( event.getKeyCode(), event.getMod() ) ) { std::string cmd = mKeyBindings.getCommandFromKeyBind( { event.getKeyCode(), event.getMod() } ); - if ( !cmd.empty() ) { - if ( !mExclusiveMode || cmd == getExclusiveModeToggleCommandName() ) - execute( cmd ); + if ( !cmd.empty() && ( !mExclusiveMode || cmd == getExclusiveModeToggleCommandName() ) ) { + execute( cmd ); return 1; } } diff --git a/src/tools/ecode/terminalmanager.cpp b/src/tools/ecode/terminalmanager.cpp index 16bf7d2dd..260fd33a5 100644 --- a/src/tools/ecode/terminalmanager.cpp +++ b/src/tools/ecode/terminalmanager.cpp @@ -628,6 +628,8 @@ UITerminal* TerminalManager::createNewTerminal( } } ); mApp->registerUnlockedCommands( *term ); + term->getKeyBindings().removeCommandKeybind( "find-replace" ); + term->getKeyBindings().removeCommandKeybind( "open-locatebar" ); term->setFocus(); return term; #endif