Fixes keyboard input buffer problem when opening a modal dialog

This commit is contained in:
Markus Gans 2020-03-07 21:32:18 +01:00
parent 925f106846
commit 77638fcaa0
13 changed files with 56 additions and 43 deletions

View File

@ -1,3 +1,6 @@
2020-03-07 Markus Gans <guru.mail@muenster.de>
* Fixes keyboard input buffer problem when opening a modal dialog
2020-03-05 Markus Gans <guru.mail@muenster.de> 2020-03-05 Markus Gans <guru.mail@muenster.de>
* Unbuffered reading of keystrokes for better latency * Unbuffered reading of keystrokes for better latency
* Mouse adjustments when resizing an rxvt terminal * Mouse adjustments when resizing an rxvt terminal

View File

@ -54,13 +54,16 @@ Keyboard::Keyboard (finalcut::FWidget* parent)
void Keyboard::onKeyPress (finalcut::FKeyEvent* ev) void Keyboard::onKeyPress (finalcut::FKeyEvent* ev)
{ {
const FKey key_id = ev->key(); const FKey key_id = ev->key();
finalcut::FString key_name = getKeyName(key_id);
bool is_last_line{false}; bool is_last_line{false};
if ( key_name.isEmpty() )
key_name = wchar_t(key_id);
if ( getPrintPos().getY() == int(getDesktopHeight()) ) if ( getPrintPos().getY() == int(getDesktopHeight()) )
is_last_line = true; is_last_line = true;
print() << "Key " << getKeyName(key_id).c_str() print() << "Key " << key_name << " (id " << key_id << ")\n";
<< " (id " << key_id << ")\n";
if ( is_last_line ) if ( is_last_line )
scrollAreaForward (getVirtualDesktop()); scrollAreaForward (getVirtualDesktop());

View File

@ -208,7 +208,10 @@ bool FApplication::sendEvent ( const FObject* receiver
case fc::MouseMove_Event: case fc::MouseMove_Event:
case fc::FocusIn_Event: case fc::FocusIn_Event:
case fc::FocusOut_Event: case fc::FocusOut_Event:
case fc::ChildFocusIn_Event:
case fc::ChildFocusOut_Event:
case fc::Accelerator_Event: case fc::Accelerator_Event:
keyboard->clearKeyBuffer();
return false; return false;
default: default:

View File

@ -827,6 +827,7 @@ FKeyName fkeyname[] =
{ fc::Fkey_mouse , "xterm mouse" }, { fc::Fkey_mouse , "xterm mouse" },
{ fc::Fkey_extended_mouse , "SGR extended mouse" }, { fc::Fkey_extended_mouse , "SGR extended mouse" },
{ fc::Fkey_urxvt_mouse , "urxvt mouse extension" }, { fc::Fkey_urxvt_mouse , "urxvt mouse extension" },
{ fc::Fkey_incomplete , "incomplete key string" },
{ 0 , "\0" } { 0 , "\0" }
}; };

View File

@ -260,7 +260,7 @@ inline FKey FKeyboard::getMetaKey()
|| fifo_buf[1] == ']' ) ) || fifo_buf[1] == ']' ) )
{ {
if ( ! isKeypressTimeout() ) if ( ! isKeypressTimeout() )
return fc::need_more_data; return fc::Fkey_incomplete;
} }
for (n = len; n < FIFO_BUF_SIZE; n++) // Remove founded entry for (n = len; n < FIFO_BUF_SIZE; n++) // Remove founded entry
@ -301,7 +301,7 @@ inline FKey FKeyboard::getSingleKey()
len = 4; len = 4;
if ( buf_len < len && ! isKeypressTimeout() ) if ( buf_len < len && ! isKeypressTimeout() )
return fc::need_more_data; return fc::Fkey_incomplete;
for (std::size_t i{0}; i < len ; i++) for (std::size_t i{0}; i < len ; i++)
utf8char[i] = char(fifo_buf[i] & 0xff); utf8char[i] = char(fifo_buf[i] & 0xff);
@ -431,12 +431,12 @@ void FKeyboard::parseKeyBuffer()
// Read the rest from the fifo buffer // Read the rest from the fifo buffer
while ( ! isKeypressTimeout() while ( ! isKeypressTimeout()
&& fifo_offset > 0 && fifo_offset > 0
&& key != fc::need_more_data ) && key != fc::Fkey_incomplete )
{ {
key = parseKeyString(); key = parseKeyString();
key = keyCorrection(key); key = keyCorrection(key);
if ( key != fc::need_more_data ) if ( key != fc::Fkey_incomplete )
keyPressed(); keyPressed();
fifo_offset = int(std::strlen(fifo_buf)); fifo_offset = int(std::strlen(fifo_buf));
@ -480,7 +480,7 @@ FKey FKeyboard::parseKeyString()
return keycode; return keycode;
if ( ! isKeypressTimeout() ) if ( ! isKeypressTimeout() )
return fc::need_more_data; return fc::Fkey_incomplete;
} }
return getSingleKey(); return getSingleKey();

View File

@ -275,47 +275,40 @@ void FTermcap::termcapKeys (char*& buffer)
} }
// VT100 key codes for the arrow and function keys // VT100 key codes for the arrow and function keys
termcapKeysVt100 (buffer); termcapKeysVt100();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTermcap::termcapKeysVt100 (char*& buffer) void FTermcap::termcapKeysVt100()
{ {
// Some terminals (e.g. PuTTY) send vt100 key codes for // Some terminals (e.g. PuTTY) send vt100 key codes for
// the arrow and function keys. // the arrow and function keys.
const char* key_up_string = tgetstr(C_STR("ku"), &buffer); for (std::size_t i{0}; fc::fkey[i].tname[0] != 0; i++)
if ( (key_up_string && (std::strcmp(key_up_string, ESC "OA") == 0))
|| ( TCAP(fc::t_cursor_up)
&& (std::strcmp(TCAP(fc::t_cursor_up), CSI "A") == 0) ) )
{ {
for (std::size_t i{0}; fc::fkey[i].tname[0] != 0; i++) if ( std::strncmp(fc::fkey[i].tname, "kux", 3) == 0 )
{ fc::fkey[i].string = C_STR(CSI "A"); // Key up
if ( std::strncmp(fc::fkey[i].tname, "kux", 3) == 0 )
fc::fkey[i].string = C_STR(CSI "A"); // Key up
if ( std::strncmp(fc::fkey[i].tname, "kdx", 3) == 0 ) if ( std::strncmp(fc::fkey[i].tname, "kdx", 3) == 0 )
fc::fkey[i].string = C_STR(CSI "B"); // Key down fc::fkey[i].string = C_STR(CSI "B"); // Key down
if ( std::strncmp(fc::fkey[i].tname, "krx", 3) == 0 ) if ( std::strncmp(fc::fkey[i].tname, "krx", 3) == 0 )
fc::fkey[i].string = C_STR(CSI "C"); // Key right fc::fkey[i].string = C_STR(CSI "C"); // Key right
if ( std::strncmp(fc::fkey[i].tname, "klx", 3) == 0 ) if ( std::strncmp(fc::fkey[i].tname, "klx", 3) == 0 )
fc::fkey[i].string = C_STR(CSI "D"); // Key left fc::fkey[i].string = C_STR(CSI "D"); // Key left
if ( std::strncmp(fc::fkey[i].tname, "k1X", 3) == 0 ) if ( std::strncmp(fc::fkey[i].tname, "k1X", 3) == 0 )
fc::fkey[i].string = C_STR(ESC "OP"); // PF1 fc::fkey[i].string = C_STR(ESC "OP"); // PF1
if ( std::strncmp(fc::fkey[i].tname, "k2X", 3) == 0 ) if ( std::strncmp(fc::fkey[i].tname, "k2X", 3) == 0 )
fc::fkey[i].string = C_STR(ESC "OQ"); // PF2 fc::fkey[i].string = C_STR(ESC "OQ"); // PF2
if ( std::strncmp(fc::fkey[i].tname, "k3X", 3) == 0 ) if ( std::strncmp(fc::fkey[i].tname, "k3X", 3) == 0 )
fc::fkey[i].string = C_STR(ESC "OR"); // PF3 fc::fkey[i].string = C_STR(ESC "OR"); // PF3
if ( std::strncmp(fc::fkey[i].tname, "k4X", 3) == 0 ) if ( std::strncmp(fc::fkey[i].tname, "k4X", 3) == 0 )
fc::fkey[i].string = C_STR(ESC "OS"); // PF4 fc::fkey[i].string = C_STR(ESC "OS"); // PF4
}
} }
} }

View File

@ -360,6 +360,14 @@ void FTermcapQuirks::putty()
TCAP(fc::t_exit_pc_charset_mode) = \ TCAP(fc::t_exit_pc_charset_mode) = \
C_STR(CSI "10m"); C_STR(CSI "10m");
if ( ! TCAP(fc::t_keypad_xmit) )
TCAP(fc::t_keypad_xmit) = \
C_STR(CSI "?1h" ESC "=");
if ( ! TCAP(fc::t_keypad_local) )
TCAP(fc::t_keypad_local) = \
C_STR(CSI "?1l" ESC ">");
if ( ! TCAP(fc::t_key_mouse) ) if ( ! TCAP(fc::t_key_mouse) )
TCAP(fc::t_key_mouse) = \ TCAP(fc::t_key_mouse) = \
C_STR(CSI "M"); C_STR(CSI "M");

View File

@ -1820,7 +1820,9 @@ void FWidget::KeyPressEvent (FKeyEvent* kev)
} }
} }
if ( kev->isAccepted() || widget->isRootWidget() ) if ( kev->isAccepted()
|| widget->isRootWidget()
|| widget->getFlags().modal )
return; return;
widget = widget->getParentWidget(); widget = widget->getParentWidget();

View File

@ -459,7 +459,7 @@ enum keys : FKey
Fkey_f61 = 0x01000192, Fkey_f61 = 0x01000192,
Fkey_f62 = 0x01000193, Fkey_f62 = 0x01000193,
Fkey_f63 = 0x01000194, Fkey_f63 = 0x01000194,
need_more_data = 0x80000000 Fkey_incomplete = UINT32_MAX
}; };
// Keyboard - modifier key combinations // Keyboard - modifier key combinations

View File

@ -118,7 +118,7 @@ class FTermcap final
static void termcapNumerics(); static void termcapNumerics();
static void termcapStrings (char*&); static void termcapStrings (char*&);
static void termcapKeys (char*&); static void termcapKeys (char*&);
static void termcapKeysVt100 (char*&); static void termcapKeysVt100();
// Data member // Data member
static FTermData* fterm_data; static FTermData* fterm_data;

View File

@ -3,7 +3,7 @@
* * * *
* This file is part of the Final Cut widget toolkit * * This file is part of the Final Cut widget toolkit *
* * * *
* Copyright 2018-2019 Markus Gans * * Copyright 2018-2020 Markus Gans *
* * * *
* The Final Cut is free software; you can redistribute it and/or * * The Final Cut is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License * * modify it under the terms of the GNU Lesser General Public License *