From eefa801eabb356346fe6a1fb1d51983e2150efb5 Mon Sep 17 00:00:00 2001 From: dav Date: Tue, 25 Jan 2011 19:07:27 +0300 Subject: [PATCH] 6431076: Cursor gets reset to text cursor in xawt TextArea when autoscrolling on append Reviewed-by: art, anthony --- .../classes/sun/awt/X11/XComponentPeer.java | 16 +- .../sun/awt/X11/XGlobalCursorManager.java | 4 +- .../classes/sun/awt/X11/XTextAreaPeer.java | 39 +- .../MouseOverScrollbarWhenTyping/Test.java | 385 +++++++++++++++++ .../MouseOverScrollbarWhenTyping/Test1.java | 386 ++++++++++++++++++ 5 files changed, 822 insertions(+), 8 deletions(-) create mode 100644 test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java create mode 100644 test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java diff --git a/src/solaris/classes/sun/awt/X11/XComponentPeer.java b/src/solaris/classes/sun/awt/X11/XComponentPeer.java index a369a7f68..6e425513c 100644 --- a/src/solaris/classes/sun/awt/X11/XComponentPeer.java +++ b/src/solaris/classes/sun/awt/X11/XComponentPeer.java @@ -725,7 +725,21 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget XGlobalCursorManager.getCursorManager().updateCursorImmediately(); } - public void pSetCursor(Cursor cursor) { + public final void pSetCursor(Cursor cursor) { + this.pSetCursor(cursor, true); + } + + /* + * The method changes the cursor. + * @param cursor - a new cursor to change to. + * @param ignoreSubComponents - if {@code true} is passed then + * the new cursor will be installed on window. + * if {@code false} is passed then + * subsequent components will try to handle + * this request and install their cursor. + */ + //ignoreSubComponents not used here + public void pSetCursor(Cursor cursor, boolean ignoreSubComponents) { XToolkit.awtLock(); try { long xcursor = XGlobalCursorManager.getCursor(cursor); diff --git a/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java b/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java index 579586ae0..c28d9d03e 100644 --- a/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java +++ b/src/solaris/classes/sun/awt/X11/XGlobalCursorManager.java @@ -104,7 +104,9 @@ public final class XGlobalCursorManager extends GlobalCursorManager { nativeContainer = new WeakReference(nc); } - ((XComponentPeer)nc_peer).pSetCursor(cur); + //6431076. A subcomponents (a XTextArea in particular) + //may want to override the cursor over some of their parts. + ((XComponentPeer)nc_peer).pSetCursor(cur, false); // in case of grab we do for Swing we need to update keep cursor updated // (we don't need this in case of AWT menus). Window Manager consider // the grabber as a current window and use its cursor. So we need to diff --git a/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java b/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java index 4cbca4422..d9cc3033a 100644 --- a/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java +++ b/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java @@ -175,6 +175,34 @@ class XTextAreaPeer extends XComponentPeer implements TextAreaPeer { super.dispose(); } + + /* + * The method overrides one from XComponentPeer + * If ignoreSubComponents=={@code true} it calls super. + * If ignoreSubComponents=={@code false} it uses the XTextArea machinery + * to change cursor appropriately. In particular it changes the cursor to + * default if over scrollbars. + */ + @Override + public void pSetCursor(Cursor cursor, boolean ignoreSubComponents) { + Point onScreen = getLocationOnScreen(); + if (ignoreSubComponents || + javaMouseEventHandler == null || + onScreen == null) + { + super.pSetCursor(cursor, true); + return; + } + + Point cursorPos = new Point(); + ((XGlobalCursorManager)XGlobalCursorManager.getCursorManager()).getCursorPos(cursorPos); + + Point localPoint = new Point(cursorPos.x - onScreen.x, cursorPos.y - onScreen.y ); + + javaMouseEventHandler.setPointerToUnderPoint(localPoint); + javaMouseEventHandler.setCursor(); + } + void setScrollBarVisibility() { int visibility = ((TextArea)target).getScrollbarVisibility(); jtext.setLineWrap(false); @@ -1264,13 +1292,13 @@ class XTextAreaPeer extends XComponentPeer implements TextAreaPeer { void handle( MouseEvent event ) { if ( ! grabbed ) { // dispatch() needs up-to-date pointer in ungrabbed case. - setPointerToUnderEventPoint( event ); + setPointerToUnderPoint( event.getPoint() ); } dispatch( event ); boolean wasGrabbed = grabbed; grabbed_update( event ); if ( wasGrabbed && ! grabbed ) { - setPointerToUnderEventPoint( event ); + setPointerToUnderPoint( event.getPoint() ); } setCursor(); } @@ -1338,7 +1366,7 @@ class XTextAreaPeer extends XComponentPeer implements TextAreaPeer { // 'target.getCursor()' is also applied from elsewhere // (at least now), but only when mouse "entered", and // before 'XTextAreaPeer.handleJavaMouseEvent' is invoked. - outer.pSetCursor( outer.target.getCursor() ); + outer.pSetCursor( outer.target.getCursor(), true ); } else { // We can write here a more intelligent cursor selection @@ -1346,7 +1374,7 @@ class XTextAreaPeer extends XComponentPeer implements TextAreaPeer { // However, I see no point in doing so now. But if you feel // like implementing it, you'll probably need to introduce // 'Pointer.Type.PANEL'. - outer.pSetCursor( outer.textPane.getCursor() ); + outer.pSetCursor( outer.textPane.getCursor(), true ); } } @@ -1391,8 +1419,7 @@ class XTextAreaPeer extends XComponentPeer implements TextAreaPeer { return l; } - private void setPointerToUnderEventPoint( MouseEvent event ) { - Point point = event.getPoint(); + private void setPointerToUnderPoint( Point point ) { if ( outer.textPane.getViewport().getBounds().contains( point ) ) { current.setText(); } diff --git a/test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java b/test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java new file mode 100644 index 000000000..098fdac7e --- /dev/null +++ b/test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test.java @@ -0,0 +1,385 @@ +/* + @test + @bug 6431076 + @summary Mouse cursor must remain DEFAULT over scrollbar when text is typed + @author Andrei Dmitriev: area=TextArea + @run main/manual Test +*/ + +import java.awt.*; +import java.awt.event.*; + +public class Test { + private static void init() { + Frame f = new Frame("Test for cursor"); + final int dim = 100; + String line = ""; + for( int i=0; i 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Test.pass(); + } + else + { + Test.fail(); + } + } + +}// TestDialog class diff --git a/test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java b/test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java new file mode 100644 index 000000000..24d0670b4 --- /dev/null +++ b/test/java/awt/TextArea/MouseOverScrollbarWhenTyping/Test1.java @@ -0,0 +1,386 @@ +/* + @test + @bug 6431076 + @summary Mouse cursor must remain DEFAULT over scrollbar when text is typed + @author Andrei Dmitriev: area=TextArea + @run main/manual Test1 +*/ + +import java.awt.*; +import java.awt.event.*; + +public class Test1 { + private static void init() { + Frame f = new Frame("Test1 for cursor"); + final int dim = 100; + String line = ""; + for( int i=0; i 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Test1.pass(); + } + else + { + Test1.fail(); + } + } + +}// TestDialog class -- GitLab