Skip to content

Commit

Permalink
[nsworkspace] make notification work
Browse files Browse the repository at this point in the history
  • Loading branch information
umjammer committed Mar 25, 2024
1 parent 7d1a90a commit 05d7ab3
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 14 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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~~

----

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;


Expand All @@ -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 {
Expand All @@ -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";
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -156,6 +163,7 @@ static NSRunningApplication getMinecraft() {

@Test
@DisplayName("NSRunningApplication")
@EnabledIfSystemProperty(named = "vavi.test", matches = "ide")
void test62() throws Exception {
try {
NSRunningApplication a = getMinecraft();
Expand Down Expand Up @@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
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;
import org.rococoa.Selector;
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;


Expand Down Expand Up @@ -45,20 +46,24 @@ 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);
Debug.println("here");
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();
}
}
3 changes: 3 additions & 0 deletions rococoa-core/src/main/java/org/rococoa/Foundation.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
7 changes: 5 additions & 2 deletions rococoa-core/src/main/java/org/rococoa/Rococoa.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 05d7ab3

Please sign in to comment.