Fix bug 281732: event handling in camino's native popup got broken when screen-relative coordinates in Cocoa widget were fixed (bug 281470), which caused the nsComboboxControlFrame/nsListControlFrame code to start doing mouse capture, and showing the XUL popup. So add a static method, ToolkitHasNativePopup(), and query that (rather than #ifdeffing). r/sr=roc, a=dbaron.

This commit is contained in:
smfr%smfr.org 2005-02-16 05:13:16 +00:00
parent fcfd665193
commit 0874f92566
3 changed files with 51 additions and 20 deletions

View File

@ -2298,8 +2298,7 @@ nsComboboxControlFrame::Paint(nsPresContext* aPresContext,
// If all of the nsITheme implementations are fixed to draw the focus border correctly, // If all of the nsITheme implementations are fixed to draw the focus border correctly,
// this #ifdef should be replaced with a -moz-appearance / ThemeSupportsWidget() check. // this #ifdef should be replaced with a -moz-appearance / ThemeSupportsWidget() check.
#ifndef MOZ_WIDGET_COCOA if (!ToolkitHasNativePopup() && mDisplayFrame) {
if (mDisplayFrame) {
aRenderingContext.PushState(); aRenderingContext.PushState();
nsRect clipRect = mDisplayFrame->GetRect(); nsRect clipRect = mDisplayFrame->GetRect();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect); aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
@ -2339,7 +2338,6 @@ nsComboboxControlFrame::Paint(nsPresContext* aPresContext,
///////////////////// /////////////////////
aRenderingContext.PopState(); aRenderingContext.PopState();
} }
#endif
} }
// Call to the base class to draw selection borders when appropriate // Call to the base class to draw selection borders when appropriate
@ -2460,3 +2458,22 @@ nsComboboxControlFrame::RestoreState(nsPresContext* aPresContext,
rv = stateful->RestoreState(aPresContext, aState); rv = stateful->RestoreState(aPresContext, aState);
return rv; return rv;
} }
//
// Some toolkits (just Cocoa at this point) use a native widget
// for the combobox popup, which affects drawing and event
// handling here and in nsListControlFrame.
//
/* static */
PRBool
nsComboboxControlFrame::ToolkitHasNativePopup()
{
#ifdef MOZ_WIDGET_COCOA
return PR_TRUE;
#else
return PR_FALSE;
#endif
}

View File

@ -213,6 +213,8 @@ public:
NS_IMETHOD SaveState(nsPresContext* aPresContext, nsPresState** aState); NS_IMETHOD SaveState(nsPresContext* aPresContext, nsPresState** aState);
NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsPresState* aState); NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsPresState* aState);
static PRBool ToolkitHasNativePopup();
protected: protected:
NS_IMETHOD CreateDisplayFrame(nsPresContext* aPresContext); NS_IMETHOD CreateDisplayFrame(nsPresContext* aPresContext);

View File

@ -35,6 +35,7 @@
* the terms of any one of the MPL, the GPL or the LGPL. * the terms of any one of the MPL, the GPL or the LGPL.
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "nscore.h" #include "nscore.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
@ -52,7 +53,7 @@
#include "nsIDOMHTMLSelectElement.h" #include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMNSHTMLSelectElement.h" #include "nsIDOMNSHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h" #include "nsIDOMHTMLOptionElement.h"
#include "nsIComboboxControlFrame.h" #include "nsComboboxControlFrame.h"
#include "nsIViewManager.h" #include "nsIViewManager.h"
#include "nsIScrollableView.h" #include "nsIScrollableView.h"
#include "nsIDOMHTMLOptGroupElement.h" #include "nsIDOMHTMLOptGroupElement.h"
@ -1355,6 +1356,14 @@ nsListControlFrame::HandleListSelection(nsIDOMEvent* aEvent,
NS_IMETHODIMP NS_IMETHODIMP
nsListControlFrame::CaptureMouseEvents(nsPresContext* aPresContext, PRBool aGrabMouseEvents) nsListControlFrame::CaptureMouseEvents(nsPresContext* aPresContext, PRBool aGrabMouseEvents)
{ {
// Currently cocoa widgets use a native popup widget which tracks clicks synchronously,
// so we never want to do mouse capturing. Note that we only bail if the list
// is in drop-down mode, and the caller is requesting capture (we let release capture
// requests go through to ensure that we can release capture requested via other
// code paths, if any exist).
if (aGrabMouseEvents && IsInDropDownMode() && nsComboboxControlFrame::ToolkitHasNativePopup())
return NS_OK;
nsIView* view = nsnull; nsIView* view = nsnull;
if (IsInDropDownMode()) { if (IsInDropDownMode()) {
view = GetView(); view = GetView();
@ -1922,7 +1931,7 @@ nsListControlFrame::GetSelectedIndex(PRInt32 * aIndex)
PRBool PRBool
nsListControlFrame::IsInDropDownMode() const nsListControlFrame::IsInDropDownMode() const
{ {
return((nsnull == mComboboxFrame) ? PR_FALSE : PR_TRUE); return (mComboboxFrame != nsnull);
} }
//--------------------------------------------------------- //---------------------------------------------------------
@ -2297,7 +2306,7 @@ nsListControlFrame::AboutToRollup()
// - IF the combobox is different from the current selected index, we // - IF the combobox is different from the current selected index, we
// reset the index. // reset the index.
if (IsInDropDownMode() == PR_TRUE) { if (IsInDropDownMode()) {
PRInt32 index; PRInt32 index;
mComboboxFrame->GetIndexOfDisplayArea(&index); mComboboxFrame->GetIndexOfDisplayArea(&index);
ComboboxFinish(index); ComboboxFinish(index);
@ -2313,7 +2322,7 @@ nsListControlFrame::DidReflow(nsPresContext* aPresContext,
{ {
nsresult rv; nsresult rv;
if (PR_TRUE == IsInDropDownMode()) if (IsInDropDownMode())
{ {
//SyncViewWithFrame(); //SyncViewWithFrame();
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW; mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
@ -2421,7 +2430,7 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
// if a right button click is on the combobox itself // if a right button click is on the combobox itself
// or on the select when in listbox mode, then let the click through // or on the select when in listbox mode, then let the click through
if (!IsLeftButton(aMouseEvent)) { if (!IsLeftButton(aMouseEvent)) {
if (IsInDropDownMode() == PR_TRUE) { if (IsInDropDownMode()) {
if (!IsClickingInCombobox(aMouseEvent)) { if (!IsClickingInCombobox(aMouseEvent)) {
aMouseEvent->PreventDefault(); aMouseEvent->PreventDefault();
@ -2494,7 +2503,7 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
mouseEvent->clickCount = 1; mouseEvent->clickCount = 1;
} else { } else {
// the click was out side of the select or its dropdown // the click was out side of the select or its dropdown
mouseEvent->clickCount = IsClickingInCombobox(aMouseEvent)?1:0; mouseEvent->clickCount = IsClickingInCombobox(aMouseEvent) ? 1 : 0;
} }
} else { } else {
REFLOW_DEBUG_MSG(">>>>>> Didn't find"); REFLOW_DEBUG_MSG(">>>>>> Didn't find");
@ -2610,7 +2619,6 @@ nsListControlFrame::GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent,
rv = NS_ERROR_FAILURE; rv = NS_ERROR_FAILURE;
} }
return rv; return rv;
} }
@ -2665,12 +2673,14 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK; return NS_OK;
} }
PRBool isDroppedDown; if (!nsComboboxControlFrame::ToolkitHasNativePopup())
mComboboxFrame->IsDroppedDown(&isDroppedDown); {
mComboboxFrame->ShowDropDown(!isDroppedDown); PRBool isDroppedDown;
mComboboxFrame->IsDroppedDown(&isDroppedDown);
if (isDroppedDown) { mComboboxFrame->ShowDropDown(!isDroppedDown);
CaptureMouseEvents(GetPresContext(), PR_FALSE); if (isDroppedDown) {
CaptureMouseEvents(GetPresContext(), PR_FALSE);
}
} }
} }
} }
@ -2687,7 +2697,7 @@ nsListControlFrame::MouseMove(nsIDOMEvent* aMouseEvent)
NS_ASSERTION(aMouseEvent, "aMouseEvent is null."); NS_ASSERTION(aMouseEvent, "aMouseEvent is null.");
//REFLOW_DEBUG_MSG("MouseMove\n"); //REFLOW_DEBUG_MSG("MouseMove\n");
if (IsInDropDownMode() == PR_TRUE) { if (IsInDropDownMode()) {
PRBool isDroppedDown = PR_FALSE; PRBool isDroppedDown = PR_FALSE;
mComboboxFrame->IsDroppedDown(&isDroppedDown); mComboboxFrame->IsDroppedDown(&isDroppedDown);
if (isDroppedDown) { if (isDroppedDown) {
@ -2716,7 +2726,7 @@ nsListControlFrame::DragMove(nsIDOMEvent* aMouseEvent)
NS_ASSERTION(aMouseEvent, "aMouseEvent is null."); NS_ASSERTION(aMouseEvent, "aMouseEvent is null.");
//REFLOW_DEBUG_MSG("DragMove\n"); //REFLOW_DEBUG_MSG("DragMove\n");
if (IsInDropDownMode() == PR_FALSE) { if (!IsInDropDownMode()) {
PRInt32 selectedIndex; PRInt32 selectedIndex;
if (NS_SUCCEEDED(GetIndexFromDOMEvent(aMouseEvent, selectedIndex))) { if (NS_SUCCEEDED(GetIndexFromDOMEvent(aMouseEvent, selectedIndex))) {
// Don't waste cycles if we already dragged over this item // Don't waste cycles if we already dragged over this item
@ -2942,7 +2952,9 @@ nsListControlFrame::GetIncrementalString()
void void
nsListControlFrame::DropDownToggleKey(nsIDOMEvent* aKeyEvent) nsListControlFrame::DropDownToggleKey(nsIDOMEvent* aKeyEvent)
{ {
if (IsInDropDownMode()) { // Cocoa widgets do native popups, so don't try to show
// dropdowns there.
if (IsInDropDownMode() && !nsComboboxControlFrame::ToolkitHasNativePopup()) {
PRBool isDroppedDown; PRBool isDroppedDown;
mComboboxFrame->IsDroppedDown(&isDroppedDown); mComboboxFrame->IsDroppedDown(&isDroppedDown);
mComboboxFrame->ShowDropDown(!isDroppedDown); mComboboxFrame->ShowDropDown(!isDroppedDown);
@ -3202,7 +3214,7 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
// XXX - Are we cover up a problem here??? // XXX - Are we cover up a problem here???
// Why aren't they getting flushed each time? // Why aren't they getting flushed each time?
// because this isn't needed for Gfx // because this isn't needed for Gfx
if (IsInDropDownMode() == PR_TRUE) { if (IsInDropDownMode()) {
// Don't flush anything but reflows lest it destroy us // Don't flush anything but reflows lest it destroy us
GetPresContext()->PresShell()-> GetPresContext()->PresShell()->
GetDocument()->FlushPendingNotifications(Flush_OnlyReflow); GetDocument()->FlushPendingNotifications(Flush_OnlyReflow);