Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8233678: [macos 10.15] System menu bar does not work initially on macOS Catalina #361

Closed
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -217,94 +217,97 @@ public String getDataDirectory() {
return userHome + File.separator + "." + name + File.separator;
}

private void notifyWillFinishLaunching() {
// Subclasses can override the following notify methods.
// Overridden methods need to call super.

protected void notifyWillFinishLaunching() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleWillFinishLaunchingAction(this, System.nanoTime());
}
}

private void notifyDidFinishLaunching() {
protected void notifyDidFinishLaunching() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleDidFinishLaunchingAction(this, System.nanoTime());
}
}

private void notifyWillBecomeActive() {
protected void notifyWillBecomeActive() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleWillBecomeActiveAction(this, System.nanoTime());
}
}

private void notifyDidBecomeActive() {
protected void notifyDidBecomeActive() {
this.initialActiveEventReceived = true;
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleDidBecomeActiveAction(this, System.nanoTime());
}
}

private void notifyWillResignActive() {
protected void notifyWillResignActive() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleWillResignActiveAction(this, System.nanoTime());
}
}

private boolean notifyThemeChanged(String themeName) {
protected boolean notifyThemeChanged(String themeName) {
EventHandler handler = getEventHandler();
if (handler != null) {
return handler.handleThemeChanged(themeName);
}
return false;
}

private void notifyDidResignActive() {
protected void notifyDidResignActive() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleDidResignActiveAction(this, System.nanoTime());
}
}

private void notifyDidReceiveMemoryWarning() {
protected void notifyDidReceiveMemoryWarning() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleDidReceiveMemoryWarning(this, System.nanoTime());
}
}

private void notifyWillHide() {
protected void notifyWillHide() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleWillHideAction(this, System.nanoTime());
}
}

private void notifyDidHide() {
protected void notifyDidHide() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleDidHideAction(this, System.nanoTime());
}
}

private void notifyWillUnhide() {
protected void notifyWillUnhide() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleWillUnhideAction(this, System.nanoTime());
}
}

private void notifyDidUnhide() {
protected void notifyDidUnhide() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleDidUnhideAction(this, System.nanoTime());
}
}

// notificiation when user drag and drops files onto app icon
private void notifyOpenFiles(String files[]) {
protected void notifyOpenFiles(String files[]) {
if ((this.initialActiveEventReceived == false) && (this.initialOpenedFiles == null)) {
// rememeber the initial opened files
this.initialOpenedFiles = files;
Expand All @@ -315,7 +318,7 @@ private void notifyOpenFiles(String files[]) {
}
}

private void notifyWillQuit() {
protected void notifyWillQuit() {
EventHandler handler = getEventHandler();
if (handler != null) {
handler.handleQuitAction(this, System.nanoTime());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
import com.sun.glass.ui.*;
import com.sun.glass.ui.CommonDialogs.ExtensionFilter;
import com.sun.glass.ui.CommonDialogs.FileChooserResult;
import com.sun.javafx.util.Logging;

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

final class MacApplication extends Application implements InvokeLaterDispatcher.InvokeLaterSubmitter {

Expand Down Expand Up @@ -73,14 +76,49 @@ native void _runLoop(ClassLoader classLoader, Runnable launchable,
boolean isTaskbarApplication);
@Override
protected void runLoop(final Runnable launchable) {
// For normal (not embedded) taskbar applications the masOS activation
// init code will deactivate and then reactivate the application to
// allow the system menubar to work properly.
// We need to spin up a nested event loop and wait for the reactivation
// to finish prior to allowing the rest of the initialization to run.
final Runnable wrappedRunnable = () -> {
if (isNormalTaskbarApp()) {
waitForReactivation();
}
launchable.run();
};

isTaskbarApplication =
AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
String taskbarAppProp = System.getProperty("glass.taskbarApplication");
return !"false".equalsIgnoreCase(taskbarAppProp);
});

ClassLoader classLoader = MacApplication.class.getClassLoader();
_runLoop(classLoader, launchable, isTaskbarApplication);
_runLoop(classLoader, wrappedRunnable, isTaskbarApplication);
}

private final CountDownLatch reactivationLatch = new CountDownLatch(1);

// Spin up a nested even loop waiting for the app reactivation event
kevinrushforth marked this conversation as resolved.
Show resolved Hide resolved
void waitForReactivation() {
final EventLoop eventLoop = createEventLoop();
Thread thr = new Thread(() -> {
try {
if (!reactivationLatch.await(5, TimeUnit.SECONDS)) {
Logging.getJavaFXLogger().warning("Timeout while waiting for app reactivation");
}
} catch (InterruptedException ex) {
Logging.getJavaFXLogger().warning("Exception while waiting for app reactivation: " + ex);
}
Application.invokeLater(() -> {
eventLoop.leave(null);
});
});
thr.setDaemon(true);
thr.start();

eventLoop.enter();
}

native private void _finishTerminating();
Expand All @@ -95,6 +133,22 @@ private void notifyApplicationDidTerminate() {
setEventThread(null);
}

private boolean firstDidResignActive = false;

@Override
protected void notifyDidResignActive() {
firstDidResignActive = true;
super.notifyDidResignActive();
}

@Override
protected void notifyDidBecomeActive() {
if (firstDidResignActive) {
reactivationLatch.countDown();
}
super.notifyDidBecomeActive();
}

// Called from the native code
private void setEventThread() {
setEventThread(Thread.currentThread());
Expand Down Expand Up @@ -313,6 +367,13 @@ protected boolean _supportsTransparentWindows() {

@Override native protected boolean _supportsSystemMenu();

// NOTE: this will not return a valid result unil the native _runloop
kevinrushforth marked this conversation as resolved.
Show resolved Hide resolved
// method has been executed and called the Runnable passed to that method.
native private boolean _isNormalTaskbarApp();
boolean isNormalTaskbarApp() {
return _isNormalTaskbarApp();
}

native protected String _getRemoteLayerServerName();
public String getRemoteLayerServerName() {
return _getRemoteLayerServerName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@
static BOOL isFullScreenExitingLoop = NO;
static NSMutableDictionary * keyCodeForCharMap = nil;
static BOOL isEmbedded = NO;
static BOOL isNormalTaskbarApp = NO;
static BOOL disableSyncRendering = NO;
static BOOL firstActivation = YES;
static BOOL shouldReactivate = NO;

#ifdef STATIC_BUILD
jint JNICALL JNI_OnLoad_glass(JavaVM *vm, void *reserved)
Expand Down Expand Up @@ -271,6 +274,13 @@ - (void)applicationDidBecomeActive:(NSNotification *)aNotification
}
[pool drain];
GLASS_CHECK_EXCEPTION(env);

if (isNormalTaskbarApp && firstActivation) {
LOG("-> deactivate (hide) app");
firstActivation = NO;
shouldReactivate = YES;
[NSApp hide:NSApp];
}
}

- (void)applicationWillResignActive:(NSNotification *)aNotification
Expand All @@ -297,6 +307,12 @@ - (void)applicationDidResignActive:(NSNotification *)aNotification
}
[pool drain];
GLASS_CHECK_EXCEPTION(env);

if (isNormalTaskbarApp && shouldReactivate) {
LOG("-> reactivate app");
shouldReactivate = NO;
[NSApp activateIgnoringOtherApps:YES];
}
}

- (void)applicationWillHide:(NSNotification *)aNotification
Expand Down Expand Up @@ -517,6 +533,7 @@ - (void)runLoop:(id)selector
{
if (self->jTaskBarApp == JNI_TRUE)
{
isNormalTaskbarApp = YES;
// move process from background only to full on app with visible Dock icon
ProcessSerialNumber psn;
if (GetCurrentProcess(&psn) == noErr)
Expand Down Expand Up @@ -1050,6 +1067,18 @@ + (BOOL)syncRenderingDisabled {
return !isEmbedded;
}

/*
* Class: com_sun_glass_ui_mac_MacApplication
* Method: _isNormalTaskbarApp
* Signature: ()Z;
*/
JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacApplication__1isNormalTaskbarApp
(JNIEnv *env, jobject japplication)
{
LOG("Java_com_sun_glass_ui_mac_MacApplication__1isNormalTaskbarApp");
return isNormalTaskbarApp;
kevinrushforth marked this conversation as resolved.
Show resolved Hide resolved
}

/*
* Class: com_sun_glass_ui_mac_MacApplication
* Method: _hide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ - (void)_setPixels:(jobject)pixels

if ([[glassmenu->item title] compare:@"Apple"] == NSOrderedSame)
{
LOG("calling setAppleMenu");
[NSApp performSelector:@selector(setAppleMenu:) withObject:glassmenu->item];
}

Expand Down