diff --git a/src/add-ons/input_server/filters/shortcut_catcher/Jamfile b/src/add-ons/input_server/filters/shortcut_catcher/Jamfile index 0182b9f8a0..f80ca1d34c 100644 --- a/src/add-ons/input_server/filters/shortcut_catcher/Jamfile +++ b/src/add-ons/input_server/filters/shortcut_catcher/Jamfile @@ -2,6 +2,8 @@ SubDir HAIKU_TOP src add-ons input_server filters shortcut_catcher ; SetSubDirSupportedPlatformsBeOSCompatible ; +UsePrivateHeaders storage ; + # Common files used here and in the app StaticLibrary libshortcuts_shared.a : BitFieldTesters.cpp diff --git a/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.cpp b/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.cpp index 40e6cae197..9d2ad01958 100644 --- a/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.cpp +++ b/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.cpp @@ -14,9 +14,12 @@ #include #include #include +#include #include #include #include +#include +#include #include #include "BitFieldTesters.h" @@ -71,20 +74,19 @@ KeyCommandMap::KeyCommandMap(const char* file) strcpy(fFileName, file); BEntry fileEntry(fFileName); - // TODO: Using a BPathMonitor would be preferable. See discussion linked off - // ticket #6278. - if (!fileEntry.Exists()) - BFile file(fFileName, B_READ_ONLY | B_CREATE_FILE); - - if (fileEntry.InitCheck() == B_NO_ERROR) { - node_ref nref; - if (fileEntry.GetNodeRef(&nref) == B_NO_ERROR) - watch_node(&nref, B_WATCH_STAT, this); + BEntry parent; + BPath parentPath; + if (fileEntry.GetParent(&parent) == B_OK + && parent.GetPath(&parentPath) == B_OK) { + BPrivate::BPathMonitor::StartWatching(parentPath.Path(), + B_WATCH_STAT | B_WATCH_FILES_ONLY, this); } - BMessage msg(FILE_UPDATED); - PostMessage(&msg); + if (fileEntry.InitCheck() == B_NO_ERROR) { + BMessage msg(FILE_UPDATED); + PostMessage(&msg); + } fPort = create_port(1, SHORTCUTS_CATCHER_PORT_NAME); _PutMessageToPort(); @@ -100,7 +102,7 @@ KeyCommandMap::~KeyCommandMap() for (int i = fInjects.CountItems() - 1; i >= 0; i--) delete (BMessage*)fInjects.ItemAt(i); - stop_watching(this); + BPrivate::BPathMonitor::StopWatching(BMessenger(this, this)); // don't know if this is necessary, but it can't hurt _DeleteHKSList(fSpecs); delete [] fFileName; @@ -219,7 +221,21 @@ KeyCommandMap::MessageReceived(BMessage* msg) _PutMessageToPort(); break; - case B_NODE_MONITOR: + case B_PATH_MONITOR: + { + const char* path = ""; + // only fall through for appropriate file + if (!(msg->FindString("path", &path) == B_OK + && strcmp(path, fFileName) == 0)) { + dev_t device; + ino_t node; + if (msg->FindInt32("device", &device) != B_OK + && msg->FindInt64("node", &node) != B_OK + && device != fNodeRef.device + && node != fNodeRef.node) + break; + } + } case FILE_UPDATED: { BMessage fileMsg; @@ -231,6 +247,7 @@ KeyCommandMap::MessageReceived(BMessage* msg) // defaults to no deletion BList* oldList = NULL; + file.GetNodeRef(&fNodeRef); int i = 0; BMessage msg; while (fileMsg.FindMessage("spec", i++, &msg) == B_OK) { @@ -241,6 +258,27 @@ KeyCommandMap::MessageReceived(BMessage* msg) if (msg.FindInt32("key", (int32*) &key) == B_OK && msg.FindMessage("act", &actMsg) == B_OK && msg.FindMessage("modtester", &testerMsg) == B_OK) { + + // Leave handling of add-ons shortcuts to Tracker + BString command; + if (actMsg.FindString("largv", &command) == B_OK) { + BPath path; + if (find_directory(B_SYSTEM_ADDONS_DIRECTORY, &path) == B_OK) { + path.Append("Tracker/"); + if (command.FindFirst(path.Path()) != B_ERROR) + continue; + } + if (find_directory(B_COMMON_ADDONS_DIRECTORY, &path) == B_OK) { + path.Append("Tracker/"); + if (command.FindFirst(path.Path()) != B_ERROR) + continue; + } + if (find_directory(B_USER_ADDONS_DIRECTORY, &path) == B_OK) { + path.Append("Tracker/"); + if (command.FindFirst(path.Path()) != B_ERROR) + continue; + } + } BArchivable* archive = instantiate_object(&testerMsg); if (BitFieldTester* tester = dynamic_cast(archive)) { @@ -282,7 +320,7 @@ KeyCommandMap::_DeleteHKSList(BList* l) if (l != NULL) { int num = l->CountItems(); for (int i = 0; i < num; i++) - delete ((hks*) l->ItemAt(i)); + delete ((hks*) l->ItemAt(0)); delete l; } } diff --git a/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.h b/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.h index b70e7c65a7..9ade3d0b80 100644 --- a/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.h +++ b/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.h @@ -18,6 +18,7 @@ #include #include #include +#include // Maps BMessages to ShortcutsSpecs! // The thread here gets file update messages, and updates @@ -49,6 +50,7 @@ private: port_id fPort; char* fFileName; + node_ref fNodeRef; BLocker fSyncSpecs; // locks the lists below BList fInjects; BList* fSpecs; diff --git a/src/add-ons/input_server/filters/shortcut_catcher/ParseCommandLine.cpp b/src/add-ons/input_server/filters/shortcut_catcher/ParseCommandLine.cpp index b7dbde0d69..c9dfc8c323 100644 --- a/src/add-ons/input_server/filters/shortcut_catcher/ParseCommandLine.cpp +++ b/src/add-ons/input_server/filters/shortcut_catcher/ParseCommandLine.cpp @@ -26,9 +26,10 @@ #include +const char *kTrackerSignature = "application/x-vnd.Be-TRAK"; + // This char is used to hold words together into single words... #define GUNK_CHAR 0x01 -#define PATHTOTRACKER "/system/Tracker" // Turn all spaces that are not-to-be-counted-as-spaces into GUNK_CHAR chars. static void @@ -219,7 +220,6 @@ CloneArgv(char** argv) } - BString ParseArgvZeroFromString(const char* command) { @@ -299,24 +299,22 @@ LaunchCommand(char** argv, int32 argc) // than launch. BDirectory testDir(&entry); if (testDir.InitCheck() == B_NO_ERROR) { - // Hack way to do this--really I should be able to do this by - // sending a BMessage. But how? When I finally get my copy of the - // BeOS Bible, maybe then I'll find out. - BPath trackerPath; - if (find_directory(B_SYSTEM_DIRECTORY, &trackerPath) != B_OK - || trackerPath.Append("Tracker") != B_OK) { - return B_ENTRY_NOT_FOUND; - } - BString cmd(trackerPath.Path()); - cmd << " '" << argv[0] << "'"; - system(cmd.String()); - return B_NO_ERROR; + entry_ref ref; + status_t status = entry.GetRef(&ref); + if (status < B_OK) + return status; + + BMessenger target(kTrackerSignature); + BMessage message(B_REFS_RECEIVED); + message.AddRef("refs", &ref); + + return target.SendMessage(&message); } else { // It's not a directory. Must be a file. entry_ref ref; if (entry.GetRef(&ref) == B_NO_ERROR) { if (argc > 1) - be_roster->Launch(&ref, argc-1, &argv[1]); + be_roster->Launch(&ref, argc - 1, &argv[1]); else be_roster->Launch(&ref); return B_NO_ERROR;