Changeset 306
- Timestamp:
- 10/28/06 13:47:45 (18 years ago)
- Location:
- trunk/appswitch/appswitch
- Files:
-
- 4 added
- 1 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/appswitch/appswitch/README
r160 r306 1 appswitch 1. 0.1 [16 May 2004]1 appswitch 1.1d1 [unreleased] 2 2 =============== 3 3 … … 33 33 % sudo /usr/bin/install -c build/appswitch /usr/local/bin 34 34 % sudo /usr/bin/install -c appswitch.1 /usr/local/man/man1 35 % rehash 35 % rehash # if necessary 36 36 37 37 Uninstallation: … … 42 42 ----------- 43 43 44 An Xcode project, 'appswitch.xcode ', is included. A precompiled45 binary is also provided. 'appswitch' was developed and tested under 46 Mac OS 10.3.3 with the April 2004 Developer Tools, and does not 47 require anyadditional software to build.44 An Xcode project, 'appswitch.xcodeproj', is included. A precompiled 45 Universal binary is also provided. 'appswitch' was developed and 46 tested under Mac OS 10.4.8 with Xcode 2.4, and does not require any 47 additional software to build. 48 48 49 49 USAGE … … 56 56 other methods, this should give you some indication. 57 57 58 appswitch -a Emacs 0.00s user 0.02s system 55% cpu 0.054 total 59 appswitch -i com.gnu.Emacs 0.00s user 0.04s system 63% cpu 0.063 total 60 open -a Emacs 0.32s user 0.12s system 50% cpu 0.876 total 61 launch -a Emacs 0.00s user 0.03s system 35% cpu 0.085 total 58 appswitch -a Emacs 0.01s user 0.01s system 28% cpu 0.069 total 59 launch -a Emacs 0.01s user 0.01s system 35% cpu 0.076 total 60 open -a Emacs 0.04s user 0.02s system 52% cpu 0.115 total 62 61 osascript -e 'tell application "Emacs" to activate' 63 0. 41s user 0.23s system 67% cpu 0.949total62 0.13s user 0.06s system 59% cpu 0.326 total 64 63 65 The above tests were performed on a PowerBook G4/800; slower systems66 s houldshow more dramatic differences.64 The above tests were performed on a Mac mini Core Duo 1.66 GHz; slower 65 systems show more dramatic differences. 67 66 68 67 COMMENTS, SUGGESTIONS, BUG REPORTS, ETC. … … 74 73 --------------- 75 74 75 1.1 - unreleased 76 - switched to Process Manager instead of CPS (slower but more 77 compatible) 78 - fixed description of -k option: SIGTERM, not SIGINT 79 - added -f option 80 - Universal Binary, compatible with Intel Macs 76 81 1.0.1 - 16 May 2004 77 82 - fixed crash matching applications with no bundle identifier -
trunk/appswitch/appswitch/VERSION
r161 r306 1 1. 0.11 1.1d1 -
trunk/appswitch/appswitch/main.c
r163 r306 3 3 Nicholas Riley <appswitch@sabi.net> 4 4 5 Copyright (c) 2003-0 4, Nicholas Riley5 Copyright (c) 2003-06, Nicholas Riley 6 6 All rights reserved. 7 7 … … 19 19 20 20 #include <unistd.h> 21 #include <signal.h> 21 22 #include <sys/ioctl.h> 23 #include <ApplicationServices/ApplicationServices.h> 22 24 #include "CPS.h" 23 25 24 26 const char *APP_NAME; 25 27 26 #define VERSION "1. 0.1"28 #define VERSION "1.1d1" 27 29 28 30 struct { 29 OSTypecreator;31 CFStringRef creator; 30 32 CFStringRef bundleID; 31 char *name;33 CFStringRef name; 32 34 pid_t pid; 33 char *path;35 CFStringRef path; 34 36 enum { 35 37 MATCH_UNKNOWN, MATCH_FRONT, MATCH_CREATOR, MATCH_BUNDLE_ID, MATCH_NAME, MATCH_PID, MATCH_PATH, MATCH_ALL 36 38 } matchType; 37 39 enum { 38 APP_NONE, APP_SWITCH, APP_SHOW, APP_HIDE, APP_QUIT, APP_KILL, APP_KILL_HARD, APP_LIST, APP_PRINT_PID 40 APP_NONE, APP_SWITCH, APP_SHOW, APP_HIDE, APP_QUIT, APP_KILL, APP_KILL_HARD, APP_LIST, APP_PRINT_PID, APP_FRONTMOST 39 41 } appAction; 40 42 Boolean longList; … … 57 59 static errList ERRS = { 58 60 // Process Manager errors 59 { appIsDaemon, "application is background-only\n", }, 60 { procNotFound, "unable to connect to system service.\nAre you logged in?" }, 61 { appIsDaemon, "application is background-only", }, 62 { procNotFound, "application not found" }, 63 { connectionInvalid, "application is not background-only", }, 61 64 // CoreGraphics errors 62 65 { kCGErrorIllegalArgument, "window server error.\nAre you logged in?" }, 63 66 { fnfErr, "file not found" }, 67 // (abused) errors 68 { permErr, "no permission" }, 64 69 { 0, NULL } 65 70 }; 66 71 67 72 void usage() { 68 fprintf(stderr, "usage: %s [-sShHqk FlLP] [-c creator] [-i bundleID] [-a name] [-p pid] [path]\n"73 fprintf(stderr, "usage: %s [-sShHqklLPfF] [-c creator] [-i bundleID] [-a name] [-p pid] [path]\n" 69 74 " -s show application, bring windows to front (do not switch)\n" 70 75 " -S show all applications\n" … … 72 77 " -H hide other applications\n" 73 78 " -q quit application\n" 74 " -k kill application (SIG INT)\n"79 " -k kill application (SIGTERM)\n" 75 80 " -K kill application hard (SIGKILL)\n" 76 81 " -l list applications\n" 77 82 " -L list applications including full paths and bundle identifiers\n" 78 83 " -P print application process ID\n" 84 " -f bring application's frontmost window to front\n" 79 85 " -F bring current application's windows to front\n" 80 86 " -c creator match application by four-character creator code ('ToyS')\n" 81 " -i bundle ID match application by bundle identifier (com.apple. scripteditor)\n"82 " -p pid match application by process identifier [slower]\n"87 " -i bundle ID match application by bundle identifier (com.apple.ScriptEditor2)\n" 88 " -p pid match application by process identifier\n" 83 89 " -a name match application by name\n" 84 90 , APP_NAME); 85 fprintf(stderr, "appswitch "VERSION" (c) 2003-0 4Nicholas Riley <http://web.sabi.net/nriley/software/>.\n"91 fprintf(stderr, "appswitch "VERSION" (c) 2003-06 Nicholas Riley <http://web.sabi.net/nriley/software/>.\n" 86 92 "Please send bugs, suggestions, etc. to <appswitch@sabi.net>.\n"); 87 93 … … 101 107 break; 102 108 } 103 109 len = strlen(errDesc) + 10 * sizeof(char); 104 110 str = (char *)malloc(len); 105 111 if (str != NULL) … … 136 142 if (argc == 1) usage(); 137 143 138 const char *opts = "c:i:p:a:sShHqkKlLP F";144 const char *opts = "c:i:p:a:sShHqkKlLPfF"; 139 145 140 146 while ( (ch = getopt(argc, argv, opts)) != -1) { … … 148 154 case 'c': 149 155 if (OPTS.matchType != MATCH_UNKNOWN) errexit("choose only one of -c, -i, -p, -a options"); 150 if (strlen(optarg) != 4) errexit("creator (argument of -c) must be four characters long"); 151 OPTS.creator = *(OSTypePtr)optarg; 156 OPTS.creator = CFStringCreateWithFileSystemRepresentation(NULL, optarg); 157 if (OPTS.creator == NULL) errexit("invalid creator (wrong text encoding?)"); 158 if (CFStringGetLength(OPTS.creator) != 4) errexit("creator (argument of -c) must be four characters long"); 152 159 OPTS.matchType = MATCH_CREATOR; 153 160 break; 154 161 case 'i': 155 162 if (OPTS.matchType != MATCH_UNKNOWN) errexit("choose only one of -c, -i, -p, -a options"); 156 OPTS.bundleID = CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding()); 163 OPTS.bundleID = CFStringCreateWithFileSystemRepresentation(NULL, optarg); 164 if (OPTS.bundleID == NULL) errexit("invalid bundle ID (wrong text encoding?)"); 157 165 OPTS.matchType = MATCH_BUNDLE_ID; 158 166 break; 159 167 case 'a': 160 168 if (OPTS.matchType != MATCH_UNKNOWN) errexit("choose only one of -c, -i, -p, -a options"); 161 OPTS.name = strdup(optarg); 169 OPTS.name = CFStringCreateWithFileSystemRepresentation(NULL, optarg); 170 if (OPTS.name == NULL) errexit("invalid application name (wrong text encoding?)"); 162 171 OPTS.matchType = MATCH_NAME; 163 172 break; 164 173 case 's': 165 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P options");174 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 166 175 OPTS.appAction = APP_SHOW; 167 176 break; 168 177 case 'h': 169 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P options");178 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 170 179 OPTS.appAction = APP_HIDE; 171 180 break; 172 181 case 'q': 173 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P options");182 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 174 183 OPTS.appAction = APP_QUIT; 175 184 break; 176 185 case 'k': 177 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P options");186 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 178 187 OPTS.appAction = APP_KILL; 179 188 break; 180 189 case 'K': 181 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P options");190 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 182 191 OPTS.appAction = APP_KILL_HARD; 183 192 break; 184 193 case 'l': 185 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P options");194 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 186 195 OPTS.appAction = APP_LIST; 187 196 break; 188 197 case 'L': 189 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P options");198 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 190 199 OPTS.appAction = APP_LIST; 191 200 OPTS.longList = true; 192 201 break; 193 202 case 'P': 194 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, - Poptions");203 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 195 204 OPTS.appAction = APP_PRINT_PID; 205 break; 206 case 'f': 207 if (OPTS.appAction != APP_NONE) errexit("choose only one of -s, -h, -q, -k, -K, -l, -L, -P, -f options"); 208 OPTS.appAction = APP_FRONTMOST; 196 209 break; 197 210 case 'S': … … 224 237 } else usage(); 225 238 } else if (argc == 1) { 226 OPTS.path = argv[0]; 239 OPTS.path = CFStringCreateWithFileSystemRepresentation(NULL, argv[0]); 240 if (OPTS.path == NULL) errexit("invalid path (wrong text encoding?)"); 227 241 OPTS.matchType = MATCH_PATH; 228 242 } else usage(); … … 234 248 } 235 249 236 CPSProcessSerNumfrontApplication() {237 CPSProcessSerNumpsn;238 OSStatus err = CPSGetFrontProcess(&psn);250 ProcessSerialNumber frontApplication() { 251 ProcessSerialNumber psn; 252 OSStatus err = GetFrontProcess(&psn); 239 253 if (err != noErr) osstatusexit(err, "can't get frontmost process"); 240 254 #if DEBUG 241 fprintf(stderr, "front application PSN %ld.%ld\n", psn. hi, psn.lo);255 fprintf(stderr, "front application PSN %ld.%ld\n", psn.lowLongOfPSN, psn.highLongOfPSN); 242 256 #endif 243 257 return psn; 244 258 } 245 259 246 Boolean bundleIdentifierForApplication(CFStringRef *bundleID, char *path) { 247 CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, path, strlen(path), false); 248 if (url == NULL) return false; 249 CFBundleRef bundle = CFBundleCreate(NULL, url); 250 if (bundle != NULL) { 251 *bundleID = CFBundleGetIdentifier(bundle); 252 if (*bundleID != NULL) { 253 CFRetain(*bundleID); 254 #if DEBUG 255 CFShow(*bundleID); 256 #endif 257 } 258 CFRelease(bundle); 259 } else { 260 *bundleID = NULL; 261 } 262 CFRelease(url); 263 return true; 264 } 265 266 OSStatus quitApplication(CPSProcessSerNum *psn) { 260 OSStatus quitApplication(ProcessSerialNumber *psn) { 267 261 AppleEvent event; 268 262 AEAddressDesc appDesc; … … 273 267 if (err != noErr) return err; 274 268 275 // XXX AECreateAppleEvent is very slow in Mac OS X 10.2.4 and earlier.276 // XXX This is Apple's bug: <http://lists.apple.com/archives/applescript-implementors/2003/Feb/19/aecreateappleeventfromco.txt>277 269 err = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &appDesc, kAutoGenerateReturnID, kAnyTransactionID, &event); 278 270 if (err != noErr) return err; … … 288 280 } 289 281 290 CPSProcessSerNum matchApplication(CPSProcessInfoRec *info) { 291 long pathMaxLength = pathconf("/", _PC_PATH_MAX); 292 long nameMaxLength = pathconf("/", _PC_NAME_MAX); 293 294 char *path = (char *)malloc(pathMaxLength); 295 char *name = (char *)malloc(nameMaxLength);; 296 297 if (path == NULL || name == NULL) errexit("can't allocate memory for path or filename buffer"); 298 282 pid_t getPID(const ProcessSerialNumber *psn) { 283 pid_t pid; 284 OSStatus err = GetProcessPID(psn, &pid); 285 if (err != noErr) osstatusexit(err, "can't get process ID"); 286 return pid; 287 } 288 289 bool infoStringMatches(CFDictionaryRef info, CFStringRef key, CFStringRef matchStr) { 290 CFStringRef str = CFDictionaryGetValue(info, key); 291 if (str == NULL) 292 return false; 293 /* note: this means we might match names/paths that are wrong, but works better in the common case */ 294 return CFStringCompare(str, matchStr, kCFCompareCaseInsensitive) == kCFCompareEqualTo; 295 } 296 297 char *getInfoCString(CFDictionaryRef info, CFStringRef key) { 298 CFStringRef str = CFDictionaryGetValue(info, key); 299 if (str == NULL) 300 return ""; 301 static char *cStr = NULL; 302 static bool wasDynamic = false; 303 if (wasDynamic) 304 free(cStr); 305 cStr = (char *)CFStringGetCStringPtr(str, CFStringGetSystemEncoding()); 306 if (cStr != NULL) { 307 wasDynamic = false; 308 } else { 309 CFIndex cStrLength = CFStringGetMaximumSizeOfFileSystemRepresentation(str); 310 cStr = (char *)malloc(cStrLength * sizeof(char)); 311 if (!CFStringGetFileSystemRepresentation(str, cStr, cStrLength)) { 312 CFShow(cStr); 313 errexit("internal error: string encoding conversion failed"); 314 } 315 wasDynamic = true; 316 } 317 return cStr; 318 } 319 320 ProcessSerialNumber matchApplication(void) { 299 321 if (OPTS.matchType == MATCH_FRONT) return frontApplication(); 300 322 301 323 OSStatus err; 302 CPSProcessSerNumpsn = {324 ProcessSerialNumber psn = { 303 325 kNoProcess, kNoProcess 304 326 }; 305 int len;327 pid_t pid; 306 328 char *format = NULL; 307 329 if (OPTS.appAction == APP_LIST) { … … 314 336 ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&ws) != -1) || 315 337 ws.ws_col != 0) termwidth = ws.ws_col; 316 char *formatButPath = "%9ld.%ld %5ld % c%c%c%c %c%c%c%c%-19.19s";338 char *formatButPath = "%9ld.%ld %5ld %4s %4s %-19.19s"; 317 339 int pathlen = termwidth - strlen(banner) - 1; 318 340 // XXX don't ever free 'format', should fix if we get called repeatedly … … 328 350 } 329 351 330 while ( (err = CPSGetNextProcess(&psn)) == noErr) { 331 err = CPSGetProcessInfo(&psn, info, path, pathMaxLength, &len, name, nameMaxLength); 332 if (err != noErr) osstatusexit(err, "can't get information for process PSN %ld.%ld", psn.hi, psn.lo); 333 334 #if DEBUG 335 fprintf(stderr, "%ld.%ld: %s : %s\n", psn.hi, psn.lo, name, path); 336 #endif 352 CFDictionaryRef info = NULL; 353 while ( (err = GetNextProcess(&psn)) == noErr) { 354 if (info != NULL) CFRelease(info); 355 info = ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask); 356 if (info == NULL) errexit("can't get information for process with PSN %ld.%ld", 357 psn.lowLongOfPSN, psn.highLongOfPSN); 337 358 338 359 switch (OPTS.matchType) { 339 360 case MATCH_ALL: 340 361 break; 341 case MATCH_CREATOR: if (OPTS.creator != info->ExecFileCreator) continue; 342 break; 343 case MATCH_NAME: if (strcmp(name, OPTS.name) != 0) continue; 344 break; 345 case MATCH_PID: if (OPTS.pid != info->UnixPID) continue; 346 break; 347 case MATCH_PATH: if (strcmp(path, OPTS.path) != 0) continue; 348 break; 349 case MATCH_BUNDLE_ID: 350 { 351 CFStringRef bundleID; 352 if (!bundleIdentifierForApplication(&bundleID, path)) 353 errexit("can't get bundle location for process '%s' (PSN %ld.%ld, pid %ld)", name, psn.hi, psn.lo, info->UnixPID); 354 if (bundleID != NULL) { 355 CFComparisonResult result = CFStringCompare(OPTS.bundleID, bundleID, kCFCompareCaseInsensitive); 356 if (result == kCFCompareEqualTo) 357 break; 358 CFRelease(bundleID); 359 } 360 continue; 361 } 362 case MATCH_CREATOR: if (!infoStringMatches(info, CFSTR("FileCreator"), OPTS.creator)) continue; 363 break; 364 case MATCH_NAME: if (!infoStringMatches(info, CFSTR("CFBundleName"), OPTS.name)) continue; 365 break; 366 case MATCH_PID: err = GetProcessPID(&psn, &pid); if (err != noErr || OPTS.pid != pid) continue; 367 break; 368 case MATCH_PATH: if (!infoStringMatches(info, CFSTR("BundlePath"), OPTS.path)) continue; 369 break; 370 case MATCH_BUNDLE_ID: if (!infoStringMatches(info, CFSTR("CFBundleIdentifier"), OPTS.bundleID)) continue; 371 break; 362 372 default: 363 373 errexit("internal error: invalid match type"); 364 374 } 365 375 if (OPTS.appAction == APP_LIST) { 366 char *type = (char *)&(info->ExecFileType), *crea = (char *)&(info->ExecFileCreator); 367 #define CXX(c) ( (c) < ' ' ? ' ' : (c) ) 368 #define OSTYPE_CHAR_ARGS(t) CXX(t[0]), CXX(t[1]), CXX(t[2]), CXX(t[3]) 369 printf(format, psn.hi, psn.lo, info->UnixPID, 370 OSTYPE_CHAR_ARGS(type), OSTYPE_CHAR_ARGS(crea), 371 name, path); 376 if (GetProcessPID(&psn, &pid) != noErr) 377 pid = -1; 378 printf(format, psn.lowLongOfPSN, psn.highLongOfPSN, pid, 379 getInfoCString(info, CFSTR("FileType")), getInfoCString(info, CFSTR("FileCreator")), 380 getInfoCString(info, CFSTR("CFBundleName")), getInfoCString(info, CFSTR("BundlePath"))); 372 381 if (OPTS.longList) { 373 CFStringRef bundleID = NULL; 374 if (!bundleIdentifierForApplication(&bundleID, path)) 375 errexit("can't get bundle location for process '%s' (PSN %ld.%ld, pid %ld)", name, psn.hi, psn.lo, info->UnixPID); 376 if (bundleID != NULL) { 377 char *bundleIDStr = (char *)CFStringGetCStringPtr(bundleID, CFStringGetSystemEncoding()); 378 if (bundleIDStr == NULL) { 379 CFIndex bundleIDLength = CFStringGetLength(bundleID) + 1; 380 bundleIDStr = (char *)malloc(bundleIDLength * sizeof(char)); 381 if (!CFStringGetCString(bundleID, bundleIDStr, bundleIDLength, CFStringGetSystemEncoding())) { 382 CFShow(bundleIDStr); 383 errexit("internal error: string encoding conversion failed for bundle identifier"); 384 } 385 printf(" (%s)", bundleIDStr); 386 free(bundleIDStr); 387 } else { 388 printf(" (%s)", bundleIDStr); 389 } 390 CFRelease(bundleID); 391 } 382 char *bundleID = getInfoCString(info, CFSTR("CFBundleIdentifier")); 383 if (bundleID[0] != '\0') 384 printf(" (%s)", bundleID); 392 385 } 393 386 putchar('\n'); … … 410 403 getargs(argc, argv); 411 404 412 // need to establish connection with window server 413 InitCursor(); 414 415 CPSProcessInfoRec info; 416 CPSProcessSerNum psn = matchApplication(&info); 405 ProcessSerialNumber psn = matchApplication(); 417 406 418 407 const char *verb = NULL; … … 420 409 case APP_NONE: break; 421 410 case APP_LIST: break; // already handled in matchApplication 422 case APP_SWITCH: err = CPSSetFrontProcess(&psn); verb = "set front"; break;423 case APP_SHOW: err = CPSPostShowReq(&psn); verb = "show"; break;424 case APP_HIDE: err = CPSPostHideReq(&psn); verb = "hide"; break;411 case APP_SWITCH: err = SetFrontProcess(&psn); verb = "set front"; break; 412 case APP_SHOW: err = ShowHideProcess(&psn, true); verb = "show"; break; 413 case APP_HIDE: err = ShowHideProcess(&psn, false); verb = "hide"; break; 425 414 case APP_QUIT: err = quitApplication(&psn); verb = "quit"; break; 426 case APP_KILL: err = CPSPostKillRequest(&psn, kNilOptions); verb = "kill"; break; 427 case APP_KILL_HARD: err = CPSPostKillRequest(&psn, bfCPSKillHard); verb = "kill"; break; 428 case APP_PRINT_PID: 429 if (info.UnixPID <= 0) errexit("can't get process ID"); 430 printf("%lu\n", info.UnixPID); // pid_t is signed, but this field isn't 415 case APP_KILL: err = KillProcess(&psn); verb = "send SIGTERM to"; break; 416 case APP_KILL_HARD: 417 { 418 if (kill(getPID(&psn), SIGKILL) == -1) 419 err = (errno == ESRCH) ? procNotFound : (errno == EPERM ? permErr : paramErr); 420 verb = "send SIGKILL to"; 431 421 break; 422 } 423 case APP_PRINT_PID: printf("%d\n", getPID(&psn)); break; 424 case APP_FRONTMOST: err = SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly); 425 verb = "bring frontmost window to front"; break; 432 426 default: 433 427 errexit("internal error: invalid application action"); … … 449 443 psn = frontApplication(); 450 444 #if DEBUG 451 fprintf(stderr, "posting show request for %ld.%ld\n", psn. hi, psn.lo);445 fprintf(stderr, "posting show request for %ld.%ld\n", psn.lowLongOfPSN, psn.highLongOfPSN); 452 446 #endif 453 447 if (OPTS.action != ACTION_NONE) usleep(750000); // XXX 454 err = CPSPostShowReq(&psn) || CPSSetFrontProcess(&psn);448 err = ShowHideProcess(&psn, true) || SetFrontProcess(&psn); 455 449 verb = "bring current application's windows to the front"; 456 450 break;
Note:
See TracChangeset
for help on using the changeset viewer.