diff --git a/app/AppDelegate.m b/app/AppDelegate.m index 16bc9202..009bd3aa 100644 --- a/app/AppDelegate.m +++ b/app/AppDelegate.m @@ -22,24 +22,33 @@ // user about what this is doing, and ideally use Touch ID. // or add an alias in the current shell environment, // which wouldn't require any special privileges - dispatch_async(dispatch_get_main_queue(), ^{ - createSymlinkWithAuthorization(); - }); + // dispatch_async(dispatch_get_main_queue(), ^{ + // createSymlinkWithAuthorization(); + // }); // show status menu NSMenu *menu = [[NSMenu alloc] init]; - - NSMenuItem *openSettingsItem = [[NSMenuItem alloc] initWithTitle:@"Settings..." action:@selector(openSettingsWindow) keyEquivalent:@""]; - [menu addItem:openSettingsItem]; - [menu addItem:[NSMenuItem separatorItem]]; [menu addItemWithTitle:@"Quit Ollama" action:@selector(quit) keyEquivalent:@"q"]; self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; + [self.statusItem addObserver:self forKeyPath:@"button.effectiveAppearance" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil]; + self.statusItem.menu = menu; - NSImage *statusImage = [NSImage imageNamed:@"icon"]; + [self showIcon]; +} + +-(void) showIcon { + NSAppearance* appearance = self.statusItem.button.effectiveAppearance; + NSString* appearanceName = (NSString*)(appearance.name); + NSString* iconName = [[appearanceName lowercaseString] containsString:@"dark"] ? @"iconDark" : @"icon"; + NSImage* statusImage = [NSImage imageNamed:iconName]; [statusImage setTemplate:YES]; self.statusItem.button.image = statusImage; } +-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + [self showIcon]; +} + - (void)openSettingsWindow { if (!self.settingsWindow) { // Create the settings window centered on the screen @@ -66,57 +75,8 @@ } } -#pragma mark - NSToolbarDelegate - -- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSToolbarItemIdentifier)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag { - NSToolbarItem *toolbarItem = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier]; - - if ([itemIdentifier isEqualToString:@"General"]) { - toolbarItem.label = @"General"; - toolbarItem.paletteLabel = @"General"; - toolbarItem.toolTip = @"General Settings"; - toolbarItem.image = [NSImage imageWithSystemSymbolName:@"gear" accessibilityDescription:nil]; // Monochrome symbol - toolbarItem.target = self; - toolbarItem.action = @selector(switchTabs:); - } - - if ([itemIdentifier isEqualToString:@"Networking"]) { - toolbarItem.label = @"Networking"; - toolbarItem.paletteLabel = @"Networking"; - toolbarItem.toolTip = @"Networking Settings"; - toolbarItem.image = [NSImage imageWithSystemSymbolName:@"network" accessibilityDescription:nil]; // Monochrome symbol - toolbarItem.target = self; - toolbarItem.action = @selector(switchTabs:); - } - // Create other items with their respective images and selectors here... - - return toolbarItem; -} - -- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar { - return @[ - NSToolbarFlexibleSpaceItemIdentifier, - @"General", - @"Networking", - NSToolbarFlexibleSpaceItemIdentifier - ]; -} - -- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar { - return @[ - NSToolbarFlexibleSpaceItemIdentifier, - @"General", - @"Networking", - NSToolbarFlexibleSpaceItemIdentifier - ]; -} - -- (void)switchTabs:(NSToolbarItem *)sender { - // Your code to switch tabs based on the sender's identifier -} - - (void)quit { - Quit(); + [NSApp stop:nil]; } @end @@ -132,12 +92,13 @@ int askToMoveToApplications() { [alert setInformativeText:@"Ollama works best when run from the Applications directory."]; [alert addButtonWithTitle:@"Move to Applications"]; [alert addButtonWithTitle:@"Don't move"]; - + [NSApp activateIgnoringOtherApps:YES]; if ([alert runModal] != NSAlertFirstButtonReturn) { return 0; } + // move to applications NSString *applicationsPath = @"/Applications"; NSString *newPath = [applicationsPath stringByAppendingPathComponent:@"Ollama.app"]; diff --git a/app/app_darwin.go b/app/app_darwin.go index bf264038..2f6e5dbb 100644 --- a/app/app_darwin.go +++ b/app/app_darwin.go @@ -33,21 +33,22 @@ func run() { panic(err) } - resources := filepath.Join(filepath.Dir(exe), "..", "Resources") - ctx, cancel := context.WithCancel(context.Background()) var done chan int - done, err = SpawnServer(ctx, filepath.Join(resources, "ollama")) + done, err = SpawnServer(ctx, filepath.Join(filepath.Dir(exe), "..", "Resources", "ollama")) if err != nil { slog.Error(fmt.Sprintf("Failed to spawn ollama server %s", err)) done = make(chan int, 1) done <- 1 } - // Run the native app + // Run the native macOS app + // Note: this will block until the app is closed C.run() + slog.Info("ollama macOS app closed") + cancel() slog.Info("Waiting for ollama server to shutdown...") if done != nil { diff --git a/app/app_darwin.m b/app/app_darwin.m index c2366af7..34ce69d1 100644 --- a/app/app_darwin.m +++ b/app/app_darwin.m @@ -38,4 +38,4 @@ void killOtherInstances() { [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; } } -} \ No newline at end of file +} diff --git a/app/app_windows.go b/app/app_windows.go index b4b84ced..91ff04ab 100644 --- a/app/app_windows.go +++ b/app/app_windows.go @@ -13,10 +13,10 @@ import ( "strings" "syscall" - "github.com/jmorganca/ollama/app/lifecycle" - "github.com/jmorganca/ollama/app/store" - "github.com/jmorganca/ollama/app/tray" - "github.com/jmorganca/ollama/app/updater" + "github.com/ollama/ollama/app/lifecycle" + "github.com/ollama/ollama/app/store" + "github.com/ollama/ollama/app/tray" + "github.com/ollama/ollama/app/updater" ) func init() { diff --git a/app/darwin/Ollama.app/Contents/Resources/icon.png b/app/darwin/Ollama.app/Contents/Resources/icon.png index 1e826e03..385972c2 100644 Binary files a/app/darwin/Ollama.app/Contents/Resources/icon.png and b/app/darwin/Ollama.app/Contents/Resources/icon.png differ diff --git a/app/darwin/Ollama.app/Contents/Resources/icon@2x.png b/app/darwin/Ollama.app/Contents/Resources/icon@2x.png index 5f8e6451..77fd58b8 100644 Binary files a/app/darwin/Ollama.app/Contents/Resources/icon@2x.png and b/app/darwin/Ollama.app/Contents/Resources/icon@2x.png differ diff --git a/app/darwin/Ollama.app/Contents/Resources/iconDark.png b/app/darwin/Ollama.app/Contents/Resources/iconDark.png index 451cc9d0..f3c087b6 100644 Binary files a/app/darwin/Ollama.app/Contents/Resources/iconDark.png and b/app/darwin/Ollama.app/Contents/Resources/iconDark.png differ diff --git a/app/darwin/Ollama.app/Contents/Resources/iconDark@2x.png b/app/darwin/Ollama.app/Contents/Resources/iconDark@2x.png index 88ff572c..acd9452b 100644 Binary files a/app/darwin/Ollama.app/Contents/Resources/iconDark@2x.png and b/app/darwin/Ollama.app/Contents/Resources/iconDark@2x.png differ diff --git a/app/lifecycle/lifecycle.go b/app/lifecycle/lifecycle.go deleted file mode 100644 index ab624e81..00000000 --- a/app/lifecycle/lifecycle.go +++ /dev/null @@ -1,92 +0,0 @@ -package lifecycle - -import ( - "context" - "fmt" - "log" - "log/slog" - "os" - "os/signal" - "syscall" - - "github.com/ollama/ollama/app/store" - "github.com/ollama/ollama/app/tray" -) - -func Run() { - InitLogging() - - ctx, cancel := context.WithCancel(context.Background()) - var done chan int - - t, err := tray.NewTray() - if err != nil { - log.Fatalf("Failed to start: %s", err) - } - callbacks := t.GetCallbacks() - - signals := make(chan os.Signal, 1) - signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) - - go func() { - slog.Debug("starting callback loop") - for { - select { - case <-callbacks.Quit: - slog.Debug("quit called") - t.Quit() - case <-signals: - slog.Debug("shutting down due to signal") - t.Quit() - case <-callbacks.Update: - err := DoUpgrade(cancel, done) - if err != nil { - slog.Warn(fmt.Sprintf("upgrade attempt failed: %s", err)) - } - case <-callbacks.ShowLogs: - ShowLogs() - case <-callbacks.DoFirstUse: - err := GetStarted() - if err != nil { - slog.Warn(fmt.Sprintf("Failed to launch getting started shell: %s", err)) - } - } - } - }() - - // Are we first use? - if !store.GetFirstTimeRun() { - slog.Debug("First time run") - err = t.DisplayFirstUseNotification() - if err != nil { - slog.Debug(fmt.Sprintf("XXX failed to display first use notification %v", err)) - } - store.SetFirstTimeRun(true) - } else { - slog.Debug("Not first time, skipping first run notification") - } - - if IsServerRunning(ctx) { - slog.Info("Detected another instance of ollama running, exiting") - os.Exit(1) - } else { - done, err = SpawnServer(ctx, CLIName) - if err != nil { - // TODO - should we retry in a backoff loop? - // TODO - should we pop up a warning and maybe add a menu item to view application logs? - slog.Error(fmt.Sprintf("Failed to spawn ollama server %s", err)) - done = make(chan int, 1) - done <- 1 - } - } - - StartBackgroundUpdaterChecker(ctx, t.UpdateAvailable) - - t.Run() - cancel() - slog.Info("Waiting for ollama server to shutdown...") - if done != nil { - <-done - } - slog.Info("Ollama app exiting") -} diff --git a/app/server_unix.go b/app/server_darwin.go similarity index 96% rename from app/server_unix.go rename to app/server_darwin.go index e0d45c8a..152f3483 100644 --- a/app/server_unix.go +++ b/app/server_darwin.go @@ -1,5 +1,3 @@ -//go:build !windows - package main import ( diff --git a/scripts/publish.sh b/scripts/publish.sh deleted file mode 100755 index 5bf15dcb..00000000 --- a/scripts/publish.sh +++ /dev/null @@ -1,25 +0,0 @@ -# Set your variables here. -REPO="jmorganca/ollama" - -# Check if VERSION is set -if [[ -z "${VERSION}" ]]; then - echo "VERSION is not set. Please set the VERSION environment variable." - exit 1 -fi - -OS=$(go env GOOS) - -./script/build_${OS}.sh - -# Create a new tag if it doesn't exist. -if ! git rev-parse v$VERSION >/dev/null 2>&1; then - git tag v$VERSION -fi - -git push origin v$VERSION - -# Create a new release. -gh release create -p v$VERSION -t v$VERSION - -# Upload the zip file. -gh release upload v$VERSION ./dist/* --clobber diff --git a/scripts/run_darwin.sh b/scripts/run_darwin.sh index 89a32a2f..f4a736b2 100755 --- a/scripts/run_darwin.sh +++ b/scripts/run_darwin.sh @@ -2,6 +2,7 @@ set -e +rm -rf $TMPDIR/Ollama.app cp -R app/darwin/Ollama.app $TMPDIR/Ollama.app mkdir -p $TMPDIR/Ollama.app/Contents/Resources $TMPDIR/Ollama.app/Contents/MacOS go build -o $TMPDIR/Ollama.app/Contents/Resources/ollama .