Bug 451015 <panel> element should not be topmost window r=deakin+gavin, sr=neil

This commit is contained in:
Masayuki Nakano 2008-09-08 21:58:07 +09:00
parent ad83ecaf10
commit f6c06380e8
7 changed files with 75 additions and 15 deletions

View File

@ -99,19 +99,15 @@
<tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
<!-- for search and content formfill/pw manager -->
<panel type="autocomplete" chromedir="&locale.dir;" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
<panel type="autocomplete" chromedir="&locale.dir;" id="PopupAutoComplete" noautofocus="true" hidden="true" level="top"/>
<!-- for url bar autocomplete -->
<panel type="autocomplete-richlistbox" chromedir="&locale.dir;" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
<panel type="autocomplete-richlistbox" chromedir="&locale.dir;" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true" level="top"/>
<!-- XXX panel element that has one or more text fields should not be
top-most panel, for IME users. See bug 433340 comment 100. -->
<panel id="editBookmarkPanel"
orient="vertical"
ignorekeys="true"
hidden="true"
noautohide="true"
onpopupshowing="this.removeAttribute('noautohide');"
onpopupshown="StarUI.panelShown(event);"
aria-labelledby="editBookmarkPanelTitle">
<hbox flex="1" align="top">
@ -197,7 +193,7 @@
<!-- Popup for site identity information -->
<panel id="identity-popup" position="after_start" hidden="true" noautofocus="true"
onpopupshown="document.getElementById('identity-popup-more-info-button').focus();"
onpopuphidden="focusAndSelectUrlBar();" norestorefocus="true"
onpopuphidden="focusAndSelectUrlBar();" norestorefocus="true" level="top"
chromedir="&locale.dir;">
<hbox id="identity-popup-container" align="top">
<image id="identity-popup-icon"/>
@ -234,7 +230,7 @@
<label crop="center" flex="1"/>
</tooltip>
<panel id="ctrlTab-panel" class="KUI-panel" hidden="true" noautofocus="true">
<panel id="ctrlTab-panel" class="KUI-panel" hidden="true" noautofocus="true" level="top">
<label id="ctrlTab-label" flex="1"/>
<svg:svg id="ctrlTab-svgRoot">
<svg:defs>

View File

@ -74,6 +74,7 @@
#include "nsReadableUtils.h"
#include "nsUnicharUtils.h"
#include "nsLayoutUtils.h"
#include "nsContentUtils.h"
#include "nsCSSFrameConstructor.h"
#include "nsIEventStateManager.h"
#include "nsIBoxLayout.h"
@ -88,6 +89,8 @@
const PRInt32 kMaxZ = 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32
PRInt8 nsMenuPopupFrame::sDefaultLevelParent = -1;
// NS_NewMenuPopupFrame
//
// Wrapper for creating a new menu popup container
@ -118,6 +121,10 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex
mInContentShell(PR_TRUE),
mPrefSize(-1, -1)
{
if (sDefaultLevelParent >= 0)
return;
sDefaultLevelParent =
nsContentUtils::GetBoolPref("ui.panel.default_level_parent", PR_FALSE);
} // ctor
@ -189,6 +196,31 @@ nsMenuPopupFrame::IsNoAutoHide()
nsGkAtoms::_true, eIgnoreCase));
}
PRBool
nsMenuPopupFrame::IsTopMost()
{
// If this panel is not a panel, this is always a top-most popup
if (mPopupType != ePopupTypePanel)
return PR_TRUE;
// If this panel is a noautohide panel, it should appear just above the parent
// window.
if (IsNoAutoHide())
return PR_FALSE;
// Otherwise, check the topmost attribute.
if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::level,
nsGkAtoms::top, eIgnoreCase))
return PR_TRUE;
if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::level,
nsGkAtoms::parent, eIgnoreCase))
return PR_FALSE;
// Otherwise, the result depends on the platform.
return sDefaultLevelParent ? PR_TRUE : PR_FALSE;
}
void
nsMenuPopupFrame::EnsureWidget()
{
@ -219,11 +251,11 @@ nsMenuPopupFrame::CreateWidgetForView(nsIView* aView)
tag = parentContent->Tag();
widgetData.mDropShadow = !(viewHasTransparentContent || tag == nsGkAtoms::menulist);
// panels which don't auto-hide need a parent widget. This allows them
// to always appear in front of the parent window but behind other windows
// that should be in front of it.
// panels which are not topmost need a parent widget. This allows them to
// always appear in front of the parent window but behind other windows that
// should be in front of it.
nsCOMPtr<nsIWidget> parentWidget;
if (IsNoAutoHide()) {
if (!IsTopMost()) {
nsCOMPtr<nsISupports> cont = PresContext()->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(cont);
if (!dsti)

View File

@ -180,6 +180,10 @@ public:
// true. These panels do not roll up automatically.
PRBool IsNoAutoHide();
// returns true if the popup is a top-most window. Otherwise, the
// panel appears in front of the parent window.
PRBool IsTopMost();
void EnsureWidget();
virtual nsresult CreateWidgetForView(nsIView* aView);
@ -353,6 +357,7 @@ protected:
// SetPopupPosition.
nsSize mPrefSize;
static PRInt8 sDefaultLevelParent;
}; // class nsMenuPopupFrame
#endif

View File

@ -1515,6 +1515,9 @@ pref("intl.jis0208.map", "CP932");
// Switch the keyboard layout per window
pref("intl.keyboard.per_window_layout", false);
// See bug 448927, on topmost panel, some IMEs are not usable on Windows.
pref("ui.panel.default_level_parent", false);
# WINNT
#endif
@ -1932,6 +1935,9 @@ pref("print.print_extra_margin", 90); // twips (90 twips is an eigth of an inch)
// This indicates whether it should use the native dialog or the XP Dialog
pref("print.use_native_print_dialog", true);
// See bug 404131, topmost <panel> element wins to Dashboard on MacOSX.
pref("ui.panel.default_level_parent", false);
# XP_MACOSX
#endif
@ -2129,6 +2135,11 @@ pref("intl.jis0208.map", "IBM943");
// This is because OS/2 doesn't support IPv6
pref("network.dns.disableIPv6", true);
// IMEs of OS/2 might use non-topmost windows for topmost <panel> element,
// see bug 451015. If there are other problems by this value, we may need to
// change this value.
pref("ui.panel.default_level_parent", false);
# OS2
#endif
@ -2220,6 +2231,11 @@ pref("ui.key.contentAccess", 3);
// xxx toolkit?
pref("browser.download.dir", "/boot/home/Downloads");
// IMEs of BeOS might use non-topmost windows for topmost <panel> element,
// see bug 451015. If there are other problems by this value, we may need to
// change this value.
pref("ui.panel.default_level_parent", false);
# BeOS
#endif
@ -2482,6 +2498,17 @@ pref("print.postscript.paper_size", "letter");
pref("print.postscript.orientation", "portrait");
pref("print.postscript.print_command", "lpr ${MOZ_PRINTER_NAME:+-P\"$MOZ_PRINTER_NAME\"}");
// On GTK2 platform, we should use topmost window level for the default window
// level of <panel> element of XUL. GTK2 has only two window types. One is
// normal top level window, other is popup window. The popup window is always
// topmost window level, therefore, we are using normal top level window for
// non-topmost panel, but it is pretty hacky. On some Window Managers, we have
// 2 problems:
// 1. The non-topmost panel steals focus from its parent window at showing.
// 2. The parent of non-topmost panel is not activated when the panel is hidden.
// So, we have no reasons we should use non-toplevel window for popup.
pref("ui.panel.default_level_parent", true);
# XP_UNIX
#endif
#endif

View File

@ -419,7 +419,7 @@
<xul:hbox class="colorpicker-button-colorbox" anonid="colorbox" flex="1" xbl:inherits="disabled"/>
<xul:panel class="colorpicker-button-menupopup"
anonid="colorpopup" noautofocus="true"
anonid="colorpopup" noautofocus="true" level="top"
onmousedown="event.stopPropagation()"
onpopupshowing="this._colorPicker.onPopupShowing()"
onpopuphiding="this._colorPicker.onPopupHiding()"

View File

@ -1240,7 +1240,7 @@
onup="this.parentNode._increaseOrDecrease(1);"
ondown="this.parentNode._increaseOrDecrease(-1);"/>
<xul:dropmarker class="datepicker-dropmarker" xbl:inherits="disabled"/>
<xul:panel onpopupshown="this.firstChild.focus();">
<xul:panel onpopupshown="this.firstChild.focus();" level="top">
<xul:datepicker anonid="grid" type="grid" class="datepicker-popupgrid"
xbl:inherits="disabled,readonly,firstdayofweek"/>
</xul:panel>

View File

@ -32,7 +32,7 @@
<xul:popupset>
<xul:panel type="autocomplete" anonid="popup"
ignorekeys="true" noautofocus="true"
ignorekeys="true" noautofocus="true" level="top"
xbl:inherits="for=id,nomatch"/>
</xul:popupset>