Author: rwhitcomb Date: Wed Dec 18 16:44:14 2013 New Revision: 1552012 URL: http://svn.apache.org/r1552012 Log: PIVOT-927: Seemingly random occurrence of a NullPointerException during mouse operations causes the UI thread to crash, making the application unresponsive.
>From the stack trace the problem is a null location for the mouse which is not checked before referencing the location variable. So, protect all references to the location with a null check first. Also make some effort to use the display mouse location if necessary (that is, if the "mapPointFromAncestor" returns a null location). This is a merge of revision 1551992 from branches/2.0.x to trunk. Modified: pivot/trunk/ (props changed) pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java Propchange: pivot/trunk/ ------------------------------------------------------------------------------ Merged /pivot/branches/2.0.x:r1551992 Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java?rev=1552012&r1=1552011&r2=1552012&view=diff ============================================================================== --- pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java (original) +++ pivot/trunk/wtk/src/org/apache/pivot/wtk/ApplicationContext.java Wed Dec 18 16:44:14 2013 @@ -178,9 +178,14 @@ public abstract class ApplicationContext Point dropLocation = dropDescendant.mapPointFromAncestor(display, location.x, location.y); - dropAction = dropTarget.dragMove(dropDescendant, dragManifest, - getSupportedDropActions(event.getSourceActions()), dropLocation.x, - dropLocation.y, userDropAction); + if (dropLocation == null) { + dropLocation = display.getMouseLocation(); + } + if (dropLocation != null) { + dropAction = dropTarget.dragMove(dropDescendant, dragManifest, + getSupportedDropActions(event.getSourceActions()), + dropLocation.x, dropLocation.y, userDropAction); + } } } else { if (previousDropDescendant != null) { @@ -217,11 +222,16 @@ public abstract class ApplicationContext java.awt.Point location = event.getLocation(); Point dropLocation = dropDescendant.mapPointFromAncestor(display, location.x, location.y); + if (dropLocation == null) { + dropLocation = display.getMouseLocation(); + } - DropTarget dropTarget = dropDescendant.getDropTarget(); - dropAction = dropTarget.userDropActionChange(dropDescendant, dragManifest, - getSupportedDropActions(event.getSourceActions()), dropLocation.x, - dropLocation.y, userDropAction); + if (dropLocation != null) { + DropTarget dropTarget = dropDescendant.getDropTarget(); + dropAction = dropTarget.userDropActionChange(dropDescendant, dragManifest, + getSupportedDropActions(event.getSourceActions()), + dropLocation.x, dropLocation.y, userDropAction); + } } if (dropAction == null) { @@ -243,14 +253,20 @@ public abstract class ApplicationContext if (dropDescendant != null) { Point dropLocation = dropDescendant.mapPointFromAncestor(display, location.x, location.y); + if (dropLocation == null) { + dropLocation = display.getMouseLocation(); + } + DropTarget dropTarget = dropDescendant.getDropTarget(); // Simulate a user drop action change to get the current // drop action int supportedDropActions = getSupportedDropActions(event.getSourceActions()); - dropAction = dropTarget.userDropActionChange(dropDescendant, dragManifest, - supportedDropActions, dropLocation.x, dropLocation.y, userDropAction); + if (dropLocation != null) { + dropAction = dropTarget.userDropActionChange(dropDescendant, dragManifest, + supportedDropActions, dropLocation.x, dropLocation.y, userDropAction); + } if (dropAction != null) { // Perform the drop @@ -920,8 +936,13 @@ public abstract class ApplicationContext } else { mouseOwner = mouseCapturer; Point location = mouseOwner.mapPointFromAncestor(display, x, y); - x = location.x; - y = location.y; + if (location == null) { + location = display.getMouseLocation(); + } + if (location != null) { + x = location.x; + y = location.y; + } } // Delegate the event to the owner @@ -1082,8 +1103,8 @@ public abstract class ApplicationContext int dragThreshold = Platform.getDragThreshold(); if (dragLocation != null - && (Math.abs(x - dragLocation.x) > dragThreshold || Math.abs(y - - dragLocation.y) > dragThreshold)) { + && (Math.abs(x - dragLocation.x) > dragThreshold || + Math.abs(y - dragLocation.y) > dragThreshold)) { // The user has dragged the mouse past the // drag threshold; try // to find a drag source @@ -1104,55 +1125,67 @@ public abstract class ApplicationContext DragSource dragSource = dragDescendant.getDragSource(); dragLocation = dragDescendant.mapPointFromAncestor(display, x, y); + if (dragLocation == null) { + dragLocation = display.getMouseLocation(); + } - if (dragSource.beginDrag(dragDescendant, dragLocation.x, - dragLocation.y)) { - // A drag has started - if (dragSource.isNative()) { - startNativeDrag(dragSource, dragDescendant, event); - - // Clear the drag state since it - // is not used for - // native drags + if (dragLocation != null) { + if (dragSource.beginDrag(dragDescendant, + dragLocation.x, dragLocation.y)) { + // A drag has started + if (dragSource.isNative()) { + startNativeDrag(dragSource, dragDescendant, + event); + + // Clear the drag state since it + // is not used for + // native drags + dragDescendant = null; + dragLocation = null; + } else { + if (dragSource.getRepresentation() != null + && dragSource.getOffset() == null) { + throw new IllegalStateException( + "Drag offset is required when a " + + " representation is specified."); + } + + if (display.isMouseOver()) { + display.mouseOut(); + } + + // Get the drag content + dragManifest = dragSource.getContent(); + + // Get the initial user drop + // action + userDropAction = getUserDropAction(event); + + // Repaint the drag visual + dragLocation = new Point(x, y); + repaintDragRepresentation(); + } + } else { + // Clear the drag state dragDescendant = null; dragLocation = null; - } else { - if (dragSource.getRepresentation() != null - && dragSource.getOffset() == null) { - throw new IllegalStateException( - "Drag offset is required when a " - + " representation is specified."); - } - - if (display.isMouseOver()) { - display.mouseOut(); - } - - // Get the drag content - dragManifest = dragSource.getContent(); - - // Get the initial user drop - // action - userDropAction = getUserDropAction(event); - - // Repaint the drag visual - dragLocation = new Point(x, y); - repaintDragRepresentation(); } - } else { - // Clear the drag state - dragDescendant = null; - dragLocation = null; } } } } else { // Delegate the event to the capturer Point location = mouseCapturer.mapPointFromAncestor(display, x, y); - boolean consumed = mouseCapturer.mouseMove(location.x, location.y); + if (location == null) { + location = display.getMouseLocation(); + } - if (consumed) { - event.consume(); + if (location != null) { + boolean consumed = mouseCapturer.mouseMove(location.x, location.y); + + if (consumed) { + event.consume(); + } } } } else { @@ -1173,9 +1206,14 @@ public abstract class ApplicationContext Point dropLocation = dropDescendant.mapPointFromAncestor( display, x, y); - dropAction = dropTarget.dragMove(dropDescendant, - dragManifest, dragSource.getSupportedDropActions(), - dropLocation.x, dropLocation.y, userDropAction); + if (dropLocation == null) { + dropLocation = display.getMouseLocation(); + } + if (dropLocation != null) { + dropAction = dropTarget.dragMove(dropDescendant, dragManifest, + dragSource.getSupportedDropActions(), + dropLocation.x, dropLocation.y, userDropAction); + } } } else { if (previousDropDescendant != null) { @@ -1261,8 +1299,13 @@ public abstract class ApplicationContext } else { mouseOwner = mouseCapturer; Point location = mouseOwner.mapPointFromAncestor(display, x, y); - x = location.x; - y = location.y; + if (location == null) { + location = display.getMouseLocation(); + } + if (location != null) { + x = location.x; + y = location.y; + } } // Delegate the event to the owner @@ -1464,15 +1507,18 @@ public abstract class ApplicationContext DropTarget dropTarget = dropDescendant.getDropTarget(); Point dropLocation = dragLocation; + if (dropLocation != null) { + dropLocation = dropDescendant.mapPointFromAncestor(display, + dropLocation.x, dropLocation.y); + } if (dropLocation == null) { dropLocation = display.getMouseLocation(); } - - dropLocation = dropDescendant.mapPointFromAncestor(display, dropLocation.x, - dropLocation.y); - dropTarget.userDropActionChange(dropDescendant, dragManifest, - dragSource.getSupportedDropActions(), dropLocation.x, dropLocation.y, - userDropAction); + if (dropLocation != null) { + dropTarget.userDropActionChange(dropDescendant, dragManifest, + dragSource.getSupportedDropActions(), + dropLocation.x, dropLocation.y, userDropAction); + } } } }