more work for bug 7347 (mac scrollwheel). now works with logitech, but still requires a click. we have code that doesn't, but there are still some issues. r=saari/sr=sfraser.

git-svn-id: svn://10.0.0.236/trunk@83931 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
pinkerton%netscape.com
2000-12-21 01:31:23 +00:00
parent 5e93b0a60f
commit 6ae938a280
3 changed files with 74 additions and 23 deletions

View File

@@ -58,8 +58,6 @@ PRBool nsMacEventHandler::sMouseInWidgetHit = PR_FALSE;
nsMacEventDispatchHandler gEventDispatchHandler;
static pascal void ScrollActionProc (ControlHandle ctrl, ControlPartCode part) ;
//
// ScrollActionProc
//
@@ -75,7 +73,8 @@ static pascal void ScrollActionProc(ControlHandle ctrl, ControlPartCode partCode
case kControlDownButtonPart:
case kControlPageUpPart:
case kControlPageDownPart:
if ( gEventDispatchHandler.GetActive() ) {
PhantomScrollbarData* data = NS_REINTERPRET_CAST(PhantomScrollbarData*, ::GetControlReference(ctrl));
if ( data && (data->mWidgetToGetEvent || gEventDispatchHandler.GetActive()) ) {
nsMouseScrollEvent scrollEvent;
scrollEvent.scrollFlags = nsMouseScrollEvent::kIsVertical;
if ( partCode == kControlPageUpPart || partCode == kControlPageDownPart )
@@ -93,7 +92,8 @@ static pascal void ScrollActionProc(ControlHandle ctrl, ControlPartCode partCode
scrollEvent.point.x = 100;
scrollEvent.point.y = 100;
scrollEvent.time = PR_IntervalNow();
scrollEvent.widget = gEventDispatchHandler.GetActive();
scrollEvent.widget = data->mWidgetToGetEvent ?
data->mWidgetToGetEvent : gEventDispatchHandler.GetActive();
scrollEvent.nativeMsg = nsnull;
// dispatch scroll event
@@ -1255,6 +1255,12 @@ PRBool nsMacEventHandler::HandleMouseDownEvent(EventRecord& aOSEvent)
// don't allow clicks that rolled up a popup through to the content area.
if ( ignoreClickInContent )
break;
nsMouseEvent mouseEvent;
PRUint32 mouseButton = NS_MOUSE_LEFT_BUTTON_DOWN;
if ( aOSEvent.modifiers & controlKey )
mouseButton = NS_MOUSE_RIGHT_BUTTON_DOWN;
ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton);
// Check if the mousedown is in our window's phantom scrollbar. If so, track
// the movement of the mouse. The scrolling code is in the action proc.
@@ -1262,18 +1268,25 @@ PRBool nsMacEventHandler::HandleMouseDownEvent(EventRecord& aOSEvent)
::GlobalToLocal ( &local );
ControlHandle scrollbar;
ControlPartCode partCode = ::FindControl(local, whichWindow, &scrollbar);
if ( partCode >= kControlUpButtonPart && partCode <= kControlPageDownPart &&
scrollbar &&
GetControlReference(scrollbar) == 'mozz' ) {
::TrackControl(scrollbar, local, mControlActionProc);
break;
if ( partCode >= kControlUpButtonPart && partCode <= kControlPageDownPart && scrollbar ) {
PhantomScrollbarData* data = NS_REINTERPRET_CAST(PhantomScrollbarData*, ::GetControlReference(scrollbar));
if ( data && data->mTag == PhantomScrollbarData::kUniqueTag ) {
#if USEMOUSEPOSITIONFORSCROLLWHEEL
// Uncomment this in order to set the widget to scroll the widget the mouse is over. However,
// we end up getting an idle event while scrolling quickly with the wheel, and the end result
// is that our idle-time mouseMove event kicks in a moves where we think the mouse is to where
// the scrollwheel driver has convinced the OS the mouse really is. Net result: we lose track
// of the widget and scrolling stops until you stop the wheel and move it again :(
data->mWidgetToGetEvent = gEventDispatchHandler.GetWidgetPointed(); // tell action proc which widget to use
#endif
::TrackControl(scrollbar, local, mControlActionProc);
data->mWidgetToGetEvent = nsnull;
break;
}
}
nsMouseEvent mouseEvent;
PRUint32 mouseButton = NS_MOUSE_LEFT_BUTTON_DOWN;
if ( aOSEvent.modifiers & controlKey )
mouseButton = NS_MOUSE_RIGHT_BUTTON_DOWN;
ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton);
nsCOMPtr<nsIWidget> kungFuDeathGrip ( mouseEvent.widget ); // ensure widget doesn't go away
nsWindow* widgetHit = NS_STATIC_CAST(nsWindow*, mouseEvent.widget); // while we're processing event
if (widgetHit)
@@ -1357,7 +1370,7 @@ PRBool nsMacEventHandler::HandleMouseMoveEvent( EventRecord& aOSEvent )
{
nsWindow* lastWidgetHit = gEventDispatchHandler.GetWidgetHit();
nsWindow* lastWidgetPointed = gEventDispatchHandler.GetWidgetPointed();
PRBool retVal = PR_FALSE;
nsMouseEvent mouseEvent;

View File

@@ -37,6 +37,27 @@ class nsWindow;
class nsMacWindow;
//
// struct PhantomScrollbarData
//
// When creating the phantom scrollbar for a Gecko instance, create
// one of these structures and stick it in the control's refCon. It
// is used not only to identify our scrollbar from any others, but
// also to pass data to the scrollbar's action proc about which
// widget is the one the mouse is over.
//
struct PhantomScrollbarData
{
PhantomScrollbarData ( )
: mTag(kUniqueTag), mWidgetToGetEvent(nsnull) { }
enum ResType { kUniqueTag = 'mozz' };
ResType mTag; // should always be kUniqueTag
nsIWidget* mWidgetToGetEvent; // for the action proc, the widget to get the event
};
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
@@ -131,7 +152,7 @@ protected:
static PRBool sInBackground;
ControlActionUPP mControlActionProc;
nsMacWindow* mTopLevelWidget;
RgnHandle mUpdateRgn;
TSMDocumentID mTSMDocument;

View File

@@ -272,11 +272,11 @@ nsMacWindow::nsMacWindow() : Inherited()
, mAcceptsActivation(PR_TRUE)
, mIsActive(PR_FALSE)
, mZoomOnShow(PR_FALSE)
, mPhantomScrollbar(nil)
, mPhantomScrollbar(nsnull)
{
//mMacEventHandler.reset(new nsMacEventHandler(this));
mMacEventHandler = (auto_ptr<nsMacEventHandler>) new nsMacEventHandler(this);
WIDGET_SET_CLASSNAME("nsMacWindow");
WIDGET_SET_CLASSNAME("nsMacWindow");
}
@@ -289,6 +289,14 @@ nsMacWindow::~nsMacWindow()
{
if (mWindowPtr)
{
// cleanup the struct we hang off the scrollbar's refcon
if ( mPhantomScrollbar ) {
PhantomScrollbarData* data =
NS_REINTERPRET_CAST(PhantomScrollbarData*, ::GetControlReference(mPhantomScrollbar));
delete data;
::SetControlReference(mPhantomScrollbar, (long)nsnull);
}
if (mWindowMadeHere)
::DisposeWindow(mWindowPtr);
@@ -300,6 +308,7 @@ nsMacWindow::~nsMacWindow()
nsMacMessageSink::RemoveRaptorWindowFromList(mWindowPtr);
mWindowPtr = nsnull;
}
}
@@ -508,13 +517,21 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
// create a phantom scrollbar to catch the attention of mousewheel
// drivers. We'll catch events sent to this scrollbar in the eventhandler
// and dispatch them into gecko as NS_SCROLL_EVENTs at that point. Stash
// an identifier in the refcon so we can check it before calling TrackControl().
Rect sbRect = { 32000, 32000, 32100, 32016 };
// and dispatch them into gecko as NS_SCROLL_EVENTs at that point. We need
// to hang a struct off the refCon in order to provide some data
// to the action proc.
//
// For Logitech, the scrollbar has to be in the content area but can have
// zero width. For USBOverdrive (used also my MSFT), the scrollbar can be
// anywhere, but must have a valid width (one pixel wide works). The
// current location (one pixel wide, and flush along the left side of the
// window) is a reasonable comprimise in the short term. It is not intended
// to fix all cases.
Rect sbRect = { 100, 0, 200, 1 };
mPhantomScrollbar = ::NewControl ( mWindowPtr, &sbRect, nil, true, 50, 0, 100,
kControlScrollBarLiveProc, (long)'mozz' );
kControlScrollBarLiveProc, (long)new PhantomScrollbarData );
::EmbedControl ( rootControl, mPhantomScrollbar );
// register tracking and receive handlers with the native Drag Manager
#if !TARGET_CARBON
if ( sDragTrackingHandlerUPP ) {