From 89d504b32f618ac6beecf8aa773fe94d09c1f5bb Mon Sep 17 00:00:00 2001 From: Anthony Petrov <anthony@openjdk.org> Date: Tue, 19 Apr 2011 14:44:09 +0400 Subject: [PATCH 01/13] 7036669: Simplify revalidating component hierarchy with multiple validate roots Introduce Component.revalidate() method Reviewed-by: art, alexp --- jdk/src/share/classes/java/awt/Component.java | 40 ++++++ .../plaf/basic/BasicSplitPaneDivider.java | 6 +- .../awt/Component/Revalidate/Revalidate.java | 122 ++++++++++++++++++ 3 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/awt/Component/Revalidate/Revalidate.java diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index 5b572797d84..f577887abe6 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -2944,6 +2944,46 @@ public abstract class Component implements ImageObserver, MenuContainer, } } + /** + * Revalidates the component hierarchy up to the nearest validate root. + * <p> + * This method first invalidates the component hierarchy starting from this + * component up to the nearest validate root. Afterwards, the component + * hierarchy is validated starting from the nearest validate root. + * <p> + * This is a convenience method supposed to help application developers + * avoid looking for validate roots manually. Basically, it's equivalent to + * first calling the {@link #invalidate()} method on this component, and + * then calling the {@link #validate()} method on the nearest validate + * root. + * + * @see Container#isValidateRoot + * @since 1.7 + */ + public void revalidate() { + synchronized (getTreeLock()) { + invalidate(); + + Container root = getContainer(); + if (root == null) { + // There's no parents. Just validate itself. + validate(); + } else { + while (!root.isValidateRoot()) { + if (root.getContainer() == null) { + // If there's no validate roots, we'll validate the + // topmost container + break; + } + + root = root.getContainer(); + } + + root.validate(); + } + } + } + /** * Creates a graphics context for this component. This method will * return <code>null</code> if this component is currently not diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java index 42c88e02823..70b0bffaac7 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java @@ -154,7 +154,7 @@ public class BasicSplitPaneDivider extends Container setBackground(UIManager.getColor("SplitPane.background")); } - private void revalidate() { + private void revalidateSplitPane() { invalidate(); if (splitPane != null) { splitPane.revalidate(); @@ -315,7 +315,7 @@ public class BasicSplitPaneDivider extends Container setCursor((orientation == JSplitPane.HORIZONTAL_SPLIT) ? Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)); - revalidate(); + revalidateSplitPane(); } else if (e.getPropertyName() == JSplitPane. ONE_TOUCH_EXPANDABLE_PROPERTY) { @@ -376,7 +376,7 @@ public class BasicSplitPaneDivider extends Container add(rightButton); } } - revalidate(); + revalidateSplitPane(); } diff --git a/jdk/test/java/awt/Component/Revalidate/Revalidate.java b/jdk/test/java/awt/Component/Revalidate/Revalidate.java new file mode 100644 index 00000000000..670c374f87d --- /dev/null +++ b/jdk/test/java/awt/Component/Revalidate/Revalidate.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 7036669 + @summary Test Component.revalidate() method + @author anthony.petrov@oracle.com: area=awt.component + @run main Revalidate +*/ + +import java.awt.*; + +public class Revalidate { + private static Frame frame = new Frame(); + private static Panel panel = new Panel() { + @Override + public boolean isValidateRoot() { + return true; + } + }; + private static Button button = new Button("Test"); + + private static void sleep() { + try { Thread.sleep(500); } catch (Exception e) {} + } + + private static void printState(String str) { + System.out.println(str + " isValid state: "); + System.out.println(" frame: " + frame.isValid()); + System.out.println(" panel: " + panel.isValid()); + System.out.println(" button: " + button.isValid()); + } + + private static void fail(String msg) { + frame.dispose(); + throw new RuntimeException(msg); + } + + private static void check(String n, Component c, boolean v) { + if (c.isValid() != v) { + fail(n + ".isValid() = " + c.isValid() + "; expected: " + v); + } + } + private static void check(String str, boolean f, boolean p, boolean b) { + printState(str); + + check("frame", frame, f); + check("panel", panel, p); + check("button", button, b); + } + + public static void main(String[] args) { + // setup + frame.add(panel); + panel.add(button); + frame.setBounds(200, 200, 300, 200); + frame.setVisible(true); + sleep(); + check("Upon showing", true, true, true); + + button.setBounds(1, 1, 30, 30); + sleep(); + check("button.setBounds():", true, false, false); + + button.revalidate(); + sleep(); + check("button.revalidate():", true, true, true); + + button.setBounds(1, 1, 30, 30); + sleep(); + check("button.setBounds():", true, false, false); + + panel.revalidate(); + sleep(); + // because the panel's validate root is actually OK + check("panel.revalidate():", true, false, false); + + button.revalidate(); + sleep(); + check("button.revalidate():", true, true, true); + + panel.setBounds(2, 2, 125, 130); + sleep(); + check("panel.setBounds():", false, false, true); + + button.revalidate(); + sleep(); + check("button.revalidate():", false, true, true); + + panel.setBounds(3, 3, 152, 121); + sleep(); + check("panel.setBounds():", false, false, true); + + panel.revalidate(); + sleep(); + check("panel.revalidate():", true, true, true); + + // cleanup + frame.dispose(); + } +} From d097a2cab142e19c36b1d8c4ca5455eb125ba719 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev <dav@openjdk.org> Date: Tue, 19 Apr 2011 18:52:49 +0400 Subject: [PATCH 02/13] 7036733: Regression : NullPointerException when scrolling horizontally on AWT List Reviewed-by: dcherepanov --- .../classes/sun/awt/X11/XListPeer.java | 5 +- .../awt/List/ScrollOutside/ScrollOut.java | 84 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/List/ScrollOutside/ScrollOut.java diff --git a/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java index c8799a1ad07..838899e49b8 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java @@ -1479,16 +1479,19 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { int h = height - (SCROLLBAR_AREA + (2 * MARGIN)); hsb.setValue(hsb.getValue() + x); + int options = PAINT_ITEMS | PAINT_HSCROLL; + Rectangle source = null; Point distance = null; if (x < 0) { source = new Rectangle(MARGIN + SPACE, MARGIN, w + x, h); distance = new Point(-x, 0); + options |= COPY_AREA; } else if (x > 0) { source = new Rectangle(MARGIN + SPACE + x, MARGIN, w - x, h); distance = new Point(-x, 0); + options |= COPY_AREA; } - int options = COPY_AREA | PAINT_ITEMS | PAINT_HSCROLL; repaint(vsb.getValue(), lastItemDisplayed(), options, source, distance); } diff --git a/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java b/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java new file mode 100644 index 00000000000..21b8f848229 --- /dev/null +++ b/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 7036733 + @summary Regression : NullPointerException when scrolling horizontally on AWT List + @author Andrei Dmitriev area=awt-list + @library ../../regtesthelpers + @build Util + @run main ScrollOut +*/ + +import java.awt.*; +import java.awt.event.*; +import sun.awt.SunToolkit; +import test.java.awt.regtesthelpers.Util; + +public class ScrollOut +{ + public static final void main(String args[]) + { + final Frame frame = new Frame(); + final List list = new List(); + Robot robot = null; + + for (int i = 0; i < 5; i++){ + list.add("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + } + + frame.add(list); + + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + + try{ + robot = new Robot(); + }catch(AWTException e){ + throw new RuntimeException(e); + } + + //Drag from center to the outside on left + Point from = new Point(list.getLocationOnScreen().x + list.getWidth()/2, + list.getLocationOnScreen().y + list.getHeight()/2); + Point to = new Point(list.getLocationOnScreen().x - 30, + from.y); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + Util.drag(robot, from, to, InputEvent.BUTTON1_MASK); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + + //Drag from center to the outside on up + to = new Point(from.x, + list.getLocationOnScreen().y - 50); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + Util.drag(robot, from, to, InputEvent.BUTTON1_MASK); + + }//End init() +} From b91701fce632312a5aacec63e7f9126dccc2dec0 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev <dav@openjdk.org> Date: Mon, 25 Apr 2011 21:08:14 +0400 Subject: [PATCH 03/13] 7030632: Pasting HTML that was copied from MS Word results in IOException Reviewed-by: uta, denis --- .../windows/classes/sun/awt/windows/WDataTransferer.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java index 21c1945140f..47dcf275430 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java @@ -830,7 +830,14 @@ class HTMLCodec extends InputStream { if( -1 == iStartOffset ){ throw new IOException(FAILURE_MSG + "invalid HTML format."); } - iReadCount = bufferedStream.skip(iStartOffset); + + int curOffset = 0; + while (curOffset < iStartOffset){ + curOffset += bufferedStream.skip(iStartOffset - curOffset); + } + + iReadCount = curOffset; + if( iStartOffset != iReadCount ){ throw new IOException(FAILURE_MSG + "Byte stream ends in description."); } From 5621d404bfbc05943b42affbba32ad2e43cda565 Mon Sep 17 00:00:00 2001 From: Denis Fokin <denis@openjdk.org> Date: Mon, 25 Apr 2011 20:39:35 +0400 Subject: [PATCH 04/13] 6888182: Readable and permitted to delete files could not be transferred through Clipboard and DnD Reviewed-by: uta --- jdk/src/windows/native/sun/windows/awt_Clipboard.cpp | 2 +- jdk/src/windows/native/sun/windows/awt_DnDDS.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp b/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp index d978090b8b3..6cea4a715fb 100644 --- a/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp @@ -294,7 +294,7 @@ Java_sun_awt_windows_WClipboard_publishClipboardData(JNIEnv *env, if (format == CF_HDROP) { DROPFILES *dropfiles = (DROPFILES *)dataout; dropfiles->pFiles = sizeof(DROPFILES); - dropfiles->fWide = FALSE; // good guess! + dropfiles->fWide = TRUE; // we publish only Unicode dataout += sizeof(DROPFILES); } diff --git a/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp b/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp index 1aea026c885..2d585e0330a 100644 --- a/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp +++ b/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp @@ -843,7 +843,7 @@ HRESULT __stdcall AwtDragSource::GetData(FORMATETC __RPC_FAR *pFormatEtc, dropfiles->pt.x = m_dropPoint.x; dropfiles->pt.y = m_dropPoint.y; dropfiles->fNC = m_fNC; - dropfiles->fWide = TRUE; // good guess! + dropfiles->fWide = TRUE; // we publish only Unicode dataout += sizeof(DROPFILES); } From f5afc05e608009a6805b59072f44a983c1b81350 Mon Sep 17 00:00:00 2001 From: Denis Fokin <denis@openjdk.org> Date: Wed, 27 Apr 2011 14:58:40 +0400 Subject: [PATCH 05/13] 7020922: java.awt.Toolkit.getPropertyChangeListeners() should mention that it returns proxies Reviewed-by: malenkov --- jdk/src/share/classes/java/awt/Toolkit.java | 40 ++++++++++++++------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index 58a4ddc7b4f..6e00e6afdbf 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -1870,11 +1870,15 @@ public abstract class Toolkit { /** * Adds the specified property change listener for the named desktop - * property. - * If pcl is null, no exception is thrown and no action is performed. + * property. When a {@link PropertyChangeListenerProxy} object is added, + * its property name is ignored, and the wrapped listener is added. + * If {@code name} is {@code null} or {@code pcl} is {@code null}, + * no exception is thrown and no action is performed. * * @param name The name of the property to listen for * @param pcl The property change listener + * @see PropertyChangeSupport#addPropertyChangeListener(String, + PropertyChangeListener) * @since 1.2 */ public void addPropertyChangeListener(String name, PropertyChangeListener pcl) { @@ -1883,11 +1887,16 @@ public abstract class Toolkit { /** * Removes the specified property change listener for the named - * desktop property. - * If pcl is null, no exception is thrown and no action is performed. + * desktop property. When a {@link PropertyChangeListenerProxy} object + * is removed, its property name is ignored, and + * the wrapped listener is removed. + * If {@code name} is {@code null} or {@code pcl} is {@code null}, + * no exception is thrown and no action is performed. * * @param name The name of the property to remove * @param pcl The property change listener + * @see PropertyChangeSupport#removePropertyChangeListener(String, + PropertyChangeListener) * @since 1.2 */ public void removePropertyChangeListener(String name, PropertyChangeListener pcl) { @@ -1896,12 +1905,15 @@ public abstract class Toolkit { /** * Returns an array of all the property change listeners - * registered on this toolkit. + * registered on this toolkit. The returned array + * contains {@code PropertyChangeListenerProxy} objects + * that associate listeners with the names of desktop properties. * - * @return all of this toolkit's <code>PropertyChangeListener</code>s - * or an empty array if no property change - * listeners are currently registered + * @return all of this toolkit's {@ code PropertyChangeListener} + * objects wrapped in {@code PropertyChangeListenerProxy} objects + * or an empty array if no listeners are added * + * @see PropertyChangeSupport#getPropertyChangeListeners() * @since 1.4 */ public PropertyChangeListener[] getPropertyChangeListeners() { @@ -1909,13 +1921,15 @@ public abstract class Toolkit { } /** - * Returns an array of all the <code>PropertyChangeListener</code>s - * associated with the named property. + * Returns an array of all property change listeners + * associated with the specified name of a desktop property. * * @param propertyName the named property - * @return all of the <code>PropertyChangeListener</code>s associated with - * the named property or an empty array if no such listeners have - * been added + * @return all of the {@code PropertyChangeListener} objects + * associated with the specified name of a desktop property + * or an empty array if no such listeners are added + * + * @see PropertyChangeSupport#getPropertyChangeListeners(String) * @since 1.4 */ public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) { From ed12b2ab1870adf1e80c6c9d03b6ce77f29b2f4d Mon Sep 17 00:00:00 2001 From: Denis Fokin <denis@openjdk.org> Date: Wed, 27 Apr 2011 17:18:38 +0400 Subject: [PATCH 06/13] 6998716: client vm crashes making browser fails to respond under some scenarios Reviewed-by: art, denis, uta --- .../windows/native/sun/windows/ObjectList.cpp | 7 +++-- .../windows/native/sun/windows/ObjectList.h | 2 +- .../native/sun/windows/awt_Component.cpp | 7 ++--- .../native/sun/windows/awt_MenuItem.cpp | 3 +-- .../windows/native/sun/windows/awt_Object.cpp | 19 +++++++++----- .../windows/native/sun/windows/awt_Object.h | 4 +++ .../windows/native/sun/windows/awt_Robot.cpp | 3 +-- .../native/sun/windows/awt_Toolkit.cpp | 26 +++++++++++++++---- .../native/sun/windows/awt_TrayIcon.cpp | 3 +-- jdk/src/windows/native/sun/windows/awtmsg.h | 1 + 10 files changed, 51 insertions(+), 24 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/ObjectList.cpp b/jdk/src/windows/native/sun/windows/ObjectList.cpp index b0614e6b97f..601c42ce2e3 100644 --- a/jdk/src/windows/native/sun/windows/ObjectList.cpp +++ b/jdk/src/windows/native/sun/windows/ObjectList.cpp @@ -48,7 +48,7 @@ void AwtObjectList::Add(AwtObject* obj) m_head = item; } -void AwtObjectList::Remove(AwtObject* obj) +BOOL AwtObjectList::Remove(AwtObject* obj) { CriticalSection::Lock l(m_lock); @@ -64,11 +64,14 @@ void AwtObjectList::Remove(AwtObject* obj) } DASSERT(item != NULL); delete item; - return; + return TRUE; } lastItem = item; item = item->next; } + + return FALSE; + // DASSERT(FALSE); // should never get here... // even if it does it shouldn't be fatal. } diff --git a/jdk/src/windows/native/sun/windows/ObjectList.h b/jdk/src/windows/native/sun/windows/ObjectList.h index 9775d0c9f1e..1e80732ca39 100644 --- a/jdk/src/windows/native/sun/windows/ObjectList.h +++ b/jdk/src/windows/native/sun/windows/ObjectList.h @@ -46,7 +46,7 @@ public: AwtObjectList(); void Add(AwtObject* obj); - void Remove(AwtObject* obj); + BOOL Remove(AwtObject* obj); #ifdef DEBUG /* Used for sanity checks only. */ AwtObject* LookUp(AwtObject* obj); diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index fd75b8d52ee..592a9b434b2 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -1969,7 +1969,9 @@ MsgRouting AwtComponent::WmDestroy() { // fix for 6259348: we should enter the SyncCall critical section before // disposing the native object, that is value 1 of lParam is intended for - AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)this, (LPARAM)1); + if(m_peerObject != NULL) { // is not being terminating + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)m_peerObject, (LPARAM)1); + } return mrConsume; } @@ -6534,8 +6536,7 @@ Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self) { TRY_NO_HANG; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp index aeb1021262a..97f3e2a7a21 100644 --- a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp +++ b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp @@ -974,8 +974,7 @@ Java_sun_awt_windows_WMenuItemPeer__1dispose(JNIEnv *env, jobject self) { TRY_NO_HANG; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Object.cpp b/jdk/src/windows/native/sun/windows/awt_Object.cpp index b7afe1aa510..54ec69a9a19 100644 --- a/jdk/src/windows/native/sun/windows/awt_Object.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Object.cpp @@ -60,11 +60,20 @@ AwtObject::~AwtObject() void AwtObject::Dispose() { - theAwtObjectList.Remove(this); + AwtToolkit::GetInstance().PostMessage(WM_AWT_DELETEOBJECT, (WPARAM)this, (LPARAM)0); +} + +void AwtObject::_Dispose(jobject self) +{ + TRY_NO_VERIFY; + + CriticalSection::Lock l(AwtToolkit::GetInstance().GetSyncCS()); // value 0 of lParam means that we should not attempt to enter the // SyncCall critical section, as it was entered someshere earlier - AwtToolkit::GetInstance().PostMessage(WM_AWT_DELETEOBJECT, (WPARAM)this, (LPARAM)0); + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)self, (LPARAM)0); + + CATCH_BAD_ALLOC; } void AwtObject::_Dispose(PDATA pData) @@ -73,14 +82,10 @@ void AwtObject::_Dispose(PDATA pData) CriticalSection::Lock l(AwtToolkit::GetInstance().GetSyncCS()); - if (pData != NULL) { - AwtObject *o = (AwtObject *)pData; - AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)o, (LPARAM)0); - } + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSEPDATA, (WPARAM)pData, (LPARAM)0); CATCH_BAD_ALLOC; } - /* * Return the peer associated with some target. This information is * maintained in a hashtable at the java level. diff --git a/jdk/src/windows/native/sun/windows/awt_Object.h b/jdk/src/windows/native/sun/windows/awt_Object.h index 6cfb83ebcc5..918e95d1c18 100644 --- a/jdk/src/windows/native/sun/windows/awt_Object.h +++ b/jdk/src/windows/native/sun/windows/awt_Object.h @@ -66,6 +66,10 @@ public: // After this method has been called, this object must not be used in any way. virtual void Dispose(); + // Static method to be called from JNI methods to dispose AwtObject + // specified by jobject + static void _Dispose(jobject self); + // Static method to be called from JNI methods to dispose AwtObject // specified by pData static void _Dispose(PDATA pData); diff --git a/jdk/src/windows/native/sun/windows/awt_Robot.cpp b/jdk/src/windows/native/sun/windows/awt_Robot.cpp index cdee9cf6001..09e12debf38 100644 --- a/jdk/src/windows/native/sun/windows/awt_Robot.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Robot.cpp @@ -353,8 +353,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WRobotPeer__1dispose( { TRY_NO_VERIFY; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index ca2bae8325a..d010d6b130c 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -740,18 +740,34 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, canDispose = syncCS.TryEnter(); } if (canDispose) { - AwtObject *o = (AwtObject *)wParam; - o->Dispose(); - if (shouldEnterCriticalSection) { - syncCS.Leave(); + if(wParam != NULL) { + AwtObject *o = (AwtObject *) JNI_GET_PDATA((jobject)wParam); + if(o != NULL && theAwtObjectList.Remove(o)) { + o->Dispose(); + } + if (shouldEnterCriticalSection) { + syncCS.Leave(); + } } } else { AwtToolkit::GetInstance().PostMessage(WM_AWT_DISPOSE, wParam, lParam); } return 0; } + case WM_AWT_DISPOSEPDATA: { + /* + * NOTE: synchronization routine (like in WM_AWT_DISPOSE) was omitted because + * this handler is called ONLY while disposing Cursor and Font objects where + * synchronization takes place. + */ + AwtObject *o = (AwtObject *) wParam; + if(o != NULL && theAwtObjectList.Remove(o)) { + o->Dispose(); + } + return 0; + } case WM_AWT_DELETEOBJECT: { - AwtObject *p = (AwtObject *)wParam; + AwtObject *p = (AwtObject *) wParam; if (p->CanBeDeleted()) { // all the messages for this component are processed, so // it can be deleted diff --git a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp index 4156c9cfec1..c2682b3b113 100644 --- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp +++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp @@ -926,8 +926,7 @@ Java_sun_awt_windows_WTrayIconPeer__1dispose(JNIEnv *env, jobject self) { TRY; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awtmsg.h b/jdk/src/windows/native/sun/windows/awtmsg.h index 898471b4923..05733c7a6f0 100644 --- a/jdk/src/windows/native/sun/windows/awtmsg.h +++ b/jdk/src/windows/native/sun/windows/awtmsg.h @@ -219,6 +219,7 @@ enum { WM_AWT_ENDCOMPOSITION, WM_AWT_DISPOSE, + WM_AWT_DISPOSEPDATA, WM_AWT_DELETEOBJECT, WM_AWT_SETCONVERSIONSTATUS, WM_AWT_GETCONVERSIONSTATUS, From 88ddcf5e65d080f143e57965f8171241db96624d Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov <dcherepanov@openjdk.org> Date: Thu, 28 Apr 2011 13:26:18 +0400 Subject: [PATCH 07/13] 7032830: GraphicsDevice.setFullScreenWindow() works strange for decorated windows on OEL 7016382: GraphicsDevice.setFullScreenWindow() - spec clarification for exclusive mode for dec/undec Frames Reviewed-by: art --- jdk/src/share/classes/java/awt/GraphicsDevice.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jdk/src/share/classes/java/awt/GraphicsDevice.java b/jdk/src/share/classes/java/awt/GraphicsDevice.java index f3b7cd390a6..b99d7ef8def 100644 --- a/jdk/src/share/classes/java/awt/GraphicsDevice.java +++ b/jdk/src/share/classes/java/awt/GraphicsDevice.java @@ -257,6 +257,11 @@ public abstract class GraphicsDevice { * 1.0f, and the background color alpha is set to 255 (completely opaque). * These values are not restored when returning to windowed mode. * <p> + * It is unspecified and platform-dependent how decorated windows operate + * in full-screen mode. For this reason, it is recommended to turn off + * the decorations in a {@code Frame} or {@code Dialog} object by using the + * {@code setUndecorated} method. + * <p> * When returning to windowed mode from an exclusive full-screen window, * any display changes made by calling {@code setDisplayMode} are * automatically restored to their original state. @@ -272,6 +277,8 @@ public abstract class GraphicsDevice { * @see #setDisplayMode * @see Component#enableInputMethods * @see Component#setVisible + * @see Frame#setUndecorated + * @see Dialog#setUndecorated * * @since 1.4 */ From c9f3d958ec3d62c02f19ec1e34c601c276fe7f25 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev <dav@openjdk.org> Date: Thu, 28 Apr 2011 20:14:30 +0400 Subject: [PATCH 08/13] 6956646: Test: MouseWheelEvent/InfiniteRecursion test receives more MouseWheelEvents than expected Reviewed-by: serb, dcherepanov --- .../InfiniteRecursion/InfiniteRecursion.java | 13 ++++++++++--- .../InfiniteRecursion/InfiniteRecursion_1.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_2.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_3.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_4.java | 10 +++++++--- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java index 6ec02ffbf45..e5533b41891 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,6 +50,11 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; + static int actualEvents = 0; public static void main(String []s) @@ -96,8 +101,10 @@ public class InfiniteRecursion { Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java index 3ed18f0e4a2..733af38731d 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,6 +50,9 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion_1 { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public static void main(String []s) @@ -95,8 +98,10 @@ public class InfiniteRecursion_1 { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java index 4aecedeb833..94444088671 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,6 +56,9 @@ import java.applet.Applet; public class InfiniteRecursion_2 extends Applet { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public void init() @@ -107,8 +110,10 @@ public class InfiniteRecursion_2 extends Applet { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } }// start() } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java index 2804b14ce7e..c12636acdc5 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,6 +50,9 @@ import java.applet.Applet; public class InfiniteRecursion_3 extends Applet { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public void init() @@ -91,8 +94,10 @@ public class InfiniteRecursion_3 extends Applet { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } }// start() } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java index 600e0fa5af3..2fbb3d2e2b0 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,8 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion_4 { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions over a single frame without any siblings + final static int EXPECTED_COUNT = MOVE_COUNT * 2; static int actualEvents = 0; public static void main(String []s) @@ -80,8 +82,10 @@ public class InfiniteRecursion_4 { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } From 1e3fce0242fc651d74d060f0817f2761a862aae9 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov <dcherepanov@openjdk.org> Date: Thu, 28 Apr 2011 19:23:44 +0400 Subject: [PATCH 09/13] 6853146: Regression: on-the-spot input is broken in AWT Peered components Reviewed-by: art, ant, naoto --- jdk/src/windows/native/sun/windows/awt_TextComponent.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp index c1fc17826b0..5e9a08f46ee 100644 --- a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp +++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp @@ -191,8 +191,11 @@ void AwtTextComponent::SetCompositionWindow(RECT& rc) { HIMC hIMC = ImmGetContext(); // rc is not used for text component. - COMPOSITIONFORM cf = { CFS_POINT, {0,0}, {0,0,0,0} }; + COMPOSITIONFORM cf = { CFS_FORCE_POSITION, {0,0}, {0,0,0,0} }; GetCaretPos(&(cf.ptCurrentPos)); + // the proxy is the native focus owner and it contains the composition window + // let's convert the position to a coordinate space relative to proxy + ::MapWindowPoints(GetHWnd(), GetProxyFocusOwner(), (LPPOINT)&cf.ptCurrentPos, 1); ImmSetCompositionWindow(hIMC, &cf); LOGFONT lf; From ac156aab263ec8a9597dcc20807b27776ad18ccd Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov <dcherepanov@openjdk.org> Date: Thu, 28 Apr 2011 19:39:47 +0400 Subject: [PATCH 10/13] 7034766: closed/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java failed on jdk7 b134 Reviewed-by: art, ant --- jdk/src/windows/native/sun/windows/awt_Frame.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 4d3374e5734..398aea6db67 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -340,12 +340,16 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms } break; case WM_SETFOCUS: + if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain + if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) { AwtSetActiveWindow(); } mr = mrConsume; break; case WM_KILLFOCUS: + if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain + if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) { AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL); From 2ab6e13a2190b421760e1571bb8c396fc561e562 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov <dcherepanov@openjdk.org> Date: Fri, 29 Apr 2011 16:02:05 +0400 Subject: [PATCH 11/13] 7034291: Regression : Preedit String on active client is committed into unexpected component Reviewed-by: art, naoto --- .../native/sun/windows/awt_Component.cpp | 8 ++----- .../windows/native/sun/windows/awt_Frame.cpp | 22 ++++++++++++++++--- .../windows/native/sun/windows/awt_Frame.h | 9 ++++---- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 592a9b434b2..45236e6ffcd 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -1203,7 +1203,7 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) { WIN_MSG(WM_IME_COMPOSITIONFULL) WIN_MSG(WM_IME_SELECT) WIN_MSG(WM_IME_CHAR) - FMT_MSG(0x0288, "WM_IME_REQUEST") + FMT_MSG(WM_IME_REQUEST) WIN_MSG(WM_IME_KEYDOWN) WIN_MSG(WM_IME_KEYUP) FMT_MSG(0x02A1, "WM_MOUSEHOVER") @@ -1733,7 +1733,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) case WM_IME_SELECT: case WM_IME_KEYUP: case WM_IME_KEYDOWN: - case 0x0288: // WM_IME_REQUEST + case WM_IME_REQUEST: CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_CHAR: @@ -4657,10 +4657,6 @@ void* AwtComponent::SetNativeFocusOwner(void *self) { ret: if (c && ::IsWindow(c->GetHWnd())) { sm_focusOwner = c->GetHWnd(); - AwtFrame *owner = (AwtFrame*)GetComponent(c->GetProxyToplevelContainer()); - if (owner) { - owner->SetLastProxiedFocusOwner(sm_focusOwner); - } } else { sm_focusOwner = NULL; } diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 398aea6db67..6662d6d54c2 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -109,7 +109,7 @@ AwtFrame::AwtFrame() { m_isMenuDropped = FALSE; m_isInputMethodWindow = FALSE; m_isUndecorated = FALSE; - m_lastProxiedFocusOwner = NULL; + m_imeTargetComponent = NULL; m_actualFocusedWindow = NULL; m_iconic = FALSE; m_zoomed = FALSE; @@ -311,6 +311,8 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms LRESULT retValue = 0L; AwtComponent *focusOwner = NULL; + AwtComponent *imeTargetComponent = NULL; + // IME and input language related messages need to be sent to a window // which has the Java input focus switch (message) { @@ -323,15 +325,29 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms case WM_IME_COMPOSITIONFULL: case WM_IME_SELECT: case WM_IME_CHAR: - case 0x0288: // WM_IME_REQUEST + case WM_IME_REQUEST: case WM_IME_KEYDOWN: case WM_IME_KEYUP: case WM_INPUTLANGCHANGEREQUEST: case WM_INPUTLANGCHANGE: + if (message == WM_IME_STARTCOMPOSITION) { + SetImeTargetComponent(sm_focusOwner); + } + imeTargetComponent = AwtComponent::GetComponent(GetImeTargetComponent()); + if (imeTargetComponent != NULL && + imeTargetComponent != this) // avoid recursive calls + { + retValue = imeTargetComponent->WindowProc(message, wParam, lParam); + mr = mrConsume; + } + if (message == WM_IME_ENDCOMPOSITION) { + SetImeTargetComponent(NULL); + } + break; // TODO: when a Choice's list is dropped down and we're scrolling in // the list WM_MOUSEWHEEL messages come to the poxy, not to the list. Why? case WM_MOUSEWHEEL: - focusOwner = AwtComponent::GetComponent(GetLastProxiedFocusOwner()); + focusOwner = AwtComponent::GetComponent(sm_focusOwner); if (focusOwner != NULL && focusOwner != this) // avoid recursive calls { diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.h b/jdk/src/windows/native/sun/windows/awt_Frame.h index 1adca139bf9..f6d692b87eb 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.h +++ b/jdk/src/windows/native/sun/windows/awt_Frame.h @@ -150,8 +150,8 @@ public: void CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd); BOOL CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd); - INLINE HWND GetLastProxiedFocusOwner() { return m_lastProxiedFocusOwner; } - INLINE void SetLastProxiedFocusOwner(HWND hwnd) { m_lastProxiedFocusOwner = hwnd; } + INLINE HWND GetImeTargetComponent() { return m_imeTargetComponent; } + INLINE void SetImeTargetComponent(HWND hwnd) { m_imeTargetComponent = hwnd; } protected: /* The frame is undecorated. */ @@ -179,9 +179,8 @@ private: /* The frame is an InputMethodWindow */ BOOL m_isInputMethodWindow; - /* Retains the last/current sm_focusOwner proxied. Actually, it should be - * a component of an owned window last/currently active. */ - HWND m_lastProxiedFocusOwner; + // retains the target component for the IME messages + HWND m_imeTargetComponent; /* * Fix for 4823903. From 202b18b4f568e73a1eef78094f9ff5ce7d6e2c3c Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov <dcherepanov@openjdk.org> Date: Fri, 29 Apr 2011 16:16:25 +0400 Subject: [PATCH 12/13] 7026055: Regression : Cannot use IME on JComboBox Japanese Reviewed-by: art, ant, naoto --- .../native/sun/windows/awt_Component.cpp | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 45236e6ffcd..024915fcffc 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -549,8 +549,6 @@ AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title, m_hwnd = hwnd; - ImmAssociateContext(NULL); - SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED | (jint)JAWT_LOCK_BOUNDS_CHANGED | (jint)JAWT_LOCK_CLIP_CHANGED); @@ -2022,25 +2020,6 @@ MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu) MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status) { - // NULL-InputContext is associated to all window just after they created. - // ( see CreateHWnd() ) - // But to TextField and TextArea on Win95, valid InputContext is associated - // by system after that. This is not happen on NT4.0 - // For workaround, force context to NULL here. - - // Fix for 4730228 - // Check if we already have Java-associated input method - HIMC context = 0; - if (m_InputMethod != NULL) { - // If so get the appropriate context from it and use it instead of empty context - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - context = (HIMC)(UINT_PTR)(JNU_GetFieldByName(env, NULL, m_InputMethod, "context", "I").i); - } - - if (ImmGetContext() != 0 && ImmGetContext() != context) { - ImmAssociateContext(context); - } - return mrDoDefault; } From 2b767e1070b9a77798dd9152afba9f0243a0640e Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov <serb@openjdk.org> Date: Tue, 3 May 2011 15:19:04 +0400 Subject: [PATCH 13/13] 7016528: Deadlock during mutual initialization of DataTransferer and DataTransferer$DataFlavorComparator Reviewed-by: dav, art, denis --- .../sun/awt/datatransfer/DataTransferer.java | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index e8fe5859b2d..82ff8899349 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -29,12 +29,10 @@ import java.awt.AWTError; import java.awt.EventQueue; import java.awt.Image; import java.awt.Graphics; -import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.FlavorMap; import java.awt.datatransfer.FlavorTable; -import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; @@ -66,8 +64,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessControlContext; -import java.security.AccessControlException; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; @@ -171,7 +167,26 @@ public abstract class DataTransferer { */ public static final DataFlavor javaTextEncodingFlavor; - private static SortedSet standardEncodings; + /** + * Lazy initialization of Standard Encodings. + */ + private static class StandardEncodingsHolder { + private static final SortedSet standardEncodings = load(); + + private static SortedSet load() { + final Comparator comparator = + new CharsetComparator(IndexedComparator.SELECT_WORST); + final SortedSet tempSet = new TreeSet(comparator); + tempSet.add("US-ASCII"); + tempSet.add("ISO-8859-1"); + tempSet.add("UTF-8"); + tempSet.add("UTF-16BE"); + tempSet.add("UTF-16LE"); + tempSet.add("UTF-16"); + tempSet.add(getDefaultTextCharset()); + return Collections.unmodifiableSortedSet(tempSet); + } + } /** * Tracks whether a particular text/* MIME type supports the charset @@ -509,18 +524,7 @@ public abstract class DataTransferer { * non-standard, character sets are not included. */ public static Iterator standardEncodings() { - if (standardEncodings == null) { - TreeSet tempSet = new TreeSet(defaultCharsetComparator); - tempSet.add("US-ASCII"); - tempSet.add("ISO-8859-1"); - tempSet.add("UTF-8"); - tempSet.add("UTF-16BE"); - tempSet.add("UTF-16LE"); - tempSet.add("UTF-16"); - tempSet.add(getDefaultTextCharset()); - standardEncodings = Collections.unmodifiableSortedSet(tempSet); - } - return standardEncodings.iterator(); + return StandardEncodingsHolder.standardEncodings.iterator(); } /** @@ -2398,7 +2402,9 @@ search: public static DataFlavor[] setToSortedDataFlavorArray(Set flavorsSet) { DataFlavor[] flavors = new DataFlavor[flavorsSet.size()]; flavorsSet.toArray(flavors); - Arrays.sort(flavors, defaultFlavorComparator); + final Comparator comparator = + new DataFlavorComparator(IndexedComparator.SELECT_WORST); + Arrays.sort(flavors, comparator); return flavors; } @@ -2455,11 +2461,6 @@ search: return new ArrayList(); } - private static CharsetComparator defaultCharsetComparator = - new CharsetComparator(IndexedComparator.SELECT_WORST); - private static DataFlavorComparator defaultFlavorComparator = - new DataFlavorComparator(IndexedComparator.SELECT_WORST); - /** * A Comparator which includes a helper function for comparing two Objects * which are likely to be keys in the specified Map.