GNUstepとCocotron / GNUstep and Cocotron

2174bd20a68bf55c494a424ad3790f4a?s=47 1024jp
March 24, 2019

GNUstepとCocotron / GNUstep and Cocotron

macOS native symposium (http://macos-native.github.io) #03 登壇資料

GitHubなどでAppKitのメソッドを検索していると不思議なAppKitの実装コードのようなものを目にすることがないでしょうか。はて、Cocoaはクローズドソースのはずだが…。GNUstepとは、Cocotronとは何なのか。いま一度これらCocoaクローンの正体を紐解いてみましょう。

2174bd20a68bf55c494a424ad3790f4a?s=128

1024jp

March 24, 2019
Tweet

Transcript

  1. 題: 発表者: 場所: 日付: (/6TUFQͱ$PDPUSPO KQ NBD04OBUJWF4ZNQPTJVN 

  2. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp ࣗݾ঺հ KQ ͸ NBD04 ΞϓϦέʔγϣϯઐ໳ͷϗϏʔ։ൃऀɻ 044 ϓϩδΣΫτӡӦ͔ΒϓϩάϥϛϯάɺΞΠίϯͷσ βΠϯ·ͰɺNBD04 ͷΞϓϦέʔγϣϯ։ൃʹؔΘΔ͜

    ͱͳΒશ෦΍ΔϚϯͰ͋Δɻ ͤΜʹ͡Ύ͏ΑΜ
 ͐͡ʔͽʔ 本業ではないよ try! Swift 2019 で初日に話しました。 10:00-10:25ʮnative macOS applicationɺ·ͨ͸AppKitͷੈքʯ
  3. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp USZ4XJGU5PLZP cf. https://speakerdeck.com/1024jp/native-macos-application-or-the-world-of-appkit VKVNG

    RTGUGPVGT RNCEG FCVG Native macOS application, or the world of AppKit try! Swift 2019 2019-03-21 1024jp ʢnative macOS applicationɺ·ͨ͸AppKitͷੈքʣ
  4. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp ࣗݾ঺հ CotEditor Gapplin BathyScaphe

    Qli application work plain-text editor SVG viewer 5ch browser movie player 2014年に
 正式引き継ぎ サポーtメンバー
 (主にデザイン・UI) 新作
  5. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp 今日の主役 GNUstep Cocotron

  6. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp ࠓ೔ͷτϐοΫ ѻ͏࿩ – macOS

    ͷྺ࢙ – GNUstep ͱ Cocotron ͱ͸ – GNUstep/Cocotron ͷ׆༻ ѻΘͳ͍࿩ – macOS ΞϓϦέʔγϣϯͷ࡞๏ – Human Interface Guidelines
  7. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp .BD04NBD04ͷྺ࢙ NeXTSTEP Mac OS

    X Ϋϩʔϯ Windows, Unix-like, etc macOS OS X Cocoa (Foundation+AppKit) Mac OS 1989-1997 1984-1999 2001-present 2006-2015? 1994 1994-present ΧʔωϧΛআ͘
 ্ҐϨΠϠʔͷΦʔϓϯԽ OSͷϕʔεͱͯ͠࠾༻ OSͷ࡮৽ Ϋϩʔϯ MacApp OPENSTEP GNUstep Cocotron (classic) NeXTSTEP Solaris, HP-UX, 
 Windows NT ( ) Rhapsody
  8. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp ֤ϑϨʔϜϫʔΫͷൺֱ Apple Inc. NeXT,

    Inc. NeXT, Inc.,
 Sun Microsystems The GNUstep Project MacApp Cocoa NeXTSTEP OPENSTEP
 (OpenStep) GNUstep Cocotron platform Mac OS macOS
 (Mac OS X) NeXTStep Solaris, Windows NT, Unix-likes Windows, Unix-likes, etc. Windows 2000, XP, Vista,
 Linux, Darwin, Solaris framework – Foundation,
 AppKit,
 CoreData – Foundation Kit,
 Application Kit,
 PostScript Base Library,
 GUI Library Foundation,
 AppKit* language Pascal 
 → C++ Objective-C
 → Swift Objective-C Objective-C Objective-C Objective-C development closed closed closed closed OSS
 github.com/ gnustep OSS
 github.com/ cjwl/cocotron year 1984-1999 2001-present 1989-1997 1994 1994-present 2006-2015? *AppKit͸WindowsͷΈ
  9. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp (/6TUFQWT$PDPUSPO GNUstep Cocotron –

    OPENSTEP Ϋϩʔϯ – ઌൃ (1994-) – υΩϡϝϯτ๛෋ – ։ൃܧଓ – Cocoa Ϋϩʔϯ – ޙൃ (2006-) – ࠷৽ʢ౰࣌ʣͷCocoaΛ࠶࣮૷͠ɺ
 WindowsͰͷಈ࡞Λॏࢹ – υΩϡϝϯτগ – ։ൃఀ଺
  10. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp 01&/45&1 cite: “Today in

    Apple history: NeXT customers get early taste of OS X”, Cult of Mac, 2017-09
 https://www.cultofmac.com/503084/today-apple-history-next-customers-get-early-taste-os-x/ NeXTSTEP
  11. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp 01&/45&14QFDJpDBUJPO OPENSTEP SPECIFICATION October

    19, 1994 ™ Figure 1. Major Components of OpenStep Application Application Kit Foundation Kit Display PostScript System Device-Dependent Windowing Extensions Operating System OpenStep – OPENSTEPͷެ։࢓༷ॻ – ܭ518ท Copyright © 1994 NeXT Computer, Inc. GNUstepの素
  12. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp 0QFO4UFQ4QFDJpDBUJPOr/47JFX OpenStep Specification—10/19/94 1-218

    Chapter 1: Application Kit NSView Inherits From: NSResponder : NSObject Conforms To: NSCoding (NSResponder) NSObject (NSObject) Declared In: AppKit/NSView.h AppKit/NSClipView.h Class Description NSView is an abstract class that provides its subclasses with a structure for drawing and for handling events. Any application that needs to display, print, or receive events must use NSView objects. To be displayed, a view must be placed in a window (represented by an NSWindow object). All the views within a window are arranged in a hierarchy, with each view having a single superview and zero or more subviews. Each view has its own area to draw in and its own coordinate system, expressed as a transformation of its superview’s coordinate system. An NSView object can scale, translate, or rotate its coordinates, or flip the polarity of its y-axis. An NSView keeps track of its size and location in two ways: as a frame rectangle (expressed in its superview’s coordinate system) and as a bounds rectangle (expressed in its own coordinate system). Both are represented by NSRect structures. Subclasses of NSView typically override drawRect: to implement an object’s distinctive appearance. They also frequently override one or more of NSView’s or NSResponder’s event-handling methods, to react to the user’s manipulations of the mouse and keyboard. Initializing NSView Objects – (id)initWithFrame:(NSRect)frameRect Initializes a new NSView object to the location and dimensions of frameRect. Managing the NSView Hierarchy – (void)addSubview:(NSView *)aView Makes aView a subview of the receiving view object. – (void)addSubview:(NSView *)aView Makes aView a subview of the receiving view object. positioned:(NSWindowOrderingMode)place It is positioned relative to otherView according to relativeTo:(NSView *)otherView place. OpenStep Specification—10/19/94 1-220 Chapter 1: Application Kit – (void)setFrameRotation:(float)angle Rotates the view’s frame to angle. This method posts the NSViewFocusChangedNotification notification with the receiving object to the default notification center. – (void)setFrameSize:(NSSize)newSize Resizes the view’s frame to newSize. This method posts the NSViewFrameChangedNotification and NSViewFocusChangedNotification notifications with the receiving object to the default notification center. Modifying the Coordinate System – (float)boundsRotation Returns the rotation of the view’s coordinate system. – (NSRect)bounds Gets the view’s bounds rectangle. – (BOOL)isFlipped Returns whether the view is flipped. – (BOOL)isRotatedFromBase Returns whether the view is rotated. – (BOOL)isRotatedOrScaledFromBase Returns whether the view is rotated or scaled. – (void)scaleUnitSquareToSize:(NSSize)newSize Scales the NSView’s coordinate system unit size to newSize. This method posts the notification NSViewFocusChangedNotification with the receiving object to the default notification center. – (void)setBounds:(NSRect)aRect Sets the NSView’s bounds rectangle to aRect. – (void)setBoundsOrigin:(NSPoint)newOrigin Sets the NSView’s drawing origin to newOrigin. This method posts the NSViewFocusChangedNotification notification with the receiving object to the default notification center. – (void)setBoundsRotation:(float)angle Rotates the NSView’s coordinate system to angle. This method posts the NSViewFocusChangedNotification notification with the receiving object to the default notification center. – (void)setBoundsSize:(NSSize)newSize Resizes the NSView’s coordinate system to newSize. This method posts the NSViewFocusChangedNotification notification with the receiving object to the default notification center. – (void)translateOriginToPoint:(NSPoint)point Shifts the NSView’s coordinate system to point. This method posts the NSViewFocusChangedNotification notification with the receiving object to the default notification center.
  13. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp %FWFMPQFS%PDVNFOUBUJPO http://www.gnustep.org/developers/documentation.html

  14. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp 'PVOEBUJPO,JU 0QFO4UFQ NSAssertionHandler NSObject

    NSAutoreleasePool NSArray NSBTreeBlock NSBundle NSByteStore NSCharacterSet NSCoder NSConditionLock NSConnection NSData NSDate NSDeserializer NSDictionary NSEnumerator NSException NSInvocation NSLock NSMethodSignature NSNotification NSNotificationCenter NSNotificationQueue NSMutableArray NSCalendarDate NSProxy NSDistantObject NSArchiver NSUnarchiver NSByteStoreFile NSMutableCharacterSet NSMutableData NSMutableDictionary NSProcessInfo NSRecursiveLock NSRunLoop NSScanner NSSerializer NSSet NSString NSThread NSTimeZone NSTimer NSUserDefaults NSValue NSMutableString NSMutableSet NSCountedSet NSTimeZoneDetail NSNumber
  15. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp 'PVOEBUJPO,JU (/6TUFQ௥Ճ෼ NSAttributedString NSAffineTransform

    NSClassDescription NSCondition NSDateFormatter NSDecimalNumber NSDecimalNumberHandler NSDirectoryEnumerator NSDistributedLock NSDistributedNotificationCenter NSError NSException NSFileHandler NSFileManager NSFormatter NSHashTable NSIndexSet NSInputStream NSIndexPath NSKeyedArchiver NSKeyedUnarchiver NSMapTable NSMutableAttributedString NSMutableIndexSet NSNull NSNumberFormatter NSOutputStream NSPipe NSPointerArray NSPointerFunctions NSPropertyListSerialization NSStream NSTask NSUndoManager NSValueTransformer NSConstantString
  16. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp 'PVOEBUJPO,JU (/6TUFQ௥Ճ෼ NSCachedURLResponse NSHTTPCookie

    NSHTTPCookieStorage NSHTTPURLResponse NSHost NSMessagePort NSMessagePortNameServer NSMutableURLRequest NSNetService NSNetServiceBrowser NSPort NSPortCoder NSPortMessage NSPortNameServer NSURL NSURLAuthenticationChallenge NSURLCache NSURLConnection NSURLCredential NSURLDownload NSURLProtectionSpace NSURLProtocol NSURLRequest NSURLResponce NSXMLDTD NSXMLDTDNode NSXMLDocument NSXMLElement NSXMLNode NSXMLParser NSSocketPort NSSocketPortNameServer NSProtocolChecker
  17. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp "QQMJDBUJPO,JU 0QFO4UFQ NSColorList NSObject

    NSColor NSCell NSColorPicker NSCursor NSDataLink NSDataLinkManager NSEvent NSFont NSFontManager NSImage NSImageRep NSPasteboard NSPrintInfo NSPrintOperation NSPrinter NSResponder NSScreen NSSelection NSSpellChecker NSSpellServer NSWorkspace NSActionCell NSBrowserCell NSBitmapImageRep NSEPSImageRep NSCachedImageRep NSCustomImageRep NSWindow NSApplication NSView NSButtonCell NSFormCell NSSliderCell NSTextFieldCell NSMenuCell NSPanel NSText NSCStringText NSSplitView NSScrollView NSControl NSBox NSClipView NSColorPanel NSDataLinkPanel NSFontPanel NSHelpPanel NSMenu NSPageLayout NSPrintPanel NSSavePanel NSOpenPanel NSTextField NSBrowser NSButton NSColorWell NSMatrix NSScroller NSSlider NSPopUpButton NSForm
  18. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp "QQMJDBUJPO,JU (/6TUFQ௥Ճ෼ NSDocument NSBezierPath

    NSComboBox NSComboBoxCell NSDocumentController NSDrawer NSDrawerDelegate NSFileWrapper NSGraphicsContext NSHelpManager NSImageCell NSImageView NSInputManager NSInputServer NSLayoutManager NSMenuItem NSMenuItemCell NSMenuView NSNib NSOpenGLContext NSOpenGLPixelFormat NSOpenGLView NSOutlineView NSProgressIndicator NSRulerMarker NSRulerView NSSecureTextField NSSecureTextFieldCell NSSound NSStepper NSStepperCell NSTabView NSTabViewItem NSTableColumn NSTableHeaderCell NSTableHeaderView NSTextContainer NSTableView NSTextView NSToolbar NSToolbarItem NSWindowController
  19. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp (/6TUFQ$PDPUSPOͷ࢖͍ํ GNUstep/CocotronΛ࢖ͬͯ
 ଞϓϥοτϑΥʔϜ޲͚CocoaΞϓϦέʔγϣϯΛ࡞Ζ͏ʂ Foundation/AppKitͷίʔυϨϕϧ࣮૷͕ಡΊΔ

  20. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp $PDPBͱ(/6TUFQͷࠩҟ ͋͘·Ͱ࢓༷ॻϕʔεͷ࠶࣮૷Ͱ͋ΓɺຊՈͱίʔυϨϕϧͰಉ͜͡ͱ͸
 ظ଴Ͱ͖ͳ͍ Մೳੑ

    – ࢓༷ॻ → GNUstepͷ࣮૷͕ޡ͍ͬͯͨ – ࣮૷͸߹͍͕ͬͯͨɺͦͷޙCocoaͷ࢓༷͕มߋ͞Εͨ – GNUstep͕࣮૷ΛఘΊͯΔ – GNUstepͷػೳ௥ՃͨΊʹOPENSTEP/Cocoaͷ࢓༷͔Βဃ཭ͨ͠ あるかな?
  21. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp (/6TUFQ$PDPUSPOͷ׆༻ ドキュメントとAppleの実装の差異に関して
 メモが残ってたりする。 NSTextView_actions.m

    /* TODO: find out what affinity is supposed to mean My current assumption: Affinity deals with which direction we are selecting in, ie. which end of the selected range is the moving end, and which is the anchor. NSSelectionAffinityUpstream means that the minimum index of the selected range is moving (ie. _selected_range.location). NSSelectionAffinityDownstream means that the maximum index of the selected range is moving (ie. _selected_range.location+_selected_range.length). Thus, when moving and selecting, we use the affinity to find out which end of the selected range to move, and after moving, we compare the character index we moved to with the anchor and set the range and affinity. The affinity is important when making keyboard selection have sensible behavior. Example: If, in the string "abcd", the insertion point is between the "c" and the "d" (selected range is (3,0)), and the user hits shift-left twice, we select the "c" and "b" (1,2) and set the affinity to NSSelectionAffinityUpstream. If the user hits shift-right, only the "c" will be selected (2,1). If the insertion point is between the "a" and the "b" (1,0) and the user hits shift-right twice, we again select the "b" and "c" (1,2), but the affinity is NSSelectionAffinityDownstream. If the user hits shift-right, the "d" is added to the selection (1,3). */ - (unsigned int) _movementOrigin { NSRange range = [self selectedRange];
  22. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp (/6TUFQ׆༻ྫ layoutManager.removeTemporaryAttribute(.foregroundColor, forCharacterRange: wholeRange)

    for (range, color) in highlights { layoutManager.addTemporaryAttribute(.foregroundColor, value: color, forCharacterRange: range) } Swift めちゃ時間かかる... γϯλοΫεϋΠϥΠτͰϝΠϯεϨουͰ΍Βͳ͍ͱ͍͚ͳ͍࡞ۀ Reference NSLayoutManager.addTemporaryAttributes(_:forCharacterRange:) Discussion Temporary attributes are used only for onscreen drawing and are not persistent in any way. NSTextView uses them to color misspelled words when continuous spell checking is enabled. Currently the only temporary attributes recognized are those that do not affect layout (colors, underlines, and so on). ಺෦తͳattributeσʔλΛมߋ͢Δ͚ͩͰԿ΋͠ͳ͍ͷͰ͸…?
  23. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp (/6TUFQ׆༻ྫ @implementation NSLayoutManager -

    (void) addTemporaryAttribute: (NSString *)attr value: (id)value forCharacterRange: (NSRange)range { [[self _temporaryAttributes] addAttribute: attr value: value range: range]; [self invalidateDisplayForCharacterRange: range]; } @end ObjC layoutManager.removeTemporaryAttribute(.foregroundColor, forCharacterRange: wholeRange) for (range, color) in highlights { layoutManager.addTemporaryAttribute(.foregroundColor, value: color, forCharacterRange: range) } Swift γϯλοΫεϋΠϥΠτͰϝΠϯεϨουͰ΍Βͳ͍ͱ͍͚ͳ͍࡞ۀ GNUstepͰͷ࣮૷ お前...!! めちゃ時間かかる...
  24. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp (/6TUFQ׆༻ྫ class LayoutManager: NSLayoutManager

    { var ignoresDisplayValidation = false override func invalidateDisplay(forCharacterRange charRange: NSRange) { if self.ignoresDisplayValidation { return } super.invalidateDisplay(forCharacterRange: charRange) } } layoutManager.ignoresDisplayValidation = true layoutManager.removeTemporaryAttribute(.foregroundColor, 
 forCharacterRange: wholeRange) for (range, color) in highlights { layoutManager.addTemporaryAttribute(.foregroundColor, value: color, forCharacterRange: range) } layoutManager.ignoresDisplayValidation = false layoutManager.invalidateDisplay(forCharacterRange: wholeRange) Swift
  25. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp ݁Ռ

  26. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp (/6TUFQ׆༻ྫ ૒ํ޲ςΩετ (bidi-text) ͰͷΧʔιϧͷಈ͖Λ஌Γ͍ͨ

    Loem ispum dolor sit amet, consectetur adipiscing … ૒ํ޲ͷ઀఺ͰͷંΓฦ͠
  27. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp ·ͱΊ – Cocoa͸NeXT༝དྷͰ͋Δ –

    Foundation+AppKitΫϩʔϯͷGNUstep / Cocotron͕ଘࡏ͢Δ – ιʔεϨϕϧͰ࣮૷͕ಡΊΔ – ͋͘·Ͱ࢓༷ॻϕʔεͷ࠶࣮૷Ͱ͋ΓɺຊՈͱίʔυϨϕϧͰಉ͜͡ͱ͸ظ଴Ͱ͖ͳ͍ – 2019ݱࡏɺ૒ํ։ൃ͸ΞΫςΟϒͰ͸ͳ͍ → ຊՈAppKitͱͷဃ཭͸ਐΉҰํ – ઌਓͷ஌ܙͱͯ͠࢖͑Δ – Ұհͷ։ൃऀ͕1ਓͰߟ͑ΔΑΓ΋ਅ࣮ʹ͍ۙظ଴஋͕ߴ͍ とはいえGNUstepは動きがあるが
  28. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp ͓ Θ Γ

  29. macOS native (/6TUFQͱ$PDPUSPO © 2019 1024jp ࢀߟจݙ – GNUstep, the

    open source OpenStep http://www.linuxfocus.org/English/March2001/article195.shtml – Core GNUstep developers interview http://www.roard.com/docs/interview/ – Developer Documentation –GNUstep http://www.gnustep.org/developers/documentation.html