Missing Mouse Events in PDFView

  • Hi,

    Is it me or does it no longer work to subclass mouse events in
    PDFView? mouseDown is called correctly in my subclass, but after that
    I never receive mouseDragged and the mouseUp events. This poses
    serious problems for what worked fine under Tiger (showing a menu
    upon mouseUp). Is there a workaround or someway to know when the
    user  stopped selecting? I now kind of resort to listening to the
    setCurrentSelection method with a cancel and delayed timer each time
    this changes, but it's far from optimal.

    Also, now I use the lower right corner of the currentselection as the
    popup point for a menu, however I have difficulties getting the menu
    to popup at the right spot.
    This is what I have now:

    // get the point where we wish to popup
    NSRect selectionRect = [[self currentSelection]boundsForPage: [self
    currentPage]];
    NSPoint popupPoint = NSMakePoint(NSMaxX(selectionRect), NSMinY
    (selectionRect));
    popupPoint = [self convertPoint: popupPoint fromPage: [self
    currentPage]];
    // create a new event
    NSEvent *currentEvent = [NSApp currentEvent];
    NSEvent *click = [NSEvent mouseEventWithType: NSLeftMouseUp
                                         location: popupPoint
            modifierFlags:[currentEvent modifierFlags]
                                         timestamp:[currentEvent timestamp]
                                   windowNumber:[currentEvent windowNumber]
                                               context:[currentEvent context]
                                    eventNumber:0
                                         clickCount:0
                                         pressure:0.5];

    [NSMenu popUpContextMenu: selectionMenu withEvent: click forView: self];

    Unfortunately this never pops up the menu at the right location,
    usually in the origin of the window or somewhere else in the pdfview.
    Any help is greatly appreciated!
    Cheers,
    Alex
  • It seems indeed they changed the internals, however PDFView doesn't
    use NSCells and NSTrackingAreas are only for mousemoved events if I'm
    not mistaken...
    Alex

    On 31-okt-2007, at 12:53, Thomas Engelmeier wrote:

    >
    > On 31.10.2007, at 11:51, Alexander Griekspoor wrote:
    >>
    >> Is it me or does it no longer work to subclass mouse events in
    >> PDFView? mouseDown is called correctly in my subclass, but after
    >> that I never receive mouseDragged and the mouseUp events. This
    >> poses serious problems for what worked fine under Tiger (showing a
    >> menu upon mouseUp). Is there a workaround or someway to know when
    >> the user  stopped selecting?
    >
    > Is it related to the problem "Re: mouseUp: in TableView on
    > Leopard" ? As I cannot spot it on the list archives, here a summary:
    >
    >>> *when* are you expecting it to be called? In NSTableView's
    >>> mouseDown,
    >>> it has always created a loop where it processed events. The mouse
    >>> logic has changed a bit to accommodate new features and bug fixes.
    >
    > and
    >
    >> TableView will consume the mouse events when tracking from
    >> mouseDown. You should use the "tracking" class of methods in the
    >> NSCell, or the -action/-doubleAction for NSTableView if you want
    >> to respond to a click or double click.
    >
    >
    > Maybe the PDFView was altered for similar reasons.
  • Hi Alex,

    On Oct 31, 2007, at 3:51 AM, Alexander Griekspoor wrote:

    > Is it me or does it no longer work to subclass mouse events in
    > PDFView? mouseDown is called correctly in my subclass, but after
    > that I never receive mouseDragged and the mouseUp events. This poses
    > serious problems for what worked fine under Tiger (showing a menu
    > upon mouseUp). Is there a workaround or someway to know when the
    > user  stopped selecting?

    It's not just you.  We have the same problem in an app that relies
    heavily on PDFView.  If you find a workaround, I'd like to hear it; I
    got too frustrated with Xcode's glacial editing speed to work on it
    any further.  I suspect we'll move everything into mouseDown:, since
    that's what Apple seems to require.

    --
    Adam
  • No workaround yet, other than using setCurrentSelection, which is not
    too bad. However, I still am facing the problem of getting to convert
    a point from the PDFSelection boundary to the right format used to
    popup the menu.
    Alex

    On 31-okt-2007, at 14:55, Adam R. Maxwell wrote:

    > Hi Alex,
    >
    > On Oct 31, 2007, at 3:51 AM, Alexander Griekspoor wrote:
    >
    >> Is it me or does it no longer work to subclass mouse events in
    >> PDFView? mouseDown is called correctly in my subclass, but after
    >> that I never receive mouseDragged and the mouseUp events. This
    >> poses serious problems for what worked fine under Tiger (showing a
    >> menu upon mouseUp). Is there a workaround or someway to know when
    >> the user  stopped selecting?
    >
    > It's not just you.  We have the same problem in an app that relies
    > heavily on PDFView.  If you find a workaround, I'd like to hear it;
    > I got too frustrated with Xcode's glacial editing speed to work on
    > it any further.  I suspect we'll move everything into mouseDown:,
    > since that's what Apple seems to require.
    >
    > --
    > Adam

    *********************************************************
                    ** Alexander Griekspoor  PhD **
    *********************************************************
             EMBL Outstation - Hinxton,
              European Bioinformatics Institute,
             Rebholz Textmining group

         Wellcome Trust Genome Campus,
                  Cambridge, CB10 1SD, UK
                        Tel:  + 44 1223 492 605
                      Fax:  + 44 1223 492 468
                      Web: http://www.mekentosj.com

        Claiming that the Macintosh is inferior to Windows
        because most people use Windows, is like saying
        that all other restaurants serve food that is
        inferior to McDonalds

    *********************************************************
  • On Oct 31, 2007, at 3:51 AM, Alexander Griekspoor wrote:
    > Is it me or does it no longer work to subclass mouse events in
    > PDFView?

    It's not you.

    I didn't realize this would break anyone....

    Most of AppKit in fact don't use the -[mouseDragged] and -[mouseUp]
    events for tracking.  As of Leopard, neither does PDF Kit.

    It turns out that, for tracking in any event, a lot of state has to be
    kept (instance vars) in order to handle dragging or tracking across
    the three event flavors.  So what PDF Kit does now is:

    // Track the mouse while down.
    while ((nextEvent = [[self window] nextEventMatchingMask:
    NSLeftMouseDraggedMask | NSLeftMouseUpMask]))
    {
      NSPoint  viewMouse;
      NSPoint  pageMouse;

      // Get mouse in page coordinates.
      viewMouse = [self convertPointFromBase: [nextEvent locationInWindow]];
      pageMouse = [self convertPoint: viewMouse toPage: page];

      // Handle mouse tracking.

      // When the mouse is let up, we are done.
      if ([nextEvent type] == NSLeftMouseUp)
      {
      // Break out of mouse tracking loop.

      break;
      }
    }

    PDF Kit  may have a bug though since I would nonetheless expect you to
    get your mouse up event.  I'm thinking PDF Kit is swallowing the mouse
    up event in it's while loop (above).

    A workaround might be to subclass mouseDown and post your own mouseUp
    event at the tail of your method after calling -[super mouseDown:] if
    on Leopard.

    Does this help?

    I apologize again for not anticipating this.

    john calhoun—
  • On Oct 31, 2007, at 8:11 AM, Alexander Griekspoor wrote:
    > No workaround yet, other than using setCurrentSelection, which is
    > not too bad. However, I still am facing the problem of getting to
    > convert a point from the PDFSelection boundary to the right format
    > used to popup the menu.

    This is a common problem with PDFView since it has its own nested
    subviews.  To access the inner-most view (where PDF content and
    selectiosn are drawn) use PDFViews: [PDFView documentView]

    Your conversion needs I think one more convert then — something like:

    popupPoint = [_pdfView convertPoint: popupPoint toView: [_pdfView
    documentView]];

    john calhoun—
  • On Oct 31, 2007, at 10:47 AM, John Calhoun wrote:

    > Most of AppKit in fact don't use the -[mouseDragged] and -[mouseUp]
    > events for tracking.

    Really? Outside of things like buttons, that's an unfortunate choice,
    isn't it? As the "Cocoa Event-Handling Guide" points out, a class
    that handles dragging in this manner is "more difficult to extend
    without the subclass reimplementing all the dragging code".

    You'd think that extending AppKit classes would be a fairly common
    thing to want to do...

    _murat
  • Thanks, that certainly helps. I wasn't aware that now the mouseDown
    method only exits on a mouseUp. The solution would be simple then
    indeed.
    Great!

    Ps. the Leopard PDFView rocks...

    On 31-okt-2007, at 17:47, John Calhoun wrote:

    > On Oct 31, 2007, at 3:51 AM, Alexander Griekspoor wrote:
    >> Is it me or does it no longer work to subclass mouse events in
    >> PDFView?
    >
    > It's not you.
    >
    > I didn't realize this would break anyone....
    >
    > Most of AppKit in fact don't use the -[mouseDragged] and -[mouseUp]
    > events for tracking.  As of Leopard, neither does PDF Kit.
    >
    > It turns out that, for tracking in any event, a lot of state has to
    > be kept (instance vars) in order to handle dragging or tracking
    > across the three event flavors.  So what PDF Kit does now is:
    >
    > // Track the mouse while down.
    > while ((nextEvent = [[self window] nextEventMatchingMask:
    > NSLeftMouseDraggedMask | NSLeftMouseUpMask]))
    > {
    > NSPoint        viewMouse;
    > NSPoint        pageMouse;
    >
    > // Get mouse in page coordinates.
    > viewMouse = [self convertPointFromBase: [nextEvent
    > locationInWindow]];
    > pageMouse = [self convertPoint: viewMouse toPage: page];
    >
    > // Handle mouse tracking.
    >
    > // When the mouse is let up, we are done.
    > if ([nextEvent type] == NSLeftMouseUp)
    > {
    > // Break out of mouse tracking loop.
    >
    > break;
    > }
    > }
    >
    > PDF Kit  may have a bug though since I would nonetheless expect you
    > to get your mouse up event.  I'm thinking PDF Kit is swallowing the
    > mouse up event in it's while loop (above).
    >
    > A workaround might be to subclass mouseDown and post your own
    > mouseUp event at the tail of your method after calling -[super
    > mouseDown:] if on Leopard.
    >
    > Does this help?
    >
    > I apologize again for not anticipating this.
    >
    > john calhoun—
    >

    *********************************************************
                    ** Alexander Griekspoor  PhD **
    *********************************************************
             EMBL Outstation - Hinxton,
              European Bioinformatics Institute,
             Rebholz Textmining group

         Wellcome Trust Genome Campus,
                  Cambridge, CB10 1SD, UK
                        Tel:  + 44 1223 492 605
                      Fax:  + 44 1223 492 468
                      Web: http://www.mekentosj.com

            Papers - Your Personal Library of Science
            2007 Winner of the Apple Design Awards
             Best Mac OS X Scientific Solution
                    http://www.mekentosj.com/papers

    *********************************************************
  • >
    >> Most of AppKit in fact don't use the -[mouseDragged] and -[mouseUp]
    >> events for tracking.
    >
    > Really? Outside of things like buttons, that's an unfortunate
    > choice, isn't it? As the "Cocoa Event-Handling Guide" points out, a
    > class that handles dragging in this manner is "more difficult to
    > extend without the subclass reimplementing all the dragging code".
    >
    > You'd think that extending AppKit classes would be a fairly common
    > thing to want to do...

    NSTableView is one such class that has to do this. It needs to take
    control of mouse tracking. It is unfortunate, as it makes more
    difficult to subclass, but hopefully we have the appropriate hooks for
    developers to do what they want. If there isn't, then please log bugs.

    --corbin
  • On Oct 31, 2007, at 11:28 AM, Murat Konar wrote:
    > Really? Outside of things like buttons, that's an unfortunate
    > choice, isn't it? As the "Cocoa Event-Handling Guide" points out, a
    > class that handles dragging in this manner is "more difficult to
    > extend without the subclass reimplementing all the dragging code".

    I probably spoke out of place to say "most of AppKit".  The code I
    modeled could well be legacy AppKit behavior.

    Some of the tracking PDFView does is in fact akin to button tracking
    (link annotations are the obvious example).  Text selection though
    perhaps is better split across the multiple events. A hybrid approach
    like that though might have been even worse for sublclassers.  I don't
    know.

    john calhoun—
  • On Wednesday, October 31, 2007, at 11:33AM, "Murat Konar" <murat...> wrote:
    >
    > On Oct 31, 2007, at 10:47 AM, John Calhoun wrote:
    >
    >> Most of AppKit in fact don't use the -[mouseDragged] and -[mouseUp]
    >> events for tracking.
    >
    > Really? Outside of things like buttons, that's an unfortunate choice,
    > isn't it? As the "Cocoa Event-Handling Guide" points out, a class
    > that handles dragging in this manner is "more difficult to extend
    > without the subclass reimplementing all the dragging code".
    >
    > You'd think that extending AppKit classes would be a fairly common
    > thing to want to do...

    I prefer using the NSResponder methods because it doesn't foul up other event handling, and I thought that's what Apple people on this list have advocated (but my memory may be faulty).  I recently discovered that NSSplitView's mouseDown: breaks mouseDragged: for subviews...which seems particularly odd since NSSplitView is useless without subviews.  I wish there were a coherent story on this from Apple.  If the frameworks force us to use while(1) loops, then just remove mouseUp:/mouseDragged: from NSResponder and be done with it.

    --
    adam
  • >
    > Really? Outside of things like buttons, that's an unfortunate choice,
    > isn't it? As the "Cocoa Event-Handling Guide" points out, a class
    > that handles dragging in this manner is "more difficult to extend
    > without the subclass reimplementing all the dragging code".

    Absolutely.  I don't use PDFView but I had to do some unpleasant
    things when sub-classing NSTextView (which behaves the same way). I
    was under the impression that this was a NextStep holdover and that
    new things wouldn't do it.

    > It turns out that, for tracking in any event, a lot of state has to be
    > kept (instance vars) in order to handle dragging or tracking across
    > the three event flavors.

    So? So keep it. What is the problem? If you're worried about the
    allocated size of the object, put your state information in a struct
    and allocate it on mouseDown and free it on mouseUp. That way you
    only increase the size of the object by a few bytes. The other way
    really limits the usefulness of the object because you can't subclass
    it properly. (Not to  mention confusing beginners who look at the
    docs, see a subclass of NSResponder and wonder why their methods
    never get called.)

    Robert Clair
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today