# HG changeset patch # User serb # Date 1343651775 -14400 # Node ID 921c2eb6b9d62e4a5d5b330e07725e10c4e4c420 # Parent 11eb06b637bb6e66eada9e6c508bf1a105a88000 7124513: [macosx] Support NSTexturedBackgroundWindowMask/different titlebar styles to create unified toolbar Reviewed-by: anthony diff -r 11eb06b637bb -r 921c2eb6b9d6 src/macosx/classes/com/apple/laf/AquaPanelUI.java --- a/src/macosx/classes/com/apple/laf/AquaPanelUI.java Mon Jul 30 16:34:04 2012 +0400 +++ b/src/macosx/classes/com/apple/laf/AquaPanelUI.java Mon Jul 30 16:36:15 2012 +0400 @@ -32,10 +32,20 @@ import com.apple.laf.AquaUtils.RecyclableSingleton; import com.apple.laf.AquaUtils.RecyclableSingletonFromDefaultConstructor; +import java.awt.Graphics; + public class AquaPanelUI extends BasicPanelUI { static RecyclableSingleton instance = new RecyclableSingletonFromDefaultConstructor(AquaPanelUI.class); public static ComponentUI createUI(final JComponent c) { return instance.get(); } + + @Override + public final void update(final Graphics g, final JComponent c) { + if (c.isOpaque()) { + AquaUtils.fillRect(g, c); + } + paint(g, c); + } } diff -r 11eb06b637bb -r 921c2eb6b9d6 src/macosx/classes/com/apple/laf/AquaRootPaneUI.java --- a/src/macosx/classes/com/apple/laf/AquaRootPaneUI.java Mon Jul 30 16:34:04 2012 +0400 +++ b/src/macosx/classes/com/apple/laf/AquaRootPaneUI.java Mon Jul 30 16:36:15 2012 +0400 @@ -319,4 +319,12 @@ updateComponentTreeUIActivation(element, active); } } + + @Override + public final void update(final Graphics g, final JComponent c) { + if (c.isOpaque()) { + AquaUtils.fillRect(g, c); + } + paint(g, c); + } } diff -r 11eb06b637bb -r 921c2eb6b9d6 src/macosx/classes/com/apple/laf/AquaToolBarUI.java --- a/src/macosx/classes/com/apple/laf/AquaToolBarUI.java Mon Jul 30 16:34:04 2012 +0400 +++ b/src/macosx/classes/com/apple/laf/AquaToolBarUI.java Mon Jul 30 16:36:15 2012 +0400 @@ -73,9 +73,7 @@ g.translate(x, y); if (c.isOpaque()) { - final Color background = c.getBackground(); - g.setColor(background); - g.fillRect(0, 0, w - 1, h - 1); + AquaUtils.fillRect(g, c, c.getBackground(), 0, 0, w - 1, h - 1); } final Color oldColor = g.getColor(); @@ -137,4 +135,12 @@ return true; } } + + @Override + public final void update(final Graphics g, final JComponent c) { + if (c.isOpaque()) { + AquaUtils.fillRect(g, c); + } + paint(g, c); + } } diff -r 11eb06b637bb -r 921c2eb6b9d6 src/macosx/classes/com/apple/laf/AquaUtils.java --- a/src/macosx/classes/com/apple/laf/AquaUtils.java Mon Jul 30 16:34:04 2012 +0400 +++ b/src/macosx/classes/com/apple/laf/AquaUtils.java Mon Jul 30 16:36:15 2012 +0400 @@ -28,18 +28,19 @@ import java.awt.*; import java.awt.image.*; import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.security.PrivilegedAction; import java.util.*; import javax.swing.*; import javax.swing.border.Border; +import javax.swing.plaf.UIResource; import sun.awt.AppContext; import sun.lwawt.macosx.CImage; import sun.lwawt.macosx.CImage.Creator; +import sun.lwawt.macosx.CPlatformWindow; import sun.swing.SwingUtilities2; import com.apple.laf.AquaImageFactory.SlicedImageControl; @@ -389,4 +390,51 @@ return false; } } + + protected static boolean isWindowTextured(final Component c) { + if (!(c instanceof JComponent)) { + return false; + } + final JRootPane pane = ((JComponent) c).getRootPane(); + if (pane == null) { + return false; + } + Object prop = pane.getClientProperty( + CPlatformWindow.WINDOW_BRUSH_METAL_LOOK); + if (prop != null) { + return Boolean.parseBoolean(prop.toString()); + } + prop = pane.getClientProperty(CPlatformWindow.WINDOW_STYLE); + return prop != null && "textured".equals(prop); + } + + private static Color resetAlpha(final Color color) { + return new Color(color.getRed(), color.getGreen(), color.getBlue(), 0); + } + + protected static void fillRect(final Graphics g, final Component c) { + fillRect(g, c, c.getBackground(), 0, 0, c.getWidth(), c.getHeight()); + } + + protected static void fillRect(final Graphics g, final Component c, + final Color color, final int x, final int y, + final int w, final int h) { + if (!(g instanceof Graphics2D)) { + return; + } + final Graphics2D cg = (Graphics2D) g.create(); + try { + if (color instanceof UIResource && isWindowTextured(c) + && color.equals(SystemColor.window)) { + cg.setComposite(AlphaComposite.Src); + cg.setColor(resetAlpha(color)); + } else { + cg.setColor(color); + } + cg.fillRect(x, y, w, h); + } finally { + cg.dispose(); + } + } } + diff -r 11eb06b637bb -r 921c2eb6b9d6 src/macosx/classes/sun/lwawt/LWWindowPeer.java --- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java Mon Jul 30 16:34:04 2012 +0400 +++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java Mon Jul 30 16:36:15 2012 +0400 @@ -112,6 +112,8 @@ private static final Color nonOpaqueBackground = new Color(0, 0, 0, 0); + private volatile boolean textured; + /** * Current modal blocker or null. * @@ -463,9 +465,23 @@ public void updateWindow() { } + public final boolean isTextured() { + return textured; + } + + public final void setTextured(final boolean isTextured) { + textured = isTextured; + } + public final boolean isTranslucent() { synchronized (getStateLock()) { - return !isOpaque || isShaped(); + /* + * Textured window is a special case of translucent window. + * The difference is only in nswindow background. So when we set + * texture property our peer became fully translucent. It doesn't + * fill background, create non opaque backbuffers and layer etc. + */ + return !isOpaque || isShaped() || isTextured(); } } @@ -634,11 +650,13 @@ g.setColor(nonOpaqueBackground); g.fillRect(0, 0, w, h); } - if (g instanceof SunGraphics2D) { - SG2DConstraint((SunGraphics2D) g, getRegion()); + if (!isTextured()) { + if (g instanceof SunGraphics2D) { + SG2DConstraint((SunGraphics2D) g, getRegion()); + } + g.setColor(getBackground()); + g.fillRect(0, 0, w, h); } - g.setColor(getBackground()); - g.fillRect(0, 0, w, h); } finally { g.dispose(); } @@ -1003,8 +1021,10 @@ if (g instanceof SunGraphics2D) { SG2DConstraint((SunGraphics2D) g, getRegion()); } - g.setColor(getBackground()); - g.fillRect(0, 0, r.width, r.height); + if (!isTextured()) { + g.setColor(getBackground()); + g.fillRect(0, 0, r.width, r.height); + } if (oldBB != null) { // Draw the old back buffer to the new one g.drawImage(oldBB, 0, 0, null); diff -r 11eb06b637bb -r 921c2eb6b9d6 src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Mon Jul 30 16:34:04 2012 +0400 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Mon Jul 30 16:36:15 2012 +0400 @@ -299,7 +299,7 @@ // If the target is a dialog, popup or tooltip we want it to ignore the brushed metal look. if (isPopup) { - styleBits = SET(styleBits, TEXTURED, true); + styleBits = SET(styleBits, TEXTURED, false); // Popups in applets don't activate applet's process styleBits = SET(styleBits, NONACTIVATING, true); } @@ -373,6 +373,8 @@ } } + peer.setTextured(IS(TEXTURED, styleBits)); + return styleBits; } @@ -740,7 +742,7 @@ @Override public void setOpaque(boolean isOpaque) { CWrapper.NSWindow.setOpaque(getNSWindowPtr(), isOpaque); - if (!isOpaque) { + if (!isOpaque && !peer.isTextured()) { long clearColor = CWrapper.NSColor.clearColor(); CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), clearColor); } diff -r 11eb06b637bb -r 921c2eb6b9d6 src/share/classes/javax/swing/JViewport.java --- a/src/share/classes/javax/swing/JViewport.java Mon Jul 30 16:34:04 2012 +0400 +++ b/src/share/classes/javax/swing/JViewport.java Mon Jul 30 16:36:15 2012 +0400 @@ -1586,10 +1586,18 @@ int bdx = blitToX - blitFromX; int bdy = blitToY - blitFromY; + Composite oldComposite = null; // Shift the scrolled region + if (g instanceof Graphics2D) { + Graphics2D g2d = (Graphics2D) g; + oldComposite = g2d.getComposite(); + g2d.setComposite(AlphaComposite.Src); + } rm.copyArea(this, g, blitFromX, blitFromY, blitW, blitH, bdx, bdy, false); - + if (oldComposite != null) { + ((Graphics2D) g).setComposite(oldComposite); + } // Paint the newly exposed region. int x = view.getX(); int y = view.getY();