Merge branch 'master' into PulseSubmodule

This commit is contained in:
khunguraharman 2024-02-14 11:54:34 -08:00 committed by GitHub
commit bb06799581
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 291 additions and 277 deletions

View File

@ -33,6 +33,7 @@ video tutorials.
- David Carlier
- Arturo Castro
- Chi-kwan Chan
- Victor Chernyakin
- TheChocolateOre
- Ali Chraghi
- Joseph Chua

View File

@ -181,8 +181,11 @@ information on what to include when reporting a bug.
- [Wayland] Added support for `glfwFocusWindow`
- [Wayland] Added dynamic loading of all Wayland libraries
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
- [Wayland] Bugfix: `GLFW_HOVERED` was true when the cursor was over any
fallback window decoration
- [X11] Bugfix: Termination would segfault if the IM had been destroyed
- [X11] Bugfix: Any IM started after initialization would not be detected
- [Linux] Bugfix: Joystick evdev fds remained open in forks (#2446)
- [POSIX] Removed use of deprecated function `gettimeofday`
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)

View File

@ -135,7 +135,7 @@ static GLFWbool openJoystickDevice(const char* path)
}
_GLFWjoystickLinux linjs = {0};
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
linjs.fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
if (linjs.fd == -1)
return GLFW_FALSE;

View File

@ -112,16 +112,16 @@ static void outputHandleScale(void* userData,
{
struct _GLFWmonitor* monitor = userData;
monitor->wl.contentScale = factor;
monitor->wl.scale = factor;
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
{
for (int i = 0; i < window->wl.scaleCount; i++)
for (size_t i = 0; i < window->wl.outputScaleCount; i++)
{
if (window->wl.scales[i].output == monitor->wl.output)
if (window->wl.outputScales[i].output == monitor->wl.output)
{
window->wl.scales[i].factor = monitor->wl.contentScale;
_glfwUpdateContentScaleWayland(window);
window->wl.outputScales[i].factor = monitor->wl.scale;
_glfwUpdateBufferScaleFromOutputsWayland(window);
break;
}
}
@ -176,7 +176,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
// The actual name of this output will be set in the geometry handler
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
monitor->wl.contentScale = 1;
monitor->wl.scale = 1;
monitor->wl.output = output;
monitor->wl.name = name;
@ -207,9 +207,9 @@ void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = (float) monitor->wl.contentScale;
*xscale = (float) monitor->wl.scale;
if (yscale)
*yscale = (float) monitor->wl.contentScale;
*yscale = (float) monitor->wl.scale;
}
void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor,

View File

@ -323,21 +323,12 @@ typedef void (* PFN_libdecor_state_free)(struct libdecor_state*);
#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_
#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_
typedef enum _GLFWdecorationSideWayland
{
GLFW_MAIN_WINDOW,
GLFW_TOP_DECORATION,
GLFW_LEFT_DECORATION,
GLFW_RIGHT_DECORATION,
GLFW_BOTTOM_DECORATION
} _GLFWdecorationSideWayland;
typedef struct _GLFWdecorationWayland
typedef struct _GLFWfallbackEdgeWayland
{
struct wl_surface* surface;
struct wl_subsurface* subsurface;
struct wp_viewport* viewport;
} _GLFWdecorationWayland;
} _GLFWfallbackEdgeWayland;
typedef struct _GLFWofferWayland
{
@ -349,7 +340,7 @@ typedef struct _GLFWofferWayland
typedef struct _GLFWscaleWayland
{
struct wl_output* output;
int factor;
int32_t factor;
} _GLFWscaleWayland;
// Wayland-specific per-window data
@ -357,6 +348,7 @@ typedef struct _GLFWscaleWayland
typedef struct _GLFWwindowWayland
{
int width, height;
int fbWidth, fbHeight;
GLFWbool visible;
GLFWbool maximized;
GLFWbool activated;
@ -387,7 +379,6 @@ typedef struct _GLFWwindowWayland
struct {
struct libdecor_frame* frame;
int mode;
} libdecor;
_GLFWcursor* currentCursor;
@ -398,10 +389,10 @@ typedef struct _GLFWwindowWayland
// We need to track the monitors the window spans on to calculate the
// optimal scaling factor.
int contentScale;
_GLFWscaleWayland* scales;
int scaleCount;
int scaleSize;
int32_t bufferScale;
_GLFWscaleWayland* outputScales;
size_t outputScaleCount;
size_t outputScaleSize;
struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer;
@ -411,10 +402,11 @@ typedef struct _GLFWwindowWayland
struct xdg_activation_token_v1* activationToken;
struct {
GLFWbool decorations;
struct wl_buffer* buffer;
_GLFWdecorationWayland top, left, right, bottom;
_GLFWdecorationSideWayland focus;
} decorations;
_GLFWfallbackEdgeWayland top, left, right, bottom;
struct wl_surface* focus;
} fallback;
} _GLFWwindowWayland;
// Wayland-specific global data
@ -594,7 +586,7 @@ typedef struct _GLFWmonitorWayland
int x;
int y;
int contentScale;
int32_t scale;
} _GLFWmonitorWayland;
// Wayland-specific per-cursor data
@ -685,7 +677,7 @@ GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window);
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);

View File

@ -192,29 +192,28 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
return buffer;
}
static void createFallbackDecoration(_GLFWwindow* window,
_GLFWdecorationWayland* decoration,
static void createFallbackEdge(_GLFWwindow* window,
_GLFWfallbackEdgeWayland* edge,
struct wl_surface* parent,
struct wl_buffer* buffer,
int x, int y,
int width, int height)
{
decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor);
wl_surface_set_user_data(decoration->surface, window);
wl_proxy_set_tag((struct wl_proxy*) decoration->surface, &_glfw.wl.tag);
decoration->subsurface =
wl_subcompositor_get_subsurface(_glfw.wl.subcompositor,
decoration->surface, parent);
wl_subsurface_set_position(decoration->subsurface, x, y);
decoration->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter,
decoration->surface);
wp_viewport_set_destination(decoration->viewport, width, height);
wl_surface_attach(decoration->surface, buffer, 0, 0);
edge->surface = wl_compositor_create_surface(_glfw.wl.compositor);
wl_surface_set_user_data(edge->surface, window);
wl_proxy_set_tag((struct wl_proxy*) edge->surface, &_glfw.wl.tag);
edge->subsurface = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor,
edge->surface, parent);
wl_subsurface_set_position(edge->subsurface, x, y);
edge->viewport = wp_viewporter_get_viewport(_glfw.wl.viewporter,
edge->surface);
wp_viewport_set_destination(edge->viewport, width, height);
wl_surface_attach(edge->surface, buffer, 0, 0);
struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor);
wl_region_add(region, 0, 0, width, height);
wl_surface_set_opaque_region(decoration->surface, region);
wl_surface_commit(decoration->surface);
wl_surface_set_opaque_region(edge->surface, region);
wl_surface_commit(edge->surface);
wl_region_destroy(region);
}
@ -226,48 +225,53 @@ static void createFallbackDecorations(_GLFWwindow* window)
if (!_glfw.wl.viewporter)
return;
if (!window->wl.decorations.buffer)
window->wl.decorations.buffer = createShmBuffer(&image);
if (!window->wl.decorations.buffer)
if (!window->wl.fallback.buffer)
window->wl.fallback.buffer = createShmBuffer(&image);
if (!window->wl.fallback.buffer)
return;
createFallbackDecoration(window, &window->wl.decorations.top, window->wl.surface,
window->wl.decorations.buffer,
createFallbackEdge(window, &window->wl.fallback.top, window->wl.surface,
window->wl.fallback.buffer,
0, -GLFW_CAPTION_HEIGHT,
window->wl.width, GLFW_CAPTION_HEIGHT);
createFallbackDecoration(window, &window->wl.decorations.left, window->wl.surface,
window->wl.decorations.buffer,
createFallbackEdge(window, &window->wl.fallback.left, window->wl.surface,
window->wl.fallback.buffer,
-GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT,
GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);
createFallbackDecoration(window, &window->wl.decorations.right, window->wl.surface,
window->wl.decorations.buffer,
createFallbackEdge(window, &window->wl.fallback.right, window->wl.surface,
window->wl.fallback.buffer,
window->wl.width, -GLFW_CAPTION_HEIGHT,
GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);
createFallbackDecoration(window, &window->wl.decorations.bottom, window->wl.surface,
window->wl.decorations.buffer,
createFallbackEdge(window, &window->wl.fallback.bottom, window->wl.surface,
window->wl.fallback.buffer,
-GLFW_BORDER_SIZE, window->wl.height,
window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE);
window->wl.fallback.decorations = GLFW_TRUE;
}
static void destroyFallbackDecoration(_GLFWdecorationWayland* decoration)
static void destroyFallbackEdge(_GLFWfallbackEdgeWayland* edge)
{
if (decoration->subsurface)
wl_subsurface_destroy(decoration->subsurface);
if (decoration->surface)
wl_surface_destroy(decoration->surface);
if (decoration->viewport)
wp_viewport_destroy(decoration->viewport);
decoration->surface = NULL;
decoration->subsurface = NULL;
decoration->viewport = NULL;
if (edge->subsurface)
wl_subsurface_destroy(edge->subsurface);
if (edge->surface)
wl_surface_destroy(edge->surface);
if (edge->viewport)
wp_viewport_destroy(edge->viewport);
edge->surface = NULL;
edge->subsurface = NULL;
edge->viewport = NULL;
}
static void destroyFallbackDecorations(_GLFWwindow* window)
{
destroyFallbackDecoration(&window->wl.decorations.top);
destroyFallbackDecoration(&window->wl.decorations.left);
destroyFallbackDecoration(&window->wl.decorations.right);
destroyFallbackDecoration(&window->wl.decorations.bottom);
window->wl.fallback.decorations = GLFW_FALSE;
destroyFallbackEdge(&window->wl.fallback.top);
destroyFallbackEdge(&window->wl.fallback.left);
destroyFallbackEdge(&window->wl.fallback.right);
destroyFallbackEdge(&window->wl.fallback.bottom);
}
static void xdgDecorationHandleConfigure(void* userData,
@ -306,44 +310,58 @@ static void setContentAreaOpaque(_GLFWwindow* window)
wl_region_destroy(region);
}
static void resizeFramebuffer(_GLFWwindow* window)
{
window->wl.fbWidth = window->wl.width * window->wl.bufferScale;
window->wl.fbHeight = window->wl.height * window->wl.bufferScale;
if (window->wl.egl.window)
{
wl_egl_window_resize(window->wl.egl.window,
window->wl.fbWidth,
window->wl.fbHeight,
0, 0);
}
if (!window->wl.transparent)
setContentAreaOpaque(window);
_glfwInputFramebufferSize(window, window->wl.fbWidth, window->wl.fbHeight);
}
static void resizeWindow(_GLFWwindow* window)
{
int scale = window->wl.contentScale;
int scaledWidth = window->wl.width * scale;
int scaledHeight = window->wl.height * scale;
resizeFramebuffer(window);
if (window->wl.egl.window)
wl_egl_window_resize(window->wl.egl.window, scaledWidth, scaledHeight, 0, 0);
if (!window->wl.transparent)
setContentAreaOpaque(window);
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
if (window->wl.fallback.decorations)
{
wp_viewport_set_destination(window->wl.fallback.top.viewport,
window->wl.width,
GLFW_CAPTION_HEIGHT);
wl_surface_commit(window->wl.fallback.top.surface);
if (!window->wl.decorations.top.surface)
return;
wp_viewport_set_destination(window->wl.fallback.left.viewport,
GLFW_BORDER_SIZE,
window->wl.height + GLFW_CAPTION_HEIGHT);
wl_surface_commit(window->wl.fallback.left.surface);
wp_viewport_set_destination(window->wl.decorations.top.viewport,
window->wl.width, GLFW_CAPTION_HEIGHT);
wl_surface_commit(window->wl.decorations.top.surface);
wp_viewport_set_destination(window->wl.decorations.left.viewport,
GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);
wl_surface_commit(window->wl.decorations.left.surface);
wl_subsurface_set_position(window->wl.decorations.right.subsurface,
wl_subsurface_set_position(window->wl.fallback.right.subsurface,
window->wl.width, -GLFW_CAPTION_HEIGHT);
wp_viewport_set_destination(window->wl.decorations.right.viewport,
GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);
wl_surface_commit(window->wl.decorations.right.surface);
wp_viewport_set_destination(window->wl.fallback.right.viewport,
GLFW_BORDER_SIZE,
window->wl.height + GLFW_CAPTION_HEIGHT);
wl_surface_commit(window->wl.fallback.right.surface);
wl_subsurface_set_position(window->wl.decorations.bottom.subsurface,
wl_subsurface_set_position(window->wl.fallback.bottom.subsurface,
-GLFW_BORDER_SIZE, window->wl.height);
wp_viewport_set_destination(window->wl.decorations.bottom.viewport,
window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE);
wl_surface_commit(window->wl.decorations.bottom.surface);
wp_viewport_set_destination(window->wl.fallback.bottom.viewport,
window->wl.width + GLFW_BORDER_SIZE * 2,
GLFW_BORDER_SIZE);
wl_surface_commit(window->wl.fallback.bottom.surface);
}
}
void _glfwUpdateContentScaleWayland(_GLFWwindow* window)
void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window)
{
if (wl_compositor_get_version(_glfw.wl.compositor) <
WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
@ -352,18 +370,18 @@ void _glfwUpdateContentScaleWayland(_GLFWwindow* window)
}
// Get the scale factor from the highest scale monitor.
int maxScale = 1;
int32_t maxScale = 1;
for (int i = 0; i < window->wl.scaleCount; i++)
maxScale = _glfw_max(window->wl.scales[i].factor, maxScale);
for (size_t i = 0; i < window->wl.outputScaleCount; i++)
maxScale = _glfw_max(window->wl.outputScales[i].factor, maxScale);
// Only change the framebuffer size if the scale changed.
if (window->wl.contentScale != maxScale)
if (window->wl.bufferScale != maxScale)
{
window->wl.contentScale = maxScale;
window->wl.bufferScale = maxScale;
wl_surface_set_buffer_scale(window->wl.surface, maxScale);
_glfwInputWindowContentScale(window, maxScale, maxScale);
resizeWindow(window);
resizeFramebuffer(window);
if (window->wl.visible)
_glfwInputWindowDamage(window);
@ -382,19 +400,19 @@ static void surfaceHandleEnter(void* userData,
if (!window || !monitor)
return;
if (window->wl.scaleCount + 1 > window->wl.scaleSize)
if (window->wl.outputScaleCount + 1 > window->wl.outputScaleSize)
{
window->wl.scaleSize++;
window->wl.scales =
_glfw_realloc(window->wl.scales,
window->wl.scaleSize * sizeof(_GLFWscaleWayland));
window->wl.outputScaleSize++;
window->wl.outputScales =
_glfw_realloc(window->wl.outputScales,
window->wl.outputScaleSize * sizeof(_GLFWscaleWayland));
}
window->wl.scaleCount++;
window->wl.scales[window->wl.scaleCount - 1].factor = monitor->wl.contentScale;
window->wl.scales[window->wl.scaleCount - 1].output = output;
window->wl.outputScaleCount++;
window->wl.outputScales[window->wl.outputScaleCount - 1] =
(_GLFWscaleWayland) { output, monitor->wl.scale };
_glfwUpdateContentScaleWayland(window);
_glfwUpdateBufferScaleFromOutputsWayland(window);
}
static void surfaceHandleLeave(void* userData,
@ -406,17 +424,18 @@ static void surfaceHandleLeave(void* userData,
_GLFWwindow* window = userData;
for (int i = 0; i < window->wl.scaleCount; i++)
for (size_t i = 0; i < window->wl.outputScaleCount; i++)
{
if (window->wl.scales[i].output == output)
if (window->wl.outputScales[i].output == output)
{
window->wl.scales[i] = window->wl.scales[window->wl.scaleCount - 1];
window->wl.scaleCount--;
window->wl.outputScales[i] =
window->wl.outputScales[window->wl.outputScaleCount - 1];
window->wl.outputScaleCount--;
break;
}
}
_glfwUpdateContentScaleWayland(window);
_glfwUpdateBufferScaleFromOutputsWayland(window);
}
static const struct wl_surface_listener surfaceListener =
@ -460,7 +479,7 @@ static void acquireMonitor(_GLFWwindow* window)
setIdleInhibitor(window, GLFW_TRUE);
if (window->wl.decorations.top.surface)
if (window->wl.fallback.decorations)
destroyFallbackDecorations(window);
}
@ -516,7 +535,7 @@ static void xdgToplevelHandleConfigure(void* userData,
if (width && height)
{
if (window->wl.decorations.top.surface)
if (window->wl.fallback.decorations)
{
window->wl.pending.width = _glfw_max(0, width - GLFW_BORDER_SIZE * 2);
window->wl.pending.height =
@ -876,7 +895,7 @@ static GLFWbool createXdgShellObjects(_GLFWwindow* window)
int minwidth = window->minwidth;
int minheight = window->minheight;
if (window->wl.decorations.top.surface)
if (window->wl.fallback.decorations)
{
minwidth += GLFW_BORDER_SIZE * 2;
minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;
@ -890,7 +909,7 @@ static GLFWbool createXdgShellObjects(_GLFWwindow* window)
int maxwidth = window->maxwidth;
int maxheight = window->maxheight;
if (window->wl.decorations.top.surface)
if (window->wl.fallback.decorations)
{
maxwidth += GLFW_BORDER_SIZE * 2;
maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;
@ -956,7 +975,9 @@ static GLFWbool createNativeSurface(_GLFWwindow* window,
window->wl.width = wndconfig->width;
window->wl.height = wndconfig->height;
window->wl.contentScale = 1;
window->wl.fbWidth = wndconfig->width;
window->wl.fbHeight = wndconfig->height;
window->wl.bufferScale = 1;
window->wl.title = _glfw_strdup(wndconfig->title);
window->wl.appId = _glfw_strdup(wndconfig->wl.appId);
@ -983,7 +1004,7 @@ static void setCursorImage(_GLFWwindow* window,
buffer = cursorWayland->buffer;
else
{
if (window->wl.contentScale > 1 && cursorWayland->cursorHiDPI)
if (window->wl.bufferScale > 1 && cursorWayland->cursorHiDPI)
{
wlCursor = cursorWayland->cursorHiDPI;
scale = 2;
@ -1019,7 +1040,7 @@ static void incrementCursorImage(_GLFWwindow* window)
{
_GLFWcursor* cursor;
if (!window || window->wl.decorations.focus != GLFW_MAIN_WINDOW)
if (!window || !window->wl.hovered)
return;
cursor = window->wl.currentCursor;
@ -1270,26 +1291,22 @@ static void pointerHandleEnter(void* userData,
_GLFWwindow* window = wl_surface_get_user_data(surface);
if (surface == window->wl.decorations.top.surface)
window->wl.decorations.focus = GLFW_TOP_DECORATION;
else if (surface == window->wl.decorations.left.surface)
window->wl.decorations.focus = GLFW_LEFT_DECORATION;
else if (surface == window->wl.decorations.right.surface)
window->wl.decorations.focus = GLFW_RIGHT_DECORATION;
else if (surface == window->wl.decorations.bottom.surface)
window->wl.decorations.focus = GLFW_BOTTOM_DECORATION;
else
window->wl.decorations.focus = GLFW_MAIN_WINDOW;
_glfw.wl.serial = serial;
_glfw.wl.pointerEnterSerial = serial;
_glfw.wl.pointerFocus = window;
if (surface == window->wl.surface)
{
window->wl.hovered = GLFW_TRUE;
_glfwSetCursorWayland(window, window->wl.currentCursor);
_glfwInputCursorEnter(window, GLFW_TRUE);
}
else
{
if (window->wl.fallback.decorations)
window->wl.fallback.focus = surface;
}
}
static void pointerHandleLeave(void* userData,
struct wl_pointer* pointer,
@ -1306,13 +1323,21 @@ static void pointerHandleLeave(void* userData,
if (!window)
return;
window->wl.hovered = GLFW_FALSE;
_glfw.wl.serial = serial;
_glfw.wl.pointerFocus = NULL;
_glfw.wl.cursorPreviousName = NULL;
if (window->wl.hovered)
{
window->wl.hovered = GLFW_FALSE;
_glfwInputCursorEnter(window, GLFW_FALSE);
}
else
{
if (window->wl.fallback.decorations)
window->wl.fallback.focus = NULL;
}
}
static void pointerHandleMotion(void* userData,
struct wl_pointer* pointer,
@ -1332,42 +1357,46 @@ static void pointerHandleMotion(void* userData,
window->wl.cursorPosX = xpos;
window->wl.cursorPosY = ypos;
const char* cursorName = NULL;
switch (window->wl.decorations.focus)
if (window->wl.hovered)
{
case GLFW_MAIN_WINDOW:
_glfw.wl.cursorPreviousName = NULL;
_glfwInputCursorPos(window, xpos, ypos);
return;
case GLFW_TOP_DECORATION:
}
if (window->wl.fallback.decorations)
{
const char* cursorName = NULL;
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
{
if (ypos < GLFW_BORDER_SIZE)
cursorName = "n-resize";
else
cursorName = "left_ptr";
break;
case GLFW_LEFT_DECORATION:
}
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
{
if (ypos < GLFW_BORDER_SIZE)
cursorName = "nw-resize";
else
cursorName = "w-resize";
break;
case GLFW_RIGHT_DECORATION:
}
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
{
if (ypos < GLFW_BORDER_SIZE)
cursorName = "ne-resize";
else
cursorName = "e-resize";
break;
case GLFW_BOTTOM_DECORATION:
}
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
{
if (xpos < GLFW_BORDER_SIZE)
cursorName = "sw-resize";
else if (xpos > window->wl.width + GLFW_BORDER_SIZE)
cursorName = "se-resize";
else
cursorName = "s-resize";
break;
default:
assert(0);
}
if (_glfw.wl.cursorPreviousName != cursorName)
@ -1376,7 +1405,7 @@ static void pointerHandleMotion(void* userData,
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
int scale = 1;
if (window->wl.contentScale > 1 && _glfw.wl.cursorThemeHiDPI)
if (window->wl.bufferScale > 1 && _glfw.wl.cursorThemeHiDPI)
{
// We only support up to scale=2 for now, since libwayland-cursor
// requires us to load a different theme for each size.
@ -1409,6 +1438,7 @@ static void pointerHandleMotion(void* userData,
_glfw.wl.cursorPreviousName = cursorName;
}
}
}
static void pointerHandleButton(void* userData,
struct wl_pointer* pointer,
@ -1418,82 +1448,74 @@ static void pointerHandleButton(void* userData,
uint32_t state)
{
_GLFWwindow* window = _glfw.wl.pointerFocus;
int glfwButton;
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
if (!window)
return;
if (window->wl.hovered)
{
_glfw.wl.serial = serial;
_glfwInputMouseClick(window,
button - BTN_LEFT,
state == WL_POINTER_BUTTON_STATE_PRESSED,
_glfw.wl.xkb.modifiers);
return;
}
if (window->wl.fallback.decorations)
{
if (button == BTN_LEFT)
{
switch (window->wl.decorations.focus)
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
{
case GLFW_MAIN_WINDOW:
break;
case GLFW_TOP_DECORATION:
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
else
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
break;
case GLFW_LEFT_DECORATION:
}
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
{
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
break;
case GLFW_RIGHT_DECORATION:
}
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
{
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
break;
case GLFW_BOTTOM_DECORATION:
}
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
{
if (window->wl.cursorPosX < GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE)
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
break;
default:
assert(0);
}
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
{
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
serial, edges);
return;
}
}
else if (button == BTN_RIGHT)
{
if (window->wl.decorations.focus != GLFW_MAIN_WINDOW &&
window->wl.xdg.toplevel)
if (window->wl.xdg.toplevel)
{
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
_glfw.wl.seat, serial,
window->wl.cursorPosX,
window->wl.cursorPosY);
return;
}
}
// Dont pass the button to the user if it was related to a decoration.
if (window->wl.decorations.focus != GLFW_MAIN_WINDOW)
return;
_glfw.wl.serial = serial;
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
* codes. */
glfwButton = button - BTN_LEFT;
_glfwInputMouseClick(window,
glfwButton,
state == WL_POINTER_BUTTON_STATE_PRESSED
? GLFW_PRESS
: GLFW_RELEASE,
_glfw.wl.xkb.modifiers);
}
}
static void pointerHandleAxis(void* userData,
@ -2028,8 +2050,8 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
window->wl.egl.window = wl_egl_window_create(window->wl.surface,
wndconfig->width,
wndconfig->height);
window->wl.fbWidth,
window->wl.fbHeight);
if (!window->wl.egl.window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -2094,8 +2116,8 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window)
destroyShellObjects(window);
if (window->wl.decorations.buffer)
wl_buffer_destroy(window->wl.decorations.buffer);
if (window->wl.fallback.buffer)
wl_buffer_destroy(window->wl.fallback.buffer);
if (window->wl.egl.window)
wl_egl_window_destroy(window->wl.egl.window);
@ -2105,7 +2127,7 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window)
_glfw_free(window->wl.title);
_glfw_free(window->wl.appId);
_glfw_free(window->wl.scales);
_glfw_free(window->wl.outputScales);
}
void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)
@ -2199,7 +2221,7 @@ void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window,
minwidth = minheight = 0;
else
{
if (window->wl.decorations.top.surface)
if (window->wl.fallback.decorations)
{
minwidth += GLFW_BORDER_SIZE * 2;
minheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;
@ -2210,7 +2232,7 @@ void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window,
maxwidth = maxheight = 0;
else
{
if (window->wl.decorations.top.surface)
if (window->wl.fallback.decorations)
{
maxwidth += GLFW_BORDER_SIZE * 2;
maxheight += GLFW_CAPTION_HEIGHT + GLFW_BORDER_SIZE;
@ -2262,18 +2284,17 @@ void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom)
void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height)
{
_glfwGetWindowSizeWayland(window, width, height);
if (width)
*width *= window->wl.contentScale;
*width = window->wl.fbWidth;
if (height)
*height *= window->wl.contentScale;
*height = window->wl.fbHeight;
}
void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom)
{
if (window->wl.decorations.top.surface)
if (window->wl.fallback.decorations)
{
if (top)
*top = GLFW_CAPTION_HEIGHT;
@ -2290,9 +2311,9 @@ void _glfwGetWindowContentScaleWayland(_GLFWwindow* window,
float* xscale, float* yscale)
{
if (xscale)
*xscale = (float) window->wl.contentScale;
*xscale = (float) window->wl.bufferScale;
if (yscale)
*yscale = (float) window->wl.contentScale;
*yscale = (float) window->wl.bufferScale;
}
void _glfwIconifyWindowWayland(_GLFWwindow* window)
@ -2919,11 +2940,8 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor)
// If we're not in the correct window just save the cursor
// the next time the pointer enters the window the cursor will change
if (window != _glfw.wl.pointerFocus ||
window->wl.decorations.focus != GLFW_MAIN_WINDOW)
{
if (!window->wl.hovered)
return;
}
// Update pointer lock to match cursor mode
if (window->cursorMode == GLFW_CURSOR_DISABLED)