PipeWire capture: hide cursor when it goes off screen or is not visible

Set cursor position to (-1,-1) to indicate it's not valid when it goes
off the screen or it gets hidden by the compositor. Compositors indicate
invalid or hidden cursor by unsetting the cursor id in cursor metadata
and using spa_meta_cursor_is_valid() will tell us the needed information
for this.

Bug: chromium:346608851
Change-Id: I71b3222ca161b7fd8e964f4f4e12b9983179beba
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/355080
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Commit-Queue: Jan Grulich <grulja@gmail.com>
Cr-Commit-Position: refs/heads/main@{#42548}
This commit is contained in:
Jan Grulich 2024-06-19 10:26:37 +02:00 committed by WebRTC LUCI CQ
parent 2d6c397795
commit e6ad337d63
2 changed files with 36 additions and 26 deletions

View File

@ -40,6 +40,14 @@ void MouseCursorMonitorPipeWire::Capture() {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_DCHECK(callback_);
absl::optional<DesktopVector> mouse_cursor_position =
options_.screencast_stream()->CaptureCursorPosition();
// Invalid cursor or position
if (!mouse_cursor_position) {
callback_->OnMouseCursor(nullptr);
return;
}
std::unique_ptr<MouseCursor> mouse_cursor =
options_.screencast_stream()->CaptureCursor();
@ -48,11 +56,7 @@ void MouseCursorMonitorPipeWire::Capture() {
}
if (mode_ == SHAPE_AND_POSITION) {
absl::optional<DesktopVector> mouse_cursor_position =
options_.screencast_stream()->CaptureCursorPosition();
if (mouse_cursor_position) {
callback_->OnMouseCursorPosition(mouse_cursor_position.value());
}
callback_->OnMouseCursorPosition(mouse_cursor_position.value());
}
}

View File

@ -680,32 +680,38 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
const struct spa_meta_cursor* cursor =
static_cast<struct spa_meta_cursor*>(spa_buffer_find_meta_data(
spa_buffer, SPA_META_Cursor, sizeof(*cursor)));
if (cursor && spa_meta_cursor_is_valid(cursor)) {
struct spa_meta_bitmap* bitmap = nullptr;
if (cursor->bitmap_offset)
bitmap =
SPA_MEMBER(cursor, cursor->bitmap_offset, struct spa_meta_bitmap);
if (cursor) {
if (spa_meta_cursor_is_valid(cursor)) {
struct spa_meta_bitmap* bitmap = nullptr;
if (bitmap && bitmap->size.width > 0 && bitmap->size.height > 0) {
const uint8_t* bitmap_data =
SPA_MEMBER(bitmap, bitmap->offset, uint8_t);
BasicDesktopFrame* mouse_frame = new BasicDesktopFrame(
DesktopSize(bitmap->size.width, bitmap->size.height));
mouse_frame->CopyPixelsFrom(
bitmap_data, bitmap->stride,
DesktopRect::MakeWH(bitmap->size.width, bitmap->size.height));
mouse_cursor_ = std::make_unique<MouseCursor>(
mouse_frame, DesktopVector(cursor->hotspot.x, cursor->hotspot.y));
if (cursor->bitmap_offset)
bitmap =
SPA_MEMBER(cursor, cursor->bitmap_offset, struct spa_meta_bitmap);
if (bitmap && bitmap->size.width > 0 && bitmap->size.height > 0) {
const uint8_t* bitmap_data =
SPA_MEMBER(bitmap, bitmap->offset, uint8_t);
BasicDesktopFrame* mouse_frame = new BasicDesktopFrame(
DesktopSize(bitmap->size.width, bitmap->size.height));
mouse_frame->CopyPixelsFrom(
bitmap_data, bitmap->stride,
DesktopRect::MakeWH(bitmap->size.width, bitmap->size.height));
mouse_cursor_ = std::make_unique<MouseCursor>(
mouse_frame, DesktopVector(cursor->hotspot.x, cursor->hotspot.y));
if (observer_) {
observer_->OnCursorShapeChanged();
}
}
mouse_cursor_position_.set(cursor->position.x, cursor->position.y);
if (observer_) {
observer_->OnCursorShapeChanged();
observer_->OnCursorPositionChanged();
}
}
mouse_cursor_position_.set(cursor->position.x, cursor->position.y);
if (observer_) {
observer_->OnCursorPositionChanged();
} else {
// Indicate an invalid cursor
mouse_cursor_position_.set(-1, -1);
}
}
}