Refactor the rendering of CSD on Wayland

This commit is contained in:
Kovid Goyal 2021-03-26 13:10:54 +05:30
parent 1e6fe7785a
commit aeb82e7fb0
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 311 additions and 185 deletions

View File

@ -66,6 +66,7 @@
"null_joystick.h",
"linux_notify.h",
"linux_desktop_settings.h",
"wl_client_side_decorations.h",
"main_loop.h"
],
"protocols": [
@ -84,6 +85,7 @@
"wl_window.c",
"wl_cursors.c",
"wl_text_input.c",
"wl_client_side_decorations.c",
"posix_thread.c",
"xkb_glfw.c",
"dbus_glfw.c",

200
glfw/wl_client_side_decorations.c vendored Normal file
View File

@ -0,0 +1,200 @@
/*
* wl_client_side_decorations.c
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "wl_client_side_decorations.h"
#include "backend_utils.h"
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#define decs window->wl.decorations
#define tb decs.title_bar
#define eb decs.edges
#define ARGB(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
static const uint32_t bg_color = 0xfffefefe;
static void
free_title_bar_resources(_GLFWwindow *window) {
if (tb.front_buffer) {
wl_buffer_destroy(tb.front_buffer);
tb.front_buffer = NULL;
}
if (tb.back_buffer) {
wl_buffer_destroy(tb.back_buffer);
tb.back_buffer = NULL;
}
if (tb.data) {
munmap(tb.data, tb.buffer_sz * 2);
tb.data = NULL;
}
}
static void
free_edge_resources(_GLFWwindow *window) {
if (eb.left) { wl_buffer_destroy(eb.left); eb.left = NULL; }
if (eb.right) { wl_buffer_destroy(eb.right); eb.right = NULL; }
if (eb.bottom) { wl_buffer_destroy(eb.bottom); eb.bottom = NULL; }
}
static bool
create_shm_buffers_for_title_bar(_GLFWwindow* window) {
free_title_bar_resources(window);
const size_t stride = 4 * window->wl.width;
tb.buffer_sz = stride * window->wl.decorations.metrics.top;
const size_t mapping_sz = tb.buffer_sz * 2;
int fd = createAnonymousFile(mapping_sz);
if (fd < 0) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Creating a buffer file for %zu B failed: %s",
mapping_sz, strerror(errno));
return false;
}
tb.data = mmap(NULL, mapping_sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (tb.data == MAP_FAILED) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: mmap failed: %s", strerror(errno));
close(fd);
return false;
}
for (uint32_t *px = (uint32_t*)tb.data, *end = (uint32_t*)(tb.data + tb.buffer_sz); px < end; px++) *px = bg_color;
struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, mapping_sz);
close(fd);
#define c(offset) wl_shm_pool_create_buffer( \
pool, offset, window->wl.width, window->wl.decorations.metrics.top, stride, WL_SHM_FORMAT_ARGB8888);
tb.front_buffer = c(0); tb.back_buffer = c(tb.buffer_sz);
#undef c
wl_shm_pool_destroy(pool);
return true;
}
static void
render_left_edge(uint8_t *data, size_t width, size_t height) {
for (uint32_t *px = (uint32_t*)data, *end = (uint32_t*)(data + 4 * width * height); px < end; px++) *px = bg_color;
}
#define render_right_edge render_left_edge
#define render_bottom_edge render_left_edge
static bool
create_shm_buffers_for_edges(_GLFWwindow* window) {
free_edge_resources(window);
const size_t vertical_width = window->wl.decorations.metrics.width, vertical_height = window->wl.height;
const size_t horizontal_height = window->wl.decorations.metrics.width, horizontal_width = window->wl.width;
const size_t mapping_sz = 4 * (2 * vertical_width * vertical_height + horizontal_height * horizontal_width);
int fd = createAnonymousFile(mapping_sz);
if (fd < 0) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Creating a buffer file for %zu B failed: %s",
mapping_sz, strerror(errno));
return false;
}
uint8_t *data = mmap(NULL, mapping_sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: mmap failed: %s", strerror(errno));
close(fd);
return false;
}
render_left_edge(data, vertical_width, vertical_height);
render_right_edge(data + 4 * vertical_width * vertical_height, vertical_width, vertical_height);
render_bottom_edge(data + 8 * vertical_width * vertical_height, horizontal_width, horizontal_height);
struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, mapping_sz);
close(fd);
eb.left = wl_shm_pool_create_buffer(
pool, 0, vertical_width, vertical_height, vertical_width * 4, WL_SHM_FORMAT_ARGB8888);
eb.right = wl_shm_pool_create_buffer(
pool, 4 * vertical_width * vertical_height, vertical_width, vertical_height, vertical_width * 4, WL_SHM_FORMAT_ARGB8888);
eb.bottom = wl_shm_pool_create_buffer(
pool, 8 * vertical_width * vertical_height, horizontal_width, horizontal_height, horizontal_width * 4, WL_SHM_FORMAT_ARGB8888);
wl_shm_pool_destroy(pool);
return true;
}
void
free_csd_surfaces(_GLFWwindow *window) {
#define d(which) {\
if (decs.subsurfaces.which) wl_subsurface_destroy(decs.subsurfaces.which); decs.subsurfaces.which = NULL; \
if (decs.surfaces.which) wl_surface_destroy(decs.surfaces.which); decs.surfaces.which = NULL; \
if (decs.viewports.which) wp_viewport_destroy(decs.viewports.which); \
}
d(left); d(top); d(right); d(bottom);
#undef d
}
#define position_decoration_surfaces(which, x, y, width, height) { \
wl_subsurface_set_position(decs.subsurfaces.which, x, y); \
wp_viewport_set_destination(decs.viewports.which, width, height); \
wl_surface_commit(decs.surfaces.which); \
}
#define create_decoration_surfaces(which, buffer) { \
decs.surfaces.which = wl_compositor_create_surface(_glfw.wl.compositor); \
decs.subsurfaces.which = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, decs.surfaces.which, window->wl.surface); \
decs.viewports.which = wp_viewporter_get_viewport(_glfw.wl.viewporter, decs.surfaces.which); \
wl_surface_attach(decs.surfaces.which, buffer, 0, 0); \
}
bool
ensure_csd_resources(_GLFWwindow *window) {
const bool size_changed = (
decs.for_window_size.width != window->wl.width ||
decs.for_window_size.height != window->wl.height ||
decs.for_window_size.scale != window->wl.scale
);
if (size_changed) {
free_title_bar_resources(window);
free_edge_resources(window);
}
if (!decs.edges.left) {
if (!create_shm_buffers_for_edges(window)) return false;
}
if (!decs.title_bar.front_buffer) {
if (!create_shm_buffers_for_title_bar(window)) return false;
}
int x, y, width, height;
x = 0; y = -decs.metrics.top;
width = window->wl.width; height = decs.metrics.top;
if (!decs.surfaces.top) create_decoration_surfaces(top, decs.title_bar.front_buffer);
position_decoration_surfaces(top, x, y, width, height);
x = -decs.metrics.width; y = -decs.metrics.top;
width = decs.metrics.width; height = decs.metrics.top + window->wl.height;
if (!decs.surfaces.left) create_decoration_surfaces(left, decs.edges.left);
position_decoration_surfaces(left, x, y, width, height);
x = window->wl.width; y = -decs.metrics.top;
if (!decs.surfaces.right) create_decoration_surfaces(right, decs.edges.right);
position_decoration_surfaces(right, x, y, width, height);
x = -decs.metrics.width; y = window->wl.height;
width = decs.metrics.horizontal + window->wl.width; height = decs.metrics.width;
if (!decs.surfaces.bottom) create_decoration_surfaces(bottom, decs.edges.bottom);
position_decoration_surfaces(bottom, x, y, width, height);
decs.for_window_size.width = window->wl.width;
decs.for_window_size.height = window->wl.height;
decs.for_window_size.scale = window->wl.scale;
return true;
}
void
free_all_csd_resources(_GLFWwindow *window) {
free_csd_surfaces(window);
free_title_bar_resources(window);
free_edge_resources(window);
}
void
resize_csd(_GLFWwindow *window) {
ensure_csd_resources(window);
}

14
glfw/wl_client_side_decorations.h vendored Normal file
View File

@ -0,0 +1,14 @@
/*
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#include "internal.h"
void free_all_csd_resources(_GLFWwindow *window);
void free_csd_surfaces(_GLFWwindow *window);
void resize_csd(_GLFWwindow *window);
bool ensure_csd_resources(_GLFWwindow *window);

87
glfw/wl_init.c vendored
View File

@ -29,6 +29,7 @@
#define _GNU_SOURCE
#include "internal.h"
#include "backend_utils.h"
#include "wl_client_side_decorations.h"
#include "linux_desktop_settings.h"
#include "../kitty/monotonic.h"
@ -59,37 +60,21 @@ static inline int min(int n1, int n2)
return n1 < n2 ? n1 : n2;
}
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
int* which)
static _GLFWwindow*
findWindowFromDecorationSurface(struct wl_surface* surface, _GLFWdecorationSideWayland* which)
{
int focus;
_GLFWdecorationSideWayland focus;
if (!which) which = &focus;
_GLFWwindow* window = _glfw.windowListHead;
if (!which)
which = &focus;
while (window)
{
if (surface == window->wl.decorations.top.surface)
{
*which = topDecoration;
break;
}
if (surface == window->wl.decorations.left.surface)
{
*which = leftDecoration;
break;
}
if (surface == window->wl.decorations.right.surface)
{
*which = rightDecoration;
break;
}
if (surface == window->wl.decorations.bottom.surface)
{
*which = bottomDecoration;
break;
}
#define q(edge, result) if (surface == window->wl.decorations.surfaces.edge) { *which = result; break; }
while (window) {
q(top, TOP_DECORATION);
q(left, LEFT_DECORATION);
q(right, RIGHT_DECORATION);
q(bottom, BOTTOM_DECORATION);
window = window->next;
}
#undef q
return window;
}
@ -104,7 +89,7 @@ static void pointerHandleEnter(void* data UNUSED,
if (!surface)
return;
int focus = 0;
_GLFWdecorationSideWayland focus = CENTRAL_WINDOW;
_GLFWwindow* window = wl_surface_get_user_data(surface);
if (!window)
{
@ -195,34 +180,34 @@ static void pointerHandleMotion(void* data UNUSED,
switch (window->wl.decorations.focus)
{
case mainWindow:
case CENTRAL_WINDOW:
window->wl.cursorPosX = x;
window->wl.cursorPosY = y;
_glfwInputCursorPos(window, x, y);
_glfw.wl.cursorPreviousShape = GLFW_INVALID_CURSOR;
return;
case topDecoration:
if (y < window->wl.decoration_metrics.width)
case TOP_DECORATION:
if (y < window->wl.decorations.metrics.width)
cursorShape = GLFW_VRESIZE_CURSOR;
else
cursorShape = GLFW_ARROW_CURSOR;
break;
case leftDecoration:
if (y < window->wl.decoration_metrics.width)
case LEFT_DECORATION:
if (y < window->wl.decorations.metrics.width)
cursorShape = GLFW_NW_RESIZE_CURSOR;
else
cursorShape = GLFW_HRESIZE_CURSOR;
break;
case rightDecoration:
if (y < window->wl.decoration_metrics.width)
case RIGHT_DECORATION:
if (y < window->wl.decorations.metrics.width)
cursorShape = GLFW_NE_RESIZE_CURSOR;
else
cursorShape = GLFW_HRESIZE_CURSOR;
break;
case bottomDecoration:
if (x < window->wl.decoration_metrics.width)
case BOTTOM_DECORATION:
if (x < window->wl.decorations.metrics.width)
cursorShape = GLFW_SW_RESIZE_CURSOR;
else if (x > window->wl.width + window->wl.decoration_metrics.width)
else if (x > window->wl.width + window->wl.decorations.metrics.width)
cursorShape = GLFW_SE_RESIZE_CURSOR;
else
cursorShape = GLFW_VRESIZE_CURSOR;
@ -251,10 +236,10 @@ static void pointerHandleButton(void* data UNUSED,
{
switch (window->wl.decorations.focus)
{
case mainWindow:
case CENTRAL_WINDOW:
break;
case topDecoration:
if (y < window->wl.decoration_metrics.width)
case TOP_DECORATION:
if (y < window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
else
{
@ -262,22 +247,22 @@ static void pointerHandleButton(void* data UNUSED,
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
}
break;
case leftDecoration:
if (y < window->wl.decoration_metrics.width)
case LEFT_DECORATION:
if (y < window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
break;
case rightDecoration:
if (y < window->wl.decoration_metrics.width)
case RIGHT_DECORATION:
if (y < window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
break;
case bottomDecoration:
if (x < window->wl.decoration_metrics.width)
case BOTTOM_DECORATION:
if (x < window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
else if (x > window->wl.width + window->wl.decoration_metrics.width)
else if (x > window->wl.width + window->wl.decorations.metrics.width)
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
else
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
@ -293,15 +278,15 @@ static void pointerHandleButton(void* data UNUSED,
}
else if (button == BTN_RIGHT)
{
if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel)
if (window->wl.decorations.focus != CENTRAL_WINDOW && window->wl.xdg.toplevel)
{
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, _glfw.wl.seat, serial, (int32_t)x, (int32_t)y - window->wl.decoration_metrics.top);
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel, _glfw.wl.seat, serial, (int32_t)x, (int32_t)y - window->wl.decorations.metrics.top);
return;
}
}
// Dont pass the button to the user if it was related to a decoration.
if (window->wl.decorations.focus != mainWindow)
if (window->wl.decorations.focus != CENTRAL_WINDOW)
return;
_glfw.wl.serial = serial;

58
glfw/wl_platform.h vendored
View File

@ -91,21 +91,13 @@ typedef void (* PFN_wl_egl_window_resize)(struct wl_egl_window*, int, int, int,
typedef enum _GLFWdecorationSideWayland
{
mainWindow,
topDecoration,
leftDecoration,
rightDecoration,
bottomDecoration,
CENTRAL_WINDOW,
TOP_DECORATION,
LEFT_DECORATION,
RIGHT_DECORATION,
BOTTOM_DECORATION,
} _GLFWdecorationSideWayland;
typedef struct _GLFWdecorationWayland
{
struct wl_surface* surface;
struct wl_subsurface* subsurface;
struct wp_viewport* viewport;
} _GLFWdecorationWayland;
// Wayland-specific per-window data
//
@ -150,10 +142,38 @@ typedef struct _GLFWwindowWayland
bool fullscreened;
struct {
bool serverSide;
struct wl_buffer* edge_buffer;
_GLFWdecorationWayland top, left, right, bottom;
int focus;
bool serverSide;
_GLFWdecorationSideWayland focus;
struct {
struct wl_surface *top, *left, *right, *bottom;
} surfaces;
struct {
struct wl_subsurface *top, *left, *right, *bottom;
} subsurfaces;
struct {
struct wp_viewport *top, *left, *right, *bottom;
} viewports;
struct {
struct wl_buffer *front_buffer, *back_buffer;
uint8_t *data;
size_t buffer_sz;
} title_bar;
struct {
struct wl_buffer *left, *right, *bottom;
} edges;
struct {
int width, height, scale;
} for_window_size;
struct {
unsigned int width, top, horizontal, vertical;
} metrics;
} decorations;
struct {
@ -162,10 +182,6 @@ typedef struct _GLFWwindowWayland
struct wl_callback *current_wl_callback;
} frameCallbackData;
struct {
unsigned int width, top, horizontal, vertical;
} decoration_metrics;
} _GLFWwindowWayland;
typedef enum _GLFWWaylandOfferType

135
glfw/wl_window.c vendored
View File

@ -32,6 +32,7 @@
#include "backend_utils.h"
#include "memfd.h"
#include "linux_notify.h"
#include "wl_client_side_decorations.h"
#include "../kitty/monotonic.h"
#include <stdio.h>
@ -221,32 +222,8 @@ static void resizeFramebuffer(_GLFWwindow* window)
setOpaqueRegion(window);
_glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
if (!window->wl.decorations.top.surface)
return;
if (window->wl.decorations.surfaces.top) resize_csd(window);
// Top decoration.
wp_viewport_set_destination(window->wl.decorations.top.viewport,
window->wl.width, window->wl.decoration_metrics.top);
wl_surface_commit(window->wl.decorations.top.surface);
// Left decoration.
wp_viewport_set_destination(window->wl.decorations.left.viewport,
window->wl.decoration_metrics.width, window->wl.height + window->wl.decoration_metrics.top);
wl_surface_commit(window->wl.decorations.left.surface);
// Right decoration.
wl_subsurface_set_position(window->wl.decorations.right.subsurface,
window->wl.width, -window->wl.decoration_metrics.top);
wp_viewport_set_destination(window->wl.decorations.right.viewport,
window->wl.decoration_metrics.width, window->wl.height + window->wl.decoration_metrics.top);
wl_surface_commit(window->wl.decorations.right.surface);
// Bottom decoration.
wl_subsurface_set_position(window->wl.decorations.bottom.subsurface,
-window->wl.decoration_metrics.width, window->wl.height);
wp_viewport_set_destination(window->wl.decorations.bottom.viewport,
window->wl.width + window->wl.decoration_metrics.horizontal, window->wl.decoration_metrics.width);
wl_surface_commit(window->wl.decorations.bottom.surface);
}
@ -280,75 +257,11 @@ static void dispatchChangesAfterConfigure(_GLFWwindow *window, int32_t width, in
}
static void createDecoration(_GLFWdecorationWayland* decoration,
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);
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);
wl_surface_commit(decoration->surface);
}
static void
createDecorations(_GLFWwindow* window) {
if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide) return;
static void createDecorations(_GLFWwindow* window)
{
unsigned char data[] = { 224, 224, 224, 255 };
const GLFWimage image = { 1, 1, data };
bool is_opaque = (data[3] == 255);
if (!_glfw.wl.viewporter || !window->decorated || window->wl.decorations.serverSide)
return;
if (!window->wl.decorations.edge_buffer)
window->wl.decorations.edge_buffer = createShmBuffer(&image, is_opaque, true);
if (!window->wl.decorations.edge_buffer)
return;
createDecoration(&window->wl.decorations.top, window->wl.surface,
window->wl.decorations.edge_buffer,
0, -window->wl.decoration_metrics.top,
window->wl.width, window->wl.decoration_metrics.top);
createDecoration(&window->wl.decorations.left, window->wl.surface,
window->wl.decorations.edge_buffer,
-window->wl.decoration_metrics.width, -window->wl.decoration_metrics.top,
window->wl.decoration_metrics.width, window->wl.height + window->wl.decoration_metrics.top);
createDecoration(&window->wl.decorations.right, window->wl.surface,
window->wl.decorations.edge_buffer,
window->wl.width, -window->wl.decoration_metrics.top,
window->wl.decoration_metrics.width, window->wl.height + window->wl.decoration_metrics.top);
createDecoration(&window->wl.decorations.bottom, window->wl.surface,
window->wl.decorations.edge_buffer,
-window->wl.decoration_metrics.width, window->wl.height,
window->wl.width + window->wl.decoration_metrics.horizontal, window->wl.decoration_metrics.width);
}
static void destroyDecoration(_GLFWdecorationWayland* decoration)
{
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;
}
static void destroyDecorations(_GLFWwindow* window)
{
destroyDecoration(&window->wl.decorations.top);
destroyDecoration(&window->wl.decorations.left);
destroyDecoration(&window->wl.decorations.right);
destroyDecoration(&window->wl.decorations.bottom);
ensure_csd_resources(window);
}
static void xdgDecorationHandleConfigure(void* data,
@ -474,8 +387,7 @@ static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, bool on)
xdg_toplevel_set_fullscreen(
window->wl.xdg.toplevel,
monitor ? monitor->wl.output : NULL);
if (!window->wl.decorations.serverSide)
destroyDecorations(window);
if (!window->wl.decorations.serverSide) free_csd_surfaces(window);
} else {
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
if (!_glfw.wl.decorationManager)
@ -541,9 +453,9 @@ static void xdgToplevelHandleConfigure(void* data,
}
window->wl.fullscreened = fullscreen;
if (!fullscreen) {
if (window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.edge_buffer) {
width -= window->wl.decoration_metrics.horizontal;
height -= window->wl.decoration_metrics.vertical;
if (window->decorated && !window->wl.decorations.serverSide && window->wl.decorations.edges.left) {
width -= window->wl.decorations.metrics.horizontal;
height -= window->wl.decorations.metrics.vertical;
}
}
dispatchChangesAfterConfigure(window, width, height);
@ -659,7 +571,7 @@ static bool createXdgSurface(_GLFWwindow* window)
static void incrementCursorImage(_GLFWwindow* window)
{
if (window && window->wl.decorations.focus == mainWindow && window->cursorMode != GLFW_CURSOR_HIDDEN) {
if (window && window->wl.decorations.focus == CENTRAL_WINDOW && window->cursorMode != GLFW_CURSOR_HIDDEN) {
_GLFWcursor* cursor = window->wl.currentCursor;
if (cursor && cursor->wl.cursor)
{
@ -802,10 +714,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
window->wl.decoration_metrics.width = 4;
window->wl.decoration_metrics.top = 24;
window->wl.decoration_metrics.horizontal = 2 * window->wl.decoration_metrics.width;
window->wl.decoration_metrics.vertical = window->wl.decoration_metrics.width + window->wl.decoration_metrics.top;
window->wl.decorations.metrics.width = 4;
window->wl.decorations.metrics.top = 24;
window->wl.decorations.metrics.horizontal = 2 * window->wl.decorations.metrics.width;
window->wl.decorations.metrics.vertical = window->wl.decorations.metrics.width + window->wl.decorations.metrics.top;
window->wl.transparent = fbconfig->transparent;
strncpy(window->wl.appId, wndconfig->wl.appId, sizeof(window->wl.appId));
@ -880,13 +792,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->context.destroy)
window->context.destroy(window);
destroyDecorations(window);
free_all_csd_resources(window);
if (window->wl.xdg.decoration)
zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
if (window->wl.decorations.edge_buffer)
wl_buffer_destroy(window->wl.decorations.edge_buffer);
if (window->wl.native)
wl_egl_window_destroy(window->wl.native);
@ -1010,13 +919,13 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
if (window->decorated && !window->monitor && !window->wl.decorations.serverSide)
{
if (top)
*top = window->wl.decoration_metrics.top;
*top = window->wl.decorations.metrics.top;
if (left)
*left = window->wl.decoration_metrics.width;
*left = window->wl.decorations.metrics.width;
if (right)
*right = window->wl.decoration_metrics.width;
*right = window->wl.decorations.metrics.width;
if (bottom)
*bottom = window->wl.decoration_metrics.width;
*bottom = window->wl.decorations.metrics.width;
}
}
@ -1176,7 +1085,7 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
if (enabled)
createDecorations(window);
else
destroyDecorations(window);
free_csd_surfaces(window);
}
}
@ -1435,7 +1344,7 @@ void _glfwPlatformSetCursor(_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 != mainWindow)
if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != CENTRAL_WINDOW)
return;
// Unlock possible pointer lock if no longer disabled.