diff --git a/include/capi/cef_render_handler_capi.h b/include/capi/cef_render_handler_capi.h index e1ed76d346f1b1f85831c0e288d619a401e4da01..e9f5095f641f777197dfd98ea55dce91dde4dcb9 100644 --- a/include/capi/cef_render_handler_capi.h +++ b/include/capi/cef_render_handler_capi.h @@ -199,7 +199,8 @@ typedef struct _cef_render_handler_t { struct _cef_drag_data_t* drag_data, cef_drag_operations_mask_t allowed_ops, int x, - int y); + int y, + int visible_offset_y); /// /// Called when the web view wants to update the mouse cursor during a drag & @@ -474,6 +475,15 @@ typedef struct _cef_render_handler_t { void(CEF_CALLBACK* on_accessibility_event)(struct _cef_render_handler_t* self, int64_t accessibilityId, int32_t eventType); + + /// + /// Get the visible area relative to the web. + /// + void(CEF_CALLBACK* get_visible_rect_to_web)(struct _cef_render_handler_t* self, + int* visibleX, + int* visibleY, + int* visibleWidth, + int* visibleHeight); } cef_render_handler_t; #ifdef __cplusplus diff --git a/include/cef_render_handler.h b/include/cef_render_handler.h index 15c3a54536b455fdc7dc780e4769b5fa8b087140..df57d6a97ff2f5c872b5466d6e5a3360f3d5db81 100644 --- a/include/cef_render_handler.h +++ b/include/cef_render_handler.h @@ -211,7 +211,8 @@ class CefRenderHandler : public virtual CefBaseRefCounted { CefRefPtr drag_data, DragOperationsMask allowed_ops, int x, - int y) { + int y, + int visible_offset_y) { return false; } @@ -479,6 +480,12 @@ class CefRenderHandler : public virtual CefBaseRefCounted { /// /*--cef()--*/ virtual void OnAccessibilityEvent(int64_t accessibilityId, int32_t eventType) {} + + /// + /// Get the visible area relative to the web. + /// + /*--cef()--*/ + virtual void GetVisibleRectToWeb(int& visibleX, int& visibleY, int& visibleWidth, int& visibleHeight) {} #endif // BUILDFLAG(IS_OHOS) }; diff --git a/libcef/browser/osr/browser_platform_delegate_osr.cc b/libcef/browser/osr/browser_platform_delegate_osr.cc index 8ffbeff8750a510533dad88db24639738f55d67e..e94125aecb2300109b534a90dc0591a90909c2ad 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.cc +++ b/libcef/browser/osr/browser_platform_delegate_osr.cc @@ -779,6 +779,14 @@ void CefBrowserPlatformDelegateOsr::DragTargetDrop(const CefMouseEvent& event) { drag_data_ = nullptr; } +float ToOhCoordinate(float origin, float device_pixel_ratio) { + if (device_pixel_ratio > 0) { + return origin * device_pixel_ratio; + } + + return origin; +} + void CefBrowserPlatformDelegateOsr::StartDragging( const content::DropData& drop_data, blink::DragOperationsMask allowed_ops, @@ -793,8 +801,26 @@ void CefBrowserPlatformDelegateOsr::StartDragging( CefRefPtr handler = browser_->GetClient()->GetRenderHandler(); if (handler.get()) { +#ifdef OHOS_DRAG_DROP + float pixel_ratio = browser_->GetHost()->GetVirtualPixelRatio(); +#ifdef OHOS_EX_TOPCONTROLS + int shrink_viewport_height = 0; + if (CefRenderWidgetHostViewOSR* view = GetOSRHostView()) { + shrink_viewport_height = view->GetShrinkViewportHeight(); + } + auto location_x = event_info.location.x(); + auto location_y = event_info.location.y() + shrink_viewport_height; +#else + auto location_x = event_info.location.x(); + auto location_y = event_info.location.y(); +#endif + float drag_image_x = ToOhCoordinate(location_x - image_offset.x(), pixel_ratio); + float drag_image_y = ToOhCoordinate(location_y - image_offset.y(), pixel_ratio); +#endif + #ifdef OHOS_DRAG_DROP CefImageImpl* image_impl = nullptr; + int visible_y = 0; if (image.size().IsEmpty()) { // An empty drag image is possible if the Javascript sets an empty drag image on purpose. // Create a dummy 1x1 pixel image to avoid crashes when converting to cef bitmap. @@ -807,7 +833,27 @@ void CefBrowserPlatformDelegateOsr::StartDragging( image_impl->AddBitmap(1.0, dummy_bitmap); } } else { - image_impl = new (std::nothrow) CefImageImpl(image); + int visible_x = 0; + int visible_width = 0; + int visible_height = 0; + handler->GetVisibleRectToWeb(visible_x, visible_y, visible_width, visible_height); + LOG(INFO) << "drag StartDragging visible rect: " << visible_x << ", " << visible_y + << ", " << visible_width << ", " << visible_height; + const SkBitmap* image_bitmap = image.bitmap(); + if (visible_height > 0 && image_bitmap && drag_image_y + image_bitmap->height() > visible_height + pixel_ratio) { + gfx::Rect visible_rect(visible_x, visible_y, visible_width, visible_height); + gfx::Rect drag_rect(drag_image_x, drag_image_y, image_bitmap->width(), image_bitmap->height()); + gfx::Rect intersect_rect = gfx::IntersectRects(visible_rect, drag_rect); + auto cut_start_y = intersect_rect.y() - drag_rect.y() > 0 ? intersect_rect.y() - drag_rect.y() : 0; + auto cut_height = intersect_rect.height(); + SkBitmap clipped_bitmap; + image_bitmap->extractSubset(&clipped_bitmap, SkIRect::MakeXYWH(0, cut_start_y, image_bitmap->width(), cut_height)); + gfx::ImageSkia clipped_image = gfx::ImageSkia::CreateFromBitmap(clipped_bitmap, pixel_ratio); + image_impl = new (std::nothrow) CefImageImpl(clipped_image); + } else { + image_impl = new (std::nothrow) CefImageImpl(image); + visible_y = 0; + } } CefRefPtr cef_image(image_impl); #else @@ -818,16 +864,11 @@ void CefBrowserPlatformDelegateOsr::StartDragging( new CefDragDataImpl(drop_data, cef_image, cef_image_pos)); drag_data->SetReadOnly(true); base::CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop allow; -#ifdef OHOS_EX_TOPCONTROLS - int shrink_viewport_height = 0; - if (CefRenderWidgetHostViewOSR* view = GetOSRHostView()) { - shrink_viewport_height = view->GetShrinkViewportHeight(); - } +#ifdef OHOS_DRAG_DROP handled = handler->StartDragging( browser_, drag_data.get(), static_cast(allowed_ops), - event_info.location.x(), - event_info.location.y() + shrink_viewport_height); + location_x, location_y, visible_y); #else handled = handler->StartDragging( browser_, drag_data.get(), diff --git a/libcef_dll/cpptoc/render_handler_cpptoc.cc b/libcef_dll/cpptoc/render_handler_cpptoc.cc index d5f632c61867d7e94d538ab1c55c2ddd8bd6f98a..b2d6d94bef2e62e41b63f7a88fb23141632a12bf 100644 --- a/libcef_dll/cpptoc/render_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/render_handler_cpptoc.cc @@ -432,7 +432,8 @@ render_handler_start_dragging(struct _cef_render_handler_t* self, cef_drag_data_t* drag_data, cef_drag_operations_mask_t allowed_ops, int x, - int y) { + int y, + int visible_offset_y) { shutdown_checker::AssertNotShutdown(); // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -455,7 +456,7 @@ render_handler_start_dragging(struct _cef_render_handler_t* self, // Execute bool _retval = CefRenderHandlerCppToC::Get(self)->StartDragging( CefBrowserCToCpp::Wrap(browser), CefDragDataCToCpp::Wrap(drag_data), - allowed_ops, x, y); + allowed_ops, x, y, visible_offset_y); // Return type: bool return _retval; @@ -1412,6 +1413,73 @@ render_handler_on_accessibility_event(struct _cef_render_handler_t* self, CefRenderHandlerCppToC::Get(self)->OnAccessibilityEvent(accessibilityId, eventType); } +void CEF_CALLBACK +render_handler_get_visible_rect_to_web(struct _cef_render_handler_t* self, + int* visibleX, + int* visibleY, + int* visibleWidth, + int* visibleHeight) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) { + return; + } + + // Verify param: visibleX; type: simple_byref + DCHECK(visibleX); + if (!visibleX) { + return; + } + // Verify param: visibleY; type: simple_byref + DCHECK(visibleY); + if (!visibleY) { + return; + } + // Verify param: visibleWidth; type: simple_byref + DCHECK(visibleWidth); + if (!visibleWidth) { + return; + } + // Verify param: visibleHeight; type: simple_byref + DCHECK(visibleHeight); + if (!visibleHeight) { + return; + } + + // Translate param: visibleX; type: simple_byref + int visibleXVal = visibleX ? *visibleX : 0; + // Translate param: visibleY; type: simple_byref + int visibleYVal = visibleY ? *visibleY : 0; + // Translate param: visibleWidth; type: simple_byref + int visibleWidthVal = visibleWidth ? *visibleWidth : 0; + // Translate param: visibleHeight; type: simple_byref + int visibleHeightVal = visibleHeight ? *visibleHeight : 0; + + // Execute + CefRenderHandlerCppToC::Get(self)->GetVisibleRectToWeb(visibleXVal, visibleYVal, visibleWidthVal, + visibleHeightVal); + + // Restore param: visibleX; type: simple_byref + if (visibleX) { + *visibleX = visibleXVal; + } + // Restore param: visibleY; type: simple_byref + if (visibleY) { + *visibleY = visibleYVal; + } + // Restore param: visibleWidth; type: simple_byref + if (visibleWidth) { + *visibleWidth = visibleWidthVal; + } + // Restore param: visibleHeight; type: simple_byref + if (visibleHeight) { + *visibleHeight = visibleHeightVal; + } +} + } // namespace // CONSTRUCTOR - Do not edit by hand. @@ -1481,6 +1549,7 @@ CefRenderHandlerCppToC::CefRenderHandlerCppToC() { GetStruct()->start_vibra_feedback = render_handler_start_vibra_feedback; GetStruct()->get_device_pixel_size = render_handler_get_device_pixel_size; GetStruct()->on_accessibility_event = render_handler_on_accessibility_event; + GetStruct()->get_visible_rect_to_web = render_handler_get_visible_rect_to_web; } // DESTRUCTOR - Do not edit by hand. diff --git a/libcef_dll/ctocpp/render_handler_ctocpp.cc b/libcef_dll/ctocpp/render_handler_ctocpp.cc index d790e3d11e4fada94316528c1a401744df90f169..56e1f54e3ca3d0fb140bf62c269877b9e0c47cf4 100644 --- a/libcef_dll/ctocpp/render_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/render_handler_ctocpp.cc @@ -343,7 +343,8 @@ bool CefRenderHandlerCToCpp::StartDragging(CefRefPtr browser, CefRefPtr drag_data, DragOperationsMask allowed_ops, int x, - int y) { + int y, + int visible_offset_y) { shutdown_checker::AssertNotShutdown(); cef_render_handler_t* _struct = GetStruct(); @@ -367,7 +368,7 @@ bool CefRenderHandlerCToCpp::StartDragging(CefRefPtr browser, // Execute int _retval = _struct->start_dragging( _struct, CefBrowserCppToC::Wrap(browser), - CefDragDataCppToC::Wrap(drag_data), allowed_ops, x, y); + CefDragDataCppToC::Wrap(drag_data), allowed_ops, x, y, visible_offset_y); // Return type: bool return _retval ? true : false; @@ -1179,6 +1180,21 @@ void CefRenderHandlerCToCpp::OnAccessibilityEvent(int64_t accessibilityId, // Execute _struct->on_accessibility_event(_struct, accessibilityId, eventType); + +NO_SANITIZE("cfi-icall") +void CefRenderHandlerCToCpp::GetVisibleRectToWeb(int& visibleX, int& visibleY, int& visibleWidth, int& visibleHeight) { + shutdown_checker::AssertNotShutdown(); + + cef_render_handler_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_visible_rect_to_web)) { + return; + } + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + _struct->get_visible_rect_to_web(_struct, &visibleX, &visibleY, &visibleWidth, &visibleHeight); +} } // CONSTRUCTOR - Do not edit by hand. diff --git a/libcef_dll/ctocpp/render_handler_ctocpp.h b/libcef_dll/ctocpp/render_handler_ctocpp.h index 100156143cb122b95ca9ab809bb47fecb94671d2..952b0da8ae340f7078be936254ade1dee06186d2 100644 --- a/libcef_dll/ctocpp/render_handler_ctocpp.h +++ b/libcef_dll/ctocpp/render_handler_ctocpp.h @@ -66,7 +66,8 @@ class CefRenderHandlerCToCpp CefRefPtr drag_data, DragOperationsMask allowed_ops, int x, - int y) override; + int y, + int visible_offset_y) override; void UpdateDragCursor(CefRefPtr browser, DragOperation operation) override; void OnScrollOffsetChanged(CefRefPtr browser, @@ -147,6 +148,7 @@ class CefRenderHandlerCToCpp void GetDevicePixelSize(CefRefPtr browser, CefSize& size) override; void OnAccessibilityEvent(int64_t accessibilityId, int32_t eventType) override; + void GetVisibleRectToWeb(int& visibleX, int& visibleY, int& visibleWidth, int& visibleHeight) override; }; #endif // CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_