From d27cea97a6a2fa62421fed891c62cff7fb884a25 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Wed, 16 Jun 2010 19:22:15 +0400 Subject: [PATCH] IDEA will restart automatically from now on Mac OS X Snow Leo --- bin/mac/relaunch | Bin 0 -> 42636 bytes native/macrestarter/relaunch.m | 66 ++++++++++++++++ .../application/impl/ApplicationImpl.java | 13 ++-- .../application/impl/MacRestarter.java | 71 ++++++++++++++++++ 4 files changed, 145 insertions(+), 5 deletions(-) create mode 100755 bin/mac/relaunch create mode 100644 native/macrestarter/relaunch.m create mode 100644 platform/platform-impl/src/com/intellij/openapi/application/impl/MacRestarter.java diff --git a/bin/mac/relaunch b/bin/mac/relaunch new file mode 100755 index 0000000000000000000000000000000000000000..f66c7b8b54f3438f09861b7f903bdf415083532c GIT binary patch literal 42636 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 literal 0 HcmV?d00001 diff --git a/native/macrestarter/relaunch.m b/native/macrestarter/relaunch.m new file mode 100644 index 000000000000..4b596895a9fa --- /dev/null +++ b/native/macrestarter/relaunch.m @@ -0,0 +1,66 @@ +// gcc -Wall -arch i386 -arch ppc -mmacosx-version-min=10.4 -Os -framework AppKit -o relaunch relaunch.m + +#import + +@interface TerminationListener : NSObject +{ + const char *executablePath; + pid_t parentProcessId; +} + +- (void) relaunch; + +@end + +@implementation TerminationListener + +- (id) initWithExecutablePath:(const char *)execPath parentProcessId:(pid_t)ppid +{ + self = [super init]; + if (self != nil) { + executablePath = execPath; + parentProcessId = ppid; + + // This adds the input source required by the run loop + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationDidTerminate:) name:NSWorkspaceDidTerminateApplicationNotification object:nil]; + if (getppid() == 1) { + // ppid is launchd (1) => parent terminated already + [self relaunch]; + } + } + return self; +} + +- (void) applicationDidTerminate:(NSNotification *)notification +{ + if (parentProcessId == [[[notification userInfo] valueForKey:@"NSApplicationProcessIdentifier"] intValue]) { + // parent just terminated + [self relaunch]; + } +} + +- (void) relaunch +{ + // [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(actualLaunch) userInfo:nil repeats:NO]; + // NSDate *future = [NSDate dateWithTimeIntervalSinceNow: 5.0 ]; + // [NSThread sleepUntilDate:future]; + + [[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithUTF8String:executablePath]]; + exit(0); +} + +@end + +int main (int argc, const char * argv[]) +{ + if (argc != 3) return EXIT_FAILURE; + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + [[[TerminationListener alloc] initWithExecutablePath:argv[1] parentProcessId:atoi(argv[2])] autorelease]; + [[NSApplication sharedApplication] run]; + + [pool release]; + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 1e156a0ec12c..2ce9771ad5ed 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -1090,16 +1090,19 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application } public boolean isRestartCapable() { - return SystemInfo.isWindows; + return SystemInfo.isWindows || SystemInfo.isMacOSSnowLeopard; } public void restart() { - if (SystemInfo.isWindows) { - Win32Restarter.restart(); + if (SystemInfo.isWindows) { + Win32Restarter.restart(); + } + else if (SystemInfo.isMacOSSnowLeopard) { + MacRestarter.restart(); } else { - exit(); - } + exit(); + } } public boolean isSaving() { diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/MacRestarter.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/MacRestarter.java new file mode 100644 index 000000000000..73dbc2f8d58d --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/MacRestarter.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.application.impl; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.mac.foundation.Foundation; +import com.intellij.ui.mac.foundation.ID; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; + +/** + * User: spLeaner + */ +public class MacRestarter { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.impl.MacRestarter"); + + private MacRestarter() { + } + + @SuppressWarnings({"RedundantArrayCreation"}) + public static void restart() { + final ID autoReleasePool = Foundation.invoke("NSAutoreleasePool", "new"); + final ID app = Foundation.invoke("NSRunningApplication", "currentApplication"); + final ID executableURL = Foundation.invoke(app, Foundation.createSelector("executableURL")); + final ID stringURL = Foundation.invoke(executableURL, Foundation.createSelector("absoluteString")); + + try { + final String executablePath = Foundation.toStringViaUTF8(stringURL); + final URL url = new URL(executablePath); + final String path = url.getPath(); + if (path.contains(".app")) { + final int appIndex = path.indexOf(".app"); + final String appPath = path.substring(0, appIndex + 4); + final String relaunchPath = path.substring(0, path.lastIndexOf('/')) + "/../../bin/relaunch"; + final long processId = Foundation.invoke(app, Foundation.createSelector("processIdentifier")).longValue(); + + final ID args = Foundation.invoke(Foundation.getClass("NSArray"), Foundation.createSelector("arrayWithObjects:"), + new Object[]{Foundation.cfString(appPath), Foundation.cfString(String.valueOf(processId))}); + + Foundation.invoke(Foundation.getClass("NSTask"), Foundation.createSelector("launchedTaskWithLaunchPath:arguments:"), + Foundation.cfString(relaunchPath), args); + } + } + catch (MalformedURLException e) { + LOG.error(e); + } + finally { + Foundation.invoke(autoReleasePool, Foundation.createSelector("release")); + ((ApplicationEx)ApplicationManager.getApplication()).exit(true); + } + } +}