Fix remaining flickering for #9841.

- Revert hrev45802. However, implement the same essential logic in
  the TeamWindow itself, and have it guard the StackTraceView,
  VariablesView, and step control buttons. This fixes flickering
  in between short steps since it prevents the intermediate clear
  from happening unnecessarily.
- Implement appropriate guards for the interim wait state.
This commit is contained in:
Rene Gollent
2013-06-30 19:53:34 -04:00
parent c2d6b9fa8e
commit a7376ac175
6 changed files with 77 additions and 75 deletions
@@ -12,7 +12,6 @@
#include <new> #include <new>
#include <ControlLook.h> #include <ControlLook.h>
#include <MessageRunner.h>
#include <Window.h> #include <Window.h>
#include "table/TableColumns.h" #include "table/TableColumns.h"
@@ -25,11 +24,6 @@
#include "UiUtils.h" #include "UiUtils.h"
enum {
MSG_CLEAR_STACK_TRACE = 'clst'
};
// #pragma mark - FramesTableModel // #pragma mark - FramesTableModel
@@ -114,7 +108,7 @@ StackTraceView::StackTraceView(Listener* listener)
fStackTrace(NULL), fStackTrace(NULL),
fFramesTable(NULL), fFramesTable(NULL),
fFramesTableModel(NULL), fFramesTableModel(NULL),
fTraceUpdateRunner(NULL), fTraceClearPending(false),
fListener(listener) fListener(listener)
{ {
SetName("Stack Trace"); SetName("Stack Trace");
@@ -155,23 +149,19 @@ StackTraceView::UnsetListener()
void void
StackTraceView::SetStackTrace(StackTrace* stackTrace) StackTraceView::SetStackTrace(StackTrace* stackTrace)
{ {
fTraceClearPending = false;
if (stackTrace == fStackTrace) if (stackTrace == fStackTrace)
return; return;
if (stackTrace == NULL) { if (fStackTrace != NULL)
if (fTraceUpdateRunner != NULL) fStackTrace->ReleaseReference();
return;
BMessage message(MSG_CLEAR_STACK_TRACE); fStackTrace = stackTrace;
fTraceUpdateRunner = new(std::nothrow) BMessageRunner(this,
message, 250000, 1);
if (fTraceUpdateRunner != NULL
&& fTraceUpdateRunner->InitCheck() == B_OK) {
return;
}
}
_SetStackTrace(stackTrace); if (fStackTrace != NULL)
fStackTrace->AcquireReference();
fFramesTableModel->SetStackTrace(fStackTrace);
} }
@@ -218,38 +208,18 @@ StackTraceView::SaveSettings(BMessage& settings)
void void
StackTraceView::MessageReceived(BMessage* message) StackTraceView::SetStackTraceClearPending()
{ {
switch (message->what) { fTraceClearPending = true;
case MSG_CLEAR_STACK_TRACE:
{
if (fTraceUpdateRunner != NULL)
_SetStackTrace(NULL);
break;
}
default:
{
BGroupView::MessageReceived(message);
break;
}
}
} }
void void
StackTraceView::TableSelectionChanged(Table* table) StackTraceView::TableSelectionChanged(Table* table)
{ {
if (fListener == NULL) if (fListener == NULL || fTraceClearPending)
return; 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 StackFrame* frame
= fFramesTableModel->FrameAt(table->SelectionModel()->RowAt(0)); = 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 // #pragma mark - Listener
@@ -11,7 +11,6 @@
#include "Team.h" #include "Team.h"
class BMessageRunner;
class StackFrame; class StackFrame;
@@ -34,7 +33,7 @@ public:
void LoadSettings(const BMessage& settings); void LoadSettings(const BMessage& settings);
status_t SaveSettings(BMessage& settings); status_t SaveSettings(BMessage& settings);
virtual void MessageReceived(BMessage* message); void SetStackTraceClearPending();
private: private:
class FramesTableModel; class FramesTableModel;
@@ -45,13 +44,11 @@ private:
void _Init(); void _Init();
void _SetStackTrace(StackTrace* stackTrace);
private: private:
StackTrace* fStackTrace; StackTrace* fStackTrace;
Table* fFramesTable; Table* fFramesTable;
FramesTableModel* fFramesTableModel; FramesTableModel* fFramesTableModel;
BMessageRunner* fTraceUpdateRunner; bool fTraceClearPending;
Listener* fListener; Listener* fListener;
}; };
@@ -19,6 +19,7 @@
#include <MenuItem.h> #include <MenuItem.h>
#include <Message.h> #include <Message.h>
#include <MessageFilter.h> #include <MessageFilter.h>
#include <MessageRunner.h>
#include <Path.h> #include <Path.h>
#include <StringView.h> #include <StringView.h>
#include <TabView.h> #include <TabView.h>
@@ -61,7 +62,8 @@ enum {
enum { enum {
MSG_CHOOSE_DEBUG_REPORT_LOCATION = 'ccrl', MSG_CHOOSE_DEBUG_REPORT_LOCATION = 'ccrl',
MSG_DEBUG_REPORT_SAVED = 'drsa', 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), fActiveSourceCode(NULL),
fActiveSourceObject(ACTIVE_SOURCE_NONE), fActiveSourceObject(ACTIVE_SOURCE_NONE),
fListener(listener), fListener(listener),
fTraceUpdateRunner(NULL),
fTabView(NULL), fTabView(NULL),
fLocalsTabView(NULL), fLocalsTabView(NULL),
fThreadListView(NULL), fThreadListView(NULL),
@@ -185,7 +188,7 @@ TeamWindow::DispatchMessage(BMessage* message, BHandler* handler)
// Handle function key shortcuts for stepping // Handle function key shortcuts for stepping
switch (message->what) { switch (message->what) {
case B_KEY_DOWN: case B_KEY_DOWN:
if (fActiveThread != NULL) { if (fActiveThread != NULL && fTraceUpdateRunner == NULL) {
int32 key; int32 key;
uint32 modifiers; uint32 modifiers;
if (message->FindInt32("key", &key) == B_OK if (message->FindInt32("key", &key) == B_OK
@@ -393,12 +396,20 @@ TeamWindow::MessageReceived(BMessage* message)
case MSG_THREAD_STEP_OVER: case MSG_THREAD_STEP_OVER:
case MSG_THREAD_STEP_INTO: case MSG_THREAD_STEP_INTO:
case MSG_THREAD_STEP_OUT: case MSG_THREAD_STEP_OUT:
if (fActiveThread != NULL) { if (fActiveThread != NULL && fTraceUpdateRunner == NULL) {
fListener->ThreadActionRequested(fActiveThread->ID(), fListener->ThreadActionRequested(fActiveThread->ID(),
message->what); message->what);
} }
break; break;
case MSG_CLEAR_STACK_TRACE:
{
if (fTraceUpdateRunner != NULL) {
_SetActiveStackTrace(NULL);
_UpdateRunButtons();
}
break;
}
case MSG_THREAD_STATE_CHANGED: case MSG_THREAD_STATE_CHANGED:
{ {
int32 threadID; int32 threadID;
@@ -729,7 +740,8 @@ void
TeamWindow::ThreadActionRequested(::Thread* thread, uint32 action, TeamWindow::ThreadActionRequested(::Thread* thread, uint32 action,
target_addr_t address) 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 void
TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace) TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace)
{ {
delete fTraceUpdateRunner;
fTraceUpdateRunner = NULL;
if (stackTrace == fActiveStackTrace) if (stackTrace == fActiveStackTrace)
return; return;
@@ -1065,6 +1080,8 @@ TeamWindow::_SetActiveStackTrace(StackTrace* stackTrace)
if (fActiveStackTrace != NULL) if (fActiveStackTrace != NULL)
_SetActiveStackFrame(fActiveStackTrace->FrameAt(0)); _SetActiveStackFrame(fActiveStackTrace->FrameAt(0));
else
_SetActiveStackFrame(NULL);
} }
@@ -1278,12 +1295,14 @@ TeamWindow::_UpdateRunButtons()
fStepOutButton->SetEnabled(false); fStepOutButton->SetEnabled(false);
break; break;
case THREAD_STATE_RUNNING: case THREAD_STATE_RUNNING:
fRunButton->SetLabel("Debug"); if (fTraceUpdateRunner == NULL) {
fRunButton->SetMessage(new BMessage(MSG_THREAD_STOP)); fRunButton->SetLabel("Debug");
fRunButton->SetEnabled(true); fRunButton->SetMessage(new BMessage(MSG_THREAD_STOP));
fStepOverButton->SetEnabled(false); fRunButton->SetEnabled(true);
fStepIntoButton->SetEnabled(false); fStepOverButton->SetEnabled(false);
fStepOutButton->SetEnabled(false); fStepIntoButton->SetEnabled(false);
fStepOutButton->SetEnabled(false);
}
break; break;
case THREAD_STATE_STOPPED: case THREAD_STATE_STOPPED:
fRunButton->SetLabel("Run"); fRunButton->SetLabel("Run");
@@ -1432,6 +1451,21 @@ TeamWindow::_HandleStackTraceChanged(thread_id threadID)
locker.Unlock(); 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); _SetActiveStackTrace(stackTrace);
} }
@@ -26,6 +26,7 @@
class BButton; class BButton;
class BFilePanel; class BFilePanel;
class BMenuBar; class BMenuBar;
class BMessageRunner;
class BSplitView; class BSplitView;
class BStringView; class BStringView;
class BTabView; class BTabView;
@@ -182,6 +183,7 @@ private:
SourceCode* fActiveSourceCode; SourceCode* fActiveSourceCode;
ActiveSourceObject fActiveSourceObject; ActiveSourceObject fActiveSourceObject;
UserInterfaceListener* fListener; UserInterfaceListener* fListener;
BMessageRunner* fTraceUpdateRunner;
BTabView* fTabView; BTabView* fTabView;
BTabView* fLocalsTabView; BTabView* fLocalsTabView;
ThreadListView* fThreadListView; ThreadListView* fThreadListView;
@@ -1428,6 +1428,7 @@ VariablesView::VariablesView(Listener* listener)
fPreviousViewState(NULL), fPreviousViewState(NULL),
fViewStateHistory(NULL), fViewStateHistory(NULL),
fTableCellContextMenuTracker(NULL), fTableCellContextMenuTracker(NULL),
fFrameClearPending(false),
fListener(listener) fListener(listener)
{ {
SetName("Variables"); SetName("Variables");
@@ -1471,6 +1472,8 @@ VariablesView::Create(Listener* listener)
void void
VariablesView::SetStackFrame(Thread* thread, StackFrame* stackFrame) VariablesView::SetStackFrame(Thread* thread, StackFrame* stackFrame)
{ {
fFrameClearPending = false;
if (thread == fThread && stackFrame == fStackFrame) if (thread == fThread && stackFrame == fStackFrame)
return; return;
@@ -1859,12 +1862,20 @@ VariablesView::SaveSettings(BMessage& settings)
} }
void
VariablesView::SetStackFrameClearPending()
{
fFrameClearPending = true;
}
void void
VariablesView::TreeTableNodeExpandedChanged(TreeTable* table, VariablesView::TreeTableNodeExpandedChanged(TreeTable* table,
const TreeTablePath& path, bool expanded) const TreeTablePath& path, bool expanded)
{ {
if (fFrameClearPending)
return;
if (expanded) { if (expanded) {
ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path); ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path);
if (node == NULL) if (node == NULL)
@@ -1901,6 +1912,9 @@ VariablesView::TreeTableCellMouseDown(TreeTable* table,
if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0) if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0)
return; return;
if (fFrameClearPending)
return;
_FinishContextMenu(true); _FinishContextMenu(true);
ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path); ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path);
@@ -47,6 +47,8 @@ public:
void LoadSettings(const BMessage& settings); void LoadSettings(const BMessage& settings);
status_t SaveSettings(BMessage& settings); status_t SaveSettings(BMessage& settings);
void SetStackFrameClearPending();
private: private:
// TreeTableListener // TreeTableListener
virtual void TreeTableNodeExpandedChanged(TreeTable* table, virtual void TreeTableNodeExpandedChanged(TreeTable* table,
@@ -94,6 +96,7 @@ private:
VariablesViewState* fPreviousViewState; VariablesViewState* fPreviousViewState;
VariablesViewStateHistory* fViewStateHistory; VariablesViewStateHistory* fViewStateHistory;
TableCellContextMenuTracker* fTableCellContextMenuTracker; TableCellContextMenuTracker* fTableCellContextMenuTracker;
bool fFrameClearPending;
Listener* fListener; Listener* fListener;
}; };