diff --git a/src/kits/tracker/AutoMounter.cpp b/src/kits/tracker/AutoMounter.cpp index 243536103e..b99f719c0a 100644 --- a/src/kits/tracker/AutoMounter.cpp +++ b/src/kits/tracker/AutoMounter.cpp @@ -82,8 +82,7 @@ AutoMounter::AutoMounter() fRemovableMode = kNoVolumes; } - if (PostMessage(kMsgInitialScan) != B_OK) - debug_printf("AutoMounter: OH NO!\n"); + PostMessage(kMsgInitialScan); } @@ -93,7 +92,8 @@ AutoMounter::~AutoMounter() void -AutoMounter::_MountVolumes(mount_mode normal, mount_mode removable) +AutoMounter::_MountVolumes(mount_mode normal, mount_mode removable, + bool initialRescan) { if (normal == kNoVolumes && removable == kNoVolumes) return; @@ -145,7 +145,13 @@ AutoMounter::_MountVolumes(mount_mode normal, mount_mode removable) return false; } - partition->Mount(); + if (partition->Mount() == B_OK) { + // notify Tracker that a new volume has been started + BMessage note(kVolumeMounted); + note.AddString("path", partition->MountedAt()); + note.AddBool("initial rescan", sInitialRescan); + be_app->PostMessage(¬e); + } return false; } @@ -445,7 +451,7 @@ AutoMounter::MessageReceived(BMessage *message) { switch (message->what) { case kMsgInitialScan: - _MountVolumes(fNormalMode, fRemovableMode); + _MountVolumes(fNormalMode, fRemovableMode, true); break; case kMountVolume: @@ -466,12 +472,12 @@ AutoMounter::MessageReceived(BMessage *message) _WriteSettings(); if (rescanNow) - _MountVolumes(fNormalMode, fRemovableMode); + _MountVolumes(fNormalMode, fRemovableMode, false); break; } case kMountAllNow: - _MountVolumes(kAllVolumes, kAllVolumes); + _MountVolumes(kAllVolumes, kAllVolumes, false); break; #if 0 @@ -588,6 +594,7 @@ static const uint32 kStartPolling = 'strp'; static BMessage gSettingsMessage; static bool gSilentAutoMounter; +static bool sInitialRescan; struct OneMountFloppyParams { status_t result; @@ -652,6 +659,13 @@ MountAndWatch(Partition *partition) return status; } + + // notify Tracker that a new volume has been started + BMessage note(kVolumeMounted); + note.AddString("path", partition->MountedAt()); + note.AddBool("initial rescan", sInitialRescan); + be_app->PostMessage(¬e); + return AutoMounterWatchNode(&nodeToWatch, B_WATCH_NAME); } @@ -965,6 +979,7 @@ AutoMounter::AutoMounter(bool checkRemovableOnly, bool checkCDs, if (!BootedInSafeMode()) { ReadSettings(); + sInitialRescan = true; thread_id rescan = spawn_thread(AutoMounter::InitialRescanBinder, "AutomountInitialScan", B_DISPLAY_PRIORITY, this); resume_thread(rescan); @@ -1462,6 +1477,8 @@ AutoMounter::InitialRescan() //+ PRINT(("restoring all volumes\n")); fList.EachMountablePartition(TryMountingRestoreOne, NULL); } + + sInitialRescan = false; } diff --git a/src/kits/tracker/AutoMounter.h b/src/kits/tracker/AutoMounter.h index 0d0eba796f..326f9b73c5 100644 --- a/src/kits/tracker/AutoMounter.h +++ b/src/kits/tracker/AutoMounter.h @@ -48,6 +48,7 @@ namespace BPrivate { const uint32 kMountVolume = 'mntv'; const uint32 kMountAllNow = 'mntn'; const uint32 kSetAutomounterParams = 'pmst'; +const uint32 kVolumeMounted = 'vmtd'; #ifdef __HAIKU__ // #pragma mark - Haiku Disk Device API @@ -69,7 +70,8 @@ class AutoMounter : public BLooper { kRestorePreviousVolumes }; - void _MountVolumes(mount_mode normal, mount_mode removable); + void _MountVolumes(mount_mode normal, mount_mode removable, + bool initialRescan); void _MountVolume(BMessage* message); bool _ForceUnmount(const char* name, status_t error); void _ReportUnmountError(const char* name, status_t error); diff --git a/src/kits/tracker/Tracker.cpp b/src/kits/tracker/Tracker.cpp index 067c5cd73d..5e9463f231 100644 --- a/src/kits/tracker/Tracker.cpp +++ b/src/kits/tracker/Tracker.cpp @@ -390,9 +390,9 @@ TTracker::MessageReceived(BMessage *message) break; case kUnmountVolume: - // When the user attempts to unmount a volume from the mount - // context menu, this is where the message gets received. Save - // pose locations and forward this to the automounter + // When the user attempts to unmount a volume from the mount + // context menu, this is where the message gets received. + // Save pose locations and forward this to the automounter SaveAllPoseLocations(); fAutoMounter->PostMessage(message); break; @@ -401,16 +401,26 @@ TTracker::MessageReceived(BMessage *message) AutomountSettingsDialog::RunAutomountSettings(fAutoMounter); break; - case kShowSplash: - { - // The AboutWindow was moved out of the Tracker in preparation - // for when we open source it. The AboutBox contains important - // credit and license issues that shouldn't be modified, and - // therefore shouldn't be open sourced. However, there is a public - // API for 3rd party apps to tell the Tracker to open the AboutBox. - run_be_about(); + case kVolumeMounted: + { + // This is sent to us by the AutoMounter whenever it mounts + // a new volume - we use it to restore the previously opened + // windows from that volume in case it has been mounted + // during the AutoMounter's initial rescan + const char* path; + bool initial; + if (message->FindBool("initial rescan", &initial) != B_OK + || message->FindString("path", &path) != B_OK + || !initial) break; - } + + _OpenPreviouslyOpenedWindows(path); + break; + } + + case kShowSplash: + run_be_about(); + break; case kAddPrinter: // show the addprinter window @@ -1185,6 +1195,84 @@ TTracker::CloseAllWindows() } +void +TTracker::_OpenPreviouslyOpenedWindows(const char* pathFilter) +{ + size_t filterLength = 0; + if (pathFilter != NULL) + filterLength = strlen(pathFilter); + + BVolume bootVolume; + BVolumeRoster().GetBootVolume(&bootVolume); + BDirectory deskDir; + attr_info attrInfo; + if (FSGetDeskDir(&deskDir, bootVolume.Device()) != B_OK + || deskDir.GetAttrInfo(kAttrOpenWindows, &attrInfo) != B_OK) + return; + + char *buffer = (char *)malloc((size_t)attrInfo.size); + BMessage message; + if (deskDir.ReadAttr(kAttrOpenWindows, B_MESSAGE_TYPE, 0, buffer, + (size_t)attrInfo.size) != attrInfo.size + || message.Unflatten(buffer) != B_OK) { + free(buffer); + return; + } + + free(buffer); + + node_ref nodeRef; + deskDir.GetNodeRef(&nodeRef); + + int32 stateMessageCounter = 0; + const char *path; + for (int32 i = 0; message.FindString("paths", i, &path) == B_OK; i++) { + if (strncmp(path, pathFilter, filterLength)) + continue; + + BEntry entry(path, true); + if (entry.InitCheck() != B_OK) + continue; + + int8 flags = 0; + for (int32 j = 0; message.FindInt8(path, j, &flags) == B_OK; j++) { + Model *model = new Model(&entry); + if (model->InitCheck() == B_OK && model->IsContainer()) { + BMessage state; + bool restoreStateFromMessage = false; + if ((flags & kOpenWindowHasState) != 0 + && message.FindMessage("window state", stateMessageCounter++, + &state) == B_OK) + restoreStateFromMessage = true; + + if (restoreStateFromMessage) { + OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace + | (flags & kOpenWindowMinimized ? kIsHidden : 0U) + | kRestoreDecor, false, &state); + } else { + OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace + | (flags & kOpenWindowMinimized ? kIsHidden : 0U) + | kRestoreDecor); + } + } else + delete model; + } + } + + // Open disks window if needed + + if (pathFilter == NULL && TrackerSettings().ShowDisksIcon() + && message.HasBool("open_disks_window")) { + BEntry entry("/"); + Model* model = new Model(&entry); + if (model->InitCheck() == B_OK) + OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace); + else + delete model; + } +} + + void TTracker::ReadyToRun() { @@ -1206,14 +1294,12 @@ TTracker::ReadyToRun() fTaskLoop = new StandAloneTaskLoop(true); - bool openDisksWindow = false; - // open desktop window BContainerWindow *deskWindow = NULL; - BVolume bootVol; - BVolumeRoster().GetBootVolume(&bootVol); + BVolume bootVolume; + BVolumeRoster().GetBootVolume(&bootVolume); BDirectory deskDir; - if (FSGetDeskDir(&deskDir, bootVol.Device()) == B_OK) { + if (FSGetDeskDir(&deskDir, bootVolume.Device()) == B_OK) { // create desktop BEntry entry; deskDir.GetEntry(&entry); @@ -1224,86 +1310,38 @@ TTracker::ReadyToRun() AutoLock windowLock(deskWindow); deskWindow->CreatePoseView(model); deskWindow->Init(); + + if (TrackerSettings().ShowDisksIcon()) { + // create model for root of everything + BEntry entry("/"); + Model model(&entry); + if (model.InitCheck() == B_OK) { + // add the root icon to desktop window + BMessage message; + message.what = B_NODE_MONITOR; + message.AddInt32("opcode", B_ENTRY_CREATED); + message.AddInt32("device", model.NodeRef()->device); + message.AddInt64("node", model.NodeRef()->node); + message.AddInt64("directory", model.EntryRef()->directory); + message.AddString("name", model.EntryRef()->name); + deskWindow->PostMessage(&message, deskWindow->PoseView()); + } + } } else delete model; // open previously open windows - attr_info attrInfo; - if (!BootedInSafeMode() - && deskDir.GetAttrInfo(kAttrOpenWindows, &attrInfo) == B_OK) { - char *buffer = (char *)malloc((size_t)attrInfo.size); - BMessage message; - if (deskDir.ReadAttr(kAttrOpenWindows, B_MESSAGE_TYPE, 0, buffer, (size_t)attrInfo.size) - == attrInfo.size - && message.Unflatten(buffer) == B_OK) { - - node_ref nodeRef; - deskDir.GetNodeRef(&nodeRef); - - int32 stateMessageCounter = 0; - const char *path; - for (int32 outer = 0;message.FindString("paths", outer, &path) == B_OK;outer++) { - int8 flags = 0; - for (int32 inner = 0;message.FindInt8(path, inner, &flags) == B_OK;inner++) { - BEntry entry(path, true); - if (entry.InitCheck() == B_OK) { - Model *model = new Model(&entry); - if (model->InitCheck() == B_OK && model->IsContainer()) { - BMessage state; - bool restoreStateFromMessage = false; - if ((flags & kOpenWindowHasState) != 0 - && message.FindMessage("window state", stateMessageCounter++, &state) == B_OK) - restoreStateFromMessage = true; - - if (restoreStateFromMessage) - OpenContainerWindow(model, 0, kOpen, - kRestoreWorkspace | (flags & kOpenWindowMinimized ? kIsHidden : 0U) | kRestoreDecor, - false, &state); - else - OpenContainerWindow(model, 0, kOpen, - kRestoreWorkspace | (flags & kOpenWindowMinimized ? kIsHidden : 0U) | kRestoreDecor); - } else - delete model; - } - } - } - - if (message.HasBool("open_disks_window")) - openDisksWindow = true; - } - free(buffer); - } - } - - // create model for root of everything - if (deskWindow) { - BEntry entry("/"); - Model model(&entry); - if (model.InitCheck() == B_OK) { - - if (TrackerSettings().ShowDisksIcon()) { - // add the root icon to desktop window - BMessage message; - message.what = B_NODE_MONITOR; - message.AddInt32("opcode", B_ENTRY_CREATED); - message.AddInt32("device", model.NodeRef()->device); - message.AddInt64("node", model.NodeRef()->node); - message.AddInt64("directory", model.EntryRef()->directory); - message.AddString("name", model.EntryRef()->name); - deskWindow->PostMessage(&message, deskWindow->PoseView()); - } - - if (openDisksWindow) - OpenContainerWindow(new Model(model), 0, kOpen, kRestoreWorkspace); - } + if (!BootedInSafeMode()) + _OpenPreviouslyOpenedWindows(); } // kick off building the mime type list for find panels, etc. fMimeTypeList = new MimeTypeList(); - if (!BootedInSafeMode()) + if (!BootedInSafeMode()) { // kick of transient query killer DeleteTransientQueriesTask::StartUpTransientQueryCleaner(); + } } MimeTypeList * diff --git a/src/kits/tracker/Tracker.h b/src/kits/tracker/Tracker.h index d9a462367f..c4f5eac148 100644 --- a/src/kits/tracker/Tracker.h +++ b/src/kits/tracker/Tracker.h @@ -198,6 +198,7 @@ class TTracker : public BApplication { OpenSelector openSelector = kOpen, uint32 openFlags = 0, bool checkAlreadyOpen = true, const BMessage *stateMessage = NULL); // pass either a Model or a list of entries to open + void _OpenPreviouslyOpenedWindows(const char* pathFilter = NULL); void SetDefaultPrinter(const BMessage *); void EditQueries(const BMessage *);