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
Родитель fcfd665193
Коммит 0874f92566
3 изменённых файлов: 51 добавлений и 20 удалений

Просмотреть файл

@ -2298,8 +2298,7 @@ nsComboboxControlFrame::Paint(nsPresContext* aPresContext,
// 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.
#ifndef MOZ_WIDGET_COCOA
if (mDisplayFrame) {
if (!ToolkitHasNativePopup() && mDisplayFrame) {
aRenderingContext.PushState();
nsRect clipRect = mDisplayFrame->GetRect();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
@ -2339,7 +2338,6 @@ nsComboboxControlFrame::Paint(nsPresContext* aPresContext,
/////////////////////
aRenderingContext.PopState();
}
#endif
}
// Call to the base class to draw selection borders when appropriate
@ -2460,3 +2458,22 @@ nsComboboxControlFrame::RestoreState(nsPresContext* aPresContext,
rv = stateful->RestoreState(aPresContext, aState);
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
}

Просмотреть файл

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

Просмотреть файл

@ -35,6 +35,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsReadableUtils.h"
@ -52,7 +53,7 @@
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMNSHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIComboboxControlFrame.h"
#include "nsComboboxControlFrame.h"
#include "nsIViewManager.h"
#include "nsIScrollableView.h"
#include "nsIDOMHTMLOptGroupElement.h"
@ -1355,6 +1356,14 @@ nsListControlFrame::HandleListSelection(nsIDOMEvent* aEvent,
NS_IMETHODIMP
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;
if (IsInDropDownMode()) {
view = GetView();
@ -1922,7 +1931,7 @@ nsListControlFrame::GetSelectedIndex(PRInt32 * aIndex)
PRBool
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
// reset the index.
if (IsInDropDownMode() == PR_TRUE) {
if (IsInDropDownMode()) {
PRInt32 index;
mComboboxFrame->GetIndexOfDisplayArea(&index);
ComboboxFinish(index);
@ -2313,7 +2322,7 @@ nsListControlFrame::DidReflow(nsPresContext* aPresContext,
{
nsresult rv;
if (PR_TRUE == IsInDropDownMode())
if (IsInDropDownMode())
{
//SyncViewWithFrame();
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
// or on the select when in listbox mode, then let the click through
if (!IsLeftButton(aMouseEvent)) {
if (IsInDropDownMode() == PR_TRUE) {
if (IsInDropDownMode()) {
if (!IsClickingInCombobox(aMouseEvent)) {
aMouseEvent->PreventDefault();
@ -2610,7 +2619,6 @@ nsListControlFrame::GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent,
rv = NS_ERROR_FAILURE;
}
return rv;
}
@ -2665,15 +2673,17 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
if (!nsComboboxControlFrame::ToolkitHasNativePopup())
{
PRBool isDroppedDown;
mComboboxFrame->IsDroppedDown(&isDroppedDown);
mComboboxFrame->ShowDropDown(!isDroppedDown);
if (isDroppedDown) {
CaptureMouseEvents(GetPresContext(), PR_FALSE);
}
}
}
}
return NS_OK;
}
@ -2687,7 +2697,7 @@ nsListControlFrame::MouseMove(nsIDOMEvent* aMouseEvent)
NS_ASSERTION(aMouseEvent, "aMouseEvent is null.");
//REFLOW_DEBUG_MSG("MouseMove\n");
if (IsInDropDownMode() == PR_TRUE) {
if (IsInDropDownMode()) {
PRBool isDroppedDown = PR_FALSE;
mComboboxFrame->IsDroppedDown(&isDroppedDown);
if (isDroppedDown) {
@ -2716,7 +2726,7 @@ nsListControlFrame::DragMove(nsIDOMEvent* aMouseEvent)
NS_ASSERTION(aMouseEvent, "aMouseEvent is null.");
//REFLOW_DEBUG_MSG("DragMove\n");
if (IsInDropDownMode() == PR_FALSE) {
if (!IsInDropDownMode()) {
PRInt32 selectedIndex;
if (NS_SUCCEEDED(GetIndexFromDOMEvent(aMouseEvent, selectedIndex))) {
// Don't waste cycles if we already dragged over this item
@ -2942,7 +2952,9 @@ nsListControlFrame::GetIncrementalString()
void
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;
mComboboxFrame->IsDroppedDown(&isDroppedDown);
mComboboxFrame->ShowDropDown(!isDroppedDown);
@ -3202,7 +3214,7 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
// XXX - Are we cover up a problem here???
// Why aren't they getting flushed each time?
// because this isn't needed for Gfx
if (IsInDropDownMode() == PR_TRUE) {
if (IsInDropDownMode()) {
// Don't flush anything but reflows lest it destroy us
GetPresContext()->PresShell()->
GetDocument()->FlushPendingNotifications(Flush_OnlyReflow);