Bug 832101 - Don't fluff out click targets for events from non-touch input [r=roc]

This commit is contained in:
Matt Brubeck 2013-01-24 06:53:18 -08:00
Родитель 675e0cc17d
Коммит cb3d44e94e
5 изменённых файлов: 46 добавлений и 11 удалений

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

@ -63,6 +63,7 @@ struct EventRadiusPrefs
uint32_t mSideRadii[4]; // TRBL order, in millimetres
bool mEnabled;
bool mRegistered;
bool mTouchOnly;
};
static EventRadiusPrefs sMouseEventRadiusPrefs;
@ -99,6 +100,13 @@ GetPrefsFor(nsEventStructType aEventStructType)
nsPrintfCString radiusPref("ui.%s.radius.%s", prefBranch, prefNames[i]);
Preferences::AddUintVarCache(&prefs->mSideRadii[i], radiusPref.get(), 0);
}
if (aEventStructType == NS_MOUSE_EVENT) {
Preferences::AddBoolVarCache(&prefs->mTouchOnly,
"ui.mouse.radius.inputSource.touchOnly", true);
} else {
prefs->mTouchOnly = false;
}
}
return prefs;
@ -236,7 +244,7 @@ GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
}
nsIFrame*
FindFrameTargetedByInputEvent(nsEventStructType aEventStructType,
FindFrameTargetedByInputEvent(const nsGUIEvent *aEvent,
nsIFrame* aRootFrame,
const nsPoint& aPointRelativeToRootFrame,
uint32_t aFlags)
@ -245,11 +253,21 @@ FindFrameTargetedByInputEvent(nsEventStructType aEventStructType,
nsIFrame* target =
nsLayoutUtils::GetFrameForPoint(aRootFrame, aPointRelativeToRootFrame,
false, ignoreRootScrollFrame);
const EventRadiusPrefs* prefs = GetPrefsFor(aEventStructType);
const EventRadiusPrefs* prefs = GetPrefsFor(aEvent->eventStructType);
if (!prefs || !prefs->mEnabled || (target && IsElementClickable(target))) {
return target;
}
// Do not modify targeting for actual mouse hardware; only for mouse
// events generated by touch-screen hardware.
if (aEvent->eventStructType == NS_MOUSE_EVENT &&
prefs->mTouchOnly &&
static_cast<const nsMouseEvent*>(aEvent)->inputSource !=
nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) {
return target;
}
nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame, prefs);
nsAutoTArray<nsIFrame*,8> candidates;
nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame, targetRect, candidates,

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

@ -21,7 +21,7 @@ enum {
* that are suitable targets, to account for inaccurate pointing devices.
*/
nsIFrame*
FindFrameTargetedByInputEvent(nsEventStructType aEventStructType,
FindFrameTargetedByInputEvent(const nsGUIEvent *aEvent,
nsIFrame* aRootFrame,
const nsPoint& aPointRelativeToRootFrame,
uint32_t aFlags = 0);

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

@ -5960,11 +5960,10 @@ PresShell::HandleEvent(nsIFrame *aFrame,
eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
touch->mRefPoint,
frame);
nsIFrame* target =
FindFrameTargetedByInputEvent(aEvent->eventStructType,
frame,
eventPoint,
flags);
nsIFrame* target = FindFrameTargetedByInputEvent(aEvent,
frame,
eventPoint,
flags);
if (target && !anyTarget) {
target->GetContentForEvent(aEvent, getter_AddRefs(anyTarget));
while (anyTarget && !anyTarget->IsElement()) {
@ -6032,7 +6031,7 @@ PresShell::HandleEvent(nsIFrame *aFrame,
flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
}
nsIFrame* target =
FindFrameTargetedByInputEvent(aEvent->eventStructType, frame, eventPoint, flags);
FindFrameTargetedByInputEvent(aEvent, frame, eventPoint, flags);
if (target) {
frame = target;
}

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

@ -44,6 +44,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=780847
<script type="application/javascript">
var prefBase = "ui.mouse.radius.";
SpecialPowers.setBoolPref(prefBase + "enabled", true);
SpecialPowers.setBoolPref(prefBase + "inputSource.touchOnly", false);
SpecialPowers.setIntPref(prefBase + "leftmm", 12);
SpecialPowers.setIntPref(prefBase + "topmm", 8);
SpecialPowers.setIntPref(prefBase + "rightmm", 4);
@ -57,6 +58,7 @@ ok(4*mm >= 10, "WARNING: mm " + mm + " too small in this configuration. Test res
function endTest() {
SpecialPowers.clearUserPref(prefBase + "enabled");
SpecialPowers.clearUserPref(prefBase + "inputSource.touchOnly");
SpecialPowers.clearUserPref(prefBase + "leftmmm");
SpecialPowers.clearUserPref(prefBase + "topmm");
SpecialPowers.clearUserPref(prefBase + "rightmm");
@ -68,9 +70,9 @@ function endTest() {
var eventTarget;
window.onmousedown = function(event) { eventTarget = event.target; };
function testMouseClick(idPosition, dx, dy, idTarget, msg) {
function testMouseClick(idPosition, dx, dy, idTarget, msg, options) {
eventTarget = null;
synthesizeMouse(document.getElementById(idPosition), dx, dy, {});
synthesizeMouse(document.getElementById(idPosition), dx, dy, options || {});
try {
is(eventTarget.id, idTarget,
"checking '" + idPosition + "' offset " + dx + "," + dy + " [" + msg + "]");
@ -96,6 +98,18 @@ function runTest() {
testMouseClick("t", -3*mm, 10, "t", "basic functionality");
testMouseClick("t", 10, -5*mm, "body", "basic functionality");
testMouseClick("t", 10, -3*mm, "t", "basic functionality");
// When inputSource.touchOnly is true, mouse input is not retargeted.
SpecialPowers.setBoolPref(prefBase + "inputSource.touchOnly", true);
testMouseClick("t", 100 + 11*mm, 10, "body", "disabled for mouse input");
testMouseClick("t", 100 + 11*mm, 10, "t", "enabled for touch input", {
inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH
});
testMouseClick("t", 100 + 13*mm, 10, "body", "basic functionality for touch", {
inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH
});
SpecialPowers.setBoolPref(prefBase + "inputSource.touchOnly", false);
setShowing("t", false);
// Now test the criteria we use to determine which elements are hittable

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

@ -1964,6 +1964,10 @@ pref("ui.mouse.radius.rightmm", 8);
pref("ui.mouse.radius.bottommm", 4);
pref("ui.mouse.radius.visitedWeight", 120);
// When true, the ui.mouse.radius.* prefs will only affect simulated mouse events generated by touch input.
// When false, the prefs will be used for all mouse events.
pref("ui.mouse.radius.inputSource.touchOnly", true);
#ifdef XP_WIN
pref("font.name.serif.ar", "Times New Roman");