Add highlighting of apps that will not quit.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41265 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jonas Sundström 2011-04-18 23:44:20 +00:00
parent 18ebc7918d
commit 73f124eb41
4 changed files with 174 additions and 16 deletions

View File

@ -29,7 +29,8 @@ TeamListItem::TeamListItem(team_info &teamInfo)
fAppInfo(),
fMiniIcon(BRect(0, 0, 15, 15), B_RGBA32),
fLargeIcon(BRect(0, 0, 31, 31), B_RGBA32),
fFound(false)
fFound(false),
fRefusingToQuit(false)
{
int32 cookie = 0;
image_info info;
@ -68,6 +69,7 @@ TeamListItem::DrawItem(BView* owner, BRect frame, bool complete)
rgb_color kHighlight = { 140, 140, 140, 0 };
rgb_color kBlack = { 0, 0, 0, 0 };
rgb_color kBlue = { 0, 0, 255, 0 };
rgb_color kRed = { 255, 0, 0, 0 };
BRect r(frame);
@ -96,7 +98,10 @@ TeamListItem::DrawItem(BView* owner, BRect frame, bool complete)
owner->SetDrawingMode(B_OP_COPY);
frame.left += 16;
owner->SetHighColor(IsSystemServer() ? kBlue : kBlack);
if (fRefusingToQuit)
owner->SetHighColor(kRed);
else
owner->SetHighColor(IsSystemServer() ? kBlue : kBlack);
BFont font = be_plain_font;
font_height finfo;
@ -175,7 +180,21 @@ TeamListItem::IsSystemServer()
bool
TeamListItem::IsApplication()
TeamListItem::IsApplication() const
{
return fAppInfo.signature[0] != '\0';
}
void
TeamListItem::SetRefusingToQuit(bool refusing)
{
fRefusingToQuit = refusing;
}
bool
TeamListItem::IsRefusingToQuit()
{
return fRefusingToQuit;
}

View File

@ -36,11 +36,14 @@ public:
const char* AppSignature() { return fAppInfo.signature; };
bool IsSystemServer();
bool IsApplication();
bool IsApplication() const;
bool Found() const { return fFound; }
void SetFound(bool found) { fFound = found; }
void SetRefusingToQuit(bool refusing);
bool IsRefusingToQuit();
static int32 MinimalHeight();
private:
@ -51,6 +54,7 @@ private:
BPath fPath;
BString fLocalizedName;
bool fFound;
bool fRefusingToQuit;
};

View File

@ -42,8 +42,49 @@
TeamMonitorWindow* gTeamMonitorWindow = NULL;
struct TeamQuitter {
team_id team;
thread_id thread;
BLooper* window;
};
status_t
QuitTeamThreadFunction(void* data)
{
TeamQuitter* teamQuitter = reinterpret_cast<TeamQuitter*>(data);
if (teamQuitter == NULL)
return B_ERROR;
status_t status;
BMessenger messenger(NULL, teamQuitter->team, &status);
if (status != B_OK)
return status;
BMessage message(B_QUIT_REQUESTED);
BMessage reply;
messenger.SendMessage(&message, &reply, 3000000, 3000000);
bool result;
if (reply.what != B_REPLY
|| reply.FindBool("result", &result) != B_OK
|| result == false) {
message.what = kMsgQuitFailed;
message.AddPointer("TeamQuitter", teamQuitter);
message.AddInt32("error", reply.what);
if (teamQuitter->window != NULL)
teamQuitter->window->PostMessage(&message);
return reply.what;
}
return B_OK;
}
filter_result
FilterLocaleChanged(BMessage* message, BHandler** target, BMessageFilter *filter)
FilterLocaleChanged(BMessage* message, BHandler** target,
BMessageFilter *filter)
{
if (message->what == B_LOCALE_CHANGED && gTeamMonitorWindow != NULL)
gTeamMonitorWindow->LocaleChanged();
@ -78,6 +119,7 @@ private:
IconView* fIconView;
const char* fInfoString;
const char* fSysComponentString;
const char* fQuitOverdueString;
BCardLayout* fLayout;
AllShowingTextView* fIconTextView;
AllShowingTextView* fInfoTextView;
@ -202,6 +244,15 @@ TeamMonitorWindow::TeamMonitorWindow()
TeamMonitorWindow::~TeamMonitorWindow()
{
while (fTeamQuitterList.ItemAt(0) != NULL) {
TeamQuitter* teamQuitter = reinterpret_cast<TeamQuitter*>
(fTeamQuitterList.RemoveItem((int32) 0));
if (teamQuitter != NULL) {
status_t status;
wait_for_thread(teamQuitter->thread, &status);
delete teamQuitter;
}
}
}
@ -252,12 +303,14 @@ TeamMonitorWindow::MessageReceived(BMessage* msg)
TeamListItem* item = dynamic_cast<TeamListItem*>(fListView->ItemAt(
fListView->CurrentSelection()));
if (item != NULL) {
BMessenger messenger(item->AppSignature(),
item->GetInfo()->team);
messenger.SendMessage(B_QUIT_REQUESTED);
QuitTeam(item);
}
break;
}
case kMsgQuitFailed:
MarkUnquittableTeam(msg);
break;
case TM_RESTART_DESKTOP:
{
if (!be_roster->IsRunning(kTrackerSignature))
@ -381,10 +434,15 @@ TeamMonitorWindow::Enable()
void
TeamMonitorWindow::Disable()
{
fListView->DeselectAll();
delete fUpdateRunner;
fUpdateRunner = NULL;
Hide();
fListView->DeselectAll();
for (int32 i = 0; i < fListView->CountItems(); i++) {
TeamListItem* item = dynamic_cast<TeamListItem*>(fListView->ItemAt(i));
if (item != NULL)
item->SetRefusingToQuit(false);
}
}
@ -404,6 +462,64 @@ TeamMonitorWindow::LocaleChanged()
}
void
TeamMonitorWindow::QuitTeam(TeamListItem* item)
{
if (item == NULL)
return;
TeamQuitter* teamQuitter = new TeamQuitter;
teamQuitter->team = item->GetInfo()->team;
teamQuitter->window = this;
teamQuitter->thread = spawn_thread(QuitTeamThreadFunction,
"team quitter", B_DISPLAY_PRIORITY, teamQuitter);
if (teamQuitter->thread < 0) {
delete teamQuitter;
return;
}
fTeamQuitterList.AddItem(teamQuitter);
if (resume_thread(teamQuitter->thread) != B_OK) {
fTeamQuitterList.RemoveItem(teamQuitter);
delete teamQuitter;
}
}
void
TeamMonitorWindow::MarkUnquittableTeam(BMessage* message)
{
if (message == NULL)
return;
int32 reply;
if (message->FindInt32("error", &reply) != B_OK)
return;
TeamQuitter* teamQuitter;
if (message->FindPointer("TeamQuitter",
reinterpret_cast<void**>(&teamQuitter)) != B_OK)
return;
for (int32 i = 0; i < fListView->CountItems(); i++) {
TeamListItem* item
= dynamic_cast<TeamListItem*>(fListView->ItemAt(i));
if (item != NULL && item->GetInfo()->team == teamQuitter->team) {
item->SetRefusingToQuit(true);
fListView->Select(i);
fListView->InvalidateItem(i);
fDescriptionView->SetItem(item);
break;
}
}
fTeamQuitterList.RemoveItem(teamQuitter);
delete teamQuitter;
}
// #pragma mark -
@ -421,6 +537,8 @@ TeamDescriptionView::TeamDescriptionView()
"Hold CONTROL+ALT+DELETE for %ld seconds to reboot.");
fSysComponentString = B_TRANSLATE("(This team is a system component)");
fQuitOverdueString = B_TRANSLATE("If the application will not quit "
"you may have to kill it.");
fInfoTextView = new AllShowingTextView("info text");
fIconTextView = new AllShowingTextView("icon text");
@ -494,28 +612,41 @@ void
TeamDescriptionView::SetItem(TeamListItem* item)
{
fItem = item;
int32 styleStart = 0;
int32 styleEnd = 0;
BTextView* view = NULL;
if (item == NULL) {
BString text;
text.SetToFormat(fInfoString, fSeconds);
fInfoTextView->SetText(text);
if (fRebootRunner != NULL && fSeconds < 4) {
BFont font;
fInfoTextView->GetFont(&font);
font.SetFace(B_BOLD_FACE);
fInfoTextView->SetStylable(true);
fInfoTextView->SetFontAndColor(text.FindLast('\n'),
text.Length() - 1, &font);
styleStart = text.FindLast('\n');
styleEnd = text.Length();
}
view = fInfoTextView;
} else {
BString text = item->Path()->Path();
if (item->IsSystemServer())
text << "\n" << fSysComponentString;
if (item->IsRefusingToQuit()) {
text << "\n\n" << fQuitOverdueString;
styleStart = text.FindLast('\n');
styleEnd = text.Length();
}
view = fIconTextView;
fIconTextView->SetText(text);
fIconView->SetIcon(item->Path()->Path());
}
if (styleStart != styleEnd && view != NULL) {
BFont font;
view->GetFont(&font);
font.SetFace(B_BOLD_FACE);
view->SetStylable(true);
view->SetFontAndColor(styleStart, styleEnd, &font);
}
if (fLayout == NULL)
return;

View File

@ -33,6 +33,8 @@ public:
void Disable();
void DeselectAll();
void LocaleChanged();
void QuitTeam(TeamListItem* item);
void MarkUnquittableTeam(BMessage* message);
private:
void UpdateList();
@ -45,9 +47,11 @@ private:
BButton* fQuitButton;
BButton* fRestartButton;
TeamDescriptionView* fDescriptionView;
BList fTeamQuitterList;
};
static const uint32 kMsgCtrlAltDelPressed = 'TMcp';
static const uint32 kMsgDeselectAll = 'TMds';
static const uint32 kMsgQuitFailed = 'TMqf';
#endif // TEAM_MONITOR_WINDOW_H