1

Dues to I am using CALayer's mask attribute to draw and clip the content, the mask's size is like a NSView with a 10 pixel border, some of my content is larger than the current NSView's size with 10 pixel. But currently the mouse move event seems only detected when mouse move into the NSView area, I am trying to use NSTrackingArea the negative origin but seems not work?

Does anybody know how to detect the mouse move event outside current view?

Thanks,

Eric

More detail of my question:

I need to draw some content outside my view (which is inside a bigger view) and detect the mouse event on my content and this is my current limitation that I can't use a larger view to draw my whole content, just consider it a special type of shadow and I need to detect mouse event on the shadow, so I use a mask to clip the whole content. Here is my code used to apple the mask. The margin is how much pixel I want to extend from my view. (apply this function to a NSView directly)

    func applyMaskToView(src: NSView, margin: CGFloat) {
    src.wantsLayer = true
    
    let mask = CALayer()
    mask.backgroundColor = NSColor.black.cgColor
    let maskFrame = CGRect(x: -margin,
                           y: -margin,
                           width: src.frame.size.width + 2*margin,
                           height: src.frame.size.height + 2*margin )
    mask.frame = maskFrame
    src.layer?.masksToBounds = false
    src.layer?.mask = mask
    return
}

The code I used to apply tracking area is here (inside the NSView subclass):

    override func updateTrackingAreas() {

    var trackingArea: NSTrackingArea?

    let options1: NSTrackingArea.Options = [.mouseEnteredAndExited,
                                            .activeAlways, 
                                            .mouseMoved,
                                            .enabledDuringMouseDrag]

    let options2: NSTrackingArea.Options = [options1, .inVisibleRect]

    for area in self.trackingAreas {
        self.removeTrackingArea(area)
    }

    if let activeBound = self.layer?.mask?.frame {
         trackingArea = NSTrackingArea.init(rect: activeBound, options: options1, owner: self, userInfo: nil)
    }
    else {
        trackingArea = NSTrackingArea.init(rect: self.bounds, options: options2, owner: self, userInfo: nil)
    }
    
    self.addTrackingArea(trackingArea!)
    super.updateTrackingAreas()
    
}

If I don't use tracking area, I can't receive the mouse event in the margin area mention in the above code. However I can receive "mouse move" only now.

彭煥閎
  • 97
  • 9
  • https://stackoverflow.com/a/31932049/2303865 – Leo Dabus Sep 17 '20 at 04:21
  • Thanks, did you mean I need to monitor global event on whole application other than my view? This view is just a small part of my full application. I can get mouse move of the view already, I problem is I can't get mouse move event just a little outside my view. So I want to find is there a easy way to detect the mouse move event base on my view's coordinate? – 彭煥閎 Sep 17 '20 at 06:29
  • I found that my problem may caused by the option value "inVisibleRect" when I initial NSTrackingArea. Seems no meter what rectangle I set to initialize NSTrackingArea, once this option exist, all my rectangle became invalid? I am not sure is this the root cause of my problem? – 彭煥閎 Sep 17 '20 at 07:41
  • After I remove the "inVisibleRect" option, the detection of "mouse move" correctly, but I still can't get "mouse drag", "mouse down", "mouse up" , ... mouse status related event after I set the Tracking area. – 彭煥閎 Sep 18 '20 at 02:17
  • Why do you need to set a tracking area? Edit your question and post your code. Make sure to provide a [mcve] – Leo Dabus Sep 18 '20 at 02:18
  • I have append more information to my question. I have a request that is a little like you need to have drag capability of view's shadow. – 彭煥閎 Sep 18 '20 at 06:34

0 Answers0