Track running apps

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@12188 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-01-22 18:23:56 +00:00
parent 852190f0f0
commit 47950c836d
3 changed files with 226 additions and 157 deletions

View file

@ -1,11 +1,14 @@
2002-01-22 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSWorkspace.h: new ivar
* Source/NSWorkspace.m: Many tidyups and little fixes, major change
to -getBestApp... so that it picks the best available app rather
than just the one specifed by the user as 'best'. This means you can
always use it to get an app even if the user has set no preference.
Fixed uninitialised variable in first version of this mod and made
user preferences override declared types opened by apps.
Keep track of launched applications so we can tell whether we need
to launch a new one or just talk to an existing one.
2002-01-21 Adam Fedor <fedor@gnu.org>

View file

@ -3,7 +3,7 @@
Interface for workspace.
Copyright (C) 1996 Free Software Foundation, Inc.
Copyright (C) 1996-2002 Free Software Foundation, Inc.
Author: Scott Christley <scottc@net-community.com>
Date: 1996
@ -43,127 +43,127 @@
@interface NSWorkspace : NSObject
{
// Attributes
NSMutableDictionary *_iconMap;
NSNotificationCenter *_workspaceCenter;
BOOL _fileSystemChanged;
BOOL _userDefaultsChanged;
NSMutableDictionary *_iconMap;
NSMutableDictionary *_launched;
NSNotificationCenter *_workspaceCenter;
BOOL _fileSystemChanged;
BOOL _userDefaultsChanged;
}
//
// Creating a Workspace
//
+ (NSWorkspace *)sharedWorkspace;
+ (NSWorkspace*) sharedWorkspace;
//
// Opening Files
//
- (BOOL)openFile: (NSString *)fullPath;
- (BOOL)openFile: (NSString *)fullPath
fromImage: (NSImage *)anImage
at: (NSPoint)point
inView: (NSView *)aView;
- (BOOL)openFile: (NSString *)fullPath
withApplication: (NSString *)appName;
- (BOOL)openFile: (NSString *)fullPath
withApplication: (NSString *)appName
andDeactivate: (BOOL)flag;
- (BOOL)openTempFile: (NSString *)fullPath;
- (BOOL) openFile: (NSString*)fullPath;
- (BOOL) openFile: (NSString*)fullPath
fromImage: (NSImage*)anImage
at: (NSPoint)point
inView: (NSView*)aView;
- (BOOL) openFile: (NSString*)fullPath
withApplication: (NSString*)appName;
- (BOOL) openFile: (NSString*)fullPath
withApplication: (NSString*)appName
andDeactivate: (BOOL)flag;
- (BOOL) openTempFile: (NSString*)fullPath;
#ifndef STRICT_OPENSTEP
- (BOOL)openURL:(NSURL *)url;
- (BOOL) openURL: (NSURL*)url;
#endif
//
// Manipulating Files
//
- (BOOL)performFileOperation: (NSString *)operation
source: (NSString *)source
destination: (NSString *)destination
files: (NSArray *)files
tag: (int *)tag;
- (BOOL)selectFile: (NSString *)fullPath
inFileViewerRootedAtPath: (NSString *)rootFullpath;
- (BOOL) performFileOperation: (NSString*)operation
source: (NSString*)source
destination: (NSString*)destination
files: (NSArray*)files
tag: (int*)tag;
- (BOOL) selectFile: (NSString*)fullPath
inFileViewerRootedAtPath: (NSString*)rootFullpath;
//
// Requesting Information about Files
//
- (NSString *)fullPathForApplication: (NSString *)appName;
- (BOOL)getFileSystemInfoForPath: (NSString *)fullPath
isRemovable: (BOOL *)removableFlag
isWritable: (BOOL *)writableFlag
isUnmountable: (BOOL *)unmountableFlag
description: (NSString **)description
type: (NSString **)fileSystemType;
- (BOOL)getInfoForFile: (NSString *)fullPath
application: (NSString **)appName
type: (NSString **)type;
- (NSImage *)iconForFile: (NSString *)fullPath;
- (NSImage *)iconForFiles: (NSArray *)pathArray;
- (NSImage *)iconForFileType: (NSString *)fileType;
- (NSString*) fullPathForApplication: (NSString*)appName;
- (BOOL) getFileSystemInfoForPath: (NSString*)fullPath
isRemovable: (BOOL*)removableFlag
isWritable: (BOOL*)writableFlag
isUnmountable: (BOOL*)unmountableFlag
description: (NSString**)description
type: (NSString**)fileSystemType;
- (BOOL) getInfoForFile: (NSString*)fullPath
application: (NSString**)appName
type: (NSString**)type;
- (NSImage*) iconForFile: (NSString*)fullPath;
- (NSImage*) iconForFiles: (NSArray*)pathArray;
- (NSImage*) iconForFileType: (NSString*)fileType;
#ifndef STRICT_OPENSTEP
- (BOOL)isFilePackageAtPath:(NSString *)fullPath;
- (BOOL) isFilePackageAtPath: (NSString*)fullPath;
#endif
//
// Tracking Changes to the File System
//
- (BOOL)fileSystemChanged;
- (void)noteFileSystemChanged;
- (BOOL) fileSystemChanged;
- (void) noteFileSystemChanged;
#ifndef STRICT_OPENSTEP
- (void)noteFileSystemChanged:(NSString *)path;
- (void) noteFileSystemChanged: (NSString*)path;
#endif
//
// Updating Registered Services and File Types
//
- (void)findApplications;
- (void) findApplications;
//
// Launching and Manipulating Applications
//
- (void)hideOtherApplications;
- (BOOL)launchApplication: (NSString *)appName;
- (BOOL)launchApplication: (NSString *)appName
showIcon: (BOOL)showIcon
autolaunch: (BOOL)autolaunch;
- (void) hideOtherApplications;
- (BOOL) launchApplication: (NSString*)appName;
- (BOOL) launchApplication: (NSString*)appName
showIcon: (BOOL)showIcon
autolaunch: (BOOL)autolaunch;
//
// Unmounting a Device
//
- (BOOL)unmountAndEjectDeviceAtPath: (NSString *)path;
- (BOOL) unmountAndEjectDeviceAtPath: (NSString*)path;
//
// Tracking Status Changes for Devices
//
- (void)checkForRemovableMedia;
- (NSArray *)mountNewRemovableMedia;
- (NSArray *)mountedRemovableMedia;
- (void) checkForRemovableMedia;
- (NSArray*) mountNewRemovableMedia;
- (NSArray*) mountedRemovableMedia;
#ifndef STRICT_OPENSTEP
- (NSArray *)mountedLocalVolumePaths;
- (NSArray*) mountedLocalVolumePaths;
#endif
//
// Notification Center
//
- (NSNotificationCenter *)notificationCenter;
- (NSNotificationCenter*) notificationCenter;
//
// Tracking Changes to the User Defaults Database
//
- (void)noteUserDefaultsChanged;
- (BOOL)userDefaultsChanged;
- (void) noteUserDefaultsChanged;
- (BOOL) userDefaultsChanged;
//
// Animating an Image
//
- (void)slideImage: (NSImage *)image
from: (NSPoint)fromPoint
to: (NSPoint)toPoint;
- (void) slideImage: (NSImage*)image
from: (NSPoint)fromPoint
to: (NSPoint)toPoint;
//
// Requesting Additional Time before Power Off or Logout
//
- (int)extendPowerOffBy: (int)requested;
- (int) extendPowerOffBy: (int)requested;
@end
@ -176,8 +176,8 @@
forExtension: (NSString*)ext;
- (NSString*) getBestIconForExtension: (NSString*)ext;
- (NSDictionary*) infoForExtension: (NSString*)ext;
- (NSBundle *) bundleForApp:(NSString *)appName;
- (NSImage *) appIconForApp:(NSString *)appName;
- (NSBundle*) bundleForApp:(NSString*)appName;
- (NSImage*) appIconForApp:(NSString*)appName;
- (NSString*) locateApplicationBinary: (NSString*)appName;
- (void) setBestApp: (NSString*)appName
inRole: (NSString*)role

View file

@ -6,9 +6,9 @@
Author: Scott Christley <scottc@net-community.com>
Date: 1996
Implementation: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Implementation by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: 1998
Implementation: Fred Kiefer <FredKiefer@gmx.de>
Implementation by: Fred Kiefer <FredKiefer@gmx.de>
Date: 2001
This file is part of the GNUstep GUI Library.
@ -169,21 +169,21 @@ static NSString *GSWorkspaceNotification = @"GSWorkspaceNotification";
@interface NSWorkspace (Private)
// Icon handling
- (NSImage*) _extIconForApp: (NSString *)appName info: (NSDictionary *)extInfo;
- (NSImage*) _getImageWithName: (NSString *)name
alternate: (NSString *)alternate;
- (NSImage *) folderImage;
- (NSImage *) unknownFiletypeImage;
- (NSImage *) rootImage;
- (NSImage*) _extIconForApp: (NSString*)appName info: (NSDictionary*)extInfo;
- (NSImage*) _getImageWithName: (NSString*)name
alternate: (NSString*)alternate;
- (NSImage*) folderImage;
- (NSImage*) unknownFiletypeImage;
- (NSImage*) rootImage;
- (NSImage*) _iconForExtension: (NSString*)ext;
- (BOOL) _extension: (NSString*)ext
role: (NSString*)role
app: (NSString**)app;
// application communication
- (BOOL) _launchApplication: (NSString *)appName
arguments: (NSArray *)args;
- (id) _connectApplication: (NSString *)appName;
- (BOOL) _launchApplication: (NSString*)appName
arguments: (NSArray*)args;
- (id) _connectApplication: (NSString*)appName;
- (id) _workspaceApplication;
@end
@ -274,7 +274,7 @@ static NSString *_rootPath = @"/";
/*
* Creating a Workspace
*/
+ (NSWorkspace *) sharedWorkspace
+ (NSWorkspace*) sharedWorkspace
{
if (sharedWorkspace == nil)
{
@ -308,15 +308,18 @@ static NSString *_rootPath = @"/";
}
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(noteUserDefaultsChanged)
name: NSUserDefaultsDidChangeNotification
object: nil];
addObserver: self
selector: @selector(noteUserDefaultsChanged)
name: NSUserDefaultsDidChangeNotification
object: nil];
_workspaceCenter = [_GSWorkspaceCenter new];
_iconMap = [NSMutableDictionary new];
_launched = [NSMutableDictionary new];
if (applications == nil)
[self findApplications];
{
[self findApplications];
}
return self;
}
@ -324,15 +327,15 @@ static NSString *_rootPath = @"/";
/*
* Opening Files
*/
- (BOOL) openFile: (NSString *)fullPath
- (BOOL) openFile: (NSString*)fullPath
{
return [self openFile: fullPath withApplication: nil];
}
- (BOOL) openFile: (NSString *)fullPath
fromImage: (NSImage *)anImage
- (BOOL) openFile: (NSString*)fullPath
fromImage: (NSImage*)anImage
at: (NSPoint)point
inView: (NSView *)aView
inView: (NSView*)aView
{
NSWindow *win = [aView window];
NSPoint screenLoc = [win convertBaseToScreen:
@ -345,14 +348,14 @@ static NSString *_rootPath = @"/";
return [self openFile: fullPath];
}
- (BOOL) openFile: (NSString *)fullPath
withApplication: (NSString *)appName
- (BOOL) openFile: (NSString*)fullPath
withApplication: (NSString*)appName
{
return [self openFile: fullPath withApplication: appName andDeactivate: YES];
}
- (BOOL) openFile: (NSString *)fullPath
withApplication: (NSString *)appName
- (BOOL) openFile: (NSString*)fullPath
withApplication: (NSString*)appName
andDeactivate: (BOOL)flag
{
id app;
@ -381,9 +384,13 @@ static NSString *_rootPath = @"/";
NS_DURING
{
if (flag == NO)
[app application: NSApp openFileWithoutUI: fullPath];
{
[app application: NSApp openFileWithoutUI: fullPath];
}
else
[app application: NSApp openFile: fullPath];
{
[app application: NSApp openFile: fullPath];
}
}
NS_HANDLER
{
@ -399,7 +406,7 @@ static NSString *_rootPath = @"/";
return YES;
}
- (BOOL) openTempFile: (NSString *)fullPath
- (BOOL) openTempFile: (NSString*)fullPath
{
id app;
NSString *appName;
@ -438,22 +445,26 @@ static NSString *_rootPath = @"/";
return YES;
}
- (BOOL)openURL:(NSURL *)url
- (BOOL) openURL: (NSURL*)url
{
if ([url isFileURL])
return [self openFile: [url path]];
{
return [self openFile: [url path]];
}
else
return NO;
{
return NO;
}
}
/*
* Manipulating Files
*/
- (BOOL) performFileOperation: (NSString *)operation
source: (NSString *)source
destination: (NSString *)destination
files: (NSArray *)files
tag: (int *)tag
- (BOOL) performFileOperation: (NSString*)operation
source: (NSString*)source
destination: (NSString*)destination
files: (NSArray*)files
tag: (int*)tag
{
id app = [self _workspaceApplication];
@ -468,8 +479,8 @@ static NSString *_rootPath = @"/";
tag: tag];
}
- (BOOL) selectFile: (NSString *)fullPath
inFileViewerRootedAtPath: (NSString *)rootFullpath
- (BOOL) selectFile: (NSString*)fullPath
inFileViewerRootedAtPath: (NSString*)rootFullpath
{
id app = [self _workspaceApplication];
@ -484,7 +495,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
/*
* Requesting Information about Files
*/
- (NSString *) fullPathForApplication: (NSString *)appName
- (NSString*) fullPathForApplication: (NSString*)appName
{
NSString *last = [appName lastPathComponent];
@ -501,10 +512,10 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
return nil;
}
- (BOOL) getFileSystemInfoForPath: (NSString *)fullPath
isRemovable: (BOOL *)removableFlag
isWritable: (BOOL *)writableFlag
isUnmountable: (BOOL *)unmountableFlag
- (BOOL) getFileSystemInfoForPath: (NSString*)fullPath
isRemovable: (BOOL*)removableFlag
isWritable: (BOOL*)writableFlag
isUnmountable: (BOOL*)unmountableFlag
description: (NSString **)description
type: (NSString **)fileSystemType
{
@ -512,7 +523,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
return NO;
}
- (BOOL) getInfoForFile: (NSString *)fullPath
- (BOOL) getInfoForFile: (NSString*)fullPath
application: (NSString **)appName
type: (NSString **)type
{
@ -583,7 +594,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
}
}
- (NSImage *) iconForFile: (NSString *)aPath
- (NSImage*) iconForFile: (NSString*)aPath
{
NSImage *image = nil;
NSString *pathExtension = [[aPath pathExtension] lowercaseString];
@ -692,7 +703,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
return image;
}
- (NSImage *) iconForFiles: (NSArray *)pathArray
- (NSImage*) iconForFiles: (NSArray*)pathArray
{
static NSImage *multipleFiles = nil;
@ -709,12 +720,12 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
return multipleFiles;
}
- (NSImage *) iconForFileType: (NSString *)fileType
- (NSImage*) iconForFileType: (NSString*)fileType
{
return [self _iconForExtension: fileType];
}
- (BOOL) isFilePackageAtPath: (NSString *)fullPath
- (BOOL) isFilePackageAtPath: (NSString*)fullPath
{
NSFileManager *mgr = [NSFileManager defaultManager];
NSDictionary *attributes;
@ -745,7 +756,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
_fileSystemChanged = YES;
}
- (void) noteFileSystemChanged: (NSString *)path
- (void) noteFileSystemChanged: (NSString*)path
{
_fileSystemChanged = YES;
}
@ -821,7 +832,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
* Calls -launchApplication:showIcon:autolaunch: with arguments set to
* show the icon but not set it up as an autolaunch.
*/
- (BOOL) launchApplication: (NSString *)appName
- (BOOL) launchApplication: (NSString*)appName
{
return [self launchApplication: appName
showIcon: YES
@ -831,7 +842,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
/**
* Launches the specified application (unless it is alreeady running)
*/
- (BOOL) launchApplication: (NSString *)appName
- (BOOL) launchApplication: (NSString*)appName
showIcon: (BOOL)showIcon
autolaunch: (BOOL)autolaunch
{
@ -849,7 +860,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
/*
* Unmounting a Device
*/
- (BOOL) unmountAndEjectDeviceAtPath: (NSString *)path
- (BOOL) unmountAndEjectDeviceAtPath: (NSString*)path
{
NSDictionary *userinfo;
NSTask *task;
@ -895,13 +906,13 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
// FIXME
}
- (NSArray *) mountNewRemovableMedia
- (NSArray*) mountNewRemovableMedia
{
// FIXME
return nil;
}
- (NSArray *) mountedRemovableMedia
- (NSArray*) mountedRemovableMedia
{
NSArray *volumes = [self mountedLocalVolumePaths];
NSMutableArray *names = [NSMutableArray arrayWithCapacity: [volumes count]];
@ -959,7 +970,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
/**
* Returns the workspace notification center
*/
- (NSNotificationCenter *) notificationCenter
- (NSNotificationCenter*) notificationCenter
{
return _workspaceCenter;
}
@ -987,7 +998,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
/**
* Animating an Image- slides it from one point on the screen to another.
*/
- (void) slideImage: (NSImage *)image
- (void) slideImage: (NSImage*)image
from: (NSPoint)fromPoint
to: (NSPoint)toPoint
{
@ -1065,7 +1076,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
/**
* Returns the application bundle for the named application.
*/
- (NSBundle*) bundleForApp: (NSString *)appName
- (NSBundle*) bundleForApp: (NSString*)appName
{
NSString *path;
@ -1101,7 +1112,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
* Returns the application icon for the given app.
* Or null if none defined or appName is not a valid application name.
*/
- (NSImage*) appIconForApp: (NSString *)appName
- (NSImage*) appIconForApp: (NSString*)appName
{
NSBundle *bundle = [self bundleForApp: appName];
NSString *iconPath;
@ -1257,7 +1268,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
@implementation NSWorkspace (Private)
- (NSImage*) _extIconForApp: (NSString *)appName info: (NSDictionary *)extInfo
- (NSImage*) _extIconForApp: (NSString*)appName info: (NSDictionary*)extInfo
{
NSDictionary *typeInfo = [extInfo objectForKey: appName];
NSString *file = [typeInfo objectForKey: @"NSIcon"];
@ -1289,8 +1300,8 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
return nil;
}
- (NSImage*) _getImageWithName: (NSString *)name
alternate: (NSString *)alternate
- (NSImage*) _getImageWithName: (NSString*)name
alternate: (NSString*)alternate
{
NSImage *image = nil;
@ -1301,7 +1312,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
}
/** Returns the default icon to display for a directory */
- (NSImage *) folderImage
- (NSImage*) folderImage
{
static NSImage *image = nil;
@ -1315,7 +1326,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
}
/** Returns the default icon to display for a directory */
- (NSImage *) unknownFiletypeImage
- (NSImage*) unknownFiletypeImage
{
static NSImage *image = nil;
@ -1329,7 +1340,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
}
/** Returns the default icon to display for a directory */
- (NSImage *) rootImage
- (NSImage*) rootImage
{
static NSImage *image = nil;
@ -1575,8 +1586,8 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
* to perform the launch for us. Otherwise we try to launch the app
* ourself as long as it is on the same host as we are.
*/
- (BOOL) _launchApplication: (NSString *)appName
arguments: (NSArray *)args
- (BOOL) _launchApplication: (NSString*)appName
arguments: (NSArray*)args
{
id app = nil;
@ -1587,6 +1598,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
}
else
{
NSTask *task;
NSString *path;
NSDictionary *userinfo;
NSString *host;
@ -1639,7 +1651,8 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
object: self
userInfo: userinfo];
if ([NSTask launchedTaskWithLaunchPath: path arguments: args] == nil)
task = [NSTask launchedTaskWithLaunchPath: path arguments: args];
if (task == nil)
{
return NO;
}
@ -1647,47 +1660,100 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
* The NSWorkspaceDidLaunchApplicationNotification will be
* sent by the started application itself.
*/
[_launched setObject: task forKey: appName];
return YES;
}
}
- (id) _connectApplication: (NSString *)appName
- (id) _connectApplication: (NSString*)appName
{
NSString *host;
NSString *port;
NSDate *when = nil;
BOOL done = NO;
id app = nil;
host = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSHost"];
if (host == nil)
while (done == NO)
{
host = @"";
}
else
{
NSHost *h;
h = [NSHost hostWithName: host];
if ([h isEqual: [NSHost currentHost]] == YES)
host = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSHost"];
if (host == nil)
{
host = @"";
}
}
port = [appName stringByDeletingPathExtension];
/*
* Try to contact a running application.
*/
NS_DURING
{
app = [NSConnection rootProxyForConnectionWithRegisteredName: port
host: host];
}
NS_HANDLER
{
/* Fatal error in DO */
app = nil;
}
NS_ENDHANDLER
else
{
NSHost *h;
h = [NSHost hostWithName: host];
if ([h isEqual: [NSHost currentHost]] == YES)
{
host = @"";
}
}
port = [appName stringByDeletingPathExtension];
/*
* Try to contact a running application.
*/
NS_DURING
{
app = [NSConnection rootProxyForConnectionWithRegisteredName: port
host: host];
}
NS_HANDLER
{
/* Fatal error in DO */
app = nil;
}
NS_ENDHANDLER
done = YES;
if (app == nil)
{
NSTask *task = [_launched objectForKey: appName];
if (task != nil && [task isRunning] == YES)
{
if (when == nil)
{
when = [[NSDate alloc] init];
done = NO;
}
else if ([when timeIntervalSinceNow] > 5.0)
{
int result;
DESTROY(when);
result = NSRunAlertPanel(appName,
@"Application seems to have hung",
@"Continue", @"Terminate", @"Wait");
if (result == NSAlertDefaultReturn)
{
done = YES;
}
else if (result == NSAlertOtherReturn)
{
done = NO;
}
else
{
[task terminate];
[_launched removeObjectForKey: appName];
done = YES;
}
}
if (done == NO)
{
NSDate *limit;
limit = [[NSDate alloc] initWithTimeIntervalSinceNow: 0.5];
[[NSRunLoop currentRunLoop] runUntilDate: limit];
RELEASE(limit);
}
}
}
}
TEST_RELEASE(when);
return app;
}