Tracker: Move CreateTrashPose() to DesktopPoseView and simplify

Add AddPosesCompleted() override in DesktopPoseView.

Better Desktop checking (by use passed in param).

Add an IconAttrChanged() convenience method that checks for icon
attribute changes only. AttrChanged() calls this and then checks
a couple of other attributes.

Change-Id: Id7d399eaea3ca2f97083c93ebfb9157327ae4f0d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10638
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
John Scipione
2026-03-31 17:04:07 +00:00
committed by waddlesplash
parent 290c47d7bd
commit 75628f3bac
6 changed files with 79 additions and 66 deletions
+36
View File
@@ -193,6 +193,42 @@ DesktopPoseView::AddPosesThreadValid(const entry_ref*) const
} }
void
DesktopPoseView::AddPosesCompleted()
{
_inherited::AddPosesCompleted();
// Create Trash pose after other poses have been added
// so that it is positioned in the next available space.
CreateTrashPose();
}
void
DesktopPoseView::CreateTrashPose()
{
BPath path;
if (find_directory(B_TRASH_DIRECTORY, &path) != B_OK)
return;
BDirectory trashDir(path.Path());
BEntry entry;
if (trashDir.GetEntry(&entry) != B_OK)
return;
// redraw Trash icon when attribute changes
node_ref nref;
if (entry.GetNodeRef(&nref) == B_OK)
WatchNewNode(&nref, B_WATCH_ATTR, BMessenger(this));
Model* trashModel = new Model(&entry);
PoseInfo poseInfo;
ReadPoseInfo(trashModel, &poseInfo);
CreatePose(trashModel, &poseInfo, false, NULL, NULL, true);
}
bool bool
DesktopPoseView::Represents(const node_ref* ref) const DesktopPoseView::Represents(const node_ref* ref) const
{ {
+2
View File
@@ -64,6 +64,8 @@ protected:
virtual EntryListBase* InitDirentIterator(const entry_ref*); virtual EntryListBase* InitDirentIterator(const entry_ref*);
virtual bool AddPosesThreadValid(const entry_ref*) const; virtual bool AddPosesThreadValid(const entry_ref*) const;
virtual void AddPosesCompleted();
virtual void CreateTrashPose();
virtual bool IsDesktopView() const; virtual bool IsDesktopView() const;
+17 -6
View File
@@ -949,13 +949,8 @@ Model::AttrChanged(const char* attrName)
// return true if icon needs updating // return true if icon needs updating
ASSERT(IsNodeOpen()); ASSERT(IsNodeOpen());
if (attrName != NULL if (IconAttrChanged(attrName))
&& (strcmp(attrName, kAttrIcon) == 0
|| strcmp(attrName, kAttrMiniIcon) == 0
|| strcmp(attrName, kAttrLargeIcon) == 0
|| strcmp(attrName, kAttrThumbnail) == 0)) {
return true; return true;
}
if (attrName == NULL if (attrName == NULL
|| strcmp(attrName, kAttrMIMEType) == 0 || strcmp(attrName, kAttrMIMEType) == 0
@@ -989,6 +984,22 @@ Model::AttrChanged(const char* attrName)
} }
bool
Model::IconAttrChanged(const char* attrName)
{
// called on an icon attribute changed by node monitor
// return true if icon needs updating
ASSERT(IsNodeOpen());
return attrName != NULL
&& (strcmp(attrName, kAttrIcon) == 0
|| strcmp(attrName, kAttrLargeIcon) == 0
|| strcmp(attrName, kAttrMiniIcon) == 0
|| strcmp(attrName, kAttrThumbnail) == 0);
}
bool bool
Model::StatChanged() Model::StatChanged()
{ {
+2
View File
@@ -169,6 +169,8 @@ public:
bool AttrChanged(const char* attrName); bool AttrChanged(const char* attrName);
// returns true if pose needs to update its icon, etc. // returns true if pose needs to update its icon, etc.
// pass null to force full update // pass null to force full update
bool IconAttrChanged(const char* attrName);
// returns true if pose needs to update its icon
bool StatChanged(); bool StatChanged();
// returns true if pose needs to update its icon // returns true if pose needs to update its icon
+22 -58
View File
@@ -801,15 +801,14 @@ BPoseView::SavePoseLocations(BRect* frameIfDesktop)
Model* model = pose->TargetModel(); Model* model = pose->TargetModel();
poseInfo.fInvisible = false; poseInfo.fInvisible = false;
bool isRoot = model->IsRoot(); // Root and Trash pose are on the Desktop
if (isRoot) if (model->IsRoot() || (model->IsTrash() && isDesktop))
poseInfo.fInitedDirectory = targetModel->NodeRef()->node; poseInfo.fInitedDirectory = targetModel->NodeRef()->node;
else else
poseInfo.fInitedDirectory = model->EntryRef()->directory; poseInfo.fInitedDirectory = model->EntryRef()->directory;
// Trash pose should be invisible except on the Desktop // Trash pose should be invisible except on the Desktop
bool isTrash = model->IsTrash(); if (model->IsTrash() && !isDesktop)
if (model->IsTrash() && !IsDesktopView())
poseInfo.fInvisible = true; poseInfo.fInvisible = true;
poseInfo.fLocation = pose->Location(this); poseInfo.fLocation = pose->Location(this);
@@ -851,7 +850,7 @@ BPoseView::SavePoseLocations(BRect* frameIfDesktop)
ASSERT(model->InitCheck() == B_OK); ASSERT(model->InitCheck() == B_OK);
// special handling for "root" disks icon // special handling for "root" disks icon
// and Trash pose on Desktop directory // and Trash pose on Desktop directory
if (isRoot || (isTrash && IsDesktopView())) { if (model->IsRoot() || (model->IsTrash() && isDesktop)) {
BDirectory deskDir; BDirectory deskDir;
if (FSGetDeskDir(&deskDir) == B_OK) { if (FSGetDeskDir(&deskDir) == B_OK) {
const char* poseInfoAttr = model->IsTrash() const char* poseInfoAttr = model->IsTrash()
@@ -1708,10 +1707,6 @@ BPoseView::AddPosesCompleted()
if (window != NULL && window->ShouldAddMenus()) if (window != NULL && window->ShouldAddMenus())
window->AddMimeTypesToMenu(); window->AddMimeTypesToMenu();
// add Trash icon to Desktop
if (IsVolumesRoot())
CreateTrashPose();
// if we're not in icon mode then we need to check for poses that // if we're not in icon mode then we need to check for poses that
// were "auto" placed to see if they overlap with other icons // were "auto" placed to see if they overlap with other icons
if (ViewMode() != kListMode) if (ViewMode() != kListMode)
@@ -1806,28 +1801,6 @@ BPoseView::RemoveRootPose()
} }
void
BPoseView::CreateTrashPose()
{
BVolume boot;
if (BVolumeRoster().GetBootVolume(&boot) == B_OK) {
BDirectory trash;
BEntry entry;
node_ref nref;
if (FSGetTrashDir(&trash, boot.Device()) == B_OK
&& trash.GetEntry(&entry) == B_OK
&& entry.GetNodeRef(&nref) == B_OK) {
WatchNewNode(&nref, B_WATCH_ATTR, BMessenger(this));
// redraw Trash icon when attribute changes
Model* model = new Model(&entry);
PoseInfo info;
ReadPoseInfo(model, &info);
CreatePose(model, &info, false, NULL, NULL, true);
}
}
}
BPose* BPose*
BPoseView::CreatePose(Model* model, PoseInfo* poseInfo, bool insertionSort, BPoseView::CreatePose(Model* model, PoseInfo* poseInfo, bool insertionSort,
int32* indexPtr, BRect* boundsPointer, bool forceDraw) int32* indexPtr, BRect* boundsPointer, bool forceDraw)
@@ -2995,22 +2968,18 @@ BPoseView::ReadPoseInfo(Model* model, PoseInfo* poseInfo)
ReadAttrResult result = kReadAttrFailed; ReadAttrResult result = kReadAttrFailed;
BEntry entry; BEntry entry;
model->GetEntry(&entry); model->GetEntry(&entry);
bool isTrash = model->IsTrash() && IsDesktopView();
// special case the "root" disks icon // special case the "root" disks icon
// as well as the trash on desktop // as well as the Trash on Desktop
if (model->IsRoot() || isTrash) { if (model->IsRoot() || (model->IsTrash() && IsDesktopView())) {
BDirectory dir; BDirectory desktopDir;
if (FSGetDeskDir(&dir) == B_OK) { if (FSGetDeskDir(&desktopDir) == B_OK) {
const char* poseInfoAttr = isTrash const char* poseInfoAttr = model->IsTrash()
? kAttrTrashPoseInfo ? kAttrTrashPoseInfo : kAttrDisksPoseInfo;
: kAttrDisksPoseInfo; const char* poseInfoAttrForeign = model->IsTrash()
const char* poseInfoAttrForeign = isTrash ? kAttrTrashPoseInfoForeign : kAttrDisksPoseInfoForeign;
? kAttrTrashPoseInfoForeign result = ReadAttr(&desktopDir, poseInfoAttr, poseInfoAttrForeign,
: kAttrDisksPoseInfoForeign; B_RAW_TYPE, 0, poseInfo, sizeof(*poseInfo), &PoseInfo::EndianSwap);
result = ReadAttr(&dir, poseInfoAttr, poseInfoAttrForeign,
B_RAW_TYPE, 0, poseInfo, sizeof(*poseInfo),
&PoseInfo::EndianSwap);
} }
} else { } else {
ASSERT(model->IsNodeOpen()); ASSERT(model->IsNodeOpen());
@@ -5924,13 +5893,16 @@ BPoseView::AttributeChanged(const BMessage* message)
if (IsFiltering()) if (IsFiltering())
visible = fFilteredPoseList->FindPose(poseModel->NodeRef(), &index) != NULL; visible = fFilteredPoseList->FindPose(poseModel->NodeRef(), &index) != NULL;
status_t infoStatus = B_ERROR; BPoint poseLoc;
if (ViewMode() == kListMode)
poseLoc.Set(0, index * fListElemHeight);
else
poseLoc = pose->Location(this);
if (attrName != NULL) { if (attrName != NULL) {
status_t infoStatus = B_ERROR;
memset(&info, 0, sizeof(attr_info)); memset(&info, 0, sizeof(attr_info));
if (strcmp(attrName, kAttrIcon) == 0 if (poseModel->IconAttrChanged(attrName)) {
|| strcmp(attrName, kAttrLargeIcon) == 0
|| strcmp(attrName, kAttrMiniIcon) == 0
|| strcmp(attrName, kAttrThumbnail) == 0) {
// set icon type manually in case attribute was removed // set icon type manually in case attribute was removed
if (strcmp(attrName, kAttrIcon) == 0) if (strcmp(attrName, kAttrIcon) == 0)
info.type = B_VECTOR_ICON_TYPE; info.type = B_VECTOR_ICON_TYPE;
@@ -5948,15 +5920,7 @@ BPoseView::AttributeChanged(const BMessage* message)
// the call below might fail if the attribute has been removed // the call below might fail if the attribute has been removed
infoStatus = poseModel->Node()->GetAttrInfo(attrName, &info); infoStatus = poseModel->Node()->GetAttrInfo(attrName, &info);
} }
}
BPoint poseLoc;
if (ViewMode() == kListMode)
poseLoc.Set(0, index * fListElemHeight);
else
poseLoc = pose->Location(this);
if (attrName != NULL) {
// update attr // update attr
pose->UpdateWidgetAndModel(attrName, infoStatus == B_OK ? info.type : 0, pose->UpdateWidgetAndModel(attrName, infoStatus == B_OK ? info.type : 0,
index, poseLoc, this, visible); index, poseLoc, this, visible);
-2
View File
@@ -493,8 +493,6 @@ protected:
virtual void CreateRootPose(); virtual void CreateRootPose();
virtual void RemoveRootPose(); virtual void RemoveRootPose();
void CreateTrashPose();
virtual bool AddPosesThreadValid(const entry_ref*) const; virtual bool AddPosesThreadValid(const entry_ref*) const;
// verifies whether or not the current set of AddPoses threads // verifies whether or not the current set of AddPoses threads
// are valid and allowed to be adding poses -- returns false // are valid and allowed to be adding poses -- returns false