Skip to content

Commit 3f299c3

Browse files
authored
Handle use case when canvas size is already controlled by css (#20956)
- implementation is inspired by SDL implementation
1 parent f148f2b commit 3f299c3

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

src/library_glfw.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,13 @@ var LibraryGLFW = {
10761076
// not valid
10771077
if (width <= 0 || height <= 0) return 0;
10781078

1079+
// check whether css is modifying the size
1080+
const canvas = Module['canvas'];
1081+
const originalCanvasWidth = canvas.width;
1082+
const orginalCanvasHeight = canvas.height;
1083+
canvas.width = 1; canvas.height = 1;
1084+
GLFW.hasExternalSizing = canvas.clientWidth != 1 || canvas.clientHeight != 1;
1085+
10791086
if (monitor) {
10801087
Browser.requestFullscreen();
10811088
} else {
@@ -1109,9 +1116,11 @@ var LibraryGLFW = {
11091116
if (!Module.ctx && useWebGL) return 0;
11101117

11111118
// Get non alive id
1112-
const canvas = Module['canvas'];
11131119
var win = new GLFW_Window(id, canvas.clientWidth, canvas.clientHeight, canvas.width, canvas.height, title, monitor, share);
11141120

1121+
win.originalCanvasWidth = originalCanvasWidth;
1122+
win.orginalCanvasHeight = orginalCanvasHeight;
1123+
11151124
// Set window to array
11161125
if (id - 1 == GLFW.windows.length) {
11171126
GLFW.windows.push(win);
@@ -1142,7 +1151,14 @@ var LibraryGLFW = {
11421151
for (var i = 0; i < GLFW.windows.length; i++)
11431152
if (GLFW.windows[i] !== null) return;
11441153

1145-
Module.ctx = Browser.destroyContext(Module['canvas'], true, true);
1154+
const canvas = Module['canvas'];
1155+
if (!GLFW.hasExternalSizing && typeof canvas.style != 'undefined') {
1156+
canvas.style.removeProperty('width');
1157+
canvas.style.removeProperty('height');
1158+
}
1159+
Module.ctx = Browser.destroyContext(canvas, true, true);
1160+
canvas.width = win.originalCanvasWidth;
1161+
canvas.height = win.orginalCanvasHeight;
11461162
},
11471163

11481164
swapBuffers: (winid) => {
@@ -1245,13 +1261,13 @@ var LibraryGLFW = {
12451261
const hNativeScaled = Math.floor(hNative * scale);
12461262
if (canvas.width != wNativeScaled) canvas.width = wNativeScaled;
12471263
if (canvas.height != hNativeScaled) canvas.height = hNativeScaled;
1248-
if (typeof canvas.style != 'undefined') {
1264+
if (!GLFW.hasExternalSizing && typeof canvas.style != 'undefined') {
12491265
if (wNativeScaled != wNative || hNativeScaled != hNative) {
1250-
canvas.style.setProperty( "width", wNative + "px", "important");
1251-
canvas.style.setProperty("height", hNative + "px", "important");
1266+
canvas.style.setProperty( 'width', wNative + 'px', 'important');
1267+
canvas.style.setProperty('height', hNative + 'px', 'important');
12521268
} else {
1253-
canvas.style.removeProperty( "width");
1254-
canvas.style.removeProperty("height");
1269+
canvas.style.removeProperty('width');
1270+
canvas.style.removeProperty('height');
12551271
}
12561272
}
12571273
},

test/browser/test_glfw3_hi_dpi_aware.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ static void checkWindowSize(GLFWwindow *window, int expectedWidth, int expectedH
5151
assert(fbw == (int) (expectedWidth * ratio) && fbh == (int) (expectedHeight * ratio));
5252
}
5353

54+
static void checkCanvasSize(int expectedWidth, int expectedHeight) {
55+
int w, h;
56+
emscripten_get_canvas_element_size("#canvas", &w, &h);
57+
printf("canvas size => %d == %d && %d == %d\n", w, expectedWidth, h, expectedHeight);
58+
assert(w == expectedWidth && h == expectedHeight);
59+
}
60+
61+
static void checkCanvasFramebufferSize(int expectedWidth, int expectedHeight) {
62+
double fbw, fbh;
63+
emscripten_get_element_css_size("#canvas", &fbw, &fbh);
64+
printf("canvas framebufferSize => %d == %d && %d == %d\n", (int) fbw, (int) expectedWidth, (int) fbh, expectedHeight);
65+
assert((int) fbw == expectedWidth && (int) fbh == expectedHeight);
66+
}
67+
5468
static bool getGLFWIsHiDPIAware() {
5569
return EM_ASM_INT(return GLFW.isHiDPIAware() ? 1 : 0) != 0;
5670
}
@@ -75,13 +89,17 @@ int main() {
7589
// Expected outcome is window size and frame buffer size are the same
7690
{
7791
printf("Use case #1\n");
92+
checkCanvasSize(300, 150); // 300x150 is the default canvas size
93+
checkCanvasFramebufferSize(300, 150);
7894
window = glfwCreateWindow(640, 480, "test_glfw3_hi_dpi_aware.c | #1", NULL, NULL);
7995
assert(window != NULL);
8096
checkHiDPIAware(window, false);
8197
checkWindowSize(window, 640, 480, 1.0);
8298
glfwSetWindowSize(window, 600, 400);
8399
checkWindowSize(window, 600, 400, 1.0);
84100
glfwDestroyWindow(window);
101+
checkCanvasSize(300, 150); // we make sure that the glfw code resets the canvas how it was
102+
checkCanvasFramebufferSize(300, 150);
85103
}
86104

87105
// Use case 2: GLFW is NOT Hi DPI Aware | devicePixelRatio is 2.0
@@ -174,6 +192,24 @@ int main() {
174192
glfwDestroyWindow(window);
175193
}
176194

195+
// Use case 8: GLFW is Hi DPI Aware | devicePixelRatio is 2.0 | canvas has css override
196+
// Expected outcome is that the framebuffer size is adjusted according to the canvas size
197+
{
198+
printf("Use case #8\n");
199+
setDevicePixelRatio(2.0);
200+
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
201+
emscripten_set_element_css_size("#canvas", 700, 525);
202+
checkCanvasSize(300, 150); // default canvas size
203+
checkCanvasFramebufferSize(700, 525); // css override
204+
window = glfwCreateWindow(640, 480, "test_glfw3_hi_dpi_aware.c | #8", NULL, NULL);
205+
assert(window != NULL);
206+
checkHiDPIAware(window, true);
207+
checkWindowSize(window, 700, 525, 2.0); // canvas size overrides window size
208+
glfwDestroyWindow(window);
209+
checkCanvasSize(300, 150);
210+
checkCanvasFramebufferSize(700, 525);
211+
}
212+
177213
glfwTerminate();
178214

179215
return 0;

0 commit comments

Comments
 (0)