From efac0cb9ab3f228a28f365ef7e3ad3acf3144eff Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Mon, 20 Oct 2025 15:09:18 +0200 Subject: =?UTF-8?q?Fix=20"New=20Wayland=20subwindow=20code=20creates=20iss?= =?UTF-8?q?ues=20with=20resizes=20of=20opengl=20windows=E2=80=A6"=20(#1311?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H | 1 + .../Wayland/Fl_Wayland_Gl_Window_Driver.cxx | 8 ++++++ src/drivers/Wayland/Fl_Wayland_Window_Driver.H | 2 +- src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 31 +++++++++++++++------- 4 files changed, 31 insertions(+), 11 deletions(-) (limited to 'src/drivers/Wayland') diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H index 75d313da7..0fac14877 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H @@ -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; diff --git a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx index c8be2676b..4817562de 100644 --- a/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx @@ -406,6 +406,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; } diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H index 5a34c16a9..1cf378178 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H @@ -149,7 +149,6 @@ struct wld_window { struct wl_callback *frame_cb; struct Fl_Wayland_Graphics_Driver::wld_buffer *buffer; struct xdg_surface *xdg_surface; - enum Fl_Wayland_Window_Driver::kind kind; union { // for each value of kind struct libdecor_frame *frame; struct wl_subsurface *subsurface; @@ -158,6 +157,7 @@ struct wld_window { }; // non-null when using custom cursor struct Fl_Wayland_Window_Driver::custom_cursor *custom_cursor; + enum Fl_Wayland_Window_Driver::kind kind; int configured_width; int configured_height; int floating_width; diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index ffb33fb4e..6c7da19fe 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -1452,7 +1452,7 @@ void Fl_Wayland_Window_Driver::makeWindow() Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); new_window->wl_surface = wl_compositor_create_surface(scr_driver->wl_compositor); - //Fl::warning("makeWindow:%p wayland-scale=%d user-scale=%.2f\n", pWindow, new_window->scale, Fl::screen_scale(0)); +//printf("makeWindow:%p %s %s\n", pWindow, pWindow->parent()?"SUB":"", pWindow->as_gl_window()?"GL":""); wl_surface_add_listener(new_window->wl_surface, &surface_listener, new_window); if (!shape()) { // rectangular FLTK windows are opaque @@ -1841,9 +1841,14 @@ 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) { +//printf("resize[%p] %dx%d is_a_resize=%d is_a_move=%d depth=%d parent_xid->frame_cb=%p\n", pWindow,W,H,is_a_resize,is_a_move,depth, (parent_xid?parent_xid->frame_cb:0) ); + 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; } @@ -1917,13 +1922,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 } -- cgit v1.2.3