@@ -819,7 +819,6 @@ ELinuxWindowWayland::ELinuxWindowWayland(
819819 wl_data_device_ (nullptr ),
820820 wl_data_offer_ (nullptr ),
821821 wl_data_source_ (nullptr ),
822- wl_cursor_theme_ (nullptr ),
823822 serial_ (0 ),
824823 zwp_text_input_manager_v1_ (nullptr ),
825824 zwp_text_input_manager_v3_ (nullptr ),
@@ -834,6 +833,13 @@ ELinuxWindowWayland::ELinuxWindowWayland(
834833 view_properties.force_scale_factor ? view_properties.scale_factor : 1.0 ;
835834 SetRotation (view_properties_.view_rotation );
836835
836+ auto xcursor_size_string = std::getenv (kXcursorSizeEnvironmentKey );
837+ cursor_size_ =
838+ xcursor_size_string ? atoi (xcursor_size_string) : kDefaultPointerSize ;
839+ if (cursor_size_ <= 0 ) {
840+ cursor_size_ = kDefaultPointerSize ;
841+ }
842+
837843 wl_display_ = wl_display_connect (nullptr );
838844 if (!wl_display_) {
839845 ELINUX_LOG (ERROR) << " Failed to connect to the Wayland display." ;
@@ -889,10 +895,10 @@ ELinuxWindowWayland::~ELinuxWindowWayland() {
889895 display_valid_ = false ;
890896 running_ = false ;
891897
892- if (wl_cursor_theme_) {
893- wl_cursor_theme_destroy (wl_cursor_theme_);
894- wl_cursor_theme_ = nullptr ;
898+ for (auto theme : wl_cursor_themes_) {
899+ wl_cursor_theme_destroy (theme.second );
895900 }
901+ wl_cursor_themes_.clear ();
896902
897903 {
898904 if (zwp_text_input_v1_) {
@@ -1201,7 +1207,7 @@ void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) {
12011207 return ;
12021208 }
12031209
1204- auto wl_cursor = GetWlCursor (cursor_name);
1210+ auto wl_cursor = GetWlCursor (cursor_name, cursor_size_ * current_scale_ );
12051211 if (!wl_cursor) {
12061212 return ;
12071213 }
@@ -1213,6 +1219,7 @@ void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) {
12131219 image->hotspot_y );
12141220 wl_surface_attach (wl_cursor_surface_, buffer, 0 , 0 );
12151221 wl_surface_damage (wl_cursor_surface_, 0 , 0 , image->width , image->height );
1222+ wl_surface_set_buffer_scale (wl_cursor_surface_, current_scale_);
12161223 wl_surface_commit (wl_cursor_surface_);
12171224 }
12181225 }
@@ -1321,12 +1328,6 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry,
13211328 constexpr uint32_t kMaxVersion = 1 ;
13221329 wl_shm_ = static_cast <decltype (wl_shm_)>(
13231330 wl_registry_bind (wl_registry, name, &wl_shm_interface, kMaxVersion ));
1324- wl_cursor_theme_ = wl_cursor_theme_load (nullptr , 32 , wl_shm_);
1325- if (!wl_cursor_theme_) {
1326- ELINUX_LOG (ERROR) << " Failed to load cursor theme." ;
1327- return ;
1328- }
1329- CreateSupportedWlCursorList ();
13301331 }
13311332 return ;
13321333 }
@@ -1378,8 +1379,22 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry,
13781379void ELinuxWindowWayland::WlUnRegistryHandler (wl_registry* wl_registry,
13791380 uint32_t name) {}
13801381
1381- void ELinuxWindowWayland::CreateSupportedWlCursorList () {
1382- std::vector<std::string> wl_cursor_themes{
1382+ bool ELinuxWindowWayland::LoadCursorTheme (uint32_t size) {
1383+ if (!wl_shm_) {
1384+ ELINUX_LOG (ERROR) << " Failed to load cursor theme because shared memory "
1385+ " buffers are not available." ;
1386+ return false ;
1387+ }
1388+
1389+ auto theme = wl_cursor_theme_load (nullptr , size, wl_shm_);
1390+ if (!theme) {
1391+ ELINUX_LOG (ERROR) << " Failed to load cursor theme for size: " << size;
1392+ return false ;
1393+ }
1394+
1395+ wl_cursor_themes_[size] = theme;
1396+
1397+ std::vector<std::string> wl_cursor_names{
13831398 kWlCursorThemeLeftPtr ,
13841399 kWlCursorThemeBottomLeftCorner ,
13851400 kWlCursorThemeBottomRightCorner ,
@@ -1395,18 +1410,24 @@ void ELinuxWindowWayland::CreateSupportedWlCursorList() {
13951410 kWlCursorThemeWatch ,
13961411 };
13971412
1398- for (const auto & theme : wl_cursor_themes) {
1399- auto wl_cursor =
1400- wl_cursor_theme_get_cursor (wl_cursor_theme_, theme.c_str ());
1413+ std::unordered_map<std::string, wl_cursor*> cursor_list;
1414+
1415+ for (const auto & cursor_name : wl_cursor_names) {
1416+ auto wl_cursor = wl_cursor_theme_get_cursor (theme, cursor_name.c_str ());
14011417 if (!wl_cursor) {
1402- ELINUX_LOG (ERROR) << " Unsupported cursor theme: " << theme .c_str ();
1418+ ELINUX_LOG (ERROR) << " Unsupported cursor theme: " << cursor_name .c_str ();
14031419 continue ;
14041420 }
1405- supported_wl_cursor_list_[theme ] = wl_cursor;
1421+ cursor_list[cursor_name ] = wl_cursor;
14061422 }
1423+
1424+ supported_wl_cursor_list_.insert (std::make_pair (size, cursor_list));
1425+
1426+ return true ;
14071427}
14081428
1409- wl_cursor* ELinuxWindowWayland::GetWlCursor (const std::string& cursor_name) {
1429+ wl_cursor* ELinuxWindowWayland::GetWlCursor (const std::string& cursor_name,
1430+ uint32_t size) {
14101431 // Convert the cursor theme name from Flutter's cursor value to Wayland's one.
14111432 // However, Wayland has not all cursor themes corresponding to Flutter.
14121433 // If there is no Wayland's cursor theme corresponding to the Flutter's cursor
@@ -1450,17 +1471,24 @@ wl_cursor* ELinuxWindowWayland::GetWlCursor(const std::string& cursor_name) {
14501471 {" zoomOut" , " " },
14511472 };
14521473
1474+ if (supported_wl_cursor_list_.find (size) == supported_wl_cursor_list_.end ()) {
1475+ if (!LoadCursorTheme (size)) {
1476+ return nullptr ;
1477+ }
1478+ }
1479+
1480+ auto cursor_list = supported_wl_cursor_list_.at (size);
1481+
14531482 if (flutter_to_wayland_cursor_map.find (cursor_name) !=
14541483 flutter_to_wayland_cursor_map.end ()) {
14551484 auto theme = flutter_to_wayland_cursor_map.at (cursor_name);
1456- if (!theme.empty () && supported_wl_cursor_list_.find (theme) !=
1457- supported_wl_cursor_list_.end ()) {
1458- return supported_wl_cursor_list_[theme];
1485+ if (!theme.empty () && cursor_list.find (theme) != cursor_list.end ()) {
1486+ return cursor_list[theme];
14591487 }
14601488 }
14611489
14621490 ELINUX_LOG (ERROR) << " Unsupported cursor: " << cursor_name.c_str ();
1463- return supported_wl_cursor_list_ [kWlCursorThemeLeftPtr ];
1491+ return cursor_list [kWlCursorThemeLeftPtr ];
14641492}
14651493
14661494void ELinuxWindowWayland::ShowVirtualKeyboard () {
0 commit comments