diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /toolkit/components/remote/nsMacRemoteServer.mm | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/remote/nsMacRemoteServer.mm')
-rw-r--r-- | toolkit/components/remote/nsMacRemoteServer.mm | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/toolkit/components/remote/nsMacRemoteServer.mm b/toolkit/components/remote/nsMacRemoteServer.mm new file mode 100644 index 0000000000..0936d4d2fd --- /dev/null +++ b/toolkit/components/remote/nsMacRemoteServer.mm @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=2: + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#import <Cocoa/Cocoa.h> +#import <CoreServices/CoreServices.h> + +#include "MacAutoreleasePool.h" +#include "nsCOMPtr.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsIWindowMediator.h" +#include "nsIWidget.h" +#include "nsICommandLineRunner.h" +#include "nsICommandLine.h" +#include "nsCommandLine.h" +#include "nsIDocShell.h" +#include "nsMacRemoteServer.h" +#include "nsXPCOM.h" +#include "RemoteUtils.h" + +CFDataRef messageServerCallback(CFMessagePortRef aLocal, int32_t aMsgid, CFDataRef aData, + void* aInfo) { + // One of the clients submitted a structure. + static_cast<nsMacRemoteServer*>(aInfo)->HandleCommandLine(aData); + + return NULL; +} + +// aData contains serialized Dictionary, which in turn contains command line arguments +void nsMacRemoteServer::HandleCommandLine(CFDataRef aData) { + mozilla::MacAutoreleasePool pool; + + if (aData) { + NSDictionary* dict = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData*)aData]; + if (dict && [dict isKindOfClass:[NSDictionary class]]) { + NSArray* args = dict[@"args"]; + if (!args) { + NS_ERROR("Wrong parameters passed to the Remote Server"); + return; + } + + nsCOMPtr<nsICommandLineRunner> cmdLine(new nsCommandLine()); + + // Converting Objective-C array into a C array, + // which nsICommandLineRunner understands. + int argc = [args count]; + const char** argv = new const char*[argc]; + for (int i = 0; i < argc; i++) { + const char* arg = [[args objectAtIndex:i] UTF8String]; + argv[i] = arg; + } + + nsresult rv = cmdLine->Init(argc, argv, nullptr, nsICommandLine::STATE_REMOTE_AUTO); + + // Cleaning up C array. + delete[] argv; + + if (NS_FAILED(rv)) { + NS_ERROR("Error initializing command line."); + return; + } + + // Processing the command line, passed from a remote instance + // in the current instance. + cmdLine->Run(); + + // And bring the app's window to front. + [[NSRunningApplication currentApplication] + activateWithOptions:NSApplicationActivateIgnoringOtherApps]; + } + } +} + +nsresult nsMacRemoteServer::Startup(const char* aAppName, const char* aProfileName) { + // This is the first instance ever. + // Let's register a notification listener here, + // In case future instances would want to notify us about command line arguments + // passed to them. Note, that if mozilla process is restarting, we still need to + // register for notifications. + + mozilla::MacAutoreleasePool pool; + + nsString className; + BuildClassName(aAppName, aProfileName, className); + + NSString* serverNameString = + [NSString stringWithCharacters:reinterpret_cast<const unichar*>(className.get()) + length:className.Length()]; + + CFMessagePortContext context; + context.copyDescription = NULL; + context.info = this; + context.release = NULL; + context.retain = NULL; + context.version = NULL; + mMessageServer = CFMessagePortCreateLocal(NULL, (CFStringRef)serverNameString, + messageServerCallback, &context, NULL); + if (!mMessageServer) { + return NS_ERROR_FAILURE; + } + mRunLoopSource = CFMessagePortCreateRunLoopSource(NULL, mMessageServer, 0); + if (!mRunLoopSource) { + CFRelease(mMessageServer); + mMessageServer = NULL; + return NS_ERROR_FAILURE; + } + CFRunLoopRef runLoop = CFRunLoopGetMain(); + CFRunLoopAddSource(runLoop, mRunLoopSource, kCFRunLoopDefaultMode); + + return NS_OK; +} + +void nsMacRemoteServer::Shutdown() { + // 1) Invalidate server connection + if (mMessageServer) { + CFMessagePortInvalidate(mMessageServer); + } + + // 2) Release run loop source + if (mRunLoopSource) { + CFRelease(mRunLoopSource); + mRunLoopSource = NULL; + } + + // 3) Release server connection + if (mMessageServer) { + CFRelease(mMessageServer); + mMessageServer = NULL; + } +} |