Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-69289

Crash on macOS when using winId() after hiding/showing QMainWindow (introduced in Qt 5.11)

    XMLWordPrintable

Details

    • macOS
    • a9246c7132a2c8864d3ae6cebd260bb9ee711fcb (qt/qtbase/5.12) 009abcd7b66738bece6cf354776dfb2ef401636b (qt/qtbase/5.15) e2f35fa6842508f6bd9d2343f08a17a2a292fd71 (qt/qtbase/5.12.7)
    • Bug Fixing Week Q2/2020

    Description

      Summary:

      Starting with Qt 5.11, winId() seems to return a freed pointer when the QMainWindow is hidden and then showed which led to a crash when used. This issue could not be reproduced on Qt 5.9 and Qt 5.10 and has been introduced in Qt 5.11.

      See attached screencast: screencast.mov

       

      Steps to reproduce:

      1. Download the attached application QtBlackTitlebar QtBlackTitlebar_src.zip
      2. Compile the application on macOS 10.13.5 and run it
      3. Close the window
      4. Using the QSystemTray, display the window

      Result: The application crashes.

       

      More information:

      The application tries to determine if the new Key NSWindow is the main window in:

      - (void)windowDidBecomeKey:(NSNotification*)notification
      

      In order to do so, it gets the singleton instance of the MainWindow (which is a QMainWindow) and gets the winId() pointer. It casts the winId() pointer to an NSView and compares the NSWindow to the NSWindow passed in the NSNotification.

       

      Using winId() like this is probably not ideal but the value returned by winId() should never be a freed pointer. If the underlaying object has been released, winId() should probably return a NULL pointer.

       

      Also I could not find any proper API to detect if the NSWindow received in windowDidBecomeKey: is the main QMainWindow. A possible workaround could be to check the class type of the NSWindow like the following, although it is again not clean:

      - (BOOL)isMainWindow:(NSWindow*)inWindow
      {
      if(inWindow == nil)
      return NO;
      
      // Only the MainWindow is an instance of QNSWindow
      if ([NSStringFromClass([inWindow class]) isEqualToString:@"QNSWindow"])
      {
      return YES;
      }
      
      return NO;
      }
      

       

      Attachments

        1. QtBlackTitlebar_src.zip
          5 kB
          user-e3f1a
        2. screencast.mov
          164 kB
          user-e3f1a

        Issue Links

          Activity

            People

              vestbo Tor Arne Vestbø
              jirauser46068 user-e3f1a (Inactive)
              Votes:
              4 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: