forked from mia/Aegisub
Fix restarting the application after changing the UI language on OS X
This commit is contained in:
parent
ebb13d96ec
commit
7780fadfc6
6 changed files with 40 additions and 121 deletions
|
@ -40,40 +40,12 @@ namespace agi {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
namespace util {
|
namespace util {
|
||||||
/// @brief Get the full name of bundle.
|
|
||||||
/// @return Full name of bundle.
|
|
||||||
/// Get the full name of the bundle itself.
|
|
||||||
///
|
|
||||||
/// @warning May return "" if the current executable is not inside a bundle.
|
|
||||||
std::string GetBundlePath();
|
|
||||||
|
|
||||||
/// @brief Get the esources directory.
|
/// @brief Get the esources directory.
|
||||||
/// @return Resources directory.
|
/// @return Resources directory.
|
||||||
///
|
///
|
||||||
/// Mainly for user interface elements such as graphics and strings
|
/// Mainly for user interface elements such as graphics and strings
|
||||||
std::string GetBundleResourcesDirectory();
|
std::string GetBundleResourcesDirectory();
|
||||||
|
|
||||||
/// @brief Get the built-in plugins directory.
|
|
||||||
/// @return Built-in plugins directory.
|
|
||||||
///
|
|
||||||
/// This is generaly only used by native Carbon and Cocoa applications. It is
|
|
||||||
/// not for general shared libraries.
|
|
||||||
std::string GetBundleBuiltInPlugInsDirectory();
|
|
||||||
|
|
||||||
/// @brief Get the private Frameworks directory.
|
|
||||||
/// @return Private Framework directory.
|
|
||||||
///
|
|
||||||
/// These are suitable locations for shared libraries.
|
|
||||||
std::string GetBundlePrivateFrameworksDirectory();
|
|
||||||
|
|
||||||
/// @brief Get the shared Frameworks directory.
|
|
||||||
/// @return Shared Framework directory.
|
|
||||||
///
|
|
||||||
/// @see GetBundlePrivateFrameworksDirectory()
|
|
||||||
/// @note Does anyone know the difference between private and shared frameworks
|
|
||||||
/// inside a bundle?
|
|
||||||
std::string GetBundleSharedFrameworksDirectory();
|
|
||||||
|
|
||||||
/// @brief Get the shared support directory
|
/// @brief Get the shared support directory
|
||||||
/// @return Shared support directory
|
/// @return Shared support directory
|
||||||
///
|
///
|
||||||
|
@ -81,18 +53,6 @@ std::string GetBundleSharedFrameworksDirectory();
|
||||||
/// bundle is considered read-only.)
|
/// bundle is considered read-only.)
|
||||||
std::string GetBundleSharedSupportDirectory();
|
std::string GetBundleSharedSupportDirectory();
|
||||||
|
|
||||||
/// @brief Get the main executable path.
|
|
||||||
/// @return Main executable path.
|
|
||||||
///
|
|
||||||
/// The binary run when the user launches the bundle from Finder.
|
|
||||||
std::string GetBundleExecutablePath();
|
|
||||||
|
|
||||||
/// @brief Get the auxillary executable path.
|
|
||||||
/// @return Auxillary executable path.
|
|
||||||
///
|
|
||||||
/// Pass the basename of the executable to get the path.
|
|
||||||
std::string GetBundleAuxillaryExecutablePath(std::string const& executableName);
|
|
||||||
|
|
||||||
std::string GetApplicationSupportDirectory();
|
std::string GetApplicationSupportDirectory();
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace agi
|
} // namespace agi
|
||||||
|
|
|
@ -25,8 +25,7 @@ static std::string EmptyIfNil(NSString *string) {
|
||||||
return string ? [string UTF8String] : "";
|
return string ? [string UTF8String] : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace agi {
|
namespace agi { namespace osx {
|
||||||
namespace osx {
|
|
||||||
AppNapDisabler::AppNapDisabler(std::string reason) : handle(nullptr) {
|
AppNapDisabler::AppNapDisabler(std::string reason) : handle(nullptr) {
|
||||||
if (reason.empty()) reason = "Loading";
|
if (reason.empty()) reason = "Loading";
|
||||||
auto processInfo = [NSProcessInfo processInfo];
|
auto processInfo = [NSProcessInfo processInfo];
|
||||||
|
@ -42,14 +41,9 @@ AppNapDisabler::~AppNapDisabler() {
|
||||||
[processInfo endActivity:(id)handle];
|
[processInfo endActivity:(id)handle];
|
||||||
[(id)handle release];
|
[(id)handle release];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
namespace util {
|
|
||||||
|
|
||||||
std::string GetBundlePath() {
|
|
||||||
@autoreleasepool {
|
|
||||||
return EmptyIfNil([[NSBundle mainBundle] bundlePath]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
namespace util {
|
||||||
|
|
||||||
std::string GetBundleResourcesDirectory() {
|
std::string GetBundleResourcesDirectory() {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
@ -57,48 +51,16 @@ std::string GetBundleResourcesDirectory() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetBundleExecutablePath() {
|
|
||||||
@autoreleasepool {
|
|
||||||
return EmptyIfNil([[NSBundle mainBundle] executablePath]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetBundleBuiltInPlugInsDirectory() {
|
|
||||||
@autoreleasepool {
|
|
||||||
return EmptyIfNil([[NSBundle mainBundle] builtInPlugInsPath]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetBundlePrivateFrameworksDirectory() {
|
|
||||||
@autoreleasepool {
|
|
||||||
return EmptyIfNil([[NSBundle mainBundle] privateFrameworksPath]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetBundleSharedFrameworksDirectory() {
|
|
||||||
@autoreleasepool {
|
|
||||||
return EmptyIfNil([[NSBundle mainBundle] sharedFrameworksPath]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetBundleSharedSupportDirectory() {
|
std::string GetBundleSharedSupportDirectory() {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
return EmptyIfNil([[NSBundle mainBundle] sharedSupportPath]);
|
return EmptyIfNil([[NSBundle mainBundle] sharedSupportPath]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetBundleAuxillaryExecutablePath(std::string const& executableName) {
|
|
||||||
@autoreleasepool {
|
|
||||||
NSString *name = [NSString stringWithUTF8String:executableName.c_str()];
|
|
||||||
return EmptyIfNil([[NSBundle mainBundle]pathForAuxiliaryExecutable:name]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetApplicationSupportDirectory() {
|
std::string GetApplicationSupportDirectory() {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
return EmptyIfNil([NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject]);
|
return EmptyIfNil([NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
|
@ -59,3 +59,10 @@ void SetPlaceholderText(wxWindow *window, wxString const& placeholder) {
|
||||||
cell.placeholderString = wxCFStringRef(placeholder).AsNSString();
|
cell.placeholderString = wxCFStringRef(placeholder).AsNSString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RestartAegisub() {
|
||||||
|
auto helperPath = [NSBundle.mainBundle pathForAuxiliaryExecutable:@"restart-helper"];
|
||||||
|
if (helperPath)
|
||||||
|
[NSTask launchedTaskWithLaunchPath:helperPath
|
||||||
|
arguments:@[NSBundle.mainBundle.executablePath]];
|
||||||
|
}
|
||||||
|
|
|
@ -94,23 +94,17 @@ int SmallestPowerOf2(int x) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __WXMAC__
|
||||||
void RestartAegisub() {
|
void RestartAegisub() {
|
||||||
config::opt->Flush();
|
config::opt->Flush();
|
||||||
|
|
||||||
#if defined(__WXMSW__)
|
#if defined(__WXMSW__)
|
||||||
wxExecute("\"" + wxStandardPaths::Get().GetExecutablePath() + "\"");
|
wxExecute("\"" + wxStandardPaths::Get().GetExecutablePath() + "\"");
|
||||||
#elif defined(__WXMAC__)
|
|
||||||
std::string bundle_path = agi::util::GetBundlePath();
|
|
||||||
std::string helper_path = agi::util::GetBundleAuxillaryExecutablePath("restart-helper");
|
|
||||||
if (bundle_path.empty() || helper_path.empty()) return;
|
|
||||||
|
|
||||||
wxString exec = fmt_wx("\"%s\" /usr/bin/open -n \"%s\"'", helper_path, bundle_path);
|
|
||||||
LOG_I("util/restart/exec") << exec.utf8_str();
|
|
||||||
wxExecute(exec);
|
|
||||||
#else
|
#else
|
||||||
wxExecute(wxStandardPaths::Get().GetExecutablePath());
|
wxExecute(wxStandardPaths::Get().GetExecutablePath());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool ForwardMouseWheelEvent(wxWindow *source, wxMouseEvent &evt) {
|
bool ForwardMouseWheelEvent(wxWindow *source, wxMouseEvent &evt) {
|
||||||
wxWindow *target = wxFindWindowAtPoint(wxGetMousePosition());
|
wxWindow *target = wxFindWindowAtPoint(wxGetMousePosition());
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
include ../Makefile.inc
|
include ../Makefile.inc
|
||||||
|
|
||||||
ifeq (yes, $(BUILD_DARWIN))
|
ifeq (yes, $(BUILD_DARWIN))
|
||||||
osx-bundle-restart-helper: osx-bundle-restart-helper.c
|
osx-bundle-restart-helper: osx-bundle-restart-helper.m
|
||||||
$(BIN_CC) -o osx-bundle-restart-helper osx-bundle-restart-helper.c
|
$(BIN_CC) -o osx-bundle-restart-helper -fmodules osx-bundle-restart-helper.m
|
||||||
CLEANFILES += osx-bundle-restart-helper
|
CLEANFILES += osx-bundle-restart-helper
|
||||||
all: osx-bundle-restart-helper
|
all: osx-bundle-restart-helper
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include <sys/event.h>
|
#include <sys/event.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
@import Foundation;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Return codes:
|
Return codes:
|
||||||
1: Error in kqueue()
|
1: Error in kqueue()
|
||||||
|
@ -42,57 +44,51 @@ Return codes:
|
||||||
|
|
||||||
If none of those happen the requested command is execve()'d.
|
If none of those happen the requested command is execve()'d.
|
||||||
*/
|
*/
|
||||||
int main(int argc, char *argv[], char *env[])
|
int main(int argc, char *argv[], char *env[]) {
|
||||||
{
|
int queue = kqueue();
|
||||||
int waitpid = getppid();
|
if (queue == -1) {
|
||||||
int queue, nchange;
|
|
||||||
struct kevent event[1];
|
|
||||||
struct kevent change[1];
|
|
||||||
struct timespec timeout = { 30, 0 };
|
|
||||||
|
|
||||||
if ((queue = kqueue()) == -1)
|
|
||||||
{
|
|
||||||
perror("Error in: kqueue()");
|
perror("Error in: kqueue()");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct kevent event[1];
|
||||||
EV_SET(event,
|
EV_SET(event,
|
||||||
waitpid,
|
getppid(),
|
||||||
EVFILT_PROC,
|
EVFILT_PROC,
|
||||||
EV_ADD|EV_ENABLE|EV_ONESHOT,
|
EV_ADD|EV_ENABLE|EV_ONESHOT,
|
||||||
NOTE_EXIT,
|
NOTE_EXIT,
|
||||||
0, 0);
|
0, 0);
|
||||||
|
|
||||||
printf("restart-helper: waiting for pid %d\n", waitpid);
|
printf("restart-helper: waiting for pid %d\n", getppid());
|
||||||
|
|
||||||
nchange = kevent(queue, change, 1, event, 1, &timeout);
|
struct kevent change[1];
|
||||||
|
struct timespec timeout = { 30, 0 };
|
||||||
|
int nchange = kevent(queue, change, 1, event, 1, &timeout);
|
||||||
|
|
||||||
if (nchange < 0)
|
if (nchange < 0) {
|
||||||
{
|
|
||||||
perror("restart-helper: Error in kevent()");
|
perror("restart-helper: Error in kevent()");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else if (nchange == 0)
|
if (nchange == 0) {
|
||||||
{
|
printf("restart-helper: Timed out waiting for pid %d\n", getppid());
|
||||||
printf("restart-helper: Timed out waiting for pid %d\n", waitpid);
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
else if (change[0].flags & EV_ERROR)
|
if (change[0].flags & EV_ERROR) {
|
||||||
{
|
|
||||||
perror("restart-helper: Error in event");
|
perror("restart-helper: Error in event");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
close(queue);
|
|
||||||
|
|
||||||
printf("restart-helper: Executing '%s'\n", argv[1]);
|
close(queue);
|
||||||
|
|
||||||
if (execve(argv[1], argv+1, env) == -1)
|
printf("restart-helper: Executing '%s'\n", argv[1]);
|
||||||
{
|
|
||||||
perror("restart-helper: Error in execve()");
|
@try {
|
||||||
return 4;
|
[NSTask launchedTaskWithLaunchPath:[NSString stringWithUTF8String:argv[1]] arguments:@[]];
|
||||||
}
|
|
||||||
return 0; /* never reached */
|
|
||||||
}
|
}
|
||||||
|
@catch (NSException *e) {
|
||||||
|
printf("restart-helper: Error launching program: %s\n", e.description.UTF8String);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in a new issue