Optimized input cursor positioning for terminals without hidden cursor
This commit is contained in:
parent
125c4b961b
commit
04a483526f
|
@ -1,5 +1,11 @@
|
||||||
|
2016-11-12 Markus Gans <guru.mail@muenster.de>
|
||||||
|
* Better support for Linux terminals with 8 colors
|
||||||
|
* Optimized input cursor positioning for terminals without hidden cursor
|
||||||
|
* Switch locale name from "en_US" to "C"
|
||||||
|
* Fix FString toLong()
|
||||||
|
|
||||||
2016-11-06 Markus Gans <guru.mail@muenster.de>
|
2016-11-06 Markus Gans <guru.mail@muenster.de>
|
||||||
* The use of xterm default colors now is configurable
|
* The adjustment of xterm default colors now is configurable
|
||||||
|
|
||||||
2016-11-05 Markus Gans <guru.mail@muenster.de>
|
2016-11-05 Markus Gans <guru.mail@muenster.de>
|
||||||
* Determine xterm maximum number of colors via OSC 4
|
* Determine xterm maximum number of colors via OSC 4
|
||||||
|
|
|
@ -79,6 +79,7 @@ void FButton::setHotkeyForegroundColor (short color)
|
||||||
button_hotkey_fg = color;
|
button_hotkey_fg = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
void FButton::setFocusForegroundColor (short color)
|
void FButton::setFocusForegroundColor (short color)
|
||||||
{
|
{
|
||||||
// valid colors -1..254
|
// valid colors -1..254
|
||||||
|
|
|
@ -592,6 +592,7 @@ void FMenu::onMouseMove (FMouseEvent* ev)
|
||||||
{
|
{
|
||||||
// Unselect selected item without mouse focus
|
// Unselect selected item without mouse focus
|
||||||
(*iter)->unsetSelected();
|
(*iter)->unsetSelected();
|
||||||
|
(*iter)->unsetFocus();
|
||||||
|
|
||||||
if ( getSelectedItem() == *iter )
|
if ( getSelectedItem() == *iter )
|
||||||
setSelectedItem(0);
|
setSelectedItem(0);
|
||||||
|
@ -1055,12 +1056,12 @@ bool FMenu::selectNextItem()
|
||||||
unselectItem();
|
unselectItem();
|
||||||
next->setSelected();
|
next->setSelected();
|
||||||
setSelectedItem(next);
|
setSelectedItem(next);
|
||||||
redraw();
|
|
||||||
next->setFocus();
|
next->setFocus();
|
||||||
|
|
||||||
if ( getStatusBar() )
|
if ( getStatusBar() )
|
||||||
getStatusBar()->drawMessage();
|
getStatusBar()->drawMessage();
|
||||||
|
|
||||||
|
redraw();
|
||||||
updateTerminal();
|
updateTerminal();
|
||||||
flush_out();
|
flush_out();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -256,9 +256,7 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
|
||||||
x1 = (*iter)->getX();
|
x1 = (*iter)->getX();
|
||||||
x2 = (*iter)->getX() + (*iter)->getWidth();
|
x2 = (*iter)->getX() + (*iter)->getWidth();
|
||||||
|
|
||||||
if ( mouse_y == 1 )
|
if ( mouse_y == 1 && (*iter)->isEnabled() && (*iter)->isSelected() )
|
||||||
{
|
|
||||||
if ( (*iter)->isEnabled() && (*iter)->isSelected() )
|
|
||||||
{
|
{
|
||||||
if ( mouse_x >= x1 && mouse_x < x2 )
|
if ( mouse_x >= x1 && mouse_x < x2 )
|
||||||
{
|
{
|
||||||
|
@ -276,12 +274,11 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
|
||||||
if ( first_item )
|
if ( first_item )
|
||||||
first_item->setFocus();
|
first_item->setFocus();
|
||||||
|
|
||||||
menu->redraw();
|
|
||||||
|
|
||||||
if ( getStatusBar() )
|
if ( getStatusBar() )
|
||||||
getStatusBar()->drawMessage();
|
getStatusBar()->drawMessage();
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
menu->redraw();
|
||||||
drop_down = true;
|
drop_down = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,7 +306,6 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,6 +271,7 @@ void FMenuItem::setSelected()
|
||||||
void FMenuItem::unsetSelected()
|
void FMenuItem::unsetSelected()
|
||||||
{
|
{
|
||||||
selected = false;
|
selected = false;
|
||||||
|
unsetCursorPos();
|
||||||
processDeactivate();
|
processDeactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -690,7 +690,7 @@ long FString::toLong() const
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( std::isdigit(*p) )
|
while ( std::iswdigit(*p) )
|
||||||
{
|
{
|
||||||
register uChar d = uChar((*p) - L'0');
|
register uChar d = uChar((*p) - L'0');
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ long FString::toLong() const
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! std::isdigit(*p) )
|
if ( *p != L'\0' && ! std::iswdigit(*p) )
|
||||||
throw std::invalid_argument ("no valid number");
|
throw std::invalid_argument ("no valid number");
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
|
@ -736,7 +736,7 @@ uLong FString::toULong() const
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( std::isdigit(*p) )
|
while ( std::iswdigit(*p) )
|
||||||
{
|
{
|
||||||
register uChar d = uChar((*p) - L'0');
|
register uChar d = uChar((*p) - L'0');
|
||||||
|
|
||||||
|
@ -750,7 +750,7 @@ uLong FString::toULong() const
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! std::isdigit(*p) )
|
if ( *p != L'\0' && ! std::iswdigit(*p) )
|
||||||
throw std::invalid_argument ("no valid number");
|
throw std::invalid_argument ("no valid number");
|
||||||
|
|
||||||
return num;
|
return num;
|
||||||
|
|
|
@ -27,6 +27,7 @@ int FTerm::stdin_status_flags;
|
||||||
uInt FTerm::baudrate;
|
uInt FTerm::baudrate;
|
||||||
bool FTerm::resize_term;
|
bool FTerm::resize_term;
|
||||||
bool FTerm::mouse_support;
|
bool FTerm::mouse_support;
|
||||||
|
bool FTerm::terminal_detection;
|
||||||
bool FTerm::raw_mode;
|
bool FTerm::raw_mode;
|
||||||
bool FTerm::input_data_pending;
|
bool FTerm::input_data_pending;
|
||||||
bool FTerm::non_blocking_stdin;
|
bool FTerm::non_blocking_stdin;
|
||||||
|
@ -2265,7 +2266,6 @@ char* FTerm::parseSecDA (char*& current_termtype)
|
||||||
{
|
{
|
||||||
terminal_id_version = -1;
|
terminal_id_version = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( terminal_id_type )
|
switch ( terminal_id_type )
|
||||||
{
|
{
|
||||||
case 0: // DEC VT100
|
case 0: // DEC VT100
|
||||||
|
@ -2520,7 +2520,8 @@ void FTerm::init_termcaps()
|
||||||
FTermcap::eat_nl_glitch = true;
|
FTermcap::eat_nl_glitch = true;
|
||||||
|
|
||||||
// maximum number of colors on screen
|
// maximum number of colors on screen
|
||||||
FTermcap::max_color = tgetnum(const_cast<char*>("Co"));
|
FTermcap::max_color = std::max( FTermcap::max_color
|
||||||
|
, tgetnum(const_cast<char*>("Co")) );
|
||||||
|
|
||||||
if ( FTermcap::max_color < 0 )
|
if ( FTermcap::max_color < 0 )
|
||||||
FTermcap::max_color = 1;
|
FTermcap::max_color = 1;
|
||||||
|
@ -2576,11 +2577,22 @@ void FTerm::init_termcaps()
|
||||||
|
|
||||||
// set ansi foreground and background color
|
// set ansi foreground and background color
|
||||||
if ( linux_terminal || cygwin_terminal )
|
if ( linux_terminal || cygwin_terminal )
|
||||||
|
{
|
||||||
|
if ( FTermcap::max_color > 8 )
|
||||||
{
|
{
|
||||||
tcap[fc::t_set_a_foreground].string = \
|
tcap[fc::t_set_a_foreground].string = \
|
||||||
const_cast<char*>(CSI "3%p1%{8}%m%d%?%p1%{7}%>%t;1%e;21%;m");
|
const_cast<char*>(CSI "3%p1%{8}%m%d%?%p1%{7}%>%t;1%e;21%;m");
|
||||||
tcap[fc::t_set_a_background].string = \
|
tcap[fc::t_set_a_background].string = \
|
||||||
const_cast<char*>(CSI "4%p1%{8}%m%d%?%p1%{7}%>%t;5%e;25%;m");
|
const_cast<char*>(CSI "4%p1%{8}%m%d%?%p1%{7}%>%t;5%e;25%;m");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tcap[fc::t_set_a_foreground].string = \
|
||||||
|
const_cast<char*>(CSI "3%p1%dm");
|
||||||
|
tcap[fc::t_set_a_background].string = \
|
||||||
|
const_cast<char*>(CSI "4%p1%dm");
|
||||||
|
}
|
||||||
|
|
||||||
tcap[fc::t_orig_pair].string = \
|
tcap[fc::t_orig_pair].string = \
|
||||||
const_cast<char*>(CSI "39;49;25m");
|
const_cast<char*>(CSI "39;49;25m");
|
||||||
}
|
}
|
||||||
|
@ -2946,6 +2958,7 @@ void FTerm::init()
|
||||||
VGAFont = \
|
VGAFont = \
|
||||||
ascii_console = \
|
ascii_console = \
|
||||||
mouse_support = \
|
mouse_support = \
|
||||||
|
|
||||||
force_vt100 = \
|
force_vt100 = \
|
||||||
tera_terminal = \
|
tera_terminal = \
|
||||||
kterm_terminal = \
|
kterm_terminal = \
|
||||||
|
@ -2960,7 +2973,8 @@ void FTerm::init()
|
||||||
xterm_default_colors = false;
|
xterm_default_colors = false;
|
||||||
|
|
||||||
// Preset to true
|
// Preset to true
|
||||||
cursor_optimisation = true;
|
cursor_optimisation = \
|
||||||
|
terminal_detection = true;
|
||||||
|
|
||||||
// assertion: programm start in cooked mode
|
// assertion: programm start in cooked mode
|
||||||
raw_mode = \
|
raw_mode = \
|
||||||
|
@ -3015,7 +3029,9 @@ void FTerm::init()
|
||||||
else
|
else
|
||||||
linux_terminal = false;
|
linux_terminal = false;
|
||||||
|
|
||||||
// start terminal detection...
|
// terminal detection
|
||||||
|
if ( terminal_detection )
|
||||||
|
{
|
||||||
setRawMode();
|
setRawMode();
|
||||||
|
|
||||||
// Identify the terminal via the answerback-message
|
// Identify the terminal via the answerback-message
|
||||||
|
@ -3024,24 +3040,50 @@ void FTerm::init()
|
||||||
// Identify the terminal via the secondary device attributes (SEC_DA)
|
// Identify the terminal via the secondary device attributes (SEC_DA)
|
||||||
new_termtype = parseSecDA (new_termtype);
|
new_termtype = parseSecDA (new_termtype);
|
||||||
|
|
||||||
if ( ! color256 && getXTermColorName(0) != "" )
|
// Determine xterm maximum number of colors via OSC 4
|
||||||
|
if ( ! color256 && ! tera_terminal && getXTermColorName(0) != "" )
|
||||||
{
|
{
|
||||||
if ( getXTermColorName(256) != "" )
|
if ( getXTermColorName(256) != "" )
|
||||||
{
|
{
|
||||||
new_termtype = const_cast<char*>("xterm-256color");
|
new_termtype = const_cast<char*>("xterm-256color");
|
||||||
}
|
}
|
||||||
else if ( FTermcap::max_color < 88 && getXTermColorName(87) != "" )
|
else if ( getXTermColorName(87) != "" )
|
||||||
{
|
{
|
||||||
new_termtype = const_cast<char*>("xterm-88color");
|
new_termtype = const_cast<char*>("xterm-88color");
|
||||||
}
|
}
|
||||||
else if ( FTermcap::max_color < 16 && getXTermColorName(15) != "" )
|
else if ( getXTermColorName(15) != "" )
|
||||||
{
|
{
|
||||||
new_termtype = const_cast<char*>("xterm-16color");
|
new_termtype = const_cast<char*>("xterm-16color");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( cygwin_terminal
|
||||||
|
|| putty_terminal
|
||||||
|
|| tera_terminal
|
||||||
|
|| rxvt_terminal )
|
||||||
|
{
|
||||||
|
FTermcap::max_color = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( linux_terminal && openConsole() == 0 )
|
||||||
|
{
|
||||||
|
if ( isConsole() )
|
||||||
|
{
|
||||||
|
if ( setBlinkAsIntensity(true) == 0 )
|
||||||
|
FTermcap::max_color = 16;
|
||||||
|
else
|
||||||
|
FTermcap::max_color = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeConsole();
|
||||||
|
setConsoleCursor(fc::underscore_cursor, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( linux_terminal && getFramebuffer_bpp() >= 4 )
|
||||||
|
FTermcap::max_color = 16;
|
||||||
|
|
||||||
unsetRawMode();
|
unsetRawMode();
|
||||||
// ...end of terminal detection
|
}
|
||||||
|
|
||||||
// stop non-blocking stdin
|
// stop non-blocking stdin
|
||||||
unsetNonBlockingInput();
|
unsetNonBlockingInput();
|
||||||
|
@ -3083,11 +3125,7 @@ void FTerm::init()
|
||||||
|
|
||||||
// TeraTerm can not show UTF-8 character
|
// TeraTerm can not show UTF-8 character
|
||||||
if ( tera_terminal && ! std::strcmp(nl_langinfo(CODESET), "UTF-8") )
|
if ( tera_terminal && ! std::strcmp(nl_langinfo(CODESET), "UTF-8") )
|
||||||
locale_name = std::setlocale (LC_ALL, "en_US");
|
locale_name = std::setlocale (LC_ALL, "C");
|
||||||
|
|
||||||
// if locale C => switch from 7bit ascii -> latin1
|
|
||||||
if ( isatty(stdout_no) && ! std::strcmp(nl_langinfo(CODESET), "ANSI_X3.4-1968") )
|
|
||||||
locale_name = std::setlocale (LC_ALL, "en_US");
|
|
||||||
|
|
||||||
// try to found a meaningful content for locale_name
|
// try to found a meaningful content for locale_name
|
||||||
if ( locale_name )
|
if ( locale_name )
|
||||||
|
@ -3164,29 +3202,6 @@ void FTerm::init()
|
||||||
unsetNonBlockingInput();
|
unsetNonBlockingInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (FTermcap::max_color == 8)
|
|
||||||
&& ( linux_terminal
|
|
||||||
|| cygwin_terminal
|
|
||||||
|| putty_terminal
|
|
||||||
|| tera_terminal
|
|
||||||
|| rxvt_terminal) )
|
|
||||||
{
|
|
||||||
FTermcap::max_color = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( linux_terminal && openConsole() == 0 )
|
|
||||||
{
|
|
||||||
if ( isConsole() )
|
|
||||||
if ( setBlinkAsIntensity(true) != 0 )
|
|
||||||
FTermcap::max_color = 8;
|
|
||||||
|
|
||||||
closeConsole();
|
|
||||||
setConsoleCursor(fc::underscore_cursor, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( linux_terminal && getFramebuffer_bpp() >= 4 )
|
|
||||||
FTermcap::max_color = 16;
|
|
||||||
|
|
||||||
if ( kde_konsole )
|
if ( kde_konsole )
|
||||||
setKDECursor(fc::UnderlineCursor);
|
setKDECursor(fc::UnderlineCursor);
|
||||||
|
|
||||||
|
|
|
@ -313,6 +313,7 @@ class FTerm
|
||||||
static FTermcap::tcap_map* tcap;
|
static FTermcap::tcap_map* tcap;
|
||||||
|
|
||||||
static bool mouse_support;
|
static bool mouse_support;
|
||||||
|
static bool terminal_detection;
|
||||||
static bool raw_mode;
|
static bool raw_mode;
|
||||||
static bool input_data_pending;
|
static bool input_data_pending;
|
||||||
static bool non_blocking_stdin;
|
static bool non_blocking_stdin;
|
||||||
|
|
|
@ -22,6 +22,8 @@ FWidget::widgetList* FWidget::dialog_list = 0;
|
||||||
FWidget::widgetList* FWidget::always_on_top_list = 0;
|
FWidget::widgetList* FWidget::always_on_top_list = 0;
|
||||||
FWidget::widgetList* FWidget::close_widget = 0;
|
FWidget::widgetList* FWidget::close_widget = 0;
|
||||||
FWidget::widget_colors FWidget::wc;
|
FWidget::widget_colors FWidget::wc;
|
||||||
|
bool FWidget::hideable;
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// class FWidget
|
// class FWidget
|
||||||
|
@ -40,7 +42,7 @@ FWidget::FWidget (FWidget* parent)
|
||||||
, shown(false)
|
, shown(false)
|
||||||
, focus(false)
|
, focus(false)
|
||||||
, focusable(true)
|
, focusable(true)
|
||||||
, visible_cursor(false)
|
, visible_cursor(true)
|
||||||
, widget_cursor_position(-1,-1)
|
, widget_cursor_position(-1,-1)
|
||||||
, size_hints()
|
, size_hints()
|
||||||
, double_flatline_mask()
|
, double_flatline_mask()
|
||||||
|
@ -72,6 +74,7 @@ FWidget::FWidget (FWidget* parent)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
visible_cursor = ! hideable;
|
||||||
offset = parent->client_offset;
|
offset = parent->client_offset;
|
||||||
double_flatline_mask.top.resize (uLong(getWidth()), false);
|
double_flatline_mask.top.resize (uLong(getWidth()), false);
|
||||||
double_flatline_mask.right.resize (uLong(getHeight()), false);
|
double_flatline_mask.right.resize (uLong(getHeight()), false);
|
||||||
|
@ -2124,6 +2127,15 @@ void FWidget::init()
|
||||||
always_on_top_list = new widgetList();
|
always_on_top_list = new widgetList();
|
||||||
close_widget = new widgetList();
|
close_widget = new widgetList();
|
||||||
|
|
||||||
|
char* cursor_off_str = disableCursor();
|
||||||
|
|
||||||
|
if ( cursor_off_str && std::strlen(cursor_off_str ) > 0 )
|
||||||
|
hideable = true;
|
||||||
|
else
|
||||||
|
hideable = false;
|
||||||
|
|
||||||
|
visible_cursor = ! hideable;
|
||||||
|
|
||||||
// determine width and height of the terminal
|
// determine width and height of the terminal
|
||||||
detectTermSize();
|
detectTermSize();
|
||||||
wsize.setRect(1, 1, getColumnNumber(), getLineNumber());
|
wsize.setRect(1, 1, getColumnNumber(), getLineNumber());
|
||||||
|
|
|
@ -514,6 +514,7 @@ class FWidget : public FVTerm
|
||||||
static FMenuBar* menubar;
|
static FMenuBar* menubar;
|
||||||
static FWidget* show_root_widget;
|
static FWidget* show_root_widget;
|
||||||
static FWidget* redraw_root_widget;
|
static FWidget* redraw_root_widget;
|
||||||
|
static bool hideable;
|
||||||
|
|
||||||
// Friend class
|
// Friend class
|
||||||
friend class FToggleButton;
|
friend class FToggleButton;
|
||||||
|
@ -683,7 +684,7 @@ inline bool FWidget::setDisable()
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FWidget::setVisibleCursor (bool on)
|
inline bool FWidget::setVisibleCursor (bool on)
|
||||||
{ return visible_cursor = (on) ? true : false; }
|
{ return visible_cursor = (on) ? true : ((hideable) ? false : true); }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline bool FWidget::setVisibleCursor()
|
inline bool FWidget::setVisibleCursor()
|
||||||
|
@ -776,7 +777,7 @@ inline bool FWidget::setCursorPos (const FPoint& pos)
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline void FWidget::unsetCursorPos()
|
inline void FWidget::unsetCursorPos()
|
||||||
{ widget_cursor_position.setPoint(-1,-1); }
|
{ setCursorPos(-1,-1); }
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
inline void FWidget::setPrintPos (const FPoint& pos)
|
inline void FWidget::setPrintPos (const FPoint& pos)
|
||||||
|
|
|
@ -19,7 +19,7 @@ int main (int, char**)
|
||||||
if ( isatty(1) && ! std::strcmp(nl_langinfo(CODESET), "ANSI_X3.4-1968") )
|
if ( isatty(1) && ! std::strcmp(nl_langinfo(CODESET), "ANSI_X3.4-1968") )
|
||||||
{
|
{
|
||||||
// locale C -> switch from 7bit ascii -> latin1
|
// locale C -> switch from 7bit ascii -> latin1
|
||||||
std::setlocale(LC_ALL, "en_US");
|
std::setlocale(LC_ALL, "C");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf (" Codeset: %s\n", nl_langinfo(CODESET));
|
printf (" Codeset: %s\n", nl_langinfo(CODESET));
|
||||||
|
|
Loading…
Reference in New Issue