Specific issue with macOS drawRect

100 views
Skip to first unread message

anmol....@gmail.com

unread,
Jul 17, 2021, 6:55:38 PM7/17/21
to fltk.general
I refer to Manolo's checkin - https://www.fltk.org/newsgroups.php?gfltk.commit+v:14544

A problem arises to support drawing done outside Fl_X::flush(), that is, after the app calls Fl_Window::make_current() at any time it wants. That situation is identified by the condition (views_use_CA && !through_drawRect). A graphics context usable outside drawRect: that ultimately appears on screen, if it exists, was not identified. Drawing operations after the call to Fl_Window::make_current() are directed to aux_bitmap. Fl_Window::make_current() calls [view setNeedsDisplay:YES] which instructs the system to run drawRect: at the next event loop. Later, when drawRect: runs, the content of aux_bitmap is copied to drawRect's graphics context.

I have a Fl_wizard window that runs fine in a very simple test app. As a part of a larger project, it just goes gray and most of the widgets disappear if I click on any field.

Tracing this in Xcode gives an error related to the same macOS code mentioned above. 

CGBitmapContextGetWidth: invalid context 0x600003722340. 

Backtrace:

  <CGBitmapContextGetWidth+49>

   <-[FLView create_aux_bitmap:retina:]+55>

    <-[FLView drawRect:]+360>

     <_NSViewDrawRect+139>

      <-[NSView _drawRect:clip:]+1103>

       <-[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:]+2143>

        <-[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:]+3503>

         <-[NSView _oldDisplayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:]+2126>

          <-[NSView displayIfNeeded]+755>

           <-[NSWindow displayIfNeeded]+261>

            <__NSWindowGetDisplayCycleObserverForDisplay_block_invoke+646>

             <NSDisplayCycleObserverInvoke+155>

              <NSDisplayCycleFlush+937>

               <_ZN2CA11Transaction19run_commit_handlersE18CATransactionPhase+106>

                <_ZN2CA11Transaction6commitEv+230>

                 <__62+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayLink]_block_invoke+266>

                  <___NSRunLoopObserverCreateWithHandler_block_invoke+41>

                   <__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__+23>

                    <__CFRunLoopDoObservers+457>

                     <__CFRunLoopRun+874>

                      <CFRunLoopRunSpecific+462>

                       <RunCurrentEventLoopInMode+292>

                        <ReceiveNextEventCommon+359>

                         <_BlockUntilNextEventMatchingListInModeWithFilter+64>

                          <_DPSNextEvent+883>

                           <-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]+1352>

                            <_ZN22Fl_Cocoa_Screen_Driver4waitEd+504>

                             <_ZN2Fl3runEv+44>

                              <_ZL8RegisterP9PF_InDataP10PF_OutData+136>

                               <EntryPointFunc+1557>



Screenshot 2021-07-16 at 6.23.12 PM copy.jpg

Manolo

unread,
Jul 18, 2021, 6:25:27 AM7/18/21
to fltk.general
This looks very much like using an old FLTK version that doesn't support macOS 10.15 or 11.
Please, triple check what source code you link your app against.
Make sure you use FLTK 1.4 or FLTK 1.3.6

anmol....@gmail.com

unread,
Jul 18, 2021, 9:08:01 AM7/18/21
to fltk.general
I had this same issue with 1.3.6 
I deleted all links to it, downloaded 1.4 from repo and installed it using Xcode.

I also used C++17 instead of C++2a in case it was a compiler issue. I tried different variants, modal vs non-modal etc - and nothing worked.

I can use this on 10.15 in a very simple test program, but as a part of a larger project, this error pops up.
There is a complex parent gui with a button (non-fltk) and my little fltk window pops up within this callback.

Is there some global init that may work ?

anmol....@gmail.com

unread,
Jul 18, 2021, 11:32:02 AM7/18/21
to fltk.general
I think the issue is that the new window has a parent window, and while Win has no issue with child windows macOS seems to work different.
Thats why a simple test program works - since I am defining the parent window. However, within the larger UI, I can only define a child window.

As a result the menu bar items for parent window disappear, leaving only the <App Name> and Window defaults. Also, any focus event like scrolling and clicking cause the entire child window to go grey.

So, if I do not have access to parent window, what is the correct method of defining and using a child window on macOS ?

I do not want to take over the menu bar of the parent, I am only interested in a simple popup wizard.
I looked at the subwindow example and it uses 

  Fl_Cursor crsr;

The cursor is set to FL_CURSOR_HAND in the child window.

And the text mentions

          "A child Fl_Window with children of its own may be useful for imbedding controls into a GL or display that needs a different visual.  

There are bugs with the origins being different between drawing and events, which I hope I have solved."


Manolo

unread,
Jul 19, 2021, 3:26:50 AM7/19/21
to fltk.general
Le dimanche 18 juillet 2021 à 00:55:38 UTC+2, anmol....@gmail.com a écrit :
I have a Fl_wizard window that runs fine in a very simple test app. As a part of a larger project, it just goes gray and most of the widgets disappear if I click on any field.

Tracing this in Xcode gives an error related to the same macOS code mentioned above. 

CGBitmapContextGetWidth: invalid context 0x600003722340. 

Backtrace:

  <CGBitmapContextGetWidth+49>

   <-[FLView create_aux_bitmap:retina:]+55>

    <-[FLView drawRect:]+360>

 …etc…


The crash is when FLTK function create_aux_bitmap calls macOS function CGBitmapContextGetWidth.
Here is that FLTK function:
- (void)create_aux_bitmap:(CGContextRef)gc retina:(BOOL)r {
  if (!gc || fl_mac_os_version >= 101600) {
    // bitmap context-related functions (e.g., CGBitmapContextGetBytesPerRow) can't be used here with macOS 11.0 "Big Sur"
    static CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
    int W = [self frame].size.width, H = [self frame].size.height;
    if (r) { W *= 2; H *= 2; }
    aux_bitmap = CGBitmapContextCreate(NULL, W, H, 8, 0, cspace, kCGImageAlphaPremultipliedFirst|kCGBitmapByteOrder32Host);
  } else {
    aux_bitmap = CGBitmapContextCreate(NULL, CGBitmapContextGetWidth(gc), CGBitmapContextGetHeight(gc),
                                       CGBitmapContextGetBitsPerComponent(gc), CGBitmapContextGetBytesPerRow(gc),
                                       CGBitmapContextGetColorSpace(gc), CGBitmapContextGetBitmapInfo(gc));
  }
  if (r) CGContextScaleCTM(aux_bitmap, 2, 2);
}

When running macOS 11 or above, the first part of the if MUST be chosen, which avoids
a call to CGBitmapContextGetWidth() that faults with these macOS versions.
Thus, either you run an older version of FLTK (Sorry, I insist because this has happened
so many times with systems containing various FLTK source trees),  or global variable fl_mac_os_version is not properly initialized.
Its value should be 1015xx on macOS 10.15, or 101600 or 11xxyy on macOS 11.
Please, have its value printed out before your program creates its first FLTK window.
It's enough to declare it with :
  extern int fl_mac_os_version;

fl_mac_os_version is assigned either as a static initializer, or when FLTK opens the display.
But if that's not enough in your special setting that mixes FLTK and non-FLTK windows,
you can force its initialization calling FLTK's public function fl_open_display() early in your program.
This requires :
#include <FL/platform.H>

Let me know, please, if it's getting better with that cure.

anmol....@gmail.com

unread,
Jul 22, 2021, 1:19:52 PM7/22/21
to fltk.general
I ended up using CFUserNotification from CoreFoundation directly. I am going to revisit this in a few weeks to see if there is still a problem.

anmol....@gmail.com

unread,
Jul 22, 2021, 3:00:35 PM7/22/21
to fltk.general
For my own reference, I get a warning here - 
NSOpenGLContext deprecated. For some odd reason, Xcode is defining __OBJC__

#ifdef __OBJC__

  @class NSOpenGLContext;

  typedef NSOpenGLContext* GLContext;

#elif defined(__cplusplus)

  typedef class NSOpenGLContext* GLContext;

#endif /* __OBJC__ */


Manolo

unread,
Jul 24, 2021, 3:02:21 AM7/24/21
to fltk.general
Le jeudi 22 juillet 2021 à 21:00:35 UTC+2, anmol....@gmail.com a écrit :
For my own reference, I get a warning here - 
NSOpenGLContext deprecated. For some odd reason, Xcode is defining __OBJC__

#ifdef __OBJC__

  @class NSOpenGLContext;

  typedef NSOpenGLContext* GLContext;

#elif defined(__cplusplus)

  typedef class NSOpenGLContext* GLContext;

#endif /* __OBJC__ */

This construct allows an include file to detect whether it's being used in an Objective-C/C++
or a C++ source file. The FLTK source code contains a majority of C++ source files, a handful
are Objective-C++ (for the macOS platform only), and a few are C.

Now, macOS has decided to deprecate all of OpenGL a few years ago, most probably in a move to push their Metal.
But there's no connection whatsoever between the warning and __OBJC__ being defined or not.

Reply all
Reply to author
Forward
0 new messages