Fix "New Wayland subwindow code creates issues with resizes of opengl windows…" (#1311)

This commit is contained in:
ManoloFLTK 2025-10-20 18:47:41 +02:00
parent e23a6bd476
commit d765037d2c
5 changed files with 30 additions and 9 deletions

View File

@ -299,6 +299,7 @@ void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
if (is_a_resize) valid(0);
pGlWindowDriver->resize(is_a_resize, W, H);
Fl_Window::resize(X,Y,W,H);
if (is_a_resize) pGlWindowDriver->after_resize();
}
/**

View File

@ -67,6 +67,7 @@ public:
virtual void make_current_after() {}
virtual void swap_buffers() {}
virtual void resize(int /*is_a_resize*/, int /*w*/, int /*h*/) {}
virtual void after_resize() {}
virtual char swap_type();
virtual void swap_interval(int) { }
virtual int swap_interval() const { return -1; }

View File

@ -38,6 +38,7 @@ private:
int mode_(int m, const int *a) FL_OVERRIDE;
void swap_buffers() FL_OVERRIDE;
void resize(int is_a_resize, int w, int h) FL_OVERRIDE;
void after_resize() FL_OVERRIDE;
char swap_type() FL_OVERRIDE;
void swap_interval(int) FL_OVERRIDE;
int swap_interval() const FL_OVERRIDE;

View File

@ -405,6 +405,14 @@ void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
}*/
}
void Fl_Wayland_Gl_Window_Driver::after_resize() {
Fl_Window *parent = (pWindow->parent() ? pWindow->window() : NULL);
struct wld_window *xid = (parent ? fl_wl_xid(parent) : NULL);
if (xid && !xid->frame_cb) {
eglSwapBuffers(Fl_Wayland_Gl_Window_Driver::egl_display, egl_surface);
}
}
char Fl_Wayland_Gl_Window_Driver::swap_type() {
return copy;
}

View File

@ -1827,9 +1827,13 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
}
Fl_Window *parent = this->parent() ? pWindow->window() : NULL;
struct wld_window *parent_xid = parent ? fl_wl_xid(parent) : NULL;
// When moving or resizing a subwindow independently from its parent, skip the move/resize
// operation if the parent window is being redrawn, in line with the frame callback mechanism.
if (depth == 1 && fl_win && parent_xid && parent_xid->frame_cb && is_a_move) {
if (depth == 1 && fl_win && parent_xid && parent_xid->frame_cb && can_expand_outside_parent_) {
// When moving or resizing a subwindow independently from its parent while the parent window
// is being redrawn, the processing depends on whether the moved/resize window
// is a draggable-subwindow. For a draggable subwindow having can_expand_outside_parent_ != 0,
// skip the X,Y,W,H tuple to process only tuples received when parent window is ready.
// This smoothes the movement of the draggable subwindow.
// Process regular subwindows normally.
depth--;
return;
}
@ -1903,13 +1907,19 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
wl_subsurface_set_position(fl_win->subsurface, X * f, Y * f);
wl_surface_commit(parent_xid->wl_surface);
}
} else if (is_a_move && !parent_xid->frame_cb) {
// Use the frame callback mechanism applied to the object's parent window
parent_xid->frame_cb = wl_surface_frame(parent_xid->wl_surface);
wl_callback_add_listener(parent_xid->frame_cb,
Fl_Wayland_Graphics_Driver::p_surface_frame_listener, parent_xid);
} else if (parent_xid->buffer && is_a_move) {
if (fl_win->subsurface) wl_subsurface_set_position(fl_win->subsurface, X * f, Y * f);
wl_surface_commit(parent_xid->wl_surface);
if (!parent_xid->buffer->wl_buffer || parent_xid->buffer->draw_buffer_needs_commit) {
if (!parent_xid->frame_cb) Fl_Wayland_Graphics_Driver::buffer_commit(parent_xid);
} else {
if (!parent_xid->frame_cb) {
// Use the frame callback mechanism applied to the object's parent window
parent_xid->frame_cb = wl_surface_frame(parent_xid->wl_surface);
wl_callback_add_listener(parent_xid->frame_cb,
Fl_Wayland_Graphics_Driver::p_surface_frame_listener, parent_xid);
}
wl_surface_commit(parent_xid->wl_surface);
}
}
checkSubwindowFrame(); // make sure subwindow doesn't leak outside parent
}