Shortcut add-on: change to accomodate tracker add-ons

* Ignore shortcuts regardings tracker add-ons. Its settings file is now shared
with Tracker, and those are now handled by Tracker.
* Use a BPathMonitor as specified in a TODO to check the presence and changes on
the settings file. (#6278)
* Use a message to ask Tracker to launch/open folders as specified in TODO
This commit is contained in:
Philippe Saint-Pierre
2013-07-11 12:38:41 -04:00
parent 56ea7a1e19
commit 1412a36abc
4 changed files with 69 additions and 29 deletions
@@ -2,6 +2,8 @@ SubDir HAIKU_TOP src add-ons input_server filters shortcut_catcher ;
SetSubDirSupportedPlatformsBeOSCompatible ; SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders storage ;
# Common files used here and in the app # Common files used here and in the app
StaticLibrary libshortcuts_shared.a : StaticLibrary libshortcuts_shared.a :
BitFieldTesters.cpp BitFieldTesters.cpp
@@ -14,9 +14,12 @@
#include <Beep.h> #include <Beep.h>
#include <Entry.h> #include <Entry.h>
#include <File.h> #include <File.h>
#include <FindDirectory.h>
#include <MessageFilter.h> #include <MessageFilter.h>
#include <NodeMonitor.h> #include <NodeMonitor.h>
#include <OS.h> #include <OS.h>
#include <Path.h>
#include <PathMonitor.h>
#include <WindowScreen.h> #include <WindowScreen.h>
#include "BitFieldTesters.h" #include "BitFieldTesters.h"
@@ -71,20 +74,19 @@ KeyCommandMap::KeyCommandMap(const char* file)
strcpy(fFileName, file); strcpy(fFileName, file);
BEntry fileEntry(fFileName); 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) { BEntry parent;
node_ref nref; BPath parentPath;
if (fileEntry.GetParent(&parent) == B_OK
if (fileEntry.GetNodeRef(&nref) == B_NO_ERROR) && parent.GetPath(&parentPath) == B_OK) {
watch_node(&nref, B_WATCH_STAT, this); BPrivate::BPathMonitor::StartWatching(parentPath.Path(),
B_WATCH_STAT | B_WATCH_FILES_ONLY, this);
} }
BMessage msg(FILE_UPDATED); if (fileEntry.InitCheck() == B_NO_ERROR) {
PostMessage(&msg); BMessage msg(FILE_UPDATED);
PostMessage(&msg);
}
fPort = create_port(1, SHORTCUTS_CATCHER_PORT_NAME); fPort = create_port(1, SHORTCUTS_CATCHER_PORT_NAME);
_PutMessageToPort(); _PutMessageToPort();
@@ -100,7 +102,7 @@ KeyCommandMap::~KeyCommandMap()
for (int i = fInjects.CountItems() - 1; i >= 0; i--) for (int i = fInjects.CountItems() - 1; i >= 0; i--)
delete (BMessage*)fInjects.ItemAt(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 // don't know if this is necessary, but it can't hurt
_DeleteHKSList(fSpecs); _DeleteHKSList(fSpecs);
delete [] fFileName; delete [] fFileName;
@@ -219,7 +221,21 @@ KeyCommandMap::MessageReceived(BMessage* msg)
_PutMessageToPort(); _PutMessageToPort();
break; 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: case FILE_UPDATED:
{ {
BMessage fileMsg; BMessage fileMsg;
@@ -231,6 +247,7 @@ KeyCommandMap::MessageReceived(BMessage* msg)
// defaults to no deletion // defaults to no deletion
BList* oldList = NULL; BList* oldList = NULL;
file.GetNodeRef(&fNodeRef);
int i = 0; int i = 0;
BMessage msg; BMessage msg;
while (fileMsg.FindMessage("spec", i++, &msg) == B_OK) { while (fileMsg.FindMessage("spec", i++, &msg) == B_OK) {
@@ -241,6 +258,27 @@ KeyCommandMap::MessageReceived(BMessage* msg)
if (msg.FindInt32("key", (int32*) &key) == B_OK if (msg.FindInt32("key", (int32*) &key) == B_OK
&& msg.FindMessage("act", &actMsg) == B_OK && msg.FindMessage("act", &actMsg) == B_OK
&& msg.FindMessage("modtester", &testerMsg) == 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); BArchivable* archive = instantiate_object(&testerMsg);
if (BitFieldTester* tester if (BitFieldTester* tester
= dynamic_cast<BitFieldTester*>(archive)) { = dynamic_cast<BitFieldTester*>(archive)) {
@@ -282,7 +320,7 @@ KeyCommandMap::_DeleteHKSList(BList* l)
if (l != NULL) { if (l != NULL) {
int num = l->CountItems(); int num = l->CountItems();
for (int i = 0; i < num; i++) for (int i = 0; i < num; i++)
delete ((hks*) l->ItemAt(i)); delete ((hks*) l->ItemAt(0));
delete l; delete l;
} }
} }
@@ -18,6 +18,7 @@
#include <Messenger.h> #include <Messenger.h>
#include <Message.h> #include <Message.h>
#include <MessageFilter.h> #include <MessageFilter.h>
#include <Node.h>
// Maps BMessages to ShortcutsSpecs! // Maps BMessages to ShortcutsSpecs!
// The thread here gets file update messages, and updates // The thread here gets file update messages, and updates
@@ -49,6 +50,7 @@ private:
port_id fPort; port_id fPort;
char* fFileName; char* fFileName;
node_ref fNodeRef;
BLocker fSyncSpecs; // locks the lists below BLocker fSyncSpecs; // locks the lists below
BList fInjects; BList fInjects;
BList* fSpecs; BList* fSpecs;
@@ -26,9 +26,10 @@
#include <SupportKit.h> #include <SupportKit.h>
const char *kTrackerSignature = "application/x-vnd.Be-TRAK";
// This char is used to hold words together into single words... // This char is used to hold words together into single words...
#define GUNK_CHAR 0x01 #define GUNK_CHAR 0x01
#define PATHTOTRACKER "/system/Tracker"
// Turn all spaces that are not-to-be-counted-as-spaces into GUNK_CHAR chars. // Turn all spaces that are not-to-be-counted-as-spaces into GUNK_CHAR chars.
static void static void
@@ -219,7 +220,6 @@ CloneArgv(char** argv)
} }
BString BString
ParseArgvZeroFromString(const char* command) ParseArgvZeroFromString(const char* command)
{ {
@@ -299,24 +299,22 @@ LaunchCommand(char** argv, int32 argc)
// than launch. // than launch.
BDirectory testDir(&entry); BDirectory testDir(&entry);
if (testDir.InitCheck() == B_NO_ERROR) { if (testDir.InitCheck() == B_NO_ERROR) {
// Hack way to do this--really I should be able to do this by entry_ref ref;
// sending a BMessage. But how? When I finally get my copy of the status_t status = entry.GetRef(&ref);
// BeOS Bible, maybe then I'll find out. if (status < B_OK)
BPath trackerPath; return status;
if (find_directory(B_SYSTEM_DIRECTORY, &trackerPath) != B_OK
|| trackerPath.Append("Tracker") != B_OK) { BMessenger target(kTrackerSignature);
return B_ENTRY_NOT_FOUND; BMessage message(B_REFS_RECEIVED);
} message.AddRef("refs", &ref);
BString cmd(trackerPath.Path());
cmd << " '" << argv[0] << "'"; return target.SendMessage(&message);
system(cmd.String());
return B_NO_ERROR;
} else { } else {
// It's not a directory. Must be a file. // It's not a directory. Must be a file.
entry_ref ref; entry_ref ref;
if (entry.GetRef(&ref) == B_NO_ERROR) { if (entry.GetRef(&ref) == B_NO_ERROR) {
if (argc > 1) if (argc > 1)
be_roster->Launch(&ref, argc-1, &argv[1]); be_roster->Launch(&ref, argc - 1, &argv[1]);
else else
be_roster->Launch(&ref); be_roster->Launch(&ref);
return B_NO_ERROR; return B_NO_ERROR;