Terminal: Allow use of Option as Meta key
Add a configuration setting that allows the left Option key to be used as a Meta key, and add support for the Escape sequences that control the Meta key's behaviour. TermWindow now maintains a copy, shared by all its component TermViews, of the current key map, and updates this copy automatically when notified by the Input Server a new key map has been loaded. The Meta key was an extra modifier key present on early UNIX workstations that provided access to the "extended" portion of the ASCII character set. Although it has vanished from modern keyboards certain UNIX software still relies on the key, most notably GNU Emacs and the GNU readline library, the latter of which is used by bash and a wide variety of other software that reads input from a terminal. (Python's interactive mode uses readline, for instance.) With this patch applied and the new setting enabled, the left Option key can be used to access additional editing and navigation features at the command line. It also makes usable the port of GNU Emacs currently available from HaikuDepot. Fixes #15294. Change-Id: I150b640b7b18384d56ab2fb017bf16ce8bdbdd78 Reviewed-on: https://review.haiku-os.org/c/haiku/+/1727 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
f36398cd4f
commit
8840b3db9a
@ -65,6 +65,10 @@ AppearancePrefView::AppearancePrefView(const char* name,
|
|||||||
B_TRANSLATE("Allow bold text"),
|
B_TRANSLATE("Allow bold text"),
|
||||||
new BMessage(MSG_ALLOW_BOLD_CHANGED));
|
new BMessage(MSG_ALLOW_BOLD_CHANGED));
|
||||||
|
|
||||||
|
fUseOptionAsMetaKey = new BCheckBox(
|
||||||
|
B_TRANSLATE("Use left Option as Meta key"),
|
||||||
|
new BMessage(MSG_USE_OPTION_AS_META_CHANGED));
|
||||||
|
|
||||||
fWarnOnExit = new BCheckBox(
|
fWarnOnExit = new BCheckBox(
|
||||||
B_TRANSLATE("Confirm exit if active programs exist"),
|
B_TRANSLATE("Confirm exit if active programs exist"),
|
||||||
new BMessage(MSG_WARN_ON_EXIT_CHANGED));
|
new BMessage(MSG_WARN_ON_EXIT_CHANGED));
|
||||||
@ -140,6 +144,7 @@ AppearancePrefView::AppearancePrefView(const char* name,
|
|||||||
B_CELLS_32x8, 8.0, "", new BMessage(MSG_COLOR_CHANGED)))
|
B_CELLS_32x8, 8.0, "", new BMessage(MSG_COLOR_CHANGED)))
|
||||||
.Add(fBlinkCursor)
|
.Add(fBlinkCursor)
|
||||||
.Add(fAllowBold)
|
.Add(fAllowBold)
|
||||||
|
.Add(fUseOptionAsMetaKey)
|
||||||
.Add(fWarnOnExit);
|
.Add(fWarnOnExit);
|
||||||
|
|
||||||
fTabTitle->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
fTabTitle->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
|
||||||
@ -172,6 +177,7 @@ AppearancePrefView::Revert()
|
|||||||
|
|
||||||
fBlinkCursor->SetValue(pref->getBool(PREF_BLINK_CURSOR));
|
fBlinkCursor->SetValue(pref->getBool(PREF_BLINK_CURSOR));
|
||||||
fAllowBold->SetValue(pref->getBool(PREF_ALLOW_BOLD));
|
fAllowBold->SetValue(pref->getBool(PREF_ALLOW_BOLD));
|
||||||
|
fUseOptionAsMetaKey->SetValue(pref->getBool(PREF_USE_OPTION_AS_META));
|
||||||
fWarnOnExit->SetValue(pref->getBool(PREF_WARN_ON_EXIT));
|
fWarnOnExit->SetValue(pref->getBool(PREF_WARN_ON_EXIT));
|
||||||
|
|
||||||
_SetCurrentColorScheme();
|
_SetCurrentColorScheme();
|
||||||
@ -194,6 +200,7 @@ AppearancePrefView::AttachedToWindow()
|
|||||||
fWindowTitle->SetTarget(this);
|
fWindowTitle->SetTarget(this);
|
||||||
fBlinkCursor->SetTarget(this);
|
fBlinkCursor->SetTarget(this);
|
||||||
fAllowBold->SetTarget(this);
|
fAllowBold->SetTarget(this);
|
||||||
|
fUseOptionAsMetaKey->SetTarget(this);
|
||||||
fWarnOnExit->SetTarget(this);
|
fWarnOnExit->SetTarget(this);
|
||||||
|
|
||||||
fFontField->Menu()->SetTargetForItems(this);
|
fFontField->Menu()->SetTargetForItems(this);
|
||||||
@ -338,6 +345,15 @@ AppearancePrefView::MessageReceived(BMessage* msg)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_USE_OPTION_AS_META_CHANGED:
|
||||||
|
if (PrefHandler::Default()->getBool(PREF_USE_OPTION_AS_META)
|
||||||
|
!= fUseOptionAsMetaKey->Value()) {
|
||||||
|
PrefHandler::Default()->setBool(PREF_USE_OPTION_AS_META,
|
||||||
|
fUseOptionAsMetaKey->Value());
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case MSG_WARN_ON_EXIT_CHANGED:
|
case MSG_WARN_ON_EXIT_CHANGED:
|
||||||
if (PrefHandler::Default()->getBool(PREF_WARN_ON_EXIT)
|
if (PrefHandler::Default()->getBool(PREF_WARN_ON_EXIT)
|
||||||
!= fWarnOnExit->Value()) {
|
!= fWarnOnExit->Value()) {
|
||||||
|
@ -25,6 +25,7 @@ static const uint32 MSG_TAB_TITLE_SETTING_CHANGED = 'mtts';
|
|||||||
static const uint32 MSG_WINDOW_TITLE_SETTING_CHANGED = 'mwts';
|
static const uint32 MSG_WINDOW_TITLE_SETTING_CHANGED = 'mwts';
|
||||||
static const uint32 MSG_BLINK_CURSOR_CHANGED = 'mbcc';
|
static const uint32 MSG_BLINK_CURSOR_CHANGED = 'mbcc';
|
||||||
static const uint32 MSG_ALLOW_BOLD_CHANGED = 'mabc';
|
static const uint32 MSG_ALLOW_BOLD_CHANGED = 'mabc';
|
||||||
|
static const uint32 MSG_USE_OPTION_AS_META_CHANGED = 'momc';
|
||||||
static const uint32 MSG_WARN_ON_EXIT_CHANGED = 'mwec';
|
static const uint32 MSG_WARN_ON_EXIT_CHANGED = 'mwec';
|
||||||
static const uint32 MSG_COLS_CHANGED = 'mccl';
|
static const uint32 MSG_COLS_CHANGED = 'mccl';
|
||||||
static const uint32 MSG_HISTORY_CHANGED = 'mhst';
|
static const uint32 MSG_HISTORY_CHANGED = 'mhst';
|
||||||
@ -78,6 +79,7 @@ private:
|
|||||||
|
|
||||||
BCheckBox* fBlinkCursor;
|
BCheckBox* fBlinkCursor;
|
||||||
BCheckBox* fAllowBold;
|
BCheckBox* fAllowBold;
|
||||||
|
BCheckBox* fUseOptionAsMetaKey;
|
||||||
BCheckBox* fWarnOnExit;
|
BCheckBox* fWarnOnExit;
|
||||||
BMenuField* fFontField;
|
BMenuField* fFontField;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
* Authors:
|
* Authors:
|
||||||
* Kian Duffy, myob@users.sourceforge.net
|
* Kian Duffy, myob@users.sourceforge.net
|
||||||
* Daniel Furrer, assimil8or@users.sourceforge.net
|
* Daniel Furrer, assimil8or@users.sourceforge.net
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -89,6 +90,7 @@ static const pref_defaults kTermDefaults[] = {
|
|||||||
{ PREF_TAB_TITLE, "%1d: %p%e" },
|
{ PREF_TAB_TITLE, "%1d: %p%e" },
|
||||||
{ PREF_WINDOW_TITLE, "%T% i: %t" },
|
{ PREF_WINDOW_TITLE, "%T% i: %t" },
|
||||||
{ PREF_BLINK_CURSOR, PREF_TRUE },
|
{ PREF_BLINK_CURSOR, PREF_TRUE },
|
||||||
|
{ PREF_USE_OPTION_AS_META, PREF_FALSE },
|
||||||
{ PREF_WARN_ON_EXIT, PREF_TRUE },
|
{ PREF_WARN_ON_EXIT, PREF_TRUE },
|
||||||
{ PREF_CURSOR_STYLE, PREF_BLOCK_CURSOR },
|
{ PREF_CURSOR_STYLE, PREF_BLOCK_CURSOR },
|
||||||
{ PREF_EMULATE_BOLD, PREF_FALSE },
|
{ PREF_EMULATE_BOLD, PREF_FALSE },
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
* Authors:
|
* Authors:
|
||||||
* Jeremiah Bailey, <jjbailey@gmail.com>
|
* Jeremiah Bailey, <jjbailey@gmail.com>
|
||||||
* Kian Duffy, <myob@users.sourceforge.net>
|
* Kian Duffy, <myob@users.sourceforge.net>
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Siarzhuk Zharski, <zharik@gmx.li>
|
* Siarzhuk Zharski, <zharik@gmx.li>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -179,6 +180,10 @@ void
|
|||||||
TermApp::MessageReceived(BMessage* message)
|
TermApp::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
|
case B_KEY_MAP_LOADED:
|
||||||
|
fTermWindow->PostMessage(message);
|
||||||
|
break;
|
||||||
|
|
||||||
case MSG_ACTIVATE_TERM:
|
case MSG_ACTIVATE_TERM:
|
||||||
fTermWindow->Activate();
|
fTermWindow->Activate();
|
||||||
break;
|
break;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Kian Duffy, myob@users.sourceforge.net
|
* Kian Duffy, myob@users.sourceforge.net
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
*/
|
*/
|
||||||
#ifndef TERMCONST_H_INCLUDED
|
#ifndef TERMCONST_H_INCLUDED
|
||||||
@ -79,6 +80,7 @@ static const uint32 MSG_SET_TERMINAL_TITLE = 'sett';
|
|||||||
static const uint32 MSG_SET_TERMINAL_COLORS = 'setc';
|
static const uint32 MSG_SET_TERMINAL_COLORS = 'setc';
|
||||||
static const uint32 MSG_RESET_TERMINAL_COLORS = 'rstc';
|
static const uint32 MSG_RESET_TERMINAL_COLORS = 'rstc';
|
||||||
static const uint32 MSG_QUIT_TERMNAL = 'qutt';
|
static const uint32 MSG_QUIT_TERMNAL = 'qutt';
|
||||||
|
static const uint32 MSG_ENABLE_META_KEY = 'emtk';
|
||||||
static const uint32 MSG_REPORT_MOUSE_EVENT = 'mous';
|
static const uint32 MSG_REPORT_MOUSE_EVENT = 'mous';
|
||||||
static const uint32 MSG_SAVE_WINDOW_POSITION = 'swps';
|
static const uint32 MSG_SAVE_WINDOW_POSITION = 'swps';
|
||||||
static const uint32 MSG_MOVE_TAB_LEFT = 'mvtl';
|
static const uint32 MSG_MOVE_TAB_LEFT = 'mvtl';
|
||||||
@ -133,6 +135,8 @@ static const char* const PREF_TEXT_ENCODING = "Text encoding";
|
|||||||
|
|
||||||
static const char* const PREF_BLINK_CURSOR = "Blinking cursor";
|
static const char* const PREF_BLINK_CURSOR = "Blinking cursor";
|
||||||
static const char* const PREF_ALLOW_BOLD = "Allow bold text";
|
static const char* const PREF_ALLOW_BOLD = "Allow bold text";
|
||||||
|
static const char* const PREF_USE_OPTION_AS_META =
|
||||||
|
"Use left Option as Meta key";
|
||||||
static const char* const PREF_WARN_ON_EXIT = "Warn on exit";
|
static const char* const PREF_WARN_ON_EXIT = "Warn on exit";
|
||||||
static const char* const PREF_CURSOR_STYLE = "Cursor style";
|
static const char* const PREF_CURSOR_STYLE = "Cursor style";
|
||||||
static const char* const PREF_EMULATE_BOLD = "Emulate bold";
|
static const char* const PREF_EMULATE_BOLD = "Emulate bold";
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Kian Duffy, myob@users.sourceforge.net
|
* Kian Duffy, myob@users.sourceforge.net
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1395,12 +1396,12 @@ TermParse::_DecPrivateModeSet(int value)
|
|||||||
fBuffer->ReportAnyMouseEvent(true);
|
fBuffer->ReportAnyMouseEvent(true);
|
||||||
break;
|
break;
|
||||||
case 1034:
|
case 1034:
|
||||||
// TODO: Interprete "meta" key, sets eighth bit.
|
// Interpret "meta" key, sets eighth bit.
|
||||||
// Not supported yet.
|
fBuffer->EnableInterpretMetaKey(true);
|
||||||
break;
|
break;
|
||||||
case 1036:
|
case 1036:
|
||||||
// TODO: Send ESC when Meta modifies a key
|
// Send ESC when Meta modifies a key
|
||||||
// Not supported yet.
|
fBuffer->EnableMetaKeySendsEscape(true);
|
||||||
break;
|
break;
|
||||||
case 1039:
|
case 1039:
|
||||||
// TODO: Send ESC when Alt modifies a key
|
// TODO: Send ESC when Alt modifies a key
|
||||||
@ -1470,12 +1471,12 @@ TermParse::_DecPrivateModeReset(int value)
|
|||||||
fBuffer->ReportAnyMouseEvent(false);
|
fBuffer->ReportAnyMouseEvent(false);
|
||||||
break;
|
break;
|
||||||
case 1034:
|
case 1034:
|
||||||
// Don't interprete "meta" key.
|
// Don't interpret "meta" key.
|
||||||
// Not supported yet.
|
fBuffer->EnableInterpretMetaKey(false);
|
||||||
break;
|
break;
|
||||||
case 1036:
|
case 1036:
|
||||||
// TODO: Don't send ESC when Meta modifies a key
|
// Don't send ESC when Meta modifies a key
|
||||||
// Not supported yet.
|
fBuffer->EnableMetaKeySendsEscape(false);
|
||||||
break;
|
break;
|
||||||
case 1039:
|
case 1039:
|
||||||
// TODO: Don't send ESC when Alt modifies a key
|
// TODO: Don't send ESC when Alt modifies a key
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
* Kian Duffy, myob@users.sourceforge.net
|
* Kian Duffy, myob@users.sourceforge.net
|
||||||
* Y.Hayakawa, hida@sawada.riec.tohoku.ac.jp
|
* Y.Hayakawa, hida@sawada.riec.tohoku.ac.jp
|
||||||
* Jonathan Schleifer, js@webkeks.org
|
* Jonathan Schleifer, js@webkeks.org
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Ingo Weinhold, ingo_weinhold@gmx.de
|
* Ingo Weinhold, ingo_weinhold@gmx.de
|
||||||
* Clemens Zeidler, haiku@Clemens-Zeidler.de
|
* Clemens Zeidler, haiku@Clemens-Zeidler.de
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
@ -307,6 +308,11 @@ TermView::_InitObject(const ShellParameters& shellParameters)
|
|||||||
fSelection.SetHighlighter(this);
|
fSelection.SetHighlighter(this);
|
||||||
fSelection.SetRange(TermPos(0, 0), TermPos(0, 0));
|
fSelection.SetRange(TermPos(0, 0), TermPos(0, 0));
|
||||||
fPrevPos = TermPos(-1, - 1);
|
fPrevPos = TermPos(-1, - 1);
|
||||||
|
fKeymap = NULL;
|
||||||
|
fKeymapChars = NULL;
|
||||||
|
fUseOptionAsMetaKey = false;
|
||||||
|
fInterpretMetaKey = true;
|
||||||
|
fMetaKeySendsEscape = true;
|
||||||
fReportX10MouseEvent = false;
|
fReportX10MouseEvent = false;
|
||||||
fReportNormalMouseEvent = false;
|
fReportNormalMouseEvent = false;
|
||||||
fReportButtonMouseEvent = false;
|
fReportButtonMouseEvent = false;
|
||||||
@ -719,6 +725,33 @@ TermView::SetEncoding(int encoding)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TermView::SetKeymap(const key_map* keymap, const char* chars)
|
||||||
|
{
|
||||||
|
delete fKeymap;
|
||||||
|
delete[] fKeymapChars;
|
||||||
|
|
||||||
|
fKeymap = keymap;
|
||||||
|
fKeymapChars = chars;
|
||||||
|
|
||||||
|
fKeymapTableForModifiers.Put(B_SHIFT_KEY,
|
||||||
|
&fKeymap->shift_map);
|
||||||
|
fKeymapTableForModifiers.Put(B_CAPS_LOCK,
|
||||||
|
&fKeymap->caps_map);
|
||||||
|
fKeymapTableForModifiers.Put(B_CAPS_LOCK | B_SHIFT_KEY,
|
||||||
|
&fKeymap->caps_shift_map);
|
||||||
|
fKeymapTableForModifiers.Put(B_CONTROL_KEY,
|
||||||
|
&fKeymap->control_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TermView::SetUseOptionAsMetaKey(bool enable)
|
||||||
|
{
|
||||||
|
fUseOptionAsMetaKey = enable && fKeymap != NULL && fKeymapChars != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TermView::SetMouseClipboard(BClipboard *clipboard)
|
TermView::SetMouseClipboard(BClipboard *clipboard)
|
||||||
{
|
{
|
||||||
@ -1801,6 +1834,16 @@ TermView::MessageReceived(BMessage *msg)
|
|||||||
fCursorHidden = hidden;
|
fCursorHidden = hidden;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MSG_ENABLE_META_KEY:
|
||||||
|
{
|
||||||
|
bool enable;
|
||||||
|
if (msg->FindBool("enableInterpretMetaKey", &enable) == B_OK)
|
||||||
|
fInterpretMetaKey = enable;
|
||||||
|
|
||||||
|
if (msg->FindBool("enableMetaKeySendsEscape", &enable) == B_OK)
|
||||||
|
fMetaKeySendsEscape = enable;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MSG_REPORT_MOUSE_EVENT:
|
case MSG_REPORT_MOUSE_EVENT:
|
||||||
{
|
{
|
||||||
bool report;
|
bool report;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
* Authors:
|
* Authors:
|
||||||
* Stefano Ceccherini, stefano.ceccherini@gmail.com
|
* Stefano Ceccherini, stefano.ceccherini@gmail.com
|
||||||
* Kian Duffy, myob@users.sourceforge.net
|
* Kian Duffy, myob@users.sourceforge.net
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Ingo Weinhold, ingo_weinhold@gmx.de
|
* Ingo Weinhold, ingo_weinhold@gmx.de
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
*/
|
*/
|
||||||
@ -15,6 +16,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
|
#include <HashMap.h>
|
||||||
|
#include <InterfaceDefs.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
@ -98,6 +101,10 @@ public:
|
|||||||
void SetScrollBar(BScrollBar* scrollBar);
|
void SetScrollBar(BScrollBar* scrollBar);
|
||||||
BScrollBar* ScrollBar() const { return fScrollBar; };
|
BScrollBar* ScrollBar() const { return fScrollBar; };
|
||||||
|
|
||||||
|
void SetKeymap(const key_map* keymap,
|
||||||
|
const char* chars);
|
||||||
|
void SetUseOptionAsMetaKey(bool enable);
|
||||||
|
|
||||||
void SetMouseClipboard(BClipboard *);
|
void SetMouseClipboard(BClipboard *);
|
||||||
|
|
||||||
void MakeDebugSnapshots();
|
void MakeDebugSnapshots();
|
||||||
@ -335,6 +342,15 @@ private:
|
|||||||
|
|
||||||
HighlightList fHighlights;
|
HighlightList fHighlights;
|
||||||
|
|
||||||
|
// keyboard
|
||||||
|
const key_map* fKeymap;
|
||||||
|
const char* fKeymapChars;
|
||||||
|
HashMap<HashKey32<int32>, const int(*)[128]>
|
||||||
|
fKeymapTableForModifiers;
|
||||||
|
bool fUseOptionAsMetaKey;
|
||||||
|
bool fInterpretMetaKey;
|
||||||
|
bool fMetaKeySendsEscape;
|
||||||
|
|
||||||
// mouse
|
// mouse
|
||||||
int32 fMouseButtons;
|
int32 fMouseButtons;
|
||||||
int32 fModifiers;
|
int32 fModifiers;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
* Stefano Ceccherini, stefano.ceccherini@gmail.com
|
* Stefano Ceccherini, stefano.ceccherini@gmail.com
|
||||||
* Kian Duffy, myob@users.sourceforge.net
|
* Kian Duffy, myob@users.sourceforge.net
|
||||||
* Y.Hayakawa, hida@sawada.riec.tohoku.ac.jp
|
* Y.Hayakawa, hida@sawada.riec.tohoku.ac.jp
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Ingo Weinhold, ingo_weinhold@gmx.de
|
* Ingo Weinhold, ingo_weinhold@gmx.de
|
||||||
* Clemens Zeidler, haiku@Clemens-Zeidler.de
|
* Clemens Zeidler, haiku@Clemens-Zeidler.de
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
@ -208,6 +209,55 @@ TermView::DefaultState::KeyDown(const char* bytes, int32 numBytes)
|
|||||||
|
|
||||||
fView->_ActivateCursor(true);
|
fView->_ActivateCursor(true);
|
||||||
|
|
||||||
|
// Handle the Option key when used as Meta
|
||||||
|
if ((mod & B_LEFT_OPTION_KEY) != 0 && fView->fUseOptionAsMetaKey
|
||||||
|
&& (fView->fInterpretMetaKey || fView->fMetaKeySendsEscape)) {
|
||||||
|
const char* bytes;
|
||||||
|
int8 numBytes;
|
||||||
|
|
||||||
|
// Determine the character produced by the same keypress without the
|
||||||
|
// Option key
|
||||||
|
mod &= B_SHIFT_KEY | B_CAPS_LOCK | B_CONTROL_KEY;
|
||||||
|
if (mod == 0) {
|
||||||
|
bytes = (const char*)&rawChar;
|
||||||
|
numBytes = 1;
|
||||||
|
} else {
|
||||||
|
const int (*keymapTable)[128] =
|
||||||
|
fView->fKeymapTableForModifiers.Get(mod);
|
||||||
|
bytes = &fView->fKeymapChars[(*keymapTable)[key]];
|
||||||
|
numBytes = *(bytes++);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numBytes <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fView->_ScrollTo(0, true);
|
||||||
|
|
||||||
|
char outputBuffer[2];
|
||||||
|
const char* toWrite = bytes;
|
||||||
|
|
||||||
|
if (fView->fMetaKeySendsEscape) {
|
||||||
|
fView->fShell->Write("\e", 1);
|
||||||
|
} else if (numBytes == 1) {
|
||||||
|
char byte = *bytes | 0x80;
|
||||||
|
|
||||||
|
// The eighth bit has special meaning in UTF-8, so if that encoding
|
||||||
|
// is in use recode the output (as xterm does)
|
||||||
|
if (fView->fEncoding == M_UTF8) {
|
||||||
|
outputBuffer[0] = 0xc0 | ((byte >> 6) & 0x03);
|
||||||
|
outputBuffer[1] = 0x80 | (byte & 0x3f);
|
||||||
|
numBytes = 2;
|
||||||
|
} else {
|
||||||
|
outputBuffer[0] = byte;
|
||||||
|
numBytes = 1;
|
||||||
|
}
|
||||||
|
toWrite = outputBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
fView->fShell->Write(toWrite, numBytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// handle multi-byte chars
|
// handle multi-byte chars
|
||||||
if (numBytes > 1) {
|
if (numBytes > 1) {
|
||||||
if (fView->fEncoding != M_UTF8) {
|
if (fView->fEncoding != M_UTF8) {
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
* Kian Duffy, myob@users.sourceforge.net
|
* Kian Duffy, myob@users.sourceforge.net
|
||||||
* Daniel Furrer, assimil8or@users.sourceforge.net
|
* Daniel Furrer, assimil8or@users.sourceforge.net
|
||||||
* John Scipione, jscipione@gmail.com
|
* John Scipione, jscipione@gmail.com
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -202,6 +203,9 @@ TermWindow::TermWindow(const BString& title, Arguments* args)
|
|||||||
fTerminalRoster.SetListener(this);
|
fTerminalRoster.SetListener(this);
|
||||||
int32 id = fTerminalRoster.ID();
|
int32 id = fTerminalRoster.ID();
|
||||||
|
|
||||||
|
// fetch the current keymap
|
||||||
|
get_key_map(&fKeymap, &fKeymapChars);
|
||||||
|
|
||||||
// apply the title settings
|
// apply the title settings
|
||||||
fTitle.pattern = title;
|
fTitle.pattern = title;
|
||||||
if (fTitle.pattern.Length() == 0) {
|
if (fTitle.pattern.Length() == 0) {
|
||||||
@ -272,6 +276,9 @@ TermWindow::~TermWindow()
|
|||||||
|
|
||||||
for (int32 i = 0; Session* session = _SessionAt(i); i++)
|
for (int32 i = 0; Session* session = _SessionAt(i); i++)
|
||||||
delete session;
|
delete session;
|
||||||
|
|
||||||
|
delete fKeymap;
|
||||||
|
delete[] fKeymapChars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -673,6 +680,10 @@ TermWindow::MessageReceived(BMessage *message)
|
|||||||
bool findresult;
|
bool findresult;
|
||||||
|
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
|
case B_KEY_MAP_LOADED:
|
||||||
|
_UpdateKeymap();
|
||||||
|
break;
|
||||||
|
|
||||||
case B_COPY:
|
case B_COPY:
|
||||||
_ActiveTermView()->Copy(be_clipboard);
|
_ActiveTermView()->Copy(be_clipboard);
|
||||||
break;
|
break;
|
||||||
@ -895,6 +906,18 @@ TermWindow::MessageReceived(BMessage *message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MSG_USE_OPTION_AS_META_CHANGED:
|
||||||
|
{
|
||||||
|
bool useOptionAsMetaKey
|
||||||
|
= PrefHandler::Default()->getBool(PREF_USE_OPTION_AS_META);
|
||||||
|
|
||||||
|
for (int32 i = 0; i < fTabView->CountTabs(); i++) {
|
||||||
|
TermView* view = _TermViewAt(i);
|
||||||
|
view->SetUseOptionAsMetaKey(useOptionAsMetaKey);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case FULLSCREEN:
|
case FULLSCREEN:
|
||||||
if (!fSavedFrame.IsValid()) { // go fullscreen
|
if (!fSavedFrame.IsValid()) { // go fullscreen
|
||||||
_ActiveTermView()->DisableResizeView();
|
_ActiveTermView()->DisableResizeView();
|
||||||
@ -1306,6 +1329,10 @@ TermWindow::_AddTab(Arguments* args, const BString& currentDirectory)
|
|||||||
if (charset != NULL)
|
if (charset != NULL)
|
||||||
view->SetEncoding(charset->GetConversionID());
|
view->SetEncoding(charset->GetConversionID());
|
||||||
|
|
||||||
|
view->SetKeymap(fKeymap, fKeymapChars);
|
||||||
|
view->SetUseOptionAsMetaKey(
|
||||||
|
PrefHandler::Default()->getBool(PREF_USE_OPTION_AS_META));
|
||||||
|
|
||||||
_SetTermColors(containerView);
|
_SetTermColors(containerView);
|
||||||
|
|
||||||
int32 tabIndex = fTabView->CountTabs() - 1;
|
int32 tabIndex = fTabView->CountTabs() - 1;
|
||||||
@ -1994,3 +2021,18 @@ TermWindow::_MoveWindowInScreen(BWindow* window)
|
|||||||
BSize screenSize(BScreen(window).Frame().Size());
|
BSize screenSize(BScreen(window).Frame().Size());
|
||||||
window->MoveTo(BLayoutUtils::MoveIntoFrame(frame, screenSize).LeftTop());
|
window->MoveTo(BLayoutUtils::MoveIntoFrame(frame, screenSize).LeftTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TermWindow::_UpdateKeymap()
|
||||||
|
{
|
||||||
|
delete fKeymap;
|
||||||
|
delete[] fKeymapChars;
|
||||||
|
|
||||||
|
get_key_map(&fKeymap, &fKeymapChars);
|
||||||
|
|
||||||
|
for (int32 i = 0; i < fTabView->CountTabs(); i++) {
|
||||||
|
TermView* view = _TermViewAt(i);
|
||||||
|
view->SetKeymap(fKeymap, fKeymapChars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#define TERM_WINDOW_H
|
#define TERM_WINDOW_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <InterfaceDefs.h>
|
||||||
#include <MessageRunner.h>
|
#include <MessageRunner.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
@ -188,6 +189,8 @@ private:
|
|||||||
|
|
||||||
void _MoveWindowInScreen(BWindow* window);
|
void _MoveWindowInScreen(BWindow* window);
|
||||||
|
|
||||||
|
void _UpdateKeymap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TerminalRoster fTerminalRoster;
|
TerminalRoster fTerminalRoster;
|
||||||
|
|
||||||
@ -228,6 +231,9 @@ private:
|
|||||||
bool fMatchWord;
|
bool fMatchWord;
|
||||||
|
|
||||||
bool fFullScreen;
|
bool fFullScreen;
|
||||||
|
|
||||||
|
key_map* fKeymap;
|
||||||
|
char* fKeymapChars;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Ingo Weinhold, ingo_weinhold@gmx.de
|
* Ingo Weinhold, ingo_weinhold@gmx.de
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -90,6 +91,28 @@ TerminalBuffer::Encoding() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TerminalBuffer::EnableInterpretMetaKey(bool enable)
|
||||||
|
{
|
||||||
|
if (fListenerValid) {
|
||||||
|
BMessage message(MSG_ENABLE_META_KEY);
|
||||||
|
message.AddBool("enableInterpretMetaKey", enable);
|
||||||
|
fListener.SendMessage(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TerminalBuffer::EnableMetaKeySendsEscape(bool enable)
|
||||||
|
{
|
||||||
|
if (fListenerValid) {
|
||||||
|
BMessage message(MSG_ENABLE_META_KEY);
|
||||||
|
message.AddBool("enableMetaKeySendsEscape", enable);
|
||||||
|
fListener.SendMessage(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TerminalBuffer::ReportX10MouseEvent(bool reportX10MouseEvent)
|
TerminalBuffer::ReportX10MouseEvent(bool reportX10MouseEvent)
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Ingo Weinhold, ingo_weinhold@gmx.de
|
* Ingo Weinhold, ingo_weinhold@gmx.de
|
||||||
|
* Simon South, simon@simonsouth.net
|
||||||
* Siarzhuk Zharski, zharik@gmx.li
|
* Siarzhuk Zharski, zharik@gmx.li
|
||||||
*/
|
*/
|
||||||
#ifndef TERMINAL_BUFFER_H
|
#ifndef TERMINAL_BUFFER_H
|
||||||
@ -52,6 +53,9 @@ public:
|
|||||||
void UseAlternateScreenBuffer(bool clear);
|
void UseAlternateScreenBuffer(bool clear);
|
||||||
void UseNormalScreenBuffer();
|
void UseNormalScreenBuffer();
|
||||||
|
|
||||||
|
void EnableInterpretMetaKey(bool enable);
|
||||||
|
void EnableMetaKeySendsEscape(bool enable);
|
||||||
|
|
||||||
void ReportX10MouseEvent(bool report);
|
void ReportX10MouseEvent(bool report);
|
||||||
void ReportNormalMouseEvent(bool report);
|
void ReportNormalMouseEvent(bool report);
|
||||||
void ReportButtonMouseEvent(bool report);
|
void ReportButtonMouseEvent(bool report);
|
||||||
|
Loading…
Reference in New Issue
Block a user