aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorEncryptedCicada2021-12-16 10:08:32 +0530
committerEncryptedCicada2021-12-16 10:08:32 +0530
commit3c94b47ff80eb81fae96049b4ed1b26657afe390 (patch)
treec2c5fdf23620dd295d3fb160804669d5be5dd668
downloadaur-3c94b47ff80eb81fae96049b4ed1b26657afe390.tar.gz
Initial upload
-rw-r--r--.SRCINFO40
-rw-r--r--.gitignore6
-rw-r--r--0001-libdecoration-support.patch1328
-rw-r--r--0002-set-O_NONBLOCK-on-repeat-timerfd.patch33
-rw-r--r--0003-Continue-poll-if-timerfd-cant-be-read.patch46
-rw-r--r--0003-wayland-don-t-crash-app-on-api-calls-to-window-focus.patch39
-rw-r--r--0004-fix-broken-opengl-screenshots-on-mutter.patch33
-rw-r--r--0005-don-t-crash-on-get-scancode-name.patch10
-rw-r--r--PKGBUILD66
-rw-r--r--README.md104
10 files changed, 1705 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..e6fd301bbdd7
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,40 @@
+pkgbase = glfw-wayland-minecraft-libdecoration
+ pkgdesc = A free, open source, portable framework for graphical application development (wayland, patched for Minecraft and Gnome)
+ pkgver = 3.4.0
+ pkgrel = 1
+ url = https://github.com/EncryptedCicada/minecraft-wayland
+ arch = x86_64
+ license = custom:ZLIB
+ makedepends = mesa
+ makedepends = cmake
+ makedepends = doxygen
+ makedepends = vulkan-headers
+ makedepends = vulkan-icd-loader
+ makedepends = extra-cmake-modules
+ makedepends = wayland-protocols
+ makedepends = libxi
+ makedepends = libxrandr
+ makedepends = libxcursor
+ makedepends = libxkbcommon
+ makedepends = libxinerama
+ depends = wayland
+ depends = libxkbcommon
+ depends = libgl
+ depends = libdecor
+ provides = glfw=3.4.0
+ conflicts = glfw
+ conflicts = glfw-wayland
+ source = https://github.com/glfw/glfw/archive/87d5646f5d2bad0562744501633bf8105f59c193.tar.gz
+ source = 0001-libdecoration-support.patch
+ source = 0002-set-O_NONBLOCK-on-repeat-timerfd.patch
+ source = 0003-wayland-don-t-crash-app-on-api-calls-to-window-focus.patch
+ source = 0004-fix-broken-opengl-screenshots-on-mutter.patch
+ source = 0005-don-t-crash-on-get-scancode-name.patch
+ sha256sums = 7b8c990cfb039110d38c7f5bb21948c402933be3f93f333fe7dcda3deaf72aa4
+ sha256sums = c163b4a0a6496d758bc656203c23151015683754a6b5c2fc4944df7296d6b5af
+ sha256sums = 5cd74a83dc7824c7696c1534f880b7a4a0992bb6dba6e4531ad1c040541f1d30
+ sha256sums = a442f8c7e40fb09775f922b95402108b366114874ee96e370c29e5f8500a02b7
+ sha256sums = 27aea70b07df2d46ac7469c129d28d695eff1ec9492489aa7b2558dd780ebdf0
+ sha256sums = 16a2410511d75f00902ab1869942a80d85261f8390a97be946f82662891351e5
+
+pkgname = glfw-wayland-minecraft-libdecoration
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000000..d53251af9d26
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+*
+!*.patch
+!.SRCINFO
+!.gitignore
+!PKGBUILD
+!README.md \ No newline at end of file
diff --git a/0001-libdecoration-support.patch b/0001-libdecoration-support.patch
new file mode 100644
index 000000000000..3a33e93990b6
--- /dev/null
+++ b/0001-libdecoration-support.patch
@@ -0,0 +1,1328 @@
+From 96ad19143d8d20553bfb86d440faaaf91eaff955 Mon Sep 17 00:00:00 2001
+From: Christian Rauch <Rauch.Christian@gmx.de>
+Date: Sun, 12 Apr 2020 14:21:03 +0100
+Subject: [PATCH 1/8] wl: fix resize glitches
+
+---
+ src/wl_window.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/src/wl_window.c b/src/wl_window.c
+index 939f9c196..3899c858c 100644
+--- a/src/wl_window.c
++++ b/src/wl_window.c
+@@ -292,7 +292,6 @@ static void setOpaqueRegion(_GLFWwindow* window)
+
+ wl_region_add(region, 0, 0, window->wl.width, window->wl.height);
+ wl_surface_set_opaque_region(window->wl.surface, region);
+- wl_surface_commit(window->wl.surface);
+ wl_region_destroy(region);
+ }
+
+
+From 69f6e358e266581ec21d3e602c626d54abb06b39 Mon Sep 17 00:00:00 2001
+From: Christian Rauch <Rauch.Christian@gmx.de>
+Date: Sat, 9 May 2020 21:06:23 +0100
+Subject: [PATCH 2/8] wl: initialise fullscreen
+
+---
+ src/wl_window.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/wl_window.c b/src/wl_window.c
+index 3899c858c..46cd742c6 100644
+--- a/src/wl_window.c
++++ b/src/wl_window.c
+@@ -826,6 +826,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
+ window->wl.visible = GLFW_FALSE;
+ }
+
++ if (window->monitor)
++ setFullscreen(window, window->monitor, window->videoMode.refreshRate);
++
+ window->wl.currentCursor = NULL;
+
+ window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));
+
+From ce0e2096b556c6753b8c21ec841b09321f9ee54e Mon Sep 17 00:00:00 2001
+From: Christian Rauch <Rauch.Christian@gmx.de>
+Date: Mon, 3 May 2021 23:46:21 +0100
+Subject: [PATCH 3/8] make windows opaque by default
+
+---
+ src/window.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/window.c b/src/window.c
+index 518b27fd5..688971f36 100644
+--- a/src/window.c
++++ b/src/window.c
+@@ -279,7 +279,7 @@ void glfwDefaultWindowHints(void)
+ _glfw.hints.framebuffer.redBits = 8;
+ _glfw.hints.framebuffer.greenBits = 8;
+ _glfw.hints.framebuffer.blueBits = 8;
+- _glfw.hints.framebuffer.alphaBits = 8;
++ _glfw.hints.framebuffer.alphaBits = 0;
+ _glfw.hints.framebuffer.depthBits = 24;
+ _glfw.hints.framebuffer.stencilBits = 8;
+ _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;
+
+From 5df88303d22f5fd0861b6b8023e795c84ef31ae9 Mon Sep 17 00:00:00 2001
+From: Christian Rauch <Rauch.Christian@gmx.de>
+Date: Fri, 19 Jun 2020 00:05:12 +0100
+Subject: [PATCH 4/8] cmake: enable AddressSanitizer in Debug builds
+
+---
+ CMakeLists.txt | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 59ab473c9..fb9fab99a 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -66,6 +66,25 @@ if (GLFW_BUILD_DOCS)
+ find_package(Doxygen)
+ endif()
+
++if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
++ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} \
++ -fsanitize=address \
++ -fsanitize=bool \
++ -fsanitize=bounds \
++ -fsanitize=enum \
++ -fsanitize=float-cast-overflow \
++ -fsanitize=float-divide-by-zero \
++ -fsanitize=nonnull-attribute \
++ -fsanitize=returns-nonnull-attribute \
++ -fsanitize=signed-integer-overflow \
++ -fsanitize=undefined \
++ -fsanitize=vla-bound \
++ -fno-sanitize=alignment \
++ -fsanitize=leak \
++ -fsanitize=object-size \
++ ")
++endif()
++
+ #--------------------------------------------------------------------
+ # Set compiler specific flags
+ #--------------------------------------------------------------------
+
+From 8b539bd285d2b7abc3511286f34bffbdc78c9837 Mon Sep 17 00:00:00 2001
+From: Christian Rauch <Rauch.Christian@gmx.de>
+Date: Fri, 16 Jul 2021 23:40:45 +0100
+Subject: [PATCH 5/8] CI: install libdecor from upstream
+
+---
+ .github/workflows/build.yml | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
+index d87ae8d1d..efe120a3c 100644
+--- a/.github/workflows/build.yml
++++ b/.github/workflows/build.yml
+@@ -43,6 +43,12 @@ jobs:
+ run: |
+ sudo apt update
+ sudo apt install wayland-protocols libwayland-dev libxkbcommon-dev
++ sudo apt install meson libpango1.0-dev
++ git clone --depth 1 https://gitlab.gnome.org/jadahl/libdecor.git --branch 0.1.0
++ cd libdecor
++ meson build --buildtype release -Ddemo=false -Ddbus=disabled
++ ninja -C build
++ sudo meson install -C build
+
+ - name: Configure static library
+ run: cmake -S . -B build-static -D GLFW_USE_WAYLAND=ON
+
+From b2ecb88f3f2cf7bccbf56afacfe2de130873a610 Mon Sep 17 00:00:00 2001
+From: Christian Rauch <Rauch.Christian@gmx.de>
+Date: Sun, 9 Feb 2020 14:01:58 +0000
+Subject: [PATCH 6/8] cmake: add 'libdecor' dependency
+
+---
+ CMakeLists.txt | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index fb9fab99a..2ff626ac7 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -40,6 +40,8 @@ cmake_dependent_option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF
+ "UNIX;NOT APPLE" OFF)
+ cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
+ "MSVC" OFF)
++cmake_dependent_option(GLFW_USE_LIBDECOR "use libdecor for client-side window decorations" ON
++ "GLFW_USE_WAYLAND" OFF)
+
+ if (BUILD_SHARED_LIBS AND UNIX)
+ # On Unix-like systems, shared libraries can use the soname system.
+@@ -225,6 +227,14 @@ if (_GLFW_WAYLAND)
+ list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
+ list(APPEND glfw_LIBRARIES "${Wayland_LINK_LIBRARIES}")
+
++ if (GLFW_USE_LIBDECOR)
++ pkg_check_modules(libdecor REQUIRED libdecor-0)
++ list(APPEND glfw_PKG_DEPS "libdecor-0")
++ list(APPEND glfw_INCLUDE_DIRS "${libdecor_INCLUDE_DIRS}")
++ list(APPEND glfw_LIBRARIES "${libdecor_LINK_LIBRARIES}")
++ add_definitions(-DWITH_DECORATION)
++ endif()
++
+ include(CheckIncludeFiles)
+ include(CheckFunctionExists)
+ check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
+
+From 7ec585b8eb5169896876f11a68c12311237fd9e1 Mon Sep 17 00:00:00 2001
+From: Christian Rauch <Rauch.Christian@gmx.de>
+Date: Sun, 9 Feb 2020 14:56:27 +0000
+Subject: [PATCH 7/8] wl: deactivate 'viewporter' decorations
+
+---
+ src/wl_init.c | 13 +++++++++++
+ src/wl_platform.h | 10 +++++++++
+ src/wl_window.c | 57 ++++++++++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 74 insertions(+), 6 deletions(-)
+
+diff --git a/src/wl_init.c b/src/wl_init.c
+index 1ba497b71..d49e44e77 100644
+--- a/src/wl_init.c
++++ b/src/wl_init.c
+@@ -56,6 +56,7 @@ 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)
+@@ -80,6 +81,7 @@ static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
+ }
+ window = window->next;
+ }
++#endif
+ return window;
+ }
+
+@@ -103,7 +105,10 @@ static void pointerHandleEnter(void* data,
+ return;
+ }
+
++#ifndef WITH_DECORATION
+ window->wl.decorations.focus = focus;
++#endif
++
+ _glfw.wl.serial = serial;
+ _glfw.wl.pointerFocus = window;
+
+@@ -194,6 +199,7 @@ static void pointerHandleMotion(void* data,
+ x = wl_fixed_to_double(sx);
+ y = wl_fixed_to_double(sy);
+
++#ifndef WITH_DECORATION
+ switch (window->wl.decorations.focus)
+ {
+ case mainWindow:
+@@ -231,6 +237,7 @@ static void pointerHandleMotion(void* data,
+ default:
+ assert(0);
+ }
++#endif
+ if (_glfw.wl.cursorPreviousName != cursorName)
+ setCursor(window, cursorName);
+ }
+@@ -248,6 +255,7 @@ static void pointerHandleButton(void* data,
+
+ if (!window)
+ return;
++#ifndef WITH_DECORATION
+ if (button == BTN_LEFT)
+ {
+ switch (window->wl.decorations.focus)
+@@ -306,6 +314,7 @@ static void pointerHandleButton(void* data,
+ // Don’t pass the button to the user if it was related to a decoration.
+ if (window->wl.decorations.focus != mainWindow)
+ return;
++#endif
+
+ _glfw.wl.serial = serial;
+
+@@ -840,11 +849,13 @@ static void registryHandleGlobal(void* data,
+ &zxdg_decoration_manager_v1_interface,
+ 1);
+ }
++#ifndef WITH_DECORATION
+ else if (strcmp(interface, "wp_viewporter") == 0)
+ {
+ _glfw.wl.viewporter =
+ wl_registry_bind(registry, name, &wp_viewporter_interface, 1);
+ }
++#endif
+ else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0)
+ {
+ _glfw.wl.relativePointerManager =
+@@ -1249,8 +1260,10 @@ void _glfwPlatformTerminate(void)
+ wl_compositor_destroy(_glfw.wl.compositor);
+ if (_glfw.wl.shm)
+ wl_shm_destroy(_glfw.wl.shm);
++#ifndef WITH_DECORATION
+ 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)
+diff --git a/src/wl_platform.h b/src/wl_platform.h
+index 966155fdd..4591becbd 100644
+--- a/src/wl_platform.h
++++ b/src/wl_platform.h
+@@ -56,7 +56,9 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
+
+ #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"
+@@ -146,6 +148,7 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st
+ #define _GLFW_DECORATION_VERTICAL (_GLFW_DECORATION_TOP + _GLFW_DECORATION_WIDTH)
+ #define _GLFW_DECORATION_HORIZONTAL (2 * _GLFW_DECORATION_WIDTH)
+
++#ifndef WITH_DECORATION
+ typedef enum _GLFWdecorationSideWayland
+ {
+ mainWindow,
+@@ -163,6 +166,7 @@ typedef struct _GLFWdecorationWayland
+ struct wp_viewport* viewport;
+
+ } _GLFWdecorationWayland;
++#endif
+
+ // Wayland-specific per-window data
+ //
+@@ -204,12 +208,16 @@ typedef struct _GLFWwindowWayland
+
+ GLFWbool wasFullscreen;
+
++#ifndef WITH_DECORATION
+ struct {
+ GLFWbool serverSide;
+ struct wl_buffer* buffer;
+ _GLFWdecorationWayland top, left, right, bottom;
+ int focus;
+ } decorations;
++#else
++ GLFWbool ssd;
++#endif
+
+ } _GLFWwindowWayland;
+
+@@ -231,7 +239,9 @@ typedef struct _GLFWlibraryWayland
+ struct wl_data_source* dataSource;
+ 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;
+ struct zwp_pointer_constraints_v1* pointerConstraints;
+ struct zwp_idle_inhibit_manager_v1* idleInhibitManager;
+diff --git a/src/wl_window.c b/src/wl_window.c
+index 46cd742c6..9e10e8a3f 100644
+--- a/src/wl_window.c
++++ b/src/wl_window.c
+@@ -40,6 +40,10 @@
+ #include <sys/timerfd.h>
+ #include <poll.h>
+
++#ifdef WITH_DECORATION
++#include <libdecoration.h>
++#endif
++
+
+ static int createTmpfileCloexec(char* tmpname)
+ {
+@@ -182,6 +186,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
+ return buffer;
+ }
+
++#ifndef WITH_DECORATION
+ static void createDecoration(_GLFWdecorationWayland* decoration,
+ struct wl_surface* parent,
+ struct wl_buffer* buffer, GLFWbool opaque,
+@@ -211,7 +216,14 @@ 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 };
+@@ -243,7 +255,9 @@ 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)
+@@ -256,7 +270,14 @@ 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);
+@@ -264,6 +285,7 @@ static void destroyDecorations(_GLFWwindow* window)
+ destroyDecoration(&window->wl.decorations.right);
+ destroyDecoration(&window->wl.decorations.bottom);
+ }
++#endif
+
+ static void xdgDecorationHandleConfigure(void* data,
+ struct zxdg_toplevel_decoration_v1* decoration,
+@@ -271,9 +293,11 @@ static void xdgDecorationHandleConfigure(void* data,
+ {
+ _GLFWwindow* window = data;
+
+- window->wl.decorations.serverSide = (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
+-
+- if (!window->wl.decorations.serverSide)
++#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);
+ }
+
+@@ -307,6 +331,7 @@ static void resizeWindow(_GLFWwindow* window)
+ _glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
+ _glfwInputWindowContentScale(window, scale, scale);
+
++#ifndef WITH_DECORATION
+ if (!window->wl.decorations.top.surface)
+ return;
+
+@@ -333,6 +358,7 @@ static void resizeWindow(_GLFWwindow* window)
+ wp_viewport_set_destination(window->wl.decorations.bottom.viewport,
+ window->wl.width + _GLFW_DECORATION_HORIZONTAL, _GLFW_DECORATION_WIDTH);
+ wl_surface_commit(window->wl.decorations.bottom.surface);
++#endif
+ }
+
+ static void checkScaleChange(_GLFWwindow* window)
+@@ -465,7 +491,11 @@ static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor,
+ monitor->wl.output);
+ }
+ setIdleInhibitor(window, GLFW_TRUE);
++#ifdef WITH_DECORATION
++ if (!window->wl.ssd)
++#else
+ if (!window->wl.decorations.serverSide)
++#endif
+ destroyDecorations(window);
+ }
+
+@@ -573,7 +603,11 @@ static void setXdgDecorations(_GLFWwindow* window)
+ }
+ else
+ {
++#ifdef WITH_DECORATION
++ window->wl.ssd = GLFW_FALSE;
++#else
+ window->wl.decorations.serverSide = GLFW_FALSE;
++#endif
+ createDecorations(window);
+ }
+ }
+@@ -689,8 +723,12 @@ static void incrementCursorImage(_GLFWwindow* window)
+ {
+ _GLFWcursor* cursor;
+
+- if (!window || window->wl.decorations.focus != mainWindow)
++ if (!window) return;
++
++#ifndef WITH_DECORATION
++ if (window->wl.decorations.focus != mainWindow)
+ return;
++#endif
+
+ cursor = window->wl.currentCursor;
+ if (cursor && cursor->wl.cursor)
+@@ -860,9 +898,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
+ destroyDecorations(window);
+ 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
+
+ if (window->wl.native)
+ wl_egl_window_destroy(window->wl.native);
+@@ -967,6 +1006,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+ int* left, int* top,
+ int* right, int* bottom)
+ {
++#ifndef WITH_DECORATION
+ if (window->decorated && !window->monitor && !window->wl.decorations.serverSide)
+ {
+ if (top)
+@@ -978,6 +1018,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+ if (bottom)
+ *bottom = _GLFW_DECORATION_WIDTH;
+ }
++#endif
+ }
+
+ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
+@@ -1461,10 +1502,14 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
+
+ window->wl.currentCursor = cursor;
+
++ if (window != _glfw.wl.pointerFocus) return;
++
++#ifndef WITH_DECORATION
+ // 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->wl.decorations.focus != mainWindow)
+ return;
++#endif
+
+ // Unlock possible pointer lock if no longer disabled.
+ if (window->cursorMode != GLFW_CURSOR_DISABLED && isPointerLocked(window))
+
+From 2fad37473f20406159dde6e43c3c24fa241686d7 Mon Sep 17 00:00:00 2001
+From: Christian Rauch <Rauch.Christian@gmx.de>
+Date: Mon, 10 Feb 2020 00:59:44 +0000
+Subject: [PATCH 8/8] wl: add decorations
+
+---
+ src/wl_init.c | 64 +++++++++--
+ src/wl_platform.h | 19 +++-
+ src/wl_window.c | 271 +++++++++++++++++++++++++++++++++-------------
+ 3 files changed, 265 insertions(+), 89 deletions(-)
+
+diff --git a/src/wl_init.c b/src/wl_init.c
+index d49e44e77..b6cdb39dd 100644
+--- a/src/wl_init.c
++++ b/src/wl_init.c
+@@ -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)
+diff --git a/src/wl_platform.h b/src/wl_platform.h
+index 4591becbd..b6b3392e4 100644
+--- a/src/wl_platform.h
++++ b/src/wl_platform.h
+@@ -54,14 +54,17 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
+ #endif
+ #include "xkb_unicode.h"
+
++#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"
+-#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"
+
+ #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
+ #define _glfw_dlclose(handle) dlclose(handle)
+@@ -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;
+diff --git a/src/wl_window.c b/src/wl_window.c
+index 9e10e8a3f..47cc14377 100644
+--- a/src/wl_window.c
++++ b/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);
+ }
++#endif
+ setIdleInhibitor(window, GLFW_TRUE);
+-#ifdef WITH_DECORATION
+- if (!window->wl.ssd)
+-#else
++#ifndef WITH_DECORATION
+ if (!window->wl.decorations.serverSide)
+-#endif
+ 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)
diff --git a/0002-set-O_NONBLOCK-on-repeat-timerfd.patch b/0002-set-O_NONBLOCK-on-repeat-timerfd.patch
new file mode 100644
index 000000000000..e21cf69be0e3
--- /dev/null
+++ b/0002-set-O_NONBLOCK-on-repeat-timerfd.patch
@@ -0,0 +1,33 @@
+From 963e728881d7551aab0b843c79915f2419d4d36e Mon Sep 17 00:00:00 2001
+From: Stone Tickle <lattis@mochiro.moe>
+Date: Fri, 5 Jun 2020 12:51:25 +0900
+Subject: [PATCH] Wayland: Set O_NONBLOCK on repeat timerfd
+
+Fixes #1710
+Fixes #1711
+---
+ src/wl_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/wl_init.c b/src/wl_init.c
+index acfe477d4..bba908fa9 100644
+--- a/src/wl_init.c
++++ b/src/wl_init.c
+@@ -1336,7 +1336,7 @@ int _glfwInitWayland(void)
+
+ _glfw.wl.timerfd = -1;
+ if (_glfw.wl.seatVersion >= 4)
+- _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
++ _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
+
+ if (!_glfw.wl.wmBase)
+ {
+@@ -1370,7 +1370,7 @@ int _glfwInitWayland(void)
+ wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm);
+ _glfw.wl.cursorSurface =
+ wl_compositor_create_surface(_glfw.wl.compositor);
+- _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
++ _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
+ }
+
+ if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
diff --git a/0003-Continue-poll-if-timerfd-cant-be-read.patch b/0003-Continue-poll-if-timerfd-cant-be-read.patch
new file mode 100644
index 000000000000..5eb7513fa298
--- /dev/null
+++ b/0003-Continue-poll-if-timerfd-cant-be-read.patch
@@ -0,0 +1,46 @@
+From 68879081cb39f50bd65d12e0f1869f5970dc71b9 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Tue, 14 Dec 2021 09:29:01 +0100
+Subject: [PATCH] =?UTF-8?q?Wayland:=20Continue=20poll()=20if=20timerfd=20c?=
+ =?UTF-8?q?an=E2=80=99t=20be=20read?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In the case the key repeat timerfd was interrupted before read(), the
+cursor timerfd wasn’t read at all even when it could.
+
+Related to #1711
+---
+ src/wl_window.c | 11 +++--------
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/src/wl_window.c b/src/wl_window.c
+index b4c59d693..8ed803b4b 100644
+--- a/src/wl_window.c
++++ b/src/wl_window.c
+@@ -751,10 +751,7 @@ static void handleEvents(int timeout)
+ if (fds[1].revents & POLLIN)
+ {
+ read_ret = read(_glfw.wl.timerfd, &repeats, sizeof(repeats));
+- if (read_ret != 8)
+- return;
+-
+- if (_glfw.wl.keyboardFocus)
++ if (read_ret == 8 && _glfw.wl.keyboardFocus)
+ {
+ for (uint64_t i = 0; i < repeats; ++i)
+ {
+@@ -770,10 +767,8 @@ static void handleEvents(int timeout)
+ if (fds[2].revents & POLLIN)
+ {
+ read_ret = read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats));
+- if (read_ret != 8)
+- return;
+-
+- incrementCursorImage(_glfw.wl.pointerFocus);
++ if (read_ret == 8)
++ incrementCursorImage(_glfw.wl.pointerFocus);
+ }
+ }
+ else
diff --git a/0003-wayland-don-t-crash-app-on-api-calls-to-window-focus.patch b/0003-wayland-don-t-crash-app-on-api-calls-to-window-focus.patch
new file mode 100644
index 000000000000..15e312aa6007
--- /dev/null
+++ b/0003-wayland-don-t-crash-app-on-api-calls-to-window-focus.patch
@@ -0,0 +1,39 @@
+From 8400d399b74f55bf128488f7ea73609babbf4eaf Mon Sep 17 00:00:00 2001
+From: ninja- <ninja-@users.noreply.github.com>
+Date: Tue, 30 Jun 2020 19:41:48 +0200
+Subject: [PATCH 3/4] wayland: don't crash app on api calls to window focus or
+ window icon - just ignore them
+
+---
+ src/wl_window.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/wl_window.c b/src/wl_window.c
+index 47cc1437..f3bda65b 100644
+--- a/src/wl_window.c
++++ b/src/wl_window.c
+@@ -1021,8 +1021,8 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
+ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
+ int count, const GLFWimage* images)
+ {
+- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
+- "Wayland: The platform does not support setting the window icon");
++ // _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
++ // "Wayland: The platform does not support setting the window icon");
+ }
+
+ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
+@@ -1201,8 +1201,8 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
+
+ void _glfwPlatformFocusWindow(_GLFWwindow* window)
+ {
+- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
+- "Wayland: The platform does not support setting the input focus");
++ // _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
++ // "Wayland: The platform does not support setting the input focus");
+ }
+
+ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
+--
+2.32.0
+
diff --git a/0004-fix-broken-opengl-screenshots-on-mutter.patch b/0004-fix-broken-opengl-screenshots-on-mutter.patch
new file mode 100644
index 000000000000..c850f99cb381
--- /dev/null
+++ b/0004-fix-broken-opengl-screenshots-on-mutter.patch
@@ -0,0 +1,33 @@
+From 4d47891ca1f3979c20f0acc3539a80d8fa97a2ad Mon Sep 17 00:00:00 2001
+From: ninja- <ninja-@users.noreply.github.com>
+Date: Tue, 30 Jun 2020 19:41:52 +0200
+Subject: [PATCH 4/4] fix broken opengl screenshots on mutter
+
+(admicos) This breaks more than just screenshots. On sway, the window is
+rendered half transparent. And we do not want that.
+---
+ src/egl_context.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/src/egl_context.c b/src/egl_context.c
+index 975c67be..b5cbeaff 100644
+--- a/src/egl_context.c
++++ b/src/egl_context.c
+@@ -175,6 +175,14 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
+ u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
+ u->doublebuffer = desired->doublebuffer;
+
++#if defined(_GLFW_WAYLAND)
++ // Avoid using transparent buffer on Wayland if transparency is not requested.
++ // Otherwise mutter will fail to properly screenshot OpenGL content.
++ if (u->alphaBits > 0 && !desired->transparent) {
++ continue;
++ }
++#endif // _GLFW_WAYLAND
++
+ u->handle = (uintptr_t) n;
+ usableCount++;
+ }
+--
+2.32.0
+
diff --git a/0005-don-t-crash-on-get-scancode-name.patch b/0005-don-t-crash-on-get-scancode-name.patch
new file mode 100644
index 000000000000..9a4c7200902d
--- /dev/null
+++ b/0005-don-t-crash-on-get-scancode-name.patch
@@ -0,0 +1,10 @@
+--- a/src/wl_window.c
++++ b/src/wl_window.c
+@@ -1378,8 +1378,6 @@
+ const char* _glfwPlatformGetScancodeName(int scancode)
+ {
+ // TODO
+- _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
+- "Wayland: Key names not yet implemented");
+ return NULL;
+ }
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..ffaffbe23db4
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,66 @@
+# Maintainer: EncryptedCicada <me@varnit.com>
+# Maintainer: Ecmel Berk Canlıer <me@ecmelberk.com>
+# Contributor: Sven-Hendrik Haase <svenstaro@gmail.com>
+# Contributor: philefou <tuxication AT gmail DOT com>
+# Contributor: lindquist <tomas@famolsen.dk>
+# Contributor: Christoph Siegenthaler <csi@gmx.ch>
+# Contributor: Mihai Militaru <mihai.militaru@ephemeros.org>
+# Contributor: SpepS <dreamspepser at yahoo dot it>
+
+pkgname=glfw-wayland-minecraft-libdecoration
+pkgdesc="A free, open source, portable framework for graphical application development (wayland, patched for Minecraft and Gnome)"
+pkgver=3.4.0
+_pkggit=87d5646f5d2bad0562744501633bf8105f59c193
+pkgrel=1
+arch=('x86_64')
+url="https://github.com/EncryptedCicada/minecraft-wayland"
+license=('custom:ZLIB')
+depends=('wayland' 'libxkbcommon' 'libgl' 'libdecor')
+conflicts=('glfw' 'glfw-wayland')
+provides=("glfw=$pkgver")
+makedepends=('mesa' 'cmake' 'doxygen' 'vulkan-headers' 'vulkan-icd-loader'
+ 'extra-cmake-modules' 'wayland-protocols' 'libxi' 'libxrandr'
+ 'libxcursor' 'libxkbcommon' 'libxinerama')
+source=("https://github.com/glfw/glfw/archive/${_pkggit}.tar.gz"
+ "0001-libdecoration-support.patch"
+ "0002-set-O_NONBLOCK-on-repeat-timerfd.patch"
+ "0003-wayland-don-t-crash-app-on-api-calls-to-window-focus.patch"
+ "0004-fix-broken-opengl-screenshots-on-mutter.patch"
+ "0005-don-t-crash-on-get-scancode-name.patch")
+sha256sums=('7b8c990cfb039110d38c7f5bb21948c402933be3f93f333fe7dcda3deaf72aa4'
+ 'c163b4a0a6496d758bc656203c23151015683754a6b5c2fc4944df7296d6b5af'
+ '5cd74a83dc7824c7696c1534f880b7a4a0992bb6dba6e4531ad1c040541f1d30'
+ 'a442f8c7e40fb09775f922b95402108b366114874ee96e370c29e5f8500a02b7'
+ '27aea70b07df2d46ac7469c129d28d695eff1ec9492489aa7b2558dd780ebdf0'
+ '16a2410511d75f00902ab1869942a80d85261f8390a97be946f82662891351e5')
+
+prepare() {
+ cd "$srcdir/glfw-$_pkggit"
+ rm -rf build-wayland || true
+ mkdir build-wayland
+
+ for patch in "$srcdir/00"*.patch; do
+ echo "Applying patch $patch"
+ patch -p1 < "$patch"
+ done
+}
+
+build() {
+ cd "$srcdir/glfw-$_pkggit/build-wayland"
+
+ cmake .. \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_INSTALL_LIBDIR=lib \
+ -DBUILD_SHARED_LIBS=ON \
+ -DGLFW_USE_WAYLAND=ON \
+ -DGLFW_USE_LIBDECOR=ON
+}
+
+package() {
+ cd "$srcdir/glfw-$_pkggit"/build-wayland
+
+ make DESTDIR=$pkgdir install
+
+ cd ..
+ install -Dm644 LICENSE.md "$pkgdir/usr/share/licenses/$pkgname/LICENSE.md"
+}
diff --git a/README.md b/README.md
new file mode 100644
index 000000000000..2f94d279d959
--- /dev/null
+++ b/README.md
@@ -0,0 +1,104 @@
+<B> This repository is for hosting the Gnome specific changes of the parent repository and to host the package on AUR. Please submit any issues or PRs on the parent repository </B>
+
+# The better way of running Minecraft Without XWayland
+
+Because I **REALLY** had nothing better to do with my life.
+
+## Requirements
+
+- A version of Minecraft >= 1.13
+
+ - Older versions are not guaranteed to work. You can still try, though.
+
+- The MultiMC Minecraft Launcher
+
+ - Use it even if you don't plan to do this. It's great!
+ - If you don't want to do that, throw this into your Java arguments, changing
+ the file path as needed: `-Dorg.lwjgl.glfw.libname=/usr/lib/libglfw.so`
+
+- A distro with a patched GLFW package
+
+ - This guide has steps for Arch, Fedora, and Gentoo
+ - Or the knowledge on how to patch packages in your distribution.
+ - In which case you can skip step 2 of this guide, as it will not apply to you
+ and you should know what to do with the `.patch` files in this repo already
+
+## Side effects
+
+- Forge will not work without another workaround
+- The controls page (and anywhere a keyboard key is shown) is a bit wonky
+ - Keys you replace through your compositor (example: `caps:swapescape`) will
+ require you to use the original key
+- Originally made for Sway, GNOME needs to manually makepkg the `libdecoration`
+ branch for GNOME specific fixes (until a new GLFW version releases. See steps for Gnome on Arch below.)
+ - I haven't received any bug reports from KDE, so it'll (probably) work
+
+## Step 1: Setting up MultiMC to use the system GLFW
+
+Go to `Settings` > `Minecraft`, and enable `Use system installation of GLFW`.
+
+If you have a Wayland-compatible version of GLFW installed (`glfw-wayland` on
+Arch) you can try launching the game. It will most likely error out with
+something about window focus not being supported. In that case, you are in the
+right direction.
+
+## Step 2: Installing the patched GLFW library
+
+If you're not under an Arch-based system, you're mostly on your own here. You
+can try waiting for someone else to write a guide I guess.
+
+### Option 1: Use the AUR
+
+Install the `glfw-wayland-minecraft-libdecoration` package from the AUR.
+
+### Option 2: Build the PKGBUILD manually
+
+`git clone` this repository to somewhere, and run `makepkg -si` inside. It will
+ask you to replace your existing GLFW package if already installed.
+
+### Option 3: Install the Fedora package
+
+Install the Fedora package from https://copr.fedorainfracloud.org/coprs/lyessaadi/minecraft-wayland-glfw/.
+See https://github.com/Admicos/minecraft-wayland/issues/4 for more information.
+
+### Option 4: Patch the Gentoo package
+
+Patch Gentoo's GLFW package by following the guide at https://github.com/Admicos/minecraft-wayland/issues/6
+
+## Step 3: There is no step 3
+
+This should be it. Try launching Minecraft now and see if it works.
+
+## Bonus: XWayland per instance
+
+If some version of Minecraft doesn't work with the patch enabled, you can
+disable it through MultiMC just for that version by
+
+- Right clicking on your instance
+- Clicking `Edit instance`
+- Going to `Settings` > `Workarounds`
+- Enabling `Native Libraries` override switch
+- Disabling the GLFW option
+
+You can also disable the global switch and enable the patch per instance if
+that's how you want to roll.
+
+## Bonus: Making Forge work
+
+Due to "Forge being Forge", you will need to add
+`-Dfml.earlyprogresswindow=false` to your Java arguments to make Forge instances
+start up properly. See [issue #1](https://github.com/Admicos/minecraft-wayland/issues/1)
+for more information.
+
+## Thanks To
+
+I really didn't do much on this other than "re-discovering" these things which
+aren't even that old. Here are the proper credits:
+
+- `ninja-` on GitHub
+
+ - For https://github.com/glfw/glfw/pull/1725
+
+- `annacrombie` on GitHub
+
+ - For https://github.com/glfw/glfw/pull/1711