Tracker: Show mounted volumes on Desktop in file panels again

Add switch to Desktop and Home shortcuts. Fixes #15148
Show Volumes or Disks on Desktop in file panel. Fixes #19547

Rename Add/RemoveRootPoses() to Add/RemoveVolumePoses().
Use default Tracker values when adapting to setting changes.

Bring ShowVolumes() into BPoseView and apply the same logic
used by file panel to DesktopPoseView to switch between Disks
and volumes on Desktop.

Add Disks or volumes to file panel in BPoseView instead.

When you set Show Disks or Show Volumes, set the other as well,
they are opposites of each other.

Remove unnecessary params related to adding/removing volumes.

Rename ShowVolumes() to ToggleDisksVolumes() and move to BPoseView.
Create IsVolumesRoot() to identify Desktop in a file panel.

Change-Id: Id250aa6cf7386c7988017a9edbdb16ec9cea00ba
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9503
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
John Scipione
2025-07-23 23:05:51 +00:00
parent 99cf83bce5
commit f21782699a
8 changed files with 184 additions and 125 deletions
+1
View File
@@ -114,6 +114,7 @@ const uint32 kEditFavorites = 'Tedf';
const uint32 kSwitchDirectory = 'Tswd';
const uint32 kQuitTracker = 'Tqit';
const uint32 kSwitchToDesktop = 'TswD';
const uint32 kSwitchToHome = 'Tswh';
const uint32 kTestIconCache = 'TicC';
+25 -42
View File
@@ -51,6 +51,7 @@ All rights reserved.
#include "FSUtils.h"
#include "PoseList.h"
#include "Tracker.h"
#include "TrackerDefaults.h"
#include "TrackerSettings.h"
#include "TrackerString.h"
@@ -95,7 +96,7 @@ DesktopPoseView::MessageReceived(BMessage* message)
break;
default:
BPoseView::MessageReceived(message);
_inherited::MessageReceived(message);
break;
}
}
@@ -188,10 +189,9 @@ DesktopPoseView::FSNotification(const BMessage* message)
break;
if (settings.MountVolumesOntoDesktop()
&& (!volume.IsShared()
|| settings.MountSharedVolumesOntoDesktop())) {
&& (!volume.IsShared() || settings.MountSharedVolumesOntoDesktop())) {
// place an icon for the volume onto the desktop
CreateVolumePose(&volume, true);
CreateVolumePose(&volume);
}
}
break;
@@ -212,7 +212,18 @@ void
DesktopPoseView::AddPosesCompleted()
{
_inherited::AddPosesCompleted();
CreateTrashPose();
CheckAutoPlacedPoses();
}
void
DesktopPoseView::AddPoses(Model* model)
{
AddVolumePoses();
_inherited::AddPoses(model);
}
@@ -236,21 +247,6 @@ DesktopPoseView::Represents(const entry_ref* ref) const
}
void
DesktopPoseView::ShowVolumes(bool visible, bool showShared)
{
if (LockLooper()) {
SavePoseLocations();
if (!visible)
RemoveRootPoses();
else
AddRootPoses(true, showShared);
UnlockLooper();
}
}
void
DesktopPoseView::StartSettingsWatch()
{
@@ -278,17 +274,14 @@ DesktopPoseView::StopSettingsWatch()
void
DesktopPoseView::AdaptToVolumeChange(BMessage* message)
{
if (Window() == NULL)
return;
TTracker* tracker = dynamic_cast<TTracker*>(be_app);
ThrowOnAssert(tracker != NULL);
bool showDisksIcon = false;
bool mountVolumesOnDesktop = true;
bool mountSharedVolumesOntoDesktop = false;
bool showDisksIcon = kDefaultShowDisksIcon;
message->FindBool("ShowDisksIcon", &showDisksIcon);
message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop);
message->FindBool("MountSharedVolumesOntoDesktop",
&mountSharedVolumesOntoDesktop);
BEntry entry("/");
Model model(&entry);
@@ -302,40 +295,30 @@ DesktopPoseView::AdaptToVolumeChange(BMessage* message)
entryMessage.AddInt32("opcode", B_ENTRY_REMOVED);
entry_ref ref;
if (entry.GetRef(&ref) == B_OK) {
BContainerWindow* disksWindow
= tracker->FindContainerWindow(&ref);
BContainerWindow* disksWindow = tracker->FindContainerWindow(&ref);
if (disksWindow != NULL) {
disksWindow->Lock();
disksWindow->Close();
}
}
}
entryMessage.AddInt32("device", model.NodeRef()->device);
entryMessage.AddInt64("node", model.NodeRef()->node);
entryMessage.AddInt64("directory", model.EntryRef()->directory);
entryMessage.AddString("name", model.EntryRef()->name);
BContainerWindow* deskWindow
= dynamic_cast<BContainerWindow*>(Window());
if (deskWindow != NULL)
deskWindow->PostMessage(&entryMessage, deskWindow->PoseView());
Window()->PostMessage(&entryMessage, this);
}
ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop);
ToggleDisksVolumes();
}
void
DesktopPoseView::AdaptToDesktopIntegrationChange(BMessage* message)
{
bool mountVolumesOnDesktop = true;
bool mountSharedVolumesOntoDesktop = true;
message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop);
message->FindBool("MountSharedVolumesOntoDesktop",
&mountSharedVolumesOntoDesktop);
ShowVolumes(false, mountSharedVolumesOntoDesktop);
ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop);
ToggleDisksVolumes();
}
+4 -5
View File
@@ -57,18 +57,17 @@ public:
static EntryListBase* InitDesktopDirentIterator(BPoseView*, const entry_ref*);
void ShowVolumes(bool visible, bool showShared);
void StartSettingsWatch();
void StopSettingsWatch();
virtual bool AddPosesThreadValid(const entry_ref*) const;
virtual void AddPosesCompleted();
protected:
virtual EntryListBase* InitDirentIterator(const entry_ref*);
virtual bool FSNotification(const BMessage*);
virtual bool AddPosesThreadValid(const entry_ref*) const;
virtual void AddPosesCompleted();
virtual void AddPoses(Model* model = NULL);
virtual bool IsDesktopView() const;
virtual bool Represents(const node_ref*) const;
+65 -46
View File
@@ -80,6 +80,7 @@ All rights reserved.
#include "NavMenu.h"
#include "Shortcuts.h"
#include "Tracker.h"
#include "TrackerDefaults.h"
#include "Utilities.h"
#include "tracker_private.h"
@@ -557,6 +558,10 @@ TFilePanel::SwitchDirectory(const entry_ref* ref)
PoseView()->SetIsDesktop(isDesktop);
_inherited::SwitchDirectory(&setToRef);
if (PoseView()->IsDesktop())
PoseView()->AddVolumePoses();
AddShortcut('D', B_COMMAND_KEY, new BMessage(kSwitchToDesktop));
AddShortcut('H', B_COMMAND_KEY, new BMessage(kSwitchToHome));
// our shortcut got possibly removed because the home
// menu item got removed - we shouldn't really have to do
@@ -804,6 +809,7 @@ TFilePanel::Init(const BMessage*)
fShortcuts = new TShortcuts(this);
AddShortcut('W', B_COMMAND_KEY, new BMessage(kCancelButton));
AddShortcut('D', B_COMMAND_KEY, new BMessage(kSwitchToDesktop));
AddShortcut('H', B_COMMAND_KEY, new BMessage(kSwitchToHome));
AddShortcut('A', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(kShowSelectionWindow));
AddShortcut('A', B_COMMAND_KEY, new BMessage(B_SELECT_ALL), this);
@@ -823,6 +829,7 @@ TFilePanel::Init(const BMessage*)
if (ShouldAddMenus())
AddMenus();
AddContextMenus();
PoseView()->ScrollTo(B_ORIGIN);
@@ -967,8 +974,7 @@ TFilePanel::RestoreWindowState(AttributeStreamNode* node)
const char* rectAttributeName = kAttrWindowFrame;
BRect frame(Frame());
if (node->Read(rectAttributeName, 0, B_RECT_TYPE, sizeof(BRect), &frame)
== sizeof(BRect)) {
if (node->Read(rectAttributeName, 0, B_RECT_TYPE, sizeof(BRect), &frame) == sizeof(BRect)) {
MoveTo(frame.LeftTop());
ResizeTo(frame.Width(), frame.Height());
}
@@ -1296,6 +1302,27 @@ TFilePanel::MessageReceived(BMessage* message)
break;
}
case kSwitchToDesktop:
{
if (PoseView() != NULL && PoseView()->IsFocus()
&& PoseView()->CanMoveToTrashOrDuplicate()) {
// duplicate selection instead
message->what = kDuplicateSelection;
PostMessage(message, PoseView());
break;
}
BPath path;
entry_ref ref;
if (find_directory(B_DESKTOP_DIRECTORY, &path) != B_OK
|| get_ref_for_path(path.Path(), &ref) != B_OK) {
break;
}
SwitchDirectory(&ref);
break;
}
case kSwitchToHome:
{
BPath homePath;
@@ -1698,7 +1725,7 @@ TFilePanel::WindowActivated(bool active)
BFilePanelPoseView::BFilePanelPoseView(Model* model)
:
BPoseView(model, kListMode),
fIsDesktop(model->IsDesktop())
fIsDesktop(model != NULL && model->IsDesktop())
{
}
@@ -1731,26 +1758,25 @@ BFilePanelPoseView::FSNotification(const BMessage* message)
switch (message->FindInt32("opcode")) {
case B_DEVICE_MOUNTED:
{
if (IsDesktop()) {
// Pretty much copied straight from DesktopPoseView.
// Would be better if the code could be shared somehow.
dev_t device;
if (message->FindInt32("new device", &device) != B_OK)
break;
if (!IsDesktop() && !TargetModel()->IsRoot())
break;
ASSERT(TargetModel() != NULL);
TrackerSettings settings;
dev_t device;
if (message->FindInt32("new device", &device) != B_OK)
break;
BVolume volume(device);
if (volume.InitCheck() != B_OK)
break;
ASSERT(TargetModel() != NULL);
TrackerSettings settings;
if (settings.MountVolumesOntoDesktop()
&& (!volume.IsShared()
|| settings.MountSharedVolumesOntoDesktop())) {
// place an icon for the volume onto the desktop
CreateVolumePose(&volume, true);
}
BVolume volume(device);
if (volume.InitCheck() != B_OK)
break;
// place volume icon onto Desktop or Root
if ((!volume.IsShared() || settings.MountSharedVolumesOntoDesktop())
&& ((IsVolumesRoot() && settings.MountVolumesOntoDesktop())
|| TargetModel()->IsRoot())) {
CreateVolumePose(&volume);
}
break;
}
@@ -1759,8 +1785,7 @@ BFilePanelPoseView::FSNotification(const BMessage* message)
{
dev_t device;
if (message->FindInt32("device", &device) == B_OK) {
if (TargetModel() != NULL
&& TargetModel()->NodeRef()->device == device) {
if (TargetModel() != NULL && TargetModel()->NodeRef()->device == device) {
// Volume currently shown in this file panel
// disappeared, reset location to home directory
BMessage message(kSwitchToHome);
@@ -1809,37 +1834,36 @@ void
BFilePanelPoseView::AddPosesCompleted()
{
_inherited::AddPosesCompleted();
if (IsDesktop())
CreateTrashPose();
// the menu that adds these shortcuts may not exist initially
Window()->AddShortcut('D', B_COMMAND_KEY, new BMessage(kSwitchToDesktop));
Window()->AddShortcut('H', B_COMMAND_KEY, new BMessage(kSwitchToHome));
UpdateScrollRange();
}
void
BFilePanelPoseView::ShowVolumes(bool visible, bool showShared)
BFilePanelPoseView::AddPoses(Model* model)
{
if (IsDesktop()) {
if (!visible)
RemoveRootPoses();
else
AddRootPoses(true, showShared);
}
if (IsDesktop())
AddVolumePoses();
TFilePanel* panel = dynamic_cast<TFilePanel*>(Window());
if (panel != NULL && TargetModel() != NULL)
panel->SwitchDirectory(TargetModel()->EntryRef());
_inherited::AddPoses(model);
}
void
BFilePanelPoseView::AdaptToVolumeChange(BMessage* message)
{
bool showDisksIcon;
bool mountVolumesOnDesktop;
bool mountSharedVolumesOntoDesktop;
if (Window() == NULL)
return;
bool showDisksIcon = kDefaultShowDisksIcon;
message->FindBool("ShowDisksIcon", &showDisksIcon);
message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop);
message->FindBool("MountSharedVolumesOntoDesktop", &mountSharedVolumesOntoDesktop);
BEntry entry("/");
Model model(&entry);
@@ -1856,23 +1880,18 @@ BFilePanelPoseView::AdaptToVolumeChange(BMessage* message)
monitorMsg.AddInt64("node", model.NodeRef()->node);
monitorMsg.AddInt64("directory", model.EntryRef()->directory);
monitorMsg.AddString("name", model.EntryRef()->name);
TrackerSettings().SetShowDisksIcon(showDisksIcon);
Window()->PostMessage(&monitorMsg, this);
}
ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop);
ToggleDisksVolumes();
}
void
BFilePanelPoseView::AdaptToDesktopIntegrationChange(BMessage* message)
{
bool mountVolumesOnDesktop = true;
bool mountSharedVolumesOntoDesktop = true;
message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop);
message->FindBool("MountSharedVolumesOntoDesktop", &mountSharedVolumesOntoDesktop);
ShowVolumes(false, mountSharedVolumesOntoDesktop);
ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop);
ToggleDisksVolumes();
}
+3 -2
View File
@@ -193,8 +193,8 @@ protected:
virtual EntryListBase* InitDirentIterator(const entry_ref*);
virtual void AddPosesCompleted();
void ShowVolumes(bool visible, bool showShared);
virtual void AddPoses(Model* model = NULL);
virtual bool IsVolumesRoot() const { return fIsDesktop; };
void AdaptToVolumeChange(BMessage*);
void AdaptToDesktopIntegrationChange(BMessage*);
@@ -205,6 +205,7 @@ private:
// the root of the world and "/boot/home/Desktop" to which
// we might have navigated from the home dir.
friend class TFilePanel;
typedef BPoseView _inherited;
};
+75 -23
View File
@@ -1280,15 +1280,13 @@ BPoseView::AddPoses(Model* model)
{
// if model is zero, PoseView has other means of iterating through all
// the entries that it adds
if (model != NULL) {
TrackerSettings settings;
if (model->IsRoot()) {
AddRootPoses(true, settings.MountSharedVolumesOntoDesktop());
return;
} else if (IsDesktopView()
&& (settings.MountVolumesOntoDesktop() || settings.ShowDisksIcon()
|| (IsFilePanel() && settings.DesktopFilePanelRoot())))
AddRootPoses(true, settings.MountSharedVolumesOntoDesktop());
// Desktop poses are added either in FilePanelPriv or DesktopPoseView
// adding volumes is all there is to do for root directory
if (TargetModel()->IsRoot()) {
AddVolumePoses();
return;
}
ShowBarberPole();
@@ -1587,8 +1585,11 @@ BPoseView::AddPosesTask(void* castToParams)
void
BPoseView::AddRootPoses(bool watchIndividually, bool mountShared)
BPoseView::AddVolumePoses()
{
if (Window() == NULL)
return;
BVolumeRoster roster;
roster.Rewind();
BVolume volume;
@@ -1606,18 +1607,18 @@ BPoseView::AddRootPoses(bool watchIndividually, bool mountShared)
monitorMsg.AddInt64("node", model.NodeRef()->node);
monitorMsg.AddInt64("directory", model.EntryRef()->directory);
monitorMsg.AddString("name", model.EntryRef()->name);
if (Window())
Window()->PostMessage(&monitorMsg, this);
Window()->PostMessage(&monitorMsg, this);
}
} else {
while (roster.GetNextVolume(&volume) == B_OK) {
if (!volume.IsPersistent())
continue;
if (volume.IsShared() && !mountShared)
if (volume.IsShared() && !TrackerSettings().MountSharedVolumesOntoDesktop())
continue;
CreateVolumePose(&volume, watchIndividually);
CreateVolumePose(&volume);
}
}
@@ -1628,7 +1629,7 @@ BPoseView::AddRootPoses(bool watchIndividually, bool mountShared)
void
BPoseView::RemoveRootPoses()
BPoseView::RemoveVolumePoses()
{
int32 index;
int32 poseCount = fPoseList->CountItems();
@@ -1652,6 +1653,25 @@ BPoseView::RemoveRootPoses()
}
void
BPoseView::ToggleDisksVolumes()
{
if (IsVolumesRoot() && LockLooper()) {
SavePoseLocations();
if (TrackerSettings().MountVolumesOntoDesktop()) {
RemoveRootPose();
AddVolumePoses();
} else {
RemoveVolumePoses();
CreateRootPose();
}
UnlockLooper();
}
}
void
BPoseView::AddTrashPoses()
{
@@ -1703,7 +1723,7 @@ BPoseView::AddPosesCompleted()
void
BPoseView::CreateVolumePose(BVolume* volume, bool watchIndividually)
BPoseView::CreateVolumePose(BVolume* volume)
{
if (volume->InitCheck() != B_OK || !volume->IsPersistent()) {
// We never want to create poses for those volumes; the file
@@ -1735,15 +1755,45 @@ BPoseView::CreateVolumePose(BVolume* volume, bool watchIndividually)
dirNode.node = ref.directory;
BPose* pose = EntryCreated(&dirNode, &itemNode, ref.name, 0);
if (pose != NULL && watchIndividually) {
// make sure volume names still get watched, even though
// they are on the desktop which is not their physical parent
if (pose != NULL && !TargetModel()->IsRoot()) {
// When placing a volume pose onto the Desktop where unlike in the
// Root window it will not be watched by the folder.
pose->TargetModel()->WatchVolumeAndMountPoint(B_WATCH_NAME
| B_WATCH_STAT | B_WATCH_ATTR, this);
}
}
void
BPoseView::CreateRootPose()
{
BEntry entry("/");
Model* model = new Model(&entry);
if (model == NULL || model->InitCheck() != B_OK) {
delete model;
return;
}
PoseInfo info;
ReadPoseInfo(model, &info);
CreatePose(model, &info, true, NULL, NULL, true);
}
void
BPoseView::RemoveRootPose()
{
BEntry entry("/");
node_ref nref;
if (entry.GetNodeRef(&nref) != B_OK)
return;
DeletePose(&nref);
Invalidate();
}
void
BPoseView::CreateTrashPose()
{
@@ -5351,9 +5401,10 @@ BPoseView::FSNotification(const BMessage* message)
&& !targetModel->IsQuery()
&& !targetModel->IsVirtualDirectory()
&& !targetModel->IsRoot()
&& (!settings.ShowDisksIcon() || !IsDesktopView())) {
&& (!settings.ShowDisksIcon() || !IsVolumesRoot())) {
if (count == 0)
break;
createPose = false;
}
@@ -5386,8 +5437,8 @@ BPoseView::FSNotification(const BMessage* message)
createdPath.Length()) == 0) {
if (pathStr[createdPath.Length()] != '/')
break;
StopWatchingParentsOf(fBrokenLinks->ItemAt(i)
->EntryRef());
StopWatchingParentsOf(fBrokenLinks->ItemAt(i)->EntryRef());
watch_node(&itemNode, B_WATCH_DIRECTORY, this);
break;
}
@@ -5463,7 +5514,7 @@ BPoseView::FSNotification(const BMessage* message)
if (targetModel != NULL && targetModel->IsRoot()) {
BVolume volume(device);
if (volume.InitCheck() == B_OK)
CreateVolumePose(&volume, false);
CreateVolumePose(&volume);
} else if (TargetModel()->IsTrash()) {
// add trash items from newly mounted volume
@@ -8390,6 +8441,7 @@ BPoseView::SwitchDir(const entry_ref* newDirRef, AttributeStreamNode* node)
AddTrashPoses();
else
AddPoses(TargetModel());
TargetModel()->CloseNode();
AdoptSystemColors();
+9 -7
View File
@@ -488,7 +488,10 @@ protected:
virtual void CreatePoses(Model**models, PoseInfo* poseInfoArray, int32 count,
BPose** resultingPoses, bool insertionSort = true, int32* lastPoseIndexPointer = 0,
BRect* boundsPointer = 0, bool forceDraw = false);
void CreateVolumePose(BVolume*, bool watchIndividually);
void CreateVolumePose(BVolume*);
virtual void CreateRootPose();
virtual void RemoveRootPose();
void CreateTrashPose();
@@ -502,12 +505,11 @@ protected:
// if <model> is zero, PoseView has other means of iterating
// through all the entries thaat it adds
virtual void AddRootPoses(bool watchIndividually, bool mountShared);
// watchIndividually is used when placing a volume pose onto
// the Desktop where unlike in the Root window it will not be
// watched by the folder representing root. If set, each volume
// will therefore be watched individually
virtual void RemoveRootPoses();
virtual void AddVolumePoses();
virtual void RemoveVolumePoses();
virtual void ToggleDisksVolumes();
virtual bool IsVolumesRoot() const { return IsDesktopView(); };
virtual void AddTrashPoses();
virtual bool DeletePose(const node_ref*, BPose* pose = NULL, int32 index = 0);
+2
View File
@@ -290,6 +290,7 @@ void
TrackerSettings::SetShowDisksIcon(bool enabled)
{
gTrackerState.fShowDisksIcon->SetValue(enabled);
gTrackerState.fMountVolumesOntoDesktop->SetValue(!enabled);
}
@@ -317,6 +318,7 @@ TrackerSettings::MountVolumesOntoDesktop()
void
TrackerSettings::SetMountVolumesOntoDesktop(bool enabled)
{
gTrackerState.fShowDisksIcon->SetValue(!enabled);
gTrackerState.fMountVolumesOntoDesktop->SetValue(enabled);
}