mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1520502 - Set the standard cursor and the custom cursor in the same IPC message. r=jmathies
This cleans up a bit and allows us to be smarter about which cursors should we allow from content or what not, which will help with bug 1445844 and co. Differential Revision: https://phabricator.services.mozilla.com/D16711
This commit is contained in:
parent
51cb6c2749
commit
ef7d8198eb
@ -6391,7 +6391,7 @@ nsDocShell::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
|
||||
nsCOMPtr<nsIWidget> mainWidget;
|
||||
GetMainWidget(getter_AddRefs(mainWidget));
|
||||
if (mainWidget) {
|
||||
mainWidget->SetCursor(eCursor_spinning);
|
||||
mainWidget->SetCursor(eCursor_spinning, nullptr, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6407,7 +6407,7 @@ nsDocShell::OnStateChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
|
||||
nsCOMPtr<nsIWidget> mainWidget;
|
||||
GetMainWidget(getter_AddRefs(mainWidget));
|
||||
if (mainWidget) {
|
||||
mainWidget->SetCursor(eCursor_standard);
|
||||
mainWidget->SetCursor(eCursor_standard, nullptr, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3826,9 +3826,9 @@ nsresult EventStateManager::SetCursor(StyleCursorKind aCursor,
|
||||
}
|
||||
|
||||
// First, try the imgIContainer, if non-null
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
uint32_t hotspotX = 0;
|
||||
uint32_t hotspotY = 0;
|
||||
if (aContainer) {
|
||||
uint32_t hotspotX, hotspotY;
|
||||
|
||||
// css3-ui says to use the CSS-specified hotspot if present,
|
||||
// otherwise use the intrinsic hotspot, otherwise use the top left
|
||||
@ -3859,12 +3859,9 @@ nsresult EventStateManager::SetCursor(StyleCursorKind aCursor,
|
||||
if (hotspotYWrap) hotspotYWrap->GetData(&hotspotY);
|
||||
}
|
||||
}
|
||||
|
||||
rv = aWidget->SetCursor(aContainer, hotspotX, hotspotY);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) aWidget->SetCursor(c);
|
||||
|
||||
aWidget->SetCursor(c, aContainer, hotspotX, hotspotY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -386,15 +386,10 @@ parent:
|
||||
* Set the native cursor.
|
||||
* @param value
|
||||
* The widget cursor to set.
|
||||
* @param force
|
||||
* Invalidate any locally cached cursor settings and force an
|
||||
* update.
|
||||
*/
|
||||
async SetCursor(nsCursor value, bool force);
|
||||
|
||||
/**
|
||||
* Set the native cursor using a custom image.
|
||||
* @param cursorData
|
||||
* @param hasCustomCursor
|
||||
* Whether there's any custom cursor represented by cursorData and
|
||||
* company.
|
||||
* @param customCursorData
|
||||
* Serialized image data.
|
||||
* @param width
|
||||
* Width of the image.
|
||||
@ -412,9 +407,12 @@ parent:
|
||||
* Invalidate any locally cached cursor settings and force an
|
||||
* update.
|
||||
*/
|
||||
async SetCustomCursor(nsCString cursorData, uint32_t width, uint32_t height,
|
||||
uint32_t stride, SurfaceFormat format,
|
||||
uint32_t hotspotX, uint32_t hotspotY, bool force);
|
||||
async SetCursor(nsCursor value,
|
||||
bool hasCustomCursor,
|
||||
nsCString customCursorData,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t stride, SurfaceFormat format,
|
||||
uint32_t hotspotX, uint32_t hotspotY, bool force);
|
||||
|
||||
/**
|
||||
* Used to set the current text of the status tooltip.
|
||||
|
@ -1038,11 +1038,9 @@ void TabParent::SendRealMouseEvent(WidgetMouseEvent& aEvent) {
|
||||
// become the current cursor. When we mouseexit, we stop.
|
||||
if (eMouseEnterIntoWidget == aEvent.mMessage) {
|
||||
mTabSetsCursor = true;
|
||||
if (mCustomCursor) {
|
||||
widget->SetCursor(mCustomCursor, mCustomCursorHotspotX,
|
||||
if (mCursor != eCursorInvalid) {
|
||||
widget->SetCursor(mCursor, mCustomCursor, mCustomCursorHotspotX,
|
||||
mCustomCursorHotspotY);
|
||||
} else if (mCursor != eCursorInvalid) {
|
||||
widget->SetCursor(mCursor);
|
||||
}
|
||||
} else if (eMouseExitFromWidget == aEvent.mMessage) {
|
||||
mTabSetsCursor = false;
|
||||
@ -1632,55 +1630,45 @@ mozilla::ipc::IPCResult TabParent::RecvAsyncMessage(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult TabParent::RecvSetCursor(const nsCursor& aCursor,
|
||||
const bool& aForce) {
|
||||
mCursor = aCursor;
|
||||
mCustomCursor = nullptr;
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
if (aForce) {
|
||||
widget->ClearCachedCursor();
|
||||
}
|
||||
if (mTabSetsCursor) {
|
||||
widget->SetCursor(mCursor);
|
||||
}
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult TabParent::RecvSetCustomCursor(
|
||||
mozilla::ipc::IPCResult TabParent::RecvSetCursor(
|
||||
const nsCursor& aCursor,
|
||||
const bool& aHasCustomCursor,
|
||||
const nsCString& aCursorData, const uint32_t& aWidth,
|
||||
const uint32_t& aHeight, const uint32_t& aStride,
|
||||
const gfx::SurfaceFormat& aFormat, const uint32_t& aHotspotX,
|
||||
const uint32_t& aHotspotY, const bool& aForce) {
|
||||
mCursor = eCursorInvalid;
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
if (aForce) {
|
||||
widget->ClearCachedCursor();
|
||||
}
|
||||
|
||||
if (mTabSetsCursor) {
|
||||
const gfx::IntSize size(aWidth, aHeight);
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> customCursor =
|
||||
gfx::CreateDataSourceSurfaceFromData(
|
||||
size, aFormat,
|
||||
reinterpret_cast<const uint8_t*>(aCursorData.BeginReading()),
|
||||
aStride);
|
||||
|
||||
RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(customCursor, size);
|
||||
nsCOMPtr<imgIContainer> cursorImage(
|
||||
image::ImageOps::CreateFromDrawable(drawable));
|
||||
widget->SetCursor(cursorImage, aHotspotX, aHotspotY);
|
||||
mCustomCursor = cursorImage;
|
||||
mCustomCursorHotspotX = aHotspotX;
|
||||
mCustomCursorHotspotY = aHotspotY;
|
||||
}
|
||||
if (!widget) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (aForce) {
|
||||
widget->ClearCachedCursor();
|
||||
}
|
||||
|
||||
if (!mTabSetsCursor) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> cursorImage;
|
||||
if (aHasCustomCursor) {
|
||||
const gfx::IntSize size(aWidth, aHeight);
|
||||
RefPtr<gfx::DataSourceSurface> customCursor =
|
||||
gfx::CreateDataSourceSurfaceFromData(
|
||||
size, aFormat,
|
||||
reinterpret_cast<const uint8_t*>(aCursorData.BeginReading()),
|
||||
aStride);
|
||||
|
||||
RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(customCursor, size);
|
||||
cursorImage = image::ImageOps::CreateFromDrawable(drawable);
|
||||
}
|
||||
|
||||
widget->SetCursor(aCursor, cursorImage, aHotspotX, aHotspotY);
|
||||
mCursor = aCursor;
|
||||
mCustomCursor = cursorImage;
|
||||
mCustomCursorHotspotX = aHotspotX;
|
||||
mCustomCursorHotspotY = aHotspotY;
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -260,14 +260,15 @@ class TabParent final : public PBrowserParent,
|
||||
nsTArray<nsCString>&& aDisabledCommands) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSetCursor(const nsCursor& aValue,
|
||||
const bool& aHasCustomCursor,
|
||||
const nsCString& aUri,
|
||||
const uint32_t& aWidth, const uint32_t& aHeight,
|
||||
const uint32_t& aStride,
|
||||
const gfx::SurfaceFormat& aFormat,
|
||||
const uint32_t& aHotspotX,
|
||||
const uint32_t& aHotspotY,
|
||||
const bool& aForce) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSetCustomCursor(
|
||||
const nsCString& aUri, const uint32_t& aWidth, const uint32_t& aHeight,
|
||||
const uint32_t& aStride, const gfx::SurfaceFormat& aFormat,
|
||||
const uint32_t& aHotspotX, const uint32_t& aHotspotY,
|
||||
const bool& aForce) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSetStatus(
|
||||
const uint32_t& aType, const nsString& aStatus) override;
|
||||
|
||||
|
@ -898,70 +898,65 @@ nsresult PuppetWidget::NotifyIMEOfPositionChange(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void PuppetWidget::SetCursor(nsCursor aCursor) {
|
||||
struct CursorSurface {
|
||||
UniquePtr<char[]> mData;
|
||||
IntSize mSize;
|
||||
};
|
||||
|
||||
void PuppetWidget::SetCursor(nsCursor aCursor,
|
||||
imgIContainer* aCursorImage,
|
||||
uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) {
|
||||
if (!mTabChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't cache on windows, Windowless flash breaks this via async cursor
|
||||
// updates.
|
||||
#if !defined(XP_WIN)
|
||||
if (mCursor == aCursor && !mCustomCursor && !mUpdateCursor) {
|
||||
if (!mUpdateCursor && mCursor == aCursor && mCustomCursor == aCursorImage &&
|
||||
(!aCursorImage ||
|
||||
(mCursorHotspotX == aHotspotX && mCursorHotspotY == aHotspotY))) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasCustomCursor = false;
|
||||
UniquePtr<char[]> customCursorData;
|
||||
size_t length = 0;
|
||||
IntSize customCursorSize;
|
||||
int32_t stride = 0;
|
||||
auto format = SurfaceFormat::B8G8R8A8;
|
||||
bool force = mUpdateCursor;
|
||||
|
||||
if (aCursorImage) {
|
||||
RefPtr<SourceSurface> surface = aCursorImage->GetFrame(
|
||||
imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE);
|
||||
if (surface) {
|
||||
if (RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface()) {
|
||||
hasCustomCursor = true;
|
||||
customCursorData = nsContentUtils::GetSurfaceData(
|
||||
WrapNotNull(dataSurface), &length, &stride);
|
||||
customCursorSize = dataSurface->GetSize();
|
||||
format = dataSurface->GetFormat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mCustomCursor = nullptr;
|
||||
|
||||
if (mTabChild && !mTabChild->SendSetCursor(aCursor, mUpdateCursor)) {
|
||||
nsDependentCString cursorData(customCursorData ? customCursorData.get() : "", length);
|
||||
if (!mTabChild->SendSetCursor(aCursor, hasCustomCursor, cursorData,
|
||||
customCursorSize.width, customCursorSize.height,
|
||||
stride, format, aHotspotX, aHotspotY, force)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCursor = aCursor;
|
||||
mUpdateCursor = false;
|
||||
}
|
||||
|
||||
nsresult PuppetWidget::SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) {
|
||||
if (!aCursor || !mTabChild) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if !defined(XP_WIN)
|
||||
if (mCustomCursor == aCursor && mCursorHotspotX == aHotspotX &&
|
||||
mCursorHotspotY == aHotspotY && !mUpdateCursor) {
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
RefPtr<mozilla::gfx::SourceSurface> surface = aCursor->GetFrame(
|
||||
imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE);
|
||||
if (!surface) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<mozilla::gfx::DataSourceSurface> dataSurface =
|
||||
surface->GetDataSurface();
|
||||
if (!dataSurface) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
size_t length;
|
||||
int32_t stride;
|
||||
mozilla::UniquePtr<char[]> surfaceData = nsContentUtils::GetSurfaceData(
|
||||
WrapNotNull(dataSurface), &length, &stride);
|
||||
|
||||
nsDependentCString cursorData(surfaceData.get(), length);
|
||||
mozilla::gfx::IntSize size = dataSurface->GetSize();
|
||||
if (!mTabChild->SendSetCustomCursor(cursorData, size.width, size.height,
|
||||
stride, dataSurface->GetFormat(),
|
||||
aHotspotX, aHotspotY, mUpdateCursor)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mCursor = eCursorInvalid;
|
||||
mCustomCursor = aCursor;
|
||||
mCustomCursor = aCursorImage;
|
||||
mCursorHotspotX = aHotspotX;
|
||||
mCursorHotspotY = aHotspotY;
|
||||
mUpdateCursor = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void PuppetWidget::ClearCachedCursor() {
|
||||
|
@ -198,9 +198,8 @@ class PuppetWidget : public nsBaseWidget,
|
||||
mNativeTextEventDispatcherListener = aListener;
|
||||
}
|
||||
|
||||
virtual void SetCursor(nsCursor aCursor) override;
|
||||
virtual nsresult SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) override;
|
||||
virtual void SetCursor(nsCursor aDefaultCursor, imgIContainer* aCustomCursor,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) override;
|
||||
|
||||
virtual void ClearCachedCursor() override;
|
||||
|
||||
|
@ -258,12 +258,8 @@ class nsWindow final : public nsBaseWidget {
|
||||
virtual already_AddRefed<nsIScreen> GetWidgetScreen() override;
|
||||
virtual nsresult MakeFullScreen(bool aFullScreen,
|
||||
nsIScreen* aTargetScreen = nullptr) override;
|
||||
|
||||
virtual void SetCursor(nsCursor aCursor) override {}
|
||||
virtual nsresult SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
void SetCursor(nsCursor aDefaultCursor, imgIContainer* aImageCursor,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) override {}
|
||||
void* GetNativeData(uint32_t aDataType) override;
|
||||
void SetNativeData(uint32_t aDataType, uintptr_t aVal) override;
|
||||
virtual nsresult SetTitle(const nsAString& aTitle) override { return NS_OK; }
|
||||
|
@ -364,9 +364,8 @@ class nsChildView final : public nsBaseWidget {
|
||||
virtual bool WidgetTypeSupportsAcceleration() override;
|
||||
virtual bool ShouldUseOffMainThreadCompositing() override;
|
||||
|
||||
virtual void SetCursor(nsCursor aCursor) override;
|
||||
virtual nsresult SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) override;
|
||||
virtual void SetCursor(nsCursor aDefaultCursor, imgIContainer* aCursor,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) override;
|
||||
|
||||
virtual nsresult SetTitle(const nsAString& title) override;
|
||||
|
||||
|
@ -762,30 +762,28 @@ nsresult nsChildView::SetFocus(bool aRaise) {
|
||||
}
|
||||
|
||||
// Override to set the cursor on the mac
|
||||
void nsChildView::SetCursor(nsCursor aCursor) {
|
||||
void nsChildView::SetCursor(nsCursor aDefaultCursor, imgIContainer* aImageCursor,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if ([mView isDragInProgress]) return; // Don't change the cursor during dragging.
|
||||
|
||||
nsBaseWidget::SetCursor(aCursor);
|
||||
[[nsCursorManager sharedInstance] setCursor:aCursor];
|
||||
if (aImageCursor) {
|
||||
nsresult rv = [[nsCursorManager sharedInstance] setCursorWithImage:aImageCursor
|
||||
hotSpotX:aHotspotX
|
||||
hotSpotY:aHotspotY
|
||||
scaleFactor:BackingScaleFactor()];
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsBaseWidget::SetCursor(aDefaultCursor, nullptr, 0, 0);
|
||||
[[nsCursorManager sharedInstance] setCursor:aDefaultCursor];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
// implement to fix "hidden virtual function" warning
|
||||
nsresult nsChildView::SetCursor(imgIContainer* aCursor, uint32_t aHotspotX, uint32_t aHotspotY) {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsBaseWidget::SetCursor(aCursor, aHotspotX, aHotspotY);
|
||||
return [[nsCursorManager sharedInstance] setCursorWithImage:aCursor
|
||||
hotSpotX:aHotspotX
|
||||
hotSpotY:aHotspotY
|
||||
scaleFactor:BackingScaleFactor()];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// Get this component dimension
|
||||
|
@ -242,9 +242,8 @@ class nsCocoaWindow final : public nsBaseWidget, public nsPIWidgetCocoa {
|
||||
virtual LayoutDeviceIntRect GetScreenBounds() override;
|
||||
void ReportMoveEvent();
|
||||
void ReportSizeEvent();
|
||||
virtual void SetCursor(nsCursor aCursor) override;
|
||||
virtual nsresult SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) override;
|
||||
virtual void SetCursor(nsCursor aDefaultCursor, imgIContainer* aCursorImage, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) override;
|
||||
|
||||
CGFloat BackingScaleFactor();
|
||||
void BackingScaleFactorChanged();
|
||||
|
@ -1629,16 +1629,10 @@ int32_t nsCocoaWindow::RoundsWidgetCoordinatesTo() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void nsCocoaWindow::SetCursor(nsCursor aCursor) {
|
||||
if (mPopupContentView) {
|
||||
mPopupContentView->SetCursor(aCursor);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsCocoaWindow::SetCursor(imgIContainer* aCursor, uint32_t aHotspotX, uint32_t aHotspotY) {
|
||||
if (mPopupContentView) return mPopupContentView->SetCursor(aCursor, aHotspotX, aHotspotY);
|
||||
|
||||
return NS_OK;
|
||||
void nsCocoaWindow::SetCursor(nsCursor aDefaultCursor, imgIContainer* aCursorImage,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) {
|
||||
if (mPopupContentView)
|
||||
mPopupContentView->SetCursor(aDefaultCursor, aCursorImage, aHotspotX, aHotspotY);
|
||||
}
|
||||
|
||||
nsresult nsCocoaWindow::SetTitle(const nsAString& aTitle) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@ -1434,61 +1434,31 @@ gboolean nsWindow::OnPropertyNotifyEvent(GtkWidget *aWidget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void nsWindow::SetCursor(nsCursor aCursor) {
|
||||
// if we're not the toplevel window pass up the cursor request to
|
||||
// the toplevel window to handle it.
|
||||
if (!mContainer && mGdkWindow) {
|
||||
nsWindow *window = GetContainerWindow();
|
||||
if (!window) return;
|
||||
|
||||
window->SetCursor(aCursor);
|
||||
return;
|
||||
static GdkCursor *GetCursorForImage(imgIContainer *aCursorImage,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) {
|
||||
if (!aCursorImage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Only change cursor if it's actually been changed
|
||||
if (aCursor != mCursor || mUpdateCursor) {
|
||||
GdkCursor *newCursor = nullptr;
|
||||
mUpdateCursor = false;
|
||||
|
||||
newCursor = get_gtk_cursor(aCursor);
|
||||
|
||||
if (nullptr != newCursor) {
|
||||
mCursor = aCursor;
|
||||
|
||||
if (!mContainer) return;
|
||||
|
||||
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mContainer)),
|
||||
newCursor);
|
||||
}
|
||||
GdkPixbuf *pixbuf = nsImageToPixbuf::ImageToPixbuf(aCursorImage);
|
||||
if (!pixbuf) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsWindow::SetCursor(imgIContainer *aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) {
|
||||
// if we're not the toplevel window pass up the cursor request to
|
||||
// the toplevel window to handle it.
|
||||
if (!mContainer && mGdkWindow) {
|
||||
nsWindow *window = GetContainerWindow();
|
||||
if (!window) return NS_ERROR_FAILURE;
|
||||
|
||||
return window->SetCursor(aCursor, aHotspotX, aHotspotY);
|
||||
}
|
||||
|
||||
mCursor = eCursorInvalid;
|
||||
|
||||
// Get the image's current frame
|
||||
GdkPixbuf *pixbuf = nsImageToPixbuf::ImageToPixbuf(aCursor);
|
||||
if (!pixbuf) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
int width = gdk_pixbuf_get_width(pixbuf);
|
||||
int height = gdk_pixbuf_get_height(pixbuf);
|
||||
|
||||
auto CleanupPixBuf =
|
||||
mozilla::MakeScopeExit([&]() { g_object_unref(pixbuf); });
|
||||
|
||||
// Reject cursors greater than 128 pixels in some direction, to prevent
|
||||
// spoofing.
|
||||
// XXX ideally we should rescale. Also, we could modify the API to
|
||||
// allow trusted content to set larger cursors.
|
||||
//
|
||||
// TODO(emilio, bug 1445844): Unify the solution for this with other
|
||||
// platforms.
|
||||
if (width > 128 || height > 128) {
|
||||
g_object_unref(pixbuf);
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Looks like all cursors need an alpha channel (tested on Gtk 2.4.4). This
|
||||
@ -1497,26 +1467,58 @@ nsresult nsWindow::SetCursor(imgIContainer *aCursor, uint32_t aHotspotX,
|
||||
if (!gdk_pixbuf_get_has_alpha(pixbuf)) {
|
||||
GdkPixbuf *alphaBuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0);
|
||||
g_object_unref(pixbuf);
|
||||
if (!alphaBuf) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
pixbuf = alphaBuf;
|
||||
}
|
||||
|
||||
GdkCursor *cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(),
|
||||
pixbuf, aHotspotX, aHotspotY);
|
||||
g_object_unref(pixbuf);
|
||||
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
if (cursor) {
|
||||
if (mContainer) {
|
||||
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mContainer)),
|
||||
cursor);
|
||||
rv = NS_OK;
|
||||
if (!alphaBuf) {
|
||||
return nullptr;
|
||||
}
|
||||
g_object_unref(cursor);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf,
|
||||
aHotspotX, aHotspotY);
|
||||
}
|
||||
|
||||
void nsWindow::SetCursor(nsCursor aDefaultCursor, imgIContainer *aCursorImage,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) {
|
||||
// if we're not the toplevel window pass up the cursor request to
|
||||
// the toplevel window to handle it.
|
||||
if (!mContainer && mGdkWindow) {
|
||||
nsWindow *window = GetContainerWindow();
|
||||
if (!window) return;
|
||||
|
||||
window->SetCursor(aDefaultCursor, aCursorImage, aHotspotX, aHotspotY);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only change cursor if it's actually been changed
|
||||
if (!aCursorImage && aDefaultCursor == mCursor && !mUpdateCursor) {
|
||||
return;
|
||||
}
|
||||
|
||||
mUpdateCursor = false;
|
||||
mCursor = eCursorInvalid;
|
||||
|
||||
// Try to set the cursor image first, and fall back to the numeric cursor.
|
||||
GdkCursor *newCursor = GetCursorForImage(aCursorImage, aHotspotX, aHotspotY);
|
||||
if (!newCursor) {
|
||||
newCursor = get_gtk_cursor(aDefaultCursor);
|
||||
if (newCursor) {
|
||||
mCursor = aDefaultCursor;
|
||||
}
|
||||
}
|
||||
|
||||
auto CleanupCursor = mozilla::MakeScopeExit([&]() {
|
||||
// get_gtk_cursor returns a weak reference, which we shouldn't unref.
|
||||
if (newCursor && mCursor == eCursorInvalid) {
|
||||
g_object_unref(newCursor);
|
||||
}
|
||||
});
|
||||
|
||||
if (!newCursor || !mContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mContainer)),
|
||||
newCursor);
|
||||
}
|
||||
|
||||
void nsWindow::Invalidate(const LayoutDeviceIntRect &aRect) {
|
||||
@ -3482,7 +3484,7 @@ nsresult nsWindow::Create(nsIWidget *aParent, nsNativeWidget aNativeParent,
|
||||
// cursor, even though our internal state
|
||||
// indicates that we already have the
|
||||
// standard cursor.
|
||||
SetCursor(eCursor_standard);
|
||||
SetCursor(eCursor_standard, nullptr, 0, 0);
|
||||
|
||||
if (aInitData->mNoAutoHide) {
|
||||
gint wmd = ConvertBorderStyles(mBorderStyle);
|
||||
|
@ -144,9 +144,8 @@ class nsWindow final : public nsBaseWidget {
|
||||
virtual LayoutDeviceIntRect GetClientBounds() override;
|
||||
virtual LayoutDeviceIntSize GetClientSize() override;
|
||||
virtual LayoutDeviceIntPoint GetClientOffset() override;
|
||||
virtual void SetCursor(nsCursor aCursor) override;
|
||||
virtual nsresult SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) override;
|
||||
virtual void SetCursor(nsCursor aDefaultCursor, imgIContainer* aCursor,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) override;
|
||||
virtual void Invalidate(const LayoutDeviceIntRect& aRect) override;
|
||||
virtual void* GetNativeData(uint32_t aDataType) override;
|
||||
virtual nsresult SetTitle(const nsAString& aTitle) override;
|
||||
|
@ -640,11 +640,10 @@ void nsBaseWidget::SetSizeMode(nsSizeMode aMode) {
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void nsBaseWidget::SetCursor(nsCursor aCursor) { mCursor = aCursor; }
|
||||
|
||||
nsresult nsBaseWidget::SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
void nsBaseWidget::SetCursor(nsCursor aCursor,
|
||||
imgIContainer*, uint32_t, uint32_t) {
|
||||
// We don't support the cursor image.
|
||||
mCursor = aCursor;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -168,9 +168,8 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
|
||||
|
||||
virtual bool IsFullyOccluded() const override { return mIsFullyOccluded; }
|
||||
|
||||
virtual void SetCursor(nsCursor aCursor) override;
|
||||
virtual nsresult SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) override;
|
||||
virtual void SetCursor(nsCursor aDefaultCursor, imgIContainer* aCursor,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) override;
|
||||
virtual void ClearCachedCursor() override { mUpdateCursor = true; }
|
||||
virtual void SetTransparencyMode(nsTransparencyMode aMode) override;
|
||||
virtual nsTransparencyMode GetTransparencyMode() override;
|
||||
|
@ -933,13 +933,6 @@ class nsIWidget : public nsISupports {
|
||||
|
||||
virtual void SetBackgroundColor(const nscolor& aColor) {}
|
||||
|
||||
/**
|
||||
* Set the cursor for this widget
|
||||
*
|
||||
* @param aCursor the new cursor for this widget
|
||||
*/
|
||||
virtual void 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.
|
||||
@ -948,16 +941,15 @@ class nsIWidget : public nsISupports {
|
||||
virtual void ClearCachedCursor() = 0;
|
||||
|
||||
/**
|
||||
* Sets an image as the cursor for this widget.
|
||||
* Sets the cursor cursor for this widget.
|
||||
*
|
||||
* @param aCursor the cursor to set
|
||||
* @param aX the X coordinate of the hotspot (from left).
|
||||
* @param aY the Y coordinate of the hotspot (from top).
|
||||
* @retval NS_ERROR_NOT_IMPLEMENTED if setting images as cursors is not
|
||||
* supported
|
||||
* @param aDefaultCursor the default cursor to be set
|
||||
* @param aCursorImage a custom cursor, maybe null.
|
||||
* @param aX the X coordinate of the hotspot for aCursorImage (from left).
|
||||
* @param aY the Y coordinate of the hotspot for aCursorImage (from top).
|
||||
*/
|
||||
virtual nsresult SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) = 0;
|
||||
virtual void SetCursor(nsCursor aDefaultCursor, imgIContainer* aCursorImage,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) = 0;
|
||||
|
||||
/**
|
||||
* Get the window type of this widget.
|
||||
|
@ -1516,7 +1516,7 @@ void nsWindow::Show(bool bState) {
|
||||
|
||||
// Set the cursor before showing the window to avoid the default wait
|
||||
// cursor.
|
||||
SetCursor(eCursor_standard);
|
||||
SetCursor(eCursor_standard, nullptr, 0, 0);
|
||||
|
||||
switch (mSizeMode) {
|
||||
case nsSizeMode_Fullscreen:
|
||||
@ -2710,208 +2710,183 @@ void nsWindow::SetBackgroundColor(const nscolor& aColor) {
|
||||
**************************************************************/
|
||||
|
||||
// Set this component cursor
|
||||
void nsWindow::SetCursor(nsCursor aCursor) {
|
||||
// Only change cursor if it's changing
|
||||
|
||||
// XXX mCursor isn't always right. Scrollbars and others change it, too.
|
||||
// XXX If we want this optimization we need a better way to do it.
|
||||
// if (aCursor != mCursor) {
|
||||
HCURSOR newCursor = nullptr;
|
||||
|
||||
static HCURSOR CursorFor(nsCursor aCursor) {
|
||||
switch (aCursor) {
|
||||
case eCursor_select:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_IBEAM);
|
||||
break;
|
||||
|
||||
return ::LoadCursor(nullptr, IDC_IBEAM);
|
||||
case eCursor_wait:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_WAIT);
|
||||
break;
|
||||
|
||||
case eCursor_hyperlink: {
|
||||
newCursor = ::LoadCursor(nullptr, IDC_HAND);
|
||||
break;
|
||||
}
|
||||
|
||||
return ::LoadCursor(nullptr, IDC_WAIT);
|
||||
case eCursor_hyperlink:
|
||||
return ::LoadCursor(nullptr, IDC_HAND);
|
||||
case eCursor_standard:
|
||||
case eCursor_context_menu: // XXX See bug 258960.
|
||||
newCursor = ::LoadCursor(nullptr, IDC_ARROW);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_ARROW);
|
||||
|
||||
case eCursor_n_resize:
|
||||
case eCursor_s_resize:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZENS);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZENS);
|
||||
|
||||
case eCursor_w_resize:
|
||||
case eCursor_e_resize:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZEWE);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZEWE);
|
||||
|
||||
case eCursor_nw_resize:
|
||||
case eCursor_se_resize:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZENWSE);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZENWSE);
|
||||
|
||||
case eCursor_ne_resize:
|
||||
case eCursor_sw_resize:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZENESW);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZENESW);
|
||||
|
||||
case eCursor_crosshair:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_CROSS);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_CROSS);
|
||||
|
||||
case eCursor_move:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZEALL);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZEALL);
|
||||
|
||||
case eCursor_help:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_HELP);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_HELP);
|
||||
|
||||
case eCursor_copy: // CSS3
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_COPY));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_COPY));
|
||||
|
||||
case eCursor_alias:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_ALIAS));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_ALIAS));
|
||||
|
||||
case eCursor_cell:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_CELL));
|
||||
break;
|
||||
|
||||
return ::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_CELL));
|
||||
case eCursor_grab:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_GRAB));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_GRAB));
|
||||
|
||||
case eCursor_grabbing:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_GRABBING));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance,
|
||||
MAKEINTRESOURCE(IDC_GRABBING));
|
||||
|
||||
case eCursor_spinning:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_APPSTARTING);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_APPSTARTING);
|
||||
|
||||
case eCursor_zoom_in:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_ZOOMIN));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_ZOOMIN));
|
||||
|
||||
case eCursor_zoom_out:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_ZOOMOUT));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance,
|
||||
MAKEINTRESOURCE(IDC_ZOOMOUT));
|
||||
|
||||
case eCursor_not_allowed:
|
||||
case eCursor_no_drop:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_NO);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_NO);
|
||||
|
||||
case eCursor_col_resize:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_COLRESIZE));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance,
|
||||
MAKEINTRESOURCE(IDC_COLRESIZE));
|
||||
|
||||
case eCursor_row_resize:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_ROWRESIZE));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance,
|
||||
MAKEINTRESOURCE(IDC_ROWRESIZE));
|
||||
|
||||
case eCursor_vertical_text:
|
||||
newCursor = ::LoadCursor(nsToolkit::mDllInstance,
|
||||
MAKEINTRESOURCE(IDC_VERTICALTEXT));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance,
|
||||
MAKEINTRESOURCE(IDC_VERTICALTEXT));
|
||||
|
||||
case eCursor_all_scroll:
|
||||
// XXX not 100% appropriate perhaps
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZEALL);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZEALL);
|
||||
|
||||
case eCursor_nesw_resize:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZENESW);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZENESW);
|
||||
|
||||
case eCursor_nwse_resize:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZENWSE);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZENWSE);
|
||||
|
||||
case eCursor_ns_resize:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZENS);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZENS);
|
||||
|
||||
case eCursor_ew_resize:
|
||||
newCursor = ::LoadCursor(nullptr, IDC_SIZEWE);
|
||||
break;
|
||||
return ::LoadCursor(nullptr, IDC_SIZEWE);
|
||||
|
||||
case eCursor_none:
|
||||
newCursor =
|
||||
::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_NONE));
|
||||
break;
|
||||
return ::LoadCursor(nsToolkit::mDllInstance, MAKEINTRESOURCE(IDC_NONE));
|
||||
|
||||
default:
|
||||
NS_ERROR("Invalid cursor type");
|
||||
break;
|
||||
}
|
||||
|
||||
if (nullptr != newCursor) {
|
||||
mCursor = aCursor;
|
||||
HCURSOR oldCursor = ::SetCursor(newCursor);
|
||||
|
||||
if (sHCursor == oldCursor) {
|
||||
NS_IF_RELEASE(sCursorImgContainer);
|
||||
if (sHCursor != nullptr) ::DestroyIcon(sHCursor);
|
||||
sHCursor = nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Setting the actual cursor
|
||||
nsresult nsWindow::SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) {
|
||||
if (sCursorImgContainer == aCursor && sHCursor) {
|
||||
::SetCursor(sHCursor);
|
||||
return NS_OK;
|
||||
static HCURSOR CursorForImage(imgIContainer* aImageContainer,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY,
|
||||
double aScale) {
|
||||
if (!aImageContainer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t width = 0;
|
||||
int32_t height = 0;
|
||||
|
||||
nsresult rv;
|
||||
rv = aCursor->GetWidth(&width);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aCursor->GetHeight(&height);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(aImageContainer->GetWidth(&width)) ||
|
||||
NS_FAILED(aImageContainer->GetHeight(&height))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Reject cursors greater than 128 pixels in either direction, to prevent
|
||||
// spoofing.
|
||||
// XXX ideally we should rescale. Also, we could modify the API to
|
||||
// allow trusted content to set larger cursors.
|
||||
if (width > 128 || height > 128) return NS_ERROR_NOT_AVAILABLE;
|
||||
if (width > 128 || height > 128) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IntSize size = RoundedToInt(Size(width * aScale, height * aScale));
|
||||
HCURSOR cursor;
|
||||
nsresult rv = nsWindowGfx::CreateIcon(aImageContainer, true, aHotspotX,
|
||||
aHotspotY, size, &cursor);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
// Setting the actual cursor
|
||||
void nsWindow::SetCursor(nsCursor aDefaultCursor, imgIContainer* aImageCursor,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) {
|
||||
if (aImageCursor && sCursorImgContainer == aImageCursor && sHCursor) {
|
||||
::SetCursor(sHCursor);
|
||||
return;
|
||||
}
|
||||
|
||||
double scale = GetDefaultScale().scale;
|
||||
IntSize size = RoundedToInt(Size(width * scale, height * scale));
|
||||
rv = nsWindowGfx::CreateIcon(aCursor, true, aHotspotX, aHotspotY, size,
|
||||
&cursor);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
HCURSOR cursor = CursorForImage(aImageCursor, aHotspotX, aHotspotY, scale);
|
||||
if (cursor) {
|
||||
mCursor = eCursorInvalid;
|
||||
::SetCursor(cursor);
|
||||
|
||||
mCursor = eCursorInvalid;
|
||||
::SetCursor(cursor);
|
||||
NS_IF_RELEASE(sCursorImgContainer);
|
||||
sCursorImgContainer = aImageCursor;
|
||||
NS_ADDREF(sCursorImgContainer);
|
||||
|
||||
NS_IF_RELEASE(sCursorImgContainer);
|
||||
sCursorImgContainer = aCursor;
|
||||
NS_ADDREF(sCursorImgContainer);
|
||||
if (sHCursor) {
|
||||
::DestroyIcon(sHCursor);
|
||||
}
|
||||
sHCursor = cursor;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sHCursor != nullptr) ::DestroyIcon(sHCursor);
|
||||
sHCursor = cursor;
|
||||
cursor = CursorFor(aDefaultCursor);
|
||||
if (!cursor) {
|
||||
return;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
mCursor = aDefaultCursor;
|
||||
HCURSOR oldCursor = ::SetCursor(cursor);
|
||||
|
||||
if (sHCursor == oldCursor) {
|
||||
NS_IF_RELEASE(sCursorImgContainer);
|
||||
if (sHCursor) {
|
||||
::DestroyIcon(sHCursor);
|
||||
}
|
||||
sHCursor = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
@ -6930,7 +6905,9 @@ void nsWindow::OnDestroy() {
|
||||
}
|
||||
|
||||
// Destroy any custom cursor resources.
|
||||
if (mCursor == eCursorInvalid) SetCursor(eCursor_standard);
|
||||
if (mCursor == eCursorInvalid) {
|
||||
SetCursor(eCursor_standard, nullptr, 0, 0);
|
||||
}
|
||||
|
||||
if (mCompositorWidgetDelegate) {
|
||||
mCompositorWidgetDelegate->OnDestroyWindow();
|
||||
|
@ -151,9 +151,8 @@ class nsWindow final : public nsWindowBase {
|
||||
virtual LayoutDeviceIntRect GetClientBounds() override;
|
||||
virtual LayoutDeviceIntPoint GetClientOffset() override;
|
||||
void SetBackgroundColor(const nscolor& aColor) override;
|
||||
virtual nsresult SetCursor(imgIContainer* aCursor, uint32_t aHotspotX,
|
||||
uint32_t aHotspotY) override;
|
||||
virtual void SetCursor(nsCursor aCursor) override;
|
||||
virtual void SetCursor(nsCursor aDefaultCursor, imgIContainer* aCursorImage,
|
||||
uint32_t aHotspotX, uint32_t aHotspotY) override;
|
||||
virtual nsresult ConfigureChildren(
|
||||
const nsTArray<Configuration>& aConfigurations) override;
|
||||
virtual bool PrepareForFullscreenTransition(nsISupports** aData) override;
|
||||
|
Loading…
Reference in New Issue
Block a user