mirror of
https://github.com/fltk/fltk.git
synced 2026-05-30 13:05:35 +08:00
Wayland: throttle window redraws during interactive resizes (#776)
This commit is contained in:
@@ -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,
|
static void handle_configure(struct libdecor_frame *frame,
|
||||||
struct libdecor_configuration *configuration, void *user_data)
|
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);
|
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;
|
struct wl_output *wl_output = NULL;
|
||||||
if (window->fl_win->fullscreen_active()) {
|
if (window->fl_win->fullscreen_active()) {
|
||||||
if (!(window->state & LIBDECOR_WINDOW_STATE_FULLSCREEN)) {
|
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);
|
//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;
|
driver->in_handle_configure = true;
|
||||||
window->fl_win->resize(0, 0, ceil(width / f), ceil(height / f));
|
window->fl_win->resize(0, 0, ceil(width / f), ceil(height / f));
|
||||||
driver->in_handle_configure = false;
|
driver->in_handle_configure = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user