[Qt-interest] QTreeView Wierdness with OS X Cocoa Qt 4.5.0

Mike Jackson imikejackson at gmail.com
Tue Apr 28 19:03:13 CEST 2009


Dennis Wilkinson wrote:
>> On 2009-03-28 11:20:47 -0400, Mike Jackson <imikejackson at
>> gmail.com> said:
>>
>>> On 2009-03-28 11:05:45 -0400, Mike Jackson <imikejackson at
>> gmail.com> said:
>>>> I have an application that uses a QTreeView with a custom TreeModel
>>>> implementation. When I build against Qt 4.5 (Cocoa 32 Bit) the
>> top few
>>>> items do not seem to receive any mouse clicks. I can use the
>> keyboard
>>>> arrow key to highlight the top (root) item then use the arrow key
>> again
>>>> to reveal but it takes a few of these iterations to finally be
>> able to
>>>> let the mouse have any effect on the tree view (like showing and
>>>> hiding) nodes.
>>>>
>>>>   Has anyone else seen anything like this? When I recompile
>> against a
>>>> 32 bit Qt 4.4.3 build (Carbon) the tree acts just fine.
>>>>
>>>> I have not compiled against a carbon Qt 4.5 though to see if it
>> is the
>>>> Cocoa/Carbon thing or the 4.4 to 4.5 thing.
>>>>
>>>> Any help would be appreciated.
>>>>
>>>> Mike Jackson
>>> I also noticed the same issues with Qt Designer and the tool
>> pallettes,
>>> specifically the Object Inspector. The same issues happen there
>> also. I
>>> can not use the mouse to make a selection (single or double
>> click). Not
>>> sure if this is all related but might seem to be.
>>>
>>>  Also, this is with a new Mac Pro if that matters at all.
>>>
>>> Thanks
>>> Mike Jackson
>> Anyone else had this problem? Did I miss something in my build? Should
>> I file a formal bug report?
>>
> 
> I've just finished debugging the same symptoms. Are you by any chance
> hiding the header() for the QTreeView?
> 
> It looks to me like the logic in [QCocoaView
> viewUnderTransparentForMouseView:widget:withWindowPoint:] in src/gui/
> kernel/qcocoaview_mac.mm is failing to account for NSViews that are
> hidden, like the NSView underlying the QTreeView's QHeaderView in this
> case. I'm working around it by installing an event filter on the
> QHeaderView and redispatching all mouse events to the viewport() if
> the header is hidden, but I think that changing the QCocoaView
> implementation to what I've posted below is a reasonable patch
> (hopefully it doesn't get rewrapped too badly).
> 
> This looks to still be an issue in 4.5.1/Cocoa.
> 
> - (NSView *)viewUnderTransparentForMouseView:(NSView *)mouseView
> widget:(QWidget *)widgetToGetMouse
>                               withWindowPoint:(NSPoint)windowPoint
> {
>      NSMutableArray *viewsToLookAt = [NSMutableArray arrayWithCapacity:
> 5];
>      [viewsToLookAt addObject:mouseView];
>      QWidget *parentWidget = widgetToGetMouse->parentWidget();
>      while (parentWidget) {
>          [viewsToLookAt addObject:qt_mac_nativeview_for(parentWidget)];
>          parentWidget = parentWidget->parentWidget();
>      }
> 
>      // Now walk through the subviews of each view and determine which
> subview should
>      // get the event. We look through all the subviews at a given
> level with
>      // the assumption that the last item to be found the candidate
> has a higher z-order.
>      // Unfortunately, fast enumeration doesn't go backwards in 10.5,
> so assume go fast
>      // forward is quicker than the slow normal way backwards.
>      NSView *candidateView = nil;
>      for (NSView *lookView in viewsToLookAt) {
>          NSPoint tmpPoint = [lookView convertPoint:windowPoint
> fromView:nil];
>          for (NSView *view in [lookView subviews]) {
>              if (view == mouseView || [view isHidden]) // don't hit
> test hidden views!
>                  continue;
>              NSRect frameRect = [view frame];
>              if (NSMouseInRect(tmpPoint, [view frame], [view
> isFlipped]))
>                  candidateView = view;
>          }
>          if (candidateView)
>              break;
>      }
> 
> 
>      if (candidateView != nil) {
>          // Now that we've got a candidate, we have to dig into it's
> tree and see where it is.
>          NSView *lowerView = nil;
>          NSView *viewForDescent = candidateView;
>          while (viewForDescent) {
>              NSPoint tmpPoint = [viewForDescent
> convertPoint:windowPoint fromView:nil];
>              // Apply same rule as above wrt z-order.
>              for (NSView *view in [viewForDescent subviews]) {
>                  if ([view isHidden]) // don't hit test hidden views!
>                      continue;
>                  if (NSMouseInRect(tmpPoint, [view frame], [view
> isFlipped]))
>                      lowerView = view;
>              }
>              if (!lowerView) // Low as we can be at this point.
>                  candidateView = viewForDescent;
> 
>              // Try to go deeper, will also exit out of the loop, if
> we found the point.
>              viewForDescent = lowerView;
>              lowerView = nil;
>          }
>      }
>      // I am transparent, so I can't be a candidate.
>      if (candidateView == mouseView)
>          candidateView = nil;
>      return candidateView;
> }
> 
> --
> Dennis
> 
> Dennis J. Wilkinson, II
> Graphical Languages UI Engineer
> The MathWorks, Inc.
> dennis.wilkinson(at)mathworks.com
> 
> 

I believe I was hiding the headers. Thanks for taking the time to debug 
it. Maybe it will make it into the 4.5.2 release. Currently there are 
still enough issues with 4.5.x Cocoa to render it useless for programs. 
Still stuck with carbon for the foreseeable future.

Mike



More information about the Qt-interest-old mailing list