Bug 1359211 - Handle touch-scrolling of XUL <listbox> in JS. r=bz,dao,kats

The APZ scrolling codepath doesn't do the right thing for <listbox>
without special handling, so have it scroll in JS instead, like we
did in bug 1302736 for <tree>.

MozReview-Commit-ID: LWJCBfhZ3Hc

--HG--
extra : rebase_source : bb8b2f7e713d35822a956e08f4e0eed0557b07b3
This commit is contained in:
Botond Ballo 2017-04-24 17:12:21 -04:00
parent b553da7bbd
commit 66ed3e9795
6 changed files with 57 additions and 0 deletions

View File

@ -9,6 +9,7 @@
interface ListBoxObject : BoxObject {
long getRowCount();
long getRowHeight();
long getNumberOfVisibleRows();
long getIndexOfFirstVisibleRow();

View File

@ -75,6 +75,16 @@ ListBoxObject::GetRowCount()
return 0;
}
int32_t
ListBoxObject::GetRowHeight()
{
nsListBoxBodyFrame* body = GetListBoxBody(true);
if (body) {
return body->GetRowHeightPixels();
}
return 0;
}
int32_t
ListBoxObject::GetNumberOfVisibleRows()
{

View File

@ -33,6 +33,7 @@ public:
// ListBoxObject.webidl
int32_t GetRowCount();
int32_t GetRowHeight();
int32_t GetNumberOfVisibleRows();
int32_t GetIndexOfFirstVisibleRow();
void EnsureIndexIsVisible(int32_t rowIndex);

View File

@ -646,6 +646,12 @@ nsListBoxBodyFrame::GetRowCount()
return mRowCount;
}
int32_t
nsListBoxBodyFrame::GetRowHeightPixels() const
{
return nsPresContext::AppUnitsToIntCSSPixels(mRowHeight);
}
int32_t
nsListBoxBodyFrame::GetFixedRowSize()
{

View File

@ -93,6 +93,7 @@ public:
// size calculation
int32_t GetRowCount();
int32_t GetRowHeightAppUnits() { return mRowHeight; }
int32_t GetRowHeightPixels() const;
int32_t GetFixedRowSize();
void SetRowHeight(nscoord aRowHeight);
nscoord GetYPosition();

View File

@ -687,6 +687,8 @@
<!-- ///////////////// private listbox members ///////////////// -->
<field name="_touchY">-1</field>
<method name="_fireOnSelect">
<body>
<![CDATA[
@ -870,6 +872,42 @@
}
]]>
</handler>
<handler event="touchstart">
<![CDATA[
if (event.touches.length > 1) {
// Multiple touch points detected, abort. In particular this aborts
// the panning gesture when the user puts a second finger down after
// already panning with one finger. Aborting at this point prevents
// the pan gesture from being resumed until all fingers are lifted
// (as opposed to when the user is back down to one finger).
this._touchY = -1;
} else {
this._touchY = event.touches[0].screenY;
}
]]>
</handler>
<handler event="touchmove">
<![CDATA[
if (event.touches.length == 1 &&
this._touchY >= 0) {
let deltaY = this._touchY - event.touches[0].screenY;
let lines = Math.trunc(deltaY / this.listBoxObject.getRowHeight());
if (Math.abs(lines) > 0) {
this.listBoxObject.scrollByLines(lines);
deltaY -= lines * this.listBoxObject.getRowHeight();
this._touchY = event.touches[0].screenY + deltaY;
}
event.preventDefault();
}
]]>
</handler>
<handler event="touchend">
<![CDATA[
this._touchY = -1;
]]>
</handler>
</handlers>
</binding>