Author: anevilyak Date: 2011-10-30 17:52:03 +0100 (Sun, 30 Oct 2011) New Revision: 43004 Changeset: https://dev.haiku-os.org/changeset/43004 Modified: haiku/trunk/src/apps/deskbar/BarView.cpp haiku/trunk/src/apps/deskbar/BarView.h haiku/trunk/src/apps/deskbar/BarWindow.cpp haiku/trunk/src/apps/deskbar/StatusView.cpp haiku/trunk/src/apps/deskbar/StatusView.h Log: Rework Deskbar's tray replicant support a bit. Instead of relying on a live query for be:deskbar_item_status in order to determine which replicants are supposed to be living in the tray, a list of entry refs is now stored. While the former approach was cool, it doesn't really work in either a multiuser or a package-aware world, where executables are generally read-only. Note this means you'll lose your existing replicants the first time you run this new revision, and need to re-add them. Modified: haiku/trunk/src/apps/deskbar/BarView.cpp =================================================================== --- haiku/trunk/src/apps/deskbar/BarView.cpp 2011-10-30 16:41:57 UTC (rev 43003) +++ haiku/trunk/src/apps/deskbar/BarView.cpp 2011-10-30 16:52:03 UTC (rev 43004) @@ -1028,6 +1028,13 @@ } +status_t +TBarView::AddItem(BEntry* entry, DeskbarShelf, int32* id) +{ + return fReplicantTray->LoadAddOn(entry, id); +} + + void TBarView::RemoveItem(int32 id) { Modified: haiku/trunk/src/apps/deskbar/BarView.h =================================================================== --- haiku/trunk/src/apps/deskbar/BarView.h 2011-10-30 16:41:57 UTC (rev 43003) +++ haiku/trunk/src/apps/deskbar/BarView.h 2011-10-30 16:52:03 UTC (rev 43004) @@ -125,6 +125,7 @@ int32 CountItems(DeskbarShelf shelf); status_t AddItem(BMessage* archive, DeskbarShelf shelf, int32* id); + status_t AddItem(BEntry* entry, DeskbarShelf shelf, int32* id); void RemoveItem(int32 id); void RemoveItem(const char* name, DeskbarShelf shelf); Modified: haiku/trunk/src/apps/deskbar/BarWindow.cpp =================================================================== --- haiku/trunk/src/apps/deskbar/BarWindow.cpp 2011-10-30 16:41:57 UTC (rev 43003) +++ haiku/trunk/src/apps/deskbar/BarWindow.cpp 2011-10-30 16:52:03 UTC (rev 43004) @@ -518,7 +518,7 @@ void TBarWindow::AddItem(BMessage* message) { - DeskbarShelf shelf; + DeskbarShelf shelf = B_DESKBAR_TRAY; entry_ref ref; int32 id = 999; BMessage reply; @@ -527,24 +527,17 @@ BMessage archivedView; if (message->FindMessage("view", &archivedView) == B_OK) { #if SHELF_AWARE - if (message->FindInt32("shelf", (int32*)&shelf) != B_OK) + message->FindInt32("shelf", &shelf); #endif - shelf = B_DESKBAR_TRAY; - BMessage* archive = new BMessage(archivedView); err = fBarView->AddItem(archive, shelf, &id); if (err < B_OK) delete archive; } else if (message->FindRef("addon", &ref) == B_OK) { - // exposing the name of the view here is not so great - TReplicantTray* tray - = dynamic_cast<TReplicantTray*>(FindView("Status")); - if (tray) { - // Force this into the deskbar even if the security code is wrong - // This is OK because the user specifically asked for this replicant - BEntry entry(&ref); - err = tray->LoadAddOn(&entry, &id, true); - } + BEntry entry(&ref); + err = entry.InitCheck(); + if (err == B_OK) + err = fBarView->AddItem(&entry, shelf, &id); } if (err == B_OK) Modified: haiku/trunk/src/apps/deskbar/StatusView.cpp =================================================================== --- haiku/trunk/src/apps/deskbar/StatusView.cpp 2011-10-30 16:41:57 UTC (rev 43003) +++ haiku/trunk/src/apps/deskbar/StatusView.cpp 2011-10-30 16:52:03 UTC (rev 43004) @@ -83,11 +83,8 @@ const char* const kInstantiateItemCFunctionName = "instantiate_deskbar_item"; const char* const kInstantiateEntryCFunctionName = "instantiate_deskbar_entry"; -const char* const kDeskbarSecurityCodeFile = "Deskbar_security_code"; -const char* const kDeskbarSecurityCodeAttr = "be:deskbar_security_code"; -const char* const kStatusPredicate = "be:deskbar_item_status"; -const char* const kEnabledPredicate = "be:deskbar_item_status = enabled"; -const char* const kDisabledPredicate = "be:deskbar_item_status = disabled"; +const char* const kReplicantSettingsFile = "Deskbar_replicants"; +const char* const kReplicantRefField = "replicant"; float sMinimumWindowWidth = kGutter + kMinimumTrayWidth + kDragRegionWidth; @@ -331,7 +328,6 @@ #ifdef DB_ADDONS case B_NODE_MONITOR: - case B_QUERY_UPDATE: HandleEntryUpdate(message); break; #endif @@ -410,53 +406,48 @@ { // list to maintain refs to each rep added/deleted fItemList = new BList(); - bool haveKey = false; BPath path; if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, true) == B_OK) { - path.Append(kDeskbarSecurityCodeFile); + path.Append(kReplicantSettingsFile); BFile file(path.Path(), B_READ_ONLY); - if (file.InitCheck() == B_OK - && file.Read(&fDeskbarSecurityCode, sizeof(fDeskbarSecurityCode)) - == sizeof(fDeskbarSecurityCode)) - haveKey = true; - } - if (!haveKey) { - // create the security code - bigtime_t real = real_time_clock_usecs(); - bigtime_t boot = system_time(); - // two computers would have to have exactly matching clocks, and launch - // Deskbar at the exact same time into the bootsequence in order for - // their security-ID to be identical - fDeskbarSecurityCode = ((real & 0xffffffffULL) << 32) - | (boot & 0xffffffffULL); - - if (find_directory (B_USER_SETTINGS_DIRECTORY, &path, true) == B_OK) { - path.Append(kDeskbarSecurityCodeFile); - BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE - | B_ERASE_FILE); - if (file.InitCheck() == B_OK) - file.Write(&fDeskbarSecurityCode, sizeof(fDeskbarSecurityCode)); + if (file.InitCheck() == B_OK) { + entry_ref ref; + status_t result; + BEntry entry; + int32 id; + if (fAddOnSettings.Unflatten(&file) == B_OK) { + for (int32 i = 0; fAddOnSettings.FindRef(kReplicantRefField, + i, &ref) == B_OK; i++) { + if (entry.SetTo(&ref) == B_OK && entry.Exists()) { + result = LoadAddOn(&entry, &id, false); + } else + result = B_ENTRY_NOT_FOUND; + + if (result != B_OK) { + fAddOnSettings.RemoveData(kReplicantRefField, i); + --i; + } + } + } } } - - // for each volume currently mounted index the volume with our indices - BVolumeRoster roster; - BVolume volume; - while (roster.GetNextVolume(&volume) == B_OK) { - fs_create_index(volume.Device(), kStatusPredicate, B_STRING_TYPE, 0); - RunAddOnQuery(&volume, kEnabledPredicate); - } - - // we also watch for volumes mounted and unmounted - watch_node(NULL, B_WATCH_MOUNT | B_WATCH_ATTR, this, Window()); } void TReplicantTray::DeleteAddOnSupport() { + BPath path; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, true) == B_OK) { + path.Append(kReplicantSettingsFile); + + BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); + if (file.InitCheck() == B_OK) + fAddOnSettings.Flatten(&file); + } + for (int32 i = fItemList->CountItems(); i-- > 0 ;) { DeskbarItemInfo* item = (DeskbarItemInfo*)fItemList->RemoveItem(i); if (item) { @@ -473,47 +464,6 @@ } -void -TReplicantTray::RunAddOnQuery(BVolume* volume, const char* predicate) -{ - // Since the new BFS supports querying for attributes without - // an index, we only run the query if the index exists (for - // newly mounted devices only - the Deskbar will automatically - // create an index for every device mounted at startup). - index_info info; - if (!volume->KnowsQuery() - || fs_stat_index(volume->Device(), kStatusPredicate, &info) != 0) - return; - - // run a new query on a specific volume and make it live - BQuery query; - query.SetVolume(volume); - query.SetPredicate(predicate); - query.Fetch(); - - int32 id; - BEntry entry; - while (query.GetNextEntry(&entry) == B_OK) { - // scan any entries returned - // attempt to load them as add-ons - // collisions are handled in LoadAddOn - LoadAddOn(&entry, &id); - } -} - - -bool -TReplicantTray::IsAddOn(entry_ref& ref) -{ - BFile file(&ref, B_READ_ONLY); - - char status[64]; - ssize_t size = file.ReadAttr(kStatusPredicate, B_STRING_TYPE, 0, &status, - sizeof(status)); - return size > 0; -} - - DeskbarItemInfo* TReplicantTray::DeskbarItemFor(node_ref& nodeRef) { @@ -565,61 +515,6 @@ BPath path; switch (opcode) { - case B_ENTRY_CREATED: - { - // entry was just listed, matches live query - const char* name; - ino_t directory; - dev_t device; - // received when an app adds a ref to the - // Deskbar add-ons folder - if (message->FindString("name", &name) == B_OK - && message->FindInt64("directory", &directory) == B_OK - && message->FindInt32("device", &device) == B_OK) { - entry_ref ref(device, directory, name); - // see if this item has the attribute - // that we expect - if (IsAddOn(ref)) { - int32 id; - BEntry entry(&ref); - LoadAddOn(&entry, &id); - } - } - break; - } - - case B_ATTR_CHANGED: - { - // from node watch on individual items - // (node_watch added in LoadAddOn) - node_ref nodeRef; - if (message->FindInt32("device", &(nodeRef.device)) == B_OK - && message->FindInt64("node", &(nodeRef.node)) == B_OK) { - // get the add-on this is for - DeskbarItemInfo* item = DeskbarItemFor(nodeRef); - if (item == NULL) - break; - - BFile file(&item->entryRef, B_READ_ONLY); - - char status[255]; - ssize_t size = file.ReadAttr(kStatusPredicate, - B_STRING_TYPE, 0, status, sizeof(status) - 1); - status[sizeof(status) - 1] = '\0'; - - // attribute was removed - if (size == B_ENTRY_NOT_FOUND) { - // cleans up and removes node_watch - UnloadAddOn(&nodeRef, NULL, true, false); - } else if (!strcmp(status, "enable")) { - int32 id; - BEntry entry(&item->entryRef, true); - LoadAddOn(&entry, &id); - } - } - break; - } - case B_ENTRY_MOVED: { entry_ref ref; @@ -663,32 +558,6 @@ } break; } - - case B_DEVICE_MOUNTED: - { - // run a new query on the new device - dev_t device; - if (message->FindInt32("new device", &device) != B_OK) - break; - - BVolume volume(device); - RunAddOnQuery(&volume, kEnabledPredicate); - break; - } - - case B_DEVICE_UNMOUNTED: - { - // remove all items associated with the device - // unmounted - // contrary to what the BeBook says, the item is called "device", - // not "new device" like it is for B_DEVICE_MOUNTED - dev_t device; - if (message->FindInt32("device", &device) != B_OK) - break; - - UnloadAddOn(NULL, &device, false, true); - break; - } } } @@ -698,7 +567,7 @@ primary function is the Instantiate function */ status_t -TReplicantTray::LoadAddOn(BEntry* entry, int32* id, bool force) +TReplicantTray::LoadAddOn(BEntry* entry, int32* id, bool addToSettings) { if (!entry) return B_ERROR; @@ -710,21 +579,6 @@ return B_ERROR; BNode node(entry); - if (!force) { - status_t error = node.InitCheck(); - if (error != B_OK) - return error; - - uint64 deskbarID; - ssize_t size = node.ReadAttr(kDeskbarSecurityCodeAttr, B_UINT64_TYPE, - 0, &deskbarID, sizeof(fDeskbarSecurityCode)); - if (size != sizeof(fDeskbarSecurityCode) - || deskbarID != fDeskbarSecurityCode) { - // no code or code doesn't match - return B_ERROR; - } - } - BPath path; status_t status = entry->GetPath(&path); if (status < B_OK) @@ -770,9 +624,12 @@ AddIcon(data, id, &ref); // add the rep; adds info to list - node.WriteAttr(kDeskbarSecurityCodeAttr, B_UINT64_TYPE, 0, - &fDeskbarSecurityCode, sizeof(fDeskbarSecurityCode)); - + if (addToSettings) { + entry_ref ref; + if (entry->GetRef(&ref) == B_OK) + fAddOnSettings.AddRef(kReplicantRefField, &ref); + } + return B_OK; } @@ -841,7 +698,6 @@ // attribute was added via Deskbar API (AddItem(entry_ref*, int32*) if (item->isAddOn) { BNode node(&item->entryRef); - node.RemoveAttr(kStatusPredicate); watch_node(&item->nodeRef, B_STOP_WATCHING, this, Window()); } Modified: haiku/trunk/src/apps/deskbar/StatusView.h =================================================================== --- haiku/trunk/src/apps/deskbar/StatusView.h 2011-10-30 16:41:57 UTC (rev 43003) +++ haiku/trunk/src/apps/deskbar/StatusView.h 2011-10-30 16:52:03 UTC (rev 43004) @@ -117,7 +117,7 @@ void DealWithClock(bool); #ifdef DB_ADDONS - status_t LoadAddOn(BEntry* entry, int32* id, bool force = false); + status_t LoadAddOn(BEntry* entry, int32* id, bool addToSettings = true); #endif private: @@ -129,9 +129,7 @@ #ifdef DB_ADDONS void InitAddOnSupport(); void DeleteAddOnSupport(); - void RunAddOnQuery(BVolume* volume, const char* predicated); - bool IsAddOn(entry_ref &ref); DeskbarItemInfo* DeskbarItemFor(node_ref &nodeRef); DeskbarItemInfo* DeskbarItemFor(int32 id); bool NodeExists(node_ref &nodeRef); @@ -162,7 +160,7 @@ bool fAlignmentSupport; #ifdef DB_ADDONS BList* fItemList; - uint64 fDeskbarSecurityCode; + BMessage fAddOnSettings; #endif };