mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-19 07:22:21 +00:00
LibWeb+WebContent+UI: Support image cursors
The `cursor` property accepts a list of possible cursors, which behave as a fallback: We use whichever cursor is the first available one. This is a little complicated because initially, any remote images have not loaded, so we need to use the fallback standard cursor, and then switch to another when it loads. So, ComputedValues stores a Vector of cursors, and then in EventHandler we scan down that list until we find a cursor that's ready for use. The spec defines cursors as being `<url>`, but allows for `<image>` instead. That includes functions like `linear-gradient()`. This commit implements image cursors in the Qt UI, but not AppKit.
This commit is contained in:
parent
fd2414ba35
commit
bfd7ac1204
Notes:
github-actions[bot]
2025-02-28 12:51:27 +00:00
Author: https://github.com/AtkinsSJ
Commit: bfd7ac1204
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3644
20 changed files with 297 additions and 170 deletions
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2023, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2023, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2024-2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -630,67 +631,86 @@ void WebContentView::initialize_client(WebView::ViewImplementation::CreateNewCli
|
|||
update_screen_rects();
|
||||
}
|
||||
|
||||
void WebContentView::update_cursor(Gfx::StandardCursor cursor)
|
||||
void WebContentView::update_cursor(Gfx::Cursor cursor)
|
||||
{
|
||||
switch (cursor) {
|
||||
case Gfx::StandardCursor::Hidden:
|
||||
setCursor(Qt::BlankCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Arrow:
|
||||
setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Crosshair:
|
||||
setCursor(Qt::CrossCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::IBeam:
|
||||
setCursor(Qt::IBeamCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeHorizontal:
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeVertical:
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeDiagonalTLBR:
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeDiagonalBLTR:
|
||||
setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeColumn:
|
||||
setCursor(Qt::SplitHCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeRow:
|
||||
setCursor(Qt::SplitVCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Hand:
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Help:
|
||||
setCursor(Qt::WhatsThisCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Drag:
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::DragCopy:
|
||||
setCursor(Qt::DragCopyCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Move:
|
||||
setCursor(Qt::DragMoveCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Wait:
|
||||
setCursor(Qt::BusyCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Disallowed:
|
||||
setCursor(Qt::ForbiddenCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Eyedropper:
|
||||
case Gfx::StandardCursor::Zoom:
|
||||
// FIXME: No corresponding Qt cursors, default to Arrow
|
||||
default:
|
||||
setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
}
|
||||
cursor.visit([this](Gfx::StandardCursor standard_cursor) {
|
||||
switch (standard_cursor) {
|
||||
case Gfx::StandardCursor::Hidden:
|
||||
setCursor(Qt::BlankCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Arrow:
|
||||
setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Crosshair:
|
||||
setCursor(Qt::CrossCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::IBeam:
|
||||
setCursor(Qt::IBeamCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeHorizontal:
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeVertical:
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeDiagonalTLBR:
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeDiagonalBLTR:
|
||||
setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeColumn:
|
||||
setCursor(Qt::SplitHCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::ResizeRow:
|
||||
setCursor(Qt::SplitVCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Hand:
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Help:
|
||||
setCursor(Qt::WhatsThisCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Drag:
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::DragCopy:
|
||||
setCursor(Qt::DragCopyCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Move:
|
||||
setCursor(Qt::DragMoveCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Wait:
|
||||
setCursor(Qt::BusyCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Disallowed:
|
||||
setCursor(Qt::ForbiddenCursor);
|
||||
break;
|
||||
case Gfx::StandardCursor::Eyedropper:
|
||||
case Gfx::StandardCursor::Zoom:
|
||||
// FIXME: No corresponding Qt cursors, default to Arrow
|
||||
default:
|
||||
setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
} },
|
||||
[this](Gfx::ImageCursor const& image_cursor) {
|
||||
if (!image_cursor.bitmap.is_valid()) {
|
||||
dbgln("Failed to set cursor: Bitmap is invalid.");
|
||||
return;
|
||||
}
|
||||
auto const& bitmap = *image_cursor.bitmap.bitmap();
|
||||
auto qimage = QImage { bitmap.scanline_u8(0), bitmap.width(), bitmap.height(), QImage::Format_ARGB32 };
|
||||
if (qimage.isNull()) {
|
||||
dbgln("Failed to set cursor: Null QImage.");
|
||||
return;
|
||||
}
|
||||
auto qpixmap = QPixmap::fromImage(qimage);
|
||||
if (qimage.isNull()) {
|
||||
dbgln("Failed to set cursor: Couldn't create QPixmap from QImage.");
|
||||
return;
|
||||
}
|
||||
setCursor(QCursor { qpixmap, image_cursor.hotspot.x(), image_cursor.hotspot.y() });
|
||||
});
|
||||
}
|
||||
|
||||
Web::DevicePixelSize WebContentView::viewport_size() const
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue