diff --git a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp index 65deea348f..bbce26ed50 100644 --- a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include "table/TableColumns.h" @@ -25,11 +24,6 @@ #include "UiUtils.h" -enum { - MSG_CLEAR_STACK_TRACE = 'clst' -}; - - // #pragma mark - FramesTableModel @@ -114,7 +108,7 @@ StackTraceView::StackTraceView(Listener* listener) fStackTrace(NULL), fFramesTable(NULL), fFramesTableModel(NULL), - fTraceUpdateRunner(NULL), + fTraceClearPending(false), fListener(listener) { SetName("Stack Trace"); @@ -155,23 +149,19 @@ StackTraceView::UnsetListener() void StackTraceView::SetStackTrace(StackTrace* stackTrace) { + fTraceClearPending = false; if (stackTrace == fStackTrace) return; - if (stackTrace == NULL) { - if (fTraceUpdateRunner != NULL) - return; + if (fStackTrace != NULL) + fStackTrace->ReleaseReference(); - BMessage message(MSG_CLEAR_STACK_TRACE); - fTraceUpdateRunner = new(std::nothrow) BMessageRunner(this, - message, 250000, 1); - if (fTraceUpdateRunner != NULL - && fTraceUpdateRunner->InitCheck() == B_OK) { - return; - } - } + fStackTrace = stackTrace; - _SetStackTrace(stackTrace); + if (fStackTrace != NULL) + fStackTrace->AcquireReference(); + + fFramesTableModel->SetStackTrace(fStackTrace); } @@ -218,38 +208,18 @@ StackTraceView::SaveSettings(BMessage& settings) void -StackTraceView::MessageReceived(BMessage* message) +StackTraceView::SetStackTraceClearPending() { - switch (message->what) { - case MSG_CLEAR_STACK_TRACE: - { - if (fTraceUpdateRunner != NULL) - _SetStackTrace(NULL); - break; - } - default: - { - BGroupView::MessageReceived(message); - break; - } - } + fTraceClearPending = true; } void StackTraceView::TableSelectionChanged(Table* table) { - if (fListener == NULL) + if (fListener == NULL || fTraceClearPending) return; - if (fTraceUpdateRunner != NULL) { - // in this instance, ignore the selection change, since the - // stack trace for which a selection change was requested will - // momentarily be invalid. This case is quite unlikely to be hit - // anyways. - return; - } - StackFrame* frame = fFramesTableModel->FrameAt(table->SelectionModel()->RowAt(0)); @@ -283,24 +253,6 @@ StackTraceView::_Init() } -void -StackTraceView::_SetStackTrace(StackTrace* stackTrace) -{ - delete fTraceUpdateRunner; - fTraceUpdateRunner = NULL; - - if (fStackTrace != NULL) - fStackTrace->ReleaseReference(); - - fStackTrace = stackTrace; - - if (fStackTrace != NULL) - fStackTrace->AcquireReference(); - - fFramesTableModel->SetStackTrace(fStackTrace); -} - - // #pragma mark - Listener diff --git a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h index 87e8a28bc4..01cbdde833 100644 --- a/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h +++ b/src/apps/debugger/user_interface/gui/team_window/StackTraceView.h @@ -11,7 +11,6 @@ #include "Team.h" -class BMessageRunner; class StackFrame; @@ -34,7 +33,7 @@ public: void LoadSettings(const BMessage& settings); status_t SaveSettings(BMessage& settings); - virtual void MessageReceived(BMessage* message); + void SetStackTraceClearPending(); private: class FramesTableModel; @@ -45,13 +44,11 @@ private: void _Init(); - void _SetStackTrace(StackTrace* stackTrace); - private: StackTrace* fStackTrace; Table* fFramesTable; FramesTableModel* fFramesTableModel; - BMessageRunner* fTraceUpdateRunner; + bool fTraceClearPending; Listener* fListener; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index 031c4c0ac1..697680149b 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +62,8 @@ enum { enum { MSG_CHOOSE_DEBUG_REPORT_LOCATION = 'ccrl', MSG_DEBUG_REPORT_SAVED = 'drsa', - MSG_LOCATE_SOURCE_IF_NEEDED = 'lsin' + MSG_LOCATE_SOURCE_IF_NEEDED = 'lsin', + MSG_CLEAR_STACK_TRACE = 'clst' }; @@ -103,6 +105,7 @@ TeamWindow::TeamWindow(::Team* team, UserInterfaceListener* listener) fActiveSourceCode(NULL), fActiveSourceObject(ACTIVE_SOURCE_NONE), fListener(listener), + fTraceUpdateRunner(NULL), fTabView(NULL), fLocalsTabView(NULL), fThreadListView(NULL), @@ -185,7 +188,7 @@ TeamWindow::DispatchMessage(BMessage* message, BHandler* handler) // Handle function key shortcuts for stepping switch (message->what) { case B_KEY_DOWN: - if (fActiveThread != NULL) { + if (fActiveThread != NULL && fTraceUpdateRunner == NULL) { int32 key; uint32 modifiers; if (message->FindInt32("key", &key) == B_OK @@ -393,12 +396,20 @@ TeamWindow::MessageReceived(BMessage* message) case MSG_THREAD_STEP_OVER: case MSG_THREAD_STEP_INTO: case MSG_THREAD_STEP_OUT: - if (fActiveThread != NULL) { + if (fActiveThread != NULL && fTraceUpdateRunner == NULL) { fListener->ThreadActionRequested(fActiveThread->ID(), message->what); } break; + case MSG_CLEAR_STACK_TRACE: + { + if (fTraceUpdateRunner != NULL) { + _SetActiveStackTrace(NULL); + _UpdateRunButtons(); + } + break; + } case MSG_THREAD_STATE_CHANGED: { int32 threadID; @@ -729,7 +740,8 @@ void TeamWindow::ThreadActionRequested(::Thread* thread, uint32 action, target_addr_t address) { - fListener->ThreadActionRequested(thread->ID(), action, address); + if (fTraceUpdateRunner == NULL) + fListener->ThreadActionRequested(thread->ID(), action, address); } @@ -1049,6 +1061,9 @@ TeamWindow::_SetActiveImage(Image* image) void TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace) { + delete fTraceUpdateRunner; + fTraceUpdateRunner = NULL; + if (stackTrace == fActiveStackTrace) return; @@ -1065,6 +1080,8 @@ TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace) if (fActiveStackTrace != NULL) _SetActiveStackFrame(fActiveStackTrace->FrameAt(0)); + else + _SetActiveStackFrame(NULL); } @@ -1278,12 +1295,14 @@ TeamWindow::_UpdateRunButtons() fStepOutButton->SetEnabled(false); break; case THREAD_STATE_RUNNING: - fRunButton->SetLabel("Debug"); - fRunButton->SetMessage(new BMessage(MSG_THREAD_STOP)); - fRunButton->SetEnabled(true); - fStepOverButton->SetEnabled(false); - fStepIntoButton->SetEnabled(false); - fStepOutButton->SetEnabled(false); + if (fTraceUpdateRunner == NULL) { + fRunButton->SetLabel("Debug"); + fRunButton->SetMessage(new BMessage(MSG_THREAD_STOP)); + fRunButton->SetEnabled(true); + fStepOverButton->SetEnabled(false); + fStepIntoButton->SetEnabled(false); + fStepOutButton->SetEnabled(false); + } break; case THREAD_STATE_STOPPED: fRunButton->SetLabel("Run"); @@ -1432,6 +1451,21 @@ TeamWindow::_HandleStackTraceChanged(thread_id threadID) locker.Unlock(); + if (stackTrace == NULL) { + if (fTraceUpdateRunner != NULL) + return; + + BMessage message(MSG_CLEAR_STACK_TRACE); + fTraceUpdateRunner = new(std::nothrow) BMessageRunner(this, + message, 250000, 1); + if (fTraceUpdateRunner != NULL + && fTraceUpdateRunner->InitCheck() == B_OK) { + fStackTraceView->SetStackTraceClearPending(); + fVariablesView->SetStackFrameClearPending(); + return; + } + } + _SetActiveStackTrace(stackTrace); } diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h index 7a2157f405..2f4d411967 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h @@ -26,6 +26,7 @@ class BButton; class BFilePanel; class BMenuBar; +class BMessageRunner; class BSplitView; class BStringView; class BTabView; @@ -182,6 +183,7 @@ private: SourceCode* fActiveSourceCode; ActiveSourceObject fActiveSourceObject; UserInterfaceListener* fListener; + BMessageRunner* fTraceUpdateRunner; BTabView* fTabView; BTabView* fLocalsTabView; ThreadListView* fThreadListView; diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 2e01387671..113c6cb8f4 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -1428,6 +1428,7 @@ VariablesView::VariablesView(Listener* listener) fPreviousViewState(NULL), fViewStateHistory(NULL), fTableCellContextMenuTracker(NULL), + fFrameClearPending(false), fListener(listener) { SetName("Variables"); @@ -1471,6 +1472,8 @@ VariablesView::Create(Listener* listener) void VariablesView::SetStackFrame(Thread* thread, StackFrame* stackFrame) { + fFrameClearPending = false; + if (thread == fThread && stackFrame == fStackFrame) return; @@ -1859,12 +1862,20 @@ VariablesView::SaveSettings(BMessage& settings) } +void +VariablesView::SetStackFrameClearPending() +{ + fFrameClearPending = true; +} void VariablesView::TreeTableNodeExpandedChanged(TreeTable* table, const TreeTablePath& path, bool expanded) { + if (fFrameClearPending) + return; + if (expanded) { ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path); if (node == NULL) @@ -1901,6 +1912,9 @@ VariablesView::TreeTableCellMouseDown(TreeTable* table, if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0) return; + if (fFrameClearPending) + return; + _FinishContextMenu(true); ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path); diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h index 974190068d..9db6c3b53e 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -47,6 +47,8 @@ public: void LoadSettings(const BMessage& settings); status_t SaveSettings(BMessage& settings); + void SetStackFrameClearPending(); + private: // TreeTableListener virtual void TreeTableNodeExpandedChanged(TreeTable* table, @@ -94,6 +96,7 @@ private: VariablesViewState* fPreviousViewState; VariablesViewStateHistory* fViewStateHistory; TableCellContextMenuTracker* fTableCellContextMenuTracker; + bool fFrameClearPending; Listener* fListener; };