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 <ControlLook.h>
#include <MessageRunner.h>
#include <Window.h>
#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
@@ -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;
};
@@ -19,6 +19,7 @@
#include <MenuItem.h>
#include <Message.h>
#include <MessageFilter.h>
#include <MessageRunner.h>
#include <Path.h>
#include <StringView.h>
#include <TabView.h>
@@ -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);
}
@@ -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;
@@ -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);
@@ -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;
};