mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 76053 Windows mouse integration: no "Snap to default button in dialog boxes" r=enn+ere, sr=roc
This commit is contained in:
parent
73d238f7a1
commit
4c03c99935
@ -167,6 +167,8 @@
|
||||
#include "nsFocusManager.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "nsIDOMXULControlElement.h"
|
||||
#include "nsIFrame.h"
|
||||
#endif
|
||||
|
||||
#include "plbase64.h"
|
||||
@ -3775,6 +3777,19 @@ nsGlobalWindow::GetMainWidget()
|
||||
return widget;
|
||||
}
|
||||
|
||||
nsIWidget*
|
||||
nsGlobalWindow::GetNearestWidget()
|
||||
{
|
||||
nsIDocShell* docShell = GetDocShell();
|
||||
NS_ENSURE_TRUE(docShell, nsnull);
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
docShell->GetPresShell(getter_AddRefs(presShell));
|
||||
NS_ENSURE_TRUE(presShell, nsnull);
|
||||
nsIFrame* rootFrame = presShell->GetRootFrame();
|
||||
NS_ENSURE_TRUE(rootFrame, nsnull);
|
||||
return rootFrame->GetView()->GetNearestWidget(nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::SetFullScreen(PRBool aFullScreen)
|
||||
{
|
||||
@ -8918,6 +8933,51 @@ nsGlobalChromeWindow::SetBrowserDOMWindow(nsIBrowserDOMWindow *aBrowserWindow)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalChromeWindow::NotifyDefaultButtonLoaded(nsIDOMElement* aDefaultButton)
|
||||
{
|
||||
#ifdef MOZ_XUL
|
||||
NS_ENSURE_ARG(aDefaultButton);
|
||||
|
||||
// Don't snap to a disabled button.
|
||||
nsCOMPtr<nsIDOMXULControlElement> xulControl =
|
||||
do_QueryInterface(aDefaultButton);
|
||||
NS_ENSURE_TRUE(xulControl, NS_ERROR_FAILURE);
|
||||
PRBool disabled;
|
||||
nsresult rv = xulControl->GetDisabled(&disabled);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (disabled)
|
||||
return NS_OK;
|
||||
|
||||
// Get the button rect in screen coordinates.
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aDefaultButton));
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
|
||||
nsIDocument *doc = content->GetCurrentDoc();
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||
nsIPresShell *shell = doc->GetPrimaryShell();
|
||||
NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
|
||||
nsIFrame *frame = shell->GetPrimaryFrameFor(content);
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
nsIntRect buttonRect = frame->GetScreenRect();
|
||||
|
||||
// Get the widget rect in screen coordinates.
|
||||
nsIWidget *widget = GetNearestWidget();
|
||||
NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
|
||||
nsIntRect widgetRect;
|
||||
rv = widget->GetScreenBounds(widgetRect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Convert the buttonRect coordinates from screen to the widget.
|
||||
buttonRect -= widgetRect.TopLeft();
|
||||
rv = widget->OnDefaultButtonLoaded(buttonRect);
|
||||
if (rv == NS_ERROR_NOT_IMPLEMENTED)
|
||||
return NS_OK;
|
||||
return rv;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
// nsGlobalModalWindow implementation
|
||||
|
||||
// QueryInterface implementation for nsGlobalModalWindow
|
||||
|
@ -608,6 +608,7 @@ protected:
|
||||
PRBool WindowExists(const nsAString& aName, PRBool aLookForCallerOnJSStack);
|
||||
|
||||
already_AddRefed<nsIWidget> GetMainWidget();
|
||||
nsIWidget* GetNearestWidget();
|
||||
|
||||
void Freeze()
|
||||
{
|
||||
|
@ -39,8 +39,9 @@
|
||||
#include "domstubs.idl"
|
||||
|
||||
interface nsIBrowserDOMWindow;
|
||||
interface nsIDOMElement;
|
||||
|
||||
[scriptable, uuid(09A5E148-2A77-4739-9DD9-3D552F5390EE)]
|
||||
[scriptable, uuid(09b86cbd-9784-4fe4-9be6-70b9bbca3a9c)]
|
||||
interface nsIDOMChromeWindow : nsISupports
|
||||
{
|
||||
const unsigned short STATE_MAXIMIZED = 1;
|
||||
@ -66,4 +67,10 @@ interface nsIDOMChromeWindow : nsISupports
|
||||
void maximize();
|
||||
void minimize();
|
||||
void restore();
|
||||
|
||||
/**
|
||||
* Notify a default button is loaded on a dialog or a wizard.
|
||||
* defaultButton is the default button.
|
||||
*/
|
||||
void notifyDefaultButtonLoaded(in nsIDOMElement defaultButton);
|
||||
};
|
||||
|
@ -97,5 +97,11 @@ else
|
||||
_TEST_FILES += test_autocomplete.xul
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
_TEST_FILES += test_cursorsnap.xul \
|
||||
window_cursorsnap_dialog.xul \
|
||||
window_cursorsnap_wizard.xul
|
||||
endif
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
|
||||
|
130
toolkit/content/tests/chrome/test_cursorsnap.xul
Normal file
130
toolkit/content/tests/chrome/test_cursorsnap.xul
Normal file
@ -0,0 +1,130 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<window title="Cursor snapping test"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const kMaxRetryCount = 4;
|
||||
const kTimeoutTime = [
|
||||
100, 100, 1000, 1000, 5000
|
||||
];
|
||||
|
||||
var gRetryCount;
|
||||
|
||||
var gTestingCount = 0;
|
||||
var gTestingIndex = -1;
|
||||
var gDisable = false;
|
||||
var gHidden = false;
|
||||
|
||||
function canRetryTest()
|
||||
{
|
||||
return gRetryCount <= kMaxRetryCount;
|
||||
}
|
||||
|
||||
function getTimeoutTime()
|
||||
{
|
||||
return kTimeoutTime[gRetryCount];
|
||||
}
|
||||
|
||||
function runNextTest()
|
||||
{
|
||||
gRetryCount = 0;
|
||||
gTestingIndex++;
|
||||
runCurrentTest();
|
||||
}
|
||||
|
||||
function retryCurrentTest()
|
||||
{
|
||||
ok(canRetryTest(), "retry the current test...");
|
||||
gRetryCount++;
|
||||
runCurrentTest();
|
||||
}
|
||||
|
||||
function runCurrentTest()
|
||||
{
|
||||
var position = "top=" + gTestingCount + ",left=" + gTestingCount + ",";
|
||||
gTestingCount++;
|
||||
switch (gTestingIndex) {
|
||||
case 0:
|
||||
gDisable = false;
|
||||
gHidden = false;
|
||||
window.open("window_cursorsnap_dialog.xul", "_blank",
|
||||
position + "chrome,width=100,height=100");
|
||||
break;
|
||||
case 1:
|
||||
gDisable = true;
|
||||
gHidden = false;
|
||||
window.open("window_cursorsnap_dialog.xul", "_blank",
|
||||
position + "chrome,width=100,height=100");
|
||||
break;
|
||||
case 2:
|
||||
gDisable = false;
|
||||
gHidden = true;
|
||||
window.open("window_cursorsnap_dialog.xul", "_blank",
|
||||
position + "chrome,width=100,height=100");
|
||||
break;
|
||||
case 3:
|
||||
gDisable = false;
|
||||
gHidden = false;
|
||||
window.open("window_cursorsnap_wizard.xul", "_blank",
|
||||
position + "chrome,width=100,height=100");
|
||||
break;
|
||||
case 4:
|
||||
gDisable = true;
|
||||
gHidden = false;
|
||||
window.open("window_cursorsnap_wizard.xul", "_blank",
|
||||
position + "chrome,width=100,height=100");
|
||||
break;
|
||||
case 5:
|
||||
gDisable = false;
|
||||
gHidden = true;
|
||||
window.open("window_cursorsnap_wizard.xul", "_blank",
|
||||
position + "chrome,width=100,height=100");
|
||||
break;
|
||||
default:
|
||||
SetPrefs(false);
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function SetPrefs(aSet)
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch2);
|
||||
const kPrefName = "ui.cursor_snapping.always_enabled";
|
||||
if (aSet) {
|
||||
prefSvc.setBoolPref(kPrefName, true);
|
||||
} else {
|
||||
prefSvc.clearUserPref(kPrefName);
|
||||
}
|
||||
}
|
||||
|
||||
SetPrefs(true);
|
||||
runNextTest();
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
104
toolkit/content/tests/chrome/window_cursorsnap_dialog.xul
Normal file
104
toolkit/content/tests/chrome/window_cursorsnap_dialog.xul
Normal file
@ -0,0 +1,104 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<dialog title="Cursor snapping test" id="dialog"
|
||||
width="600" height="600"
|
||||
onload="onload();"
|
||||
onunload="onunload();"
|
||||
buttons="accept,cancel"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
function ok(aCondition, aMessage)
|
||||
{
|
||||
window.opener.wrappedJSObject.SimpleTest.ok(aCondition, aMessage);
|
||||
}
|
||||
|
||||
function is(aLeft, aRight, aMessage)
|
||||
{
|
||||
window.opener.wrappedJSObject.SimpleTest.is(aLeft, aRight, aMessage);
|
||||
}
|
||||
|
||||
function isnot(aLeft, aRight, aMessage)
|
||||
{
|
||||
window.opener.wrappedJSObject.SimpleTest.isnot(aLeft, aRight, aMessage);
|
||||
}
|
||||
|
||||
function canRetryTest()
|
||||
{
|
||||
return window.opener.wrappedJSObject.canRetryTest();
|
||||
}
|
||||
|
||||
function getTimeoutTime()
|
||||
{
|
||||
return window.opener.wrappedJSObject.getTimeoutTime();
|
||||
}
|
||||
|
||||
var gTimer;
|
||||
var gRetry;
|
||||
|
||||
function finishByTimeout()
|
||||
{
|
||||
var button = document.getElementById("dialog").getButton("accept");
|
||||
if (button.disabled)
|
||||
ok(true, "cursor is NOT snapped to the disabled button (dialog)");
|
||||
else if (button.hidden)
|
||||
ok(true, "cursor is NOT snapped to the hidden button (dialog)");
|
||||
else {
|
||||
if (!canRetryTest()) {
|
||||
ok(false, "cursor is NOT snapped to the default button (dialog)");
|
||||
} else {
|
||||
// otherwise, this may be unexpected timeout, we should retry the test.
|
||||
gRetry = true;
|
||||
}
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
function finish()
|
||||
{
|
||||
window.close();
|
||||
}
|
||||
|
||||
function onMouseMove(aEvent)
|
||||
{
|
||||
var button = document.getElementById("dialog").getButton("accept");
|
||||
if (button.disabled)
|
||||
ok(false, "cursor IS snapped to the disabled button (dialog)");
|
||||
else if (button.hidden)
|
||||
ok(false, "cursor IS snapped to the hidden button (dialog)");
|
||||
else
|
||||
ok(true, "cursor IS snapped to the default button (dialog)");
|
||||
clearTimeout(gTimer);
|
||||
finish();
|
||||
}
|
||||
|
||||
function onload()
|
||||
{
|
||||
var button = document.getElementById("dialog").getButton("accept");
|
||||
button.addEventListener("mousemove", onMouseMove, false);
|
||||
|
||||
if (window.opener.wrappedJSObject.gDisable) {
|
||||
button.disabled = true;
|
||||
}
|
||||
if (window.opener.wrappedJSObject.gHidden) {
|
||||
button.hidden = true;
|
||||
}
|
||||
gRetry = false;
|
||||
gTimer = setTimeout(finishByTimeout, getTimeoutTime());
|
||||
}
|
||||
|
||||
function onunload()
|
||||
{
|
||||
if (gRetry) {
|
||||
window.opener.wrappedJSObject.retryCurrentTest();
|
||||
} else {
|
||||
window.opener.wrappedJSObject.runNextTest();
|
||||
}
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</dialog>
|
111
toolkit/content/tests/chrome/window_cursorsnap_wizard.xul
Normal file
111
toolkit/content/tests/chrome/window_cursorsnap_wizard.xul
Normal file
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<wizard title="Cursor snapping test" id="wizard"
|
||||
width="600" height="600"
|
||||
onload="onload();"
|
||||
onunload="onunload();"
|
||||
buttons="accept,cancel"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<wizardpage>
|
||||
<label value="first page"/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage>
|
||||
<label value="second page"/>
|
||||
</wizardpage>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
function ok(aCondition, aMessage)
|
||||
{
|
||||
window.opener.wrappedJSObject.SimpleTest.ok(aCondition, aMessage);
|
||||
}
|
||||
|
||||
function is(aLeft, aRight, aMessage)
|
||||
{
|
||||
window.opener.wrappedJSObject.SimpleTest.is(aLeft, aRight, aMessage);
|
||||
}
|
||||
|
||||
function isnot(aLeft, aRight, aMessage)
|
||||
{
|
||||
window.opener.wrappedJSObject.SimpleTest.isnot(aLeft, aRight, aMessage);
|
||||
}
|
||||
|
||||
function canRetryTest()
|
||||
{
|
||||
return window.opener.wrappedJSObject.canRetryTest();
|
||||
}
|
||||
|
||||
function getTimeoutTime()
|
||||
{
|
||||
return window.opener.wrappedJSObject.getTimeoutTime();
|
||||
}
|
||||
|
||||
var gTimer;
|
||||
var gRetry = false;
|
||||
|
||||
function finishByTimeout()
|
||||
{
|
||||
var button = document.getElementById("wizard").getButton("next");
|
||||
if (button.disabled)
|
||||
ok(true, "cursor is NOT snapped to the disabled button (wizard)");
|
||||
else if (button.hidden)
|
||||
ok(true, "cursor is NOT snapped to the hidden button (wizard)");
|
||||
else {
|
||||
if (!canRetryTest()) {
|
||||
ok(false, "cursor is NOT snapped to the default button (wizard)");
|
||||
} else {
|
||||
// otherwise, this may be unexpected timeout, we should retry the test.
|
||||
gRetry = true;
|
||||
}
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
function finish()
|
||||
{
|
||||
window.close();
|
||||
}
|
||||
|
||||
function onMouseMove()
|
||||
{
|
||||
var button = document.getElementById("wizard").getButton("next");
|
||||
if (button.disabled)
|
||||
ok(false, "cursor IS snapped to the disabled button (wizard)");
|
||||
else if (button.hidden)
|
||||
ok(false, "cursor IS snapped to the hidden button (wizard)");
|
||||
else
|
||||
ok(true, "cursor IS snapped to the default button (wizard)");
|
||||
clearTimeout(gTimer);
|
||||
finish();
|
||||
}
|
||||
|
||||
function onload()
|
||||
{
|
||||
var button = document.getElementById("wizard").getButton("next");
|
||||
button.addEventListener("mousemove", onMouseMove, false);
|
||||
|
||||
if (window.opener.wrappedJSObject.gDisable) {
|
||||
button.disabled = true;
|
||||
}
|
||||
if (window.opener.wrappedJSObject.gHidden) {
|
||||
button.hidden = true;
|
||||
}
|
||||
gTimer = setTimeout(finishByTimeout, getTimeoutTime());
|
||||
}
|
||||
|
||||
function onunload()
|
||||
{
|
||||
if (gRetry) {
|
||||
window.opener.wrappedJSObject.retryCurrentTest();
|
||||
} else {
|
||||
window.opener.wrappedJSObject.runNextTest();
|
||||
}
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</wizard>
|
@ -158,9 +158,11 @@
|
||||
<body>
|
||||
<![CDATA[
|
||||
function focusInit() {
|
||||
const dialog = document.documentElement;
|
||||
const defaultButton = dialog.getButton(dialog.defaultButton);
|
||||
// give focus to the first focusable element in the dialog
|
||||
if (!document.commandDispatcher.focusedElement) {
|
||||
document.commandDispatcher.advanceFocusIntoSubtree(document.documentElement);
|
||||
document.commandDispatcher.advanceFocusIntoSubtree(dialog);
|
||||
var focusedElt = document.commandDispatcher.focusedElement;
|
||||
if (focusedElt) {
|
||||
if (focusedElt.localName == 'tab') {
|
||||
@ -174,14 +176,17 @@
|
||||
}
|
||||
#ifndef XP_MACOSX
|
||||
else {
|
||||
const dialog = document.documentElement;
|
||||
const defaultButton = dialog.getButton(dialog.defaultButton);
|
||||
if (focusedElt.hasAttribute("dlgtype") && focusedElt != defaultButton)
|
||||
defaultButton.focus();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (defaultButton)
|
||||
window.notifyDefaultButtonLoaded(defaultButton);
|
||||
} catch (e) { }
|
||||
}
|
||||
|
||||
// Give focus after onload completes, see bug 103197.
|
||||
|
@ -324,6 +324,13 @@
|
||||
// give focus to the first focusable element in the dialog
|
||||
if (!document.commandDispatcher.focusedElement)
|
||||
document.commandDispatcher.advanceFocusIntoSubtree(document.documentElement);
|
||||
|
||||
try {
|
||||
var button =
|
||||
document.documentElement._wizardButtons.defaultButton;
|
||||
if (button)
|
||||
window.notifyDefaultButtonLoaded(button);
|
||||
} catch (e) { }
|
||||
};
|
||||
|
||||
// Give focus after onload completes, see bug 103197.
|
||||
@ -581,6 +588,21 @@
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<property name="defaultButton" readonly="true">
|
||||
<getter><![CDATA[
|
||||
const kXULNS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var buttons = this._wizardButtonDeck.selectedPanel
|
||||
.getElementsByTagNameNS(kXULNS, "button");
|
||||
for (var i = 0; i < buttons.length; i++) {
|
||||
if (buttons[i].getAttribute("default") == "true" &&
|
||||
!buttons[i].hidden && !buttons[i].disabled)
|
||||
return buttons[i];
|
||||
}
|
||||
return null;
|
||||
]]></getter>
|
||||
</property>
|
||||
</implementation>
|
||||
</binding>
|
||||
#endif
|
||||
|
@ -100,10 +100,10 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event);
|
||||
#define NS_NATIVE_TSF_DISPLAY_ATTR_MGR 102
|
||||
#endif
|
||||
|
||||
// 3d277f04-93f4-4384-9fdc-e1e2d1fc4e33
|
||||
// {a395289d-b344-42c3-ae7e-34d64282b6e0}
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0x3d277f04, 0x93f4, 0x4384, \
|
||||
{ 0x9f, 0xdc, 0xe1, 0xe2, 0xd1, 0xfc, 0x4e, 0x33 } }
|
||||
{ 0xa395289d, 0xb344, 0x42c3, \
|
||||
{ 0xae, 0x7e, 0x34, 0xd6, 0x42, 0x82, 0xb6, 0xe0 } }
|
||||
|
||||
/*
|
||||
* Window shadow styles
|
||||
@ -1064,6 +1064,12 @@ class nsIWidget : public nsISupports {
|
||||
*/
|
||||
NS_IMETHOD OnIMESelectionChange(void) = 0;
|
||||
|
||||
/*
|
||||
* Call this method when a dialog is opened which has a default button.
|
||||
* The button's rectangle should be supplied in aButtonRect.
|
||||
*/
|
||||
NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect) = 0;
|
||||
|
||||
protected:
|
||||
// keep the list of children. We also keep track of our siblings.
|
||||
// The ownership model is as follows: parent holds a strong ref to
|
||||
|
@ -2762,6 +2762,69 @@ gfxASurface *nsWindow::GetThebesSurface()
|
||||
return (new gfxWindowsSurface(mWnd));
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* SECTION: nsIWidget::OnDefaultButtonLoaded
|
||||
*
|
||||
* Called after the dialog is loaded and it has a default button.
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::OnDefaultButtonLoaded(const nsIntRect &aButtonRect)
|
||||
{
|
||||
#ifdef WINCE
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#else
|
||||
if (aButtonRect.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
// Don't snap when we are not active.
|
||||
HWND activeWnd = ::GetActiveWindow();
|
||||
if (activeWnd != ::GetForegroundWindow() ||
|
||||
GetTopLevelHWND(mWnd, PR_TRUE) != GetTopLevelHWND(activeWnd, PR_TRUE)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool isAlwaysSnapCursor = PR_FALSE;
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefs) {
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
prefs->GetBranch(nsnull, getter_AddRefs(prefBranch));
|
||||
if (prefBranch) {
|
||||
prefBranch->GetBoolPref("ui.cursor_snapping.always_enabled",
|
||||
&isAlwaysSnapCursor);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAlwaysSnapCursor) {
|
||||
BOOL snapDefaultButton;
|
||||
if (!::SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0,
|
||||
&snapDefaultButton, 0) || !snapDefaultButton)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIntRect widgetRect;
|
||||
nsresult rv = GetScreenBounds(widgetRect);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsIntRect buttonRect(aButtonRect + widgetRect.TopLeft());
|
||||
|
||||
nsIntPoint centerOfButton(buttonRect.x + buttonRect.width / 2,
|
||||
buttonRect.y + buttonRect.height / 2);
|
||||
// The center of the button can be outside of the widget.
|
||||
// E.g., it could be hidden by scrolling.
|
||||
if (!widgetRect.Contains(centerOfButton)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!::SetCursorPos(centerOfButton.x, centerOfButton.y)) {
|
||||
NS_ERROR("SetCursorPos failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
**************************************************************
|
||||
**
|
||||
|
@ -161,6 +161,7 @@ public:
|
||||
NS_IMETHOD GetAttention(PRInt32 aCycleCount);
|
||||
virtual PRBool HasPendingInputEvent();
|
||||
gfxASurface *GetThebesSurface();
|
||||
NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect);
|
||||
virtual nsresult SynthesizeNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
|
||||
PRInt32 aNativeKeyCode,
|
||||
PRUint32 aModifierFlags,
|
||||
|
@ -141,6 +141,7 @@ public:
|
||||
NS_IMETHOD OnIMEFocusChange(PRBool aFocus) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD OnIMETextChange(PRUint32 aStart, PRUint32 aOldEnd, PRUint32 aNewEnd) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD OnIMESelectionChange(void) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
protected:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user