Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into UI
Browse files Browse the repository at this point in the history
  • Loading branch information
groverlynn committed Apr 4, 2024
2 parents 2356165 + cc0aea0 commit 84d8500
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 53 deletions.
89 changes: 70 additions & 19 deletions input_source.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@

static const char kInstallLocation[] = "/Library/Input Methods/Squirrel.app";
static const CFStringRef kHansInputModeID =
CFSTR("im.rime.inputmethod.Squirrel.Hans");
CFSTR("im.rime.inputmethod.Squirrel.Hans");
static const CFStringRef kHantInputModeID =
CFSTR("im.rime.inputmethod.Squirrel.Hant");
CFSTR("im.rime.inputmethod.Squirrel.Hant");

typedef NS_OPTIONS(int, RimeInputMode) {
DEFAULT_INPUT_MODE = 1 << 0,
HANS_INPUT_MODE = 1 << 0,
HANT_INPUT_MODE = 1 << 1
};
#define HANS_INPUT_MODE (1 << 0)
#define HANT_INPUT_MODE (1 << 1)

#define DEFAULT_INPUT_MODE HANS_INPUT_MODE

int GetEnabledInputModes(void);

void RegisterInputSource(void) {
int enabled_input_modes = GetEnabledInputModes();
if (enabled_input_modes) {
// Already registered.
return;
}
CFURLRef installedLocationURL = CFURLCreateFromFileSystemRepresentation(
NULL, (UInt8*)kInstallLocation, (CFIndex)strlen(kInstallLocation), false);
if (installedLocationURL) {
Expand All @@ -22,36 +28,81 @@ void RegisterInputSource(void) {
}
}

void ActivateInputSource(int enabled_modes) {
void EnableInputSource(void) {
int enabled_input_modes = GetEnabledInputModes();
if (enabled_input_modes) {
// keep user's manually enabled input modes.
return;
}
// neither is enabled, enable the default input mode.
int input_modes_to_enable = DEFAULT_INPUT_MODE;
CFArrayRef sourceList = TISCreateInputSourceList(NULL, true);
for (CFIndex i = 0; i < CFArrayGetCount(sourceList); ++i) {
TISInputSourceRef inputSource =
(TISInputSourceRef)CFArrayGetValueAtIndex(sourceList, i);
CFStringRef sourceID = (CFStringRef)TISGetInputSourceProperty(
inputSource, kTISPropertyInputSourceID);
// NSLog(@"Examining input source: %@", sourceID);
if ((!CFStringCompare(sourceID, kHansInputModeID, 0) &&
((input_modes_to_enable & HANS_INPUT_MODE) != 0)) ||
(!CFStringCompare(sourceID, kHantInputModeID, 0) &&
((input_modes_to_enable & HANT_INPUT_MODE) != 0))) {
CFBooleanRef isEnabled = (CFBooleanRef)TISGetInputSourceProperty(
inputSource, kTISPropertyInputSourceIsEnabled);
if (!CFBooleanGetValue(isEnabled)) {
TISEnableInputSource(inputSource);
NSLog(@"Enabled input source: %@", sourceID);
}
}
}
CFRelease(sourceList);
}

void SelectInputSource(void) {
int enabled_input_modes = GetEnabledInputModes();
int input_modes_to_select = ((enabled_input_modes & DEFAULT_INPUT_MODE) != 0)
? DEFAULT_INPUT_MODE
: enabled_input_modes;
if (!input_modes_to_select) {
NSLog(@"No enabled input sources.");
return;
}
CFArrayRef sourceList = TISCreateInputSourceList(NULL, true);
for (CFIndex i = 0; i < CFArrayGetCount(sourceList); ++i) {
TISInputSourceRef inputSource =
(TISInputSourceRef)CFArrayGetValueAtIndex(sourceList, i);
(TISInputSourceRef)CFArrayGetValueAtIndex(sourceList, i);
CFStringRef sourceID = (CFStringRef)TISGetInputSourceProperty(
inputSource, kTISPropertyInputSourceID);
// NSLog(@"Examining input source: %@", sourceID);
if ((!CFStringCompare(sourceID, kHansInputModeID, 0) &&
((enabled_modes & HANS_INPUT_MODE) != 0)) ||
((input_modes_to_select & HANS_INPUT_MODE) != 0)) ||
(!CFStringCompare(sourceID, kHantInputModeID, 0) &&
((enabled_modes & HANT_INPUT_MODE) != 0))) {
TISEnableInputSource(inputSource);
NSLog(@"Enabled input source: %@", sourceID);
((input_modes_to_select & HANT_INPUT_MODE) != 0))) {
// select the first enabled input mode in Squirrel.
CFBooleanRef isEnabled = (CFBooleanRef)TISGetInputSourceProperty(
inputSource, kTISPropertyInputSourceIsEnabled);
if (!CFBooleanGetValue(isEnabled)) {
continue;
}
CFBooleanRef isSelectable = (CFBooleanRef)TISGetInputSourceProperty(
inputSource, kTISPropertyInputSourceIsSelectCapable);
if (CFBooleanGetValue(isSelectable)) {
CFBooleanRef isSelected = (CFBooleanRef)TISGetInputSourceProperty(
inputSource, kTISPropertyInputSourceIsSelected);
if (!CFBooleanGetValue(isSelected) && CFBooleanGetValue(isSelectable)) {
TISSelectInputSource(inputSource);
NSLog(@"Selected input source: %@", sourceID);
}
break;
}
}
CFRelease(sourceList);
}

void DeactivateInputSource(void) {
void DisableInputSource(void) {
CFArrayRef sourceList = TISCreateInputSourceList(NULL, true);
for (CFIndex i = CFArrayGetCount(sourceList); i > 0; --i) {
TISInputSourceRef inputSource =
(TISInputSourceRef)CFArrayGetValueAtIndex(sourceList, i - 1);
(TISInputSourceRef)CFArrayGetValueAtIndex(sourceList, i - 1);
CFStringRef sourceID = (CFStringRef)TISGetInputSourceProperty(
inputSource, kTISPropertyInputSourceID);
// NSLog(@"Examining input source: %@", sourceID);
Expand All @@ -68,12 +119,12 @@ void DeactivateInputSource(void) {
CFRelease(sourceList);
}

RimeInputMode GetEnabledInputModes(void) {
RimeInputMode input_modes = 0;
int GetEnabledInputModes(void) {
int input_modes = 0;
CFArrayRef sourceList = TISCreateInputSourceList(NULL, true);
for (CFIndex i = 0; i < CFArrayGetCount(sourceList); ++i) {
TISInputSourceRef inputSource =
(TISInputSourceRef)CFArrayGetValueAtIndex(sourceList, i);
(TISInputSourceRef)CFArrayGetValueAtIndex(sourceList, i);
CFStringRef sourceID = (CFStringRef)TISGetInputSourceProperty(
inputSource, kTISPropertyInputSourceID);
// NSLog(@"Examining input source: %@", sourceID);
Expand Down
67 changes: 37 additions & 30 deletions main.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,12 @@
#import <Cocoa/Cocoa.h>
#import <InputMethodKit/InputMethodKit.h>
#import <rime_api.h>

typedef NS_OPTIONS(int, RimeInputMode) {
DEFAULT_INPUT_MODE = 1 << 0,
HANS_INPUT_MODE = 1 << 0,
HANT_INPUT_MODE = 1 << 1
};
#import <string.h>

void RegisterInputSource(void);
RimeInputMode GetEnabledInputModes(void);
void DeactivateInputSource(void);
void ActivateInputSource(RimeInputMode input_modes);
void DisableInputSource(void);
void EnableInputSource(void);
void SelectInputSource(void);

// Each input method needs a unique connection name.
// Note that periods and spaces are not allowed in the connection name.
Expand All @@ -23,7 +18,7 @@ int main(int argc, char* argv[]) {
if (argc > 1 && !strcmp("--quit", argv[1])) {
NSString* bundleId = [NSBundle mainBundle].bundleIdentifier;
NSArray<NSRunningApplication*>* runningSquirrels =
[NSRunningApplication runningApplicationsWithBundleIdentifier:bundleId];
[NSRunningApplication runningApplicationsWithBundleIdentifier:bundleId];
for (NSRunningApplication* squirrelApp in runningSquirrels) {
[squirrelApp terminate];
}
Expand All @@ -32,23 +27,35 @@ int main(int argc, char* argv[]) {

if (argc > 1 && !strcmp("--reload", argv[1])) {
[[NSDistributedNotificationCenter defaultCenter]
postNotificationName:@"SquirrelReloadNotification"
object:nil];
postNotificationName:@"SquirrelReloadNotification"
object:nil];
return 0;
}

if (argc > 1 && !strcmp("--install", argv[1])) {
// register and enable Squirrel
if (argc > 1 && (!strcmp("--register-input-source", argv[1]) ||
!strcmp("--install", argv[1]))) {
RegisterInputSource();
int input_modes = GetEnabledInputModes();
DeactivateInputSource();
ActivateInputSource(input_modes ?: DEFAULT_INPUT_MODE);
return 0;
}

if (argc > 1 && !strcmp("--enable-input-source", argv[1])) {
EnableInputSource();
return 0;
}

if (argc > 1 && !strcmp("--disable-input-source", argv[1])) {
DisableInputSource();
return 0;
}

if (argc > 1 && !strcmp("--select-input-source", argv[1])) {
SelectInputSource();
return 0;
}

if (argc > 1 && !strcmp("--build", argv[1])) {
// notification
show_notification("deploy_update");
show_message("deploy_update", "deploy");
// build all schemas in current directory
RIME_STRUCT(RimeTraits, builder_traits);
builder_traits.app_name = "rime.squirrel-builder";
Expand All @@ -59,39 +66,39 @@ int main(int argc, char* argv[]) {

if (argc > 1 && !strcmp("--sync", argv[1])) {
[[NSDistributedNotificationCenter defaultCenter]
postNotificationName:@"SquirrelSyncNotification"
object:nil];
postNotificationName:@"SquirrelSyncNotification"
object:nil];
return 0;
}

@autoreleasepool {
// find the bundle identifier and then initialize the input method server
NSBundle* main = [NSBundle mainBundle];
IMKServer* server __unused =
[[IMKServer alloc] initWithName:kConnectionName
bundleIdentifier:main.bundleIdentifier];
[[IMKServer alloc] initWithName:kConnectionName
bundleIdentifier:main.bundleIdentifier];

// load the bundle explicitly because in this case the input method is a
// background only application
[main loadNibNamed:@"MainMenu"
owner:NSApplication.sharedApplication
topLevelObjects:nil];
owner:[NSApplication sharedApplication]
topLevelObjects:nil];

// opencc will be configured with relative dictionary paths
[[NSFileManager defaultManager]
changeCurrentDirectoryPath:main.sharedSupportPath];
changeCurrentDirectoryPath:main.sharedSupportPath];

if (NSApp.squirrelAppDelegate.problematicLaunchDetected) {
NSLog(@"Problematic launch detected!");
NSArray* args = @[ @"Problematic launch detected! \
Squirrel may be suffering a crash due to imporper configuration. \
Revert previous modifications to see if the problem recurs." ];
[NSTask
launchedTaskWithExecutableURL:[NSURL fileURLWithPath:@"/usr/bin/say"
isDirectory:NO]
arguments:args
error:nil
terminationHandler:nil];
launchedTaskWithExecutableURL:[NSURL fileURLWithPath:@"/usr/bin/say"
isDirectory:NO]
arguments:args
error:nil
terminationHandler:nil];
} else {
[NSApp.squirrelAppDelegate setupRime];
[NSApp.squirrelAppDelegate startRimeWithFullCheck:false];
Expand Down
12 changes: 8 additions & 4 deletions scripts/postinstall
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
#!/bin/bash
set -e

login_user=`/usr/bin/stat -f%Su /dev/console`
squirrel_app_root="${DSTROOT}/Squirrel.app"
squirrel_executable="${squirrel_app_root}/Contents/MacOS/Squirrel"
rime_package_installer="${squirrel_app_root}/Contents/MacOS/rime-install"
rime_shared_data_path="${squirrel_app_root}/Contents/SharedSupport"

/usr/bin/sudo -u "${login_user}" /usr/bin/killall Squirrel > /dev/null
/usr/bin/sudo -u "${login_user}" /usr/bin/killall Squirrel > /dev/null || true

"${squirrel_executable}" --register-input-source

if [ -z "${RIME_NO_PREBUILD}" ]; then
pushd "${rime_shared_data_path}" > /dev/null
"${squirrel_executable}" --build
popd > /dev/null
fi

/usr/bin/sudo -u "${login_user}" "${squirrel_executable}" --install
fi && (
/usr/bin/sudo -u "${login_user}" "${squirrel_executable}" --enable-input-source
/usr/bin/sudo -u "${login_user}" "${squirrel_executable}" --select-input-source
)

0 comments on commit 84d8500

Please sign in to comment.