mirror of
https://github.com/glfw/glfw.git
synced 2025-06-15 12:12:16 +00:00
wl: add decorations
This commit is contained in:
parent
7ec585b8eb
commit
2fad37473f
@ -44,11 +44,14 @@
|
||||
#include <wayland-client.h>
|
||||
|
||||
|
||||
const char *proxy_tag = "glfw-proxy";
|
||||
|
||||
static inline int min(int n1, int n2)
|
||||
{
|
||||
return n1 < n2 ? n1 : n2;
|
||||
}
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||
int* which)
|
||||
{
|
||||
@ -56,7 +59,6 @@ static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||
_GLFWwindow* window = _glfw.windowListHead;
|
||||
if (!which)
|
||||
which = &focus;
|
||||
#ifndef WITH_DECORATION
|
||||
while (window)
|
||||
{
|
||||
if (surface == window->wl.decorations.top.surface)
|
||||
@ -81,9 +83,22 @@ static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||
}
|
||||
window = window->next;
|
||||
}
|
||||
#endif
|
||||
return window;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
void decoration_error(struct libdecor *context,
|
||||
enum libdecor_error error,
|
||||
const char *message)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Caught error (%d): %s\n", error, message);
|
||||
}
|
||||
|
||||
static struct libdecor_interface decoration_interface = {
|
||||
decoration_error,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void pointerHandleEnter(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
@ -96,8 +111,16 @@ static void pointerHandleEnter(void* data,
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
int focus = 0;
|
||||
if (wl_proxy_get_tag((struct wl_proxy *) surface) != &proxy_tag)
|
||||
return;
|
||||
|
||||
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
if (surface != window->wl.surface)
|
||||
return;
|
||||
#else
|
||||
int focus = 0;
|
||||
if (!window)
|
||||
{
|
||||
window = findWindowFromDecorationSurface(surface, &focus);
|
||||
@ -105,7 +128,6 @@ static void pointerHandleEnter(void* data,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
window->wl.decorations.focus = focus;
|
||||
#endif
|
||||
|
||||
@ -196,10 +218,16 @@ static void pointerHandleMotion(void* data,
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
x = wl_fixed_to_double(sx);
|
||||
y = wl_fixed_to_double(sy);
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
#ifdef WITH_DECORATION
|
||||
window->wl.cursorPosX = x;
|
||||
window->wl.cursorPosY = y;
|
||||
_glfwInputCursorPos(window, x, y);
|
||||
_glfw.wl.cursorPreviousName = NULL;
|
||||
#else
|
||||
switch (window->wl.decorations.focus)
|
||||
{
|
||||
case mainWindow:
|
||||
@ -251,11 +279,11 @@ static void pointerHandleButton(void* data,
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
int glfwButton;
|
||||
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
#ifndef WITH_DECORATION
|
||||
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||
if (button == BTN_LEFT)
|
||||
{
|
||||
switch (window->wl.decorations.focus)
|
||||
@ -477,13 +505,21 @@ static void keyboardHandleEnter(void* data,
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
if (wl_proxy_get_tag((struct wl_proxy *) surface) != &proxy_tag)
|
||||
return;
|
||||
|
||||
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
||||
#ifdef WITH_DECORATION
|
||||
if (surface != window->wl.surface)
|
||||
return;
|
||||
#else
|
||||
if (!window)
|
||||
{
|
||||
window = findWindowFromDecorationSurface(surface, NULL);
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
_glfw.wl.serial = serial;
|
||||
_glfw.wl.keyboardFocus = window;
|
||||
@ -778,6 +814,7 @@ static const struct wl_data_device_listener dataDeviceListener = {
|
||||
dataDeviceHandleSelection,
|
||||
};
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
static void wmBaseHandlePing(void* data,
|
||||
struct xdg_wm_base* wmBase,
|
||||
uint32_t serial)
|
||||
@ -788,6 +825,7 @@ static void wmBaseHandlePing(void* data,
|
||||
static const struct xdg_wm_base_listener wmBaseListener = {
|
||||
wmBaseHandlePing
|
||||
};
|
||||
#endif
|
||||
|
||||
static void registryHandleGlobal(void* data,
|
||||
struct wl_registry* registry,
|
||||
@ -836,6 +874,7 @@ static void registryHandleGlobal(void* data,
|
||||
&wl_data_device_manager_interface, 1);
|
||||
}
|
||||
}
|
||||
#ifndef WITH_DECORATION
|
||||
else if (strcmp(interface, "xdg_wm_base") == 0)
|
||||
{
|
||||
_glfw.wl.wmBase =
|
||||
@ -849,7 +888,6 @@ static void registryHandleGlobal(void* data,
|
||||
&zxdg_decoration_manager_v1_interface,
|
||||
1);
|
||||
}
|
||||
#ifndef WITH_DECORATION
|
||||
else if (strcmp(interface, "wp_viewporter") == 0)
|
||||
{
|
||||
_glfw.wl.viewporter =
|
||||
@ -1163,12 +1201,14 @@ int _glfwPlatformInit(void)
|
||||
if (_glfw.wl.seatVersion >= 4)
|
||||
_glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
if (!_glfw.wl.wmBase)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to find xdg-shell in your compositor");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_glfw.wl.pointer && _glfw.wl.shm)
|
||||
{
|
||||
@ -1214,6 +1254,10 @@ int _glfwPlatformInit(void)
|
||||
_glfw.wl.clipboardSize = 4096;
|
||||
}
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
_glfw.wl.csd_context = libdecor_new(_glfw.wl.display, &decoration_interface);
|
||||
#endif
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
@ -1260,14 +1304,16 @@ void _glfwPlatformTerminate(void)
|
||||
wl_compositor_destroy(_glfw.wl.compositor);
|
||||
if (_glfw.wl.shm)
|
||||
wl_shm_destroy(_glfw.wl.shm);
|
||||
#ifndef WITH_DECORATION
|
||||
#ifdef WITH_DECORATION
|
||||
libdecor_unref(_glfw.wl.csd_context);
|
||||
#else
|
||||
if (_glfw.wl.viewporter)
|
||||
wp_viewporter_destroy(_glfw.wl.viewporter);
|
||||
#endif
|
||||
if (_glfw.wl.decorationManager)
|
||||
zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager);
|
||||
if (_glfw.wl.wmBase)
|
||||
xdg_wm_base_destroy(_glfw.wl.wmBase);
|
||||
#endif
|
||||
if (_glfw.wl.dataSource)
|
||||
wl_data_source_destroy(_glfw.wl.dataSource);
|
||||
if (_glfw.wl.dataDevice)
|
||||
|
@ -54,15 +54,18 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
#endif
|
||||
#include "xkb_unicode.h"
|
||||
|
||||
#include "wayland-xdg-shell-client-protocol.h"
|
||||
#include "wayland-xdg-decoration-client-protocol.h"
|
||||
#ifndef WITH_DECORATION
|
||||
#include "wayland-viewporter-client-protocol.h"
|
||||
#endif
|
||||
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
#include <libdecor.h>
|
||||
#else
|
||||
#include "wayland-xdg-shell-client-protocol.h"
|
||||
#include "wayland-xdg-decoration-client-protocol.h"
|
||||
#include "wayland-viewporter-client-protocol.h"
|
||||
#endif
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||
@ -181,11 +184,13 @@ typedef struct _GLFWwindowWayland
|
||||
struct wl_egl_window* native;
|
||||
struct wl_callback* callback;
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
struct {
|
||||
struct xdg_surface* surface;
|
||||
struct xdg_toplevel* toplevel;
|
||||
struct zxdg_toplevel_decoration_v1* decoration;
|
||||
} xdg;
|
||||
#endif
|
||||
|
||||
_GLFWcursor* currentCursor;
|
||||
double cursorPosX, cursorPosY;
|
||||
@ -216,7 +221,7 @@ typedef struct _GLFWwindowWayland
|
||||
int focus;
|
||||
} decorations;
|
||||
#else
|
||||
GLFWbool ssd;
|
||||
struct libdecor_frame *decoration_frame;
|
||||
#endif
|
||||
|
||||
} _GLFWwindowWayland;
|
||||
@ -237,9 +242,11 @@ typedef struct _GLFWlibraryWayland
|
||||
struct wl_data_device* dataDevice;
|
||||
struct wl_data_offer* dataOffer;
|
||||
struct wl_data_source* dataSource;
|
||||
#ifdef WITH_DECORATION
|
||||
struct libdecor *csd_context;
|
||||
#else
|
||||
struct xdg_wm_base* wmBase;
|
||||
struct zxdg_decoration_manager_v1* decorationManager;
|
||||
#ifndef WITH_DECORATION
|
||||
struct wp_viewporter* viewporter;
|
||||
#endif
|
||||
struct zwp_relative_pointer_manager_v1* relativePointerManager;
|
||||
|
273
src/wl_window.c
273
src/wl_window.c
@ -41,10 +41,12 @@
|
||||
#include <poll.h>
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
#include <libdecoration.h>
|
||||
#include <libdecor.h>
|
||||
#endif
|
||||
|
||||
|
||||
extern const char *proxy_tag;
|
||||
|
||||
static int createTmpfileCloexec(char* tmpname)
|
||||
{
|
||||
int fd;
|
||||
@ -186,7 +188,61 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
#ifdef WITH_DECORATION
|
||||
static void resizeWindow(_GLFWwindow* window);
|
||||
void frame_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *user_data)
|
||||
{
|
||||
_GLFWwindow* window = user_data;
|
||||
|
||||
int width, height;
|
||||
if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
|
||||
width = window->wl.width;
|
||||
height = window->wl.height;
|
||||
}
|
||||
|
||||
window->wl.width = width;
|
||||
window->wl.height = height;
|
||||
resizeWindow(window);
|
||||
|
||||
_glfwInputWindowSize(window, width, height);
|
||||
_glfwPlatformSetWindowSize(window, width, height);
|
||||
_glfwInputWindowDamage(window);
|
||||
|
||||
struct libdecor_state *state = libdecor_state_new(width, height);
|
||||
libdecor_frame_commit(frame, state, configuration);
|
||||
libdecor_state_free(state);
|
||||
}
|
||||
|
||||
void frame_close(struct libdecor_frame *frame, void *user_data)
|
||||
{
|
||||
_glfwInputWindowCloseRequest(user_data);
|
||||
}
|
||||
|
||||
void frame_commit(struct libdecor_frame *frame, void *user_data)
|
||||
{
|
||||
_GLFWwindow* window = user_data;
|
||||
|
||||
_glfwInputWindowDamage(window);
|
||||
}
|
||||
|
||||
static struct libdecor_frame_interface frame_interface = {
|
||||
frame_configure,
|
||||
frame_close,
|
||||
frame_commit,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
static void createDecorations(_GLFWwindow* window)
|
||||
{
|
||||
// TODO: enable decoration
|
||||
}
|
||||
|
||||
static void destroyDecorations(_GLFWwindow* window)
|
||||
{
|
||||
// TODO: disable decoration
|
||||
}
|
||||
#else
|
||||
static void createDecoration(_GLFWdecorationWayland* decoration,
|
||||
struct wl_surface* parent,
|
||||
struct wl_buffer* buffer, GLFWbool opaque,
|
||||
@ -216,14 +272,7 @@ static void createDecoration(_GLFWdecorationWayland* decoration,
|
||||
else
|
||||
wl_surface_commit(decoration->surface);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
static void createDecorations(_GLFWwindow* window)
|
||||
{
|
||||
//
|
||||
}
|
||||
#else
|
||||
static void createDecorations(_GLFWwindow* window)
|
||||
{
|
||||
unsigned char data[] = { 224, 224, 224, 255 };
|
||||
@ -255,9 +304,7 @@ static void createDecorations(_GLFWwindow* window)
|
||||
-_GLFW_DECORATION_WIDTH, window->wl.height,
|
||||
window->wl.width + _GLFW_DECORATION_HORIZONTAL, _GLFW_DECORATION_WIDTH);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
static void destroyDecoration(_GLFWdecorationWayland* decoration)
|
||||
{
|
||||
if (decoration->subsurface)
|
||||
@ -270,14 +317,7 @@ static void destroyDecoration(_GLFWdecorationWayland* decoration)
|
||||
decoration->subsurface = NULL;
|
||||
decoration->viewport = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
static void destroyDecorations(_GLFWwindow* window)
|
||||
{
|
||||
//
|
||||
}
|
||||
#else
|
||||
static void destroyDecorations(_GLFWwindow* window)
|
||||
{
|
||||
destroyDecoration(&window->wl.decorations.top);
|
||||
@ -287,23 +327,21 @@ static void destroyDecorations(_GLFWwindow* window)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
static void xdgDecorationHandleConfigure(void* data,
|
||||
struct zxdg_toplevel_decoration_v1* decoration,
|
||||
uint32_t mode)
|
||||
{
|
||||
_GLFWwindow* window = data;
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
if (!(window->wl.ssd = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE)))
|
||||
#else
|
||||
if (!(window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE)))
|
||||
#endif
|
||||
createDecorations(window);
|
||||
}
|
||||
|
||||
static const struct zxdg_toplevel_decoration_v1_listener xdgDecorationListener = {
|
||||
xdgDecorationHandleConfigure,
|
||||
};
|
||||
#endif
|
||||
|
||||
// Makes the surface considered as XRGB instead of ARGB.
|
||||
static void setOpaqueRegion(_GLFWwindow* window)
|
||||
@ -392,6 +430,9 @@ static void surfaceHandleEnter(void *data,
|
||||
struct wl_surface *surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
if (wl_proxy_get_tag((struct wl_proxy *) output) != &proxy_tag)
|
||||
return;
|
||||
|
||||
_GLFWwindow* window = data;
|
||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||
|
||||
@ -412,6 +453,9 @@ static void surfaceHandleLeave(void *data,
|
||||
struct wl_surface *surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
if (wl_proxy_get_tag((struct wl_proxy *) output) != &proxy_tag)
|
||||
return;
|
||||
|
||||
_GLFWwindow* window = data;
|
||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||
GLFWbool found;
|
||||
@ -452,8 +496,7 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
|
||||
}
|
||||
}
|
||||
|
||||
static GLFWbool createSurface(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig)
|
||||
static GLFWbool createSurface(_GLFWwindow* window)
|
||||
{
|
||||
window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
|
||||
if (!window->wl.surface)
|
||||
@ -464,41 +507,60 @@ static GLFWbool createSurface(_GLFWwindow* window,
|
||||
window);
|
||||
|
||||
wl_surface_set_user_data(window->wl.surface, window);
|
||||
wl_proxy_set_tag((struct wl_proxy *) window->wl.surface, &proxy_tag);
|
||||
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
|
||||
window->wl.native = wl_egl_window_create(window->wl.surface,
|
||||
wndconfig->width,
|
||||
wndconfig->height);
|
||||
window->wl.width,
|
||||
window->wl.height);
|
||||
if (!window->wl.native)
|
||||
return GLFW_FALSE;
|
||||
|
||||
window->wl.width = wndconfig->width;
|
||||
window->wl.height = wndconfig->height;
|
||||
window->wl.scale = 1;
|
||||
|
||||
if (!window->wl.transparent)
|
||||
setOpaqueRegion(window);
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
static GLFWbool createSurfaceDecoration(_GLFWwindow* window)
|
||||
{
|
||||
window->wl.decoration_frame = libdecor_decorate(_glfw.wl.csd_context,
|
||||
window->wl.surface,
|
||||
&frame_interface,
|
||||
window);
|
||||
libdecor_frame_map(window->wl.decoration_frame);
|
||||
|
||||
window->wl.scale = 1;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor,
|
||||
int refreshRate)
|
||||
{
|
||||
#ifdef WITH_DECORATION
|
||||
libdecor_frame_set_fullscreen(window->wl.decoration_frame, monitor->wl.output);
|
||||
#else
|
||||
if (window->wl.xdg.toplevel)
|
||||
{
|
||||
xdg_toplevel_set_fullscreen(
|
||||
window->wl.xdg.toplevel,
|
||||
monitor->wl.output);
|
||||
}
|
||||
setIdleInhibitor(window, GLFW_TRUE);
|
||||
#ifdef WITH_DECORATION
|
||||
if (!window->wl.ssd)
|
||||
#else
|
||||
if (!window->wl.decorations.serverSide)
|
||||
#endif
|
||||
setIdleInhibitor(window, GLFW_TRUE);
|
||||
#ifndef WITH_DECORATION
|
||||
if (!window->wl.decorations.serverSide)
|
||||
destroyDecorations(window);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
|
||||
static void xdgToplevelHandleConfigure(void* data,
|
||||
struct xdg_toplevel* toplevel,
|
||||
int32_t width,
|
||||
@ -603,11 +665,7 @@ static void setXdgDecorations(_GLFWwindow* window)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WITH_DECORATION
|
||||
window->wl.ssd = GLFW_FALSE;
|
||||
#else
|
||||
window->wl.decorations.serverSide = GLFW_FALSE;
|
||||
#endif
|
||||
createDecorations(window);
|
||||
}
|
||||
}
|
||||
@ -672,6 +730,7 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void setCursorImage(_GLFWwindow* window,
|
||||
_GLFWcursorWayland* cursorWayland)
|
||||
@ -825,7 +884,17 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
{
|
||||
window->wl.transparent = fbconfig->transparent;
|
||||
|
||||
if (!createSurface(window, wndconfig))
|
||||
window->wl.visible = wndconfig->visible;
|
||||
window->wl.width = wndconfig->width;
|
||||
window->wl.height = wndconfig->height;
|
||||
|
||||
// TODO: enable visibility support
|
||||
window->wl.visible = GLFW_TRUE;
|
||||
|
||||
// unsupported on Wayland by design
|
||||
window->focusOnShow = GLFW_FALSE;
|
||||
|
||||
if (!createSurface(window))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
@ -847,9 +916,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
if (wndconfig->title)
|
||||
window->wl.title = _glfw_strdup(wndconfig->title);
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
if (wndconfig->visible)
|
||||
{
|
||||
if (!createXdgSurface(window))
|
||||
@ -863,6 +930,16 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
window->wl.xdg.toplevel = NULL;
|
||||
window->wl.visible = GLFW_FALSE;
|
||||
}
|
||||
#else
|
||||
if (!createSurfaceDecoration(window))
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
|
||||
window->wl.scale = 1;
|
||||
|
||||
_glfwPlatformSetWindowTitle(window, wndconfig->title);
|
||||
|
||||
_glfwPlatformSetWindowResizable(window, wndconfig->resizable);
|
||||
|
||||
if (window->monitor)
|
||||
setFullscreen(window, window->monitor, window->videoMode.refreshRate);
|
||||
@ -873,6 +950,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
window->wl.monitorsCount = 0;
|
||||
window->wl.monitorsSize = 1;
|
||||
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
@ -896,9 +975,11 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
window->context.destroy(window);
|
||||
|
||||
destroyDecorations(window);
|
||||
#ifdef WITH_DECORATION
|
||||
libdecor_frame_unref(window->wl.decoration_frame);
|
||||
#else
|
||||
if (window->wl.xdg.decoration)
|
||||
zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
|
||||
#ifndef WITH_DECORATION
|
||||
if (window->wl.decorations.buffer)
|
||||
wl_buffer_destroy(window->wl.decorations.buffer);
|
||||
#endif
|
||||
@ -906,11 +987,13 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
if (window->wl.native)
|
||||
wl_egl_window_destroy(window->wl.native);
|
||||
|
||||
#ifndef WITH_DECORATION
|
||||
if (window->wl.xdg.toplevel)
|
||||
xdg_toplevel_destroy(window->wl.xdg.toplevel);
|
||||
|
||||
if (window->wl.xdg.surface)
|
||||
xdg_surface_destroy(window->wl.xdg.surface);
|
||||
#endif
|
||||
|
||||
if (window->wl.surface)
|
||||
wl_surface_destroy(window->wl.surface);
|
||||
@ -924,8 +1007,15 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
if (window->wl.title)
|
||||
free(window->wl.title);
|
||||
window->wl.title = _glfw_strdup(title);
|
||||
if (window->wl.xdg.toplevel)
|
||||
xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
|
||||
|
||||
#ifdef WITH_DECORATION
|
||||
if (window->wl.decoration_frame) {
|
||||
libdecor_frame_set_title(window->wl.decoration_frame, window->wl.title);
|
||||
libdecor_frame_set_app_id(window->wl.decoration_frame, window->wl.title);
|
||||
}
|
||||
#else
|
||||
xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
@ -971,16 +1061,23 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||
int minwidth, int minheight,
|
||||
int maxwidth, int maxheight)
|
||||
{
|
||||
if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
|
||||
minwidth = minheight = 0;
|
||||
if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)
|
||||
maxwidth = maxheight = 0;
|
||||
#ifdef WITH_DECORATION
|
||||
libdecor_frame_set_min_content_size(window->wl.decoration_frame,
|
||||
minwidth, minheight);
|
||||
libdecor_frame_set_max_content_size(window->wl.decoration_frame,
|
||||
maxwidth, maxheight);
|
||||
#else
|
||||
if (window->wl.xdg.toplevel)
|
||||
{
|
||||
if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
|
||||
minwidth = minheight = 0;
|
||||
if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)
|
||||
maxwidth = maxheight = 0;
|
||||
xdg_toplevel_set_min_size(window->wl.xdg.toplevel, minwidth, minheight);
|
||||
xdg_toplevel_set_max_size(window->wl.xdg.toplevel, maxwidth, maxheight);
|
||||
wl_surface_commit(window->wl.surface);
|
||||
}
|
||||
#endif
|
||||
wl_surface_commit(window->wl.surface);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window,
|
||||
@ -1032,31 +1129,37 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
||||
|
||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
xdg_toplevel_set_minimized(window->wl.xdg.toplevel);
|
||||
#ifdef WITH_DECORATION
|
||||
libdecor_frame_set_minimized(window->wl.decoration_frame);
|
||||
#else
|
||||
xdg_toplevel_set_minimized(window->wl.xdg.toplevel);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
{
|
||||
if (window->monitor)
|
||||
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
|
||||
if (window->wl.maximized)
|
||||
xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
|
||||
// There is no way to unset minimized, or even to know if we are
|
||||
// minimized, so there is nothing to do in this case.
|
||||
}
|
||||
#ifdef WITH_DECORATION
|
||||
libdecor_frame_unset_fullscreen(window->wl.decoration_frame);
|
||||
libdecor_frame_unset_maximized(window->wl.decoration_frame);
|
||||
#else
|
||||
if (window->monitor)
|
||||
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
|
||||
if (window->wl.maximized)
|
||||
xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
|
||||
// There is no way to unset minimized, or even to know if we are
|
||||
// minimized, so there is nothing to do in this case.
|
||||
#endif
|
||||
_glfwInputWindowMonitor(window, NULL);
|
||||
window->wl.maximized = GLFW_FALSE;
|
||||
}
|
||||
|
||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
{
|
||||
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
||||
}
|
||||
#ifdef WITH_DECORATION
|
||||
libdecor_frame_set_maximized(window->wl.decoration_frame);
|
||||
#else
|
||||
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
||||
#endif
|
||||
window->wl.maximized = GLFW_TRUE;
|
||||
}
|
||||
|
||||
@ -1064,13 +1167,18 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->wl.visible)
|
||||
{
|
||||
createXdgSurface(window);
|
||||
window->wl.visible = GLFW_TRUE;
|
||||
#ifndef WITH_DECORATION
|
||||
createXdgSurface(window);
|
||||
#else
|
||||
// TODO: enable visibility support
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||
{
|
||||
#ifndef WITH_DECORATION
|
||||
if (window->wl.xdg.toplevel)
|
||||
{
|
||||
xdg_toplevel_destroy(window->wl.xdg.toplevel);
|
||||
@ -1078,6 +1186,9 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||
window->wl.xdg.toplevel = NULL;
|
||||
window->wl.xdg.surface = NULL;
|
||||
}
|
||||
#else
|
||||
// TODO: enable visibility support
|
||||
#endif
|
||||
window->wl.visible = GLFW_FALSE;
|
||||
}
|
||||
|
||||
@ -1106,11 +1217,14 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
|
||||
#ifdef WITH_DECORATION
|
||||
libdecor_frame_unset_fullscreen(window->wl.decoration_frame);
|
||||
#else
|
||||
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
|
||||
setIdleInhibitor(window, GLFW_FALSE);
|
||||
if (!_glfw.wl.decorationManager)
|
||||
createDecorations(window);
|
||||
#endif
|
||||
}
|
||||
_glfwInputWindowMonitor(window, monitor);
|
||||
}
|
||||
@ -1149,9 +1263,14 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||
"Wayland: Window attribute setting not implemented yet");
|
||||
#ifdef WITH_DECORATION
|
||||
if (enabled)
|
||||
libdecor_frame_set_capabilities(window->wl.decoration_frame,
|
||||
LIBDECOR_ACTION_RESIZE);
|
||||
else
|
||||
libdecor_frame_unset_capabilities(window->wl.decoration_frame,
|
||||
LIBDECOR_ACTION_RESIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
@ -1167,9 +1286,13 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||
"Wayland: Window attribute setting not implemented yet");
|
||||
#ifdef WITH_DECORATION
|
||||
if (window->wl.maximized)
|
||||
libdecor_frame_unset_maximized(window->wl.decoration_frame);
|
||||
|
||||
if (window->wl.wasFullscreen)
|
||||
libdecor_frame_unset_fullscreen(window->wl.decoration_frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled)
|
||||
|
Loading…
Reference in New Issue
Block a user