Wayland: Implement HiDPI support

Windows now keep track of the monitors they are on, so we can calculate
the best scaling factor for them, by using the maximum of each of the
monitors.

The compositor scales down the buffer automatically when it is on a
lower density monitor, instead of the previous way where it was scaling
up the buffer on higher density monitors, which makes the application
look much better on those ones.
This commit is contained in:
Emmanuel Gil Peyrot
2015-10-10 16:35:06 +01:00
committed by Jonas Ådahl
parent ecd04539ec
commit 06479ba535
4 changed files with 111 additions and 3 deletions
+90 -1
View File
@@ -72,6 +72,79 @@ static const struct wl_shell_surface_listener shellSurfaceListener = {
handlePopupDone
};
static void checkScaleChange(_GLFWwindow* window)
{
int scaledWidth, scaledHeight;
int scale = 1;
int i;
int monitorScale;
// Get the scale factor from the highest scale monitor.
for (i = 0; i < window->wl.monitorsCount; ++i)
{
monitorScale = window->wl.monitors[i]->wl.scale;
if (scale < monitorScale)
scale = monitorScale;
}
// Only change the framebuffer size if the scale changed.
if (scale != window->wl.scale)
{
window->wl.scale = scale;
scaledWidth = window->wl.width * scale;
scaledHeight = window->wl.height * scale;
wl_surface_set_buffer_scale(window->wl.surface, scale);
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
}
}
static void handleEnter(void *data,
struct wl_surface *surface,
struct wl_output *output)
{
_GLFWwindow* window = data;
_GLFWmonitor* monitor = wl_output_get_user_data(output);
if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)
{
++window->wl.monitorsSize;
window->wl.monitors =
realloc(window->wl.monitors,
window->wl.monitorsSize * sizeof(_GLFWmonitor*));
}
window->wl.monitors[window->wl.monitorsCount++] = monitor;
checkScaleChange(window);
}
static void handleLeave(void *data,
struct wl_surface *surface,
struct wl_output *output)
{
_GLFWwindow* window = data;
_GLFWmonitor* monitor = wl_output_get_user_data(output);
GLFWbool found;
int i;
for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
{
if (monitor == window->wl.monitors[i])
found = GLFW_TRUE;
if (found)
window->wl.monitors[i] = window->wl.monitors[i + 1];
}
window->wl.monitors[--window->wl.monitorsCount] = NULL;
checkScaleChange(window);
}
static const struct wl_surface_listener surfaceListener = {
handleEnter,
handleLeave
};
static GLFWbool createSurface(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig)
{
@@ -79,6 +152,10 @@ static GLFWbool createSurface(_GLFWwindow* window,
if (!window->wl.surface)
return GLFW_FALSE;
wl_surface_add_listener(window->wl.surface,
&surfaceListener,
window);
wl_surface_set_user_data(window->wl.surface, window);
window->wl.native = wl_egl_window_create(window->wl.surface,
@@ -98,6 +175,7 @@ static GLFWbool createSurface(_GLFWwindow* window,
window->wl.width = wndconfig->width;
window->wl.height = wndconfig->height;
window->wl.scale = 1;
return GLFW_TRUE;
}
@@ -262,6 +340,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
window->wl.currentCursor = NULL;
window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));
window->wl.monitorsCount = 0;
window->wl.monitorsSize = 1;
return GLFW_TRUE;
}
@@ -288,6 +370,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->wl.surface)
wl_surface_destroy(window->wl.surface);
free(window->wl.monitors);
}
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
@@ -322,9 +406,12 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
wl_egl_window_resize(window->wl.native, width, height, 0, 0);
int scaledWidth = width * window->wl.scale;
int scaledHeight = height * window->wl.scale;
window->wl.width = width;
window->wl.height = height;
wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
}
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
@@ -344,6 +431,8 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{
_glfwPlatformGetWindowSize(window, width, height);
*width *= window->wl.scale;
*height *= window->wl.scale;
}
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,