Skip to content

Commit 935c89a

Browse files
authored
Match IntelliJ's zoom setting in the embedded DevTools panels (#7933)
1 parent d5ac6ac commit 935c89a

File tree

8 files changed

+98
-39
lines changed

8 files changed

+98
-39
lines changed

flutter-idea/src/io/flutter/devtools/DevToolsUrl.java

-18
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public class DevToolsUrl {
2525
public String colorHexCode;
2626
public Boolean isBright;
2727
public String widgetId;
28-
public Float fontSize;
2928
public String hide;
3029
private final FlutterSdkVersion flutterSdkVersion;
3130
private final FlutterSdkUtil sdkUtil;
@@ -45,7 +44,6 @@ public static class Builder {
4544
private String page;
4645
private Boolean embed;
4746
private String widgetId;
48-
private Float fontSize;
4947
private String hide;
5048

5149
private FlutterSdkVersion flutterSdkVersion;
@@ -88,11 +86,6 @@ public Builder setWidgetId(String widgetId) {
8886
return this;
8987
}
9088

91-
public Builder setFontSize(Float fontSize) {
92-
this.fontSize = fontSize;
93-
return this;
94-
}
95-
9689
public Builder setHide(String hide) {
9790
this.hide = hide;
9891
return this;
@@ -147,7 +140,6 @@ private DevToolsUrl(Builder builder) {
147140
if (builder.embed) {
148141
this.colorHexCode = builder.devToolsUtils.getColorHexCode();
149142
this.isBright = builder.devToolsUtils.getIsBackgroundBright();
150-
this.fontSize = builder.devToolsUtils.getFontSize();
151143
}
152144
this.hide = builder.hide;
153145
this.widgetId = builder.widgetId;
@@ -196,9 +188,6 @@ public String getUrlString() {
196188
}
197189
}
198190
}
199-
if (fontSize != null) {
200-
params.add("fontSize=" + fontSize);
201-
}
202191
if (ideFeature != null) {
203192
params.add("ideFeature=" + ideFeature.value);
204193
}
@@ -226,11 +215,4 @@ public void maybeUpdateColor() {
226215
colorHexCode = newColor;
227216
isBright = devToolsUtils.getIsBackgroundBright();
228217
}
229-
230-
public void maybeUpdateFontSize() {
231-
final Float newFontSize = devToolsUtils.getFontSize();
232-
if (fontSize == null || !fontSize.equals(newFontSize)) {
233-
fontSize = newFontSize;
234-
}
235-
}
236218
}

flutter-idea/src/io/flutter/jxbrowser/EmbeddedJxBrowser.java

+21
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,15 @@
2525
import io.flutter.settings.FlutterSettings;
2626
import io.flutter.utils.AsyncUtils;
2727
import io.flutter.utils.JxBrowserUtils;
28+
import io.flutter.utils.ZoomLevelSelector;
2829
import io.flutter.view.EmbeddedBrowser;
2930
import io.flutter.view.EmbeddedTab;
3031
import io.flutter.utils.LabelInput;
3132
import org.jetbrains.annotations.NotNull;
3233
import org.jetbrains.annotations.Nullable;
34+
import com.teamdev.jxbrowser.zoom.Zoom;
35+
import com.teamdev.jxbrowser.zoom.ZoomLevel;
36+
import com.intellij.ide.ui.UISettingsUtils;
3337

3438
import javax.swing.*;
3539
import java.awt.*;
@@ -43,13 +47,16 @@
4347
class EmbeddedJxBrowserTab implements EmbeddedTab {
4448
private final Engine engine;
4549
private Browser browser;
50+
private Zoom zoom;
51+
private final ZoomLevelSelector zoomSelector = new ZoomLevelSelector();
4652
private static final Logger LOG = Logger.getInstance(EmbeddedJxBrowserTab.class);
4753

4854
public EmbeddedJxBrowserTab(Engine engine) {
4955
this.engine = engine;
5056

5157
try {
5258
this.browser = engine.newBrowser();
59+
this.zoom = this.browser.zoom();
5360
this.browser.settings().enableTransparentBackground();
5461
this.browser.on(ConsoleMessageReceived.class, event -> {
5562
final ConsoleMessage consoleMessage = event.consoleMessage();
@@ -74,6 +81,20 @@ public void close() {
7481
this.browser.close();
7582
}
7683

84+
@Override
85+
public void matchIdeZoom() {
86+
if (this.zoom != null) {
87+
final ZoomLevel zoomLevel = zoomSelector.getClosestZoomLevel(getIdeZoomPercent());
88+
this.zoom.level(zoomLevel);
89+
}
90+
}
91+
92+
private int getIdeZoomPercent() {
93+
final UISettingsUtils uiSettingsUtils = UISettingsUtils.getInstance();
94+
final float ideScale = uiSettingsUtils.getCurrentIdeScale();
95+
return Math.round(ideScale * 100);
96+
}
97+
7798
@Override
7899
public JComponent getTabComponent(ContentManager contentManager) {
79100
// Creating Swing component for rendering web content
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2025 The Chromium Authors. All rights reserved.
3+
* Use of this source code is governed by a BSD-style license that can be
4+
* found in the LICENSE file.
5+
*/
6+
package io.flutter.utils;
7+
8+
import com.teamdev.jxbrowser.zoom.ZoomLevel;
9+
import org.jetbrains.annotations.NotNull;
10+
11+
import java.util.Map;
12+
13+
import static java.util.Map.entry;
14+
15+
public class ZoomLevelSelector {
16+
@NotNull final Map<Integer, ZoomLevel> zoomLevels = Map.ofEntries(
17+
entry(25, ZoomLevel.P_25),
18+
entry(33, ZoomLevel.P_33),
19+
entry(50, ZoomLevel.P_50),
20+
entry(67, ZoomLevel.P_67),
21+
entry(75, ZoomLevel.P_75),
22+
entry(80, ZoomLevel.P_80),
23+
entry(90, ZoomLevel.P_90),
24+
entry(100, ZoomLevel.P_100),
25+
entry(110, ZoomLevel.P_110),
26+
entry(125, ZoomLevel.P_125),
27+
entry(150, ZoomLevel.P_150),
28+
entry(175, ZoomLevel.P_175),
29+
entry(200, ZoomLevel.P_200),
30+
entry(250, ZoomLevel.P_250),
31+
entry(300, ZoomLevel.P_300),
32+
entry(400, ZoomLevel.P_400),
33+
entry(500, ZoomLevel.P_500)
34+
);
35+
36+
public @NotNull ZoomLevel getClosestZoomLevel(int zoomPercent) {
37+
ZoomLevel closest = ZoomLevel.P_100;
38+
int minDifference = Integer.MAX_VALUE;
39+
40+
for (Map.Entry<Integer, ZoomLevel> entry : zoomLevels.entrySet()) {
41+
int currentDifference = Math.abs(zoomPercent - entry.getKey());
42+
if (currentDifference < minDifference) {
43+
minDifference = currentDifference;
44+
closest = entry.getValue();
45+
}
46+
}
47+
48+
return closest;
49+
}}

flutter-idea/src/io/flutter/view/EmbeddedBrowser.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ public void openPanel(ToolWindow toolWindow, String tabName, DevToolsUrl devTool
140140
tab.content.setIcon(FlutterIcons.Phone);
141141
tab.contentManager.addContent(tab.content);
142142
tab.contentManager.setSelectedContent(tab.content, true);
143+
tab.embeddedTab.matchIdeZoom();
143144
});
144145
}
145146

@@ -262,8 +263,8 @@ public void refresh(String toolWindowId) {
262263
tab.devToolsUrlFuture.thenAccept(devToolsUrl -> {
263264
if (devToolsUrl == null) return;
264265
devToolsUrl.maybeUpdateColor();
265-
devToolsUrl.maybeUpdateFontSize();
266266
tab.embeddedTab.loadUrl(devToolsUrl.getUrlString());
267+
tab.embeddedTab.matchIdeZoom();
267268
});
268269
});
269270
}
@@ -290,6 +291,7 @@ private void updateUrlAndReload(Function<DevToolsUrl, DevToolsUrl> newDevToolsUr
290291
return;
291292
}
292293
tab.embeddedTab.loadUrl(devToolsUrl.getUrlString());
294+
tab.embeddedTab.matchIdeZoom();
293295
});
294296
});
295297
});

flutter-idea/src/io/flutter/view/EmbeddedJcefBrowser.java

+5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public void close() {
3333

3434
}
3535

36+
@Override
37+
public void matchIdeZoom() {
38+
39+
}
40+
3641
@Override
3742
public JComponent getTabComponent(ContentManager contentManager) {
3843
browser.getComponent().setPreferredSize(new Dimension(contentManager.getComponent().getWidth(), contentManager.getComponent().getHeight()));

flutter-idea/src/io/flutter/view/EmbeddedTab.java

+2
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ public interface EmbeddedTab {
1414

1515
void close();
1616

17+
void matchIdeZoom();
18+
1719
JComponent getTabComponent(ContentManager contentManager);
1820
}

flutter-idea/testSrc/unit/io/flutter/FlutterUtilsTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
*/
66
package io.flutter;
77

8+
import com.teamdev.jxbrowser.zoom.ZoomLevel;
9+
import io.flutter.utils.ZoomLevelSelector;
810
import org.junit.Test;
911

1012
import static io.flutter.FlutterUtils.isValidDartIdentifier;
1113
import static io.flutter.FlutterUtils.isValidPackageName;
1214
import static org.junit.Assert.assertFalse;
15+
import static org.junit.Assert.assertSame;
1316
import static org.junit.Assert.assertTrue;
1417

1518
public class FlutterUtilsTest {
@@ -39,4 +42,19 @@ public void validPackageNames() {
3942
assertFalse("expected " + name + " to be invalid", isValidPackageName(name));
4043
}
4144
}
45+
46+
@Test
47+
public void zoomLevelSelector() {
48+
final ZoomLevelSelector zoomLevelSelector = new ZoomLevelSelector();
49+
assertSame(zoomLevelSelector.getClosestZoomLevel(-70), ZoomLevel.P_25);
50+
assertSame(zoomLevelSelector.getClosestZoomLevel(-10), ZoomLevel.P_25);
51+
assertSame(zoomLevelSelector.getClosestZoomLevel(0), ZoomLevel.P_25);
52+
assertSame(zoomLevelSelector.getClosestZoomLevel(1), ZoomLevel.P_25);
53+
assertSame(zoomLevelSelector.getClosestZoomLevel(20), ZoomLevel.P_25);
54+
assertSame(zoomLevelSelector.getClosestZoomLevel(28), ZoomLevel.P_25);
55+
assertSame(zoomLevelSelector.getClosestZoomLevel(35), ZoomLevel.P_33);
56+
assertSame(zoomLevelSelector.getClosestZoomLevel(222), ZoomLevel.P_200);
57+
assertSame(zoomLevelSelector.getClosestZoomLevel(226), ZoomLevel.P_250);
58+
assertSame(zoomLevelSelector.getClosestZoomLevel(700), ZoomLevel.P_500);
59+
}
4260
}

flutter-idea/testSrc/unit/io/flutter/devtools/DevToolsUrlTest.java

-20
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public void testGetUrlStringWithoutColor() {
3434
final DevToolsUtils noColorUtils = mock(DevToolsUtils.class);
3535
when(noColorUtils.getColorHexCode()).thenReturn(null);
3636
when(noColorUtils.getIsBackgroundBright()).thenReturn(null);
37-
when(noColorUtils.getFontSize()).thenReturn(null);
3837

3938
assertEquals(
4039
"http://127.0.0.1:9100/timeline?ide=IntelliJ-IDEA&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
@@ -163,7 +162,6 @@ public final void testGetUrlStringWithColor() {
163162
final DevToolsUtils lightUtils = mock(DevToolsUtils.class);
164163
when(lightUtils.getColorHexCode()).thenReturn("ffffff");
165164
when(lightUtils.getIsBackgroundBright()).thenReturn(true);
166-
when(lightUtils.getFontSize()).thenReturn(null);
167165

168166
assertEquals(
169167
"http://127.0.0.1:9100/timeline?ide=IntelliJ-IDEA&backgroundColor=ffffff&theme=light&embed=true&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
@@ -181,29 +179,11 @@ public final void testGetUrlStringWithColor() {
181179
.getUrlString()
182180
);
183181

184-
when(lightUtils.getFontSize()).thenReturn(12f);
185-
assertEquals(
186-
"http://127.0.0.1:9100/timeline?ide=IntelliJ-IDEA&backgroundColor=ffffff&theme=light&embed=true&fontSize=12.0&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
187-
new DevToolsUrl.Builder()
188-
.setDevToolsHost(devtoolsHost)
189-
.setDevToolsPort(devtoolsPort)
190-
.setVmServiceUri(serviceProtocolUri)
191-
.setEmbed(true)
192-
.setPage(page)
193-
.setFlutterSdkVersion(newVersion)
194-
.setWorkspaceCache(notBazelWorkspaceCache)
195-
.setFlutterSdkUtil(mockSdkUtil)
196-
.setDevToolsUtils(lightUtils)
197-
.build()
198-
.getUrlString()
199-
);
200-
201182
when(mockSdkUtil.getFlutterHostEnvValue()).thenReturn("Android-Studio");
202183

203184
final DevToolsUtils darkUtils = mock(DevToolsUtils.class);
204185
when(darkUtils.getColorHexCode()).thenReturn("3c3f41");
205186
when(darkUtils.getIsBackgroundBright()).thenReturn(false);
206-
when(darkUtils.getFontSize()).thenReturn(null);
207187

208188
assertEquals(
209189
"http://127.0.0.1:9100/timeline?ide=Android-Studio&backgroundColor=3c3f41&theme=dark&embed=true&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",

0 commit comments

Comments
 (0)