diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java index d4fa3551e85b..9a20cb09ec2e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeFrameImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.wm.impl; +import com.apple.eawt.FullScreenUtilities; import com.intellij.diagnostic.IdeMessagePanel; import com.intellij.ide.AppLifecycleListener; import com.intellij.ide.DataManager; @@ -45,7 +46,10 @@ import com.intellij.openapi.wm.IdeRootPaneNorthExtension; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; import com.intellij.openapi.wm.ex.StatusBarEx; -import com.intellij.openapi.wm.impl.status.*; +import com.intellij.openapi.wm.impl.status.EncodingPanel; +import com.intellij.openapi.wm.impl.status.InsertOverwritePanel; +import com.intellij.openapi.wm.impl.status.PositionPanel; +import com.intellij.openapi.wm.impl.status.ToggleReadOnlyAttributePanel; import com.intellij.ui.AppUIUtil; import com.intellij.ui.BalloonLayout; import com.intellij.ui.FocusTrackback; @@ -108,7 +112,9 @@ public class IdeFrameImpl extends JFrame implements IdeFrame, DataProvider { // to show window thumbnail under Macs // http://lists.apple.com/archives/java-dev/2009/Dec/msg00240.html - if (SystemInfo.isMac) setIconImage(null); + if (SystemInfo.isMac) setIconImage(null); + // enable fullscreen titlebar button + if (SystemInfo.isMacOSLion) FullScreenUtilities.setWindowCanFullScreen(this, true); MouseGestureManager.getInstance().add(this); } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java index 0347e6ea21a2..f903e5742fb7 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java @@ -15,6 +15,10 @@ */ package com.intellij.ui.mac; +import com.apple.eawt.AppEvent; +import com.apple.eawt.FullScreenAdapter; +import com.apple.eawt.FullScreenUtilities; +import com.intellij.Patches; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.Disposable; @@ -31,11 +35,8 @@ import com.sun.jna.Callback; import org.jetbrains.annotations.NotNull; import javax.swing.*; -import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; import java.util.concurrent.atomic.AtomicInteger; import static com.intellij.ui.mac.foundation.Foundation.invoke; @@ -101,10 +102,7 @@ public class MacMainFrameDecorator implements UISettingsListener, Disposable { private static Runnable CURRENT_SETTER = null; private static Function CURRENT_GETTER = null; - - private Callback myDidExit; - private Callback myDidEnter; - private Callback myWindowWillMiniaturize; + private boolean myInFullScreen; private IdeFrameImpl myFrame; @@ -128,113 +126,43 @@ public class MacMainFrameDecorator implements UISettingsListener, Disposable { try { if (SystemInfo.isMacOSLion) { - // fullscreen support - frame.addWindowListener(new WindowAdapter() { + FullScreenUtilities.addFullScreenListenerTo(frame, new FullScreenAdapter() { @Override - public void windowDeiconified(WindowEvent e) { - Window window1 = e.getWindow(); - - if (window1 instanceof JFrame) { - ID w = MacUtil.findWindowForTitle(((JFrame)window1).getTitle()); - if (w != null && w.intValue() > 0) { - try { - Thread.sleep(300); + public void windowEnteredFullScreen(AppEvent.FullScreenEvent event) { + myInFullScreen = true; + + JRootPane rootPane = frame.getRootPane(); + if (rootPane != null) rootPane.putClientProperty(FULL_SCREEN, Boolean.TRUE); + if (Patches.APPLE_BUG_ID_10207064) { + // fix problem with bottom empty bar + // it seems like the title is still visible in fullscreen but the window itself shifted up for titlebar height + // and the size of the frame is still calculated to be the height of the screen which is wrong + // so just add these titlebar height to the frame height once again + Timer timer = new Timer(300, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + frame.setSize(frame.getWidth(), frame.getHeight() + frame.getInsets().top); + } + }); } - catch (InterruptedException e1) { - // ignore - } - - invoke(w, "setCollectionBehavior:", 1 << 7); - } + }); + timer.setRepeats(false); + timer.start(); } } + + @Override + public void windowExitedFullScreen(AppEvent.FullScreenEvent event) { + myInFullScreen = false; + frame.storeFullScreenStateIfNeeded(false); + + JRootPane rootPane = frame.getRootPane(); + if (rootPane != null) rootPane.putClientProperty(FULL_SCREEN, null); + } }); - - final ID delegateClass = Foundation.allocateObjcClassPair(Foundation.getClass("NSObject"), "IdeaNSWindowDelegate" + v); - Foundation.registerObjcClassPair(delegateClass); - - - // something happens with event processing if main frame will be minimized and then restored back under java version "1.6.0_29" and maybe later - // so we will drop this behavior and restore it back on deminiaturization (see above) - myWindowWillMiniaturize = new Callback() { - public void callback(ID caller, ID notification) { - ID w = MacUtil.findWindowForTitle(frame.getTitle()); - if (w != null && w.intValue() > 0) { - invoke(w, "setCollectionBehavior:", 0); - } - } - }; - Foundation.addMethod(delegateClass, Foundation.createSelector("windowWillMiniaturize:"), myWindowWillMiniaturize, "v*"); - - myDidExit = new Callback() { - public void callback(ID caller, ID notification) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - myInFullScreen = false; - frame.storeFullScreenStateIfNeeded(false); - - JRootPane rootPane = frame.getRootPane(); - if (rootPane != null) rootPane.putClientProperty(FULL_SCREEN, null); - } - }); - } - }; - Foundation.addMethod(delegateClass, Foundation.createSelector("windowDidExitFullScreen:"), myDidExit, "v*"); - - myDidEnter = new Callback() { - public void callback(ID caller, ID notification) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - myInFullScreen = true; - //((IdeFrameImpl)frame).storeFullScreenStateIfNeeded(true); - - // fix problem with bottom empty bar - // it seems like the title is still visible in fullscreen but the window itself shifted up for titlebar height - // and the size of the frame is still calculated to be the height of the screen which is wrong - // so just add these titlebar height to the frame height once again - Timer timer = new Timer(300, new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - frame.setSize(frame.getWidth(), frame.getHeight() + frame.getInsets().top); - } - }); - } - }); - - JRootPane rootPane = frame.getRootPane(); - if (rootPane != null) rootPane.putClientProperty(FULL_SCREEN, Boolean.TRUE); - - timer.setRepeats(false); - timer.start(); - } - }); - } - }; - - Foundation.addMethod(delegateClass, Foundation.createSelector("windowDidEnterFullScreen:"), myDidEnter, "v*"); - - // enable fullscreen titlebar button - invoke(window, "setCollectionBehavior:", 1 << 7); // NSCollectionBehaviorFullScreenPrimary = 1 << 7, NSCollectionBehaviorFullScreenAuxiliary = 1 << 8 - - ID notificationCenter = invoke("NSNotificationCenter", "defaultCenter"); - - ID delegate = invoke(invoke("IdeaNSWindowDelegate" + v, "alloc"), "init"); - invoke(notificationCenter, "addObserver:selector:name:object:", delegate, - Foundation.createSelector("windowDidEnterFullScreen:"), - Foundation.nsString("NSWindowDidEnterFullScreenNotification"), window); - - invoke(notificationCenter, "addObserver:selector:name:object:", delegate, - Foundation.createSelector("windowDidExitFullScreen:"), - Foundation.nsString("NSWindowDidExitFullScreenNotification"), window); - - invoke(notificationCenter, "addObserver:selector:name:object:", delegate, - Foundation.createSelector("windowWillMiniaturize:"), - Foundation.nsString("NSWindowWillMiniaturizeNotification"), window); } else { // toggle toolbar String className = "IdeaToolbar" + v; diff --git a/platform/util/src/com/intellij/Patches.java b/platform/util/src/com/intellij/Patches.java index 54b9ed6d21d4..998639c91ba6 100644 --- a/platform/util/src/com/intellij/Patches.java +++ b/platform/util/src/com/intellij/Patches.java @@ -104,6 +104,14 @@ public class Patches { */ public static final boolean APPLE_BUG_ID_5359442 = SystemInfo.isMac && (!SystemInfo.isMacOSLeopard || !SystemInfo.isJavaVersionAtLeast("1.5.0_16")); + /** + * Lion eAWT FullScreen mode leads to visual artifacts + * + * @see com.intellij.util.concurrency.LockFactory + */ + public static final boolean APPLE_BUG_ID_10207064 = + SystemInfo.isMac && (!SystemInfo.isMacOSLeopard || !SystemInfo.isJavaVersionAtLeast("1.6.0_30")); + /** * Index out of bounds at apple.laf.AquaTabbedPaneUI.tabForCoordinate * http://www.jetbrains.net/jira/browse/IDEADEV-15769