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:
parent
18ebc7918d
commit
73f124eb41
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user