From 63e535210c682c21c5fda440e0a66e1698f7ecee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20K=C3=B6nig?= <leonard.r.koenig@googlemail.com>
Date: Wed, 28 Oct 2020 19:23:28 +0100
Subject: [PATCH] Wayland: Fix destroying CSDs in the correct order

On Wayland we implement Client-Side Decorations if the compositors do not
implement SSDs.  In that case, the destructors of the surfaces were called
in the wrong order, leading to a dereference of an already freed object.
We need to first destroy the subsurface before destroying the parent surface.

Related PR on kitty: https://github.com/kovidgoyal/kitty/pull/3066
Related issue on kitty: https://github.com/kovidgoyal/kitty/issues/3051

Closes #1798.

(cherry picked from commit 0dc1005c853e9bdd00448ca1a3405858790a9fef)
---
 README.md       | 2 ++
 src/wl_window.c | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index deb2c609..e0359e48 100644
--- a/README.md
+++ b/README.md
@@ -147,6 +147,7 @@ information on what to include when reporting a bug.
  - [Wayland] Bugfix: Retrieving partial framebuffer size would segfault
  - [Wayland] Bugfix: Scrolling offsets were inverted compared to other platforms
    (#1463)
+ - [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong worder
 
 
 ## Contact
@@ -370,6 +371,7 @@ skills.
  - Santi Zupancic
  - Jonas Ådahl
  - Lasse Öörni
+ - Leonard König
  - All the unmentioned and anonymous contributors in the GLFW community, for bug
    reports, patches, feedback, testing and encouragement
 
diff --git a/src/wl_window.c b/src/wl_window.c
index f811fffc..d10861cd 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -312,10 +312,10 @@ static void createDecorations(_GLFWwindow* window)
 
 static void destroyDecoration(_GLFWdecorationWayland* decoration)
 {
-    if (decoration->surface)
-        wl_surface_destroy(decoration->surface);
     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;