Skip to content

Commit 5b04a49

Browse files
committed
macOS: ObjC NSApp activation to fix window display when launched as subprocess
1 parent 7cf05b9 commit 5b04a49

3 files changed

Lines changed: 35 additions & 14 deletions

File tree

mode/CppMode.jar

-11 Bytes
Binary file not shown.

src/Processing.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
#include <sstream>
2626
#include <fstream>
2727
#include <chrono>
28+
#ifdef __APPLE__
29+
#include <objc/runtime.h>
30+
#include <objc/message.h>
31+
#include <dlfcn.h>
32+
#endif
2833
#ifndef _WIN32
2934
#include <thread>
3035
#endif
@@ -3364,17 +3369,28 @@ void PApplet::run(){
33643369
initPerlin(0); // initialize noise table with default seed
33653370

33663371
#if defined(__APPLE__)
3367-
// Register with macOS window server -- required when launched as a subprocess
3368-
// (e.g. from Processing IDE). Without this, GLFW cannot create windows.
3372+
// Make this process a foreground app so GLFW can create windows.
3373+
// Required when launched as a subprocess from the Processing IDE.
3374+
// Uses ObjC runtime directly -- no .m file needed.
33693375
{
3370-
void* handle = dlopen("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices", RTLD_LAZY);
3371-
if (handle) {
3372-
typedef int (*TFunc)(void*);
3373-
TFunc f = (TFunc)dlsym(handle, "TransformProcessType");
3374-
if (f) {
3375-
// kProcessTransformToForegroundApplication = 1
3376-
unsigned int psn[2] = {0, 1}; // kCurrentProcess
3377-
f(psn);
3376+
void* appkit = dlopen("/System/Library/Frameworks/AppKit.framework/AppKit", RTLD_LAZY);
3377+
if (appkit) {
3378+
// id NSApp = [NSApplication sharedApplication]
3379+
typedef void* (*id_imp)(void*, void*);
3380+
typedef void (*void_imp)(void*, void*, long);
3381+
typedef void (*void_imp2)(void*, void*, bool);
3382+
void* cls = (void*)dlsym(RTLD_DEFAULT, "OBJC_CLASS_$_NSApplication");
3383+
if (cls) {
3384+
void* sel_shared = sel_registerName("sharedApplication");
3385+
void* sel_policy = sel_registerName("setActivationPolicy:");
3386+
void* sel_activate = sel_registerName("activateIgnoringOtherApps:");
3387+
id_imp msgSend = (id_imp) objc_msgSend;
3388+
void* app = msgSend(cls, (void*)sel_shared);
3389+
if (app) {
3390+
// NSApplicationActivationPolicyRegular = 0
3391+
((void_imp)objc_msgSend)(app, (void*)sel_policy, 0L);
3392+
((void_imp2)objc_msgSend)(app, (void*)sel_activate, true);
3393+
}
33783394
}
33793395
}
33803396
}

src/java/CppBuild.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,9 +1494,14 @@ private File writeSketchImpl(RunnerListener listener) throws IOException {
14941494
boolean isTypeSpec = item instanceof TypeDef td && td.name().contains("<");
14951495
boolean isTemplatedVar = item instanceof VariableDecl vd
14961496
&& !vd.templateParams().isEmpty();
1497-
boolean isTemplateInstVar = item instanceof VariableDecl vd2
1498-
&& vd2.type() instanceof processing.mode.cpp.NamedType nt
1499-
&& !nt.templateArgs().isEmpty();
1497+
// Template-instantiated vars (e.g. ArrayList<Ball> balls) must be at namespace
1498+
// scope unless their initializer references sketch member variables.
1499+
// If initializer is a CallExpr with args, keep in sketch to avoid
1500+
// "segments not declared" errors (Array<Ground*> ground(segments)).
1501+
// Template-instantiated variables (ArrayList<Ball>, Array<Ground*>, etc.)
1502+
// are valid struct members -- do NOT hoist them to namespace scope.
1503+
// Only variable TEMPLATES (template<typename T> T pi = ...) need hoisting.
1504+
boolean isTemplateInstVar = false;
15001505
if (isTypeSpec || isTemplatedVar || isTemplateInstVar) {
15011506
templateScopeItems.add(item);
15021507
} else {
@@ -3247,7 +3252,7 @@ else if (!cmd.contains(defaultsCpp.getAbsolutePath()))
32473252
} else if (homebrewPrefix != null) {
32483253
cmd.add("-L" + homebrewPrefix + "/lib");
32493254
}
3250-
Collections.addAll(cmd, "-lglfw", "-lGLEW", "-lm", "-pthread");
3255+
Collections.addAll(cmd, "-lglfw", "-lGLEW", "-lm", "-pthread", "-lobjc");
32513256
Collections.addAll(cmd, "-framework", "OpenGL");
32523257
Collections.addAll(cmd, "-framework", "Cocoa");
32533258
Collections.addAll(cmd, "-framework", "IOKit");

0 commit comments

Comments
 (0)