* Fixed a possible endless loop: when the calling team should receive the B_REFS_RECEIVED
message, we no longer send a message. This seems to be what BeOS does, and it prevents Tracker from playing ping-pong when trying opening generic files. * Eliminated superfluous otherTeam & targetTeam variables in _LaunchApp(). * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16564 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+55
-38
@@ -1724,27 +1724,36 @@ BRoster::_RemoveApp(team_id team) const
|
|||||||
status_t
|
status_t
|
||||||
BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
|
BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
|
||||||
const BList *messageList, int argc,
|
const BList *messageList, int argc,
|
||||||
const char *const *args, team_id *appTeam) const
|
const char *const *args, team_id *_appTeam) const
|
||||||
{
|
{
|
||||||
DBG(OUT("BRoster::xLaunchAppPrivate()"));
|
DBG(OUT("BRoster::_LaunchApp()"));
|
||||||
status_t error = (mimeType || ref ? B_OK : B_BAD_VALUE);
|
|
||||||
|
if (_appTeam != NULL) {
|
||||||
|
// we're supposed to set _appTeam to -1 on error; we'll
|
||||||
|
// reset it later if everything goes well
|
||||||
|
*_appTeam = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mimeType == NULL && ref == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// use a mutable copy of the document entry_ref
|
// use a mutable copy of the document entry_ref
|
||||||
entry_ref _docRef;
|
entry_ref _docRef;
|
||||||
entry_ref *docRef = NULL;
|
entry_ref *docRef = NULL;
|
||||||
if (error == B_OK && ref) {
|
if (ref != NULL) {
|
||||||
_docRef = *ref;
|
_docRef = *ref;
|
||||||
docRef = &_docRef;
|
docRef = &_docRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the app
|
// find the app
|
||||||
entry_ref appRef;
|
entry_ref appRef;
|
||||||
char signature[B_MIME_TYPE_LENGTH];
|
char signature[B_MIME_TYPE_LENGTH];
|
||||||
uint32 appFlags = B_REG_DEFAULT_APP_FLAGS;
|
uint32 appFlags = B_REG_DEFAULT_APP_FLAGS;
|
||||||
bool wasDocument = true;
|
bool wasDocument = true;
|
||||||
if (error == B_OK) {
|
status_t error = _ResolveApp(mimeType, docRef, &appRef, signature, &appFlags,
|
||||||
error = _ResolveApp(mimeType, docRef, &appRef, signature, &appFlags,
|
|
||||||
&wasDocument);
|
&wasDocument);
|
||||||
}
|
|
||||||
DBG(OUT(" find app: %s (%lx)\n", strerror(error), error));
|
DBG(OUT(" find app: %s (%lx)\n", strerror(error), error));
|
||||||
|
|
||||||
// build an argument vector
|
// build an argument vector
|
||||||
ArgVector argVector;
|
ArgVector argVector;
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
@@ -1752,27 +1761,28 @@ BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
|
|||||||
(wasDocument ? docRef : NULL));
|
(wasDocument ? docRef : NULL));
|
||||||
}
|
}
|
||||||
DBG(OUT(" build argv: %s (%lx)\n", strerror(error), error));
|
DBG(OUT(" build argv: %s (%lx)\n", strerror(error), error));
|
||||||
|
|
||||||
// pre-register the app
|
// pre-register the app
|
||||||
app_info appInfo;
|
app_info appInfo;
|
||||||
bool alreadyRunning = false;
|
bool alreadyRunning = false;
|
||||||
uint32 appToken = 0;
|
uint32 appToken = 0;
|
||||||
team_id otherTeam = -1;
|
team_id team = -1;
|
||||||
uint32 otherAppFlags = B_REG_DEFAULT_APP_FLAGS;
|
uint32 otherAppFlags = B_REG_DEFAULT_APP_FLAGS;
|
||||||
if (error == B_OK && !alreadyRunning) {
|
if (error == B_OK && !alreadyRunning) {
|
||||||
error = _AddApplication(signature, &appRef, appFlags, -1, -1, -1, false,
|
error = _AddApplication(signature, &appRef, appFlags, -1, -1, -1, false,
|
||||||
&appToken, &otherTeam);
|
&appToken, &team);
|
||||||
if (error == B_ALREADY_RUNNING) {
|
if (error == B_ALREADY_RUNNING) {
|
||||||
DBG(OUT(" already running\n"));
|
DBG(OUT(" already running\n"));
|
||||||
alreadyRunning = true;
|
alreadyRunning = true;
|
||||||
error = B_OK;
|
error = B_OK;
|
||||||
// get the app flags for the running application
|
// get the app flags for the running application
|
||||||
if (GetRunningAppInfo(otherTeam, &appInfo) == B_OK)
|
if (GetRunningAppInfo(team, &appInfo) == B_OK)
|
||||||
otherAppFlags = appInfo.flags;
|
otherAppFlags = appInfo.flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBG(OUT(" pre-register: %s (%lx)\n", strerror(error), error));
|
DBG(OUT(" pre-register: %s (%lx)\n", strerror(error), error));
|
||||||
|
|
||||||
// launch the app
|
// launch the app
|
||||||
team_id team = -1;
|
|
||||||
if (error == B_OK && !alreadyRunning) {
|
if (error == B_OK && !alreadyRunning) {
|
||||||
DBG(OUT(" token: %lu\n", appToken));
|
DBG(OUT(" token: %lu\n", appToken));
|
||||||
// load the app image
|
// load the app image
|
||||||
@@ -1810,10 +1820,14 @@ BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alreadyRunning && current_team() == team) {
|
||||||
|
// The target team is calling us, so we don't send it the message
|
||||||
|
// to prevent an endless loop
|
||||||
|
error = B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
// send "on launch" messages
|
// send "on launch" messages
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
// the messages go to the launched team or to the already running one
|
|
||||||
team_id targetTeam = (alreadyRunning ? otherTeam : team);
|
|
||||||
// If the target app is B_ARGV_ONLY almost no messages are sent to it.
|
// If the target app is B_ARGV_ONLY almost no messages are sent to it.
|
||||||
// More precisely, the launched app gets at least B_ARGV_RECEIVED and
|
// More precisely, the launched app gets at least B_ARGV_RECEIVED and
|
||||||
// B_READY_TO_RUN, an already running app gets nothing.
|
// B_READY_TO_RUN, an already running app gets nothing.
|
||||||
@@ -1822,19 +1836,21 @@ BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
|
|||||||
const BList *_messageList = (argvOnly ? NULL : messageList);
|
const BList *_messageList = (argvOnly ? NULL : messageList);
|
||||||
// don't send ref, if it refers to the app or is included in the
|
// don't send ref, if it refers to the app or is included in the
|
||||||
// argument vector
|
// argument vector
|
||||||
const entry_ref *_ref = (argvOnly || !wasDocument
|
const entry_ref *_ref = argvOnly || !wasDocument
|
||||||
|| argVector.Count() > 1 ? NULL : docRef);
|
|| argVector.Count() > 1 ? NULL : docRef;
|
||||||
if (!(argvOnly && alreadyRunning)) {
|
if (!(argvOnly && alreadyRunning)) {
|
||||||
_SendToRunning(targetTeam, argVector.Count(), argVector.Args(),
|
_SendToRunning(team, argVector.Count(), argVector.Args(),
|
||||||
_messageList, _ref, !alreadyRunning);
|
_messageList, _ref, !alreadyRunning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set return values
|
// set return values
|
||||||
if (error == B_OK && alreadyRunning)
|
if (error == B_OK) {
|
||||||
error = B_ALREADY_RUNNING;
|
if (alreadyRunning)
|
||||||
if (appTeam)
|
error = B_ALREADY_RUNNING;
|
||||||
*appTeam = (error == B_OK ? team : -1);
|
else if (_appTeam)
|
||||||
|
*_appTeam = team;
|
||||||
|
}
|
||||||
|
|
||||||
DBG(OUT("BRoster::_LaunchApp() done: %s (%lx)\n",
|
DBG(OUT("BRoster::_LaunchApp() done: %s (%lx)\n",
|
||||||
strerror(error), error));
|
strerror(error), error));
|
||||||
@@ -1998,21 +2014,21 @@ BRoster::_TranslateRef(entry_ref *ref, BMimeType *appMeta,
|
|||||||
entry_ref *appRef, BFile *appFile,
|
entry_ref *appRef, BFile *appFile,
|
||||||
bool *wasDocument) const
|
bool *wasDocument) const
|
||||||
{
|
{
|
||||||
status_t error = (ref && appMeta && appRef && appFile ? B_OK
|
if (ref == NULL || appMeta == NULL || appRef == NULL || appFile == NULL)
|
||||||
: B_BAD_VALUE);
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// resolve ref, if necessary
|
// resolve ref, if necessary
|
||||||
if (error == B_OK) {
|
BEntry entry;
|
||||||
BEntry entry;
|
status_t error = entry.SetTo(ref, false);
|
||||||
error = entry.SetTo(ref, false);
|
if (error == B_OK && entry.IsSymLink()) {
|
||||||
if (error == B_OK && entry.IsSymLink()) {
|
// ref refers to a link
|
||||||
// ref refers to a link
|
error = entry.SetTo(ref, true);
|
||||||
error = entry.SetTo(ref, true);
|
if (error == B_OK)
|
||||||
if (error == B_OK)
|
error = entry.GetRef(ref);
|
||||||
error = entry.GetRef(ref);
|
if (error != B_OK)
|
||||||
if (error != B_OK)
|
error = B_LAUNCH_FAILED_NO_RESOLVE_LINK;
|
||||||
error = B_LAUNCH_FAILED_NO_RESOLVE_LINK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// init node
|
// init node
|
||||||
BNode node;
|
BNode node;
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
@@ -2095,13 +2111,14 @@ status_t
|
|||||||
BRoster::_TranslateType(const char *mimeType, BMimeType *appMeta,
|
BRoster::_TranslateType(const char *mimeType, BMimeType *appMeta,
|
||||||
entry_ref *appRef, BFile *appFile) const
|
entry_ref *appRef, BFile *appFile) const
|
||||||
{
|
{
|
||||||
status_t error = (mimeType && appMeta && appRef && appFile
|
if (mimeType == NULL || appMeta == NULL || appRef == NULL
|
||||||
&& strlen(mimeType) < B_MIME_TYPE_LENGTH ? B_OK
|
|| appFile == NULL || strlen(mimeType) >= B_MIME_TYPE_LENGTH)
|
||||||
: B_BAD_VALUE);
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// create a BMimeType and check, if the type is installed
|
// create a BMimeType and check, if the type is installed
|
||||||
BMimeType type;
|
BMimeType type;
|
||||||
if (error == B_OK)
|
status_t error = type.SetTo(mimeType);
|
||||||
error = type.SetTo(mimeType);
|
|
||||||
// get the preferred app
|
// get the preferred app
|
||||||
char appSignature[B_MIME_TYPE_LENGTH];
|
char appSignature[B_MIME_TYPE_LENGTH];
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
|
|||||||
Reference in New Issue
Block a user