mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 13:04:35 +00:00
Wayland: Simplify per-window ouput scales tracking
This replaces (one case of) manual management of weak links between
windows and monitors, both objects with complex life times, with
wl_object pointers used as opaque key values.
(cherry picked from commit efa9297a41
)
This commit is contained in:
parent
5ac970120a
commit
e5d19c9fac
@ -110,14 +110,15 @@ static void outputHandleScale(void* userData,
|
|||||||
{
|
{
|
||||||
struct _GLFWmonitor* monitor = userData;
|
struct _GLFWmonitor* monitor = userData;
|
||||||
|
|
||||||
monitor->wl.scale = factor;
|
monitor->wl.contentScale = factor;
|
||||||
|
|
||||||
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < window->wl.monitorsCount; i++)
|
for (int i = 0; i < window->wl.scaleCount; i++)
|
||||||
{
|
{
|
||||||
if (window->wl.monitors[i] == monitor)
|
if (window->wl.scales[i].output == monitor->wl.output)
|
||||||
{
|
{
|
||||||
|
window->wl.scales[i].factor = monitor->wl.contentScale;
|
||||||
_glfwUpdateContentScaleWayland(window);
|
_glfwUpdateContentScaleWayland(window);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -183,7 +184,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
|||||||
|
|
||||||
// The actual name of this output will be set in the geometry handler
|
// The actual name of this output will be set in the geometry handler
|
||||||
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
|
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
|
||||||
monitor->wl.scale = 1;
|
monitor->wl.contentScale = 1;
|
||||||
monitor->wl.output = output;
|
monitor->wl.output = output;
|
||||||
monitor->wl.name = name;
|
monitor->wl.name = name;
|
||||||
|
|
||||||
@ -214,9 +215,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
|||||||
float* xscale, float* yscale)
|
float* xscale, float* yscale)
|
||||||
{
|
{
|
||||||
if (xscale)
|
if (xscale)
|
||||||
*xscale = (float) monitor->wl.scale;
|
*xscale = (float) monitor->wl.contentScale;
|
||||||
if (yscale)
|
if (yscale)
|
||||||
*yscale = (float) monitor->wl.scale;
|
*yscale = (float) monitor->wl.contentScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||||
|
@ -169,6 +169,12 @@ typedef struct _GLFWofferWayland
|
|||||||
GLFWbool text_uri_list;
|
GLFWbool text_uri_list;
|
||||||
} _GLFWofferWayland;
|
} _GLFWofferWayland;
|
||||||
|
|
||||||
|
typedef struct _GLFWscaleWayland
|
||||||
|
{
|
||||||
|
struct wl_output* output;
|
||||||
|
int factor;
|
||||||
|
} _GLFWscaleWayland;
|
||||||
|
|
||||||
// Wayland-specific per-window data
|
// Wayland-specific per-window data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWwindowWayland
|
typedef struct _GLFWwindowWayland
|
||||||
@ -209,10 +215,10 @@ typedef struct _GLFWwindowWayland
|
|||||||
|
|
||||||
// We need to track the monitors the window spans on to calculate the
|
// We need to track the monitors the window spans on to calculate the
|
||||||
// optimal scaling factor.
|
// optimal scaling factor.
|
||||||
int scale;
|
int contentScale;
|
||||||
_GLFWmonitor** monitors;
|
_GLFWscaleWayland* scales;
|
||||||
int monitorsCount;
|
int scaleCount;
|
||||||
int monitorsSize;
|
int scaleSize;
|
||||||
|
|
||||||
struct zwp_relative_pointer_v1* relativePointer;
|
struct zwp_relative_pointer_v1* relativePointer;
|
||||||
struct zwp_locked_pointer_v1* lockedPointer;
|
struct zwp_locked_pointer_v1* lockedPointer;
|
||||||
@ -346,7 +352,7 @@ typedef struct _GLFWmonitorWayland
|
|||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int scale;
|
int contentScale;
|
||||||
} _GLFWmonitorWayland;
|
} _GLFWmonitorWayland;
|
||||||
|
|
||||||
// Wayland-specific per-cursor data
|
// Wayland-specific per-cursor data
|
||||||
|
@ -346,7 +346,7 @@ static void setContentAreaOpaque(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void resizeWindow(_GLFWwindow* window)
|
static void resizeWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
int scale = window->wl.scale;
|
int scale = window->wl.contentScale;
|
||||||
int scaledWidth = window->wl.width * scale;
|
int scaledWidth = window->wl.width * scale;
|
||||||
int scaledHeight = window->wl.height * scale;
|
int scaledHeight = window->wl.height * scale;
|
||||||
|
|
||||||
@ -391,13 +391,13 @@ void _glfwUpdateContentScaleWayland(_GLFWwindow* window)
|
|||||||
// Get the scale factor from the highest scale monitor.
|
// Get the scale factor from the highest scale monitor.
|
||||||
int maxScale = 1;
|
int maxScale = 1;
|
||||||
|
|
||||||
for (int i = 0; i < window->wl.monitorsCount; i++)
|
for (int i = 0; i < window->wl.scaleCount; i++)
|
||||||
maxScale = _glfw_max(window->wl.monitors[i]->wl.scale, maxScale);
|
maxScale = _glfw_max(window->wl.scales[i].factor, maxScale);
|
||||||
|
|
||||||
// Only change the framebuffer size if the scale changed.
|
// Only change the framebuffer size if the scale changed.
|
||||||
if (window->wl.scale != maxScale)
|
if (window->wl.contentScale != maxScale)
|
||||||
{
|
{
|
||||||
window->wl.scale = maxScale;
|
window->wl.contentScale = maxScale;
|
||||||
wl_surface_set_buffer_scale(window->wl.surface, maxScale);
|
wl_surface_set_buffer_scale(window->wl.surface, maxScale);
|
||||||
_glfwInputWindowContentScale(window, maxScale, maxScale);
|
_glfwInputWindowContentScale(window, maxScale, maxScale);
|
||||||
resizeWindow(window);
|
resizeWindow(window);
|
||||||
@ -416,16 +416,20 @@ static void surfaceHandleEnter(void* userData,
|
|||||||
|
|
||||||
_GLFWwindow* window = userData;
|
_GLFWwindow* window = userData;
|
||||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||||
|
if (!window || !monitor)
|
||||||
|
return;
|
||||||
|
|
||||||
if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)
|
if (window->wl.scaleCount + 1 > window->wl.scaleSize)
|
||||||
{
|
{
|
||||||
++window->wl.monitorsSize;
|
window->wl.scaleSize++;
|
||||||
window->wl.monitors =
|
window->wl.scales =
|
||||||
realloc(window->wl.monitors,
|
realloc(window->wl.scales,
|
||||||
window->wl.monitorsSize * sizeof(_GLFWmonitor*));
|
window->wl.scaleSize * sizeof(_GLFWscaleWayland));
|
||||||
}
|
}
|
||||||
|
|
||||||
window->wl.monitors[window->wl.monitorsCount++] = monitor;
|
window->wl.scaleCount++;
|
||||||
|
window->wl.scales[window->wl.scaleCount - 1].factor = monitor->wl.contentScale;
|
||||||
|
window->wl.scales[window->wl.scaleCount - 1].output = output;
|
||||||
|
|
||||||
_glfwUpdateContentScaleWayland(window);
|
_glfwUpdateContentScaleWayland(window);
|
||||||
}
|
}
|
||||||
@ -438,18 +442,16 @@ static void surfaceHandleLeave(void* userData,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_GLFWwindow* window = userData;
|
_GLFWwindow* window = userData;
|
||||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
|
||||||
GLFWbool found;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
|
for (int i = 0; i < window->wl.scaleCount; i++)
|
||||||
{
|
{
|
||||||
if (monitor == window->wl.monitors[i])
|
if (window->wl.scales[i].output == output)
|
||||||
found = GLFW_TRUE;
|
{
|
||||||
if (found)
|
window->wl.scales[i] = window->wl.scales[window->wl.scaleCount - 1];
|
||||||
window->wl.monitors[i] = window->wl.monitors[i + 1];
|
window->wl.scaleCount--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
window->wl.monitors[--window->wl.monitorsCount] = NULL;
|
|
||||||
|
|
||||||
_glfwUpdateContentScaleWayland(window);
|
_glfwUpdateContentScaleWayland(window);
|
||||||
}
|
}
|
||||||
@ -780,7 +782,7 @@ static GLFWbool createNativeSurface(_GLFWwindow* window,
|
|||||||
|
|
||||||
window->wl.width = wndconfig->width;
|
window->wl.width = wndconfig->width;
|
||||||
window->wl.height = wndconfig->height;
|
window->wl.height = wndconfig->height;
|
||||||
window->wl.scale = 1;
|
window->wl.contentScale = 1;
|
||||||
window->wl.title = _glfw_strdup(wndconfig->title);
|
window->wl.title = _glfw_strdup(wndconfig->title);
|
||||||
|
|
||||||
window->wl.maximized = wndconfig->maximized;
|
window->wl.maximized = wndconfig->maximized;
|
||||||
@ -806,7 +808,7 @@ static void setCursorImage(_GLFWwindow* window,
|
|||||||
buffer = cursorWayland->buffer;
|
buffer = cursorWayland->buffer;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (window->wl.scale > 1 && cursorWayland->cursorHiDPI)
|
if (window->wl.contentScale > 1 && cursorWayland->cursorHiDPI)
|
||||||
{
|
{
|
||||||
wlCursor = cursorWayland->cursorHiDPI;
|
wlCursor = cursorWayland->cursorHiDPI;
|
||||||
scale = 2;
|
scale = 2;
|
||||||
@ -1162,7 +1164,7 @@ static void setCursor(_GLFWwindow* window, const char* name)
|
|||||||
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
|
|
||||||
if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI)
|
if (window->wl.contentScale > 1 && _glfw.wl.cursorThemeHiDPI)
|
||||||
{
|
{
|
||||||
// We only support up to scale=2 for now, since libwayland-cursor
|
// We only support up to scale=2 for now, since libwayland-cursor
|
||||||
// requires us to load a different theme for each size.
|
// requires us to load a different theme for each size.
|
||||||
@ -1961,7 +1963,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
wl_surface_destroy(window->wl.surface);
|
wl_surface_destroy(window->wl.surface);
|
||||||
|
|
||||||
free(window->wl.title);
|
free(window->wl.title);
|
||||||
free(window->wl.monitors);
|
free(window->wl.scales);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||||
@ -2092,9 +2094,9 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
_glfwPlatformGetWindowSize(window, width, height);
|
_glfwPlatformGetWindowSize(window, width, height);
|
||||||
if (width)
|
if (width)
|
||||||
*width *= window->wl.scale;
|
*width *= window->wl.contentScale;
|
||||||
if (height)
|
if (height)
|
||||||
*height *= window->wl.scale;
|
*height *= window->wl.contentScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||||
@ -2118,9 +2120,9 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
|||||||
float* xscale, float* yscale)
|
float* xscale, float* yscale)
|
||||||
{
|
{
|
||||||
if (xscale)
|
if (xscale)
|
||||||
*xscale = (float) window->wl.scale;
|
*xscale = (float) window->wl.contentScale;
|
||||||
if (yscale)
|
if (yscale)
|
||||||
*yscale = (float) window->wl.scale;
|
*yscale = (float) window->wl.contentScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
||||||
|
Loading…
Reference in New Issue
Block a user