Skip to content

Commit

Permalink
Run Apple driver in a worker process
Browse files Browse the repository at this point in the history
  • Loading branch information
cyanfish committed Mar 7, 2023
1 parent 1d13213 commit 0372839
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 3 deletions.
4 changes: 4 additions & 0 deletions NAPS2.App.Mac/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
<key>CFBundleIconFile</key>
<string>Icon.icns</string>
<key>NSPrincipalClass</key>
<!-- We start as a background application in case we're in worker mode and don't want to show a UI.
If we're in GUI mode we dynamically switch to a foreground application (see MacEntryPoint.cs). -->
<string>NSApplication</string>
<key>LSBackgroundOnly</key>
<true/>
</dict>
</plist>
7 changes: 6 additions & 1 deletion NAPS2.Lib.Mac/EntryPoints/MacEntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ public static int Run(string[] args)
}
if (args.Length > 0 && args[0] == "worker")
{
return WorkerEntryPoint.Run(args.Skip(1).ToArray(), new MacModule());
return MacWorkerEntryPoint.Run(args.Skip(1).ToArray());
}

// We start the process as a background process (by setting LSBackgroundOnly in Info.plist) and only turn it
// into a foreground process once we know we're not in worker or console mode. This ensures workers don't have
// a chance to show in the dock.
MacProcessHelper.TransformThisProcessToForeground();

// Initialize Autofac (the DI framework)
var container = AutoFacHelper.FromModules(
new CommonModule(), new MacModule(), new RecoveryModule(), new ContextModule());
Expand Down
12 changes: 12 additions & 0 deletions NAPS2.Lib.Mac/EntryPoints/MacWorkerEntryPoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using NAPS2.Modules;

namespace NAPS2.EntryPoints;

public static class MacWorkerEntryPoint
{
public static int Run(string[] args)
{
var app = NSApplication.SharedApplication;
return WorkerEntryPoint.Run(args, new MacModule(), () => app.Run(), () => app.Terminate(null));
}
}
26 changes: 26 additions & 0 deletions NAPS2.Lib.Mac/Util/MacProcessHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace NAPS2.Util;

public class MacProcessHelper
{
[DllImport("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices")]
private static extern int TransformProcessType(ref ProcessSerialNumber psn, int type);

private static ProcessSerialNumber _currentProcess = new() { hi = 0, lo = 2 };

public static void TransformThisProcessToBackground()
{
TransformProcessType(ref _currentProcess, 2);
}

public static void TransformThisProcessToForeground()
{
TransformProcessType(ref _currentProcess, 1);
}

[StructLayout(LayoutKind.Sequential)]
private struct ProcessSerialNumber
{
public int hi;
public int lo;
}
}
7 changes: 5 additions & 2 deletions NAPS2.Sdk/Scan/Internal/ScanBridgeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ public ScanBridgeFactory(ScanningContext scanningContext)

public IScanBridge Create(ScanOptions options)
{
// TODO: Ideally Apple could be run in a worker too for stability. But we would need to set up the worker with
// an NSApplication etc. (I assume - trying without gives a Device Offline error)
if (options.Driver == Driver.Apple)
{
// Run ImageCaptureCore in a worker process for added stability
return new WorkerScanBridge(_scanningContext, WorkerType.Native);
}
if (options.Driver == Driver.Sane)
{
// Run SANE in a worker process for added stability
Expand Down

0 comments on commit 0372839

Please sign in to comment.