mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 941774 - Base widget implementation. r=roc
This commit is contained in:
parent
d85f619b11
commit
eb0464623a
@ -12,12 +12,15 @@
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsWidgetInitData.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "Units.h"
|
||||
|
||||
// forward declarations
|
||||
@ -97,8 +100,8 @@ typedef void* nsNativeWidget;
|
||||
#endif
|
||||
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0x746cb189, 0x9793, 0x4e53, \
|
||||
{ 0x89, 0x47, 0x78, 0x56, 0xb6, 0xcd, 0x9f, 0x71 } }
|
||||
{ 0x67da44c4, 0xe21b, 0x4742, \
|
||||
{ 0x9c, 0x2b, 0x26, 0xc7, 0x70, 0x21, 0xde, 0x87 } }
|
||||
|
||||
/*
|
||||
* Window shadow styles
|
||||
@ -493,7 +496,9 @@ class nsIWidget : public nsISupports {
|
||||
: mLastChild(nullptr)
|
||||
, mPrevSibling(nullptr)
|
||||
, mOnDestroyCalled(false)
|
||||
{}
|
||||
{
|
||||
ClearNativeTouchSequence();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -1559,6 +1564,85 @@ class nsIWidget : public nsISupports {
|
||||
uint32_t aModifierFlags,
|
||||
uint32_t aAdditionalFlags) = 0;
|
||||
|
||||
/*
|
||||
* TouchPointerState states for SynthesizeNativeTouchPoint. Match
|
||||
* touch states in nsIDOMWindowUtils.idl.
|
||||
*/
|
||||
enum TouchPointerState {
|
||||
// The pointer is in a hover state above the digitizer
|
||||
TOUCH_HOVER = 0x01,
|
||||
// The pointer is in contact with the digitizer
|
||||
TOUCH_CONTACT = 0x02,
|
||||
// The pointer has been removed from the digitizer detection area
|
||||
TOUCH_REMOVE = 0x04,
|
||||
// The pointer has been canceled. Will cancel any pending os level
|
||||
// gestures that would triggered as a result of completion of the
|
||||
// input sequence. This may not cancel moz platform related events
|
||||
// that might get tirggered by input already delivered.
|
||||
TOUCH_CANCEL = 0x08
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a new or update an existing touch pointer on the digitizer.
|
||||
* To trigger os level gestures, individual touch points should
|
||||
* transition through a complete set of touch states which should be
|
||||
* sent as individual messages.
|
||||
*
|
||||
* @param aPointerId The touch point id to create or update.
|
||||
* @param aPointerState one or more of the touch states listed above
|
||||
* @param aScreenX, aScreenY screen coords of this event
|
||||
* @param aPressure 0.0 -> 1.0 float val indicating pressure
|
||||
* @param aOrientation 0 -> 359 degree value indicating the
|
||||
* orientation of the pointer. Use 90 for normal taps.
|
||||
*/
|
||||
virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
||||
TouchPointerState aPointerState,
|
||||
nsIntPoint aPointerScreenPoint,
|
||||
double aPointerPressure,
|
||||
uint32_t aPointerOrientation) = 0;
|
||||
|
||||
/*
|
||||
* Cancels all active simulated touch input points and pending long taps.
|
||||
* Native widgets should track existing points such that they can clear the
|
||||
* digitizer state when this call is made.
|
||||
*/
|
||||
virtual nsresult ClearNativeTouchSequence();
|
||||
|
||||
/*
|
||||
* Helper for simulating a simple tap event with one touch point. When
|
||||
* aLongTap is true, simulates a native long tap with a duration equal to
|
||||
* ui.click_hold_context_menus.delay. This pref is compatible with the
|
||||
* apzc long tap duration. Defaults to 1.5 seconds.
|
||||
*/
|
||||
nsresult SynthesizeNativeTouchTap(nsIntPoint aPointerScreenPoint,
|
||||
bool aLongTap);
|
||||
|
||||
private:
|
||||
class LongTapInfo
|
||||
{
|
||||
public:
|
||||
LongTapInfo(int32_t aPointerId, nsIntPoint& aPoint,
|
||||
mozilla::TimeDuration aDuration) :
|
||||
mPointerId(aPointerId),
|
||||
mPosition(aPoint),
|
||||
mDuration(aDuration),
|
||||
mStamp(mozilla::TimeStamp::Now())
|
||||
{
|
||||
}
|
||||
|
||||
int32_t mPointerId;
|
||||
nsIntPoint mPosition;
|
||||
mozilla::TimeDuration mDuration;
|
||||
mozilla::TimeStamp mStamp;
|
||||
};
|
||||
|
||||
static void OnLongTapTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
nsAutoPtr<LongTapInfo> mLongTapTouchPoint;
|
||||
nsCOMPtr<nsITimer> mLongTapTimer;
|
||||
static int32_t sPointerIdCounter;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Activates a native menu item at the position specified by the index
|
||||
* string. The index string is a string of positive integers separated
|
||||
|
@ -70,6 +70,11 @@ nsIContent* nsBaseWidget::mLastRollup = nullptr;
|
||||
// in NativeWindowTheme.
|
||||
bool gDisableNativeTheme = false;
|
||||
|
||||
// Async pump timer during injected long touch taps
|
||||
#define TOUCH_INJECT_PUMP_TIMER_MSEC 50
|
||||
#define TOUCH_INJECT_LONG_TAP_DEFAULT_MSEC 1500
|
||||
int32_t nsIWidget::sPointerIdCounter = 0;
|
||||
|
||||
// nsBaseWidget
|
||||
NS_IMPL_ISUPPORTS1(nsBaseWidget, nsIWidget)
|
||||
|
||||
@ -1526,7 +1531,103 @@ nsBaseWidget::GetRootAccessible()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif // ACCESSIBILITY
|
||||
|
||||
nsresult
|
||||
nsIWidget::SynthesizeNativeTouchTap(nsIntPoint aPointerScreenPoint, bool aLongTap)
|
||||
{
|
||||
if (sPointerIdCounter > TOUCH_INJECT_MAX_POINTS) {
|
||||
sPointerIdCounter = 0;
|
||||
}
|
||||
int pointerId = sPointerIdCounter;
|
||||
sPointerIdCounter++;
|
||||
nsresult rv = SynthesizeNativeTouchPoint(pointerId, TOUCH_CONTACT,
|
||||
aPointerScreenPoint, 1.0, 90);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!aLongTap) {
|
||||
nsresult rv = SynthesizeNativeTouchPoint(pointerId, TOUCH_REMOVE,
|
||||
aPointerScreenPoint, 0, 0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// initiate a long tap
|
||||
int elapse = Preferences::GetInt("ui.click_hold_context_menus.delay",
|
||||
TOUCH_INJECT_LONG_TAP_DEFAULT_MSEC);
|
||||
if (!mLongTapTimer) {
|
||||
mLongTapTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
SynthesizeNativeTouchPoint(pointerId, TOUCH_CANCEL,
|
||||
aPointerScreenPoint, 0, 0);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
// Windows requires recuring events, so we set this to a smaller window
|
||||
// than the pref value.
|
||||
int timeout = elapse;
|
||||
if (timeout > TOUCH_INJECT_PUMP_TIMER_MSEC) {
|
||||
timeout = TOUCH_INJECT_PUMP_TIMER_MSEC;
|
||||
}
|
||||
mLongTapTimer->InitWithFuncCallback(OnLongTapTimerCallback, this,
|
||||
timeout,
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
|
||||
// If we already have a long tap pending, cancel it. We only allow one long
|
||||
// tap to be active at a time.
|
||||
if (mLongTapTouchPoint) {
|
||||
SynthesizeNativeTouchPoint(mLongTapTouchPoint->mPointerId, TOUCH_CANCEL,
|
||||
mLongTapTouchPoint->mPosition, 0, 0);
|
||||
}
|
||||
|
||||
mLongTapTouchPoint = new LongTapInfo(pointerId, aPointerScreenPoint,
|
||||
TimeDuration::FromMilliseconds(elapse));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsIWidget::OnLongTapTimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
nsIWidget *self = static_cast<nsIWidget *>(aClosure);
|
||||
|
||||
if ((self->mLongTapTouchPoint->mStamp + self->mLongTapTouchPoint->mDuration) >
|
||||
TimeStamp::Now()) {
|
||||
#ifdef XP_WIN
|
||||
// Windows needs us to keep pumping feedback to the digitizer, so update
|
||||
// the pointer id with the same position.
|
||||
self->SynthesizeNativeTouchPoint(self->mLongTapTouchPoint->mPointerId,
|
||||
TOUCH_CONTACT,
|
||||
self->mLongTapTouchPoint->mPosition,
|
||||
1.0, 90);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// finished, remove the touch point
|
||||
self->mLongTapTimer->Cancel();
|
||||
self->mLongTapTimer = nullptr;
|
||||
self->SynthesizeNativeTouchPoint(self->mLongTapTouchPoint->mPointerId,
|
||||
TOUCH_REMOVE,
|
||||
self->mLongTapTouchPoint->mPosition,
|
||||
0, 0);
|
||||
self->mLongTapTouchPoint = nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIWidget::ClearNativeTouchSequence()
|
||||
{
|
||||
if (!mLongTapTimer) {
|
||||
return NS_OK;
|
||||
}
|
||||
mLongTapTimer->Cancel();
|
||||
mLongTapTimer = nullptr;
|
||||
SynthesizeNativeTouchPoint(mLongTapTouchPoint->mPointerId, TOUCH_CANCEL,
|
||||
mLongTapTouchPoint->mPosition, 0, 0);
|
||||
mLongTapTouchPoint = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
@ -41,6 +41,11 @@ namespace base {
|
||||
class Thread;
|
||||
}
|
||||
|
||||
// Windows specific constant indicating the maximum number of touch points the
|
||||
// inject api will allow. This also sets the maximum numerical value for touch
|
||||
// ids we can use when injecting touch points on Windows.
|
||||
#define TOUCH_INJECT_MAX_POINTS 256
|
||||
|
||||
class nsBaseWidget;
|
||||
|
||||
class WidgetShutdownObserver MOZ_FINAL : public nsIObserver
|
||||
@ -320,6 +325,14 @@ protected:
|
||||
uint32_t aAdditionalFlags)
|
||||
{ return NS_ERROR_UNEXPECTED; }
|
||||
|
||||
virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
||||
TouchPointerState aPointerState,
|
||||
nsIntPoint aPointerScreenPoint,
|
||||
double aPointerPressure,
|
||||
uint32_t aPointerOrientation)
|
||||
{ return NS_ERROR_UNEXPECTED; }
|
||||
|
||||
protected:
|
||||
// Stores the clip rectangles in aRects into mClipRects. Returns true
|
||||
// if the new rectangles are different from the old rectangles.
|
||||
bool StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);
|
||||
|
Loading…
Reference in New Issue
Block a user