diff --git a/README.md b/README.md index 87081c2..86b0bd2 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ implementation of Objective-C interfaces in Java. * https://developer.apple.com/documentation/appkit/nsrunningapplication?language=objc * separate same parts of jna-platform (like jna-platform-extended) * deprecate rococoa-contrib +* ~~selector and java method binding for notification~~ ---- diff --git a/pom.xml b/pom.xml index 5f70e0b..0b4f0c5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.rococoa rococoa-parent - 0.8.9 + 0.8.10 pom diff --git a/rococoa-cocoa/pom.xml b/rococoa-cocoa/pom.xml index 4d54210..feef576 100644 --- a/rococoa-cocoa/pom.xml +++ b/rococoa-cocoa/pom.xml @@ -10,7 +10,7 @@ org.rococoa rococoa-parent - 0.8.9 + 0.8.10 Rococoa Cocoa Mappings diff --git a/rococoa-contrib/pom.xml b/rococoa-contrib/pom.xml index b5e704e..2fded4a 100644 --- a/rococoa-contrib/pom.xml +++ b/rococoa-contrib/pom.xml @@ -10,7 +10,7 @@ org.rococoa rococoa-parent - 0.8.9 + 0.8.10 Rococoa Contrib diff --git a/rococoa-contrib/src/main/java/org/rococoa/cocoa/appkit/NSWorkspace.java b/rococoa-contrib/src/main/java/org/rococoa/cocoa/appkit/NSWorkspace.java index d757df0..d832358 100644 --- a/rococoa-contrib/src/main/java/org/rococoa/cocoa/appkit/NSWorkspace.java +++ b/rococoa-contrib/src/main/java/org/rococoa/cocoa/appkit/NSWorkspace.java @@ -6,11 +6,10 @@ package org.rococoa.cocoa.appkit; -import java.util.logging.Logger; - import org.rococoa.ObjCClass; import org.rococoa.Rococoa; import org.rococoa.cocoa.foundation.NSArray; +import org.rococoa.cocoa.foundation.NSNotificationCenter; import org.rococoa.cocoa.foundation.NSObject; @@ -22,8 +21,6 @@ */ public abstract class NSWorkspace extends NSObject { - private static final Logger logger = Logger.getLogger(NSWorkspace.class.getName()); - public static final _Class CLASS = Rococoa.createClass("NSWorkspace", _Class.class); public interface _Class extends ObjCClass { @@ -35,9 +32,18 @@ public static NSWorkspace sharedWorkspace() { return CLASS.sharedWorkspace(); } + /** The notification center for workspace notifications. */ + public abstract NSNotificationCenter notificationCenter(); + /** Returns an array of running apps. */ public abstract NSArray /* NSRunningApplication */ runningApplications(); /** Returns the frontmost app, which is the app that receives key events. */ public abstract NSRunningApplication frontmostApplication(); + + /** Returns the app that owns the currently displayed menu bar. */ + public abstract NSRunningApplication menuBarOwningApplication(); + + public static final String NSWorkspaceDidActivateApplicationNotification = "NSWorkspaceDidActivateApplicationNotification"; + public static final String NSWorkspaceDidDeactivateApplicationNotification = "NSWorkspaceDidDeactivateApplicationNotification"; } diff --git a/rococoa-contrib/src/test/java/org/rococoa/cocoa/coregraphics/CoreGraphicsLibraryTest.java b/rococoa-contrib/src/test/java/org/rococoa/cocoa/coregraphics/CoreGraphicsLibraryTest.java index 9eaa5f5..78898cb 100644 --- a/rococoa-contrib/src/test/java/org/rococoa/cocoa/coregraphics/CoreGraphicsLibraryTest.java +++ b/rococoa-contrib/src/test/java/org/rococoa/cocoa/coregraphics/CoreGraphicsLibraryTest.java @@ -8,27 +8,34 @@ import java.util.Arrays; import java.util.NoSuchElementException; +import java.util.concurrent.CountDownLatch; import java.util.logging.Level; import java.util.stream.IntStream; +import com.sun.jna.Callback; import com.sun.jna.Pointer; import com.sun.jna.platform.mac.CoreFoundation.CFArrayRef; -import com.sun.jna.platform.mac.CoreFoundation.CFDictionaryRef; import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.junit.jupiter.api.condition.EnabledIfSystemProperty; import org.rococoa.Foundation; +import org.rococoa.ObjCObject; import org.rococoa.Rococoa; +import org.rococoa.Selector; import org.rococoa.cocoa.appkit.NSRunningApplication; import org.rococoa.cocoa.appkit.NSWorkspace; import org.rococoa.cocoa.corefoundation.CoreFoundation; import org.rococoa.cocoa.coreimage.CIImage; +import org.rococoa.cocoa.foundation.NSBundle; import org.rococoa.cocoa.foundation.NSDictionary; -import org.rococoa.cocoa.foundation.NSRect; +import org.rococoa.cocoa.foundation.NSNotification; +import org.rococoa.cocoa.foundation.NSNotificationCenter; +import org.rococoa.cocoa.foundation.NSObject; import org.rococoa.cocoa.foundation.NSString; +import org.rococoa.cocoa.gamecontroller.GCController; import vavi.util.Debug; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -156,6 +163,7 @@ static NSRunningApplication getMinecraft() { @Test @DisplayName("NSRunningApplication") + @EnabledIfSystemProperty(named = "vavi.test", matches = "ide") void test62() throws Exception { try { NSRunningApplication a = getMinecraft(); @@ -196,4 +204,35 @@ void test8() throws Exception { } } } + + CountDownLatch cdl = new CountDownLatch(1); + + class MyObserver implements Callback { + + public void applicationWasActivated(NSNotification notification) { + NSWorkspace workspace = Rococoa.cast(notification.object(), NSWorkspace.class); + NSRunningApplication a = workspace.frontmostApplication(); +Debug.println("applicationWasActivated: " + a.bundleIdentifier() + ":" + a.processIdentifier()); + } + + public void applicationWasDeactivated(NSNotification notification) { + NSWorkspace workspace = Rococoa.cast(notification.object(), NSWorkspace.class); + NSRunningApplication a = workspace.frontmostApplication(); +Debug.println("applicationWasDeactivated: " + a.bundleIdentifier() + ":" + a.processIdentifier()); + } + } + + @Test + @EnabledIfSystemProperty(named = "vavi.test", matches = "ide") + void test9() throws Exception { + ObjCObject proxy = Rococoa.proxy(new CoreGraphicsLibraryTest.MyObserver()); + Selector sel1 = Foundation.selector("applicationWasActivated:"); + Selector sel2 = Foundation.selector("applicationWasDeactivated:"); + + NSNotificationCenter notificationCenter = NSWorkspace.sharedWorkspace().notificationCenter(); + notificationCenter.addObserver_selector_name_object(proxy.id(), sel1, NSWorkspace.NSWorkspaceDidActivateApplicationNotification, null); + notificationCenter.addObserver_selector_name_object(proxy.id(), sel2, NSWorkspace.NSWorkspaceDidActivateApplicationNotification, null); + + cdl.await(); + } } diff --git a/rococoa-contrib/src/test/java/org/rococoa/cocoa/gamecontroller/GCControllerTest.java b/rococoa-contrib/src/test/java/org/rococoa/cocoa/gamecontroller/GCControllerTest.java index 788c63f..c6a232f 100644 --- a/rococoa-contrib/src/test/java/org/rococoa/cocoa/gamecontroller/GCControllerTest.java +++ b/rococoa-contrib/src/test/java/org/rococoa/cocoa/gamecontroller/GCControllerTest.java @@ -9,8 +9,8 @@ import java.util.concurrent.CountDownLatch; import com.sun.jna.Callback; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIfSystemProperty; import org.rococoa.Foundation; import org.rococoa.ObjCObject; import org.rococoa.Rococoa; @@ -18,6 +18,7 @@ import org.rococoa.cocoa.foundation.NSBundle; import org.rococoa.cocoa.foundation.NSNotification; import org.rococoa.cocoa.foundation.NSNotificationCenter; +import org.rococoa.cocoa.foundation.NSString; import vavi.util.Debug; @@ -45,7 +46,7 @@ public void controllerDidDisconnect(NSNotification notification) { } @Test - @Disabled("wip") + @EnabledIfSystemProperty(named = "vavi.test", matches = "ide") void test1() throws Exception { Debug.println(NSBundle.mainBundle().bundleIdentifier()); GCController.controllers().forEach(System.err::println); @@ -53,12 +54,16 @@ void test1() throws Exception { GCController controller = GCController.controllers().get(0); ObjCObject proxy = Rococoa.proxy(new MyObserver()); - Selector sel1 = Foundation.selector("controllerDidConnect"); - Selector sel2 = Foundation.selector("controllerDidDisconnect"); + Selector sel1 = Foundation.selector("controllerDidConnect:"); + Selector sel2 = Foundation.selector("controllerDidDisconnect:"); NSNotificationCenter notificationCenter = NSNotificationCenter.CLASS.defaultCenter(); notificationCenter.addObserver_selector_name_object(proxy.id(), sel1, GCController.GCControllerDidConnectNotification, null); + // fake notification + NSNotification notification = NSNotification.CLASS.notificationWithName_object(GCController.GCControllerDidConnectNotification, NSString.stringWithString("hello world")); + notificationCenter.postNotification(notification); + cdl.await(); } } \ No newline at end of file diff --git a/rococoa-core/pom.xml b/rococoa-core/pom.xml index c199dba..bf50d34 100644 --- a/rococoa-core/pom.xml +++ b/rococoa-core/pom.xml @@ -9,7 +9,7 @@ org.rococoa rococoa-parent - 0.8.9 + 0.8.10 Rococoa Core diff --git a/rococoa-core/src/main/java/org/rococoa/Foundation.java b/rococoa-core/src/main/java/org/rococoa/Foundation.java index 07f0c49..e9bcaac 100644 --- a/rococoa-core/src/main/java/org/rococoa/Foundation.java +++ b/rococoa-core/src/main/java/org/rococoa/Foundation.java @@ -193,6 +193,9 @@ public static ID getClass(String className) { return foundationLibrary.objc_getClass(className); } + /** + * @param selectorName colon ended function name e.g. {@code "selector:"} + */ public static Selector selector(String selectorName) { Selector cached = selectorCache.get(selectorName); if (cached != null) { diff --git a/rococoa-core/src/main/java/org/rococoa/Rococoa.java b/rococoa-core/src/main/java/org/rococoa/Rococoa.java index a0c1915..6c77f4f 100644 --- a/rococoa-core/src/main/java/org/rococoa/Rococoa.java +++ b/rococoa-core/src/main/java/org/rococoa/Rococoa.java @@ -211,13 +211,16 @@ private static void checkRetainCount(ID ocInstance, int expected) { } } - /** __bridge */ + /** + * Toll-Free Bridging __bridge + * @see "https://developer.apple.com/library/archive/documentation/General/Conceptual/CocoaEncyclopedia/Toll-FreeBridgin/Toll-FreeBridgin.html#//apple_ref/doc/uid/TP40010810-CH2" + */ public static NSArray toNSArray(Pointer p) { ID id = Foundation.getRococoaLibrary().bridgeArray(p); return wrap(id, NSArray.class); } - /** __bridge */ + /** Toll-Free Bridging __bridge */ public static NSDictionary toNSDictionary(Pointer p) { ID id = Foundation.getRococoaLibrary().bridgeDictionary(p); return wrap(id, NSDictionary.class); diff --git a/rococoa-core/src/main/java/org/rococoa/cocoa/foundation/NSNotificationCenter.java b/rococoa-core/src/main/java/org/rococoa/cocoa/foundation/NSNotificationCenter.java index 99aae19..1d0b1f3 100644 --- a/rococoa-core/src/main/java/org/rococoa/cocoa/foundation/NSNotificationCenter.java +++ b/rococoa-core/src/main/java/org/rococoa/cocoa/foundation/NSNotificationCenter.java @@ -32,7 +32,7 @@ public interface _Class extends ObjCClass { } public abstract void addObserver_selector_name_object(ID notificationObserver, - Selector notificationSelector, + Selector notificationSelector, // works! don't touch String notificationName, NSObject notificationSender);