зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1003943 - Properly update widget cursors when the mouse passes between remote frames. r=smaug
This commit is contained in:
Родитель
2ee59969dc
Коммит
e88a91f7f4
|
@ -558,6 +558,17 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
case NS_MOUSE_EXIT:
|
||||
// If this is a remote frame, we receive NS_MOUSE_EXIT from the parent
|
||||
// the mouse exits our content. Since the parent may update the cursor
|
||||
// while the mouse is outside our frame, and since PuppetWidget caches the
|
||||
// current cursor internally, re-entering our content (say from over a
|
||||
// window edge) wont update the cursor if the cached value and the current
|
||||
// cursor match. So when the mouse exits a remote frame, clear the cached
|
||||
// widget cursor so a proper update will occur when the mouse re-enters.
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
ClearCachedWidgetCursor(mCurrentTarget);
|
||||
}
|
||||
|
||||
// If the event is not a top-level window exit, then it's not
|
||||
// really an exit --- we may have traversed widget boundaries but
|
||||
// we're still in our toplevel window.
|
||||
|
@ -3329,6 +3340,19 @@ EventStateManager::UpdateCursor(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
EventStateManager::ClearCachedWidgetCursor(nsIFrame* aTargetFrame)
|
||||
{
|
||||
if (!aTargetFrame) {
|
||||
return;
|
||||
}
|
||||
nsIWidget* aWidget = aTargetFrame->GetNearestWidget();
|
||||
if (!aWidget) {
|
||||
return;
|
||||
}
|
||||
aWidget->ClearCachedCursor();
|
||||
}
|
||||
|
||||
nsresult
|
||||
EventStateManager::SetCursor(int32_t aCursor, imgIContainer* aContainer,
|
||||
bool aHaveHotspot,
|
||||
|
|
|
@ -271,6 +271,15 @@ protected:
|
|||
*/
|
||||
static int32_t GetAccessModifierMaskFor(nsISupports* aDocShell);
|
||||
|
||||
/*
|
||||
* If aTargetFrame's widget has a cached cursor value, resets the cursor
|
||||
* such that the next call to SetCursor on the widget will force an update
|
||||
* of the native cursor. For use in getting puppet widget to update its
|
||||
* cursor between mouse exit / enter transitions. This call basically wraps
|
||||
* nsIWidget ClearCachedCursor.
|
||||
*/
|
||||
void ClearCachedWidgetCursor(nsIFrame* aTargetFrame);
|
||||
|
||||
void UpdateCursor(nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
|
|
|
@ -226,7 +226,16 @@ parent:
|
|||
*/
|
||||
sync GetWidgetNativeData() returns (WindowsHandle value);
|
||||
|
||||
SetCursor(uint32_t value);
|
||||
/**
|
||||
* Set the native cursor.
|
||||
* @param value
|
||||
* The widget cursor to set.
|
||||
* @param force
|
||||
* Invalidate any locally cached cursor settings and force an
|
||||
* update.
|
||||
*/
|
||||
SetCursor(uint32_t value, bool force);
|
||||
|
||||
SetBackgroundColor(nscolor color);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1017,10 +1017,13 @@ TabParent::RecvAsyncMessage(const nsString& aMessage,
|
|||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSetCursor(const uint32_t& aCursor)
|
||||
TabParent::RecvSetCursor(const uint32_t& aCursor, const bool& aForce)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
if (aForce) {
|
||||
widget->ClearCachedCursor();
|
||||
}
|
||||
widget->SetCursor((nsCursor) aCursor);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -168,7 +168,7 @@ public:
|
|||
const int32_t& aCause,
|
||||
const int32_t& aFocusChange) MOZ_OVERRIDE;
|
||||
virtual bool RecvRequestFocus(const bool& aCanRaise) MOZ_OVERRIDE;
|
||||
virtual bool RecvSetCursor(const uint32_t& aValue) MOZ_OVERRIDE;
|
||||
virtual bool RecvSetCursor(const uint32_t& aValue, const bool& aForce) MOZ_OVERRIDE;
|
||||
virtual bool RecvSetBackgroundColor(const nscolor& aValue) MOZ_OVERRIDE;
|
||||
virtual bool RecvSetStatus(const uint32_t& aType, const nsString& aStatus) MOZ_OVERRIDE;
|
||||
virtual bool RecvIsParentWindowMainWidgetVisible(bool* aIsVisible);
|
||||
|
|
|
@ -1507,8 +1507,9 @@ nsWindow::SetCursor(nsCursor aCursor)
|
|||
}
|
||||
|
||||
// Only change cursor if it's actually been changed
|
||||
if (aCursor != mCursor) {
|
||||
if (aCursor != mCursor || mUpdateCursor) {
|
||||
GdkCursor *newCursor = nullptr;
|
||||
mUpdateCursor = false;
|
||||
|
||||
newCursor = get_gtk_cursor(aCursor);
|
||||
|
||||
|
|
|
@ -100,8 +100,8 @@ typedef void* nsNativeWidget;
|
|||
#endif
|
||||
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0x91944a4b, 0xbc29, 0x44aa, \
|
||||
{ 0x99, 0x21, 0x42, 0xeb, 0x1f, 0xbb, 0xa6, 0x89 } }
|
||||
{ 0x5b27abd6, 0x9e53, 0x4a0a, \
|
||||
{ 0x86, 0xf, 0x77, 0x5c, 0xc5, 0x69, 0x35, 0xf } };
|
||||
|
||||
/*
|
||||
* Window shadow styles
|
||||
|
@ -1165,6 +1165,13 @@ class nsIWidget : public nsISupports {
|
|||
|
||||
NS_IMETHOD SetCursor(nsCursor aCursor) = 0;
|
||||
|
||||
/**
|
||||
* If a cursor type is currently cached locally for this widget, clear the
|
||||
* cached cursor to force an update on the next SetCursor call.
|
||||
*/
|
||||
|
||||
virtual void ClearCachedCursor() = 0;
|
||||
|
||||
/**
|
||||
* Sets an image as the cursor for this widget.
|
||||
*
|
||||
|
|
|
@ -809,10 +809,10 @@ nsWindow::GetGLFrameBufferFormat()
|
|||
NS_IMETHODIMP
|
||||
nsWindow::SetCursor(nsCursor aCursor)
|
||||
{
|
||||
if (mCursor == aCursor) {
|
||||
if (mCursor == aCursor && !mUpdateCursor) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mUpdateCursor = false;
|
||||
mCursor = aCursor;
|
||||
if (mWidget) {
|
||||
mWidget->SetCursor(mCursor);
|
||||
|
|
|
@ -649,15 +649,17 @@ PuppetWidget::NotifyIMEOfSelectionChange(
|
|||
NS_IMETHODIMP
|
||||
PuppetWidget::SetCursor(nsCursor aCursor)
|
||||
{
|
||||
if (mCursor == aCursor) {
|
||||
if (mCursor == aCursor && !mUpdateCursor) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mTabChild && !mTabChild->SendSetCursor(aCursor)) {
|
||||
if (mTabChild &&
|
||||
!mTabChild->SendSetCursor(aCursor, mUpdateCursor)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mCursor = aCursor;
|
||||
mUpdateCursor = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ nsBaseWidget::nsBaseWidget()
|
|||
, mAttachedWidgetListener(nullptr)
|
||||
, mContext(nullptr)
|
||||
, mCursor(eCursor_standard)
|
||||
, mUpdateCursor(true)
|
||||
, mBorderStyle(eBorderStyle_none)
|
||||
, mUseLayersAcceleration(false)
|
||||
, mForceLayersAcceleration(false)
|
||||
|
|
|
@ -115,6 +115,7 @@ public:
|
|||
NS_IMETHOD SetCursor(nsCursor aCursor);
|
||||
NS_IMETHOD SetCursor(imgIContainer* aCursor,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY);
|
||||
virtual void ClearCachedCursor() { mUpdateCursor = true; }
|
||||
virtual void SetTransparencyMode(nsTransparencyMode aMode);
|
||||
virtual nsTransparencyMode GetTransparencyMode();
|
||||
virtual void GetWindowClipRegion(nsTArray<nsIntRect>* aRects);
|
||||
|
@ -402,6 +403,7 @@ protected:
|
|||
nsRefPtr<CompositorParent> mCompositorParent;
|
||||
nsRefPtr<WidgetShutdownObserver> mShutdownObserver;
|
||||
nsCursor mCursor;
|
||||
bool mUpdateCursor;
|
||||
nsBorderStyle mBorderStyle;
|
||||
bool mUseLayersAcceleration;
|
||||
bool mForceLayersAcceleration;
|
||||
|
|
Загрузка…
Ссылка в новой задаче