@@ -148,6 +148,40 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = {
148148 self->running_ = false ;
149149 }};
150150
151+ const wl_surface_listener ELinuxWindowWayland::kWlSurfaceListener = {
152+ .enter =
153+ [](void * data, wl_surface* wl_surface, wl_output* output) {
154+ // The compositor can send a null output: crbug.com/1332540
155+ if (!output) {
156+ ELINUX_LOG (ERROR) << " cannot enter a NULL output" ;
157+ return ;
158+ }
159+
160+ const uint32_t output_id =
161+ wl_proxy_get_id (reinterpret_cast <wl_proxy*>(output));
162+ ELINUX_LOG (TRACE) << " window entered output " << output_id;
163+ auto self = reinterpret_cast <ELinuxWindowWayland*>(data);
164+
165+ self->entered_outputs_ .insert (output_id);
166+ self->UpdateWindowScale ();
167+ },
168+ .leave =
169+ [](void * data, wl_surface* wl_surface, wl_output* output) {
170+ // The compositor can send a null output: crbug.com/1332540
171+ if (!output) {
172+ ELINUX_LOG (ERROR) << " cannot leave a NULL output" ;
173+ return ;
174+ }
175+
176+ const uint32_t output_id =
177+ wl_proxy_get_id (reinterpret_cast <wl_proxy*>(output));
178+ ELINUX_LOG (TRACE) << " window left output " << output_id;
179+ auto self = reinterpret_cast <ELinuxWindowWayland*>(data);
180+
181+ self->entered_outputs_ .erase (output_id);
182+ self->UpdateWindowScale ();
183+ }};
184+
151185const wp_presentation_listener ELinuxWindowWayland::kWpPresentationListener = {
152186 .clock_id =
153187 [](void * data, wp_presentation* wp_presentation, uint32_t clk_id) {
@@ -570,9 +604,16 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = {
570604 .done = [](void * data, wl_output* wl_output) -> void {},
571605 .scale = [](void * data, wl_output* wl_output, int32_t scale) -> void {
572606 auto self = reinterpret_cast <ELinuxWindowWayland*>(data);
573- ELINUX_LOG (INFO) << " Display output scale: " << scale;
574- if (!self->view_properties_ .force_scale_factor )
575- self->current_scale_ = scale;
607+
608+ const uint32_t output_id =
609+ wl_proxy_get_id (reinterpret_cast <wl_proxy*>(wl_output));
610+
611+ ELINUX_LOG (INFO) << " Display scale for output(" << output_id
612+ << " ): " << scale;
613+
614+ self->wl_output_scale_factors_ [output_id] = scale;
615+
616+ self->UpdateWindowScale ();
576617 },
577618};
578619
@@ -1125,6 +1166,8 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) {
11251166 native_window_ =
11261167 std::make_unique<NativeWindowWayland>(wl_compositor_, width, height);
11271168
1169+ wl_surface_add_listener (native_window_->Surface (), &kWlSurfaceListener , this );
1170+
11281171 xdg_surface_ =
11291172 xdg_wm_base_get_xdg_surface (xdg_wm_base_, native_window_->Surface ());
11301173 if (!xdg_surface_) {
@@ -1527,4 +1570,31 @@ void ELinuxWindowWayland::DismissVirtualKeybaord() {
15271570 }
15281571}
15291572
1573+ void ELinuxWindowWayland::UpdateWindowScale () {
1574+ if (this ->view_properties_ .force_scale_factor )
1575+ return ;
1576+
1577+ double scale_factor = 1.0 ;
1578+ for (auto output_id : entered_outputs_) {
1579+ if (wl_output_scale_factors_.find (output_id) ==
1580+ wl_output_scale_factors_.end ())
1581+ continue ;
1582+
1583+ auto output_scale_factor = wl_output_scale_factors_.at (output_id);
1584+ if (output_scale_factor > scale_factor)
1585+ scale_factor = output_scale_factor;
1586+ }
1587+
1588+ if (this ->current_scale_ == scale_factor)
1589+ return ;
1590+
1591+ ELINUX_LOG (TRACE) << " Window scale has changed: " << scale_factor;
1592+ this ->current_scale_ = scale_factor;
1593+
1594+ if (this ->binding_handler_delegate_ ) {
1595+ this ->binding_handler_delegate_ ->OnWindowSizeChanged (
1596+ this ->view_properties_ .width , this ->view_properties_ .height );
1597+ }
1598+ }
1599+
15301600} // namespace flutter
0 commit comments