Skip to content

Commit 3aaff94

Browse files
committed
Add HighDPI support for Wayland
Signed-off-by: Valentin Hăloiu <valentin.haloiu@gmail.com>
1 parent 5316c72 commit 3aaff94

12 files changed

+99
-38
lines changed

src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ enum FlutterDesktopViewRotation {
7676

7777
// Properties for configuring a Flutter view instance.
7878
typedef struct {
79-
// View width.
79+
// View width in logical pixels.
8080
int width;
8181

82-
// View height.
82+
// View height in logical pixels.
8383
int height;
8484

8585
// View rotation setting.

src/flutter/shell/platform/linux_embedded/window/elinux_window.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ class ELinuxWindow {
1818
virtual bool IsValid() const = 0;
1919

2020
// Get current window width in physical pixels.
21-
uint32_t GetCurrentWidth() const { return view_properties_.width; }
21+
uint32_t GetCurrentWidth() const {
22+
return view_properties_.width * current_scale_;
23+
}
2224

2325
// Get current window height in physical pixels.
24-
uint32_t GetCurrentHeight() const { return view_properties_.height; }
26+
uint32_t GetCurrentHeight() const {
27+
return view_properties_.height * current_scale_;
28+
}
2529

2630
void SetRotation(FlutterDesktopViewRotation rotation) {
2731
if (rotation == FlutterDesktopViewRotation::kRotation_90) {

src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,14 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = {
135135
self->view_properties_.width = next_width;
136136
self->view_properties_.height = next_height;
137137
if (self->window_decorations_) {
138-
self->window_decorations_->Resize(next_width, next_height);
138+
self->window_decorations_->Resize(next_width, next_height,
139+
self->current_scale_);
139140
}
140141
if (self->binding_handler_delegate_) {
141142
self->binding_handler_delegate_->OnWindowSizeChanged(
142-
next_width,
143-
next_height - self->WindowDecorationsPhysicalHeight());
143+
next_width * self->current_scale_,
144+
next_height * self->current_scale_ -
145+
self->WindowDecorationsPhysicalHeight());
144146
}
145147
},
146148
.close =
@@ -313,11 +315,11 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = {
313315
}
314316

315317
if (self->binding_handler_delegate_) {
316-
double x = wl_fixed_to_double(surface_x);
317-
double y = wl_fixed_to_double(surface_y);
318-
self->binding_handler_delegate_->OnPointerMove(x, y);
319-
self->pointer_x_ = x;
320-
self->pointer_y_ = y;
318+
double x_px = wl_fixed_to_double(surface_x) * self->current_scale_;
319+
double y_px = wl_fixed_to_double(surface_y) * self->current_scale_;
320+
self->binding_handler_delegate_->OnPointerMove(x_px, y_px);
321+
self->pointer_x_ = x_px;
322+
self->pointer_y_ = y_px;
321323
}
322324
},
323325
.leave = [](void* data,
@@ -347,11 +349,11 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = {
347349
wl_fixed_t surface_y) -> void {
348350
auto self = reinterpret_cast<ELinuxWindowWayland*>(data);
349351
if (self->binding_handler_delegate_) {
350-
double x = wl_fixed_to_double(surface_x);
351-
double y = wl_fixed_to_double(surface_y);
352-
self->binding_handler_delegate_->OnPointerMove(x, y);
353-
self->pointer_x_ = x;
354-
self->pointer_y_ = y;
352+
double x_px = wl_fixed_to_double(surface_x) * self->current_scale_;
353+
double y_px = wl_fixed_to_double(surface_y) * self->current_scale_;
354+
self->binding_handler_delegate_->OnPointerMove(x_px, y_px);
355+
self->pointer_x_ = x_px;
356+
self->pointer_y_ = y_px;
355357
}
356358
},
357359
.button = [](void* data,
@@ -604,7 +606,10 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = {
604606
self->view_properties_.height = height;
605607

606608
if (self->window_decorations_) {
607-
self->window_decorations_->Resize(width, height);
609+
int32_t width_dip = width / self->current_scale_;
610+
int32_t height_dip = height / self->current_scale_;
611+
self->window_decorations_->Resize(width_dip, height_dip,
612+
self->current_scale_);
608613
}
609614

610615
if (self->binding_handler_delegate_) {
@@ -1158,8 +1163,8 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px,
11581163
}
11591164

11601165
if (view_properties_.view_mode == FlutterDesktopViewMode::kFullscreen) {
1161-
width_px = view_properties_.width;
1162-
height_px = view_properties_.height;
1166+
width_px = view_properties_.width * current_scale_;
1167+
height_px = view_properties_.height * current_scale_;
11631168
}
11641169

11651170
ELINUX_LOG(TRACE) << "Created the Wayland surface: " << width_px << "x"
@@ -1192,6 +1197,7 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px,
11921197
xdg_toplevel_ = xdg_surface_get_toplevel(xdg_surface_);
11931198
xdg_toplevel_set_title(xdg_toplevel_, "Flutter");
11941199
xdg_toplevel_add_listener(xdg_toplevel_, &kXdgToplevelListener, this);
1200+
wl_surface_set_buffer_scale(native_window_->Surface(), current_scale_);
11951201
wl_surface_commit(native_window_->Surface());
11961202

11971203
{
@@ -1211,9 +1217,11 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px,
12111217
render_surface_->SetNativeWindow(native_window_.get());
12121218

12131219
if (view_properties_.use_window_decoration) {
1220+
int32_t width_dip = width_px / current_scale_;
1221+
int32_t height_dip = height_px / current_scale_;
12141222
window_decorations_ = std::make_unique<WindowDecorationsWayland>(
12151223
wl_display_, wl_compositor_, wl_subcompositor_,
1216-
native_window_->Surface(), width_px, height_px);
1224+
native_window_->Surface(), width_dip, height_dip, current_scale_);
12171225
}
12181226

12191227
return true;
@@ -1604,10 +1612,18 @@ void ELinuxWindowWayland::UpdateWindowScale() {
16041612
ELINUX_LOG(TRACE) << "Window scale has changed: " << scale_factor;
16051613
this->current_scale_ = scale_factor;
16061614

1615+
wl_surface_set_buffer_scale(native_window_->Surface(), current_scale_);
1616+
1617+
if (this->window_decorations_) {
1618+
this->window_decorations_->Resize(this->view_properties_.width,
1619+
this->view_properties_.height,
1620+
this->current_scale_);
1621+
}
1622+
16071623
if (this->binding_handler_delegate_) {
16081624
this->binding_handler_delegate_->OnWindowSizeChanged(
1609-
this->view_properties_.width,
1610-
this->view_properties_.height -
1625+
this->view_properties_.width * this->current_scale_,
1626+
this->view_properties_.height * this->current_scale_ -
16111627
this->WindowDecorationsPhysicalHeight());
16121628
}
16131629
}

src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,13 @@ void NativeWindowWaylandDecoration::SetPosition(const int32_t x_dip,
7777
wl_subsurface_set_position(subsurface_, x_dip, y_dip);
7878
}
7979

80+
void NativeWindowWaylandDecoration::SetScaleFactor(float scale_factor) {
81+
if (!valid_) {
82+
ELINUX_LOG(ERROR) << "Failed to set the scale factor of the window.";
83+
return;
84+
}
85+
86+
wl_surface_set_buffer_scale(surface_, scale_factor);
87+
}
88+
8089
} // namespace flutter

src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class NativeWindowWaylandDecoration : public NativeWindow {
2929
// |NativeWindow|
3030
void SetPosition(const int32_t x_dip, const int32_t y_dip) override;
3131

32+
// Sets the scale factor for the next commit. Scale factor persists until a
33+
// new one is set.
34+
void SetScaleFactor(float scale_factor);
35+
3236
wl_surface* Surface() const { return surface_; }
3337

3438
private:

src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class WindowDecoration {
3636
// @param[in] height_px Physical height of the window.
3737
virtual void Resize(const size_t width_px, const size_t height_px) = 0;
3838

39+
// Sets the scale factor for the next commit. Scale factor persists until a
40+
// new one is set.
41+
virtual void SetScaleFactor(float scale_factor) = 0;
42+
3943
void DestroyContext() const { render_surface_->DestroyContext(); };
4044

4145
wl_surface* Surface() const { return native_window_->Surface(); };

src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ void WindowDecorationButton::Resize(const size_t width_px,
208208
render_surface_->Resize(width_px, height_px);
209209
}
210210

211+
void WindowDecorationButton::SetScaleFactor(float scale_factor) {
212+
native_window_->SetScaleFactor(scale_factor);
213+
}
214+
211215
void WindowDecorationButton::LoadShader() {
212216
if (shader_) {
213217
return;

src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class WindowDecorationButton : public WindowDecoration {
2626
// |WindowDecoration|
2727
void Resize(const size_t width_px, const size_t height_px) override;
2828

29+
// |WindowDecoration|
30+
void SetScaleFactor(float scale_factor) override;
31+
2932
private:
3033
void LoadShader();
3134

src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,8 @@ void WindowDecorationTitlebar::Resize(const size_t width_px,
7979
render_surface_->Resize(width_px, height_px);
8080
}
8181

82+
void WindowDecorationTitlebar::SetScaleFactor(float scale_factor) {
83+
native_window_->SetScaleFactor(scale_factor);
84+
}
85+
8286
} // namespace flutter

src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class WindowDecorationTitlebar : public WindowDecoration {
2323

2424
// |WindowDecoration|
2525
void Resize(const size_t width_px, const size_t height_px) override;
26+
27+
// |WindowDecoration|
28+
void SetScaleFactor(float scale_factor) override;
2629
};
2730

2831
} // namespace flutter

src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ WindowDecorationsWayland::WindowDecorationsWayland(
2323
wl_subcompositor* subcompositor,
2424
wl_surface* root_surface,
2525
int32_t width_dip,
26-
int32_t height_dip) {
26+
int32_t height_dip,
27+
double pixel_ratio) {
2728
constexpr bool sub_egl_display = true;
2829

2930
// title-bar.
3031
titlebar_ = std::make_unique<WindowDecorationTitlebar>(
31-
std::make_unique<NativeWindowWaylandDecoration>(compositor, subcompositor,
32-
root_surface, width_dip,
33-
kTitleBarHeightDIP),
32+
std::make_unique<NativeWindowWaylandDecoration>(
33+
compositor, subcompositor, root_surface, width_dip * pixel_ratio,
34+
kTitleBarHeightDIP * pixel_ratio),
3435
std::make_unique<SurfaceDecoration>(std::make_unique<ContextEgl>(
3536
std::make_unique<EnvironmentEgl>(display, sub_egl_display))));
3637
titlebar_->SetPosition(0, -kTitleBarHeightDIP);
@@ -40,8 +41,8 @@ WindowDecorationsWayland::WindowDecorationsWayland(
4041
buttons_.push_back(std::make_unique<WindowDecorationButton>(
4142
type,
4243
std::make_unique<NativeWindowWaylandDecoration>(
43-
compositor, subcompositor, root_surface, kButtonWidthDIP,
44-
kButtonHeightDIP),
44+
compositor, subcompositor, root_surface,
45+
kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio),
4546
std::make_unique<SurfaceDecoration>(std::make_unique<ContextEgl>(
4647
std::make_unique<EnvironmentEgl>(display, sub_egl_display)))));
4748
buttons_[type]->SetPosition(
@@ -53,8 +54,8 @@ WindowDecorationsWayland::WindowDecorationsWayland(
5354
buttons_.push_back(std::make_unique<WindowDecorationButton>(
5455
type,
5556
std::make_unique<NativeWindowWaylandDecoration>(
56-
compositor, subcompositor, root_surface, kButtonWidthDIP,
57-
kButtonHeightDIP),
57+
compositor, subcompositor, root_surface,
58+
kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio),
5859
std::make_unique<SurfaceDecoration>(std::make_unique<ContextEgl>(
5960
std::make_unique<EnvironmentEgl>(display, sub_egl_display)))));
6061
buttons_[type]->SetPosition(
@@ -66,8 +67,8 @@ WindowDecorationsWayland::WindowDecorationsWayland(
6667
buttons_.push_back(std::make_unique<WindowDecorationButton>(
6768
type,
6869
std::make_unique<NativeWindowWaylandDecoration>(
69-
compositor, subcompositor, root_surface, kButtonWidthDIP,
70-
kButtonHeightDIP),
70+
compositor, subcompositor, root_surface,
71+
kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio),
7172
std::make_unique<SurfaceDecoration>(std::make_unique<ContextEgl>(
7273
std::make_unique<EnvironmentEgl>(display, sub_egl_display)))));
7374
buttons_[type]->SetPosition(
@@ -91,15 +92,19 @@ void WindowDecorationsWayland::Draw() {
9192
}
9293

9394
void WindowDecorationsWayland::Resize(const int32_t width_dip,
94-
const int32_t height_dip) {
95+
const int32_t height_dip,
96+
double pixel_ratio) {
97+
titlebar_->SetScaleFactor(pixel_ratio);
9598
titlebar_->SetPosition(0, -kTitleBarHeightDIP);
96-
titlebar_->Resize(width_dip, kTitleBarHeightDIP);
99+
titlebar_->Resize(width_dip * pixel_ratio, kTitleBarHeightDIP * pixel_ratio);
97100

98101
for (auto i = 0; i < buttons_.size(); i++) {
102+
buttons_[i]->SetScaleFactor(pixel_ratio);
99103
buttons_[i]->SetPosition(
100104
width_dip - kButtonWidthDIP * (i + 1) - kButtonMarginDIP * (i + 1),
101105
-(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2));
102-
buttons_[i]->Resize(kButtonWidthDIP, kButtonHeightDIP);
106+
buttons_[i]->Resize(kButtonWidthDIP * pixel_ratio,
107+
kButtonHeightDIP * pixel_ratio);
103108
}
104109
}
105110

src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,24 @@ class WindowDecorationsWayland {
2828
public:
2929
// @param[in] width_dip Logical width of the window (i.e. surface width).
3030
// @param[in] height_dip Logical height of the window (i.e. surface height).
31+
// @param[in] pixel_ratio Physical / logical pixels ratio.
3132
WindowDecorationsWayland(wl_display* display,
3233
wl_compositor* compositor,
3334
wl_subcompositor* subcompositor,
3435
wl_surface* root_surface,
3536
int32_t width_dip,
36-
int32_t height_dip);
37+
int32_t height_dip,
38+
double pixel_ratio);
3739
~WindowDecorationsWayland();
3840

3941
void Draw();
4042

4143
// @param[in] width_dip Logical width of the window (i.e. surface width).
4244
// @param[in] height_dip Logical height of the window (i.e. surface height).
43-
void Resize(const int32_t width_dip, const int32_t height_dip);
45+
// @param[in] pixel_ratio Physical / logical pixels ratio.
46+
void Resize(const int32_t width_dip,
47+
const int32_t height_dip,
48+
double pixel_ratio);
4449

4550
bool IsMatched(wl_surface* surface,
4651
WindowDecoration::DecorationType decoration_type) const;

0 commit comments

Comments
 (0)