2016-07-07 5 views
4

Ich erstelle meine eigene Unterklasse von NSApplication und stoße in einen Roadblock. Hier ist meine Implementierung der run() Methode.NSWindow schließt nicht, wenn mit benutzerdefinierter NSApplication erstellt

override func run() { 
    finishLaunching() 
    repeat { 

     let event = nextEventMatchingMask(0xfffffffffffffff, untilDate: NSDate.distantPast(), inMode: NSDefaultRunLoopMode, dequeue: true) 
     if event != nil { sendEvent(event!) } 
     updateWindows() 

    } while true 

} 

In meinem main.swift Ich habe dies:

let myApp: MyApplication = MyApplication.sharedApplication() as! MyApplication 

let window = NSWindow(contentRect: NSMakeRect(0, 0, 100, 100), styleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask , backing: .Buffered, defer: false) 
window.makeKeyAndOrderFront(nil) 

myApp.run() 

Der Grund, warum ich habe 0xfffffffffffffff statt Int(NSEventMask.AnyEventMask.rawValue) da dieser überläuft, wenn UInt64-Int umgewandelt.

Das Problem ist, wenn ich auf den roten Schließen-Button klicke, wird das Fenster nicht geschlossen, und wenn ich "Beenden" aus dem Dock-Icon-Menü wähle, wird es nicht beendet. Warum passiert das?

EDIT: Das gleiche Problem in diskutiert wird this answer.

EDIT 2: Ich habe eine Objective-c Version dieses Codes erstellt, und alles funktioniert. Ich vermute das Problem ist, dass ich NSAnyEventMask nicht in Swift verwenden kann.

Antwort

0

Ich habe das Problem gelöst, in Objective-C kann ich einfach das verwenden, und meine App wird auf das Quit-Element im Dock-Menü reagieren.

NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask 
            untilDate:nil 
             inMode:NSDefaultRunLoopMode 
             dequeue:YES]; 

In Swift, wenn Sie versuchen, wie das nächste Ereignis zu bekommen, dass Sie dies tun würden:

let event = nextEventMatchingMask(Int(NSEventMask.AnyEventMask.rawValue), 
            untilDate: NSDate.distantPast(), 
            inMode: NSDefaultRunLoopMode, 
            dequeue: true) 

Sie jedoch einen Überlauffehler erhalten, wenn sie von UInt64 Umwandlung Int. Dies scheint nicht beabsichtigt zu sein. Zuerst versuchte ich, dieses Problem zu lösen, indem ich es durch 0xfffffffffffffff ersetzte. Dies funktionierte gut und die App würde auf Ereignisse reagieren. Aber das war nicht genug. Die App muss auch auf Ereignisse reagieren, die mit einer Maske übereinstimmen 0x1. Ich habe keine Ahnung warum, aber das erlaubt mir, meine App aus dem Dock-Menü auszublenden und zu verstecken. (0x0 erlaubt es mir nur zu beenden.)

So dann wird die gesamte run() Implementierung einer Unterklasse Swift NSApplication ist dies:

override func run() { 
    finishLaunching() 
    setValue(true, forKey: "running") 

    while true { 
     let event = nextEventMatchingMask(0xfffffffffffffff, untilDate: NSDate.distantPast(), inMode: NSDefaultRunLoopMode, dequeue: true) 
     let dockEvent = nextEventMatchingMask(0x1, untilDate: NSDate.distantPast(), inMode: NSDefaultRunLoopMode, dequeue: true) 

     if dockEvent != nil { sendEvent(dockEvent!) } 
     if event != nil { sendEvent(event!) } 

     if !running { break } 

     updateWindows() 
    } 
} 
1

Sie sollten nur während self.running wiederholen. Das könnte erklären, warum deine App nicht beendet wird. Wenn Ihre App so konfiguriert ist, dass sie beim Schließen des letzten Fensters beendet wird, kann dies auch erklären, warum Ihr Fenster nicht geschlossen wird. Es kann sein, dass das Framework das Fenster nicht separat schließt, wenn die gesamte App sowieso beendet wird.

+0

Das Problem ist, dass das, was tut, ist es nicht laufen zu lassen. Ich kann 'running' nicht explizit festlegen, ohne' super.run() '' –

+0

Hmm zu nennen. Ja, ich sehe, dass Apples alter [GLUT-Beispielcode] (https://developer.apple.com/legacy/library/samplecode/glut/Listings/GLUTApplication_m.html) darauf abzielt, die Instanzvariable '_running' der Superklasse direkt zu setzen Swift wird wahrscheinlich nicht erlauben. Also könntest du es mit KVC versuchen: 'setValue (true, forKey:" running ")'. –

+0

Ich habe ehrlich gesagt noch nie davon gehört. Könnten Sie das in ein Codebeispiel einfügen? Das, was du eingibst, funktioniert nicht. - Vergiss, was ich gesagt habe, aber es funktioniert nicht. –