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 Apps      FLTK Library      Forums      Links     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-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.