diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-09-29 12:29:52 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-09-29 12:29:52 +0200 |
| commit | ff0a3a9d59ecc6acecdebfd44250746a786636b6 (patch) | |
| tree | b3a59901030db6d363b6698696acd0bb1e5591ab /src/drivers | |
| parent | 491db97a3b25e2202766d559cec32cad701de3f8 (diff) | |
Wayland: throttle window redraws during interactive resizes (#776)
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 2af93b973..317aa906c 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -737,6 +737,67 @@ 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) { @@ -754,6 +815,10 @@ 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)) { @@ -805,6 +870,16 @@ static void handle_configure(struct libdecor_frame *frame, //fprintf(stderr,"handle_configure: using floating %dx%d\n",width,height); } +#ifndef LIBDECOR_MR131 + bool in_decorated_window_resizing = (window->state & LIBDECOR_WINDOW_STATE_RESIZING); +#endif + //printf("resize request received from compositor to %dx%d\n",width,height); + if (in_decorated_window_resizing && window->buffer->cb) { + // Skip resizing & redrawing. The last resize request won't be skipped because + // in_decorated_window_resizing will be false then. + return; + } + driver->in_handle_configure = true; window->fl_win->resize(0, 0, ceil(width / f), ceil(height / f)); driver->in_handle_configure = false; |
