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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
Reference in New Issue
Block a user