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>
|
||||
* 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>
|
||||
* Determine xterm maximum number of colors via OSC 4
|
||||
|
|
|
@ -79,6 +79,7 @@ void FButton::setHotkeyForegroundColor (short color)
|
|||
button_hotkey_fg = color;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void FButton::setFocusForegroundColor (short color)
|
||||
{
|
||||
// valid colors -1..254
|
||||
|
|
|
@ -592,6 +592,7 @@ void FMenu::onMouseMove (FMouseEvent* ev)
|
|||
{
|
||||
// Unselect selected item without mouse focus
|
||||
(*iter)->unsetSelected();
|
||||
(*iter)->unsetFocus();
|
||||
|
||||
if ( getSelectedItem() == *iter )
|
||||
setSelectedItem(0);
|
||||
|
@ -1055,12 +1056,12 @@ bool FMenu::selectNextItem()
|
|||
unselectItem();
|
||||
next->setSelected();
|
||||
setSelectedItem(next);
|
||||
redraw();
|
||||
next->setFocus();
|
||||
|
||||
if ( getStatusBar() )
|
||||
getStatusBar()->drawMessage();
|
||||
|
||||
redraw();
|
||||
updateTerminal();
|
||||
flush_out();
|
||||
break;
|
||||
|
|
|
@ -256,47 +256,30 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
|
|||
x1 = (*iter)->getX();
|
||||
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 )
|
||||
// Mouse pointer over item
|
||||
if ( (*iter)->hasMenu() )
|
||||
{
|
||||
// Mouse pointer over item
|
||||
if ( (*iter)->hasMenu() )
|
||||
FMenu* menu = (*iter)->getMenu();
|
||||
|
||||
if ( ! menu->hasSelectedItem() )
|
||||
{
|
||||
FMenu* menu = (*iter)->getMenu();
|
||||
FMenuItem* first_item;
|
||||
menu->selectFirstItem();
|
||||
first_item = menu->getSelectedItem();
|
||||
|
||||
if ( ! menu->hasSelectedItem() )
|
||||
{
|
||||
FMenuItem* first_item;
|
||||
menu->selectFirstItem();
|
||||
first_item = menu->getSelectedItem();
|
||||
if ( first_item )
|
||||
first_item->setFocus();
|
||||
|
||||
if ( first_item )
|
||||
first_item->setFocus();
|
||||
if ( getStatusBar() )
|
||||
getStatusBar()->drawMessage();
|
||||
|
||||
menu->redraw();
|
||||
|
||||
if ( getStatusBar() )
|
||||
getStatusBar()->drawMessage();
|
||||
|
||||
redraw();
|
||||
drop_down = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*iter)->unsetSelected();
|
||||
|
||||
if ( getSelectedItem() == *iter )
|
||||
{
|
||||
setSelectedItem(0);
|
||||
leaveMenuBar();
|
||||
drop_down = false;
|
||||
(*iter)->processClicked();
|
||||
return;
|
||||
}
|
||||
redraw();
|
||||
menu->redraw();
|
||||
drop_down = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -304,11 +287,24 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
|
|||
(*iter)->unsetSelected();
|
||||
|
||||
if ( getSelectedItem() == *iter )
|
||||
{
|
||||
setSelectedItem(0);
|
||||
|
||||
redraw();
|
||||
leaveMenuBar();
|
||||
drop_down = false;
|
||||
(*iter)->processClicked();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*iter)->unsetSelected();
|
||||
|
||||
if ( getSelectedItem() == *iter )
|
||||
setSelectedItem(0);
|
||||
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
++iter;
|
||||
|
|
|
@ -271,6 +271,7 @@ void FMenuItem::setSelected()
|
|||
void FMenuItem::unsetSelected()
|
||||
{
|
||||
selected = false;
|
||||
unsetCursorPos();
|
||||
processDeactivate();
|
||||
}
|
||||
|
||||
|
|
|
@ -690,7 +690,7 @@ long FString::toLong() const
|
|||
p++;
|
||||
}
|
||||
|
||||
while ( std::isdigit(*p) )
|
||||
while ( std::iswdigit(*p) )
|
||||
{
|
||||
register uChar d = uChar((*p) - L'0');
|
||||
|
||||
|
@ -704,7 +704,7 @@ long FString::toLong() const
|
|||
p++;
|
||||
}
|
||||
|
||||
if ( ! std::isdigit(*p) )
|
||||
if ( *p != L'\0' && ! std::iswdigit(*p) )
|
||||
throw std::invalid_argument ("no valid number");
|
||||
|
||||
return num;
|
||||
|
@ -736,7 +736,7 @@ uLong FString::toULong() const
|
|||
p++;
|
||||
}
|
||||
|
||||
while ( std::isdigit(*p) )
|
||||
while ( std::iswdigit(*p) )
|
||||
{
|
||||
register uChar d = uChar((*p) - L'0');
|
||||
|
||||
|
@ -750,7 +750,7 @@ uLong FString::toULong() const
|
|||
p++;
|
||||
}
|
||||
|
||||
if ( ! std::isdigit(*p) )
|
||||
if ( *p != L'\0' && ! std::iswdigit(*p) )
|
||||
throw std::invalid_argument ("no valid number");
|
||||
|
||||
return num;
|
||||
|
|
135
src/fterm.cpp
135
src/fterm.cpp
|
@ -27,6 +27,7 @@ int FTerm::stdin_status_flags;
|
|||
uInt FTerm::baudrate;
|
||||
bool FTerm::resize_term;
|
||||
bool FTerm::mouse_support;
|
||||
bool FTerm::terminal_detection;
|
||||
bool FTerm::raw_mode;
|
||||
bool FTerm::input_data_pending;
|
||||
bool FTerm::non_blocking_stdin;
|
||||
|
@ -2265,7 +2266,6 @@ char* FTerm::parseSecDA (char*& current_termtype)
|
|||
{
|
||||
terminal_id_version = -1;
|
||||
}
|
||||
|
||||
switch ( terminal_id_type )
|
||||
{
|
||||
case 0: // DEC VT100
|
||||
|
@ -2520,7 +2520,8 @@ void FTerm::init_termcaps()
|
|||
FTermcap::eat_nl_glitch = true;
|
||||
|
||||
// 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 )
|
||||
FTermcap::max_color = 1;
|
||||
|
@ -2577,10 +2578,21 @@ void FTerm::init_termcaps()
|
|||
// set ansi foreground and background color
|
||||
if ( linux_terminal || cygwin_terminal )
|
||||
{
|
||||
tcap[fc::t_set_a_foreground].string = \
|
||||
const_cast<char*>(CSI "3%p1%{8}%m%d%?%p1%{7}%>%t;1%e;21%;m");
|
||||
tcap[fc::t_set_a_background].string = \
|
||||
const_cast<char*>(CSI "4%p1%{8}%m%d%?%p1%{7}%>%t;5%e;25%;m");
|
||||
if ( FTermcap::max_color > 8 )
|
||||
{
|
||||
tcap[fc::t_set_a_foreground].string = \
|
||||
const_cast<char*>(CSI "3%p1%{8}%m%d%?%p1%{7}%>%t;1%e;21%;m");
|
||||
tcap[fc::t_set_a_background].string = \
|
||||
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 = \
|
||||
const_cast<char*>(CSI "39;49;25m");
|
||||
}
|
||||
|
@ -2946,6 +2958,7 @@ void FTerm::init()
|
|||
VGAFont = \
|
||||
ascii_console = \
|
||||
mouse_support = \
|
||||
|
||||
force_vt100 = \
|
||||
tera_terminal = \
|
||||
kterm_terminal = \
|
||||
|
@ -2960,7 +2973,8 @@ void FTerm::init()
|
|||
xterm_default_colors = false;
|
||||
|
||||
// Preset to true
|
||||
cursor_optimisation = true;
|
||||
cursor_optimisation = \
|
||||
terminal_detection = true;
|
||||
|
||||
// assertion: programm start in cooked mode
|
||||
raw_mode = \
|
||||
|
@ -3015,33 +3029,61 @@ void FTerm::init()
|
|||
else
|
||||
linux_terminal = false;
|
||||
|
||||
// start terminal detection...
|
||||
setRawMode();
|
||||
|
||||
// Identify the terminal via the answerback-message
|
||||
new_termtype = parseAnswerbackMsg (new_termtype);
|
||||
|
||||
// Identify the terminal via the secondary device attributes (SEC_DA)
|
||||
new_termtype = parseSecDA (new_termtype);
|
||||
|
||||
if ( ! color256 && getXTermColorName(0) != "" )
|
||||
// terminal detection
|
||||
if ( terminal_detection )
|
||||
{
|
||||
if ( getXTermColorName(256) != "" )
|
||||
{
|
||||
new_termtype = const_cast<char*>("xterm-256color");
|
||||
}
|
||||
else if ( FTermcap::max_color < 88 && getXTermColorName(87) != "" )
|
||||
{
|
||||
new_termtype = const_cast<char*>("xterm-88color");
|
||||
}
|
||||
else if ( FTermcap::max_color < 16 && getXTermColorName(15) != "" )
|
||||
{
|
||||
new_termtype = const_cast<char*>("xterm-16color");
|
||||
}
|
||||
}
|
||||
setRawMode();
|
||||
|
||||
unsetRawMode();
|
||||
// ...end of terminal detection
|
||||
// Identify the terminal via the answerback-message
|
||||
new_termtype = parseAnswerbackMsg (new_termtype);
|
||||
|
||||
// Identify the terminal via the secondary device attributes (SEC_DA)
|
||||
new_termtype = parseSecDA (new_termtype);
|
||||
|
||||
// Determine xterm maximum number of colors via OSC 4
|
||||
if ( ! color256 && ! tera_terminal && getXTermColorName(0) != "" )
|
||||
{
|
||||
if ( getXTermColorName(256) != "" )
|
||||
{
|
||||
new_termtype = const_cast<char*>("xterm-256color");
|
||||
}
|
||||
else if ( getXTermColorName(87) != "" )
|
||||
{
|
||||
new_termtype = const_cast<char*>("xterm-88color");
|
||||
}
|
||||
else if ( getXTermColorName(15) != "" )
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
// stop non-blocking stdin
|
||||
unsetNonBlockingInput();
|
||||
|
@ -3083,11 +3125,7 @@ void FTerm::init()
|
|||
|
||||
// TeraTerm can not show UTF-8 character
|
||||
if ( tera_terminal && ! std::strcmp(nl_langinfo(CODESET), "UTF-8") )
|
||||
locale_name = std::setlocale (LC_ALL, "en_US");
|
||||
|
||||
// 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");
|
||||
locale_name = std::setlocale (LC_ALL, "C");
|
||||
|
||||
// try to found a meaningful content for locale_name
|
||||
if ( locale_name )
|
||||
|
@ -3164,29 +3202,6 @@ void FTerm::init()
|
|||
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 )
|
||||
setKDECursor(fc::UnderlineCursor);
|
||||
|
||||
|
|
|
@ -313,6 +313,7 @@ class FTerm
|
|||
static FTermcap::tcap_map* tcap;
|
||||
|
||||
static bool mouse_support;
|
||||
static bool terminal_detection;
|
||||
static bool raw_mode;
|
||||
static bool input_data_pending;
|
||||
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::close_widget = 0;
|
||||
FWidget::widget_colors FWidget::wc;
|
||||
bool FWidget::hideable;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FWidget
|
||||
|
@ -40,7 +42,7 @@ FWidget::FWidget (FWidget* parent)
|
|||
, shown(false)
|
||||
, focus(false)
|
||||
, focusable(true)
|
||||
, visible_cursor(false)
|
||||
, visible_cursor(true)
|
||||
, widget_cursor_position(-1,-1)
|
||||
, size_hints()
|
||||
, double_flatline_mask()
|
||||
|
@ -72,6 +74,7 @@ FWidget::FWidget (FWidget* parent)
|
|||
}
|
||||
else
|
||||
{
|
||||
visible_cursor = ! hideable;
|
||||
offset = parent->client_offset;
|
||||
double_flatline_mask.top.resize (uLong(getWidth()), false);
|
||||
double_flatline_mask.right.resize (uLong(getHeight()), false);
|
||||
|
@ -2124,6 +2127,15 @@ void FWidget::init()
|
|||
always_on_top_list = 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
|
||||
detectTermSize();
|
||||
wsize.setRect(1, 1, getColumnNumber(), getLineNumber());
|
||||
|
|
|
@ -514,6 +514,7 @@ class FWidget : public FVTerm
|
|||
static FMenuBar* menubar;
|
||||
static FWidget* show_root_widget;
|
||||
static FWidget* redraw_root_widget;
|
||||
static bool hideable;
|
||||
|
||||
// Friend class
|
||||
friend class FToggleButton;
|
||||
|
@ -683,7 +684,7 @@ inline bool FWidget::setDisable()
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FWidget::setVisibleCursor (bool on)
|
||||
{ return visible_cursor = (on) ? true : false; }
|
||||
{ return visible_cursor = (on) ? true : ((hideable) ? false : true); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FWidget::setVisibleCursor()
|
||||
|
@ -776,7 +777,7 @@ inline bool FWidget::setCursorPos (const FPoint& pos)
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FWidget::unsetCursorPos()
|
||||
{ widget_cursor_position.setPoint(-1,-1); }
|
||||
{ setCursorPos(-1,-1); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
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") )
|
||||
{
|
||||
// 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));
|
||||
|
|
Loading…
Reference in New Issue