summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2025-10-20 15:09:18 +0200
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2025-10-20 15:09:52 +0200
commitefac0cb9ab3f228a28f365ef7e3ad3acf3144eff (patch)
tree5225e38b1316d3e44633a5670ec00e4dc7da0eb0
parent0ced7991b4d855538f426e95a2f9eb76ba3dbf0f (diff)
Fix "New Wayland subwindow code creates issues with resizes of opengl windows…" (#1311)
-rw-r--r--src/Fl_Gl_Window.cxx1
-rw-r--r--src/Fl_Gl_Window_Driver.H1
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.H1
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx8
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Window_Driver.H2
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx31
6 files changed, 33 insertions, 11 deletions
diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx
index b56bd30f9..56d6f076f 100644
--- a/src/Fl_Gl_Window.cxx
+++ b/src/Fl_Gl_Window.cxx
@@ -300,6 +300,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();
}
/**
diff --git a/src/Fl_Gl_Window_Driver.H b/src/Fl_Gl_Window_Driver.H
index d40cbf89e..aed986d6d 100644
--- a/src/Fl_Gl_Window_Driver.H
+++ b/src/Fl_Gl_Window_Driver.H
@@ -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; }
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
}