[Bf-blender-cvs] [b245bfa5768] decoration: decoration

Christian Rauch noreply at git.blender.org
Mon Jun 1 01:20:14 CEST 2020


Commit: b245bfa57681a426f391dab2ea38e5404a5ea5b4
Author: Christian Rauch
Date:   Thu May 21 00:03:04 2020 +0100
Branches: decoration
https://developer.blender.org/rBb245bfa57681a426f391dab2ea38e5404a5ea5b4

decoration

===================================================================

M	intern/ghost/CMakeLists.txt
M	intern/ghost/intern/GHOST_SystemWayland.cpp
M	intern/ghost/intern/GHOST_SystemWayland.h
M	intern/ghost/intern/GHOST_WindowWayland.cpp

===================================================================

diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 2999a64fdea..613b3ab299c 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -299,11 +299,6 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
       ${CMAKE_CURRENT_BINARY_DIR}
     )
 
-    # xdg-shell.
-    generate_protocol_bindings(
-      xdg-shell
-      "${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
-    )
     # Pointer-constraints.
     generate_protocol_bindings(
       pointer-constraints
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 31110694ea6..f1be1c95068 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -141,7 +141,7 @@ struct display_t {
 
   struct wl_display *display;
   struct wl_compositor *compositor = nullptr;
-  struct xdg_wm_base *xdg_shell = nullptr;
+  struct libdecor *decoration_context = nullptr;
   struct wl_shm *shm = nullptr;
   std::vector<output_t *> outputs;
   std::vector<input_t *> inputs;
@@ -238,8 +238,8 @@ static void display_destroy(display_t *d)
     wl_compositor_destroy(d->compositor);
   }
 
-  if (d->xdg_shell) {
-    xdg_wm_base_destroy(d->xdg_shell);
+  if (d->decoration_context) {
+    libdecor_unref(d->decoration_context);
   }
 
   if (eglGetDisplay) {
@@ -827,7 +827,8 @@ static void pointer_leave(void *data,
                           struct wl_surface *surface)
 {
   if (surface != nullptr) {
-    static_cast<input_t *>(data)->focus_pointer = nullptr;
+    // TODO: separate surface destinations
+//    static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface))->deactivate();
   }
 }
 
@@ -1209,13 +1210,15 @@ static const struct wl_output_listener output_listener = {
     output_scale,
 };
 
-static void shell_ping(void * /*data*/, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
+static void
+handle_error(struct libdecor */*context*/, enum libdecor_error error, const char *message)
 {
-  xdg_wm_base_pong(xdg_wm_base, serial);
+  GHOST_PRINT("decoration error ("<<  error <<"): " << message << std::endl);
+  exit(EXIT_FAILURE);
 }
 
-static const struct xdg_wm_base_listener shell_listener = {
-    shell_ping,
+static struct libdecor_interface libdecor_iface = {
+  .error = handle_error,
 };
 
 static void global_add(void *data,
@@ -1229,11 +1232,6 @@ static void global_add(void *data,
     display->compositor = static_cast<wl_compositor *>(
         wl_registry_bind(wl_registry, name, &wl_compositor_interface, 1));
   }
-  else if (!strcmp(interface, xdg_wm_base_interface.name)) {
-    display->xdg_shell = static_cast<xdg_wm_base *>(
-        wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1));
-    xdg_wm_base_add_listener(display->xdg_shell, &shell_listener, nullptr);
-  }
   else if (!strcmp(interface, wl_output_interface.name)) {
     output_t *output = new output_t;
     output->scale = 1;
@@ -1322,9 +1320,11 @@ GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new display_t)
   wl_display_roundtrip(d->display);
   wl_registry_destroy(registry);
 
-  if (!d->xdg_shell) {
+  d->decoration_context = libdecor_new(d->display, &libdecor_iface);
+
+  if (!d->decoration_context) {
     display_destroy(d);
-    throw std::runtime_error("Wayland: unable to access xdg_shell!");
+    throw std::runtime_error("Wayland: unable to create window decorations!");
   }
 
   /* Register data device per seat for IPC between Wayland clients. */
@@ -1569,9 +1569,9 @@ wl_compositor *GHOST_SystemWayland::compositor()
   return d->compositor;
 }
 
-xdg_wm_base *GHOST_SystemWayland::shell()
+libdecor *GHOST_SystemWayland::decoration()
 {
-  return d->xdg_shell;
+  return d->decoration_context;
 }
 
 void GHOST_SystemWayland::setSelection(const std::string &selection)
diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h
index 89cd3406b69..43b31bddd6b 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.h
+++ b/intern/ghost/intern/GHOST_SystemWayland.h
@@ -27,7 +27,7 @@
 #include "GHOST_WindowWayland.h"
 
 #include <wayland-client.h>
-#include <xdg-shell-client-protocol.h>
+#include <libdecoration/libdecoration.h>
 
 #include <string>
 
@@ -83,7 +83,7 @@ class GHOST_SystemWayland : public GHOST_System {
 
   wl_compositor *compositor();
 
-  xdg_wm_base *shell();
+  libdecor *decoration();
 
   void setSelection(const std::string &selection);
 
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
index a25b281e4ee..2cbd81e00b5 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.cpp
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -34,10 +34,8 @@
 struct window_t {
   GHOST_WindowWayland *w;
   wl_surface *surface;
-  struct xdg_surface *xdg_surface;
-  struct xdg_toplevel *xdg_toplevel;
+  struct libdecor_frame *frame;
   wl_egl_window *egl_window;
-  int32_t pending_width, pending_height;
   bool is_maximised;
   bool is_fullscreen;
   bool is_active;
@@ -52,88 +50,58 @@ struct window_t {
  * an event is received from the compositor.
  * \{ */
 
-static void toplevel_configure(
-    void *data, xdg_toplevel * /*xdg_toplevel*/, int32_t width, int32_t height, wl_array *states)
+static void
+frame_configure(struct libdecor_frame *frame,
+     struct libdecor_configuration *configuration,
+     void *data)
 {
   window_t *win = static_cast<window_t *>(data);
-  win->pending_width = width;
-  win->pending_height = height;
-
-  win->is_maximised = false;
-  win->is_fullscreen = false;
-  win->is_active = false;
-
-  /* Note that the macro 'wl_array_for_each' would typically be used to simplify this logic,
-   * however it's not compatible with C++, so perform casts instead.
-   * If this needs to be done more often we could define our own C++ compatible macro. */
-  for (enum xdg_toplevel_state *state = static_cast<xdg_toplevel_state *>(states->data);
-       reinterpret_cast<uint8_t *>(state) < (static_cast<uint8_t *>(states->data) + states->size);
-       state++) {
-    switch (*state) {
-      case XDG_TOPLEVEL_STATE_MAXIMIZED:
-        win->is_maximised = true;
-        break;
-      case XDG_TOPLEVEL_STATE_FULLSCREEN:
-        win->is_fullscreen = true;
-        break;
-      case XDG_TOPLEVEL_STATE_ACTIVATED:
-        win->is_active = true;
-        break;
-      default:
-        break;
-    }
+
+  int width, height;
+  enum libdecor_window_state window_state;
+  struct libdecor_state *state;
+
+  if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
+    width = win->width;
+    height = win->height;
   }
-}
 
-static void toplevel_close(void *data, xdg_toplevel * /*xdg_toplevel*/)
-{
-  static_cast<window_t *>(data)->w->close();
-}
+  win->width = width;
+  win->height = height;
 
-static const xdg_toplevel_listener toplevel_listener = {
-    toplevel_configure,
-    toplevel_close,
-};
+  wl_egl_window_resize(win->egl_window, win->width, win->height, 0, 0);
+  win->w->notify_size();
 
-static void surface_configure(void *data, xdg_surface *xdg_surface, uint32_t serial)
-{
-  window_t *win = static_cast<window_t *>(data);
+  if (!libdecor_configuration_get_window_state(configuration, &window_state))
+    window_state = LIBDECOR_WINDOW_STATE_NONE;
 
-  int w, h;
-  wl_egl_window_get_attached_size(win->egl_window, &w, &h);
-  if (win->pending_width != 0 && win->pending_height != 0 && win->pending_width != w &&
-      win->pending_height != h) {
-    win->width = win->pending_width;
-    win->height = win->pending_height;
-    wl_egl_window_resize(win->egl_window, win->pending_width, win->pending_height, 0, 0);
-    win->pending_width = 0;
-    win->pending_height = 0;
-    win->w->notify_size();
-  }
+  win->is_maximised = window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED;
+  win->is_fullscreen = window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN;
+  win->is_active = window_state & LIBDECOR_WINDOW_STATE_ACTIVE;
 
-  if (win->is_active) {
-    win->w->activate();
-  }
-  else {
-    win->w->deactivate();
-  }
+  win->is_active ? win->w->activate() : win->w->deactivate();
 
-  xdg_surface_ack_configure(xdg_surface, serial);
+  state = libdecor_state_new(width, height);
+  libdecor_frame_commit(frame, state, configuration);
+  libdecor_state_free(state);
 }
 
-static const xdg_surface_listener surface_listener = {
-    surface_configure,
-};
+static void
+frame_close(struct libdecor_frame */*frame*/, void *data)
+{
+  static_cast<window_t *>(data)->w->close();
+}
 
 static void
-handle_error(struct libdecor *context, enum libdecor_error error, const char *message)
+frame_commit(void *data)
 {
-  GHOST_PRINT("decoration error ("<<  error <<"): " << message << std::endl);
-  exit(EXIT_FAILURE);
+  wl_surface_commit(static_cast<window_t *>(data)->surface);
 }
 
-static struct libdecor_interface libdecor_iface = {
-  .error = handle_error,
+static struct libdecor_frame_interface libdecor_frame_iface = {
+  frame_configure,
+  frame_close,
+  frame_commit,
 };
 
 /** \} */
@@ -176,26 +144,27 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
   w->surface = wl_compositor_create_surface(m_system->compositor());
   w->egl_window = wl_egl_window_create(w->surface, int(width), int(height));
 
-  struct libdecor *context = libdecor_new(m_system->display(), &libdecor_iface);
-
-  w->xdg_surface = xdg_wm_base_get_xdg_surface(m_system->shell(), w->surface);
-  w->xdg_toplevel = xdg_surface_get_toplevel(w->xdg_surface);
-
   wl_surface_set_user_data(w->surface, this);
 
-  xdg_surface_add_listener(w->xdg_surface, &surface_listener, w);
-  xdg_toplevel_add_listener(w->xdg_toplevel, &toplevel_listener, w);
+  /* create window decorations */
+  w->frame = libdecor_decorate(m_system->decoration(), w->surface, &libdecor_frame_iface, w);
+  libdecor_frame_map(w->frame);
+
+//  libdecor_frame_set_min_content_size(w->frame, 200, 200);
 
   if (parentWindow) {
-    xdg_toplevel_set_parent(
-        w->xdg_toplevel, dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->w->xdg_toplevel);
+    // TODO: enable parent relation
+//    libdecor_frame_set_parent_frame(w->frame, dynamic_cast<const GHOST_WindowWayland *>(parentWindow)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list