* TermWindow does maintain a separate Session list instead of doing
nasty things with the tab view. * The tabs are named "Shell <number>" now, which is somewhat more useful than all being named "Terminal". This is similar to Konsole and we should probably also support setting the tab name by the user. Until Haiku supports persistent sessions, that is not really useful, though. * Shift-Left/Right iterates through the tabs, now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25960 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -82,6 +82,8 @@ const uint32 FULLSCREEN = 'fscr';
|
|||||||
const uint32 MSG_FONT_CHANGED = 'fntc';
|
const uint32 MSG_FONT_CHANGED = 'fntc';
|
||||||
const uint32 SAVE_AS_DEFAULT = 'sadf';
|
const uint32 SAVE_AS_DEFAULT = 'sadf';
|
||||||
const uint32 MSG_CHECK_CHILDREN = 'ckch';
|
const uint32 MSG_CHECK_CHILDREN = 'ckch';
|
||||||
|
const uint32 MSG_PREVIOUS_TAB = 'ptab';
|
||||||
|
const uint32 MSG_NEXT_TAB = 'ntab';
|
||||||
|
|
||||||
const uint32 MSG_TERMINAL_BUFFER_CHANGED = 'bufc';
|
const uint32 MSG_TERMINAL_BUFFER_CHANGED = 'bufc';
|
||||||
const uint32 MSG_SET_TERMNAL_TITLE = 'sett';
|
const uint32 MSG_SET_TERMNAL_TITLE = 'sett';
|
||||||
|
|||||||
@@ -1155,18 +1155,26 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
|
|
||||||
case B_LEFT_ARROW:
|
case B_LEFT_ARROW:
|
||||||
if (rawChar == B_LEFT_ARROW) {
|
if (rawChar == B_LEFT_ARROW) {
|
||||||
if (mod & B_CONTROL_KEY)
|
if (mod & B_SHIFT_KEY) {
|
||||||
|
BMessage message(MSG_PREVIOUS_TAB);
|
||||||
|
message.AddPointer("termView", this);
|
||||||
|
Window()->PostMessage(&message);
|
||||||
|
} else if (mod & B_CONTROL_KEY) {
|
||||||
toWrite = CTRL_LEFT_ARROW_KEY_CODE;
|
toWrite = CTRL_LEFT_ARROW_KEY_CODE;
|
||||||
else
|
} else
|
||||||
toWrite = LEFT_ARROW_KEY_CODE;
|
toWrite = LEFT_ARROW_KEY_CODE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_RIGHT_ARROW:
|
case B_RIGHT_ARROW:
|
||||||
if (rawChar == B_RIGHT_ARROW) {
|
if (rawChar == B_RIGHT_ARROW) {
|
||||||
if (mod & B_CONTROL_KEY)
|
if (mod & B_SHIFT_KEY) {
|
||||||
|
BMessage message(MSG_NEXT_TAB);
|
||||||
|
message.AddPointer("termView", this);
|
||||||
|
Window()->PostMessage(&message);
|
||||||
|
} else if (mod & B_CONTROL_KEY) {
|
||||||
toWrite = CTRL_RIGHT_ARROW_KEY_CODE;
|
toWrite = CTRL_RIGHT_ARROW_KEY_CODE;
|
||||||
else
|
} else
|
||||||
toWrite = RIGHT_ARROW_KEY_CODE;
|
toWrite = RIGHT_ARROW_KEY_CODE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -87,6 +87,41 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct TermWindow::Session {
|
||||||
|
int32 id;
|
||||||
|
BString name;
|
||||||
|
TermViewContainerView* containerView;
|
||||||
|
|
||||||
|
Session(int32 id, TermViewContainerView* containerView)
|
||||||
|
:
|
||||||
|
id(id),
|
||||||
|
containerView(containerView)
|
||||||
|
{
|
||||||
|
name = "Shell ";
|
||||||
|
name << id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TermWindow::TabView : public SmartTabView {
|
||||||
|
public:
|
||||||
|
TabView(TermWindow* window, BRect frame, const char *name)
|
||||||
|
:
|
||||||
|
SmartTabView(frame, name),
|
||||||
|
fWindow(window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void RemoveAndDeleteTab(int32 index)
|
||||||
|
{
|
||||||
|
fWindow->_RemoveTab(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TermWindow* fWindow;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
TermWindow::TermWindow(BRect frame, const char* title, Arguments *args)
|
TermWindow::TermWindow(BRect frame, const char* title, Arguments *args)
|
||||||
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
|
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
|
||||||
fTabView(NULL),
|
fTabView(NULL),
|
||||||
@@ -124,6 +159,9 @@ TermWindow::~TermWindow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
PrefHandler::DeleteDefault();
|
PrefHandler::DeleteDefault();
|
||||||
|
|
||||||
|
for (int32 i = 0; Session* session = (Session*)fSessions.ItemAt(i); i++)
|
||||||
|
delete session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -139,7 +177,7 @@ TermWindow::_InitWindow()
|
|||||||
BRect textFrame = Bounds();
|
BRect textFrame = Bounds();
|
||||||
textFrame.top = fMenubar->Bounds().bottom + 1.0;
|
textFrame.top = fMenubar->Bounds().bottom + 1.0;
|
||||||
|
|
||||||
fTabView = new SmartTabView(textFrame, "tab view");
|
fTabView = new TabView(this, textFrame, "tab view");
|
||||||
AddChild(fTabView);
|
AddChild(fTabView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,6 +487,21 @@ TermWindow::MessageReceived(BMessage *message)
|
|||||||
_CheckChildren();
|
_CheckChildren();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_PREVIOUS_TAB:
|
||||||
|
case MSG_NEXT_TAB:
|
||||||
|
{
|
||||||
|
TermView* termView;
|
||||||
|
if (message->FindPointer("termView", (void**)&termView) == B_OK) {
|
||||||
|
int32 count = fSessions.CountItems();
|
||||||
|
int32 index = _IndexOfTermView(termView);
|
||||||
|
if (count > 1 && index >= 0) {
|
||||||
|
index += message->what == MSG_PREVIOUS_TAB ? -1 : 1;
|
||||||
|
fTabView->Select((index + count) % count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kNewTab:
|
case kNewTab:
|
||||||
if (fTabView->CountTabs() < kMaxTabs)
|
if (fTabView->CountTabs() < kMaxTabs)
|
||||||
_AddTab(NULL);
|
_AddTab(NULL);
|
||||||
@@ -606,12 +659,15 @@ TermWindow::_AddTab(Arguments *args)
|
|||||||
BScrollView *scrollView = new TermScrollView("scrollView",
|
BScrollView *scrollView = new TermScrollView("scrollView",
|
||||||
containerView, view);
|
containerView, view);
|
||||||
|
|
||||||
|
Session* session = new Session(_NewSessionID(), containerView);
|
||||||
|
fSessions.AddItem(session);
|
||||||
|
|
||||||
BTab *tab = new BTab;
|
BTab *tab = new BTab;
|
||||||
// TODO: Use a better name. For example, do like MacOsX's Terminal
|
// TODO: Use a better name. For example, do like MacOsX's Terminal
|
||||||
// and update the title using the last executed command ?
|
// and update the title using the last executed command ?
|
||||||
// Or like Gnome's Terminal and use the current path ?
|
// Or like Gnome's Terminal and use the current path ?
|
||||||
fTabView->AddTab(scrollView, tab);
|
fTabView->AddTab(scrollView, tab);
|
||||||
tab->SetLabel("Terminal");
|
tab->SetLabel(session->name.String());
|
||||||
view->SetScrollBar(scrollView->ScrollBar(B_VERTICAL));
|
view->SetScrollBar(scrollView->ScrollBar(B_VERTICAL));
|
||||||
|
|
||||||
// Resize the vertical scrollbar to take the window gripping handle into account
|
// Resize the vertical scrollbar to take the window gripping handle into account
|
||||||
@@ -654,17 +710,21 @@ TermWindow::_AddTab(Arguments *args)
|
|||||||
// TODO: Should cleanup, I guess
|
// TODO: Should cleanup, I guess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TermWindow::_RemoveTab(int32 index)
|
TermWindow::_RemoveTab(int32 index)
|
||||||
{
|
{
|
||||||
if (fTabView->CountTabs() > 1)
|
if (fSessions.CountItems() > 1) {
|
||||||
delete fTabView->RemoveTab(index);
|
if (Session* session = (Session*)fSessions.RemoveItem(index)) {
|
||||||
else
|
delete session;
|
||||||
|
delete fTabView->RemoveTab(index);
|
||||||
|
}
|
||||||
|
} else
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TermViewContainerView*
|
TermViewContainerView*
|
||||||
TermWindow::_ActiveTermViewContainerView() const
|
TermWindow::_ActiveTermViewContainerView() const
|
||||||
{
|
{
|
||||||
@@ -675,11 +735,9 @@ TermWindow::_ActiveTermViewContainerView() const
|
|||||||
TermViewContainerView*
|
TermViewContainerView*
|
||||||
TermWindow::_TermViewContainerViewAt(int32 index) const
|
TermWindow::_TermViewContainerViewAt(int32 index) const
|
||||||
{
|
{
|
||||||
// TODO: BAD HACK:
|
if (Session* session = (Session*)fSessions.ItemAt(index))
|
||||||
// We should probably use the observer api to tell
|
return session->containerView;
|
||||||
// the various "tabs" when settings are changed. Fix this.
|
return NULL;
|
||||||
BScrollView* scrollView = (BScrollView*)fTabView->ViewForTab(index);
|
|
||||||
return scrollView ? (TermViewContainerView*)scrollView->Target() : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -718,16 +776,10 @@ TermWindow::_IndexOfTermView(TermView* termView) const
|
|||||||
void
|
void
|
||||||
TermWindow::_CheckChildren()
|
TermWindow::_CheckChildren()
|
||||||
{
|
{
|
||||||
// There seems to be no separate list of sessions, so we have to iterate
|
int32 count = fSessions.CountItems();
|
||||||
// through the tabs.
|
|
||||||
int32 count = fTabView->CountTabs();
|
|
||||||
for (int32 i = count - 1; i >= 0; i--) {
|
for (int32 i = count - 1; i >= 0; i--) {
|
||||||
// get the term view
|
Session* session = (Session*)fSessions.ItemAt(i);
|
||||||
TermView* termView = _TermViewAt(i);
|
session->containerView->GetTermView()->CheckShellGone();
|
||||||
if (!termView)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
termView->CheckShellGone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,6 +839,29 @@ TermWindow::_BuildWindowSizeMenu(BMenu *menu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
TermWindow::_NewSessionID()
|
||||||
|
{
|
||||||
|
for (int32 id = 1; ; id++) {
|
||||||
|
bool used = false;
|
||||||
|
|
||||||
|
for (int32 i = 0;
|
||||||
|
Session* session = (Session*)fSessions.ItemAt(i); i++) {
|
||||||
|
if (id == session->id) {
|
||||||
|
used = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!used)
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
// CustomTermView
|
// CustomTermView
|
||||||
CustomTermView::CustomTermView(int32 rows, int32 columns, int32 argc, const char **argv, int32 historySize)
|
CustomTermView::CustomTermView(int32 rows, int32 columns, int32 argc, const char **argv, int32 historySize)
|
||||||
:
|
:
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ protected:
|
|||||||
virtual void MenusBeginning();
|
virtual void MenusBeginning();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Session;
|
||||||
|
class TabView;
|
||||||
|
friend class TabView;
|
||||||
|
|
||||||
void _SetTermColors(TermViewContainerView *termView);
|
void _SetTermColors(TermViewContainerView *termView);
|
||||||
void _InitWindow();
|
void _InitWindow();
|
||||||
void _SetupMenu();
|
void _SetupMenu();
|
||||||
@@ -73,10 +77,13 @@ private:
|
|||||||
void _CheckChildren();
|
void _CheckChildren();
|
||||||
void _ResizeView(TermView *view);
|
void _ResizeView(TermView *view);
|
||||||
void _BuildWindowSizeMenu(BMenu *menu);
|
void _BuildWindowSizeMenu(BMenu *menu);
|
||||||
|
int32 _NewSessionID();
|
||||||
|
|
||||||
|
BList fSessions;
|
||||||
|
|
||||||
SmartTabView *fTabView;
|
TabView *fTabView;
|
||||||
TermView *fTermView;
|
TermView *fTermView;
|
||||||
|
|
||||||
BMenuBar *fMenubar;
|
BMenuBar *fMenubar;
|
||||||
BMenu *fFilemenu;
|
BMenu *fFilemenu;
|
||||||
BMenu *fEditmenu;
|
BMenu *fEditmenu;
|
||||||
|
|||||||
Reference in New Issue
Block a user