FLTK logo

[master] 7e484c6 - Fix for [fltk.coredev] reentrant calls with Fl_Window::resize

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Library      Forums      Links      Apps     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 7e484c6 - Fix for reentrant calls with Fl_Window::resize "ManoloFLTK" Nov 24, 2021  
 
commit 7e484c614c16f0a6580ba2c2efaa654ab4e08082
Author:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Wed Nov 24 10:35:18 2021 +0100
Commit:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Wed Nov 24 10:35:18 2021 +0100

    Fix for [fltk.coredev] reentrant calls with Fl_Window::resize

 src/Fl_cocoa.mm                              | 23 ++++++++++++++++++-----
 src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H   |  2 ++
 src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx | 10 ++++++++++
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git src/Fl_cocoa.mm src/Fl_cocoa.mm
index 2c130f5..e151150 100644
--- src/Fl_cocoa.mm
+++ src/Fl_cocoa.mm
@@ -1221,7 +1221,12 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
     main_screen_height = CGDisplayBounds(CGMainDisplayID()).size.height;
     int X, Y;
     CocoatoFLTK(window, X, Y);
-    if (window->x() != X || window->y() != Y) window->position(X, Y);
+    if (window->x() != X || window->y() != Y) {
+      if (!Fl_Cocoa_Window_Driver::driver(window)->through_resize())
+         window->position(X, Y);
+      else
+        window->Fl_Widget::resize(X,Y,window->w(),window->h());
+    }
     update_e_xy_and_e_xy_root(nsw);
     // at least since MacOS 10.9: OS moves subwindows contained in a moved window
     // setSubwindowFrame is no longer necessary.
@@ -1244,7 +1249,10 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
   float s = Fl::screen_driver()->scale(window->screen_num());
   NSRect r = [view frame];
   Fl_Cocoa_Window_Driver::driver(window)->view_resized(1);
-  window->resize(X, Y, lround(r.size.width/s), lround(r.size.height/s));
+  if (Fl_Cocoa_Window_Driver::driver(window)->through_resize())
+    Fl_Cocoa_Window_Driver::driver(window)->resize(X, Y, lround(r.size.width/s), lround(r.size.height/s));
+  else
+    window->resize(X, Y, lround(r.size.width/s), lround(r.size.height/s));
   Fl_Cocoa_Window_Driver::driver(window)->view_resized(0);
   update_e_xy_and_e_xy_root(nsw);
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14
@@ -3327,9 +3335,10 @@ void Fl_Cocoa_Window_Driver::resize(int X, int Y, int W, int H) {
   if (view_resized() || !visible_r()) {
     pWindow->Fl_Group::resize(X, Y, W, H);
     if (!pWindow->shown()) pWindow->init_sizes();
-  } else {
+  } else if (!through_resize()) {
     NSPoint pt = FLTKtoCocoa(pWindow, X, Y, H);
     FLWindow *xid = fl_xid(pWindow);
+    through_resize(1);
     if (W != w() || H != h() || Fl_Window::is_a_rescale()) {
       NSRect r;
       float s = Fl::screen_driver()->scale(screen_num());
@@ -3347,10 +3356,14 @@ void Fl_Cocoa_Window_Driver::resize(int X, int Y, int W, int H) {
     }
     else {
       if (pWindow->parent()) starting_moved_window = pWindow;
-      [xid setFrameOrigin:pt]; // set cocoa coords to FLTK position
-      x(X); y(Y); // useful when frame did not move but X or Y changed
+      if (!NSEqualPoints([xid frame].origin, pt))
+        [xid setFrameOrigin:pt]; // set cocoa coords to FLTK position
+      else {
+        x(X); y(Y);
+      }
       if (pWindow->parent()) starting_moved_window = NULL;
     }
+    through_resize(0);
   }
 }
 
diff --git src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
index 970d788..6f0f11d 100644
--- src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
+++ src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
@@ -100,6 +100,8 @@ public:
   void changed_resolution(bool);// sets whether window just moved to display with another resolution
   bool view_resized();   // did window's view receive [FLView view_did_resize] message?
   void view_resized(bool b); // sets whether window's view received [FLView view_did_resize] message
+  bool through_resize();   // did Fl_Window::resize() run already
+  void through_resize(bool b); // set whether Fl_Window::resize() run already
   CGRect* subRect() { return subRect_; } // getter
   void subRect(CGRect *r) { subRect_ = r; } // setter
   static void destroy(FLWindow*);
diff --git src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
index 1b6205c..f9ba656 100644
--- src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
+++ src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
@@ -262,6 +262,7 @@ int Fl_Cocoa_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h, i
 static const unsigned mapped_mask = 1;
 static const unsigned changed_mask = 2;
 static const unsigned view_resized_mask = 4;
+static const unsigned through_resize_mask = 8;
 
 bool Fl_Cocoa_Window_Driver::mapped_to_retina() {
   return window_flags_ & mapped_mask;
@@ -290,6 +291,15 @@ void Fl_Cocoa_Window_Driver::view_resized(bool b) {
   else window_flags_ &= ~view_resized_mask;
 }
 
+bool Fl_Cocoa_Window_Driver::through_resize() {
+  return window_flags_ & through_resize_mask;
+}
+
+void Fl_Cocoa_Window_Driver::through_resize(bool b) {
+  if (b) window_flags_ |= through_resize_mask;
+  else window_flags_ &= ~through_resize_mask;
+}
+
 
 // clip the graphics context to rounded corners
 void Fl_Cocoa_Window_Driver::clip_to_rounded_corners(CGContextRef gc, int w, int h) {
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2025 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.