summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx5
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx71
3 files changed, 74 insertions, 4 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b01ee09ab..81a7b6605 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -756,7 +756,7 @@ if(UNIX AND FLTK_BACKEND_WAYLAND)
list(APPEND OPTIONAL_LIBS PkgConfig::WLD_EGL PkgConfig::PKG_EGL)
endif(FLTK_USE_GL)
if(USE_SYSTEM_LIBDECOR)
- list(APPEND OPTIONAL_LIBS PkgConfig::SYSTEM_LIBDECOR)
+ list(APPEND OPTIONAL_LIBS ${SYSTEM_LIBDECOR_LDFLAGS})
elseif(GTK_FOUND AND FLTK_USE_LIBDECOR_GTK)
list(APPEND OPTIONAL_LIBS PkgConfig::GTK)
endif(USE_SYSTEM_LIBDECOR)
diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
index efbb176ab..60011393d 100644
--- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
@@ -47,7 +47,7 @@
#include <string.h> // for strerror()
extern "C" {
bool libdecor_get_cursor_settings(char **theme, int *size);
- bool fl_is_surface_gtk_titlebar(struct wl_surface *, struct libdecor *);
+ bool fl_is_surface_gtk_titlebar(struct wl_surface *, struct libdecor *, struct wl_display *);
}
// set this to 1 for keyboard debug output, 0 for no debug output
@@ -206,7 +206,8 @@ static void pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t se
Fl_Window *win = event_coords_from_surface(surface, surface_x, surface_y);
if (!win && gtk_shell) { // check that surface is the headerbar of a GTK-decorated window
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
- if (fl_is_surface_gtk_titlebar(surface, scr_driver->libdecor_context)) {
+ if (fl_is_surface_gtk_titlebar(surface, scr_driver->libdecor_context,
+ Fl_Wayland_Screen_Driver::wl_display)) {
gtk_shell_surface = surface;
}
}
diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
index e8a0a1af9..ff1682e31 100644
--- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
+++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
@@ -769,6 +769,69 @@ static struct Fl_Wayland_Screen_Driver::output *screen_num_to_output(int num_scr
}
+#define LIBDECOR_MR131 1 // this means libdecor does not include MR!131 yet
+
+#ifdef LIBDECOR_MR131
+/* === Beginning of hack that would become un-needed if libdecor accepted MR!131 === */
+
+// true while the GUI is interactively resizing a decorated window
+static bool in_decorated_window_resizing = false;
+
+
+// libdecor's configure cb function for xdg_toplevel objects
+static void (*decor_xdg_toplevel_configure)(void*, struct xdg_toplevel *, int32_t,
+ int32_t, struct wl_array *);
+
+
+static void fltk_xdg_toplevel_configure(void *user_data, struct xdg_toplevel *xdg_toplevel,
+ int32_t width, int32_t height,
+ struct wl_array *states) {
+ uint32_t *p;
+ in_decorated_window_resizing = false;
+ // Replace wl_array_for_each(p, states) rejected by C++
+ for (p = (uint32_t *)(states)->data;
+ (const char *) p < ((const char *) (states)->data + (states)->size);
+ (p)++) {
+ if (*p == XDG_TOPLEVEL_STATE_RESIZING) {
+ in_decorated_window_resizing = true;
+ break;
+ }
+ }
+ decor_xdg_toplevel_configure(user_data, xdg_toplevel, width, height, states);
+}
+
+
+struct wl_object { // copied from wayland-private.h
+ const struct wl_interface *interface;
+ const void *implementation;
+ uint32_t id;
+};
+
+
+// replace libdecor's toplevel configure cb by FLTK's
+static void use_FLTK_toplevel_configure_cb(struct libdecor_frame *frame) {
+ struct wl_object *object = (struct wl_object *)libdecor_frame_get_xdg_toplevel(frame);
+ static struct xdg_toplevel_listener *fltk_listener = NULL;
+ if (!fltk_listener) {
+ struct xdg_toplevel_listener *decor_listener = (struct xdg_toplevel_listener*)
+ object->implementation;
+ fltk_listener = (struct xdg_toplevel_listener*)
+ malloc(sizeof(struct xdg_toplevel_listener));
+ // initialize FLTK's listener with libdecor's values
+ *fltk_listener = *decor_listener;
+ // memorize libdecor's toplevel configure cb
+ decor_xdg_toplevel_configure = decor_listener->configure;
+ // replace libdecor's toplevel configure cb by FLTK's
+ fltk_listener->configure = fltk_xdg_toplevel_configure;
+ }
+ // replace the toplevel listener by a copy whose configure member is FLTK's
+ object->implementation = fltk_listener;
+}
+
+/* === End of hack that would become un-needed if libdecor accepted MR!131 === */
+#endif // LIBDECOR_MR131
+
+
static void handle_configure(struct libdecor_frame *frame,
struct libdecor_configuration *configuration, void *user_data)
{
@@ -786,6 +849,9 @@ static void handle_configure(struct libdecor_frame *frame,
if (!window->xdg_surface) window->xdg_surface = libdecor_frame_get_xdg_surface(frame);
+#ifdef LIBDECOR_MR131
+ if (is_1st_run) use_FLTK_toplevel_configure_cb(frame);
+#endif
struct wl_output *wl_output = NULL;
if (window->fl_win->fullscreen_active()) {
if (!(window->state & LIBDECOR_WINDOW_STATE_FULLSCREEN)) {
@@ -839,7 +905,10 @@ static void handle_configure(struct libdecor_frame *frame,
//fprintf(stderr,"handle_configure: using floating %dx%d\n",width,height);
}
- bool condition = (window->state & LIBDECOR_WINDOW_STATE_RESIZING);
+#ifndef LIBDECOR_MR131
+ bool in_decorated_window_resizing = (window->state & LIBDECOR_WINDOW_STATE_RESIZING);
+#endif
+ bool condition = in_decorated_window_resizing;
if (condition) { // see issue #878
condition = (window->covered ? (window->buffer && window->buffer->in_use) : (window->frame_cb != NULL));
}